From: Felix Fietkau Date: Tue, 10 Jan 2006 19:43:00 +0000 (+0000) Subject: large target/linux cleanup X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=ea35a1edbebfa01ee51e625e670a65fa985fc1b5;p=librecmc%2Flibrecmc.git large target/linux cleanup SVN-Revision: 2877 --- diff --git a/openwrt/target/linux/Config.in b/openwrt/target/linux/Config.in index 4b621231c7..5a6c11a0f1 100644 --- a/openwrt/target/linux/Config.in +++ b/openwrt/target/linux/Config.in @@ -67,58 +67,8 @@ config BR2_LINUX_PCMCIA_SUPPORT comment "Device specific modules" -config BR2_PACKAGE_KMOD_BRCM_ET - prompt "kmod-brcm-et...................... Broadcom Ethernet Driver" - tristate - depends BR2_LINUX_2_4_BRCM - default m - help - Proprietary driver for Broadcom Ethernet chipsets (obsolete) +source "target/linux/*-2.[46]/Config.in" -config BR2_PACKAGE_KMOD_BRCM_WL - prompt "kmod-brcm-wl...................... Broadcom Wireless Network Driver" - tristate - depends BR2_LINUX_2_4_BRCM - default y - help - Proprietary driver for Broadcom Wireless chipsets - -config BR2_PACKAGE_KMOD_BRCM_WL2 - prompt "kmod-brcm-wl2..................... Broadcom Wireless Network Driver (new)" - tristate - depends BR2_LINUX_2_4_BRCM - default m - help - Proprietary driver for Broadcom Wireless chipsets - New version with Multi-BSS capability - -config BR2_PACKAGE_KMOD_CPMAC - prompt "kmod-cpmac........................ AR7 CPMAC Network Driver" - tristate - default y - depends BR2_LINUX_2_4_AR7 - help - Driver for the AR7 CPMAC network chip - -config BR2_PACKAGE_KMOD_SANGAM_ATM_A - prompt "kmod-sangam-atm-annex-a........... AR7 Sangam ADSL Driver (Annex A)" - tristate - default m - depends BR2_LINUX_2_4_AR7 - select BR2_PACKAGE_KMOD_ATM - help - ATM driver for the Sangam ADSL chip on AR7 - Annex A version - -config BR2_PACKAGE_KMOD_SANGAM_ATM_B - prompt "kmod-sangam-atm-annex-b........... AR7 Sangam ADSL Driver (Annex B)" - tristate - default y - depends BR2_LINUX_2_4_AR7 - select BR2_PACKAGE_KMOD_ATM - help - ATM driver for the Sangam ADSL chip on AR7 - Annex B version comment "Networking modules" @@ -126,7 +76,7 @@ config BR2_PACKAGE_KMOD_ATM prompt "kmod-atm.......................... ATM support" tristate default y if BR2_LINUX_2_4_AR7 - default m if BR2_LINUX_2_6_BRCM + default m help ATM support @@ -164,7 +114,6 @@ config BR2_PACKAGE_KMOD_PPPOATM prompt "kmod-pppoatm.................... PPPoA (PPP over ATM) kernel support" tristate default y if BR2_LINUX_2_4_AR7 - default m if BR2_LINUX_2_6_BRCM default m depends BR2_PACKAGE_KMOD_PPP select BR2_PACKAGE_KMOD_ATM diff --git a/openwrt/target/linux/Makefile b/openwrt/target/linux/Makefile index 5dfe12ad7f..038983f3aa 100644 --- a/openwrt/target/linux/Makefile +++ b/openwrt/target/linux/Makefile @@ -10,23 +10,23 @@ define kernel_template $(1)/$(2)-clean: @$(TRACE) target/linux/linux-$(1)/clean - $(MAKE) -C linux-$(1) KERNEL="$(1)" BOARD="$(2)" clean + $(MAKE) -C $(2)-$(1) BOARD="$(2)" clean $(1)/$(2)-prepare: @$(TRACE) target/linux/linux-$(1)/prepare - $(MAKE) -C linux-$(1) KERNEL="$(1)" BOARD="$(2)" prepare + $(MAKE) -C $(2)-$(1) BOARD="$(2)" prepare $(1)/$(2)-compile: @$(TRACE) target/linux/linux-$(1)/compile - $(MAKE) -C linux-$(1) KERNEL="$(1)" BOARD="$(2)" compile + $(MAKE) -C $(2)-$(1) BOARD="$(2)" compile $(1)/$(2)-rebuild: @$(TRACE) target/linux/linux-$(1)/rebuild - $(MAKE) -C linux-$(1) KERNEL="$(1)" BOARD="$(2)" rebuild + $(MAKE) -C $(2)-$(1) BOARD="$(2)" rebuild $(1)/$(2)-install: @$(TRACE) target/linux/linux-$(1)/install - $(MAKE) -C linux-$(1) KERNEL="$(1)" BOARD="$(2)" install + $(MAKE) -C $(2)-$(1) BOARD="$(2)" install $(1)/$(2)-image: $(1)/$(2)-install @$(TRACE) target/linux/image/install diff --git a/openwrt/target/linux/ar531x-2.4/Makefile b/openwrt/target/linux/ar531x-2.4/Makefile new file mode 100644 index 0000000000..989bcc4582 --- /dev/null +++ b/openwrt/target/linux/ar531x-2.4/Makefile @@ -0,0 +1,17 @@ +include $(TOPDIR)/rules.mk + +LINUX_VERSION:=2.4.32 +LINUX_RELEASE:=1 +LINUX_KERNEL_MD5SUM:=38f4d0830e95a20f4bfed17622d5557c + +include ../rules.mk +include ./config +include ../generic-$(KERNEL)/modules.mk +include ../kernel.mk + +$(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked + [ -d ../generic-$(KERNEL)/patches ] && $(PATCH) $(LINUX_DIR) ../generic-$(KERNEL)/patches $(MAKE_TRACE) + [ -d ./patches ] && $(PATCH) $(LINUX_DIR) ./patches $(MAKE_TRACE) + @cp config $(LINUX_DIR)/.config + touch $@ + diff --git a/openwrt/target/linux/ar531x-2.4/config b/openwrt/target/linux/ar531x-2.4/config new file mode 100644 index 0000000000..77c5beb3c2 --- /dev/null +++ b/openwrt/target/linux/ar531x-2.4/config @@ -0,0 +1,1102 @@ +# +# 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_VENETDEV=y +CONFIG_MARVELL_ENET_PHY=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=y +# 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=y +CONFIG_BLK_DEV_RAM_SIZE=3072 +CONFIG_BLK_DEV_INITRD=y +# 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=m +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_RTSP=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_TIME=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_RTSP=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_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=m +# 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/ar531x-2.4/patches/000-atheros-support.patch b/openwrt/target/linux/ar531x-2.4/patches/000-atheros-support.patch new file mode 100644 index 0000000000..de7115b46a --- /dev/null +++ b/openwrt/target/linux/ar531x-2.4/patches/000-atheros-support.patch @@ -0,0 +1,11411 @@ +diff -urN linux-mips/arch/mips/ar531x/ar531xdbg_io.c mips-linux-2.4.25/arch/mips/ar531x/ar531xdbg_io.c +--- linux-mips/arch/mips/ar531x/ar531xdbg_io.c 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xdbg_io.c 2005-12-30 17:26:30.606883840 +0000 +@@ -0,0 +1,234 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright MontaVista Software Inc ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Basic support for polled character input/output ++ * using the AR531X's serial port. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++ ++#if CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB ++/* base addr of uart and clock timing */ ++#if CONFIG_AR5315 ++#define BASE AR5315_UART0 ++#else ++#define BASE AR531X_UART0 ++#endif ++ ++/* distance in bytes between two serial registers */ ++#define REG_OFFSET 4 ++ ++/* ++ * 0 - we need to do serial init ++ * 1 - skip serial init ++ */ ++static int serialPortInitialized = 0; ++ ++/* ++ * * the default baud rate *if* we do serial init ++ * */ ++#define BAUD_DEFAULT UART16550_BAUD_9600 ++ ++/* === END OF CONFIG === */ ++ ++#define UART16550_BAUD_2400 2400 ++#define UART16550_BAUD_4800 4800 ++#define UART16550_BAUD_9600 9600 ++#define UART16550_BAUD_19200 19200 ++#define UART16550_BAUD_38400 38400 ++#define UART16550_BAUD_57600 57600 ++#define UART16550_BAUD_115200 115200 ++ ++#define UART16550_PARITY_NONE 0 ++#define UART16550_PARITY_ODD 0x08 ++#define UART16550_PARITY_EVEN 0x18 ++#define UART16550_PARITY_MARK 0x28 ++#define UART16550_PARITY_SPACE 0x38 ++ ++#define UART16550_DATA_5BIT 0x0 ++#define UART16550_DATA_6BIT 0x1 ++#define UART16550_DATA_7BIT 0x2 ++#define UART16550_DATA_8BIT 0x3 ++ ++#define UART16550_STOP_1BIT 0x0 ++#define UART16550_STOP_2BIT 0x4 ++ ++/* register offset */ ++#define OFS_RCV_BUFFER (0*REG_OFFSET) ++#define OFS_TRANS_HOLD (0*REG_OFFSET) ++#define OFS_SEND_BUFFER (0*REG_OFFSET) ++#define OFS_INTR_ENABLE (1*REG_OFFSET) ++#define OFS_INTR_ID (2*REG_OFFSET) ++#define OFS_DATA_FORMAT (3*REG_OFFSET) ++#define OFS_LINE_CONTROL (3*REG_OFFSET) ++#define OFS_MODEM_CONTROL (4*REG_OFFSET) ++#define OFS_RS232_OUTPUT (4*REG_OFFSET) ++#define OFS_LINE_STATUS (5*REG_OFFSET) ++#define OFS_MODEM_STATUS (6*REG_OFFSET) ++#define OFS_RS232_INPUT (6*REG_OFFSET) ++#define OFS_SCRATCH_PAD (7*REG_OFFSET) ++ ++#define OFS_DIVISOR_LSB (0*REG_OFFSET) ++#define OFS_DIVISOR_MSB (1*REG_OFFSET) ++ ++ ++/* memory-mapped read/write of the port */ ++#define UART16550_READ(y) (*((volatile u8*)(BASE + y))) ++#define UART16550_WRITE(y, z) ((*((volatile u8*)(BASE + y))) = z) ++ ++void ++debugPortInit(u32 baud, u8 data, u8 parity, u8 stop) ++{ ++ /* Pull UART out of reset */ ++#if CONFIG_AR5315 ++ sysRegWrite(AR5315_RESET, ++ sysRegRead(AR5315_RESET) & ~(RESET_UART0)); ++#else ++ sysRegWrite(AR531X_RESET, ++ sysRegRead(AR531X_RESET) & ~(AR531X_RESET_UART0)); ++#endif ++ ++ /* disable interrupts */ ++ UART16550_WRITE(OFS_LINE_CONTROL, 0x0); ++ UART16550_WRITE(OFS_INTR_ENABLE, 0); ++ ++ /* set up buad rate */ ++ { ++ u32 divisor; ++#if CONFIG_AR5315 ++ u32 uart_clock_rate = ar531x_apb_frequency(); ++#else ++ u32 uart_clock_rate = ar531x_cpu_frequency() / 4; ++#endif ++ u32 base_baud = uart_clock_rate / 16; ++ ++ /* set DIAB bit */ ++ UART16550_WRITE(OFS_LINE_CONTROL, 0x80); ++ ++ /* set divisor */ ++ divisor = base_baud / baud; ++ UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); ++ UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8); ++ ++ /* clear DIAB bit */ ++ UART16550_WRITE(OFS_LINE_CONTROL, 0x0); ++ } ++ ++ /* set data format */ ++ UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); ++} ++ ++u8 ++getDebugChar(void) ++{ ++ if (!serialPortInitialized) { ++ serialPortInitialized = 1; ++ debugPortInit(BAUD_DEFAULT, ++ UART16550_DATA_8BIT, ++ UART16550_PARITY_NONE, UART16550_STOP_1BIT); ++ } ++ ++ while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); ++ return UART16550_READ(OFS_RCV_BUFFER); ++} ++ ++#if CONFIG_KGDB ++/* ++ * Peek at the most recently received character. ++ * Don't wait for a new character to be received. ++ */ ++u8 ++peekDebugChar(void) ++{ ++ return UART16550_READ(OFS_RCV_BUFFER); ++} ++ ++static int kgdbInitialized = 0; ++ ++void ++kgdbInit(void) ++{ ++#if CONFIG_AR5315 ++ sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION); ++#else ++ sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION); ++#endif ++ ++ if (!kgdbInitialized) { ++ printk("Setting debug traps - please connect the remote debugger.\n"); ++ set_debug_traps(); ++ kgdbInitialized = 1; ++ } ++ breakpoint(); ++} ++ ++int ++kgdbEnabled(void) ++{ ++ return kgdbInitialized; ++} ++ ++#define DEBUG_CHAR '\001'; ++ ++int ++kgdbInterrupt(void) ++{ ++ if (!kgdbInitialized) { ++ return 0; ++ } ++ ++ /* ++ * Try to avoid swallowing too much input: Only consume ++ * a character if nothing new has arrived. Yes, there's ++ * still a small hole here, and we may lose an input ++ * character now and then. ++ */ ++ if (UART16550_READ(OFS_LINE_STATUS) & 1) { ++ return 0; ++ } else { ++ return UART16550_READ(OFS_RCV_BUFFER) == DEBUG_CHAR; ++ } ++} ++#endif ++ ++ ++void ++putDebugChar(char byte) ++{ ++ if (!serialPortInitialized) { ++ serialPortInitialized = 1; ++ debugPortInit(BAUD_DEFAULT, ++ UART16550_DATA_8BIT, ++ UART16550_PARITY_NONE, UART16550_STOP_1BIT); ++ } ++ ++ while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0); ++ UART16550_WRITE(OFS_SEND_BUFFER, byte); ++ } ++#endif /* CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB */ +diff -urN linux-mips/arch/mips/ar531x/ar531xgpio.c mips-linux-2.4.25/arch/mips/ar531x/ar531xgpio.c +--- linux-mips/arch/mips/ar531x/ar531xgpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xgpio.c 2005-12-30 17:26:30.606883840 +0000 +@@ -0,0 +1,147 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Support for GPIO -- General Purpose Input/Output Pins ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++ ++/* GPIO Interrupt Support */ ++ ++/* Turn on the specified AR531X_GPIO_IRQ interrupt */ ++static unsigned int ++ar531x_gpio_intr_startup(unsigned int irq) ++{ ++ ar531x_gpio_intr_enable(irq); ++ return 0; ++} ++ ++/* Turn off the specified AR531X_GPIO_IRQ interrupt */ ++static void ++ar531x_gpio_intr_shutdown(unsigned int irq) ++{ ++ ar531x_gpio_intr_disable(irq); ++} ++ ++u32 gpioIntMask = 0; ++ ++/* Enable the specified AR531X_GPIO_IRQ interrupt */ ++void ++ar531x_gpio_intr_enable(unsigned int irq) ++{ ++ u32 reg; ++ int gpio; ++ ++#ifndef CONFIG_AR5315 ++ gpio = irq - AR531X_GPIO_IRQ_BASE; ++ gpioIntMask |= gpio; ++ ++ reg = sysRegRead(AR531X_GPIO_CR); ++ reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio)); ++ reg |= GPIO_CR_I(gpio); ++ reg |= GPIO_CR_INT(gpio); ++ ++ sysRegWrite(AR531X_GPIO_CR, reg); ++ (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */ ++#endif ++} ++ ++/* Disable the specified AR531X_GPIO_IRQ interrupt */ ++void ++ar531x_gpio_intr_disable(unsigned int irq) ++{ ++ u32 reg; ++ int gpio; ++ ++#ifndef CONFIG_AR5315 ++ gpio = irq - AR531X_GPIO_IRQ_BASE; ++ reg = sysRegRead(AR531X_GPIO_CR); ++ reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio)); ++ reg |= GPIO_CR_I(gpio); ++ /* No GPIO_CR_INT bit */ ++ ++ sysRegWrite(AR531X_GPIO_CR, reg); ++ (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */ ++ ++ gpioIntMask &= ~gpio; ++#endif ++} ++ ++static void ++ar531x_gpio_intr_ack(unsigned int irq) ++{ ++ ar531x_gpio_intr_disable(irq); ++} ++ ++static void ++ar531x_gpio_intr_end(unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) ++ ar531x_gpio_intr_enable(irq); ++} ++ ++static void ++ar531x_gpio_intr_set_affinity(unsigned int irq, unsigned long mask) ++{ ++ /* Only 1 CPU; ignore affinity request */ ++} ++ ++int ar531x_gpio_irq_base; ++ ++struct hw_interrupt_type ar531x_gpio_intr_controller = { ++ "AR531X GPIO", ++ ar531x_gpio_intr_startup, ++ ar531x_gpio_intr_shutdown, ++ ar531x_gpio_intr_enable, ++ ar531x_gpio_intr_disable, ++ ar531x_gpio_intr_ack, ++ ar531x_gpio_intr_end, ++ ar531x_gpio_intr_set_affinity, ++}; ++ ++void ++ar531x_gpio_intr_init(int irq_base) ++{ ++ int i; ++ ++ for (i = irq_base; i < irq_base + AR531X_GPIO_IRQ_COUNT; i++) { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = NULL; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &ar531x_gpio_intr_controller; ++ } ++ ++ ar531x_gpio_irq_base = irq_base; ++} ++ ++/* ARGSUSED */ ++void ++spurious_gpio_handler(int cpl, void *dev_id, struct pt_regs *regs) ++{ ++ u32 gpioDataIn; ++#if CONFIG_AR5315 ++ gpioDataIn = sysRegRead(AR5315_GPIO_DI) & gpioIntMask; ++#else ++ gpioDataIn = sysRegRead(AR531X_GPIO_DI) & gpioIntMask; ++#endif ++ ++ printk("spurious_gpio_handler: 0x%x di=0x%8.8x gpioIntMask=0x%8.8x\n", ++ cpl, gpioDataIn, gpioIntMask); ++} ++ ++struct irqaction spurious_gpio = ++ {spurious_gpio_handler, SA_INTERRUPT, 0, "spurious_gpio", ++ NULL, NULL}; ++ +diff -urN linux-mips/arch/mips/ar531x/ar531x.h mips-linux-2.4.25/arch/mips/ar531x/ar531x.h +--- linux-mips/arch/mips/ar531x/ar531x.h 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531x.h 2005-12-30 17:26:30.605883992 +0000 +@@ -0,0 +1,1018 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++#ifndef AR531X_H ++#define AR531X_H 1 ++ ++#ifndef CONFIG_AR5315 ++ ++#include ++ ++/* Address Map */ ++#define AR531X_WLAN0 0x18000000 ++#define AR531X_WLAN1 0x18500000 ++#define AR531X_ENET0 0x18100000 ++#define AR531X_ENET1 0x18200000 ++#define AR531X_SDRAMCTL 0x18300000 ++#define AR531X_FLASHCTL 0x18400000 ++#define AR531X_APBBASE 0x1c000000 ++#define AR531X_FLASH 0x1e000000 ++#define AR531X_UART0 0xbc000003 /* UART MMR */ ++ ++/* ++ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that ++ * should be considered available. The AR5312 supports 2 enet MACS, ++ * even though many reference boards only actually use 1 of them ++ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch. ++ * The AR2312 supports 1 enet MAC. ++ */ ++#define AR531X_NUM_ENET_MAC 2 ++ ++/* ++ * Need these defines to determine true number of ethernet MACs ++ */ ++#define AR5212_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ ++#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ ++#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ ++#define AR531X_RADIO_MASK_OFF 0xc8 ++#define AR531X_RADIO0_MASK 0x0003 ++#define AR531X_RADIO1_MASK 0x000c ++#define AR531X_RADIO1_S 2 ++ ++/* ++ * AR531X_NUM_WMAC defines the number of Wireless MACs that\ ++ * should be considered available. ++ */ ++#define AR531X_NUM_WMAC 2 ++ ++/* Reset/Timer Block Address Map */ ++#define AR531X_RESETTMR (AR531X_APBBASE + 0x3000) ++#define AR531X_TIMER (AR531X_RESETTMR + 0x0000) /* countdown timer */ ++#define AR531X_WD_CTRL (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */ ++#define AR531X_WD_TIMER (AR531X_RESETTMR + 0x000c) /* watchdog timer */ ++#define AR531X_ISR (AR531X_RESETTMR + 0x0010) /* Intr Status Reg */ ++#define AR531X_IMR (AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */ ++#define AR531X_RESET (AR531X_RESETTMR + 0x0020) ++#define AR5312_CLOCKCTL1 (AR531X_RESETTMR + 0x0064) ++#define AR5312_SCRATCH (AR531X_RESETTMR + 0x006c) ++#define AR531X_PROCADDR (AR531X_RESETTMR + 0x0070) ++#define AR531X_PROC1 (AR531X_RESETTMR + 0x0074) ++#define AR531X_DMAADDR (AR531X_RESETTMR + 0x0078) ++#define AR531X_DMA1 (AR531X_RESETTMR + 0x007c) ++#define AR531X_ENABLE (AR531X_RESETTMR + 0x0080) /* interface enb */ ++#define AR531X_REV (AR531X_RESETTMR + 0x0090) /* revision */ ++ ++/* AR531X_WD_CTRL register bit field definitions */ ++#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000 ++#define AR531X_WD_CTRL_NMI 0x0001 ++#define AR531X_WD_CTRL_RESET 0x0002 ++ ++/* AR531X_ISR register bit field definitions */ ++#define AR531X_ISR_NONE 0x0000 ++#define AR531X_ISR_TIMER 0x0001 ++#define AR531X_ISR_AHBPROC 0x0002 ++#define AR531X_ISR_AHBDMA 0x0004 ++#define AR531X_ISR_GPIO 0x0008 ++#define AR531X_ISR_UART0 0x0010 ++#define AR531X_ISR_UART0DMA 0x0020 ++#define AR531X_ISR_WD 0x0040 ++#define AR531X_ISR_LOCAL 0x0080 ++ ++/* AR531X_RESET register bit field definitions */ ++#define AR531X_RESET_SYSTEM 0x00000001 /* cold reset full system */ ++#define AR531X_RESET_PROC 0x00000002 /* cold reset MIPS core */ ++#define AR531X_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC and BB */ ++#define AR531X_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ ++#define AR531X_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ ++#define AR531X_RESET_ENET0 0x00000020 /* cold reset ENET0 mac */ ++#define AR531X_RESET_ENET1 0x00000040 /* cold reset ENET1 mac */ ++#define AR531X_RESET_UART0 0x00000100 /* cold reset UART0 (high speed) */ ++#define AR531X_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */ ++#define AR531X_RESET_APB 0x00000400 /* cold reset APB (ar5312) */ ++#define AR531X_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */ ++#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */ ++#define AR531X_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BaseBand */ ++#define AR531X_RESET_NMI 0x00010000 /* send an NMI to the processor */ ++#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 mac */ ++#define AR531X_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 baseband */ ++#define AR531X_RESET_LOCAL_BUS 0x00080000 /* reset local bus */ ++#define AR531X_RESET_WDOG 0x00100000 /* last reset was a watchdog */ ++ ++#define AR531X_RESET_WMAC0_BITS \ ++ AR531X_RESET_WLAN0 |\ ++ AR531X_RESET_WARM_WLAN0_MAC |\ ++ AR531X_RESET_WARM_WLAN0_BB ++ ++#define AR531X_RESERT_WMAC1_BITS \ ++ AR531X_RESET_WLAN1 |\ ++ AR531X_RESET_WARM_WLAN1_MAC |\ ++ AR531X_RESET_WARM_WLAN1_BB ++ ++/* AR5312_CLOCKCTL1 register bit field definitions */ ++#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 ++#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 ++#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 ++#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 ++#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 ++ ++/* Valid for AR5312 and AR2312 */ ++#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 ++#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 ++#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 ++#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 ++#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 ++ ++/* Valid for AR2313 */ ++#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000 ++#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12 ++#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000 ++#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16 ++#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000 ++ ++ ++/* AR531X_ENABLE register bit field definitions */ ++#define AR531X_ENABLE_WLAN0 0x0001 ++#define AR531X_ENABLE_ENET0 0x0002 ++#define AR531X_ENABLE_ENET1 0x0004 ++#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008 /* UART, and WLAN1 PIOs */ ++#define AR531X_ENABLE_WLAN1_DMA 0x0010 /* WLAN1 DMAs */ ++#define AR531X_ENABLE_WLAN1 \ ++ (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA) ++ ++/* AR531X_REV register bit field definitions */ ++#define AR531X_REV_WMAC_MAJ 0xf000 ++#define AR531X_REV_WMAC_MAJ_S 12 ++#define AR531X_REV_WMAC_MIN 0x0f00 ++#define AR531X_REV_WMAC_MIN_S 8 ++#define AR531X_REV_MAJ 0x00f0 ++#define AR531X_REV_MAJ_S 4 ++#define AR531X_REV_MIN 0x000f ++#define AR531X_REV_MIN_S 0 ++#define AR531X_REV_CHIP (REV_MAJ|REV_MIN) ++ ++/* Major revision numbers, bits 7..4 of Revision ID register */ ++#define AR531X_REV_MAJ_AR5312 0x4 ++#define AR531X_REV_MAJ_AR2313 0x5 ++ ++/* Minor revision numbers, bits 3..0 of Revision ID register */ ++#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */ ++#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */ ++ ++/* AR531X_FLASHCTL register bit field definitions */ ++#define FLASHCTL_IDCY 0x0000000f /* Idle cycle turn around time */ ++#define FLASHCTL_IDCY_S 0 ++#define FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ ++#define FLASHCTL_WST1_S 5 ++#define FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ ++#define FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ ++#define FLASHCTL_WST2_S 11 ++#define FLASHCTL_AC 0x00070000 /* Flash address check (added) */ ++#define FLASHCTL_AC_S 16 ++#define FLASHCTL_AC_128K 0x00000000 ++#define FLASHCTL_AC_256K 0x00010000 ++#define FLASHCTL_AC_512K 0x00020000 ++#define FLASHCTL_AC_1M 0x00030000 ++#define FLASHCTL_AC_2M 0x00040000 ++#define FLASHCTL_AC_4M 0x00050000 ++#define FLASHCTL_AC_8M 0x00060000 ++#define FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ ++#define FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ ++#define FLASHCTL_BUSERR 0x01000000 /* Bus transfer error status flag */ ++#define FLASHCTL_WPERR 0x02000000 /* Write protect error status flag */ ++#define FLASHCTL_WP 0x04000000 /* Write protect */ ++#define FLASHCTL_BM 0x08000000 /* Burst mode */ ++#define FLASHCTL_MW 0x30000000 /* Memory width */ ++#define FLASHCTL_MWx8 0x00000000 /* Memory width x8 */ ++#define FLASHCTL_MWx16 0x10000000 /* Memory width x16 */ ++#define FLASHCTL_MWx32 0x20000000 /* Memory width x32 (not supported) */ ++#define FLASHCTL_ATNR 0x00000000 /* Access type == no retry */ ++#define FLASHCTL_ATR 0x80000000 /* Access type == retry every */ ++#define FLASHCTL_ATR4 0xc0000000 /* Access type == retry every 4 */ ++ ++/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices. */ ++#define AR531X_FLASHCTL0 (AR531X_FLASHCTL + 0x00) ++#define AR531X_FLASHCTL1 (AR531X_FLASHCTL + 0x04) ++#define AR531X_FLASHCTL2 (AR531X_FLASHCTL + 0x08) ++ ++/* ARM SDRAM Controller -- just enough to determine memory size */ ++#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04) ++#define MEM_CFG1_AC0 0x00000700 /* bank 0: SDRAM addr check (added) */ ++#define MEM_CFG1_AC0_S 8 ++#define MEM_CFG1_AC1 0x00007000 /* bank 1: SDRAM addr check (added) */ ++#define MEM_CFG1_AC1_S 12 ++ ++/* GPIO Address Map */ ++#define AR531X_GPIO (AR531X_APBBASE + 0x2000) ++#define AR531X_GPIO_DO (AR531X_GPIO + 0x00) /* output register */ ++#define AR531X_GPIO_DI (AR531X_GPIO + 0x04) /* intput register */ ++#define AR531X_GPIO_CR (AR531X_GPIO + 0x08) /* control register */ ++ ++/* GPIO Control Register bit field definitions */ ++#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ ++#define GPIO_CR_O(x) (0 << (x)) /* mask for output */ ++#define GPIO_CR_I(x) (1 << (x)) /* mask for input */ ++#define GPIO_CR_INT(x) (1 << ((x)+8)) /* mask for interrupt */ ++#define GPIO_CR_UART(x) (1 << ((x)+16)) /* uart multiplex */ ++ ++ ++typedef unsigned int AR531X_REG; ++ ++#define sysRegRead(phys) \ ++ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) ++ ++#define sysRegWrite(phys, val) \ ++ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) ++ ++ ++/* ++ * This is board-specific data that is stored in a "fixed" location in flash. ++ * It is shared across operating systems, so it should not be changed lightly. ++ * The main reason we need it is in order to extract the ethernet MAC ++ * address(es). ++ */ ++struct ar531x_boarddata { ++ u32 magic; /* board data is valid */ ++#define AR531X_BD_MAGIC 0x35333131 /* "5311", for all 531x platforms */ ++ u16 cksum; /* checksum (starting with BD_REV 2) */ ++ u16 rev; /* revision of this struct */ ++#define BD_REV 4 ++ char boardName[64]; /* Name of board */ ++ u16 major; /* Board major number */ ++ u16 minor; /* Board minor number */ ++ u32 config; /* Board configuration */ ++#define BD_ENET0 0x00000001 /* ENET0 is stuffed */ ++#define BD_ENET1 0x00000002 /* ENET1 is stuffed */ ++#define BD_UART1 0x00000004 /* UART1 is stuffed */ ++#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ ++#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ ++#define BD_SYSLED 0x00000020 /* System LED stuffed */ ++#define BD_EXTUARTCLK 0x00000040 /* External UART clock */ ++#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ ++#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ ++#define BD_WLAN0 0x00000200 /* Enable WLAN0 */ ++#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ memCap for testing */ ++#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ ++#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ ++#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ ++#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ ++#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ ++#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ ++#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ ++ u16 resetConfigGpio; /* Reset factory GPIO pin */ ++ u16 sysLedGpio; /* System LED GPIO pin */ ++ ++ u32 cpuFreq; /* CPU core frequency in Hz */ ++ u32 sysFreq; /* System frequency in Hz */ ++ u32 cntFreq; /* Calculated C0_COUNT frequency */ ++ ++ u8 wlan0Mac[6]; ++ u8 enet0Mac[6]; ++ u8 enet1Mac[6]; ++ ++ u16 pciId; /* Pseudo PCIID for common code */ ++ u16 memCap; /* cap bank1 in MB */ ++ ++ /* version 3 */ ++ u8 wlan1Mac[6]; /* (ar5212) */ ++}; ++ ++#else ++ ++/* ++ * Address map ++ */ ++#define AR5315_SDRAM0 0x00000000 /* DRAM */ ++#define AR5315_SPI_READ 0x08000000 /* SPI FLASH */ ++#define AR5315_WLAN0 0xB0000000 /* Wireless MMR */ ++#define AR5315_PCI 0xB0100000 /* PCI MMR */ ++#define AR5315_SDRAMCTL 0xB0300000 /* SDRAM MMR */ ++#define AR5315_LOCAL 0xB0400000 /* LOCAL BUS MMR */ ++#define AR5315_ENET0 0xB0500000 /* ETHERNET MMR */ ++#define AR5315_DSLBASE 0xB1000000 /* RESET CONTROL MMR */ ++#define AR5315_UART0 0xB1100003 /* UART MMR */ ++#define AR5315_SPI 0xB1300000 /* SPI FLASH MMR */ ++#define AR5315_FLASHBT 0xBfc00000 /* ro boot alias to FLASH */ ++#define AR5315_RAM1 0x40000000 /* ram alias */ ++#define AR5315_PCIEXT 0x80000000 /* pci external */ ++#define AR5315_RAM2 0xc0000000 /* ram alias */ ++#define AR5315_RAM3 0xe0000000 /* ram alias */ ++ ++/* ++ * Reset Register ++ */ ++#define AR5315_COLD_RESET (AR5315_DSLBASE + 0x0000) ++ ++/* Cold Reset */ ++#define RESET_COLD_AHB 0x00000001 ++#define RESET_COLD_APB 0x00000002 ++#define RESET_COLD_CPU 0x00000004 ++#define RESET_COLD_CPUWARM 0x00000008 ++#define RESET_SYSTEM (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB) /* full system */ ++ ++/* Warm Reset */ ++ ++#define AR5315_RESET (AR5315_DSLBASE + 0x0004) ++ ++#define RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ ++#define RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BaseBand */ ++#define RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ ++#define RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ ++#define RESET_MEMCTL 0x00000010 /* warm reset memory controller */ ++#define RESET_LOCAL 0x00000020 /* warm reset local bus */ ++#define RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ ++#define RESET_SPI 0x00000080 /* warm reset SPI interface */ ++#define RESET_UART0 0x00000100 /* warm reset UART0 */ ++#define RESET_IR_RSVD 0x00000200 /* warm reset IR interface */ ++#define RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ ++#define RESET_ENET0 0x00000800 /* cold reset ENET0 mac */ ++ ++/* ++ * AHB master arbitration control ++ */ ++#define AR5315_AHB_ARB_CTL (AR5315_DSLBASE + 0x0008) ++ ++#define ARB_CPU 0x00000001 /* CPU, default */ ++#define ARB_WLAN 0x00000002 /* WLAN */ ++#define ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ ++#define ARB_LOCAL 0x00000008 /* LOCAL */ ++#define ARB_PCI 0x00000010 /* PCI */ ++#define ARB_ETHERNET 0x00000020 /* Ethernet */ ++#define ARB_RETRY 0x00000100 /* retry policy, debug only */ ++ ++/* ++ * Config Register ++ */ ++#define AR5315_ENDIAN_CTL (AR5315_DSLBASE + 0x000c) ++ ++#define CONFIG_AHB 0x00000001 /* EC - AHB bridge endianess */ ++#define CONFIG_WLAN 0x00000002 /* WLAN byteswap */ ++#define CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */ ++#define CONFIG_PCI 0x00000008 /* PCI byteswap */ ++#define CONFIG_MEMCTL 0x00000010 /* Memory controller endianess */ ++#define CONFIG_LOCAL 0x00000020 /* Local bus byteswap */ ++#define CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ ++ ++#define CONFIG_MERGE 0x00000200 /* CPU write buffer merge */ ++#define CONFIG_CPU 0x00000400 /* CPU big endian */ ++#define CONFIG_PCIAHB 0x00000800 ++#define CONFIG_PCIAHB_BRIDGE 0x00001000 ++#define CONFIG_SPI 0x00008000 /* SPI byteswap */ ++#define CONFIG_CPU_DRAM 0x00010000 ++#define CONFIG_CPU_PCI 0x00020000 ++#define CONFIG_CPU_MMR 0x00040000 ++#define CONFIG_BIG 0x00000400 ++ ++ ++/* ++ * NMI control ++ */ ++#define AR5315_NMI_CTL (AR5315_DSLBASE + 0x0010) ++ ++#define NMI_EN 1 ++ ++/* ++ * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0). ++ */ ++#define AR5315_SREV (AR5315_DSLBASE + 0x0014) ++ ++#define REV_MAJ 0x00f0 ++#define REV_MAJ_S 4 ++#define REV_MIN 0x000f ++#define REV_MIN_S 0 ++#define REV_CHIP (REV_MAJ|REV_MIN) ++ ++/* ++ * Interface Enable ++ */ ++#define AR5315_IF_CTL (AR5315_DSLBASE + 0x0018) ++ ++#define IF_MASK 0x00000007 ++#define IF_DISABLED 0 ++#define IF_PCI 1 ++#define IF_TS_LOCAL 2 ++#define IF_ALL 3 /* only for emulation with separate pins */ ++#define IF_LOCAL_HOST 0x00000008 ++#define IF_PCI_HOST 0x00000010 ++#define IF_PCI_INTR 0x00000020 ++#define IF_PCI_CLK_MASK 0x00030000 ++#define IF_PCI_CLK_INPUT 0 ++#define IF_PCI_CLK_OUTPUT_LOW 1 ++#define IF_PCI_CLK_OUTPUT_CLK 2 ++#define IF_PCI_CLK_OUTPUT_HIGH 3 ++#define IF_PCI_CLK_SHIFT 16 ++ ++ ++/* Major revision numbers, bits 7..4 of Revision ID register */ ++#define REV_MAJ_AR5311 0x01 ++#define REV_MAJ_AR5312 0x04 ++#define REV_MAJ_AR5315 0x0B ++ ++/* ++ * APB Interrupt control ++ */ ++ ++#define AR5315_ISR (AR5315_DSLBASE + 0x0020) ++#define AR5315_IMR (AR5315_DSLBASE + 0x0024) ++#define AR5315_GISR (AR5315_DSLBASE + 0x0028) ++ ++#define ISR_UART0 0x0001 /* high speed UART */ ++#define ISR_I2C_RSVD 0x0002 /* I2C bus */ ++#define ISR_SPI 0x0004 /* SPI bus */ ++#define ISR_AHB 0x0008 /* AHB error */ ++#define ISR_APB 0x0010 /* APB error */ ++#define ISR_TIMER 0x0020 /* timer */ ++#define ISR_GPIO 0x0040 /* GPIO */ ++#define ISR_WD 0x0080 /* watchdog */ ++#define ISR_IR_RSVD 0x0100 /* IR */ ++ ++#define IMR_UART0 ISR_UART0 ++#define IMR_I2C_RSVD ISR_I2C_RSVD ++#define IMR_SPI ISR_SPI ++#define IMR_AHB ISR_AHB ++#define IMR_APB ISR_APB ++#define IMR_TIMER ISR_TIMER ++#define IMR_GPIO ISR_GPIO ++#define IMR_WD ISR_WD ++#define IMR_IR_RSVD ISR_IR_RSVD ++ ++#define GISR_MISC 0x0001 ++#define GISR_WLAN0 0x0002 ++#define GISR_MPEGTS_RSVD 0x0004 ++#define GISR_LOCALPCI 0x0008 ++#define GISR_WMACPOLL 0x0010 ++#define GISR_TIMER 0x0020 ++#define GISR_ETHERNET 0x0040 ++ ++/* ++ * Interrupt routing from IO to the processor IP bits ++ * Define our inter mask and level ++ */ ++#define AR5315_INTR_MISCIO SR_IBIT3 ++#define AR5315_INTR_WLAN0 SR_IBIT4 ++#define AR5315_INTR_ENET0 SR_IBIT5 ++#define AR5315_INTR_LOCALPCI SR_IBIT6 ++#define AR5315_INTR_WMACPOLL SR_IBIT7 ++#define AR5315_INTR_COMPARE SR_IBIT8 ++ ++/* ++ * Timers ++ */ ++#define AR5315_TIMER (AR5315_DSLBASE + 0x0030) ++#define AR5315_RELOAD (AR5315_DSLBASE + 0x0034) ++#define AR5315_WD (AR5315_DSLBASE + 0x0038) ++#define AR5315_WDC (AR5315_DSLBASE + 0x003c) ++ ++#define WDC_RESET 0x00000002 /* reset on watchdog */ ++#define WDC_NMI 0x00000001 /* NMI on watchdog */ ++#define WDC_IGNORE_EXPIRATION 0x00000000 ++ ++/* ++ * Interface Debug ++ */ ++#define AR531X_FLASHDBG (AR531X_RESETTMR + 0x0040) ++#define AR531X_MIIDBG (AR531X_RESETTMR + 0x0044) ++ ++ ++/* ++ * CPU Performance Counters ++ */ ++#define AR5315_PERFCNT0 (AR5315_DSLBASE + 0x0048) ++#define AR5315_PERFCNT1 (AR5315_DSLBASE + 0x004c) ++ ++#define PERF_DATAHIT 0x0001 /* Count Data Cache Hits */ ++#define PERF_DATAMISS 0x0002 /* Count Data Cache Misses */ ++#define PERF_INSTHIT 0x0004 /* Count Instruction Cache Hits */ ++#define PERF_INSTMISS 0x0008 /* Count Instruction Cache Misses */ ++#define PERF_ACTIVE 0x0010 /* Count Active Processor Cycles */ ++#define PERF_WBHIT 0x0020 /* Count CPU Write Buffer Hits */ ++#define PERF_WBMISS 0x0040 /* Count CPU Write Buffer Misses */ ++ ++#define PERF_EB_ARDY 0x0001 /* Count EB_ARdy signal */ ++#define PERF_EB_AVALID 0x0002 /* Count EB_AValid signal */ ++#define PERF_EB_WDRDY 0x0004 /* Count EB_WDRdy signal */ ++#define PERF_EB_RDVAL 0x0008 /* Count EB_RdVal signal */ ++#define PERF_VRADDR 0x0010 /* Count valid read address cycles */ ++#define PERF_VWADDR 0x0020 /* Count valid write address cycles */ ++#define PERF_VWDATA 0x0040 /* Count valid write data cycles */ ++ ++/* ++ * AHB Error Reporting. ++ */ ++#define AR5315_AHB_ERR0 (AR5315_DSLBASE + 0x0050) /* error */ ++#define AR5315_AHB_ERR1 (AR5315_DSLBASE + 0x0054) /* haddr */ ++#define AR5315_AHB_ERR2 (AR5315_DSLBASE + 0x0058) /* hwdata */ ++#define AR5315_AHB_ERR3 (AR5315_DSLBASE + 0x005c) /* hrdata */ ++#define AR5315_AHB_ERR4 (AR5315_DSLBASE + 0x0060) /* status */ ++ ++#define AHB_ERROR_DET 1 /* AHB Error has been detected, */ ++ /* write 1 to clear all bits in ERR0 */ ++#define AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */ ++#define AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */ ++ ++#define PROCERR_HMAST 0x0000000f ++#define PROCERR_HMAST_DFLT 0 ++#define PROCERR_HMAST_WMAC 1 ++#define PROCERR_HMAST_ENET 2 ++#define PROCERR_HMAST_PCIENDPT 3 ++#define PROCERR_HMAST_LOCAL 4 ++#define PROCERR_HMAST_CPU 5 ++#define PROCERR_HMAST_PCITGT 6 ++ ++#define PROCERR_HMAST_S 0 ++#define PROCERR_HWRITE 0x00000010 ++#define PROCERR_HSIZE 0x00000060 ++#define PROCERR_HSIZE_S 5 ++#define PROCERR_HTRANS 0x00000180 ++#define PROCERR_HTRANS_S 7 ++#define PROCERR_HBURST 0x00000e00 ++#define PROCERR_HBURST_S 9 ++ ++ ++ ++/* ++ * Clock Control ++ */ ++#define AR5315_PLLC_CTL (AR5315_DSLBASE + 0x0064) ++#define AR5315_PLLV_CTL (AR5315_DSLBASE + 0x0068) ++#define AR5315_CPUCLK (AR5315_DSLBASE + 0x006c) ++#define AR5315_AMBACLK (AR5315_DSLBASE + 0x0070) ++#define AR5315_SYNCCLK (AR5315_DSLBASE + 0x0074) ++#define AR5315_DSL_SLEEP_CTL (AR5315_DSLBASE + 0x0080) ++#define AR5315_DSL_SLEEP_DUR (AR5315_DSLBASE + 0x0084) ++ ++/* PLLc Control fields */ ++#define PLLC_REF_DIV_M 0x00000003 ++#define PLLC_REF_DIV_S 0 ++#define PLLC_FDBACK_DIV_M 0x0000007C ++#define PLLC_FDBACK_DIV_S 2 ++#define PLLC_ADD_FDBACK_DIV_M 0x00000080 ++#define PLLC_ADD_FDBACK_DIV_S 7 ++#define PLLC_CLKC_DIV_M 0x0001c000 ++#define PLLC_CLKC_DIV_S 14 ++#define PLLC_CLKM_DIV_M 0x00700000 ++#define PLLC_CLKM_DIV_S 20 ++ ++/* CPU CLK Control fields */ ++#define CPUCLK_CLK_SEL_M 0x00000003 ++#define CPUCLK_CLK_SEL_S 0 ++#define CPUCLK_CLK_DIV_M 0x0000000c ++#define CPUCLK_CLK_DIV_S 2 ++ ++/* AMBA CLK Control fields */ ++#define AMBACLK_CLK_SEL_M 0x00000003 ++#define AMBACLK_CLK_SEL_S 0 ++#define AMBACLK_CLK_DIV_M 0x0000000c ++#define AMBACLK_CLK_DIV_S 2 ++ ++#if defined(COBRA_EMUL) ++#define AR5315_AMBA_CLOCK_RATE 20000000 ++#define AR5315_CPU_CLOCK_RATE 40000000 ++#else ++#if defined(DEFAULT_PLL) ++#define AR5315_AMBA_CLOCK_RATE 40000000 ++#define AR5315_CPU_CLOCK_RATE 40000000 ++#else ++#define AR5315_AMBA_CLOCK_RATE 92000000 ++#define AR5315_CPU_CLOCK_RATE 184000000 ++#endif /* ! DEFAULT_PLL */ ++#endif /* ! COBRA_EMUL */ ++ ++#define AR5315_UART_CLOCK_RATE AR5315_AMBA_CLOCK_RATE ++#define AR5315_SDRAM_CLOCK_RATE AR5315_AMBA_CLOCK_RATE ++ ++/* ++ * The UART computes baud rate as: ++ * baud = clock / (16 * divisor) ++ * where divisor is specified as a High Byte (DLM) and a Low Byte (DLL). ++ */ ++#define DESIRED_BAUD_RATE 38400 ++ ++/* ++ * The WATCHDOG value is computed as ++ * 10 seconds * AR531X_WATCHDOG_CLOCK_RATE ++ */ ++#define DESIRED_WATCHDOG_SECONDS 10 ++#define AR531X_WATCHDOG_TIME \ ++ (DESIRED_WATCHDOG_SECONDS * AR531X_WATCHDOG_CLOCK_RATE) ++ ++ ++#define CLOCKCTL_UART0 0x0010 /* enable UART0 external clock */ ++ ++ ++ /* ++ * Applicable "PCICFG" bits for WLAN(s). Assoc status and LED mode. ++ */ ++#define AR531X_PCICFG (AR531X_RESETTMR + 0x00b0) ++#define ASSOC_STATUS_M 0x00000003 ++#define ASSOC_STATUS_NONE 0 ++#define ASSOC_STATUS_PENDING 1 ++#define ASSOC_STATUS_ASSOCIATED 2 ++#define LED_MODE_M 0x0000001c ++#define LED_BLINK_THRESHOLD_M 0x000000e0 ++#define LED_SLOW_BLINK_MODE 0x00000100 ++ ++/* ++ * GPIO ++ */ ++ ++#define AR5315_GPIO_DI (AR5315_DSLBASE + 0x0088) ++#define AR5315_GPIO_DO (AR5315_DSLBASE + 0x0090) ++#define AR5315_GPIO_CR (AR5315_DSLBASE + 0x0098) ++#define AR5315_GPIO_INT (AR5315_DSLBASE + 0x00a0) ++ ++#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ ++#define GPIO_CR_O(x) (1 << (x)) /* output */ ++#define GPIO_CR_I(x) (0 << (x)) /* input */ ++ ++#define GPIO_INT(x,Y) ((x) << (8 * (Y))) /* interrupt enable */ ++#define GPIO_INT_M(Y) ((0x3F) << (8 * (Y))) /* mask for int */ ++#define GPIO_INT_LVL(x,Y) ((x) << (8 * (Y) + 6)) /* interrupt level */ ++#define GPIO_INT_LVL_M(Y) ((0x3) << (8 * (Y) + 6)) /* mask for int level */ ++ ++#define AR5315_RESET_GPIO 5 ++#define AR5315_NUM_GPIO 22 ++ ++ ++/* ++ * PCI Clock Control ++ */ ++ ++#define AR5315_PCICLK (AR5315_DSLBASE + 0x00a4) ++ ++#define PCICLK_INPUT_M 0x3 ++#define PCICLK_INPUT_S 0 ++ ++#define PCICLK_PLLC_CLKM 0 ++#define PCICLK_PLLC_CLKM1 1 ++#define PCICLK_PLLC_CLKC 2 ++#define PCICLK_REF_CLK 3 ++ ++#define PCICLK_DIV_M 0xc ++#define PCICLK_DIV_S 2 ++ ++#define PCICLK_IN_FREQ 0 ++#define PCICLK_IN_FREQ_DIV_6 1 ++#define PCICLK_IN_FREQ_DIV_8 2 ++#define PCICLK_IN_FREQ_DIV_10 3 ++ ++/* ++ * Observation Control Register ++ */ ++#define AR5315_OCR (AR5315_DSLBASE + 0x00b0) ++#define OCR_GPIO0_IRIN 0x0040 ++#define OCR_GPIO1_IROUT 0x0080 ++#define OCR_GPIO3_RXCLR 0x0200 ++ ++/* ++ * General Clock Control ++ */ ++ ++#define AR5315_MISCCLK (AR5315_DSLBASE + 0x00b4) ++#define MISCCLK_PLLBYPASS_EN 0x00000001 ++#define MISCCLK_PROCREFCLK 0x00000002 ++ ++/* ++ * SDRAM Controller ++ * - No read or write buffers are included. ++ */ ++#define AR5315_MEM_CFG (AR5315_SDRAMCTL + 0x00) ++#define AR5315_MEM_CTRL (AR5315_SDRAMCTL + 0x0c) ++#define AR5315_MEM_REF (AR5315_SDRAMCTL + 0x10) ++ ++#define SDRAM_DATA_WIDTH_M 0x00006000 ++#define SDRAM_DATA_WIDTH_S 13 ++ ++#define SDRAM_COL_WIDTH_M 0x00001E00 ++#define SDRAM_COL_WIDTH_S 9 ++ ++#define SDRAM_ROW_WIDTH_M 0x000001E0 ++#define SDRAM_ROW_WIDTH_S 5 ++ ++#define SDRAM_BANKADDR_BITS_M 0x00000018 ++#define SDRAM_BANKADDR_BITS_S 3 ++ ++ ++/* ++ * SDRAM Memory Refresh (MEM_REF) value is computed as: ++ * MEMCTL_SREFR = (Tr * hclk_freq) / R ++ * where Tr is max. time of refresh of any single row ++ * R is number of rows in the DRAM ++ * For most 133MHz SDRAM parts, Tr=64ms, R=4096 or 8192 ++ */ ++#if defined(COBRA_EMUL) ++#define AR5315_SDRAM_MEMORY_REFRESH_VALUE 0x96 ++#else ++#if defined(DEFAULT_PLL) ++#define AR5315_SDRAM_MEMORY_REFRESH_VALUE 0x200 ++#else ++#define AR5315_SDRAM_MEMORY_REFRESH_VALUE 0x61a ++#endif /* ! DEFAULT_PLL */ ++#endif ++ ++#if defined(AR5315) ++ ++#define AR5315_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ ++#define AR5315_SDRAM_DATA_WIDTH 16 /* bits */ ++#define AR5315_SDRAM_COL_WIDTH 8 ++#define AR5315_SDRAM_ROW_WIDTH 12 ++ ++#else ++ ++#define AR5315_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ ++#define AR5315_SDRAM_DATA_WIDTH 16 ++#define AR5315_SDRAM_COL_WIDTH 8 ++#define AR5315_SDRAM_ROW_WIDTH 12 ++ ++#endif /* ! AR5315 */ ++ ++/* ++ * SPI Flash Interface Registers ++ */ ++ ++#define AR5315_SPI_CTL (AR5315_SPI + 0x00) ++#define AR5315_SPI_OPCODE (AR5315_SPI + 0x04) ++#define AR5315_SPI_DATA (AR5315_SPI + 0x08) ++ ++#define SPI_CTL_START 0x00000100 ++#define SPI_CTL_BUSY 0x00010000 ++#define SPI_CTL_TXCNT_MASK 0x0000000f ++#define SPI_CTL_RXCNT_MASK 0x000000f0 ++#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff ++#define SPI_CTL_SIZE_MASK 0x00060000 ++ ++#define SPI_CTL_CLK_SEL_MASK 0x03000000 ++#define SPI_OPCODE_MASK 0x000000ff ++ ++/* ++ * PCI-MAC Configuration registers ++ */ ++#define PCI_MAC_RC (AR5315_PCI + 0x4000) ++#define PCI_MAC_SCR (AR5315_PCI + 0x4004) ++#define PCI_MAC_INTPEND (AR5315_PCI + 0x4008) ++#define PCI_MAC_SFR (AR5315_PCI + 0x400C) ++#define PCI_MAC_PCICFG (AR5315_PCI + 0x4010) ++#define PCI_MAC_SREV (AR5315_PCI + 0x4020) ++ ++#define PCI_MAC_RC_MAC 0x00000001 ++#define PCI_MAC_RC_BB 0x00000002 ++ ++#define PCI_MAC_SCR_SLMODE_M 0x00030000 ++#define PCI_MAC_SCR_SLMODE_S 16 ++#define PCI_MAC_SCR_SLM_FWAKE 0 ++#define PCI_MAC_SCR_SLM_FSLEEP 1 ++#define PCI_MAC_SCR_SLM_NORMAL 2 ++ ++#define PCI_MAC_SFR_SLEEP 0x00000001 ++ ++#define PCI_MAC_PCICFG_SPWR_DN 0x00010000 ++ ++ ++ ++ ++/* ++ * PCI Bus Interface Registers ++ */ ++#define AR5315_PCI_1MS_REG (AR5315_PCI + 0x0008) ++#define AR5315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ ++ ++#define AR5315_PCI_MISC_CONFIG (AR5315_PCI + 0x000c) ++#define AR5315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ ++#define AR5315_PCIMISC_CFG_SEL 0x00000002 /* mem or config cycles */ ++#define AR5315_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */ ++#define AR5315_PCIMISC_RST_MODE 0x00000030 ++#define AR5315_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */ ++#define AR5315_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */ ++#define AR5315_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */ ++#define AR5315_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */ ++#define AR5315_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */ ++#define AR5315_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */ ++#define AR5315_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */ ++#define AR5315_PCICACHE_DIS 0x00001000 /* PCI external access cache disable */ ++ ++#define AR5315_PCI_OUT_TSTAMP (AR5315_PCI + 0x0010) ++ ++#define AR5315_PCI_UNCACHE_CFG (AR5315_PCI + 0x0014) ++ ++#define AR5315_PCI_IN_EN (AR5315_PCI + 0x0100) ++#define AR5315_PCI_IN_EN0 0x01 /* Enable chain 0 */ ++#define AR5315_PCI_IN_EN1 0x02 /* Enable chain 1 */ ++#define AR5315_PCI_IN_EN2 0x04 /* Enable chain 2 */ ++#define AR5315_PCI_IN_EN3 0x08 /* Enable chain 3 */ ++ ++#define AR5315_PCI_IN_DIS (AR5315_PCI + 0x0104) ++#define AR5315_PCI_IN_DIS0 0x01 /* Disable chain 0 */ ++#define AR5315_PCI_IN_DIS1 0x02 /* Disable chain 1 */ ++#define AR5315_PCI_IN_DIS2 0x04 /* Disable chain 2 */ ++#define AR5315_PCI_IN_DIS3 0x08 /* Disable chain 3 */ ++ ++#define AR5315_PCI_IN_PTR (AR5315_PCI + 0x0200) ++ ++#define AR5315_PCI_OUT_EN (AR5315_PCI + 0x0400) ++#define AR5315_PCI_OUT_EN0 0x01 /* Enable chain 0 */ ++ ++#define AR5315_PCI_OUT_DIS (AR5315_PCI + 0x0404) ++#define AR5315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ ++ ++#define AR5315_PCI_OUT_PTR (AR5315_PCI + 0x0408) ++ ++#define AR5315_PCI_INT_STATUS (AR5315_PCI + 0x0500) /* write one to clr */ ++#define AR5315_PCI_TXINT 0x00000001 /* Desc In Completed */ ++#define AR5315_PCI_TXOK 0x00000002 /* Desc In OK */ ++#define AR5315_PCI_TXERR 0x00000004 /* Desc In ERR */ ++#define AR5315_PCI_TXEOL 0x00000008 /* Desc In End-of-List */ ++#define AR5315_PCI_RXINT 0x00000010 /* Desc Out Completed */ ++#define AR5315_PCI_RXOK 0x00000020 /* Desc Out OK */ ++#define AR5315_PCI_RXERR 0x00000040 /* Desc Out ERR */ ++#define AR5315_PCI_RXEOL 0x00000080 /* Desc Out EOL */ ++#define AR5315_PCI_TXOOD 0x00000200 /* Desc In Out-of-Desc */ ++#define AR5315_PCI_MASK 0x0000FFFF /* Desc Mask */ ++#define AR5315_PCI_EXT_INT 0x02000000 ++#define AR5315_PCI_ABORT_INT 0x04000000 ++ ++#define AR5315_PCI_INT_MASK (AR5315_PCI + 0x0504) /* same as INT_STATUS */ ++ ++#define AR5315_PCI_INTEN_REG (AR5315_PCI + 0x0508) ++#define AR5315_PCI_INT_DISABLE 0x00 /* disable pci interrupts */ ++#define AR5315_PCI_INT_ENABLE 0x01 /* enable pci interrupts */ ++ ++#define AR5315_PCI_HOST_IN_EN (AR5315_PCI + 0x0800) ++#define AR5315_PCI_HOST_IN_DIS (AR5315_PCI + 0x0804) ++#define AR5315_PCI_HOST_IN_PTR (AR5315_PCI + 0x0810) ++#define AR5315_PCI_HOST_OUT_EN (AR5315_PCI + 0x0900) ++#define AR5315_PCI_HOST_OUT_DIS (AR5315_PCI + 0x0904) ++#define AR5315_PCI_HOST_OUT_PTR (AR5315_PCI + 0x0908) ++ ++ ++/* ++ * Local Bus Interface Registers ++ */ ++#define AR5315_LB_CONFIG (AR5315_LOCAL + 0x0000) ++#define AR5315_LBCONF_OE 0x00000001 /* =1 OE is low-true */ ++#define AR5315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */ ++#define AR5315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */ ++#define AR5315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */ ++#define AR5315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */ ++#define AR5315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */ ++#define AR5315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */ ++#define AR5315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */ ++#define AR5315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */ ++#define AR5315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */ ++#define AR5315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */ ++#define AR5315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */ ++#define AR5315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */ ++#define AR5315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */ ++#define AR5315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */ ++#define AR5315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */ ++#define AR5315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */ ++#define AR5315_LBCONF_INT 0x00020000 /* =1 Intr is low true */ ++#define AR5315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */ ++#define AR5315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */ ++#define AR5315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */ ++#define AR5315_LBCONF_INT_CTR3 0x000C0000 /* GND drive, Vdd drive */ ++#define AR5315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */ ++#define AR5315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */ ++#define AR5315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */ ++ ++#define AR5315_LB_CLKSEL (AR5315_LOCAL + 0x0004) ++#define AR5315_LBCLK_EXT 0x0001 /* use external clk for lb */ ++ ++#define AR5315_LB_1MS (AR5315_LOCAL + 0x0008) ++#define AR5315_LB1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ ++ ++#define AR5315_LB_MISCCFG (AR5315_LOCAL + 0x000C) ++#define AR5315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */ ++#define AR5315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */ ++#define AR5315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */ ++#define AR5315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */ ++#define AR5315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */ ++#define AR5315_LBM_TIMEOUT_MASK 0x00FFFF80 ++#define AR5315_LBM_TIMEOUT_SHFT 7 ++#define AR5315_LBM_PORTMUX 0x07000000 ++ ++ ++#define AR5315_LB_RXTSOFF (AR5315_LOCAL + 0x0010) ++ ++#define AR5315_LB_TX_CHAIN_EN (AR5315_LOCAL + 0x0100) ++#define AR5315_LB_TXEN_0 0x01 ++#define AR5315_LB_TXEN_1 0x02 ++#define AR5315_LB_TXEN_2 0x04 ++#define AR5315_LB_TXEN_3 0x08 ++ ++#define AR5315_LB_TX_CHAIN_DIS (AR5315_LOCAL + 0x0104) ++#define AR5315_LB_TX_DESC_PTR (AR5315_LOCAL + 0x0200) ++ ++#define AR5315_LB_RX_CHAIN_EN (AR5315_LOCAL + 0x0400) ++#define AR5315_LB_RXEN 0x01 ++ ++#define AR5315_LB_RX_CHAIN_DIS (AR5315_LOCAL + 0x0404) ++#define AR5315_LB_RX_DESC_PTR (AR5315_LOCAL + 0x0408) ++ ++#define AR5315_LB_INT_STATUS (AR5315_LOCAL + 0x0500) ++#define AR5315_INT_TX_DESC 0x0001 ++#define AR5315_INT_TX_OK 0x0002 ++#define AR5315_INT_TX_ERR 0x0004 ++#define AR5315_INT_TX_EOF 0x0008 ++#define AR5315_INT_RX_DESC 0x0010 ++#define AR5315_INT_RX_OK 0x0020 ++#define AR5315_INT_RX_ERR 0x0040 ++#define AR5315_INT_RX_EOF 0x0080 ++#define AR5315_INT_TX_TRUNC 0x0100 ++#define AR5315_INT_TX_STARVE 0x0200 ++#define AR5315_INT_LB_TIMEOUT 0x0400 ++#define AR5315_INT_LB_ERR 0x0800 ++#define AR5315_INT_MBOX_WR 0x1000 ++#define AR5315_INT_MBOX_RD 0x2000 ++ ++/* Bit definitions for INT MASK are the same as INT_STATUS */ ++#define AR5315_LB_INT_MASK (AR5315_LOCAL + 0x0504) ++ ++#define AR5315_LB_INT_EN (AR5315_LOCAL + 0x0508) ++#define AR5315_LB_MBOX (AR5315_LOCAL + 0x0600) ++ ++ ++ ++/* ++ * IR Interface Registers ++ */ ++#define AR5315_IR_PKTDATA (AR5315_IR + 0x0000) ++ ++#define AR5315_IR_PKTLEN (AR5315_IR + 0x07fc) /* 0 - 63 */ ++ ++#define AR5315_IR_CONTROL (AR5315_IR + 0x0800) ++#define AR5315_IRCTL_TX 0x00000000 /* use as tranmitter */ ++#define AR5315_IRCTL_RX 0x00000001 /* use as receiver */ ++#define AR5315_IRCTL_SAMPLECLK_MASK 0x00003ffe /* Sample clk divisor mask */ ++#define AR5315_IRCTL_SAMPLECLK_SHFT 1 ++#define AR5315_IRCTL_OUTPUTCLK_MASK 0x03ffc000 /* Output clk divisor mask */ ++#define AR5315_IRCTL_OUTPUTCLK_SHFT 14 ++ ++#define AR5315_IR_STATUS (AR5315_IR + 0x0804) ++#define AR5315_IRSTS_RX 0x00000001 /* receive in progress */ ++#define AR5315_IRSTS_TX 0x00000002 /* transmit in progress */ ++ ++#define AR5315_IR_CONFIG (AR5315_IR + 0x0808) ++#define AR5315_IRCFG_INVIN 0x00000001 /* invert input polarity */ ++#define AR5315_IRCFG_INVOUT 0x00000002 /* invert output polarity */ ++#define AR5315_IRCFG_SEQ_START_WIN_SEL 0x00000004 /* 1 => 28, 0 => 7 */ ++#define AR5315_IRCFG_SEQ_START_THRESH 0x000000f0 /* */ ++#define AR5315_IRCFG_SEQ_END_UNIT_SEL 0x00000100 /* */ ++#define AR5315_IRCFG_SEQ_END_UNIT_THRESH 0x00007e00 /* */ ++#define AR5315_IRCFG_SEQ_END_WIN_SEL 0x00008000 /* */ ++#define AR5315_IRCFG_SEQ_END_WIN_THRESH 0x001f0000 /* */ ++#define AR5315_IRCFG_NUM_BACKOFF_WORDS 0x01e00000 /* */ ++ ++/* ++ * PCI memory constants: Memory area 1 and 2 are the same size - ++ * (twice the PCI_TLB_PAGE_SIZE). The definition of ++ * CPU_TO_PCI_MEM_SIZE is coupled with the TLB setup routine ++ * sysLib.c/sysTlbInit(), in that it assumes that 2 pages of size ++ * PCI_TLB_PAGE_SIZE are set up in the TLB for each PCI memory space. ++ */ ++ ++#define CPU_TO_PCI_MEM_BASE1 0xE0000000 ++#define CPU_TO_PCI_MEM_SIZE1 (2*PCI_TLB_PAGE_SIZE) ++ ++ ++/* TLB attributes for PCI transactions */ ++ ++#define PCI_MMU_PAGEMASK 0x00003FFF ++#define MMU_PAGE_UNCACHED 0x00000010 ++#define MMU_PAGE_DIRTY 0x00000004 ++#define MMU_PAGE_VALID 0x00000002 ++#define MMU_PAGE_GLOBAL 0x00000001 ++#define PCI_MMU_PAGEATTRIB (MMU_PAGE_UNCACHED|MMU_PAGE_DIRTY|\ ++ MMU_PAGE_VALID|MMU_PAGE_GLOBAL) ++#define PCI_MEMORY_SPACE1_VIRT 0xE0000000 /* Used for non-prefet mem */ ++#define PCI_MEMORY_SPACE1_PHYS 0x80000000 ++#define PCI_TLB_PAGE_SIZE 0x01000000 ++#define TLB_HI_MASK 0xFFFFE000 ++#define TLB_LO_MASK 0x3FFFFFFF ++#define PAGEMASK_SHIFT 11 ++#define TLB_LO_SHIFT 6 ++ ++#define PCI_MAX_LATENCY 0xFFF /* Max PCI latency */ ++ ++#define HOST_PCI_DEV_ID 3 ++#define HOST_PCI_MBAR0 0x10000000 ++#define HOST_PCI_MBAR1 0x20000000 ++#define HOST_PCI_MBAR2 0x30000000 ++ ++#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1 ++#define PCI_DEVICE_MEM_SPACE 0x800000 ++ ++ ++typedef unsigned int AR531X_REG; ++ ++#define sysRegRead(phys) \ ++ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) ++ ++#define sysRegWrite(phys, val) \ ++ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) ++#endif ++ ++#endif +diff -urN linux-mips/arch/mips/ar531x/ar531xintr.S mips-linux-2.4.25/arch/mips/ar531x/ar531xintr.S +--- linux-mips/arch/mips/ar531x/ar531xintr.S 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xintr.S 2005-12-30 17:26:31.000823952 +0000 +@@ -0,0 +1,30 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * Glue code to save registers and get us to the interrupt dispatcher ++ */ ++ .text ++ .set noat ++ .align 5 ++NESTED(ar531x_interrupt_receive, PT_SIZE, sp) ++ SAVE_ALL ++ CLI ++ .set at ++ ++ move a0, sp ++ jal ar531x_irq_dispatch ++ ++ j ret_from_irq ++ ++ END(ar531x_interrupt_receive) +diff -urN linux-mips/arch/mips/ar531x/ar531xirq.c mips-linux-2.4.25/arch/mips/ar531x/ar531xirq.c +--- linux-mips/arch/mips/ar531x/ar531xirq.c 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xirq.c 2005-12-30 17:26:31.000823952 +0000 +@@ -0,0 +1,442 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Interrupt support for AR531X WiSOC. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++#include ++ ++extern int setup_irq(unsigned int irq, struct irqaction *irqaction); ++ ++static void ar531x_misc_intr_enable(unsigned int irq); ++static void ar531x_misc_intr_disable(unsigned int irq); ++ ++/* Turn on the specified AR531X_MISC_IRQ interrupt */ ++static unsigned int ++ar531x_misc_intr_startup(unsigned int irq) ++{ ++ ar531x_misc_intr_enable(irq); ++ return 0; ++} ++ ++/* Turn off the specified AR531X_MISC_IRQ interrupt */ ++static void ++ar531x_misc_intr_shutdown(unsigned int irq) ++{ ++ ar531x_misc_intr_disable(irq); ++} ++ ++/* Enable the specified AR531X_MISC_IRQ interrupt */ ++static void ++ar531x_misc_intr_enable(unsigned int irq) ++{ ++ unsigned int imr; ++ ++#if CONFIG_AR5315 ++ imr = sysRegRead(AR5315_IMR); ++ switch(irq) ++ { ++ case AR531X_MISC_IRQ_TIMER: ++ imr |= IMR_TIMER; ++ break; ++ ++ case AR531X_MISC_IRQ_AHB_PROC: ++ imr |= IMR_AHB; ++ break; ++ ++ case AR531X_MISC_IRQ_AHB_DMA: ++ imr |= 0/* ?? */; ++ break; ++ /* ++ case AR531X_ISR_GPIO: ++ imr |= IMR_GPIO; ++ break; ++ */ ++ ++ case AR531X_MISC_IRQ_UART0: ++ imr |= IMR_UART0; ++ break; ++ ++ ++ case AR531X_MISC_IRQ_WATCHDOG: ++ imr |= IMR_WD; ++ break; ++ ++ case AR531X_MISC_IRQ_LOCAL: ++ imr |= 0/* ?? */; ++ break; ++ ++ } ++ sysRegWrite(AR5315_IMR, imr); ++ imr=sysRegRead(AR5315_IMR); /* flush write buffer */ ++ //printk("enable Interrupt irq 0x%x imr 0x%x \n",irq,imr); ++ ++#else ++ imr = sysRegRead(AR531X_IMR); ++ imr |= (1 << (irq - AR531X_MISC_IRQ_BASE - 1)); ++ sysRegWrite(AR531X_IMR, imr); ++ sysRegRead(AR531X_IMR); /* flush write buffer */ ++#endif ++} ++ ++/* Disable the specified AR531X_MISC_IRQ interrupt */ ++static void ++ar531x_misc_intr_disable(unsigned int irq) ++{ ++ unsigned int imr; ++ ++#if CONFIG_AR5315 ++ imr = sysRegRead(AR5315_IMR); ++ switch(irq) ++ { ++ case AR531X_MISC_IRQ_TIMER: ++ imr &= (~IMR_TIMER); ++ break; ++ ++ case AR531X_MISC_IRQ_AHB_PROC: ++ imr &= (~IMR_AHB); ++ break; ++ ++ case AR531X_MISC_IRQ_AHB_DMA: ++ imr &= 0/* ?? */; ++ break; ++ /* ++ case AR531X_ISR_GPIO: ++ imr &= ~IMR_GPIO; ++ break; ++ */ ++ ++ case AR531X_MISC_IRQ_UART0: ++ imr &= (~IMR_UART0); ++ break; ++ ++ case AR531X_MISC_IRQ_WATCHDOG: ++ imr &= (~IMR_WD); ++ break; ++ ++ case AR531X_MISC_IRQ_LOCAL: ++ imr &= ~0/* ?? */; ++ break; ++ ++ } ++ sysRegWrite(AR5315_IMR, imr); ++ sysRegRead(AR5315_IMR); /* flush write buffer */ ++#else ++ imr = sysRegRead(AR531X_IMR); ++ imr &= ~(1 << (irq - AR531X_MISC_IRQ_BASE - 1)); ++ sysRegWrite(AR531X_IMR, imr); ++ sysRegRead(AR531X_IMR); /* flush write buffer */ ++#endif ++} ++ ++static void ++ar531x_misc_intr_ack(unsigned int irq) ++{ ++ ar531x_misc_intr_disable(irq); ++} ++ ++static void ++ar531x_misc_intr_end(unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) ++ ar531x_misc_intr_enable(irq); ++} ++ ++static void ++ar531x_misc_intr_set_affinity(unsigned int irq, unsigned long mask) ++{ ++ /* Only 1 CPU; ignore affinity request */ ++} ++ ++struct hw_interrupt_type ar531x_misc_intr_controller = { ++ "AR531X MISC", ++ ar531x_misc_intr_startup, ++ ar531x_misc_intr_shutdown, ++ ar531x_misc_intr_enable, ++ ar531x_misc_intr_disable, ++ ar531x_misc_intr_ack, ++ ar531x_misc_intr_end, ++ ar531x_misc_intr_set_affinity, ++}; ++ ++int ar531x_misc_irq_base; ++ ++/* ++ * Determine interrupt source among interrupts that use IP6 ++ */ ++void ++ar531x_misc_intr_init(int irq_base) ++{ ++ int i; ++ ++ for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = NULL; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &ar531x_misc_intr_controller; ++ } ++ ++ ar531x_misc_irq_base = irq_base; ++} ++ ++/* ARGSUSED */ ++void ++spurious_irq_handler(int cpl, void *dev_id, struct pt_regs *regs) ++{ ++ /* ++ printk("spurious_irq_handler: %d cause=0x%8.8x status=0x%8.8x\n", ++ cpl, cause_intrs, status_intrs); ++ */ ++} ++ ++/* ARGSUSED */ ++void ++spurious_misc_handler(int cpl, void *dev_id, struct pt_regs *regs) ++{ ++ /* ++ printk("spurious_misc_handler: 0x%x isr=0x%8.8x imr=0x%8.8x\n", ++ cpl, ar531x_isr, ar531x_imr); ++ */ ++} ++ ++void ++ar531x_timer_handler(int cpl, void *dev_id, struct pt_regs *regs) ++{ ++#if CONFIG_AR5315 ++ (void)sysRegRead(AR5315_TIMER); /* clear interrupt */ ++#else ++ (void)sysRegRead(AR531X_TIMER); /* clear interrupt */ ++#endif ++} ++ ++void ++ar531x_ahb_proc_handler(int cpl, void *dev_id, struct pt_regs *regs) ++{ ++ u32 procAddr; ++ u32 proc1; ++ u32 dmaAddr; ++ u32 dma1; ++#if CONFIG_AR5315 ++ sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); ++ sysRegRead(AR5315_AHB_ERR1); ++#else ++ proc1 = sysRegRead(AR531X_PROC1); ++ procAddr = sysRegRead(AR531X_PROCADDR); /* clears error state */ ++ dma1 = sysRegRead(AR531X_DMA1); ++ dmaAddr = sysRegRead(AR531X_DMAADDR); /* clears error state */ ++#endif ++ ++ printk("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n", ++ procAddr, proc1, dmaAddr, dma1); ++ ++ machine_restart("AHB error"); /* Catastrophic failure */ ++} ++ ++static struct irqaction cascade = ++ {no_action, SA_INTERRUPT, 0, "cascade", ++ NULL, NULL}; ++ ++static struct irqaction spurious_irq = ++ {spurious_irq_handler, SA_INTERRUPT, 0, "spurious_irq", ++ NULL, NULL}; ++ ++static struct irqaction spurious_misc = ++ {spurious_misc_handler, SA_INTERRUPT, 0, "spurious_misc", ++ NULL, NULL}; ++ ++static struct irqaction ar531x_timer_interrupt = ++ {ar531x_timer_handler, SA_INTERRUPT, 0, "ar531x_timer_interrupt", ++ NULL, NULL}; ++ ++static struct irqaction ar531x_ahb_proc_interrupt = ++ {ar531x_ahb_proc_handler, SA_INTERRUPT, 0, "ar531x_ahb_proc_interrupt", ++ NULL, NULL}; ++ ++extern asmlinkage void ar531x_interrupt_receive(void); ++ ++/* ++ * Called when an interrupt is received, this function ++ * determines exactly which interrupt it was, and it ++ * invokes the appropriate handler. ++ * ++ * Implicitly, we also define interrupt priority by ++ * choosing which to dispatch first. ++ */ ++extern void dump_uart(void *); ++ ++#if CONFIG_AR5315 ++ ++void ++ar531x_irq_dispatch(struct pt_regs *regs) ++{ ++ int cause_intrs = regs->cp0_cause; ++ int status_intrs = regs->cp0_status; ++ int pending = cause_intrs & status_intrs; ++ ++ if (pending & CAUSEF_IP3) { ++ do_IRQ(AR531X_IRQ_WLAN0_INTRS, regs); ++ } ++ else if (pending & CAUSEF_IP4) { ++ do_IRQ(AR531X_IRQ_ENET0_INTRS, regs); ++ } ++ else if (pending & CAUSEF_IP2) { ++ AR531X_REG ar531x_isr = sysRegRead(AR5315_ISR); ++ AR531X_REG ar531x_imr = sysRegRead(AR5315_IMR); ++ unsigned int ar531x_misc_intrs = ar531x_isr & ar531x_imr; ++ ++ if (ar531x_misc_intrs & ISR_TIMER) ++ do_IRQ(AR531X_MISC_IRQ_TIMER, regs); ++ else if (ar531x_misc_intrs & ISR_AHB) ++ do_IRQ(AR531X_MISC_IRQ_AHB_PROC, regs); ++ else if (ar531x_misc_intrs & ISR_GPIO) ++ { ++ int i; ++ u32 gpioIntPending; ++ ++ gpioIntPending = sysRegRead(AR5315_GPIO_DI) & gpioIntMask; ++ for (i=0; icp0_epc); ++ } ++#endif /* CONFIG_KGDB */ ++ } ++ else if (ar531x_misc_intrs & ISR_WD) ++ do_IRQ(AR531X_MISC_IRQ_WATCHDOG, regs); ++ else ++ do_IRQ(AR531X_MISC_IRQ_NONE, regs); ++ } else if (pending & CAUSEF_IP7) { ++ do_IRQ(AR531X_IRQ_CPU_CLOCK, regs); ++ } ++ else { ++ do_IRQ(AR531X_IRQ_NONE, regs); ++ } ++} ++ ++#else ++ ++void ++ar531x_irq_dispatch(struct pt_regs *regs) ++{ ++ int cause_intrs = regs->cp0_cause; ++ int status_intrs = regs->cp0_status; ++ int pending = cause_intrs & status_intrs; ++ ++ if (pending & CAUSEF_IP2) { ++ do_IRQ(AR531X_IRQ_WLAN0_INTRS, regs); ++ } ++ else if (pending & CAUSEF_IP3) { ++ do_IRQ(AR531X_IRQ_ENET0_INTRS, regs); ++ } ++ else if (pending & CAUSEF_IP4) { ++ do_IRQ(AR531X_IRQ_ENET1_INTRS, regs); ++ } ++ else if (pending & CAUSEF_IP5) { ++ do_IRQ(AR531X_IRQ_WLAN1_INTRS, regs); ++ } ++ else if (pending & CAUSEF_IP6) { ++ AR531X_REG ar531x_isr = sysRegRead(AR531X_ISR); ++ AR531X_REG ar531x_imr = sysRegRead(AR531X_IMR); ++ unsigned int ar531x_misc_intrs = ar531x_isr & ar531x_imr; ++ ++ if (ar531x_misc_intrs & AR531X_ISR_TIMER) ++ do_IRQ(AR531X_MISC_IRQ_TIMER, regs); ++ else if (ar531x_misc_intrs & AR531X_ISR_AHBPROC) ++ do_IRQ(AR531X_MISC_IRQ_AHB_PROC, regs); ++ else if (ar531x_misc_intrs & AR531X_ISR_AHBDMA) ++ do_IRQ(AR531X_MISC_IRQ_AHB_DMA, regs); ++ else if (ar531x_misc_intrs & AR531X_ISR_GPIO) ++ { ++ int i; ++ u32 gpioIntPending; ++ ++ gpioIntPending = sysRegRead(AR531X_GPIO_DI) & gpioIntMask; ++ for (i=0; icp0_epc); ++ } ++#endif /* CONFIG_KGDB */ ++ } ++ else if (ar531x_misc_intrs & AR531X_ISR_WD) ++ do_IRQ(AR531X_MISC_IRQ_WATCHDOG, regs); ++ else if (ar531x_misc_intrs & AR531X_ISR_LOCAL) ++ do_IRQ(AR531X_MISC_IRQ_LOCAL, regs); ++ else ++ do_IRQ(AR531X_MISC_IRQ_NONE, regs); ++ } else if (pending & CAUSEF_IP7) { ++ do_IRQ(AR531X_IRQ_CPU_CLOCK, regs); ++ } else ++ do_IRQ(AR531X_IRQ_NONE, regs); ++} ++ ++#endif ++ ++void __init init_IRQ(void) ++{ ++ init_generic_irq(); ++ set_except_vector(0, ar531x_interrupt_receive); ++ ++ /* Initialize interrupt controllers */ ++ mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); ++ ar531x_misc_intr_init(AR531X_MISC_IRQ_BASE); ++ ar531x_gpio_intr_init(AR531X_GPIO_IRQ_BASE); ++ setup_irq(AR531X_IRQ_MISC_INTRS, &cascade); ++ /* ++ * AR531X_IRQ_CPU_CLOCK is setup by ar531x_timer_setup. ++ */ ++ ++ /* Default "spurious interrupt" handlers */ ++ setup_irq(AR531X_IRQ_NONE, &spurious_irq); ++ setup_irq(AR531X_MISC_IRQ_NONE, &spurious_misc); ++ setup_irq(AR531X_GPIO_IRQ_NONE, &spurious_gpio); ++#ifndef CONFIG_AR5315 ++ setup_irq(AR531X_MISC_IRQ_TIMER, &ar531x_timer_interrupt); ++#endif ++ setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar531x_ahb_proc_interrupt); ++ setup_irq(AR531X_MISC_IRQ_GPIO, &cascade); ++ ++#ifdef CONFIG_KGDB ++#if CONFIG_EARLY_STOP ++ kgdbInit(); ++#endif ++#endif ++} +diff -urN linux-mips/arch/mips/ar531x/ar531xksyms.c mips-linux-2.4.25/arch/mips/ar531x/ar531xksyms.c +--- linux-mips/arch/mips/ar531x/ar531xksyms.c 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xksyms.c 2005-12-30 17:26:31.001823800 +0000 +@@ -0,0 +1,17 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++#include ++#include "asm/atheros/ar531xbsp.h" ++ ++#ifdef CONFIG_KGDB ++EXPORT_SYMBOL(kgdbInit); ++EXPORT_SYMBOL(kgdbEnabled); ++#endif ++EXPORT_SYMBOL(ar531x_sys_frequency); ++EXPORT_SYMBOL(get_system_type); +diff -urN linux-mips/arch/mips/ar531x/ar531xlnx.h mips-linux-2.4.25/arch/mips/ar531x/ar531xlnx.h +--- linux-mips/arch/mips/ar531x/ar531xlnx.h 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xlnx.h 2005-12-30 17:26:31.001823800 +0000 +@@ -0,0 +1,135 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * This file contains definitions needed in order to compile ++ * AR531X products for linux. Definitions that are largely ++ * AR531X-specific and independent of operating system belong ++ * in ar531x.h rather than this file. ++ */ ++#include "ar531x.h" ++ ++#define MIPS_CPU_IRQ_BASE 0x00 ++#define AR531X_HIGH_PRIO 0x10 ++#define AR531X_MISC_IRQ_BASE 0x20 ++#define AR531X_GPIO_IRQ_BASE 0x30 ++ ++/* Software's idea of interrupts handled by "CPU Interrupt Controller" */ ++#if CONFIG_AR5315 ++#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 ++#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ ++#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ ++#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ ++#define AR531X_IRQ_LCBUS_PCI MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ ++#define AR531X_IRQ_WLAN0_POLL MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ ++#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ ++#else ++#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 ++#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ ++#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ ++#define AR531X_IRQ_ENET1_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ ++#define AR531X_IRQ_WLAN1_INTRS MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */ ++#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ ++#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ ++#endif ++/* Miscellaneous interrupts, which share IP6 */ ++#define AR531X_MISC_IRQ_NONE AR531X_MISC_IRQ_BASE+0 ++#define AR531X_MISC_IRQ_TIMER AR531X_MISC_IRQ_BASE+1 ++#define AR531X_MISC_IRQ_AHB_PROC AR531X_MISC_IRQ_BASE+2 ++#define AR531X_MISC_IRQ_AHB_DMA AR531X_MISC_IRQ_BASE+3 ++#define AR531X_MISC_IRQ_GPIO AR531X_MISC_IRQ_BASE+4 ++#define AR531X_MISC_IRQ_UART0 AR531X_MISC_IRQ_BASE+5 ++#define AR531X_MISC_IRQ_UART0_DMA AR531X_MISC_IRQ_BASE+6 ++#define AR531X_MISC_IRQ_WATCHDOG AR531X_MISC_IRQ_BASE+7 ++#define AR531X_MISC_IRQ_LOCAL AR531X_MISC_IRQ_BASE+8 ++#define AR531X_MISC_IRQ_COUNT 9 ++ ++/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */ ++#define AR531X_GPIO_IRQ_NONE AR531X_MISC_IRQ_BASE+0 ++#define AR531X_GPIO_IRQ(n) AR531X_MISC_IRQ_BASE+(n)+1 ++#ifdef CONFIG_AR5315 ++#define AR531X_GPIO_IRQ_COUNT 2 ++#else ++#define AR531X_GPIO_IRQ_COUNT 9 ++#endif ++ ++#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr) ++#define PHYS_TO_K0(physaddr) KSEG0ADDR(physaddr) ++#define UNMAPPED_TO_PHYS(vaddr) PHYSADDR(vaddr) ++#define IS_UNMAPPED_VADDR(vaddr) \ ++ ((KSEGX(vaddr) == KSEG0) || (KSEGX(vaddr) == KSEG1)) ++ ++/* IOCTL commands for /proc/ar531x */ ++#define AR531X_CTRL_DO_BREAKPOINT 1 ++#define AR531X_CTRL_DO_MADWIFI 2 ++ ++/* ++ * Definitions for operating system portability. ++ * These are vxWorks-->Linux translations. ++ */ ++#define LOCAL static ++#define BOOL int ++#define TRUE 1 ++#define FALSE 0 ++#define UINT8 u8 ++#define UINT16 u16 ++#define UINT32 u32 ++#define PRINTF printk ++#if /* DEBUG */ 1 ++#define DEBUG_PRINTF printk ++#define INLINE ++#else ++DEBUG_PRINTF while (0) printk ++#define INLINE inline ++#endif ++#define sysUDelay(usecs) udelay(usecs) ++#define sysMsDelay(msecs) mdelay(msecs) ++typedef volatile UINT8 *VIRT_ADDR; ++#define MALLOC(sz) kmalloc(sz, GFP_KERNEL) ++#define MALLOC_NOSLEEP(sz) kmalloc(sz, GFP_ATOMIC) ++#define FREE(ptr) kfree((void *)ptr) ++#define BSP_BUG() do { printk("kernel BSP BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) ++#define BSP_BUG_ON(condition) do { if (unlikely((condition)!=0)) BSP_BUG(); } while(0) ++#define ASSERT(x) BSP_BUG_ON(!(x)) ++ ++extern struct ar531x_boarddata *ar531x_board_configuration; ++extern char *ar531x_radio_configuration; ++extern char *enet_mac_address_get(int MACUnit); ++ ++extern void kgdbInit(void); ++extern int kgdbEnabled(void); ++extern void breakpoint(void); ++extern int kgdbInterrupt(void); ++extern unsigned int ar531x_cpu_frequency(void); ++extern unsigned int ar531x_sys_frequency(void); ++ ++/* GPIO support */ ++extern struct irqaction spurious_gpio; ++extern unsigned int gpioIntMask; ++extern void ar531x_gpio_intr_init(int irq_base); ++extern void ar531x_gpio_ctrl_output(int gpio); ++extern void ar531x_gpio_ctrl_input(int gpio); ++extern void ar531x_gpio_set(int gpio, int val); ++extern int ar531x_gpio_get(int gpio); ++extern void ar531x_gpio_intr_enable(unsigned int irq); ++extern void ar531x_gpio_intr_disable(unsigned int irq); ++ ++/* Watchdog Timer support */ ++extern int watchdog_start(unsigned int milliseconds); ++extern int watchdog_stop(void); ++extern int watchdog_is_enabled(void); ++extern unsigned int watchdog_min_timer_reached(void); ++extern void watchdog_notify_alive(void); ++ ++#define A_DATA_CACHE_INVAL(start, length) \ ++ dma_cache_inv((UINT32)(start),(length)) ++ ++#define sysWbFlush() mb() ++ ++#define intDisable(x) cli() ++#define intEnable(x) sti() +diff -urN linux-mips/arch/mips/ar531x/ar531xprom.c mips-linux-2.4.25/arch/mips/ar531x/ar531xprom.c +--- linux-mips/arch/mips/ar531x/ar531xprom.c 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xprom.c 2005-12-30 17:26:31.001823800 +0000 +@@ -0,0 +1,88 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright MontaVista Software Inc ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Prom setup file for ar531x ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "ar531xlnx.h" ++ ++#define COMMAND_LINE_SIZE 512 ++ ++char arcs_cmdline[COMMAND_LINE_SIZE]; ++ ++void __init prom_init(int argc, char *argv[]) ++{ ++ int i; ++ unsigned int memcfg1; ++ int bank0AC, bank1AC; ++ int memsz_in_mb; ++ strcpy(arcs_cmdline, "console=ttyS0,9600"); ++ for (i=0; i> MEM_CFG1_AC0_S; ++ bank1AC = (memcfg1 & MEM_CFG1_AC1) >> MEM_CFG1_AC1_S; ++ memsz_in_mb = (bank0AC ? (1 << (bank0AC+1)) : 0) ++ + (bank1AC ? (1 << (bank1AC+1)) : 0); ++#endif ++ ++ /* ++ * By default, use all available memory. You can override this ++ * to use, say, 8MB by specifying "mem=8M" as an argument on the ++ * linux bootup command line. ++ */ ++ add_memory_region(0, memsz_in_mb << 20, BOOT_MEM_RAM); ++} ++ ++void __init prom_free_prom_memory(void) ++{ ++} +diff -urN linux-mips/arch/mips/ar531x/ar531xsetup.c mips-linux-2.4.25/arch/mips/ar531x/ar531xsetup.c +--- linux-mips/arch/mips/ar531x/ar531xsetup.c 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/ar531xsetup.c 2005-12-30 17:26:31.002823648 +0000 +@@ -0,0 +1,406 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Initialization for ar531x SOC. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++ ++void ++ar531x_restart(char *command) ++{ ++ for(;;) { ++#if CONFIG_AR5315 ++ /* ++ ** Cold reset does not work,work around is to use the GPIO reset bit. ++ */ ++ unsigned int reg; ++ reg = sysRegRead(AR5315_GPIO_DO); ++ reg &= ~(1 << AR5315_RESET_GPIO); ++ sysRegWrite(AR5315_GPIO_DO, reg); ++ (void)sysRegRead(AR5315_GPIO_DO); /* flush write to hardware */ ++ ++#else ++ sysRegWrite(AR531X_RESET, AR531X_RESET_SYSTEM); ++#endif ++ } ++} ++ ++void ++ar531x_halt(void) ++{ ++ printk(KERN_NOTICE "\n** You can safely turn off the power\n"); ++ while (1); ++} ++ ++void ++ar531x_power_off(void) ++{ ++ ar531x_halt(); ++} ++ ++const char * ++get_system_type(void) ++{ ++#if CONFIG_AR5315 ++ return "Atheros AR5315"; ++#else ++ return "Atheros AR531X"; ++#endif ++} ++ ++/* ++ * This table is indexed by bits 5..4 of the CLOCKCTL1 register ++ * to determine the predevisor value. ++ */ ++static int CLOCKCTL1_PREDIVIDE_TABLE[4] = { ++ 1, ++ 2, ++ 4, ++ 5 ++}; ++ ++#if CONFIG_AR5315 ++static int PLLC_DIVIDE_TABLE[5] = { ++ 2, ++ 3, ++ 4, ++ 6, ++ 3 ++}; ++ ++unsigned int ++ar531x_cpu_frequency(void) ++{ ++ static unsigned int ar531x_calculated_cpu_freq=0; ++ unsigned int clockCtl,pllcCtrl,cpuDiv; ++ unsigned int pllcOut,refdiv,fdiv,divby2; ++ ++ if(ar531x_calculated_cpu_freq) ++ return ar531x_calculated_cpu_freq; ++ ++ ++ pllcCtrl = sysRegRead(AR5315_PLLC_CTL); ++ refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S; ++ refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv]; ++ fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S; ++ divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S; ++ divby2 += 1; ++ pllcOut = (40000000/refdiv)*(2*divby2)*fdiv; ++ ++ clockCtl = sysRegRead(AR5315_CPUCLK); ++ ++ /* clkm input selected */ ++ if((clockCtl & CPUCLK_CLK_SEL_M) == 0 || (clockCtl & CPUCLK_CLK_SEL_M) == 1 ) { ++ unsigned int clkMdiv; ++ clkMdiv = (pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S; ++ clkMdiv = PLLC_DIVIDE_TABLE[clkMdiv]; ++ ++ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; ++ if(cpuDiv) cpuDiv *= 2; ++ else cpuDiv=1; ++ ++ ar531x_calculated_cpu_freq= (pllcOut/(clkMdiv * cpuDiv)) ; ++ ++ return ar531x_calculated_cpu_freq; ++ } ++ ++ /* clkc input selected */ ++ if((clockCtl & CPUCLK_CLK_SEL_M) == 2 ) { ++ unsigned int clkCdiv; ++ clkCdiv = (pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S; ++ clkCdiv = PLLC_DIVIDE_TABLE[clkCdiv]; ++ ++ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; ++ if(cpuDiv) cpuDiv *= 2; ++ else cpuDiv=1; ++ ++ ar531x_calculated_cpu_freq= (pllcOut/(clkCdiv * cpuDiv)) ; ++ ++ return ar531x_calculated_cpu_freq; ++ } else { /* ref_clk selected */ ++ ++ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; ++ if(cpuDiv) cpuDiv *= 2; ++ else cpuDiv=1; ++ ++ ar531x_calculated_cpu_freq= (40000000/(cpuDiv)) ; ++ return ar531x_calculated_cpu_freq; ++ } ++} ++ ++unsigned int ++ar531x_apb_frequency(void) ++{ ++ static unsigned int ar531x_calculated_cpu_freq=0; ++ unsigned int clockCtl,pllcCtrl,cpuDiv; ++ unsigned int pllcOut,refdiv,fdiv,divby2; ++ ++ if(ar531x_calculated_cpu_freq) ++ return ar531x_calculated_cpu_freq; ++ ++ ++ pllcCtrl = sysRegRead(AR5315_PLLC_CTL); ++ refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S; ++ refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv]; ++ fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S; ++ divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S; ++ divby2 += 1; ++ pllcOut = (40000000/refdiv)*(2*divby2)*fdiv; ++ ++ clockCtl = sysRegRead(AR5315_AMBACLK); ++ ++ /* clkm input selected */ ++ if((clockCtl & CPUCLK_CLK_SEL_M) == 0 || (clockCtl & CPUCLK_CLK_SEL_M) == 1 ) { ++ unsigned int clkMdiv; ++ clkMdiv = (pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S; ++ clkMdiv = PLLC_DIVIDE_TABLE[clkMdiv]; ++ ++ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; ++ if(cpuDiv) cpuDiv *= 2; ++ else cpuDiv=1; ++ ++ ar531x_calculated_cpu_freq= (pllcOut/(clkMdiv * cpuDiv)) ; ++ ++ return ar531x_calculated_cpu_freq; ++ } ++ ++ /* clkc input selected */ ++ if((clockCtl & CPUCLK_CLK_SEL_M) == 2 ) { ++ unsigned int clkCdiv; ++ clkCdiv = (pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S; ++ clkCdiv = PLLC_DIVIDE_TABLE[clkCdiv]; ++ ++ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; ++ if(cpuDiv) cpuDiv *= 2; ++ else cpuDiv=1; ++ ++ ar531x_calculated_cpu_freq= (pllcOut/(clkCdiv * cpuDiv)) ; ++ ++ return ar531x_calculated_cpu_freq; ++ } else { /* ref_clk selected */ ++ ++ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; ++ if(cpuDiv) cpuDiv *= 2; ++ else cpuDiv=1; ++ ++ ar531x_calculated_cpu_freq= (40000000/(cpuDiv)) ; ++ return ar531x_calculated_cpu_freq; ++ } ++} ++ ++#else ++unsigned int ++ar531x_cpu_frequency(void) ++{ ++ static unsigned int ar531x_calculated_cpu_freq; ++ unsigned int clockctl1_predivide_mask; ++ unsigned int clockctl1_predivide_shift; ++ unsigned int clockctl1_multiplier_mask; ++ unsigned int clockctl1_multiplier_shift; ++ unsigned int clockctl1_doubler_mask; ++ int wisoc_revision; ++ ++ /* ++ * Trust the bootrom's idea of cpu frequency. ++ */ ++ ar531x_calculated_cpu_freq = sysRegRead(AR5312_SCRATCH); ++ if (ar531x_calculated_cpu_freq) ++ return ar531x_calculated_cpu_freq; ++ ++ wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S; ++ ++ if (wisoc_revision == AR531X_REV_MAJ_AR2313) { ++ clockctl1_predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; ++ clockctl1_predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; ++ clockctl1_multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; ++ clockctl1_multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; ++ clockctl1_doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; ++ } else { /* AR5312 and AR2312 */ ++ clockctl1_predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; ++ clockctl1_predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; ++ clockctl1_multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; ++ clockctl1_multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; ++ clockctl1_doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; ++ } ++ ++ /* ++ * Clocking is derived from a fixed 40MHz input clock. ++ * cpuFreq = InputClock * MULT (where MULT is PLL multiplier) ++ * ++ * sysFreq = cpuFreq / 4 (used for APB clock, serial, ++ * flash, Timer, Watchdog Timer) ++ * ++ * cntFreq = cpuFreq / 2 (use for CPU count/compare) ++ * ++ * So, for example, with a PLL multiplier of 5, we have ++ * cpuFrez = 200MHz ++ * sysFreq = 50MHz ++ * cntFreq = 100MHz ++ * ++ * We compute the CPU frequency, based on PLL settings. ++ */ ++ if (ar531x_calculated_cpu_freq == 0) { ++ unsigned int clockCtl1 = sysRegRead(AR5312_CLOCKCTL1); ++ ++ int preDivideSelect = (clockCtl1 & clockctl1_predivide_mask) >> ++ clockctl1_predivide_shift; ++ ++ int preDivisor = CLOCKCTL1_PREDIVIDE_TABLE[preDivideSelect]; ++ ++ int multiplier = (clockCtl1 & clockctl1_multiplier_mask) >> ++ clockctl1_multiplier_shift; ++ ++ if (clockCtl1 & clockctl1_doubler_mask) { ++ multiplier = multiplier << 1; ++ } ++ ++ ar531x_calculated_cpu_freq = (40000000 / preDivisor) * multiplier; ++ } ++ ++ return ar531x_calculated_cpu_freq; ++} ++#endif ++ ++unsigned int ++ar531x_sys_frequency(void) ++{ ++ static unsigned int ar531x_calculated_sys_freq = 0; ++ ++ if (ar531x_calculated_sys_freq == 0) { ++ ar531x_calculated_sys_freq = ar531x_cpu_frequency() / 4; ++ } ++ ++ return ar531x_calculated_sys_freq; ++} ++ ++static void __init ++flash_setup(void) ++{ ++ UINT32 flash_ctl; ++#ifndef CONFIG_AR5315 ++ /* Configure flash bank 0 */ ++ flash_ctl = FLASHCTL_E | ++ FLASHCTL_AC_8M | ++ FLASHCTL_RBLE | ++ (0x01 << FLASHCTL_IDCY_S) | ++ (0x07 << FLASHCTL_WST1_S) | ++ (0x07 << FLASHCTL_WST2_S) | ++ (sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MW); ++ ++ sysRegWrite(AR531X_FLASHCTL0, flash_ctl); ++ ++ /* Disable other flash banks */ ++ sysRegWrite(AR531X_FLASHCTL1, ++ sysRegRead(AR531X_FLASHCTL1) & ~(FLASHCTL_E | FLASHCTL_AC)); ++ ++ sysRegWrite(AR531X_FLASHCTL2, ++ sysRegRead(AR531X_FLASHCTL2) & ~(FLASHCTL_E | FLASHCTL_AC)); ++#endif ++} ++ ++ ++ ++void __init ++serial_setup(void) ++{ ++ struct serial_struct s; ++ ++ memset(&s, 0, sizeof(s)); ++ ++ s.flags = STD_COM_FLAGS; ++ s.io_type = SERIAL_IO_MEM; ++#if CONFIG_AR5315 ++ s.baud_base = ar531x_apb_frequency()/16; ++#else ++ s.baud_base = ar531x_sys_frequency()/16; ++#endif ++ s.irq = AR531X_MISC_IRQ_UART0; ++ s.iomem_reg_shift = 2; ++#if CONFIG_AR5315 ++ s.iomem_base = (u8 *)AR5315_UART0; ++#else ++ s.iomem_base = (u8 *)AR531X_UART0; ++#endif ++ ++ if (early_serial_setup(&s) != 0) ++ printk(KERN_ERR "early_serial_setup failed\n"); ++} ++ ++extern int setup_irq(unsigned int irq, struct irqaction *irqaction); ++static void __init ++ar531x_timer_setup(struct irqaction *irq) ++{ ++ unsigned int count; ++ ++ /* Usually irq is timer_irqaction (timer_interrupt) */ ++ setup_irq(AR531X_IRQ_CPU_CLOCK, irq); ++ ++ /* to generate the first CPU timer interrupt */ ++ count = read_c0_count(); ++ write_c0_compare(count + 1000); ++} ++ ++extern void (*board_time_init)(void); ++ ++static void __init ++ar531x_time_init(void) ++{ ++ mips_hpt_frequency = ar531x_cpu_frequency() / 2; ++} ++ ++void __init ++ar531x_setup(void) ++{ ++ /* Clear any lingering AHB errors */ ++#if CONFIG_AR5315 ++ unsigned int config = read_c0_config(); ++ write_c0_config(config & ~0x3); ++ sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); ++ sysRegRead(AR5315_AHB_ERR1); ++ sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION); ++#else ++ sysRegRead(AR531X_PROCADDR); ++ sysRegRead(AR531X_DMAADDR); ++ ++ sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION); ++ ++#endif ++ ++ /* Disable data watchpoints */ ++ write_c0_watchlo0(0); ++ ++ board_time_init = ar531x_time_init; ++ board_timer_setup = ar531x_timer_setup; ++ ++ _machine_restart = ar531x_restart; ++ _machine_halt = ar531x_halt; ++ _machine_power_off = ar531x_power_off; ++ ++ flash_setup(); ++ serial_setup(); ++} +diff -urN linux-mips/arch/mips/ar531x/Makefile mips-linux-2.4.25/arch/mips/ar531x/Makefile +--- linux-mips/arch/mips/ar531x/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/Makefile 2005-12-30 17:26:29.912989328 +0000 +@@ -0,0 +1,33 @@ ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++# ++ ++# Makefile for Atheros ar531x boards ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++ ++.S.s: ++ $(CPP) $(CFLAGS) $< -o $*.s ++.S.o: ++ $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o ++ ++O_TARGET:= ar531x.o ++ ++export-objs = ar531xksyms.o ++ ++obj-y := ar531xdbg_io.o \ ++ ar531xsetup.o \ ++ ar531xprom.o \ ++ ar531xirq.o \ ++ ar531xintr.o \ ++ ar531xgpio.o \ ++ ar531xksyms.o ++ ++include $(TOPDIR)/Rules.make +diff -urN linux-mips/arch/mips/ar531x/README mips-linux-2.4.25/arch/mips/ar531x/README +--- linux-mips/arch/mips/ar531x/README 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/README 2005-12-30 17:26:30.478903296 +0000 +@@ -0,0 +1,68 @@ ++Basic information for the AR531X Board Support Package ++ ++This directory contains the "LBSP" -- Linux Board Support Package -- ++for Linux on the Atheros AR531X Wireless System-On-a-Chip. It is intended ++primarily as a building block for wireless products. At this time, the ++AR531X Linux BSP is experimental code, and is actively UNDER CONSTRUCTION. ++ ++Some components that are supported by this LBSP along with a standard 2.4 ++Linux MIPS kernel include ++ R4Kc CPU ++ instruction and data caches ++ SDRAM ++ flash (Macronix, AMD, STS, etc.) ++ 16550 serial port ++ ethernet MACs ++ ethernet PHY or PHY Switch (RealTek, Kendin, Marvell) ++ General-Purpose I/O pins ++ kernel debugging with kgdb ++ ++This LBSP code does NOT include drivers for the wireless components of the ++chip/boards! Drivers for those components may be distributed separately. ++In particular, the MADWiFi project under SourceForge supports (not yet!) ++wireless functions on the AR531X chipset. See ++ http://www.sourceforge.net/projects/madwifi ++ ++Files included in this BSP: ++ae531xlnx.c - Linux-specific portions of the ethernet driver ++ae531xmac.c - OS-independent AR531X ethernet MAC code ++ae531xmac.h - OS-independent AR531X ethernet MAC software definitions ++ae531xreg.h - OS-independent AR531X ethernet MAC hardware definitions ++ar531x.h - OS-independent AR531X system hardware definitions ++ar531xlnx.h - Linux-specific AR531X system definitions and externs ++defconfig-ar531x - Default Linux configuration file ++intr_recv.S - Linux interrupt "glue" code ++ar531xirq.c - Linux Interrupt Request management ++Makefile - Linux makefile ++mvPhy.c - OS-independent ethernet PHY code for Marvell Switch ++mvPhy.h - OS-independent ethernet PHY definitions for Marvell Switch ++ar531xprom.c - Linux prom "glue" code ++ar531xsetup.c - Linux startup code ++ar531xdbg_io.c - Support for kgdb-based debugging and for EARLY_PRINTK_HACK ++ar531xproc.c - Pseudo-device driver for /proc/ar531x device ++ar531xgpio.c - Support for General Purpose I/O pins ++ar531xwmacsl.c - Wireless MAC Support Layer ++ ++Additional files, distributed with the BSP: ++README - This file ++README.BUILD - Instructions for building a linux kernel from source ++README.EXECUTE - Instructions for testing your linux kernel ++README.RAMDISK - Instructions for building a root ramdisk image ++ ++ramdisk.gz - A binary ramdisk image, suitable for use with AR531X. ++DIFFS - Directory that contains "patch" files (See README.BUILD) ++ ++ ++There are several ways to boot a vmlinux image on an AR531X board: ++ -You can boot in over ethernet from the vxWorks bootrom, which is preloaded ++ on all Atheros boards ++ -You can use an ICE (e.g. VisionICE) to load the vmlinux image. You will ++ need appropriate register initialization (e.g. AP30.ini file) ++ -You can use the eCos RedBoot bootrom loader. This is a full-featured ++ bootrom which as been ported to AR531x. It can boot vmlinux over ethernet ++ or from flash. Source code is available from Atheros. ++ ++Please send comments, corrections, complaints, criticisms, suggestions, ++enhancements, requests, or any other reasonable communications regarding ++this effort, to "linux@atheros.com". Your email will be received by a ++couple of engineers, and redirected as appropriate. +diff -urN linux-mips/arch/mips/ar531x/README.BUILD mips-linux-2.4.25/arch/mips/ar531x/README.BUILD +--- linux-mips/arch/mips/ar531x/README.BUILD 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/README.BUILD 2005-12-30 17:26:30.478903296 +0000 +@@ -0,0 +1,47 @@ ++ How to BUILD a linux kernel for an AR531X system ++ ++It is expected that you will build Linux on an existing Linux system, which ++has all of the standard Linux tools. ++ ++01) Obtain a MIPS BigEndian ELF gcc-compatible toolchain. For example, ++ if you're cross-compiling on a x86 Linux system, you could use: ++ ftp://ftp.mips.com/pub/tools/software/sde-for-linux/sdelinux-5.01-4eb.i386.rpm ++ ++02) Obtain the latest working MIPS Linux kernel ++ cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs login (password "cvs") ++ cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs co -r linux_2_4 linux ++ ++ Now "cd linux". The remainder of these instructions assume ++ that you are in the linux directory. ++ ++03) Place the contents of this directory at arch/mips/ar531x. ++ ++04) Use the patch command to patch generic linux files according ++ to the DIFFS directory ++ for i in arch/mips/ar531x/DIFFS/*.diff ++ do ++ patch -p1 < $i ++ done ++ NOTE: This version of the AR531X Linux BSP was tested with ++ MIPS Linux 2.4.22 as of 11/14/03. If you use a different ++ (e.g. more recent) version of Linux source, you may need to ++ resolve some minor patch and compilation issues. ++ ++05) Set up a RAMDISK image. ++ See the instructions in README.RAMDISK. ++ ++06) Set up a linux configuration using ar531x/defconfig-ar531x. ++ cp arch/mips/ar531x/defconfig-ar531x .config ++ make oldconfig (answer all questions that are asked) ++ NOTE: For development/debug purposes, you may want to ++ enable CONFIG_RUNTIME_DEBUG and CONFIG_KGDB. ++ ++07) Make dependencies. ++ make dep ++ ++08) Build the linux kernel ++ make ++ ++09) The linux image you just built is in vmlinux. ++ See instructions in README.EXECUTE to run your vmlinux ++ image on an AP531X-based board. +diff -urN linux-mips/arch/mips/ar531x/README.EXECUTE mips-linux-2.4.25/arch/mips/ar531x/README.EXECUTE +--- linux-mips/arch/mips/ar531x/README.EXECUTE 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/README.EXECUTE 2005-12-30 17:26:30.479903144 +0000 +@@ -0,0 +1,23 @@ ++ How to EXECUTE a linux image on an AR531X system ++ ++There are currently three ways to run you vmlinux image: ++ 1) Load it using the vxWorks bootrom that is supplied with the board. ++ You can load it over ethernet or from the TFFS file system, if you ++ have sufficient flash to store the image. ++ 2) Load it using an ICE (e.g. VisionICE). ++ 3) Use a bootrom loader, such as eCos RedBoot. ++ ++After you have booted linux: ++ By default, the root filesystem on ramdisk is read-only. ++ To make it writable, use "mount -o remount w /". ++ ++ The user-level commands are slightly non-standard, as they ++ are based on "busybox". ++ ++ The "wget" command is included. You can use wget to fetch ++ files from any ftp server. So, for instance, you can fetch ++ a kernel module and then "insmod" it. ++ ++Note that the standard source-level kernel debugger, kgdb, works well ++over the serial line with this port. We use kgdb and the kgdb_demux perl ++script -- available over the www -- for debugging. +diff -urN linux-mips/arch/mips/ar531x/README.VERSION mips-linux-2.4.25/arch/mips/ar531x/README.VERSION +--- linux-mips/arch/mips/ar531x/README.VERSION 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/arch/mips/ar531x/README.VERSION 2005-12-30 17:26:30.479903144 +0000 +@@ -0,0 +1 @@ ++Source release last modified: 12/16/03 +diff -urN linux-mips/arch/mips/config-shared.in mips-linux-2.4.25/arch/mips/config-shared.in +--- linux-mips/arch/mips/config-shared.in 2005-12-24 15:11:15.963885864 +0000 ++++ mips-linux-2.4.25/arch/mips/config-shared.in 2005-12-30 17:26:31.611731080 +0000 +@@ -34,6 +34,7 @@ + dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy PB1200 board' CONFIG_MIPS_PB1200 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32 ++dep_bool 'Support for Atheros AR5312/AR2312 WiSoC (EXPERIMENTAL)' CONFIG_AR531X $CONFIG_AR531X $CONFIG_EXPERIMENTAL + dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32 + dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32 + dep_bool 'Support for Cogent CSB250 board' CONFIG_COGENT_CSB250 $CONFIG_MIPS32 +@@ -238,6 +239,63 @@ + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_OLD_TIME_C y + fi ++if [ "$CONFIG_AR531X" = "y" ]; then ++ define_bool CONFIG_IRQ_CPU y ++ define_bool CONFIG_CPU_R4X00 y ++ define_bool CONFIG_SERIAL y ++ define_bool CONFIG_NEW_IRQ y ++ define_bool CONFIG_NEW_TIME_C y ++ define_bool CONFIG_AR5312 ++ define_bool CONFIG_NONCOHERENT_IO y ++ bool 'Enable early printk hack' CONFIG_EARLY_PRINTK_HACK ++ define_bool CONFIG_SCSI n ++ mainmenu_option next_comment ++ comment 'Board selection' ++ choice 'Board type' \ ++ "UNKNOWN CONFIG_APUNKNOWN \ ++ AP30 CONFIG_AP30 \ ++ AP31 CONFIG_AP31 \ ++ AP33 CONFIG_AP33 \ ++ AP38 CONFIG_AP38 \ ++ AP43 CONFIG_AP43 \ ++ AP48 CONFIG_AP48 \ ++ AP51 CONFIG_AP51 \ ++ AP30-ASK CONFIG_AP30ASK" AP30 ++ if [ "$CONFIG_AP30" = "y" -o "$CONFIG_AP30ASK" = "y" ]; then ++ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 2 ++ fi ++ if [ "$CONFIG_AP33" = "y" ]; then ++ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 ++ fi ++ if [ "$CONFIG_AP38" = "y" ]; then ++ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 ++ fi ++ if [ "$CONFIG_AP43" = "y" ]; then ++ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 ++ fi ++ if [ "$CONFIG_AP48" = "y" ]; then ++ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 ++ fi ++ if [ "$CONFIG_AP51" = "y" ]; then ++ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 ++ define_bool CONFIG_MTD_REDBOOT_PARTS y ++ define_bool CONFIG_AR5315 y ++ define_bool CONFIG_MTD_SPIFLASH y ++ define_bool CONFIG_MTD_CFI n ++ define_bool CONFIG_MTD_JEDECPROBE n ++ define_bool CONFIG_MTD_CFI_INTELEXT n ++ define_bool CONFIG_MTD_CFI_AMDSTD n ++ define_bool CONFIG_MTD_OBSOLETE_CHIPS n ++ define_bool CONFIG_MTD_AMDSTD n ++ define_bool CONFIG_MTD_JEDEC n ++ define_bool CONFIG_MTD_PHYSMAP n ++ fi ++ mainmenu_option next_comment ++ comment 'Flash Selection' ++ choice 'Flash Size' \ ++ "2MB CONFIG_FLASH_2MB \ ++ 4MB CONFIG_FLASH_4MB" 2MB ++fi + if [ "$CONFIG_CASIO_E55" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + +diff -urN linux-mips/arch/mips/kernel/setup.c mips-linux-2.4.25/arch/mips/kernel/setup.c +--- linux-mips/arch/mips/kernel/setup.c 2005-12-24 15:11:16.188851664 +0000 ++++ mips-linux-2.4.25/arch/mips/kernel/setup.c 2005-12-30 17:26:33.536438480 +0000 +@@ -496,6 +496,7 @@ + void hp_setup(void); + void au1x00_setup(void); + void frame_info_init(void); ++ void ar531x_setup(void); + + frame_info_init(); + #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) +@@ -693,6 +694,12 @@ + pmc_yosemite_setup(); + break; + #endif ++ ++#ifdef CONFIG_AR531X ++ case MACH_GROUP_AR531X: ++ ar531x_setup(); ++ break; ++#endif + default: + panic("Unsupported architecture"); + } +diff -urN linux-mips/arch/mips/Makefile mips-linux-2.4.25/arch/mips/Makefile +--- linux-mips/arch/mips/Makefile 2005-12-24 15:11:15.903894984 +0000 ++++ mips-linux-2.4.25/arch/mips/Makefile 2005-12-30 17:26:29.911989480 +0000 +@@ -701,6 +701,17 @@ + LOADADDR += 0x80020000 + endif + ++ifdef CONFIG_AR531X ++SUBDIRS += arch/mips/ar531x ++LIBS += arch/mips/ar531x/ar531x.o ++ifdef CONFIG_AP51 ++LOADADDR += 0x80041000 ++else ++LOADADDR += 0x80002000 ++endif ++ ++endif ++ + # + # Choosing incompatible machines durings configuration will result in + # error messages during linking. Select a default linkscript if +diff -urN linux-mips/ath_version.mk mips-linux-2.4.25/ath_version.mk +--- linux-mips/ath_version.mk 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/ath_version.mk 2005-12-30 17:27:00.579327336 +0000 +@@ -0,0 +1 @@ ++EXTRAVERSION=-LSDK-5.0.0-RC5 +diff -urN linux-mips/drivers/char/serial.c mips-linux-2.4.25/drivers/char/serial.c +--- linux-mips/drivers/char/serial.c 2005-12-24 15:11:21.796999096 +0000 ++++ mips-linux-2.4.25/drivers/char/serial.c 2005-12-30 17:27:10.815771160 +0000 +@@ -3441,7 +3441,7 @@ + + static _INLINE_ void show_serial_version(void) + { +- printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, ++ printk(KERN_INFO "%s version %s%s (%s) with%s\n", serial_name, + serial_version, LOCAL_VERSTRING, serial_revdate, + serial_options); + } +@@ -5567,7 +5567,7 @@ + printk(KERN_INFO"ttyS%02d%s at 0x%p (irq = %d) is a %s\n", + state->line + SERIAL_DEV_OFFSET, + (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", +- state->iomem_base, state->irq, ++ (void *)state->iomem_base, state->irq, + uart_config[state->type].name); + } + else { +diff -urN linux-mips/drivers/mtd/chips/cfi_cmdset_0002.c mips-linux-2.4.25/drivers/mtd/chips/cfi_cmdset_0002.c +--- linux-mips/drivers/mtd/chips/cfi_cmdset_0002.c 2005-12-24 15:11:25.102496584 +0000 ++++ mips-linux-2.4.25/drivers/mtd/chips/cfi_cmdset_0002.c 2005-12-30 17:27:21.333172272 +0000 +@@ -511,7 +511,7 @@ + or tells us why it failed. */ + dq6 = CMD(1<<6); + dq5 = CMD(1<<5); +- timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */ ++ timeo = jiffies + (HZ/1000) + 1; /* setting timeout to 1ms for now */ + + oldstatus = cfi_read(map, adr); + status = cfi_read(map, adr); +@@ -536,16 +536,18 @@ + if( (status & dq5) == dq5 ) { + /* When DQ5 raises, we must check once again + if DQ6 is toggling. If not, the erase has been +- completed OK. If not, reset chip. */ ++ completed OK. But if so, reset chip. */ + oldstatus = cfi_read(map, adr); + status = cfi_read(map, adr); + + if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) { ++#if 0 + printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" ); ++#endif + } else { + /* DQ5 is active so we can do a reset and stop the erase */ + cfi_write(map, CMD(0xF0), chip->start); +- printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" ); ++ printk(KERN_WARNING "Internal flash device timeout pt A occurred or write operation was performed while flash was programming. timeout=%d\n",chip->word_write_time ); + } + } else { + printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword."); +@@ -959,7 +961,7 @@ + { + /* DQ5 is active so we can do a reset and stop the erase */ + cfi_write(map, CMD(0xF0), chip->start); +- printk( KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was erasing\n" ); ++ printk( KERN_WARNING "Internal flash device timeout pt B occured or write operation was performed while flash was erasing\n" ); + } + } + else +diff -urN linux-mips/drivers/mtd/chips/cfi_probe.c mips-linux-2.4.25/drivers/mtd/chips/cfi_probe.c +--- linux-mips/drivers/mtd/chips/cfi_probe.c 2005-12-24 15:11:25.103496432 +0000 ++++ mips-linux-2.4.25/drivers/mtd/chips/cfi_probe.c 2005-12-30 17:27:21.507145824 +0000 +@@ -51,7 +51,7 @@ + struct flchip *chips, struct cfi_private *cfi) + { + int i; +- ++ + if ((base + 0) >= map->size) { + printk(KERN_NOTICE + "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", +@@ -221,12 +221,10 @@ + + static void print_cfi_ident(struct cfi_ident *cfip) + { +-#if 0 + if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { + printk("Invalid CFI ident structure.\n"); + return; + } +-#endif + printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); + if (cfip->P_ADR) + printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); +diff -urN linux-mips/drivers/mtd/chips/jedec_probe.c mips-linux-2.4.25/drivers/mtd/chips/jedec_probe.c +--- linux-mips/drivers/mtd/chips/jedec_probe.c 2005-12-24 15:11:25.126492936 +0000 ++++ mips-linux-2.4.25/drivers/mtd/chips/jedec_probe.c 2005-12-30 17:27:21.532142024 +0000 +@@ -104,6 +104,7 @@ + #define SST29LE512 0x003d + #define SST39LF800 0x2781 + #define SST39LF160 0x2782 ++#define SST39LF1601 0x234b + #define SST39LF512 0x00D4 + #define SST39LF010 0x00D5 + #define SST39LF020 0x00D6 +@@ -113,6 +114,8 @@ + #define SST49LF030A 0x001C + #define SST49LF040A 0x0051 + #define SST49LF080A 0x005B ++#define SST39VF3201 0x235B ++#define SST39VF3202 0x235A + + /* Toshiba */ + #define TC58FVT160 0x00C2 +@@ -900,7 +903,43 @@ + NumEraseRegions: 1, + regions: {ERASEINFO(0x01000,256), + } +- } ++ }, { ++ mfr_id: MANUFACTURER_SST, ++ dev_id: SST39LF160, ++ name: "SST 39LF160", ++ DevSize: SIZE_2MiB, ++ CmdSet: P_ID_AMD_STD, ++ NumEraseRegions: 1, ++ regions: {ERASEINFO(0x01000,512), ++ } ++ }, { ++ mfr_id: MANUFACTURER_SST, ++ dev_id: SST39LF1601, ++ name: "SST 39LF1601", ++ DevSize: SIZE_2MiB, ++ CmdSet: P_ID_AMD_STD, ++ NumEraseRegions: 1, ++ regions: {ERASEINFO(0x01000,512), ++ } ++ }, { ++ mfr_id: MANUFACTURER_SST, ++ dev_id: SST39VF3201, ++ name: "SST 39VF3201", ++ DevSize: SIZE_4MiB, ++ CmdSet: P_ID_AMD_STD, ++ NumEraseRegions: 1, ++ regions: {ERASEINFO(0x01000,1024), ++ } ++ }, { ++ mfr_id: MANUFACTURER_SST, ++ dev_id: SST39VF3202, ++ name: "SST 39VF3202", ++ DevSize: SIZE_4MiB, ++ CmdSet: P_ID_AMD_STD, ++ NumEraseRegions: 1, ++ regions: {ERASEINFO(0x01000,1024), ++ } ++ } + }; + + +@@ -967,6 +1006,35 @@ + p_cfi->cfiq->DevSize = jedec_table[index].DevSize; + p_cfi->cfi_mode = CFI_MODE_JEDEC; + ++ /* ++ * Add the following code to set the flash timing parameters. ++ * Maybe this is done in a table somwehere else? I can't find it. ++ */ ++ ++ ++ switch(jedec_table[index].dev_id) { ++ case SST39VF3201: ++ case SST39VF3202: ++ p_cfi->cfiq->WordWriteTimeoutTyp = 3; /* 8 us */ ++ p_cfi->cfiq->WordWriteTimeoutMax = 4; /* 16 us */ ++ p_cfi->cfiq->BlockEraseTimeoutTyp = 15; /* Actually 18ms, max 25 */ ++ p_cfi->cfiq->BlockEraseTimeoutMax = 15; /* Actually 25ms */ ++ p_cfi->cfiq->ChipEraseTimeoutTyp = 16; /* Max is 50ms, typical is 40ms */ ++ p_cfi->cfiq->ChipEraseTimeoutMax = 16; ++ break; ++ case SST39LF160: ++ case SST39LF1601: ++ p_cfi->cfiq->WordWriteTimeoutTyp = 4; /* 14 us */ ++ p_cfi->cfiq->WordWriteTimeoutMax = 5; /* 20 us */ ++ p_cfi->cfiq->BlockEraseTimeoutTyp = 15; /* Actually 18ms, max 25 */ ++ p_cfi->cfiq->BlockEraseTimeoutMax = 15; /* Actually 25ms */ ++ p_cfi->cfiq->ChipEraseTimeoutTyp = 17; /* Max is 70ms, typical is 40ms */ ++ p_cfi->cfiq->ChipEraseTimeoutMax = 17; ++ break; ++ } ++ ++ ++ + for (i=0; icfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; + } +diff -urN linux-mips/drivers/mtd/Config.in mips-linux-2.4.25/drivers/mtd/Config.in +--- linux-mips/drivers/mtd/Config.in 2005-12-24 15:11:25.091498256 +0000 ++++ mips-linux-2.4.25/drivers/mtd/Config.in 2005-12-30 17:27:21.182195224 +0000 +@@ -14,6 +14,9 @@ + dep_tristate ' MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD + dep_tristate ' MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD + dep_tristate ' RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS ++ if [ "$CONFIG_MTD_END_RESERVED" != "" ]; then ++ define_int CONFIG_MTD_END_RESERVED $CONFIG_MTD_END_RESERVED ++ fi + dep_tristate ' Command line partition table parsing' CONFIG_MTD_CMDLINE_PARTS $CONFIG_MTD_PARTITIONS + if [ "$CONFIG_ARM" = "y" ]; then + dep_tristate ' ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS +diff -urN linux-mips/drivers/mtd/devices/Makefile mips-linux-2.4.25/drivers/mtd/devices/Makefile +--- linux-mips/drivers/mtd/devices/Makefile 2005-12-24 15:11:25.128492632 +0000 ++++ mips-linux-2.4.25/drivers/mtd/devices/Makefile 2005-12-30 17:27:21.561137616 +0000 +@@ -22,5 +22,6 @@ + obj-$(CONFIG_MTD_MTDRAM) += mtdram.o + obj-$(CONFIG_MTD_LART) += lart.o + obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o ++obj-$(CONFIG_MTD_SPIFLASH) += spiflash.o + + include $(TOPDIR)/Rules.make +diff -urN linux-mips/drivers/mtd/devices/spiflash.c mips-linux-2.4.25/drivers/mtd/devices/spiflash.c +--- linux-mips/drivers/mtd/devices/spiflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/drivers/mtd/devices/spiflash.c 2005-12-30 17:27:21.652123784 +0000 +@@ -0,0 +1,506 @@ ++ ++/* ++ * MTD driver for the SPI Flash Memory support. ++ * ++ * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/drivers/mtd/devices/spiflash.c#3 $ ++ * ++ * ++ * Copyright (c) 2005-2006 Atheros Communications Inc. ++ * ++ * This code is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++/*=========================================================================== ++** !!!! VERY IMPORTANT NOTICE !!!! FLASH DATA STORED IN LITTLE ENDIAN FORMAT ++** ++** This module contains the Serial Flash access routines for the Atheros SOC. ++** The Atheros SOC integrates a SPI flash controller that is used to access ++** serial flash parts. The SPI flash controller executes in "Little Endian" ++** mode. THEREFORE, all WRITES and READS from the MIPS CPU must be ++** BYTESWAPPED! The SPI Flash controller hardware by default performs READ ++** ONLY byteswapping when accessed via the SPI Flash Alias memory region ++** (Physical Address 0x0800_0000 - 0x0fff_ffff). The data stored in the ++** flash sectors is stored in "Little Endian" format. ++** ++** The spiflash_write() routine performs byteswapping on all write ++** operations. ++**===========================================================================*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "spiflash.h" ++ ++/* debugging */ ++/* #define SPIFLASH_DEBUG */ ++ ++#ifndef __BIG_ENDIAN ++#error This driver currently only works with big endian CPU. ++#endif ++ ++static char module_name[] = "spiflash"; ++ ++#define MIN(a,b) ((a) < (b) ? (a) : (b)) ++#define FALSE 0 ++#define TRUE 1 ++ ++#define ROOTFS_NAME "rootfs" ++ ++static __u32 spiflash_regread32(int reg); ++static void spiflash_regwrite32(int reg, __u32 data); ++static __u32 spiflash_sendcmd (int op); ++ ++int __init spiflash_init (void); ++void __exit spiflash_exit (void); ++static int spiflash_probe (void); ++static int spiflash_erase (struct mtd_info *mtd,struct erase_info *instr); ++static int spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf); ++static int spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf); ++ ++/* Flash configuration table */ ++struct flashconfig { ++ __u32 byte_cnt; ++ __u32 sector_cnt; ++ __u32 sector_size; ++ __u32 cs_addrmask; ++} flashconfig_tbl[MAX_FLASH] = ++ { ++ { 0, 0, 0, 0}, ++ { STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE, 0x0}, ++ { STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE, 0x0}, ++ { STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE, 0x0} ++ }; ++ ++/* Mapping of generic opcodes to STM serial flash opcodes */ ++struct opcodes { ++ __u16 code; ++ __s8 tx_cnt; ++ __s8 rx_cnt; ++} stm_opcodes[] = { ++ {STM_OP_WR_ENABLE, 1, 0}, ++ {STM_OP_WR_DISABLE, 1, 0}, ++ {STM_OP_RD_STATUS, 1, 1}, ++ {STM_OP_WR_STATUS, 1, 0}, ++ {STM_OP_RD_DATA, 4, 4}, ++ {STM_OP_FAST_RD_DATA, 1, 0}, ++ {STM_OP_PAGE_PGRM, 8, 0}, ++ {STM_OP_SECTOR_ERASE, 4, 0}, ++ {STM_OP_BULK_ERASE, 1, 0}, ++ {STM_OP_DEEP_PWRDOWN, 1, 0}, ++ {STM_OP_RD_SIG, 4, 1} ++}; ++ ++/* Driver private data structure */ ++struct spiflash_data { ++ struct mtd_info *mtd; ++ struct mtd_partition *parsed_parts; /* parsed partitions */ ++ void *spiflash_readaddr; /* memory mapped data for read */ ++ void *spiflash_mmraddr; /* memory mapped register space */ ++}; ++ ++static struct spiflash_data *spidata; ++ ++extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); ++ ++/***************************************************************************************************/ ++ ++static __u32 ++spiflash_regread32(int reg) ++{ ++ volatile __u32 *data = (__u32 *)(spidata->spiflash_mmraddr + reg); ++ ++ return (*data); ++} ++ ++static void ++spiflash_regwrite32(int reg, __u32 data) ++{ ++ volatile __u32 *addr = (__u32 *)(spidata->spiflash_mmraddr + reg); ++ ++ *addr = data; ++ return; ++} ++ ++static __u32 ++spiflash_sendcmd (int op) ++{ ++ __u32 reg; ++ __u32 mask; ++ struct opcodes *ptr_opcode; ++ ++ ptr_opcode = &stm_opcodes[op]; ++ ++ do { ++ reg = spiflash_regread32(SPI_FLASH_CTL); ++ } while (reg & SPI_CTL_BUSY); ++ ++ spiflash_regwrite32(SPI_FLASH_OPCODE, ptr_opcode->code); ++ ++ reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | ++ (ptr_opcode->rx_cnt << 4) | SPI_CTL_START; ++ ++ spiflash_regwrite32(SPI_FLASH_CTL, reg); ++ ++ if (ptr_opcode->rx_cnt > 0) { ++ do { ++ reg = spiflash_regread32(SPI_FLASH_CTL); ++ } while (reg & SPI_CTL_BUSY); ++ ++ reg = (__u32) spiflash_regread32(SPI_FLASH_DATA); ++ ++ switch (ptr_opcode->rx_cnt) { ++ case 1: ++ mask = 0x000000ff; ++ break; ++ case 2: ++ mask = 0x0000ffff; ++ break; ++ case 3: ++ mask = 0x00ffffff; ++ break; ++ default: ++ mask = 0xffffffff; ++ break; ++ } ++ ++ reg &= mask; ++ } ++ else { ++ reg = 0; ++ } ++ ++ return reg; ++} ++ ++/* Probe SPI flash device ++ * Function returns 0 for failure. ++ * and flashconfig_tbl array index for success. ++ */ ++static int ++spiflash_probe (void) ++{ ++ __u32 sig; ++ int flash_size; ++ ++ /* Read the signature on the flash device */ ++ sig = spiflash_sendcmd(SPI_RD_SIG); ++ ++ switch (sig) { ++ case STM_8MBIT_SIGNATURE: ++ flash_size = FLASH_1MB; ++ break; ++ case STM_16MBIT_SIGNATURE: ++ flash_size = FLASH_2MB; ++ break; ++ case STM_32MBIT_SIGNATURE: ++ flash_size = FLASH_4MB; ++ break; ++ default: ++ printk (KERN_WARNING "%s: Read of flash device signature failed!\n", module_name); ++ return (0); ++ } ++ ++ return (flash_size); ++} ++ ++ ++static int ++spiflash_erase (struct mtd_info *mtd,struct erase_info *instr) ++{ ++ struct opcodes *ptr_opcode; ++ __u32 temp, reg; ++ int finished = FALSE; ++ ++#ifdef SPIFLASH_DEBUG ++ printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len); ++#endif ++ ++ /* sanity checks */ ++ if (instr->addr + instr->len > mtd->size) return (-EINVAL); ++ ++ ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; ++ ++ temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code); ++ spiflash_sendcmd(SPI_WRITE_ENABLE); ++ do { ++ reg = spiflash_regread32(SPI_FLASH_CTL); ++ } while (reg & SPI_CTL_BUSY); ++ ++ spiflash_regwrite32(SPI_FLASH_OPCODE, temp); ++ ++ reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | SPI_CTL_START; ++ spiflash_regwrite32(SPI_FLASH_CTL, reg); ++ ++ do { ++ reg = spiflash_sendcmd(SPI_RD_STATUS); ++ if (!(reg & SPI_STATUS_WIP)) { ++ finished = TRUE; ++ } ++ } while (!finished); ++ ++ instr->state = MTD_ERASE_DONE; ++ if (instr->callback) instr->callback (instr); ++ ++#ifdef SPIFLASH_DEBUG ++ printk (KERN_DEBUG "%s return\n",__FUNCTION__); ++#endif ++ return (0); ++} ++ ++static int ++spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf) ++{ ++ u_char *read_addr; ++ ++#ifdef SPIFLASH_DEBUG ++ printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,(int)len); ++#endif ++ ++ /* sanity checks */ ++ if (!len) return (0); ++ if (from + len > mtd->size) return (-EINVAL); ++ ++ ++ /* we always read len bytes */ ++ *retlen = len; ++ ++ read_addr = (u_char *)(spidata->spiflash_readaddr + from); ++ memcpy(buf, read_addr, len); ++ ++ return (0); ++} ++ ++static int ++spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf) ++{ ++ int done = FALSE, page_offset, bytes_left, finished; ++ __u32 xact_len, spi_data = 0, opcode, reg; ++ ++#ifdef SPIFLASH_DEBUG ++ printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len); ++#endif ++ ++ *retlen = 0; ++ ++ /* sanity checks */ ++ if (!len) return (0); ++ if (to + len > mtd->size) return (-EINVAL); ++ ++ opcode = stm_opcodes[SPI_PAGE_PROGRAM].code; ++ bytes_left = len; ++ ++ while (done == FALSE) { ++ xact_len = MIN(bytes_left, sizeof(__u32)); ++ ++ /* 32-bit writes cannot span across a page boundary ++ * (256 bytes). This types of writes require two page ++ * program operations to handle it correctly. The STM part ++ * will write the overflow data to the beginning of the ++ * current page as opposed to the subsequent page. ++ */ ++ page_offset = (to & (STM_PAGE_SIZE - 1)) + xact_len; ++ ++ if (page_offset > STM_PAGE_SIZE) { ++ xact_len -= (page_offset - STM_PAGE_SIZE); ++ } ++ ++ spiflash_sendcmd(SPI_WRITE_ENABLE); ++ ++ do { ++ reg = spiflash_regread32(SPI_FLASH_CTL); ++ } while (reg & SPI_CTL_BUSY); ++ ++ switch (xact_len) { ++ case 1: ++ (__u8)spi_data = *buf; ++ break; ++ case 2: ++ spi_data = (buf[1] << 8) | buf[0]; ++ break; ++ case 3: ++ spi_data = (buf[2] << 16) | (buf[1] << 8) | buf[0]; ++ break; ++ case 4: ++ spi_data = (buf[3] << 24) | (buf[2] << 16) | ++ (buf[1] << 8) | buf[0]; ++ break; ++ default: ++ printk("spiflash_write: default case\n"); ++ break; ++ } ++ ++ spiflash_regwrite32(SPI_FLASH_DATA, spi_data); ++ opcode = (opcode & SPI_OPCODE_MASK) | ((__u32)to << 8); ++ spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); ++ ++ reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | (xact_len + 4) | SPI_CTL_START; ++ spiflash_regwrite32(SPI_FLASH_CTL, reg); ++ finished = FALSE; ++ ++ do { ++ udelay(1); ++ reg = spiflash_sendcmd(SPI_RD_STATUS); ++ if (!(reg & SPI_STATUS_WIP)) { ++ finished = TRUE; ++ } ++ } while (!finished); ++ ++ bytes_left -= xact_len; ++ to += xact_len; ++ buf += xact_len; ++ ++ *retlen += xact_len; ++ ++ if (bytes_left == 0) { ++ done = TRUE; ++ } ++ } ++ ++ return (0); ++} ++ ++ ++int __init ++spiflash_init (void) ++{ ++ int result, i; ++ int index, num_parts; ++ struct mtd_info *mtd; ++ struct mtd_partition *mtd_parts; ++ ++ spidata = kmalloc(sizeof(struct spiflash_data), GFP_KERNEL); ++ if (!spidata) ++ return (-ENXIO); ++ ++ spidata->spiflash_mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE); ++ if (!spidata->spiflash_mmraddr) { ++ printk (KERN_WARNING "%s: Failed to map flash device\n", module_name); ++ kfree(spidata); ++ return (-ENXIO); ++ } ++ ++ mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); ++ if (!mtd) { ++ kfree(spidata); ++ return (-ENXIO); ++ } ++ ++ memset (mtd,0,sizeof (*mtd)); ++ ++ printk ("MTD driver for SPI flash.\n"); ++ printk ("%s: Probing for Serial flash ...\n", module_name); ++ if (!(index = spiflash_probe ())) { ++ printk (KERN_WARNING "%s: Found no serial flash device\n", module_name); ++ kfree(mtd); ++ kfree(spidata); ++ return (-ENXIO); ++ } ++ printk ("%s: Found SPI serial Flash.\n", module_name); ++ printk ("%d: size\n", flashconfig_tbl[index].byte_cnt); ++ ++ spidata->spiflash_readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt); ++ if (!spidata->spiflash_readaddr) { ++ printk (KERN_WARNING "%s: Failed to map flash device\n", module_name); ++ kfree(mtd); ++ kfree(spidata); ++ return (-ENXIO); ++ } ++ ++ mtd->name = module_name; ++ mtd->type = MTD_NORFLASH; ++ mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE); ++ mtd->size = flashconfig_tbl[index].byte_cnt; ++ mtd->erasesize = flashconfig_tbl[index].sector_size; ++ mtd->numeraseregions = 0; ++ mtd->eraseregions = NULL; ++ mtd->module = THIS_MODULE; ++ mtd->erase = spiflash_erase; ++ mtd->read = spiflash_read; ++ mtd->write = spiflash_write; ++ ++#ifdef SPIFLASH_DEBUG ++ printk (KERN_DEBUG ++ "mtd->name = %s\n" ++ "mtd->size = 0x%.8x (%uM)\n" ++ "mtd->erasesize = 0x%.8x (%uK)\n" ++ "mtd->numeraseregions = %d\n", ++ mtd->name, ++ mtd->size, mtd->size / (1024*1024), ++ mtd->erasesize, mtd->erasesize / 1024, ++ mtd->numeraseregions); ++ ++ if (mtd->numeraseregions) { ++ for (result = 0; result < mtd->numeraseregions; result++) { ++ printk (KERN_DEBUG ++ "\n\n" ++ "mtd->eraseregions[%d].offset = 0x%.8x\n" ++ "mtd->eraseregions[%d].erasesize = 0x%.8x (%uK)\n" ++ "mtd->eraseregions[%d].numblocks = %d\n", ++ result,mtd->eraseregions[result].offset, ++ result,mtd->eraseregions[result].erasesize,mtd->eraseregions[result].erasesize / 1024, ++ result,mtd->eraseregions[result].numblocks); ++ } ++ } ++#endif ++ ++#ifndef CONFIG_BLK_DEV_INITRD ++ /* parse redboot partitions */ ++ num_parts = parse_redboot_partitions(mtd, &spidata->parsed_parts); ++ ++#ifdef SPIFLASH_DEBUG ++ printk (KERN_DEBUG "Found %d redboot partitions\n", num_parts); ++#endif ++ ++ if (num_parts) { ++ result = add_mtd_partitions(mtd, spidata->parsed_parts, num_parts); ++ /* Find root partition */ ++ mtd_parts = spidata->parsed_parts; ++ for (i=0; i < num_parts; i++) { ++ if (!strcmp(mtd_parts[i].name, ROOTFS_NAME)) { ++ /* Create root device */ ++ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, i); ++ break; ++ } ++ } ++ } else { ++#ifdef SPIFLASH_DEBUG ++ printk (KERN_DEBUG "Did not find any redboot partitions\n"); ++#endif ++ kfree(mtd); ++ kfree(spidata); ++ return (-ENXIO); ++ } ++#endif ++ ++ spidata->mtd = mtd; ++ ++ return (result); ++} ++ ++void __exit ++spiflash_exit (void) ++{ ++ if (spidata && spidata->parsed_parts) { ++ del_mtd_partitions (spidata->mtd); ++ kfree(spidata->mtd); ++ kfree(spidata); ++ } ++} ++ ++module_init (spiflash_init); ++module_exit (spiflash_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Atheros Communications Inc"); ++MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros SOC"); ++ +diff -urN linux-mips/drivers/mtd/devices/spiflash.h mips-linux-2.4.25/drivers/mtd/devices/spiflash.h +--- linux-mips/drivers/mtd/devices/spiflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/drivers/mtd/devices/spiflash.h 2005-12-30 17:27:21.652123784 +0000 +@@ -0,0 +1,113 @@ ++/* ++ * SPI Flash Memory support header file. ++ * ++ * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/drivers/mtd/devices/spiflash.h#3 $ ++ * ++ * ++ * Copyright (c) 2005, Atheros Communications Inc. ++ * ++ * This code is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++#define FLASH_1MB 1 ++#define FLASH_2MB 2 ++#define FLASH_4MB 3 ++#define MAX_FLASH 4 ++ ++#define STM_PAGE_SIZE 256 ++ ++#define STM_8MBIT_SIGNATURE 0x13 ++#define STM_M25P80_BYTE_COUNT 1048576 ++#define STM_M25P80_SECTOR_COUNT 16 ++#define STM_M25P80_SECTOR_SIZE 0x10000 ++ ++#define STM_16MBIT_SIGNATURE 0x14 ++#define STM_M25P16_BYTE_COUNT 2097152 ++#define STM_M25P16_SECTOR_COUNT 32 ++#define STM_M25P16_SECTOR_SIZE 0x10000 ++ ++#define STM_32MBIT_SIGNATURE 0x15 ++#define STM_M25P32_BYTE_COUNT 4194304 ++#define STM_M25P32_SECTOR_COUNT 64 ++#define STM_M25P32_SECTOR_SIZE 0x10000 ++ ++#define STM_1MB_BYTE_COUNT STM_M25P80_BYTE_COUNT ++#define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT ++#define STM_1MB_SECTOR_SIZE STM_M25P80_SECTOR_SIZE ++#define STM_2MB_BYTE_COUNT STM_M25P16_BYTE_COUNT ++#define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT ++#define STM_2MB_SECTOR_SIZE STM_M25P16_SECTOR_SIZE ++#define STM_4MB_BYTE_COUNT STM_M25P32_BYTE_COUNT ++#define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT ++#define STM_4MB_SECTOR_SIZE STM_M25P32_SECTOR_SIZE ++ ++#define SPI_WRITE_ENABLE 0 ++#define SPI_WRITE_DISABLE 1 ++#define SPI_RD_STATUS 2 ++#define SPI_WR_STATUS 3 ++#define SPI_RD_DATA 4 ++#define SPI_FAST_RD_DATA 5 ++#define SPI_PAGE_PROGRAM 6 ++#define SPI_SECTOR_ERASE 7 ++#define SPI_BULK_ERASE 8 ++#define SPI_DEEP_PWRDOWN 9 ++#define SPI_RD_SIG 10 ++#define SPI_MAX_OPCODES 11 ++ ++#define SFI_WRITE_BUFFER_SIZE 4 ++#define SFI_FLASH_ADDR_MASK 0x00ffffff ++ ++/* ++ * ST Microelectronics Opcodes for Serial Flash ++ */ ++ ++#define STM_OP_WR_ENABLE 0x06 /* Write Enable */ ++#define STM_OP_WR_DISABLE 0x04 /* Write Disable */ ++#define STM_OP_RD_STATUS 0x05 /* Read Status */ ++#define STM_OP_WR_STATUS 0x01 /* Write Status */ ++#define STM_OP_RD_DATA 0x03 /* Read Data */ ++#define STM_OP_FAST_RD_DATA 0x0b /* Fast Read Data */ ++#define STM_OP_PAGE_PGRM 0x02 /* Page Program */ ++#define STM_OP_SECTOR_ERASE 0xd8 /* Sector Erase */ ++#define STM_OP_BULK_ERASE 0xc7 /* Bulk Erase */ ++#define STM_OP_DEEP_PWRDOWN 0xb9 /* Deep Power-Down Mode */ ++#define STM_OP_RD_SIG 0xab /* Read Electronic Signature */ ++ ++#define STM_STATUS_WIP 0x01 /* Write-In-Progress */ ++#define STM_STATUS_WEL 0x02 /* Write Enable Latch */ ++#define STM_STATUS_BP0 0x04 /* Block Protect 0 */ ++#define STM_STATUS_BP1 0x08 /* Block Protect 1 */ ++#define STM_STATUS_BP2 0x10 /* Block Protect 2 */ ++#define STM_STATUS_SRWD 0x80 /* Status Register Write Disable */ ++ ++/* ++ * SPI Flash Interface Registers ++ */ ++#define AR531XPLUS_SPI_READ 0x1fc00000 ++#define AR531XPLUS_SPI_MMR 0x11300000 ++#define AR531XPLUS_SPI_MMR_SIZE 12 ++ ++#define AR531XPLUS_SPI_CTL 0x00 ++#define AR531XPLUS_SPI_OPCODE 0x04 ++#define AR531XPLUS_SPI_DATA 0x08 ++ ++#define SPI_FLASH_READ AR531XPLUS_SPI_READ ++#define SPI_FLASH_MMR AR531XPLUS_SPI_MMR ++#define SPI_FLASH_MMR_SIZE AR531XPLUS_SPI_MMR_SIZE ++#define SPI_FLASH_CTL AR531XPLUS_SPI_CTL ++#define SPI_FLASH_OPCODE AR531XPLUS_SPI_OPCODE ++#define SPI_FLASH_DATA AR531XPLUS_SPI_DATA ++ ++#define SPI_CTL_START 0x00000100 ++#define SPI_CTL_BUSY 0x00010000 ++#define SPI_CTL_TXCNT_MASK 0x0000000f ++#define SPI_CTL_RXCNT_MASK 0x000000f0 ++#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff ++#define SPI_CTL_SIZE_MASK 0x00060000 ++ ++#define SPI_CTL_CLK_SEL_MASK 0x03000000 ++#define SPI_OPCODE_MASK 0x000000ff ++ ++#define SPI_STATUS_WIP STM_STATUS_WIP +diff -urN linux-mips/drivers/mtd/maps/Config.in mips-linux-2.4.25/drivers/mtd/maps/Config.in +--- linux-mips/drivers/mtd/maps/Config.in 2005-12-24 15:11:25.158488072 +0000 ++++ mips-linux-2.4.25/drivers/mtd/maps/Config.in 2005-12-30 17:27:21.660122568 +0000 +@@ -9,7 +9,14 @@ + dep_tristate ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE + if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then + hex ' Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000 +- hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000 ++ if [ "$CONFIG_FLASH_2MB" = "y" ]; then ++ define_hex CONFIG_MTD_PHYSMAP_LEN 200000 ++ fi ++ if [ "$CONFIG_FLASH_4MB" = "y" ]; then ++ define_hex CONFIG_MTD_PHYSMAP_LEN 400000 ++ fi ++ ++# hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000 + int ' Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2 + fi + +diff -urN linux-mips/drivers/mtd/maps/physmap.c mips-linux-2.4.25/drivers/mtd/maps/physmap.c +--- linux-mips/drivers/mtd/maps/physmap.c 2005-12-24 15:11:25.217479104 +0000 ++++ mips-linux-2.4.25/drivers/mtd/maps/physmap.c 2005-12-30 17:27:22.044064200 +0000 +@@ -80,12 +80,25 @@ + }; + + #ifdef CONFIG_MTD_PARTITIONS +-#ifdef CONFIG_MTD_CMDLINE_PARTS ++#if defined(CONFIG_MTD_CMDLINE_PARTS) || defined(CONFIG_MTD_REDBOOT_PARTS) + static struct mtd_partition *mtd_parts = 0; + static int mtd_parts_nb = 0; + #else + static struct mtd_partition physmap_partitions[] = { + /* Put your own partition definitions here */ ++ { ++ name: "rootfs", ++#ifdef CONFIG_FLASH_2MB ++ size: 0x000e0000, ++ offset: 0x000f0000, ++#endif ++#ifdef CONFIG_FLASH_4MB ++ size: 0x002dd000, ++ offset: 0x00100000, ++#endif ++ ++ /* Allow file system to be mounted for writing */ ++ } + #if 0 + { + name: "bootROM", +@@ -138,6 +151,22 @@ + + add_mtd_device(mymtd); + #ifdef CONFIG_MTD_PARTITIONS ++#ifdef CONFIG_MTD_REDBOOT_PARTS ++ { ++ extern int parse_redboot_partitions(struct mtd_info *master, ++ struct mtd_partition **pparts); ++ ++ struct mtd_partition *rb_parts = 0; ++ int rb_parts_nb = 0; ++ ++ rb_parts_nb = parse_redboot_partitions(mymtd, &rb_parts); ++ if (rb_parts_nb > 0) { ++ printk(KERN_NOTICE ++ "Using redboot flash partitioning"); ++ add_mtd_partitions (mymtd, rb_parts, rb_parts_nb); ++ } ++ } ++#endif + #ifdef CONFIG_MTD_CMDLINE_PARTS + mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, + "phys"); +@@ -147,7 +176,8 @@ + "Using command line partition definition\n"); + add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); + } +-#else ++#endif ++#if !defined(CONFIG_MTD_CMDLINE_PARTS) && !defined(CONFIG_MTD_REDBOOT_PARTS) + if (NUM_PARTITIONS != 0) + { + printk(KERN_NOTICE +diff -urN linux-mips/drivers/mtd/redboot.c mips-linux-2.4.25/drivers/mtd/redboot.c +--- linux-mips/drivers/mtd/redboot.c 2005-12-24 15:11:25.249474240 +0000 ++++ mips-linux-2.4.25/drivers/mtd/redboot.c 2005-12-30 17:27:22.517992152 +0000 +@@ -51,8 +51,14 @@ + return -ENOMEM; + + /* Read the start of the last erase block */ +- ret = master->read(master, master->size - master->erasesize, ++ { ++ u_int32_t part_table_start = master->size - master->erasesize; ++#if defined(CONFIG_MTD_END_RESERVED) ++ part_table_start -= CONFIG_MTD_END_RESERVED; ++#endif ++ ret = master->read(master, part_table_start, + PAGE_SIZE, &retlen, (void *)buf); ++ } + + if (ret) + goto out; +diff -urN linux-mips/drivers/net/Config.in mips-linux-2.4.25/drivers/net/Config.in +--- linux-mips/drivers/net/Config.in 2005-12-24 15:11:25.725401888 +0000 ++++ mips-linux-2.4.25/drivers/net/Config.in 2005-12-30 17:27:22.684966768 +0000 +@@ -24,6 +24,18 @@ + comment 'Ethernet (10 or 100Mbit)' + bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET + if [ "$CONFIG_NET_ETHERNET" = "y" ]; then ++ define_bool CONFIG_VENETDEV n ++ tristate ' BUILT-IN ATHEROS ENET DRIVER' CONFIG_NET_ATHEROS_ETHER ++ if [ "$CONFIG_AP38" = "y" -o "$CONFIG_AP48" = "y" ]; then ++ define_bool CONFIG_KENDIN_ENET_PHY y ++ elif [ "$CONFIG_AP30ASK" = "y" ]; then ++ define_bool CONFIG_KENDIN_KS8995XA_ENET_PHY y ++ bool 'Multiple Ethernet address hack ' CONFIG_ASK_MULT_MAC_HACK ++ elif [ "$CONFIG_AP51" = "y" ]; then ++ define_bool CONFIG_ICPLUS_ENET_PHY y ++ else ++ define_bool CONFIG_MARVELL_ENET_PHY y ++ fi + if [ "$CONFIG_ARM" = "y" ]; then + dep_bool ' ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110 + tristate ' Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS +diff -urN linux-mips/drivers/net/Makefile mips-linux-2.4.25/drivers/net/Makefile +--- linux-mips/drivers/net/Makefile 2005-12-24 15:11:25.726401736 +0000 ++++ mips-linux-2.4.25/drivers/net/Makefile 2005-12-30 17:27:22.709962968 +0000 +@@ -31,6 +31,10 @@ + obj-y += e1000/e1000.o + endif + ++ifeq ($(CONFIG_NET_ATHEROS_ETHER),y) ++ obj-y += ath/ae531x.o ++endif ++ + ifeq ($(CONFIG_BONDING),y) + obj-y += bonding/bonding.o + endif +@@ -53,8 +57,13 @@ + subdir-$(CONFIG_SKFP) += skfp + subdir-$(CONFIG_E100) += e100 + subdir-$(CONFIG_E1000) += e1000 ++subdir-$(CONFIG_NET_ATHEROS_ETHER) += ath + subdir-$(CONFIG_BONDING) += bonding + ++ifeq ($(CONFIG_ATHAP33),y) ++subdir-$(CONFIG_ATHAP33) += athap33 ++endif ++ + # + # link order important here + # +@@ -242,6 +251,10 @@ + obj-$(CONFIG_R8169) += r8169.o + obj-$(CONFIG_AMD8111_ETH) += amd8111e.o mii.o + ++ifeq ($(CONFIG_ATHAP33),y) ++obj-$(CONFIG_ATHAP33) += athap33/ath_ap_mips.o ++endif ++ + # non-drivers/net drivers who want mii lib + obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o + obj-$(CONFIG_USB_USBNET) += mii.o +diff -urN linux-mips/fs/jffs2/nodelist.h mips-linux-2.4.25/fs/jffs2/nodelist.h +--- linux-mips/fs/jffs2/nodelist.h 2005-12-24 15:11:50.407649616 +0000 ++++ mips-linux-2.4.25/fs/jffs2/nodelist.h 2005-12-30 17:27:51.289618200 +0000 +@@ -31,7 +31,7 @@ + * provisions above, a recipient may use your version of this file + * under either the RHEPL or the GPL. + * +- * $Id: nodelist.h,v 1.46.2.5 2003/11/02 13:54:20 dwmw2 Exp $ ++ * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/fs/jffs2/nodelist.h#3 $ + * + */ + +@@ -222,8 +222,8 @@ + #define ALLOC_DELETION 1 /* Deletion node. Best to allow it */ + #define ALLOC_GC 2 /* Space requested for GC. Give it or die */ + +-#define JFFS2_RESERVED_BLOCKS_BASE 3 /* Number of free blocks there must be before we... */ +-#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 2) /* ... allow a normal filesystem write */ ++#define JFFS2_RESERVED_BLOCKS_BASE 2 /* Number of free blocks there must be before we... */ ++#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... allow a normal filesystem write */ + #define JFFS2_RESERVED_BLOCKS_DELETION (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... allow a normal filesystem deletion */ + #define JFFS2_RESERVED_BLOCKS_GCTRIGGER (JFFS2_RESERVED_BLOCKS_BASE + 3) /* ... wake up the GC thread */ + #define JFFS2_RESERVED_BLOCKS_GCBAD (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... pick a block from the bad_list to GC */ +diff -urN linux-mips/fs/partitions/Config.in mips-linux-2.4.25/fs/partitions/Config.in +--- linux-mips/fs/partitions/Config.in 2005-12-24 15:11:52.366351848 +0000 ++++ mips-linux-2.4.25/fs/partitions/Config.in 2005-12-30 17:27:52.279467720 +0000 +@@ -39,7 +39,7 @@ + fi + if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \ + "$CONFIG_MAC" != "y" -a "$CONFIG_SGI_IP22" != "y" -a \ +- "$CONFIG_SGI_IP27" != "y" ]; then ++ "$CONFIG_SGI_IP27" != "y" -a "$CONFIG_AR531X" != "y" ]; then + define_bool CONFIG_MSDOS_PARTITION y + fi + if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_AFFS_FS" = "y" ]; then +diff -urN linux-mips/include/asm-mips/atheros/ar531xbsp.h mips-linux-2.4.25/include/asm-mips/atheros/ar531xbsp.h +--- linux-mips/include/asm-mips/atheros/ar531xbsp.h 1970-01-01 01:00:00.000000000 +0100 ++++ mips-linux-2.4.25/include/asm-mips/atheros/ar531xbsp.h 2005-12-30 17:28:01.523062480 +0000 +@@ -0,0 +1,17 @@ ++#ifndef __ASM_ATHEROS_BSP_SUPPORT_H ++#define __ASM_ATHEROS_BSP_SUPPORT_H ++/* ++ * These are definitions and functions provided by the bsp to support the ++ * AR5312 WiSoC running LSDK. For different BSP implementations, different ++ * BSP functions will be needed. ++ */ ++ ++extern unsigned int ar531x_sys_frequency(void); ++extern const char* get_system_type(void); ++ ++#ifdef CONFIG_KGDB ++extern void kgdbInit(void); ++extern int kgdbEnabled(void); ++#endif ++ ++#endif /* __ASM_ATHEROS_BSP_SUPPORT_H */ +diff -urN linux-mips/include/asm-mips/bootinfo.h mips-linux-2.4.25/include/asm-mips/bootinfo.h +--- linux-mips/include/asm-mips/bootinfo.h 2005-12-24 15:12:00.645093288 +0000 ++++ mips-linux-2.4.25/include/asm-mips/bootinfo.h 2005-12-30 17:28:01.534060808 +0000 +@@ -37,6 +37,7 @@ + #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ + #define MACH_GROUP_LASAT 21 + #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ ++#define MACH_GROUP_AR531X 23 /* Atheros AR531X */ + + /* + * Valid machtype values for group unknown (low order halfword of mips_machtype) +@@ -198,6 +199,17 @@ + */ + #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ + ++/* ++ * Valid machtype for group MACH_GROUP_AR5312 ++ */ ++#define MACH_ATHEROS_UNUSED 0 ++#define MACH_ATHEROS_AP30 1 /* AP30 */ ++#define MACH_ATHEROS_AP33 2 /* AP33 */ ++#define MACH_ATHEROS_AP38 3 /* AP38 */ ++#define MACH_ATHEROS_AP43 4 /* AP43 */ ++#define MACH_ATHEROS_AP48 5 /* AP48 */ ++#define MACH_ATHEROS_PB32 6 /* PB32 */ ++ + #define CL_SIZE (256) + + const char *get_system_type(void); +diff -urN linux-mips/include/asm-mips/page.h mips-linux-2.4.25/include/asm-mips/page.h +--- linux-mips/include/asm-mips/page.h 2005-12-24 15:12:01.097024584 +0000 ++++ mips-linux-2.4.25/include/asm-mips/page.h 2005-12-30 17:28:01.898005480 +0000 +@@ -13,7 +13,6 @@ + #include + #include + +-#ifdef __KERNEL__ + + /* + * PAGE_SHIFT determines the page size +@@ -30,6 +29,7 @@ + #define PAGE_SIZE (1L << PAGE_SHIFT) + #define PAGE_MASK (~(PAGE_SIZE-1)) + ++#ifdef __KERNEL__ + #ifndef __ASSEMBLY__ + + #include +diff -urN linux-mips/include/asm-mips/serial.h mips-linux-2.4.25/include/asm-mips/serial.h +--- linux-mips/include/asm-mips/serial.h 2005-12-24 15:12:01.130019568 +0000 ++++ mips-linux-2.4.25/include/asm-mips/serial.h 2005-12-30 17:28:02.143968088 +0000 +@@ -410,6 +410,11 @@ + #define DDB5477_SERIAL_PORT_DEFNS + #endif + ++#if defined(CONFIG_AR531X) ++#undef RS_TABLE_SIZE ++#define RS_TABLE_SIZE 1 ++#endif ++ + #define SERIAL_PORT_DFNS \ + ATLAS_SERIAL_PORT_DEFNS \ + AU1000_SERIAL_PORT_DEFNS \ +diff -urN linux-mips/kernel/printk.c mips-linux-2.4.25/kernel/printk.c +--- linux-mips/kernel/printk.c 2005-12-24 15:12:09.361768152 +0000 ++++ mips-linux-2.4.25/kernel/printk.c 2005-12-30 17:28:11.943478336 +0000 +@@ -383,6 +383,18 @@ + _call_console_drivers(start_print, end, msg_level); + } + ++#if CONFIG_EARLY_PRINTK_HACK ++void putDebugChar(char byte); ++static void emit_log_char(char c) ++{ ++ if (c == '\n') { ++ putDebugChar('\r'); ++ putDebugChar('\n'); ++ } else { ++ putDebugChar(c); ++ } ++} ++#else + static void emit_log_char(char c) + { + LOG_BUF(log_end) = c; +@@ -394,6 +406,7 @@ + if (logged_chars < LOG_BUF_LEN) + logged_chars++; + } ++#endif + + /* + * This is printk. It can be called from any context. We want it to work. +@@ -696,3 +709,4 @@ + tty->driver.write(tty, 0, msg, strlen(msg)); + return; + } ++ +diff -urN linux-mips-orig/drivers/net/ath/ae531x.h linux-mips-new/drivers/net/ath/ae531x.h +--- linux-mips-orig/drivers/net/ath/ae531x.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ae531x.h 2005-12-31 12:33:57.672538976 +0000 +@@ -0,0 +1,43 @@ ++#ifndef __AE531X_H ++#define __AE531X_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++#include "ae531xreg.h" ++#include "ae531xmac.h" ++ ++extern void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, ++ int *rxBuffSizep); ++extern void ae531x_swptr_free(VIRT_ADDR desc); ++extern BOOL ae531x_twisted_enet(void); ++extern void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, ++ UINT16 data); ++extern UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg); ++extern void ae531x_unitLinkGained(int ethUnit); ++extern void ae531x_unitLinkLost(int ethUnit); ++extern void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data); ++extern void ae531x_MACReset(ae531x_MAC_t *MACInfo); ++extern void ae531x_DisableComm(ae531x_MAC_t *MACInfo); ++extern void ae531x_FreeQueues(ae531x_MAC_t *MACInfo); ++extern void ae531x_reset(ae531x_MAC_t *MACInfo); ++extern int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo); ++extern void ae531x_EnableComm(ae531x_MAC_t *MACInfo); ++extern void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo); ++extern void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo); ++extern void ae531x_DmaReset(ae531x_MAC_t *MACInfo); ++extern void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo); ++extern void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data); ++extern void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); ++extern BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo); ++extern UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg); ++extern void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); ++ ++#endif /* __AE531X_H */ +diff -urN linux-mips-orig/drivers/net/ath/ae531xlnx.c linux-mips-new/drivers/net/ath/ae531xlnx.c +--- linux-mips-orig/drivers/net/ath/ae531xlnx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ae531xlnx.c 2005-12-31 12:33:57.673538824 +0000 +@@ -0,0 +1,1303 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Ethernet driver for Atheros' ae531x ethernet MAC. ++ * This is a fairly generic driver, but it's intended ++ * for use in typical Atheros products. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++#include "ae531xreg.h" ++#include "ae531xmac.h" ++#include "ae531x.h" ++ ++#ifndef EXPORT_SYMTAB ++#define EXPORT_SYMTAB ++#endif ++ ++#ifdef DEBUG ++void my_mvPhyShow(int ethUnit); ++#endif ++ ++static struct ar531x_boarddata *ar531x_boardConfig=NULL; ++ ++static char *radioConfig=NULL; ++ ++#define AE531X_LAN_PORT 0 ++#define AE531X_DEV_PER_MAC 1 ++ ++/* ++ * ae531x_MAC_state contains driver-specific linux-specific per-MAC information. ++ * The OSinfo member of ae531x_MAC_t points to one of these. ++ */ ++typedef struct ae531x_MAC_state { ++ int irq; ++ struct tq_struct restart_task; ++ struct net_device_stats stats; ++ struct ae531x_dev_sw_state *dev_sw_state[AE531X_DEV_PER_MAC]; ++ int primary_dev; ++ ae531x_MAC_t MACInfo; /* hardware state */ ++} ae531x_MAC_state_t; ++ ++/* ++ * ae531x_dev_sw_state contains driver-specific linux-specific per-device ++ * information. The net_device priv member points to one of these, and ++ * this structure contains a pointer to the associated MAC information. ++ */ ++ ++typedef struct ae531x_dev_sw_state { ++ int enetUnit; /* system unit number "eth%d" */ ++ int unit_on_MAC; /* MAC-relative unit number */ ++ struct net_device *dev; ++ ae531x_MAC_state_t *MAC_state; /* underlying MAC hw/sw state */ ++} ae531x_dev_sw_state_t; ++ ++/* ++ * Driver-independent linux-specific per-ethernet device software information. ++ */ ++static struct net_device *ae531x_MAC_dev[AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC]; ++ ++/* Driver-dependent per-MAC information */ ++static ae531x_MAC_state_t per_MAC_info[AR531X_NUM_ENET_MAC]; ++ ++/* ++ * Receive buffers need enough room to hold the following: ++ * 1) a max MTU-sized packet. ++ * 2) space for an ethernet header ++ * 3) room at the beginning of the receive buffer in order ++ * to facilitate cooperating drivers that need to PREpend ++ * data. ++ * 4) Depending on configuration, we may need some additional ++ * room at the END of the rx buffer for phy-supplied ++ * trailers (if any). (c.f. CONFIG_VENETDEV) ++ * ++ * The DMA engine insists on 32-bit aligned RX buffers. ++ * TBDXXX: With current code, the IP stack ends up looking ++ * at misaligned headers with word operations. The misaligned ++ * reads are software-emulated via handle_adel_int. We'd ++ * rather align the buffers on a 16-bit boundary, but the ++ * DMA engine doesn't permit it??? ++ */ ++#define ETH_MAX_MTU 1518 ++#define AE531X_RX_BUF_SIZE \ ++ (((RXBUFF_RESERVE + ETH_HLEN + ETH_MAX_MTU + PHY_TRAILER_SIZE) + 3) & ~3) ++ ++/* Forward references to local functions */ ++static void ae531x_TxReap(ae531x_MAC_state_t *MAC_state); ++static int ae531x_phy_poll(void *data); ++static int ae531x_MAC_stop(struct net_device *dev); ++static int ae531x_MAC_open(struct net_device *dev); ++ ++/******************************************************************************* ++* ae531x_MAC_poll checks for received packets, and sends data ++* up the stack. ++*/ ++int ++ae531x_MAC_poll(struct net_device *dev, int *budget) ++{ ++ struct sk_buff *skb; ++ struct sk_buff *newskb; ++ char *rxBufp; ++ int unused_length; ++ VIRT_ADDR rxDesc; ++ int length; ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ae531x_MAC_t *MACInfo; ++ u32 cmdsts; ++ int rx_limit; ++ int rx_received; ++ int rxDescCount; ++ struct net_device *rxdev; ++ int early_stop; ++ int retval; ++#ifdef DEBUG ++ static int rxDescCountMax = 0; ++#endif ++ ++ ARRIVE(); ++ ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ MAC_state = dev_sw_state->MAC_state; ++ MACInfo = &MAC_state->MACInfo; ++ rx_limit = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev->quota; ++ rx_received = 0; ++ ++ rxDescCount = 0; ++ ++ early_stop = 0; ++ do { ++ ae531x_AckIntr(MACInfo, DmaIntRxCompleted); ++ ++ for(;!early_stop;) { ++ rxDesc = MACInfo->rxQueue.curDescAddr; ++ cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc)); ++ ++ AE531X_PRINT(AE531X_DEBUG_RX, ++ ("examine rxDesc %p with cmdsts=0x%x\n", ++ (void *)rxDesc, cmdsts)); ++ ++ if (cmdsts & DescOwnByDma) { ++ /* There's nothing left to process in the RX ring */ ++ goto rx_all_done; ++ } ++ ++ rxDescCount++; ++ ++ AE531X_CONSUME_DESC((&MACInfo->rxQueue)); ++ ++ A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE); ++ ++ /* Process a packet */ ++ length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN; ++ if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) == ++ (DescRxFirst | DescRxLast) ) { ++ /* Descriptor status indicates "NO errors" */ ++ skb = AE531X_DESC_SWPTR_GET(rxDesc); ++ ++ /* ++ * Allocate a replacement skb. ++ * We want to get another buffer ready for Rx ASAP. ++ */ ++ newskb = (struct sk_buff *)ae531x_rxbuf_alloc(MACInfo, &rxBufp, &unused_length); ++ if(newskb == NULL ) { ++ /* ++ * Give this descriptor back to the DMA engine, ++ * and drop the received packet. ++ */ ++ MAC_state->stats.rx_dropped++; ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("Can't allocate new skb\n")); ++ } else { ++ AE531X_DESC_BUFPTR_SET(rxDesc, virt_to_bus(rxBufp)); ++ AE531X_DESC_SWPTR_SET(rxDesc, newskb); ++ } ++ ++ AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma); ++ rxDesc = NULL; /* sanity -- cannot use rxDesc now */ ++ sysWbFlush(); ++ ++ if (newskb == NULL) { ++ retval = 1; ++ goto rx_no_skbs; ++ } else { ++ /* Sync data cache w.r.t. DMA */ ++ A_DATA_CACHE_INVAL(skb->data, length); ++ ++ rxdev = dev_sw_state->dev; ++ ++ if (rxdev == NULL) { ++ /* ++ * We received a packet for a virtual enet device ++ * that is no longer up. Ignore it. ++ */ ++ kfree_skb(skb); ++ continue; ++ } ++ ++ /* Advance data pointer to show that there's data here */ ++ skb_put(skb, length); ++ skb->protocol = eth_type_trans(skb, rxdev); ++ skb->dev = rxdev; ++ rxdev->last_rx = jiffies; ++ rxdev->quota--; ++ ++ if (rx_limit-- < 0) { ++ early_stop=1; ++ /* We've done enough for now -- more later */ ++ AE531X_PRINT(AE531X_DEBUG_RX_STOP, ++ ("Enet%d RX early stop. Quota=%d rxDescCount=%d budget=%d\n", ++ MACInfo->unit, dev->quota, rxDescCount, *budget)); ++ } ++ rx_received++; ++ ++ /* Send the data up the stack */ ++ AE531X_PRINT(AE531X_DEBUG_RX, ++ ("Send data up stack: skb=%p data=%p length=%d\n", ++ (void *)skb, (void *)skb->data, length)); ++ ++ netif_receive_skb(skb); ++ ++ MAC_state->stats.rx_packets++; ++ MAC_state->stats.rx_bytes += length; ++ } ++ } else { ++ /* Descriptor status indicates ERRORS */ ++ MAC_state->stats.rx_errors++; ++ ++ if (cmdsts & (DescRxRunt | DescRxLateColl)) { ++ MAC_state->stats.collisions++; ++ } ++ ++ if (cmdsts & DescRxLengthError) { ++ MAC_state->stats.rx_length_errors++; ++ } ++ ++ if (cmdsts & DescRxCrc) { ++ MAC_state->stats.rx_crc_errors++; ++ } ++ ++ if (cmdsts & DescRxDribbling) { ++ MAC_state->stats.rx_frame_errors++; ++ } ++ ++ AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma); ++ ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("Bad receive. rxDesc=%p cmdsts=0x%8.8x\n", ++ (void *)rxDesc, cmdsts)); ++ } ++ } ++ } while ((!early_stop) && ++ ae531x_ReadDmaReg(MACInfo, DmaStatus) & DmaIntRxCompleted); ++ ++rx_all_done: ++ AE531X_PRINT(AE531X_DEBUG_RX, ++ ("rx done (%d)\n", rxDescCount)); ++ *budget -= rxDescCount; ++ ++ if (!early_stop) { ++ netif_rx_complete(dev); ++ ++ ae531x_SetDmaReg(MACInfo, DmaIntrEnb, ++ DmaIeRxCompleted | DmaIeRxNoBuffer); ++ ae531x_WriteDmaReg(MACInfo, DmaRxPollDemand, 0); ++ } ++ ++ retval = early_stop; ++ ++rx_no_skbs: ++ ++ LEAVE(); ++ ++#ifdef DEBUG ++ if (rxDescCount > rxDescCountMax) { ++ printk("max rx %d\n", rxDescCount); ++ rxDescCountMax = rxDescCount; ++ } ++#endif ++ ++ return retval; ++} ++ ++/******************************************************************************* ++* ae531x_restart stops all ethernet devices associated with a physical MAC, ++* then shuts down the MAC. Then it re-opens all devices that were in use. ++* TBDXXX: needs testing! ++*/ ++static void ++ae531x_restart(void *data) ++{ ++ ae531x_MAC_t *MACInfo = (ae531x_MAC_t *)data; ++ ae531x_MAC_state_t *MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo; ++ struct net_device *saved_dev[AE531X_DEV_PER_MAC]; ++ int i; ++ ++ for (i=0; idev_sw_state[i]->dev) != NULL) { ++ ae531x_MAC_stop(saved_dev[i]); ++ } ++ } ++ ++ for (i=0; iOSinfo; ++ for(;;) { ++ /* Clear any unhandled intr causes. */ ++ ae531x_WriteDmaReg(MACInfo, DmaStatus, UnhandledIntrMask); ++ ++ regIsr = ae531x_ReadDmaReg(MACInfo, DmaStatus); ++ regImr = ae531x_ReadDmaReg(MACInfo, DmaIntrEnb); ++ pendIntrs = regIsr & regImr; ++ ++ AE531X_PRINT(AE531X_DEBUG_INT, ++ ("ethmac%d: intIsr=0x%8.8x intImr=0x%8.8x pendIntrs=0x%8.8x\n", ++ MACInfo->unit, regIsr, regImr, pendIntrs )); ++ ++ if ((pendIntrs & DmaAllIntCauseMask) == 0) ++ break; ++ ++ if ((pendIntrs & DmaIntRxCompleted) || ++ (pendIntrs & DmaIntRxNoBuffer)) { ++ if (netif_rx_schedule_prep(MAC_state->dev_sw_state[MAC_state->primary_dev]->dev)) { ++ ae531x_ClearDmaReg(MACInfo, ++ DmaIntrEnb, ++ DmaIeRxCompleted | DmaIeRxNoBuffer); ++ ae531x_AckIntr(MACInfo, ++ DmaIntRxCompleted | DmaIntRxNoBuffer); ++ (void)ae531x_ReadDmaReg(MACInfo, DmaIntrEnb); ++ __netif_rx_schedule(MAC_state->dev_sw_state[MAC_state->primary_dev]->dev); ++ } else { ++#if 0 ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("%s: Interrupt (0x%8.8x/0x%8.8x) while in poll. regs@%p, pc=%p, ra=%p\n", ++ __FILE__, ++ regIsr, ++ ae531x_ReadDmaReg(MACInfo, DmaIntrEnb), ++ (void *)regs, ++ (void *)regs->cp0_epc, ++ (void *)regs->regs[31])); ++#endif ++ ae531x_AckIntr(MACInfo, ++ DmaIntRxCompleted | DmaIntRxNoBuffer); ++ } ++ } ++ ++ if (pendIntrs & ++ (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow)) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("ethmac%d: TX Error Intr (0x%x)\n", ++ MACInfo->unit, pendIntrs)); ++ ae531x_AckIntr(MACInfo, ++ (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow)); ++ } ++ ++ if (pendIntrs & DmaIntBusError) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("ethmac%d: DMA Bus Error Intr (0x%x)\n", ++ MACInfo->unit, pendIntrs)); ++ ae531x_AckIntr(MACInfo, DmaIntBusError); ++ /* Reset the chip, if it's not already being done */ ++ if (ae531x_IsInResetMode(MACInfo)) { ++ goto intr_done; ++ } ++ ae531x_BeginResetMode(MACInfo); ++ schedule_task(&MAC_state->restart_task); ++ } ++ ++ if (pendIntrs & DmaIntRxStopped) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("ethmac%d: RX Stopped Intr (0x%x)\n", ++ MACInfo->unit, pendIntrs)); ++ ae531x_AckIntr(MACInfo, DmaIntRxStopped); ++ } ++ } ++ ++ intr_done: ++ LEAVE(); ++} ++ ++/******************************************************************************* ++* ae531x_MAC_get_stats returns statistics for a specified device ++*/ ++static struct net_device_stats* ++ae531x_MAC_get_stats(struct net_device *dev) ++{ ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ++ ARRIVE(); ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ MAC_state = dev_sw_state->MAC_state; ++ ++ LEAVE(); ++ return &MAC_state->stats; ++} ++ ++#define AE531X_PHY_POLL_SECONDS 2 ++ ++#if CONFIG_AR5315 ++ ++/******************************************************************************* ++* ae531x_getMACInfo returns the MACInfo of the interface given by unit ++*/ ++ae531x_MAC_t *ae531x_getMAcInfo(int ethUnit) ++{ ++ int i,j; ++ for(i=0;ienetUnit == ethUnit) ++ return (&(per_MAC_info[i].MACInfo)); ++ } ++ } ++ } ++ return NULL; ++} ++ ++ ++#endif ++ ++/******************************************************************************* ++* ae531x_phy_poll periodically checks for changes in phy status ++* (e.g. dropped link). ++*/ ++static int ++ae531x_phy_poll(void *data) ++{ ++ ae531x_dev_sw_state_t *dev_sw_state = (ae531x_dev_sw_state_t *)data; ++ ae531x_MAC_t *MACInfo = &dev_sw_state->MAC_state->MACInfo; ++ int unit = dev_sw_state->enetUnit; ++ ++ while(dev_sw_state->dev!=NULL) { ++ if (MACInfo->port_is_up) { ++ phyCheckStatusChange(unit); ++ } ++ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout(AE531X_PHY_POLL_SECONDS * HZ); ++ } ++ ++ return 0; ++} ++ ++ ++static char invalid_enet_MAC_addr[] = {0, 0, 0, 0, 0, 0}; ++ ++/* ++ * Fetch a pointer to an ethernet's MAC address ++ * in the Board Configuration data (in flash). ++ */ ++char * ++ae531x_enet_mac_address_get(int MACUnit) ++{ ++ /* XXX: Hack for poorly configured boards. ++ * Cannot setup bridging properly (brctl) when both enet ++ * interfaces share the same MAC address. ++ * ++ */ ++ ++#ifdef CONFIG_ASK_MULT_MAC_HACK ++ static u8 enet0Mac[6] = {0x00, 0x0d, 0x0b, 0x13, 0x6b, 0x16}; ++ static u8 enet1Mac[6] = {0x00, 0x0d, 0x0b, 0x13, 0x6b, 0x17}; ++#endif ++ ++ if (!ar531x_boardConfig) ++ return invalid_enet_MAC_addr; ++ if (MACUnit == 0) { ++#ifndef CONFIG_ASK_MULT_MAC_HACK ++ return ar531x_boardConfig->enet0Mac; ++#else ++ return enet0Mac; ++#endif ++ } ++ if (MACUnit == 1) { ++#ifndef CONFIG_ASK_MULT_MAC_HACK ++ return ar531x_boardConfig->enet1Mac; ++#else ++ return enet1Mac; ++#endif ++ } ++ printk("Invalid ethernet MAC unit number (%d)!\n", MACUnit); ++ return invalid_enet_MAC_addr; ++} ++ ++ ++ ++/******************************************************************************* ++* ae531x_MAC_open is the standard Linux open function. It puts ++* hardware into a known good state, allocates queues, starts ++* the phy polling task, and arranges for interrupts to be handled. ++*/ ++static int ++ae531x_MAC_open(struct net_device *dev) ++{ ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ae531x_MAC_t *MACInfo; ++ u8 *MACAddr; ++ int rv; ++ struct tq_struct *restart_task; ++ pid_t phy_poll_pid; ++ ARRIVE(); ++ ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ dev_sw_state->dev = dev; ++ MAC_state = dev_sw_state->MAC_state; ++ MACInfo = &MAC_state->MACInfo; ++ ++ restart_task = &MAC_state->restart_task; ++ restart_task->routine = ae531x_restart; ++ restart_task->data = (void *)MACInfo; ++ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ae531x_MAC_open eth%d ethmac%d macBase=0x%x dmaBase=0x%x irq=0x%x\n", ++ dev_sw_state->enetUnit, ++ MACInfo->unit, ++ MACInfo->macBase, ++ MACInfo->dmaBase, ++ MAC_state->irq)); ++ ++ /* Default MAC address */ ++ MACAddr = ae531x_enet_mac_address_get(MACInfo->unit); ++ memcpy(dev->dev_addr, MACAddr, dev->addr_len ); ++ ++ if (!MACInfo->port_is_up) { ++ /* Bring MAC and PHY out of reset */ ++ ae531x_reset(MACInfo); ++ ++ /* Attach interrupt handler */ ++ rv = request_irq(MAC_state->irq, ae531x_MAC_intr, SA_INTERRUPT, ++ "ae531x_MAC_intr", (void *)MACInfo); ++ if (rv < 0) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("request_irq(0x%x) failed (%d)\n", ++ MAC_state->irq, rv)); ++ goto open_failure; ++ } ++ ++ /* Initialize PHY */ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ("\n --- phyBase: %08x\n", MACInfo->phyBase)); ++ phySetup(MACInfo->unit, MACInfo->phyBase); ++ ++ /* Start thread to poll for phy link status changes */ ++ phy_poll_pid = kernel_thread(ae531x_phy_poll, dev_sw_state, 0); ++ if (phy_poll_pid < 0) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("ethmac%d unable to start Phy Poll thread\n", ++ MACInfo->unit)); ++ } ++ ++ /* Allocate RX/TX Queues */ ++ if (ae531x_AllocateQueues(MACInfo) < 0) { ++ AE531X_PRINT(AE531X_DEBUG_RESET, ("Queue allocation failed")); ++ free_irq(MAC_state->irq, (void *)MACInfo); ++ goto open_failure; ++ } ++ ++ /* Initialize DMA and descriptors */ ++ ae531x_DmaReset(MACInfo); ++ ++ /* Initialize MAC */ ++ ae531x_MACReset(MACInfo); ++ ++ /* Enable Receive/Transmit */ ++ ae531x_EnableComm(MACInfo); ++ ++ MAC_state->primary_dev = dev_sw_state->unit_on_MAC; ++ MACInfo->port_is_up = TRUE; ++ } ++ ++ dev->trans_start = jiffies; ++ SET_MODULE_OWNER(dev); ++ ++ LEAVE(); ++ return 0; ++ ++open_failure: ++ LEAVE(); ++ return -1; ++} ++ ++/* ++ * Shut down MAC hardware. ++ */ ++static void ++ae531x_MAC_shutdown(ae531x_MAC_state_t *MAC_state) ++{ ++ ae531x_MAC_t *MACInfo; ++ ++ MACInfo = &MAC_state->MACInfo; ++ MACInfo->port_is_up = FALSE; ++ ++ /* Disable Receive/Transmit */ ++ ae531x_DisableComm(MACInfo); ++ ++ /* Disable Interrupts */ ++ ae531x_DmaIntDisable(MACInfo); ++ sysWbFlush(); ++ free_irq(MAC_state->irq, (void *)MACInfo); ++ ++ /* Free Transmit & Receive skb's/descriptors */ ++ ae531x_TxReap(MAC_state); /* one last time */ ++ ae531x_FreeQueues(MACInfo); ++} ++ ++/******************************************************************************* ++* ae531x_MAC_stop is the standard Linux stop function. It undoes ++* everything set up by ae531x_MAC_open. ++*/ ++static int ++ae531x_MAC_stop(struct net_device *dev) ++{ ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ae531x_MAC_t *MACInfo; ++ int i; ++ ++ ARRIVE(); ++ ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ MAC_state = dev_sw_state->MAC_state; ++ MACInfo = &MAC_state->MACInfo; ++ ++ for (i=0; idev_sw_state[i]->dev) && ++ (MAC_state->dev_sw_state[i]->dev != dev_sw_state->dev)) { ++ break; ++ } ++ } ++ ++ if (i < AE531X_DEV_PER_MAC) { ++ /* Physical MAC is still in use */ ++ if (MAC_state->primary_dev == dev_sw_state->unit_on_MAC) { ++ /* ++ * If the primary_dev is being stopped ++ * then we need to assign a new one. ++ */ ++ MAC_state->primary_dev = i; ++ } ++ } else { ++ /* Physical MAC is no longer in use */ ++ ae531x_MAC_shutdown(MAC_state); ++ } ++ ++ dev_sw_state->dev = NULL; ++ LEAVE(); ++ return 0; ++} ++ ++/******************************************************************************* ++* ae531x_rxbuf_alloc - Allocate an skb to be associated with an RX descriptor. ++* ++* RETURNS: A pointer to the skb. Also returns a pointer to the underlying ++* buffer and the size of that buffer. ++*/ ++void * ++ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, int *rxBuffSizep) ++{ ++ int buf_size; ++ struct sk_buff *skb; ++ char *rxBuff; ++ int rxBuffSize; ++ ++ buf_size = AE531X_RX_BUF_SIZE; ++ ++ skb = dev_alloc_skb(buf_size); ++ if (skb) { ++ /* skb->dev = dev; */ ++ skb_reserve(skb, RXBUFF_RESERVE); ++ ++ rxBuffSize = skb_tailroom(skb); ++ rxBuff = skb->tail; ++ ++ *rxBuffp = rxBuff; ++ *rxBuffSizep = rxBuffSize; ++ } ++ ++ return skb; ++} ++ ++/******************************************************************************* ++* ae531x_swptr_free - Free the skb, if any, associated with a descriptor. ++*/ ++void ++ae531x_swptr_free(VIRT_ADDR desc) ++{ ++ struct sk_buff *skb; ++ ++ skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(desc); ++ if (skb) { ++ AE531X_DESC_SWPTR_SET(desc, NULL); ++ kfree_skb(skb); ++ } ++} ++ ++/******************************************************************************* ++* ++* ae531x_TxReap - the driver Tx completion routine. ++* ++* This routine reaps sk_buffs which have already been transmitted. ++* ++*/ ++static void ++ae531x_TxReap(ae531x_MAC_state_t *MAC_state) ++{ ++ AE531X_QUEUE *txq; ++ VIRT_ADDR txDesc; ++ UINT32 cmdsts; ++ struct sk_buff *skb; ++ int reaped; ++ ae531x_MAC_t *MACInfo; ++ static int aeUselessReap = 0; ++#ifdef DEBUG ++ static int aeMaxReap = 0; ++#endif ++ ARRIVE(); ++ ++ MACInfo = &MAC_state->MACInfo; ++ txq = &MACInfo->txQueue; ++ reaped = 0; ++ ++ while (1) { ++ ++ txDesc = AE531X_QUEUE_ELE_NEXT_GET(txq, txq->reapDescAddr); ++ if (txDesc == txq->curDescAddr) { ++ break; ++ } ++ ++ cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(txDesc)); ++ if (cmdsts & DescOwnByDma) { ++ break; ++ } ++ ++ /* Release sk_buff associated with completed transmit */ ++ skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(txDesc); ++ if (skb) { ++ kfree_skb(skb); ++ AE531X_DESC_SWPTR_SET(txDesc, NULL); ++ } ++ ++ /* Update statistics according to completed transmit desc */ ++ if (cmdsts & DescTxErrors) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("enetmac%d Tx prior error: 0x%8.8x <0x%8.8x> 0x%8.8x\n", ++ MACInfo->unit, ++ cmdsts, ++ DescTxErrors, ++ (int)txDesc)); ++#ifdef DEBUG ++ //my_mvPhyShow(MACInfo->unit); ++ printk ("ae531xMacControl: 0x%08x\tMacFlowControl: 0x%08x\n", ++ ae531x_ReadMacReg(MACInfo, MacControl), ++ ae531x_ReadMacReg(MACInfo, MacFlowControl)); ++#endif ++ MAC_state->stats.tx_errors++; ++ if (cmdsts & (DescTxLateCollision | DescTxExcCollisions)) { ++ MAC_state->stats.tx_aborted_errors++; ++ } ++ if (cmdsts & (DescTxLostCarrier | DescTxNoCarrier)) { ++ MAC_state->stats.tx_carrier_errors++; ++ } ++ } else { ++ MAC_state->stats.tx_bytes += AE531X_DESC_STATUS_RX_SIZE(cmdsts); ++ MAC_state->stats.tx_packets++; ++ } ++ ++ MAC_state->stats.collisions += ++ ((cmdsts & DescTxCollMask) >> DescTxCollShift); ++ ++ txq->reapDescAddr = txDesc; ++ reaped++; ++ } ++ ++ if (reaped > 0) { ++ int i; ++ ++#ifdef DEBUG ++ if (reaped > aeMaxReap) { ++ aeMaxReap = reaped; ++ printk("max reaped = %d\n", reaped); ++ } ++#endif ++ AE531X_PRINT(AE531X_DEBUG_TX_REAP, ++ ("reaped %d\n", reaped)); ++ ++ /* ++ * Re-start transmit queues for all ethernet devices ++ * associated with this MAC. ++ */ ++ for (i=0; idev_sw_state[i]->dev) ++ netif_start_queue(MAC_state->dev_sw_state[i]->dev); ++ } ++ } else { ++ aeUselessReap++; ++ } ++ ++ LEAVE(); ++} ++ ++ ++/******************************************************************************* ++* ae531x_MAC_start_xmit sends a packet. ++*/ ++static int ++ae531x_MAC_start_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ae531x_MAC_t *MACInfo; ++ u32 buf; ++ u32 ctrlen; ++ u32 length; ++ int mtu; ++ int max_buf_size; ++ VIRT_ADDR txDesc; ++ ++ ARRIVE(); ++ ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ MAC_state = dev_sw_state->MAC_state; ++ MACInfo = &MAC_state->MACInfo; ++ ++ length = skb->len; ++ ++ /* Check if this port is up, else toss packet */ ++ if (!MACInfo->port_is_up) { ++ buf = virt_to_bus(skb->data); ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("eth%d Tx Down, dropping buf=0x%8.8x, length=0x%8.8x, skb=%p\n", ++ dev_sw_state->enetUnit, buf, length, (void *)skb)); ++ ++ MAC_state->stats.tx_dropped++; ++ MAC_state->stats.tx_carrier_errors++; ++ goto dropFrame; ++ } ++ ++ if (ae531x_IsInResetMode(MACInfo)) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("eth%d Tx: In Chip reset - drop frame\n", ++ dev_sw_state->enetUnit)); ++ ++ MAC_state->stats.tx_dropped++; ++ MAC_state->stats.tx_aborted_errors++; ++ goto dropFrame; ++ } ++ ++ /* Check if we can transport this packet */ ++ length = max((u32)60, length); /* total length */ ++ mtu = dev->mtu; ++ max_buf_size = mtu + ETH_HLEN; ++ if (length > max_buf_size) { ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("eth%d Tx: length %d too long. mtu=%d, trailer=%d\n", ++ dev_sw_state->enetUnit, length, mtu, PHY_TRAILER_SIZE)); ++ ++ MAC_state->stats.tx_errors++; ++ MAC_state->stats.tx_aborted_errors++; ++ ++ goto dropFrame; ++ } ++ ++ /* Reap any old, completed Tx descriptors */ ++ ae531x_TxReap(MAC_state); ++ ++ txDesc = MACInfo->txQueue.curDescAddr; ++ if (txDesc == MACInfo->txQueue.reapDescAddr) { ++ int i; ++ ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("eth%d Tx: cannot get txDesc\n", ++ dev_sw_state->enetUnit)); ++ ++ MAC_state->stats.tx_dropped++; ++ MAC_state->stats.tx_fifo_errors++; ++ ++ /* ++ * Stop transmit queues for any ethernet devices ++ * associated with this MAC. ++ */ ++#if 0 /* XXX: no way to recover from queue stop until ae531x_MAC_tx_timeout() ++ * is rewritten to avoid calls to shedule(). ++ */ ++ for (i=0; idev_sw_state[i]->dev) ++ netif_stop_queue(MAC_state->dev_sw_state[i]->dev); ++ } ++#endif ++ goto dropFrame; ++ } ++ ++ /* We won't fail now; so consume this descriptor */ ++ AE531X_CONSUME_DESC((&MACInfo->txQueue)); ++ ++ /* Update the descriptor */ ++ buf = virt_to_bus(skb->data); ++ AE531X_DESC_BUFPTR_SET(txDesc, buf); ++ AE531X_DESC_SWPTR_SET(txDesc, skb); ++ ctrlen = AE531X_DESC_CTRLEN_GET(txDesc); ++ ctrlen = (ctrlen & (DescEndOfRing)) | ++ DescTxFirst | ++ DescTxLast | ++ DescTxIntEnable; ++ ++ ctrlen |= ((length << DescSize1Shift) & DescSize1Mask); ++ ++ AE531X_DESC_CTRLEN_SET(txDesc, ctrlen); ++ AE531X_DESC_STATUS_SET(txDesc, DescOwnByDma); ++ ++ /* Alert DMA engine to resume Tx */ ++ ae531x_WriteDmaReg(MACInfo, DmaTxPollDemand, 0); ++ sysWbFlush(); ++ ++ AE531X_PRINT(AE531X_DEBUG_TX, ++ ("eth%d Tx: Desc=0x%8.8x, L=0x%8.8x, D=0x%8.8x, d=0x%8.8x, length=0x%8.8x\n", ++ dev_sw_state->enetUnit, ++ (UINT32)txDesc, ++ AE531X_DESC_CTRLEN_GET(txDesc), ++ buf, ++ AE531X_DESC_LNKBUF_GET(txDesc), ++ length)); ++ ++ /* Tell upper layers to keep it coming */ ++ dev->trans_start = jiffies; ++ ++ LEAVE(); ++ ++ return 0; ++ ++dropFrame: ++ kfree_skb(skb); ++ LEAVE(); ++ return 0; ++} ++ ++ ++/******************************************************************************* ++* ae531x_MAC_tx_timeout handles transmit timeouts ++*/ ++static void ++ae531x_MAC_tx_timeout(struct net_device *dev) ++{ ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ae531x_MAC_t *MACInfo; ++ ++ ARRIVE(); ++ ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ MAC_state = dev_sw_state->MAC_state; ++ MACInfo = &MAC_state->MACInfo; ++ ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("enet%d: Tx timeout\n", dev_sw_state->enetUnit)); ++ ++ ae531x_restart(MACInfo); ++ ++ LEAVE(); ++} ++ ++ ++/******************************************************************************* ++* ae531x_MAC_do_ioctl is a placeholder for future ioctls. ++*/ ++static int ++ae531x_MAC_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++{ ++ int rv; ++ ae531x_MAC_t *MACInfo; ++ struct ioctl_data { ++ u32 unit; ++ u32 addr; ++ u32 data; ++ } *req; ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ++ ARRIVE(); ++ ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ MAC_state = dev_sw_state->MAC_state; ++ MACInfo = &MAC_state->MACInfo; ++ ++ req = (struct ioctl_data *)ifr->ifr_data; ++ ++ switch( cmd ) { ++ default: ++ AE531X_PRINT(AE531X_DEBUG_ERROR, ++ ("Unsupported ioctl: 0x%x\n", cmd)); ++ rv = -EOPNOTSUPP; ++ } ++ ++ LEAVE(); ++ return rv; ++} ++ ++static void ++ae531x_MAC_setup_fntable(struct net_device *dev) ++{ ++ ARRIVE(); ++ ++ dev->get_stats = ae531x_MAC_get_stats; ++ dev->open = ae531x_MAC_open; ++ dev->stop = ae531x_MAC_stop; ++ dev->hard_start_xmit = ae531x_MAC_start_xmit; ++ dev->do_ioctl = ae531x_MAC_do_ioctl; ++ dev->poll = ae531x_MAC_poll; ++ dev->weight = 16; ++#if 0 /* XXX: currently, ae531x_MAC_tx_timeout() will call functions ++ * that in turn call schedule(). this is BAD, since the ++ * timeout call runs at interrupt time. until ae531x_MAC_tx_timeout ++ * is rewritten to avoid schedule() calls, we do not use it. ++ */ ++ dev->tx_timeout = ae531x_MAC_tx_timeout; ++#else ++ dev->tx_timeout = NULL; ++#endif ++ dev->features = NETIF_F_HW_CSUM |\ ++ NETIF_F_HIGHDMA; ++ ++ LEAVE(); ++} ++ ++static void ++ar5312EepromRead(char *EepromAddr, u_int16_t id, unsigned int off, ++ unsigned int nbytes, char *data) ++{ ++ int i; ++ ++ for (i=0; i>8) & ++ (AR531X_REV_MAJ | AR531X_REV_MIN))); ++ switch (devid) { ++ case AR5212_AR5312_REV2: ++ case AR5212_AR5312_REV7: ++ /* Need to determine if we have a 5312 or a 2312 since they ++ have the same Silicon Rev ID*/ ++ ar5312EepromRead(radioConfig,0,2*AR531X_RADIO_MASK_OFF,2, ++ (char *) &radioMask); ++ if ((radioMask & AR531X_RADIO0_MASK) != 0) { ++ return 2; ++ } ++ return 1; ++ case AR5212_AR2313_REV8: ++ return 1; ++ } ++ ++ /* default to 1 */ ++ return 1; ++} ++ ++BOOL ++ae531x_twisted_enet(void) ++{ ++ int wisoc_revision; ++ ++ wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S; ++ if ( (wisoc_revision == AR531X_REV_MAJ_AR2313) || ++ /* next clause is used to determine AR2312, based on number of MACs. ++ * must do this since revision is same for 5312 and 2312. ++ */ ++ (wisoc_revision == AR531X_REV_MAJ_AR5312 && ae531x_get_numMACs() == 1) ) { ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++int ++ae531x_get_board_config(void) ++{ ++ int dataFound; ++ char *bd_config; ++ ++ /* ++ * Find start of Board Configuration data, using heuristics: ++ * Search back from the (aliased) end of flash by 0x1000 bytes ++ * at a time until we find the string "5311", which marks the ++ * start of Board Configuration. Give up if we've searched ++ * more than 500KB. ++ */ ++ dataFound = 0; ++ for (bd_config = (char *)0xbffff000; ++ bd_config > (char *)0xbff80000; ++ bd_config -= 0x1000) ++ { ++ if ( *(int *)bd_config == AR531X_BD_MAGIC) { ++ dataFound = 1; ++ break; ++ } ++ } ++ ++ if (!dataFound) { ++ printk("Could not find Board Configuration Data\n"); ++ bd_config = NULL; ++ } ++ ++ ar531x_boardConfig = (struct ar531x_boarddata *) bd_config; ++ ++ return(dataFound); ++} ++ ++int ++ae531x_get_radio_config(void) ++{ ++ int dataFound; ++ char *radio_config; ++ ++ /* ++ * Now find the start of Radio Configuration data, using heuristics: ++ * Search forward from Board Configuration data by 0x1000 bytes ++ * at a time until we find non-0xffffffff. ++ */ ++ dataFound = 0; ++ for (radio_config = ((char *) ar531x_boardConfig) + 0x1000; ++ radio_config < (char *)0xbffff000; ++ radio_config += 0x1000) ++ { ++ if (*(int *)radio_config != 0xffffffff) { ++ dataFound = 1; ++ break; ++ } ++ } ++ ++ if (!dataFound) { /* AR2316 relocates radio config to new location */ ++ dataFound = 0; ++ for (radio_config = ((char *) ar531x_boardConfig) + 0xf8; ++ radio_config < (char *)0xbffff0f8; ++ radio_config += 0x1000) ++ { ++ if (*(int *)radio_config != 0xffffffff) { ++ dataFound = 1; ++ break; ++ } ++ } ++ } ++ ++ if (!dataFound) { ++ printk("Could not find Radio Configuration data\n"); ++ radio_config = NULL; ++ } ++ radioConfig = radio_config; ++ return(dataFound); ++} ++ ++static int __init ++ae531x_MAC_setup(void) ++{ ++ int next_dev, i; ++ struct net_device *dev; ++ ae531x_dev_sw_state_t *dev_sw_state; ++ ae531x_MAC_state_t *MAC_state; ++ ae531x_MAC_t *MACInfo; ++ char *addr; ++ ++ ARRIVE(); ++ ++ MOD_INC_USE_COUNT; ++ for (i=0;i=0; ++ i++, next_dev--){ ++ ++ /* if MAC is bogus in config data, skip */ ++ addr = ae531x_enet_mac_address_get(next_dev); ++ if((*(u32 *)addr == 0xffffffff) && (*(u16 *)(addr+4)==0xffff)){ ++ /* bogus MAC config data */ ++ continue; ++ } ++ ++ dev = ae531x_MAC_dev[next_dev] = ++ init_etherdev(NULL, sizeof(ae531x_dev_sw_state_t)); ++ ++ if (dev == NULL) { ++ LEAVE(); ++ return -1; ++ } ++ ++ ae531x_MAC_setup_fntable(dev); ++ ++ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; ++ dev_sw_state->enetUnit = next_dev; ++ dev_sw_state->unit_on_MAC = 0; ++ MAC_state = &per_MAC_info[next_dev]; ++ dev_sw_state->MAC_state = MAC_state; ++ MAC_state->dev_sw_state[AE531X_LAN_PORT] = dev_sw_state; ++ MAC_state->primary_dev = -1; ++ ++ /* Initialize per-MAC information */ ++ MACInfo = &MAC_state->MACInfo; ++ ++ MACInfo->unit = next_dev; ++ ++ if (MACInfo->unit == 0) { ++ MACInfo->macBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_MAC_OFFSET); ++ MACInfo->dmaBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_DMA_OFFSET); ++ MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET); ++ MAC_state->irq = AR531X_IRQ_ENET0_INTRS; ++ } else { ++#ifndef CONFIG_AR5315 ++ MACInfo->macBase = (u32) (PHYS_TO_K1(AR531X_ENET1)+AE531X_MAC_OFFSET); ++ MACInfo->dmaBase = (u32) (PHYS_TO_K1(AR531X_ENET1)+AE531X_DMA_OFFSET); ++ if (ae531x_twisted_enet()) { ++ MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET); ++ } else { ++ MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_PHY_OFFSET); ++ } ++ MAC_state->irq = AR531X_IRQ_ENET1_INTRS; ++#endif ++ } ++ ++ MACInfo->OSinfo = (void *)MAC_state; ++ ++ } ++ ++ LEAVE(); ++ return 0; ++} ++module_init(ae531x_MAC_setup); ++ ++/******************************************************************************* ++* ae531x_MAC_unload is the module unload function ++*/ ++static void __exit ++ae531x_MAC_unload(void) ++{ ++ int i; ++ ++ for (i=0;ipriv)->dev) != NULL) ++ ae531x_MAC_stop(ae531x_MAC_dev[i]); ++ ae531x_MAC_dev[i] = NULL; ++ } ++ } ++ MOD_DEC_USE_COUNT; ++} ++ ++MODULE_AUTHOR("Atheros Communications, Inc."); ++MODULE_DESCRIPTION("Support for Atheros WiSoC Ethernet device"); ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("Atheros"); ++#endif ++module_exit(ae531x_MAC_unload); +diff -urN linux-mips-orig/drivers/net/ath/ae531xmac.c linux-mips-new/drivers/net/ath/ae531xmac.c +--- linux-mips-orig/drivers/net/ath/ae531xmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ae531xmac.c 2005-12-31 12:33:57.673538824 +0000 +@@ -0,0 +1,951 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++ ++/* ++ * Ethernet driver for Atheros' ae531x ethernet MAC. ++ */ ++ ++#if linux ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++#endif /* linux */ ++ ++#include "ae531xreg.h" ++#include "ae531xmac.h" ++ ++#ifdef DEBUG ++int ae531x_MAC_debug = AE531X_DEBUG_ERROR; ++#else ++int ae531x_MAC_debug = 0; ++#endif ++ ++extern char *ae531x_enet_mac_address_get(int); ++ ++/* Forward references to local functions */ ++static void ae531x_QueueDestroy(AE531X_QUEUE *q); ++ ++ ++/****************************************************************************** ++* ++* ae531x_ReadMacReg - read AE MAC register ++* ++* RETURNS: register value ++*/ ++UINT32 ++ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg) ++{ ++ UINT32 addr = MACInfo->macBase+reg; ++ UINT32 data; ++ ++ data = RegRead(addr); ++ return data; ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_WriteMacReg - write AE MAC register ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data) ++{ ++ UINT32 addr = MACInfo->macBase+reg; ++ ++ RegWrite(data, addr); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_SetMacReg - set bits in AE MAC register ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) ++{ ++ UINT32 addr = MACInfo->macBase+reg; ++ UINT32 data = RegRead(addr); ++ ++ data |= val; ++ RegWrite(data, addr); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_ClearMacReg - clear bits in AE MAC register ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) ++{ ++ UINT32 addr = MACInfo->macBase+reg; ++ UINT32 data = RegRead(addr); ++ ++ data &= ~val; ++ RegWrite(data, addr); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_ReadDmaReg - read AE DMA register ++* ++* RETURNS: register value ++*/ ++UINT32 ++ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg) ++{ ++ UINT32 addr = MACInfo->dmaBase+reg; ++ UINT32 data = RegRead(addr); ++ ++ return data; ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_WriteDmaReg - write AE DMA register ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data) ++{ ++ UINT32 addr = MACInfo->dmaBase+reg; ++ ++ RegWrite(data, addr); ++} ++ ++ ++/****************************************************************************** ++ * ++ * ae531x_AckIntr - clear interrupt bits in the status register. ++ * Note: Interrupt bits are *cleared* by writing a 1. ++ */ ++void ++ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data) ++{ ++ ae531x_WriteDmaReg(MACInfo, DmaStatus, data); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_SetDmaReg - set bits in an AE DMA register ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) ++{ ++ UINT32 addr = MACInfo->dmaBase+reg; ++ UINT32 data = RegRead(addr); ++ ++ data |= val; ++ RegWrite(data, addr); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_ClearDmaReg - clear bits in an AE DMA register ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) ++{ ++ UINT32 addr = MACInfo->dmaBase+reg; ++ UINT32 data = RegRead(addr); ++ ++ data &= ~val; ++ RegWrite(data, addr); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_ReadMiiReg - read PHY registers via AE MAC Mii addr/data registers ++* ++* RETURNS: register value ++*/ ++UINT32 ++ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg) ++{ ++ UINT32 data; ++ UINT32 addr = phyBase+reg; ++ ++ data = RegRead(addr); ++ return data; ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_WriteMiiReg - write PHY registers via AE MAC Mii addr/data registers ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data) ++{ ++ UINT32 addr = phyBase+reg; ++ ++ RegWrite(data, addr); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_MiiRead - read AE Mii register ++* ++* RETURNS: register value ++*/ ++UINT16 ++ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg) ++{ ++ UINT32 addr; ++ UINT16 data; ++ ++ addr = ((phyAddr << MiiDevShift) & MiiDevMask) | ((reg << MiiRegShift) & MiiRegMask); ++ ++ ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr ); ++ do { ++ /* nop */ ++ } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy); ++ ++ data = ae531x_ReadMiiReg(phyBase, MacMiiData) & 0xFFFF; ++ ++ return data; ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_MiiWrite - write AE Mii register ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data) ++{ ++ UINT32 addr; ++ ++ ae531x_WriteMiiReg(phyBase, MacMiiData, data ); ++ ++ addr = ((phyAddr << MiiDevShift) & MiiDevMask) | ++ ((reg << MiiRegShift) & MiiRegMask) | MiiWrite; ++ ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr ); ++ ++ do { ++ /* nop */ ++ } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy); ++} ++ ++ ++/******************************************************************************* ++* ae531x_BeginResetMode - enter a special "reset mode" in which ++* -no interrupts are expected from the device ++* -the device will not transmit nor receive ++* -attempts to send or receive will return with an error and ++* -the device will be reset at the next convenient opportunity. ++*/ ++void ++ae531x_BeginResetMode(ae531x_MAC_t *MACInfo) ++{ ++ /* Set the reset flag */ ++ MACInfo->aeProcessRst = 1; ++} ++ ++ ++/******************************************************************************* ++* ae531x_EndResetMode - exit the special "reset mode" entered ++* earlier via a call to ae531x_BeginResetMode. ++*/ ++void ++ae531x_EndResetMode(ae531x_MAC_t *MACInfo) ++{ ++ MACInfo->aeProcessRst = 0; ++} ++ ++ ++/******************************************************************************* ++* ae531x_IsInResetMode - determine whether or not the device is ++* currently in "reset mode" (i.e. that a device reset is pending) ++*/ ++BOOL ++ae531x_IsInResetMode(ae531x_MAC_t *MACInfo) ++{ ++ return MACInfo->aeProcessRst; ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_DmaRxStart - Start Rx ++* ++* RETURNS: N/A ++*/ ++static void ++ae531x_DmaRxStart(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_SetDmaReg(MACInfo, DmaControl, DmaRxStart); ++ sysWbFlush(); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_DmaRxStop - Stop Rx ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_DmaRxStop(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_ClearDmaReg(MACInfo, DmaControl, DmaRxStart); ++ sysWbFlush(); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_DmaTxStart - Start Tx ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_DmaTxStart(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_SetDmaReg(MACInfo, DmaControl, DmaTxStart); ++ sysWbFlush(); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_DmaTxStop - Stop Tx ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_DmaTxStop(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_ClearDmaReg(MACInfo, DmaControl, DmaTxStart); ++ sysWbFlush(); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_DmaIntEnable - Enable DMA interrupts ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntEnable); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_DmaIntDisable - Disable DMA interrupts ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_DmaIntClear - Clear DMA interrupts ++* ++* RETURNS: N/A ++*/ ++static void ++ae531x_DmaIntClear(ae531x_MAC_t *MACInfo) ++{ ++ /* clear all interrupt requests */ ++ ae531x_WriteDmaReg(MACInfo, DmaStatus, ++ ae531x_ReadDmaReg(MACInfo, DmaStatus)); ++} ++ ++ ++/****************************************************************************** ++* Initialize generic queue data ++*/ ++void ++ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count) ++{ ++ ARRIVE(); ++ q->firstDescAddr = pMem; ++ q->lastDescAddr = (VIRT_ADDR)((UINT32)q->firstDescAddr + ++ (count - 1) * AE531X_QUEUE_ELE_SIZE); ++ q->curDescAddr = q->firstDescAddr; ++ q->count = count; ++ LEAVE(); ++} ++ ++ ++/****************************************************************************** ++* ae531x_TxQueueCreate - create a circular queue of descriptors for Transmit ++*/ ++static int ++ae531x_TxQueueCreate(ae531x_MAC_t *MACInfo, ++ AE531X_QUEUE *q, ++ char *pMem, ++ int count) ++{ ++ int i; ++ VIRT_ADDR descAddr; ++ ++ ARRIVE(); ++ ++ ae531x_QueueInit(q, pMem, count); ++ q->reapDescAddr = q->lastDescAddr; ++ ++ /* Initialize Tx buffer descriptors. */ ++ for (i=0, descAddr=q->firstDescAddr; ++ ilastDescAddr, ++ DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr)); ++ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Txbuf begin = %x, end = %x\n", ++ MACInfo->unit, ++ (UINT32)q->firstDescAddr, ++ (UINT32)q->lastDescAddr)); ++ ++ LEAVE(); ++ return 0; ++} ++ ++ ++/****************************************************************************** ++* ae531x_RxQueueCreate - create a circular queue of Rx descriptors ++*/ ++int ++ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, ++ AE531X_QUEUE *q, ++ char *pMem, ++ int count) ++{ ++ int i; ++ VIRT_ADDR descAddr; ++ ++ ARRIVE(); ++ ++ ae531x_QueueInit(q, pMem, count); ++ q->reapDescAddr = NULL; ++ ++ ++ /* Initialize Rx buffer descriptors */ ++ for (i=0, descAddr=q->firstDescAddr; ++ iunit)); ++ ae531x_QueueDestroy(q); ++ return -1; ++ } ++ AE531X_DESC_SWPTR_SET(descAddr, swptr); ++ ++ AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma); ++ AE531X_DESC_CTRLEN_SET(descAddr, rxBufferSize); ++ AE531X_DESC_BUFPTR_SET(descAddr, virt_to_bus(rxBuffer)); ++ AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0); ++ } /* for each desc */ ++ ++ /* Make the queue circular */ ++ AE531X_DESC_CTRLEN_SET(q->lastDescAddr, ++ DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr)); ++ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Rxbuf begin = %x, end = %x\n", ++ MACInfo->unit, ++ (UINT32)q->firstDescAddr, ++ (UINT32)q->lastDescAddr)); ++ ++ LEAVE(); ++ return 0; ++} ++ ++ ++/****************************************************************************** ++* ae531x_QueueDestroy -- Free all buffers and descriptors associated ++* with a queue. ++*/ ++static void ++ae531x_QueueDestroy(AE531X_QUEUE *q) ++{ ++ int i; ++ int count; ++ VIRT_ADDR descAddr; ++ ++ ARRIVE(); ++ ++ count = q->count; ++ ++ for (i=0, descAddr=q->firstDescAddr; ++ itxQueue); ++} ++ ++static void ++ae531x_RxQueueDestroy(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_QueueDestroy(&MACInfo->rxQueue); ++} ++ ++ ++/****************************************************************************** ++* ae531x_AllocateQueues - Allocate receive and transmit queues ++*/ ++int ++ae531x_AllocateQueues(ae531x_MAC_t *MACInfo) ++{ ++ size_t QMemSize; ++ char *pTxBuf = NULL; ++ char *pRxBuf = NULL; ++ ++ ARRIVE(); ++ ++ MACInfo->txDescCount = AE531X_TX_DESC_COUNT_DEFAULT; ++ QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->txDescCount; ++ pTxBuf = MALLOC(QMemSize); ++ if (pTxBuf == NULL) { ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Failed to allocate TX queue\n", MACInfo->unit)); ++ goto AllocQFail; ++ } ++ ++ if (ae531x_TxQueueCreate(MACInfo, &MACInfo->txQueue, pTxBuf, ++ MACInfo->txDescCount) < 0) ++ { ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Failed to create TX queue\n", MACInfo->unit)); ++ goto AllocQFail; ++ } ++ ++ MACInfo->rxDescCount = AE531X_RX_DESC_COUNT_DEFAULT; ++ QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->rxDescCount; ++ pRxBuf = MALLOC(QMemSize); ++ if (pRxBuf == NULL) { ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Failed to allocate RX queue\n", MACInfo->unit)); ++ goto AllocQFail; ++ } ++ ++ if (ae531x_RxQueueCreate(MACInfo, &MACInfo->rxQueue, pRxBuf, ++ MACInfo->rxDescCount) < 0) ++ { ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Failed to create RX queue\n", MACInfo->unit)); ++ goto AllocQFail; ++ } ++ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Memory setup complete.\n", MACInfo->unit)); ++ ++ LEAVE(); ++ return 0; ++ ++AllocQFail: ++ MACInfo->txDescCount = 0; /* sanity */ ++ MACInfo->rxDescCount = 0; /* sanity */ ++ ++ if (pTxBuf) { ++ FREE(pTxBuf); ++ } ++ if (pRxBuf) { ++ FREE(pRxBuf); ++ } ++ ++ LEAVE(); ++ return -1; ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_FreeQueues - Free Transmit & Receive queues ++*/ ++void ++ae531x_FreeQueues(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_TxQueueDestroy(MACInfo); ++ FREE(MACInfo->txQueue.firstDescAddr); ++ ++ ae531x_RxQueueDestroy(MACInfo); ++ FREE(MACInfo->rxQueue.firstDescAddr); ++} ++ ++/****************************************************************************** ++* ++* ae531x_DmaReset - Reset DMA and TLI controllers ++* ++* RETURNS: N/A ++*/ ++void ++ae531x_DmaReset(ae531x_MAC_t *MACInfo) ++{ ++ int i; ++ UINT32 descAddr; ++ ++ ARRIVE(); ++ ++ /* Disable device interrupts prior to any errors during stop */ ++ intDisable(MACInfo->ilevel); ++ ++ /* Disable MAC rx and tx */ ++ ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable)); ++ ++ udelay(1); ++ ++ /* Reset dma controller */ ++ ++ ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaResetOn); ++ ++ /* Delay 2 usec */ ++ sysUDelay(2); ++ ++ /* Flush the rx queue */ ++ descAddr = (UINT32)MACInfo->rxQueue.firstDescAddr; ++ MACInfo->rxQueue.curDescAddr = MACInfo->rxQueue.firstDescAddr; ++ for (i=0; ++ i<(MACInfo->rxDescCount); ++ i++, descAddr += AE531X_QUEUE_ELE_SIZE) { ++ AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma); ++ } ++ ++ /* Flush the tx queue */ ++ descAddr = (UINT32)MACInfo->txQueue.firstDescAddr; ++ MACInfo->txQueue.curDescAddr = MACInfo->txQueue.firstDescAddr; ++ MACInfo->txQueue.reapDescAddr = MACInfo->txQueue.lastDescAddr; ++ for (i=0; ++ i<(MACInfo->txDescCount); ++ i++, descAddr += AE531X_QUEUE_ELE_SIZE) { ++ AE531X_DESC_STATUS_SET (descAddr, 0); ++ } ++ ++ /* Set init register values */ ++ ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaBusModeInit); ++ ++ /* Install the first Tx and Rx queues on the device */ ++ ae531x_WriteDmaReg(MACInfo, DmaRxBaseAddr, ++ virt_to_bus(MACInfo->rxQueue.firstDescAddr)); ++ ae531x_WriteDmaReg(MACInfo, DmaTxBaseAddr, ++ virt_to_bus(MACInfo->txQueue.firstDescAddr)); ++ ++ ++ ae531x_WriteDmaReg(MACInfo, DmaControl, DmaStoreAndForward); ++ ++ ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable); ++ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d: DMA RESET!\n", MACInfo->unit)); ++ ++ /* Turn on device interrupts -- enable most errors */ ++ ae531x_DmaIntClear(MACInfo); /* clear interrupt requests */ ++ ae531x_DmaIntEnable(MACInfo); /* enable interrupts */ ++ ++ ae531x_EndResetMode(MACInfo); ++ ++ intEnable(MACInfo->ilevel); ++ ++ LEAVE(); ++} ++ ++ ++/****************************************************************************** ++* ++* ae531x_MACAddressSet - Set the ethernet address ++* ++* Sets the ethernet address according to settings in flash. ++* ++* RETURNS: void ++*/ ++static void ++ae531x_MACAddressSet(ae531x_MAC_t *MACInfo) ++{ ++ unsigned int data; ++ UINT8 *macAddr; ++ ++ ARRIVE(); ++ ++ macAddr = ae531x_enet_mac_address_get(MACInfo->unit); ++ ++ /* set our MAC address */ ++ data = (macAddr[5]<<8) | macAddr[4]; ++ ae531x_WriteMacReg(MACInfo, MacAddrHigh, data ); ++ ++ data = (macAddr[3]<<24) | (macAddr[2]<<16) | (macAddr[1]<<8) | macAddr[0]; ++ ae531x_WriteMacReg(MACInfo, MacAddrLow, data ); ++ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ ("ethmac%d Verify MAC address %8.8X %8.8X \n", ++ MACInfo->unit, ++ ae531x_ReadMacReg(MACInfo, MacAddrLow), ++ ae531x_ReadMacReg(MACInfo, MacAddrHigh))); ++ ++ AE531X_PRINT(AE531X_DEBUG_RESET, ++ (" sb = %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", ++ 0xff&macAddr[0], ++ 0xff&macAddr[1], ++ 0xff&macAddr[2], ++ 0xff&macAddr[3], ++ 0xff&macAddr[4], ++ 0xff&macAddr[5])); ++ LEAVE(); ++} ++ ++ ++/****************************************************************************** ++* ++* ae_SetMACFromPhy - read Phy settings and update Mac ++* with current duplex and speed. ++* ++* RETURNS: ++*/ ++static void ++ae531x_SetMACFromPhy(ae531x_MAC_t *MACInfo) ++{ ++ UINT32 macCtl; ++ BOOL fullDuplex; ++ UINT32 timeout; ++ ++ ARRIVE(); ++ ++ timeout = jiffies+(HZ/1000)*AE531X_NEGOT_TIMEOUT; ++ ++ /* Get duplex mode from Phy */ ++ while (((fullDuplex = phyIsFullDuplex(MACInfo->unit)) == -1) && ++ (jiffies <= timeout)); ++ ++ /* Flag is set for full duplex mode, else cleared */ ++ macCtl = ae531x_ReadMacReg(MACInfo, MacControl); ++ ++ if (fullDuplex) { ++ /* set values of control registers */ ++ macCtl &= ~MacDisableRxOwn; ++ macCtl |= MacFullDuplex; ++ ae531x_WriteMacReg(MACInfo, MacControl, macCtl); ++ ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitFdx); ++ } else { ++ /* set values of control registers */ ++ ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitHdx); ++ macCtl |= MacDisableRxOwn; ++ macCtl &= ~MacFullDuplex; ++ ae531x_WriteMacReg(MACInfo, MacControl, macCtl); ++ } ++ ++ LEAVE(); ++} ++ ++ ++/****************************************************************************** ++* ae531x_MACReset -- sets MAC address and duplex. ++*/ ++void ++ae531x_MACReset(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_MACAddressSet(MACInfo); ++#ifndef CONFIG_AR5315 ++ ae531x_SetMACFromPhy(MACInfo); ++#endif ++} ++ ++ ++/****************************************************************************** ++* ae531x_EnableComm -- enable Transmit and Receive ++*/ ++void ++ae531x_EnableComm(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_SetMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable)); ++ ae531x_DmaRxStart(MACInfo); /* start receiver */ ++ ae531x_DmaTxStart(MACInfo); /* start transmitter */ ++} ++ ++ ++/****************************************************************************** ++* ae531x_DisableComm -- disable Transmit and Receive ++*/ ++void ++ae531x_DisableComm(ae531x_MAC_t *MACInfo) ++{ ++ ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable)); ++} ++ ++ ++/****************************************************************************** ++* ae531x_reset -- Cold reset ethernet interface ++*/ ++void ++ae531x_reset(ae531x_MAC_t *MACInfo) ++{ ++ UINT32 mask = 0; ++ UINT32 regtmp; ++#ifndef CONFIG_AR5315 ++ ++ if (MACInfo->unit == 0) { ++ mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0; ++ } else { ++ mask = AR531X_RESET_ENET1 | AR531X_RESET_EPHY1; ++ } ++ ++ /* Put into reset */ ++ regtmp = sysRegRead(AR531X_RESET); ++ sysRegWrite(AR531X_RESET, regtmp | mask); ++ sysMsDelay(15); ++ ++ /* Pull out of reset */ ++ regtmp = sysRegRead(AR531X_RESET); ++ sysRegWrite(AR531X_RESET, regtmp & ~mask); ++ sysUDelay(25); ++ ++ /* Enable */ ++ if (MACInfo->unit == 0) { ++ mask = AR531X_ENABLE_ENET0; ++ } else { ++ mask = AR531X_ENABLE_ENET1; ++ } ++ regtmp = sysRegRead(AR531X_ENABLE); ++ sysRegWrite(AR531X_ENABLE, regtmp | mask); ++#else ++ if (MACInfo->unit == 0) { ++ mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0; ++ } ++ /* Enable Arbitration for Ethernet bus */ ++ regtmp = sysRegRead(AR531XPLUS_AHB_ARB_CTL); ++ regtmp |= ARB_ETHERNET; ++ sysRegWrite(AR531XPLUS_AHB_ARB_CTL, regtmp); ++ ++ /* Put into reset */ ++ regtmp = sysRegRead(AR531X_RESET); ++ sysRegWrite(AR531X_RESET, regtmp | mask); ++ sysMsDelay(10); ++ ++ /* Pull out of reset */ ++ regtmp = sysRegRead(AR531X_RESET); ++ sysRegWrite(AR531X_RESET, regtmp & ~mask); ++ sysMsDelay(10); ++ ++ regtmp = sysRegRead(AR531XPLUS_IF_CTL); ++ regtmp |= IF_TS_LOCAL; ++ sysRegWrite(AR531XPLUS_IF_CTL, regtmp); ++#endif ++} ++ ++ ++/****************************************************************************** ++* ae531x_unitLinkLost -- Called from PHY layer to notify the MAC layer ++* that there are no longer any live links associated with a MAC. ++*/ ++void ++ae531x_unitLinkLost(int ethUnit) ++{ ++ AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE, ++ ("enetmac%d link down\n", ethUnit)); ++} ++ ++ ++/****************************************************************************** ++* ae531x_unitLinkGained -- Called from PHY layer to notify the MAC layer ++* that there are 1 or more live links associated with a MAC. ++*/ ++void ++ae531x_unitLinkGained(int ethUnit) ++{ ++#if CONFIG_AR5315 ++#define AE531X_POLL_MILLI_SECONDS 200 ++ ae531x_MAC_t *MACInfo = ae531x_getMAcInfo(ethUnit); ++ while(!MACInfo || !MACInfo->port_is_up) ++ { ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout((AE531X_POLL_MILLI_SECONDS * HZ)/1000); ++ MACInfo = ae531x_getMAcInfo(ethUnit); ++ } ++ ae531x_SetMACFromPhy(MACInfo); ++#endif ++ AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE, ++ ("enet%d link up\n", ethUnit)); ++} ++ ++/****************************************************************************** ++* ae531x_ethMacDefault -- Called from PHY layer to determine the default ++* ethernet MAC. On some "twisted" platforms, the only usable MAC is 1, ++* while on others the usable MAC is 0. Future boards may allow both MACs ++* to be used; in this case, return -1 to indicate that there IS NO default ++* MAC. ++*/ ++int ++ae531x_ethMacDefault(void) ++{ ++ if (ae531x_twisted_enet()) ++ return 1; ++ ++ return 0; ++ ++} +diff -urN linux-mips-orig/drivers/net/ath/ae531xmac.h linux-mips-new/drivers/net/ath/ae531xmac.h +--- linux-mips-orig/drivers/net/ath/ae531xmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ae531xmac.h 2005-12-31 12:33:57.674538672 +0000 +@@ -0,0 +1,229 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * See README to understand the decomposition of the ethernet driver. ++ * ++ * This file contains OS-independent pure software definitions for ++ * ethernet support on the AR531X platform. ++ */ ++ ++#ifndef _AE531XMAC_H_ ++#define _AE531XMAC_H_ ++ ++#include ++#include ++ ++/* ++ * DEBUG switches to control verbosity. ++ * Just modify the value of ae531x_MAC_debug. ++ */ ++#define AE531X_DEBUG_ALL 0xffffffff ++#define AE531X_DEBUG_ERROR 0x00000001 /* Unusual conditions and Errors */ ++#define AE531X_DEBUG_ARRIVE 0x00000002 /* Arrive into a function */ ++#define AE531X_DEBUG_LEAVE 0x00000004 /* Leave a function */ ++#define AE531X_DEBUG_RESET 0x00000008 /* Reset */ ++#define AE531X_DEBUG_TX 0x00000010 /* Transmit */ ++#define AE531X_DEBUG_TX_REAP 0x00000020 /* Transmit Descriptor Reaping */ ++#define AE531X_DEBUG_RX 0x00000040 /* Receive */ ++#define AE531X_DEBUG_RX_STOP 0x00000080 /* Receive Early Stop */ ++#define AE531X_DEBUG_INT 0x00000100 /* Interrupts */ ++#define AE531X_DEBUG_LINK_CHANGE 0x00000200 /* PHY Link status changed */ ++ ++#define AE531X_NEGOT_TIMEOUT 500 /* ms to wait for autonegotiation */ ++ ++extern int ae531x_MAC_debug; ++ ++#define AE531X_PRINT(FLG, X) \ ++{ \ ++ if (ae531x_MAC_debug & (FLG)) { \ ++ DEBUG_PRINTF("%s#%d:%s ", \ ++ __FILE__, \ ++ __LINE__, \ ++ __FUNCTION__); \ ++ DEBUG_PRINTF X; \ ++ } \ ++} ++ ++#define ARRIVE() AE531X_PRINT(AE531X_DEBUG_ARRIVE, ("Arrive{\n")) ++#define LEAVE() AE531X_PRINT(AE531X_DEBUG_LEAVE, ("}Leave\n")) ++ ++#define RegRead(addr) \ ++ (*(volatile unsigned int *)(addr)) ++ ++#define RegWrite(val,addr) \ ++ ((*(volatile unsigned int *)(addr)) = (val)) ++ ++/***************************************************************** ++ * Phy code is broken out into a separate layer, so that different ++ * PHY hardware can easily be supported. ++ * ++ * These functions are provided by the PHY layer for use by the MAC layer. ++ * phySetup -- Set phy hardware appropriately for a MAC unit ++ * ++ * phyCheckStatusChange -- Look for dropped/initiated links on any ++ * phy port associated with a MAC unit ++ * ++ * phyIsSpeed100 -- Determines whether or not a PHY is up and ++ * running at 100Mbit ++ * ++ * phyIsFullDuplex -- Determines whether or not a PHY is up and ++ * running in Full Duplex mode ++ * ++ */ ++#if CONFIG_MARVELL_ENET_PHY ++/* ++ * Mapping of generic phy APIs to Marvell Ethernet Switch phy functions. ++ */ ++#include "mvPhy.h" ++#define phySetup(ethUnit, phyBase) mv_phySetup((ethUnit), (phyBase)) ++#define phyCheckStatusChange(ethUnit) mv_phyCheckStatusChange(ethUnit) ++#define phyIsSpeed100(ethUnit) mv_phyIsSpeed100(ethUnit) ++#define phyIsFullDuplex(ethUnit) mv_phyIsFullDuplex(ethUnit) ++ ++#if CONFIG_VENETDEV ++#define PHY_TRAILER_SIZE MV_PHY_TRAILER_SIZE ++extern void mv_phyDetermineSource(char *data, int len, int *pFromLAN); ++extern void mv_phySetDestinationPort(char *data, int len, int fromLAN); ++#define phyDetermineSource(data, len, pFromLAN) mv_phyDetermineSource((data), (len), (pFromLAN)) ++#define phySetDestinationPort(data, len, fromLAN) mv_phySetDestinationPort((data), (len), (fromLAN)) ++#else ++#define PHY_TRAILER_SIZE 0 ++#endif ++#endif /* CONFIG_MARVELL_ENET_PHY */ ++ ++#if CONFIG_KENDIN_ENET_PHY || CONFIG_REALTEK_ENET_PHY || CONFIG_KENDIN_KS8995XA_ENET_PHY ++/* ++ * Mapping of generic phy APIs to Kendin KS8721B and RealTek RTL8201BL phys. ++ */ ++#include "rtPhy.h" ++#define phySetup(ethUnit, phyBase) rt_phySetup((ethUnit), (phyBase)) ++#define phyCheckStatusChange(ethUnit) rt_phyCheckStatusChange(ethUnit) ++#define phyIsSpeed100(ethUnit) rt_phyIsSpeed100(ethUnit) ++#define phyIsFullDuplex(ethUnit) rt_phyIsFullDuplex(ethUnit) ++#endif ++ ++#if CONFIG_ICPLUS_ENET_PHY ++/* ++ * Mapping of generic phy APIs to Icplus phys. ++ */ ++#include "ipPhy.h" ++#define phySetup(ethUnit, phyBase) ip_phySetup((ethUnit), (phyBase)) ++#define phyCheckStatusChange(ethUnit) ip_phyCheckStatusChange(ethUnit) ++#define phyIsSpeed100(ethUnit) ip_phyIsSpeed100(ethUnit) ++#define phyIsFullDuplex(ethUnit) ip_phyIsFullDuplex(ethUnit) ++#endif ++ ++#if !defined(PHY_TRAILER_SIZE) ++#define PHY_TRAILER_SIZE 0 ++#endif ++ ++/***************************************************************** ++ * MAC-independent interface to be used by PHY code ++ * ++ * These functions are provided by the MAC layer for use by the PHY layer. ++ */ ++#define phyRegRead ae531x_MiiRead ++#define phyRegWrite ae531x_MiiWrite ++#define phyLinkLost(ethUnit) ae531x_unitLinkLost(ethUnit) ++#define phyLinkGained(ethUnit) ae531x_unitLinkGained(ethUnit) ++#define phyEthMacDefault() ae531x_ethMacDefault() ++ ++void ae531x_unitLinkLost(int unit); ++void ae531x_unitLinkGained(int unit); ++int ae531x_ethMacDefault(void); ++ ++ ++/* ++ * RXBUFF_RESERVE enables building header on WLAN-side in place ++ * NB: Divisible by 2 but NOT 4. Otherwise handle_adel_int() will ++ * be used by the ip layer for misaligned word accesses and ++ * performance will suffer - a lot. ++ */ ++#define ETH_CRC_LEN 4 ++#define RXBUFF_RESERVE 98 ++// #define RXBUFF_RESERVE 98 ++ ++/***************************************************************** ++ * Descriptor queue ++ */ ++typedef struct ae531x_queue { ++ VIRT_ADDR firstDescAddr; /* descriptor array address */ ++ VIRT_ADDR lastDescAddr; /* last descriptor address */ ++ VIRT_ADDR curDescAddr; /* current descriptor address */ ++ VIRT_ADDR reapDescAddr; /* current tail of tx descriptors reaped */ ++ UINT16 count; /* number of elements */ ++} AE531X_QUEUE; ++ ++/* Given a descriptor, return the next one in a circular list */ ++#define AE531X_QUEUE_ELE_NEXT_GET(q, descAddr) \ ++ ((descAddr) == (q)->lastDescAddr) ? (q)->firstDescAddr : \ ++ (VIRT_ADDR)((UINT32)(descAddr) + AE531X_QUEUE_ELE_SIZE) ++ ++/* Move the "current descriptor" forward to the next one */ ++#define AE531X_CONSUME_DESC(q) \ ++ q->curDescAddr = AE531X_QUEUE_ELE_NEXT_GET(q, q->curDescAddr) ++ ++/***************************************************************** ++ * Per-ethernet-MAC OS-independent information ++ */ ++typedef struct ae531x_MAC_s { ++ u32 unit; /* MAC unit ID */ ++ u32 macBase; /* MAC base address */ ++ u32 dmaBase; /* DMA base address */ ++ u32 phyBase; /* PHY base address */ ++ AE531X_QUEUE txQueue; /* Transmit descriptor queue */ ++ AE531X_QUEUE rxQueue; /* Receive descriptor queue */ ++ UINT16 txDescCount; /* Transmit descriptor count */ ++ UINT16 rxDescCount; /* Receive descriptor count */ ++ BOOL aeProcessRst; /* flag to indicate reset in progress */ ++ BOOL port_is_up; /* flag to indicate port is up */ ++ void *OSinfo; /* OS-dependent data */ ++} ae531x_MAC_t; ++ ++#define AE531X_TX_DESC_COUNT_DEFAULT 128 /* Transmit descriptors */ ++#define AE531X_RX_DESC_COUNT_DEFAULT 128 /* Receive descriptors */ ++ ++ ++/***************************************************************** ++ * Interfaces exported by the OS-independent MAC layer ++ */ ++void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo); ++void ae531x_EndResetMode(ae531x_MAC_t *MACInfo); ++BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo); ++int ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, AE531X_QUEUE *q, ++ char *pMem, int count); ++int ae531x_QueueDelete(struct ae531x_queue *q); ++void ae531x_DmaReset(ae531x_MAC_t *MACInfo); ++void ae531x_MACReset(ae531x_MAC_t *MACInfo); ++void ae531x_EnableComm(ae531x_MAC_t *MACInfo); ++void ae531x_DisableComm(ae531x_MAC_t *MACInfo); ++void ae531x_reset(ae531x_MAC_t *MACInfo); ++int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo); ++void ae531x_FreeQueues(ae531x_MAC_t *MACInfo); ++void ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count); ++UINT32 ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg); ++void ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data); ++void ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); ++void ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); ++void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); ++void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); ++UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg); ++void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data); ++UINT32 ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg); ++void ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data); ++UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg); ++void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data); ++void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo); ++void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo); ++void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 val); ++void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBptr, int *rxBSize); ++void ae531x_swptr_free(VIRT_ADDR txDesc); ++BOOL ae531x_twisted_enet(void); ++ ++#endif /* _AE531XMAC_H_ */ +diff -urN linux-mips-orig/drivers/net/ath/ae531xreg.h linux-mips-new/drivers/net/ath/ae531xreg.h +--- linux-mips-orig/drivers/net/ath/ae531xreg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ae531xreg.h 2005-12-31 12:33:57.675538520 +0000 +@@ -0,0 +1,439 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * See README to understand the decomposition of the ethernet driver. ++ * ++ * Register definitions for Atheros AR531X Ethernet MAC. ++ */ ++ ++#ifndef _AE531XREG_H_ ++#define _AE531XREG_H_ ++ ++#define AE531X_MAC_OFFSET 0x0000 ++#define AE531X_PHY_OFFSET 0x0000 /* Same as MAC offset */ ++#define AE531X_DMA_OFFSET 0x1000 ++ ++/***********************************************************/ ++/* MAC110 registers, base address is BAR+AE531X_MAC_OFFSET */ ++/***********************************************************/ ++#define MacControl 0x00 /* control */ ++#define MacAddrHigh 0x04 /* address high */ ++#define MacAddrLow 0x08 /* address low */ ++#define MacMultiHashHigh 0x0C /* multicast hash table high */ ++#define MacMultiHashLow 0x10 /* multicast hash table low */ ++#define MacMiiAddr 0x14 /* MII address */ ++#define MacMiiData 0x18 /* MII data */ ++#define MacFlowControl 0x1C /* Flow control */ ++#define MacVlan1Tag 0x4C /* VLAN1 tag */ ++#define MacVlan2Tag 0x50 /* VLAN2 tag */ ++ ++ ++/***************************************************************/ ++/* DMA engine registers, base address is BAR+AE531X_DMA_OFFSET */ ++/***************************************************************/ ++#define DmaBusMode 0x00 /* CSR0 - Bus Mode */ ++#define DmaTxPollDemand 0x04 /* CSR1 - Transmit Poll Demand */ ++#define DmaRxPollDemand 0x08 /* CSR2 - Receive Poll Demand */ ++#define DmaRxBaseAddr 0x0C /* CSR3 - Receive list base address */ ++#define DmaTxBaseAddr 0x10 /* CSR4 - Transmit list base address */ ++#define DmaStatus 0x14 /* CSR5 - Dma status */ ++#define DmaControl 0x18 /* CSR6 - Dma control */ ++#define DmaIntrEnb 0x1C /* CSR7 - Interrupt enable */ ++#define DmaOverflowCnt 0x20 /* CSR8 - Missed Frame and Buff Overflow counter */ ++#define DmaTxCurrAddr 0x50 /* CSR20 - Current host transmit buffer address */ ++#define DmaRxCurrAddr 0x54 /* CSR21 - Current host receive buffer address */ ++ ++/**********************************************************/ ++/* MAC Control register layout */ ++/**********************************************************/ ++#define MacFilterOff 0x80000000 /* Receive all incoming packets RW */ ++#define MacFilterOn 0 /* Receive filtered packets only 0 */ ++#define MacBigEndian 0x40000000 /* Big endian mode RW */ ++#define MacLittleEndian 0 /* Little endian 0 */ ++#define MacHeartBeatOff 0x10000000 /* Heartbeat signal qual disable RW*/ ++#define MacHeartBeatOn 0 /* Heartbeat signal qual enable 0 */ ++#define MacSelectSrl 0x08000000 /* Select SRL port RW */ ++#define MacSelectMii 0 /* Select MII port 0 */ ++#define MacDisableRxOwn 0x00800000 /* Disable receive own packets RW */ ++#define MacEnableRxOwn 0 /* Enable receive own packets 0 */ ++#define MacLoopbackExt 0x00400000 /* External loopback RW */ ++#define MacLoopbackInt 0x00200000 /* Internal loopback */ ++#define MacLoopbackOff 0 /* Normal mode 00 */ ++#define MacFullDuplex 0x00100000 /* Full duplex mode RW */ ++#define MacHalfDuplex 0 /* Half duplex mode 0 */ ++#define MacMulticastFilterOff 0x00080000 /* Pass all multicast packets RW */ ++#define MacMulticastFilterOn 0 /* Pass filtered mcast packets 0 */ ++#define MacPromiscuousModeOn 0x00040000 /* Receive all valid packets RW 1 */ ++#define MacPromiscuousModeOff 0 /* Receive filtered packets only */ ++#define MacFilterInverse 0x00020000 /* Inverse filtering RW */ ++#define MacFilterNormal 0 /* Normal filtering 0 */ ++#define MacBadFramesEnable 0x00010000 /* Pass bad frames RW */ ++#define MacBadFramesDisable 0 /* Do not pass bad frames 0 */ ++#define MacPerfectFilterOff 0x00008000 /* Hash filtering only RW */ ++#define MacPerfectFilterOn 0 /* Both perfect and hash filtering 0 */ ++#define MacHashFilterOn 0x00002000 /* perform hash filtering RW */ ++#define MacHashFilterOff 0 /* perfect filtering only 0 */ ++#define MacLateCollisionOn 0x00001000 /* Enable late collision control RW */ ++#define MacLateCollisionOff 0 /* Disable late collision control 0 */ ++#define MacBroadcastDisable 0x00000800 /* Disable reception of bcast frames RW */ ++#define MacBroadcastEnable 0 /* Enable broadcast frames 0 */ ++#define MacRetryDisable 0x00000400 /* Disable retransmission RW */ ++#define MacRetryEnable 0 /* Enable retransmission 0 */ ++#define MacPadStripEnable 0x00000100 /* Pad stripping enable RW */ ++#define MacPadStripDisable 0 /* Pad stripping disable 0 */ ++#define MacBackoff 0 /* Backoff Limit RW 00 */ ++#define MacDeferralCheckEnable 0x00000020 /* Deferral check enable RW */ ++#define MacDeferralCheckDisable 0 /* Deferral check disable 0 */ ++#define MacTxEnable 0x00000008 /* Transmitter enable RW */ ++#define MacTxDisable 0 /* Transmitter disable 0 */ ++#define MacRxEnable 0x00000004 /* Receiver enable RW */ ++#define MacRxDisable 0 /* Receiver disable 0 */ ++ ++ ++/**********************************************************/ ++/* MII address register layout */ ++/**********************************************************/ ++#define MiiDevMask 0x0000F800 /* MII device address */ ++#define MiiDevShift 11 ++#define MiiRegMask 0x000007C0 /* MII register */ ++#define MiiRegShift 6 ++#define MiiWrite 0x00000002 /* Write to register */ ++#define MiiRead 0 /* Read from register */ ++#define MiiBusy 0x00000001 /* MII interface is busy */ ++ ++/**********************************************************/ ++/* MII Data register layout */ ++/**********************************************************/ ++#define MiiDataMask 0x0000FFFF /* MII Data */ ++ ++/**********************************************************/ ++/* MAC flow control register layout */ ++/**********************************************************/ ++#define MacPauseTimeMask 0xFFFF0000 /* PAUSE TIME field in ctrl frame */ ++#define MacPauseTimeShift 15 ++#define MacControlFrameEnable 0x00000004 /* Enable pass ctrl frames to host */ ++#define MacControlFrameDisable 0 /* Do not pass ctrl frames to host */ ++#define MacFlowControlEnable 0x00000002 /* Enable flow control */ ++#define MacFlowControlDisable 0 /* Disable flow control */ ++#define MacSendPauseFrame 0x00000001 /* send pause frame */ ++ ++/**********************************************************/ ++/* DMA bus mode register layout */ ++/**********************************************************/ ++#define DmaRxAlign16 0x01000000 /* Force all rx buffers to align on odd hw bndry */ ++#define DmaBigEndianDes 0x00100000 /* Big endian data buffer descriptors RW */ ++#define DmaLittleEndianDesc 0 /* Little endian data descriptors */ ++#define DmaBurstLength32 0x00002000 /* Dma burst length 32 RW */ ++#define DmaBurstLength16 0x00001000 /* Dma burst length 16 */ ++#define DmaBurstLength8 0x00000800 /* Dma burst length 8 */ ++#define DmaBurstLength4 0x00000400 /* Dma burst length 4 */ ++#define DmaBurstLength2 0x00000200 /* Dma burst length 2 */ ++#define DmaBurstLength1 0x00000100 /* Dma burst length 1 */ ++#define DmaBurstLength0 0x00000000 /* Dma burst length 0 */ ++#define DmaBigEndianData 0x00000080 /* Big endian data buffers RW */ ++#define DmaLittleEndianData 0 /* Little endian data buffers 0 */ ++#define DmaDescriptorSkip16 0x00000040 /* number of dwords to skip RW */ ++#define DmaDescriptorSkip8 0x00000020 /* between two unchained descriptors */ ++#define DmaDescriptorSkip4 0x00000010 ++#define DmaDescriptorSkip2 0x00000008 ++#define DmaDescriptorSkip1 0x00000004 ++#define DmaDescriptorSkip0 0 ++#define DmaReceivePriorityOff 0x00000002 /* equal rx and tx priorities RW */ ++#define DmaReceivePriorityOn 0 /* Rx has prioryty over Tx 0 */ ++#define DmaResetOn 0x00000001 /* Reset DMA engine RW */ ++#define DmaResetOff 0 ++ ++/**********************************************************/ ++/* DMA Status register layout */ ++/**********************************************************/ ++#define DmaRxAbort 0x01000000 /* receiver bus abort R 0 */ ++#define DmaTxAbort 0x00800000 /* transmitter bus abort R 0 */ ++#define DmaTxState 0x00700000 /* Transmit process state R 000 */ ++#define DmaTxStopped 0x00000000 /* Stopped */ ++#define DmaTxFetching 0x00100000 /* Running - fetching the descriptor */ ++#define DmaTxWaiting 0x00200000 /* Running - waiting for end of transmission */ ++#define DmaTxReading 0x00300000 /* Running - reading the data from memory */ ++#define DmaTxSuspended 0x00600000 /* Suspended */ ++#define DmaTxClosing 0x00700000 /* Running - closing descriptor */ ++#define DmaRxState 0x000E0000 /* Receive process state 000 */ ++#define DmaRxStopped 0x00000000 /* Stopped */ ++#define DmaRxFetching 0x00020000 /* Running - fetching the descriptor */ ++#define DmaRxChecking 0x00040000 /* Running - checking for end of packet */ ++#define DmaRxWaiting 0x00060000 /* Running - waiting for packet */ ++#define DmaRxSuspended 0x00080000 /* Suspended */ ++#define DmaRxClosing 0x000A0000 /* Running - closing descriptor */ ++#define DmaRxFlushing 0x000C0000 /* Running - flushing the current frame */ ++#define DmaRxQueuing 0x000E0000 /* Running - queuing the recieve frame into host memory */ ++#define DmaIntNormal 0x00010000 /* Normal interrupt summary RW 0 */ ++#define DmaIntAbnormal 0x00008000 /* Abnormal interrupt summary RW 0 */ ++#define DmaIntEarlyRx 0x00004000 /* Early receive interrupt (Normal) RW 0 */ ++#define DmaIntBusError 0x00002000 /* Fatal bus error (Abnormal) RW 0 */ ++#define DmaIntEarlyTx 0x00000400 /* Early transmit interrupt RW 0 */ ++#define DmaIntRxStopped 0x00000100 /* Receive process stopped (Abnormal) RW 0 */ ++#define DmaIntRxNoBuffer 0x00000080 /* Receive buffer unavailable (Abnormal) RW 0*/ ++#define DmaIntRxCompleted 0x00000040 /* Completion of frame reception(Normal) RW 0*/ ++#define DmaIntTxUnderflow 0x00000020 /* Transmit underflow (Abnormal) RW 0 */ ++#define DmaIntTxJabber 0x00000008 /* Transmit Jabber Timeout (Abnormal) RW 0 */ ++#define DmaIntTxNoBuffer 0x00000004 /* Transmit buffer unavailable (Normal) RW 0*/ ++#define DmaIntTxStopped 0x00000002 /* Transmit process stopped (Abnormal) RW 0 */ ++#define DmaIntTxCompleted 0x00000001 /* Transmit completed (Normal) RW 0 */ ++ ++/**********************************************************/ ++/* DMA control register layout */ ++/**********************************************************/ ++#define DmaStoreAndForward 0x00000000 /* Store and forward RW 0 */ ++#define DmaTxThreshCtl256 0x0000c000 /* Non-SF threshold is 256 words */ ++#define DmaTxThreshCtl128 0x00008000 /* Non-SF threshold is 128 words */ ++#define DmaTxThreshCtl064 0x00004000 /* Non-SF threshold is 64 words */ ++#define DmaTxThreshCtl032 0x00000000 /* Non-SF threshold is 32 words */ ++#define DmaTxStart 0x00002000 /* Start/Stop transmission RW 0 */ ++#define DmaTxSecondFrame 0x00000004 /* Operate on second frame RW 0 */ ++#define DmaRxStart 0x00000002 /* Start/Stop reception RW 0 */ ++ ++/**********************************************************/ ++/* DMA interrupt enable register layout */ ++/**********************************************************/ ++#define DmaIeNormal DmaIntNormal /* Normal interrupt enable RW 0 */ ++#define DmaIeAbnormal DmaIntAbnormal /* Abnormal interrupt enable RW 0 */ ++#define DmaIeEarlyRx DmaIntEarlyRx /* Early receive interrupt enable RW 0 */ ++#define DmaIeBusError DmaIntBusError /* Fatal bus error enable RW 0 */ ++#define DmaIeEarlyTx DmaIntEarlyTx /* Early transmit interrupt enable RW 0 */ ++#define DmaIeRxStopped DmaIntRxStopped /* Receive process stopped enable RW 0 */ ++#define DmaIeRxNoBuffer DmaIntRxNoBuffer /* Receive buffer unavailable enable RW 0 */ ++#define DmaIeRxCompleted DmaIntRxCompleted /* Completion of frame reception enable RW 0 */ ++#define DmaIeTxUnderflow DmaIntTxUnderflow /* Transmit underflow enable RW 0 */ ++#define DmaIeTxJabber DmaIntTxJabber /* Transmit jabber timeout RW 0 */ ++#define DmaIeTxNoBuffer DmaIntTxNoBuffer /* Transmit buffer unavailable enable RW 0 */ ++#define DmaIeTxStopped DmaIntTxStopped /* Transmit process stopped enable RW 0 */ ++#define DmaIeTxCompleted DmaIntTxCompleted /* Transmit completed enable RW 0 */ ++ ++/****************************************************************/ ++/* DMA Missed Frame and Buffer Overflow Counter register layout */ ++/****************************************************************/ ++#define DmaRxBufferMissedFrame 0xffff0000 /* cleared on read */ ++#define DmaMissedFrameShift 16 ++#define DmaRxBufferOverflowCnt 0x0000ffff /* cleared on read */ ++#define DmaMissedFrameCountMask 0x0000ffff ++ ++/**********************************************************/ ++/* DMA Engine descriptor layout */ ++/**********************************************************/ ++/* status word of DMA descriptor */ ++#define DescOwnByDma 0x80000000 /* Descriptor is owned by DMA engine */ ++#define DescFrameLengthMask 0x3FFF0000 /* Receive descriptor frame length */ ++#define DescFrameLengthShift 16 ++#define DescError 0x00008000 /* Error summary bit OR of following bits */ ++#define DescRxTruncated 0x00004000 /* Rx - no more descs for receive frame */ ++#define DescRxLengthError 0x00001000 /* Rx - frame size not matching with length field */ ++#define DescRxRunt 0x00000800 /* Rx - runt frame, damaged by a ++ collision or term before 64 bytes */ ++#define DescRxMulticast 0x00000400 /* Rx - received frame is multicast */ ++#define DescRxFirst 0x00000200 /* Rx - first descriptor of the frame */ ++#define DescRxLast 0x00000100 /* Rx - last descriptor of the frame */ ++#define DescRxLongFrame 0x00000080 /* Rx - frame is longer than 1518 bytes */ ++#define DescRxLateColl 0x00000040 /* Rx - frame was damaged by a late collision */ ++#define DescRxFrameEther 0x00000020 /* Rx - Frame type Ethernet 802.3*/ ++#define DescRxMiiError 0x00000008 /* Rx - error reported by MII interface */ ++#define DescRxDribbling 0x00000004 /* Rx - frame contains noninteger multiple of 8 bits */ ++#define DescRxCrc 0x00000002 /* Rx - CRC error */ ++#define DescTxTimeout 0x00004000 /* Tx - Transmit jabber timeout */ ++#define DescTxLostCarrier 0x00000800 /* Tx - carrier lost during tramsmission */ ++#define DescTxNoCarrier 0x00000400 /* Tx - no carrier signal from tranceiver */ ++#define DescTxLateCollision 0x00000200 /* Tx - transmission aborted due to collision */ ++#define DescTxExcCollisions 0x00000100 /* Tx - transmission aborted after 16 collisions */ ++#define DescTxHeartbeatFail 0x00000080 /* Tx - heartbeat collision check failure */ ++#define DescTxCollMask 0x00000078 /* Tx - Collision count */ ++#define DescTxCollShift 3 ++#define DescTxExcDeferral 0x00000004 /* Tx - excessive deferral */ ++#define DescTxUnderflow 0x00000002 /* Tx - late data arrival from memory */ ++#define DescTxDeferred 0x00000001 /* Tx - frame transmision deferred */ ++ ++/* length word of DMA descriptor */ ++#define DescTxIntEnable 0x80000000 /* Tx - interrupt on completion */ ++#define DescTxLast 0x40000000 /* Tx - Last segment of the frame */ ++#define DescTxFirst 0x20000000 /* Tx - First segment of the frame */ ++#define DescTxDisableCrc 0x04000000 /* Tx - Add CRC disabled (first segment only) */ ++#define DescEndOfRing 0x02000000 /* End of descriptors ring */ ++#define DescChain 0x01000000 /* Second buffer address is chain address */ ++#define DescTxDisablePadd 0x00800000 /* disable padding */ ++#define DescSize2Mask 0x003FF800 /* Buffer 2 size */ ++#define DescSize2Shift 11 ++#define DescSize1Mask 0x000007FF /* Buffer 1 size */ ++#define DescSize1Shift 0 ++ ++/**********************************************************/ ++/* Initial register values */ ++/**********************************************************/ ++/* Full-duplex mode with perfect filter on */ ++#define MacControlInitFdx \ ++ ( MacFilterOn \ ++ | MacLittleEndian \ ++ | MacHeartBeatOn \ ++ | MacSelectMii \ ++ | MacEnableRxOwn \ ++ | MacLoopbackOff \ ++ | MacFullDuplex \ ++ | MacMulticastFilterOn \ ++ | MacPromiscuousModeOff \ ++ | MacFilterNormal \ ++ | MacBadFramesDisable \ ++ | MacPerfectFilterOn \ ++ | MacHashFilterOff \ ++ | MacLateCollisionOff \ ++ | MacBroadcastEnable \ ++ | MacRetryEnable \ ++ | MacPadStripDisable \ ++ | MacDeferralCheckDisable \ ++ | MacTxEnable \ ++ | MacRxEnable) ++ ++/* Full-duplex mode */ ++#define MacFlowControlInitFdx \ ++ ( MacControlFrameDisable \ ++ | MacFlowControlEnable) ++ ++/* Half-duplex mode with perfect filter on */ ++#define MacControlInitHdx \ ++ ( MacFilterOn \ ++ | MacLittleEndian \ ++ | MacHeartBeatOn \ ++ | MacSelectMii \ ++ | MacDisableRxOwn \ ++ | MacLoopbackOff \ ++ | MacHalfDuplex \ ++ | MacMulticastFilterOn \ ++ | MacPromiscuousModeOff \ ++ | MacFilterNormal \ ++ | MacBadFramesDisable \ ++ | MacPerfectFilterOn \ ++ | MacHashFilterOff \ ++ | MacLateCollisionOff \ ++ | MacBroadcastEnable \ ++ | MacRetryEnable \ ++ | MacPadStripDisable \ ++ | MacDeferralCheckDisable \ ++ | MacTxEnable \ ++ | MacRxEnable) ++ ++/* Half-duplex mode */ ++#define MacFlowControlInitHdx \ ++ ( MacControlFrameDisable \ ++ | MacFlowControlDisable) ++ ++/* Bus Mode Rx odd half word align */ ++#define DmaBusModeInit \ ++ ( DmaLittleEndianDesc \ ++ | DmaRxAlign16 \ ++ | DmaBurstLength32 \ ++ | DmaBigEndianData \ ++ | DmaDescriptorSkip1 \ ++ | DmaReceivePriorityOn \ ++ | DmaResetOff) ++ ++#define DmaControlInit (DmaStoreAndForward) ++ ++/* Interrupt groups */ ++#define DmaIntEnable \ ++ ( DmaIeNormal \ ++ | DmaIeAbnormal \ ++ | DmaIntBusError \ ++ | DmaIntRxStopped \ ++ | DmaIntRxNoBuffer \ ++ | DmaIntRxCompleted \ ++ | DmaIntTxUnderflow \ ++ | DmaIntTxStopped) ++ ++#define DmaIntDisable 0 ++ ++#define DmaAllIntCauseMask \ ++ ( DmaIeNormal \ ++ | DmaIeAbnormal \ ++ | DmaIntEarlyRx \ ++ | DmaIntBusError \ ++ | DmaIntEarlyTx \ ++ | DmaIntRxStopped \ ++ | DmaIntRxNoBuffer \ ++ | DmaIntRxCompleted \ ++ | DmaIntTxUnderflow \ ++ | DmaIntTxJabber \ ++ | DmaIntTxNoBuffer \ ++ | DmaIntTxStopped \ ++ | DmaIntTxCompleted) ++ ++#define UnhandledIntrMask \ ++ (DmaAllIntCauseMask \ ++ & ~(DmaIntRxNoBuffer \ ++ | DmaIntTxStopped \ ++ | DmaIntTxJabber \ ++ | DmaIntTxUnderflow \ ++ | DmaIntBusError \ ++ | DmaIntRxCompleted )) ++ ++#define DescRxErrors \ ++ (DescRxTruncated \ ++ | DescRxRunt \ ++ | DescRxLateColl \ ++ | DescRxMiiError \ ++ | DescRxCrc) ++ ++#define DescTxErrors \ ++ ( DescTxTimeout \ ++ | DescTxLateCollision \ ++ | DescTxExcCollisions \ ++ | DescTxExcDeferral \ ++ | DescTxUnderflow) ++ ++/**********************************************************/ ++/* Descriptor Layout */ ++/**********************************************************/ ++#define AE531X_DESC_STATUS 0x00 /* Status offset */ ++#define AE531X_DESC_CTRLEN 0x04 /* Control and Length offset */ ++#define AE531X_DESC_BUFPTR 0x08 /* Buffer pointer offset */ ++#define AE531X_DESC_LNKBUF 0x0c /* Link field offset, or ptr to 2nd buf */ ++#define AE531X_DESC_SWPTR 0x10 /* OS-Dependent software pointer */ ++ ++#define AE531X_DESC_SIZE 0x10 /* 4 words, 16 bytes */ ++#define AE531X_QUEUE_ELE_SIZE 0x14 /* with software pointer extension */ ++ ++/* Accessors to the dma descriptor fields */ ++#define AE531X_DESC_STATUS_GET(ptr) \ ++ *(volatile UINT32 *)((UINT32)(ptr) + AE531X_DESC_STATUS) ++ ++#define AE531X_DESC_STATUS_SET(ptr, val) \ ++ AE531X_DESC_STATUS_GET(ptr) = (val) ++ ++#define AE531X_DESC_CTRLEN_GET(ptr) \ ++ *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_CTRLEN) ++ ++#define AE531X_DESC_CTRLEN_SET(ptr, val) \ ++ AE531X_DESC_CTRLEN_GET(ptr) = (val) ++ ++#define AE531X_DESC_BUFPTR_GET(ptr) \ ++ *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_BUFPTR) ++ ++#define AE531X_DESC_BUFPTR_SET(ptr,val) \ ++ AE531X_DESC_BUFPTR_GET(ptr) = (UINT32)(val) ++ ++#define AE531X_DESC_LNKBUF_GET(ptr) \ ++ *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_LNKBUF) ++ ++#define AE531X_DESC_LNKBUF_SET(ptr, val) \ ++ AE531X_DESC_LNKBUF_GET(ptr) = (val) ++ ++#define AE531X_DESC_SWPTR_GET(ptr) \ ++ (void *)(*(volatile UINT32 *) ((UINT32)ptr + AE531X_DESC_SWPTR)) ++ ++#define AE531X_DESC_SWPTR_SET(ptr,val) \ ++ AE531X_DESC_SWPTR_GET(ptr) = (void *)(val) ++ ++/* Get size of Rx data from desc, in bytes */ ++#define AE531X_DESC_STATUS_RX_SIZE(x) \ ++ (((x) & DescFrameLengthMask) >> DescFrameLengthShift) ++ ++#endif /* _AE531XREG_H_ */ +diff -urN linux-mips-orig/drivers/net/ath/ar531x.h linux-mips-new/drivers/net/ath/ar531x.h +--- linux-mips-orig/drivers/net/ath/ar531x.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ar531x.h 2005-12-31 12:33:57.676538368 +0000 +@@ -0,0 +1,1124 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++#ifndef AR531X_H ++#define AR531X_H 1 ++ ++ ++#ifndef CONFIG_AR5315 ++ ++#include ++ ++/* Address Map */ ++#define AR531X_WLAN0 0x18000000 ++#define AR531X_WLAN1 0x18500000 ++#define AR531X_ENET0 0x18100000 ++#define AR531X_ENET1 0x18200000 ++#define AR531X_SDRAMCTL 0x18300000 ++#define AR531X_FLASHCTL 0x18400000 ++#define AR531X_APBBASE 0x1c000000 ++#define AR531X_FLASH 0x1e000000 ++ ++/* ++ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that ++ * should be considered available. The AR5312 supports 2 enet MACS, ++ * even though many reference boards only actually use 1 of them ++ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch. ++ * The AR2312 supports 1 enet MAC. ++ */ ++#define AR531X_NUM_ENET_MAC 2 ++ ++/* ++ * Need these defines to determine true number of ethernet MACs ++ */ ++#define AR5212_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ ++#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ ++#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ ++#define AR531X_RADIO_MASK_OFF 0xc8 ++#define AR531X_RADIO0_MASK 0x0003 ++#define AR531X_RADIO1_MASK 0x000c ++#define AR531X_RADIO1_S 2 ++ ++/* ++ * AR531X_NUM_WMAC defines the number of Wireless MACs that\ ++ * should be considered available. ++ */ ++#define AR531X_NUM_WMAC 2 ++ ++/* Reset/Timer Block Address Map */ ++#define AR531X_RESETTMR (AR531X_APBBASE + 0x3000) ++#define AR531X_TIMER (AR531X_RESETTMR + 0x0000) /* countdown timer */ ++#define AR531X_WD_CTRL (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */ ++#define AR531X_WD_TIMER (AR531X_RESETTMR + 0x000c) /* watchdog timer */ ++#define AR531X_ISR (AR531X_RESETTMR + 0x0010) /* Intr Status Reg */ ++#define AR531X_IMR (AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */ ++#define AR531X_RESET (AR531X_RESETTMR + 0x0020) ++#define AR5312_CLOCKCTL1 (AR531X_RESETTMR + 0x0064) ++#define AR5312_SCRATCH (AR531X_RESETTMR + 0x006c) ++#define AR531X_PROCADDR (AR531X_RESETTMR + 0x0070) ++#define AR531X_PROC1 (AR531X_RESETTMR + 0x0074) ++#define AR531X_DMAADDR (AR531X_RESETTMR + 0x0078) ++#define AR531X_DMA1 (AR531X_RESETTMR + 0x007c) ++#define AR531X_ENABLE (AR531X_RESETTMR + 0x0080) /* interface enb */ ++#define AR531X_REV (AR531X_RESETTMR + 0x0090) /* revision */ ++ ++/* AR531X_WD_CTRL register bit field definitions */ ++#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000 ++#define AR531X_WD_CTRL_NMI 0x0001 ++#define AR531X_WD_CTRL_RESET 0x0002 ++ ++/* AR531X_ISR register bit field definitions */ ++#define AR531X_ISR_NONE 0x0000 ++#define AR531X_ISR_TIMER 0x0001 ++#define AR531X_ISR_AHBPROC 0x0002 ++#define AR531X_ISR_AHBDMA 0x0004 ++#define AR531X_ISR_GPIO 0x0008 ++#define AR531X_ISR_UART0 0x0010 ++#define AR531X_ISR_UART0DMA 0x0020 ++#define AR531X_ISR_WD 0x0040 ++#define AR531X_ISR_LOCAL 0x0080 ++ ++/* AR531X_RESET register bit field definitions */ ++#define AR531X_RESET_SYSTEM 0x00000001 /* cold reset full system */ ++#define AR531X_RESET_PROC 0x00000002 /* cold reset MIPS core */ ++#define AR531X_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC and BB */ ++#define AR531X_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ ++#define AR531X_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ ++#define AR531X_RESET_ENET0 0x00000020 /* cold reset ENET0 mac */ ++#define AR531X_RESET_ENET1 0x00000040 /* cold reset ENET1 mac */ ++#define AR531X_RESET_UART0 0x00000100 /* cold reset UART0 (high speed) */ ++#define AR531X_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */ ++#define AR531X_RESET_APB 0x00000400 /* cold reset APB (ar5312) */ ++#define AR531X_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */ ++#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */ ++#define AR531X_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BaseBand */ ++#define AR531X_RESET_NMI 0x00010000 /* send an NMI to the processor */ ++#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 mac */ ++#define AR531X_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 baseband */ ++#define AR531X_RESET_LOCAL_BUS 0x00080000 /* reset local bus */ ++#define AR531X_RESET_WDOG 0x00100000 /* last reset was a watchdog */ ++ ++#define AR531X_RESET_WMAC0_BITS \ ++ AR531X_RESET_WLAN0 |\ ++ AR531X_RESET_WARM_WLAN0_MAC |\ ++ AR531X_RESET_WARM_WLAN0_BB ++ ++#define AR531X_RESERT_WMAC1_BITS \ ++ AR531X_RESET_WLAN1 |\ ++ AR531X_RESET_WARM_WLAN1_MAC |\ ++ AR531X_RESET_WARM_WLAN1_BB ++ ++/* AR5312_CLOCKCTL1 register bit field definitions */ ++#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 ++#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 ++#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 ++#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 ++#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 ++ ++/* Valid for AR5312 and AR2312 */ ++#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 ++#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 ++#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 ++#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 ++#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 ++ ++/* Valid for AR2313 */ ++#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000 ++#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12 ++#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000 ++#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16 ++#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000 ++ ++ ++/* AR531X_ENABLE register bit field definitions */ ++#define AR531X_ENABLE_WLAN0 0x0001 ++#define AR531X_ENABLE_ENET0 0x0002 ++#define AR531X_ENABLE_ENET1 0x0004 ++#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008 /* UART, and WLAN1 PIOs */ ++#define AR531X_ENABLE_WLAN1_DMA 0x0010 /* WLAN1 DMAs */ ++#define AR531X_ENABLE_WLAN1 \ ++ (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA) ++ ++/* AR531X_REV register bit field definitions */ ++#define AR531X_REV_WMAC_MAJ 0xf000 ++#define AR531X_REV_WMAC_MAJ_S 12 ++#define AR531X_REV_WMAC_MIN 0x0f00 ++#define AR531X_REV_WMAC_MIN_S 8 ++#define AR531X_REV_MAJ 0x00f0 ++#define AR531X_REV_MAJ_S 4 ++#define AR531X_REV_MIN 0x000f ++#define AR531X_REV_MIN_S 0 ++#define AR531X_REV_CHIP (REV_MAJ|REV_MIN) ++ ++/* Major revision numbers, bits 7..4 of Revision ID register */ ++#define AR531X_REV_MAJ_AR5312 0x4 ++#define AR531X_REV_MAJ_AR2313 0x5 ++ ++/* Minor revision numbers, bits 3..0 of Revision ID register */ ++#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */ ++#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */ ++ ++/* AR531X_FLASHCTL register bit field definitions */ ++#define FLASHCTL_IDCY 0x0000000f /* Idle cycle turn around time */ ++#define FLASHCTL_IDCY_S 0 ++#define FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ ++#define FLASHCTL_WST1_S 5 ++#define FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ ++#define FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ ++#define FLASHCTL_WST2_S 11 ++#define FLASHCTL_AC 0x00070000 /* Flash address check (added) */ ++#define FLASHCTL_AC_S 16 ++#define FLASHCTL_AC_128K 0x00000000 ++#define FLASHCTL_AC_256K 0x00010000 ++#define FLASHCTL_AC_512K 0x00020000 ++#define FLASHCTL_AC_1M 0x00030000 ++#define FLASHCTL_AC_2M 0x00040000 ++#define FLASHCTL_AC_4M 0x00050000 ++#define FLASHCTL_AC_8M 0x00060000 ++#define FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ ++#define FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ ++#define FLASHCTL_BUSERR 0x01000000 /* Bus transfer error status flag */ ++#define FLASHCTL_WPERR 0x02000000 /* Write protect error status flag */ ++#define FLASHCTL_WP 0x04000000 /* Write protect */ ++#define FLASHCTL_BM 0x08000000 /* Burst mode */ ++#define FLASHCTL_MW 0x30000000 /* Memory width */ ++#define FLASHCTL_MWx8 0x00000000 /* Memory width x8 */ ++#define FLASHCTL_MWx16 0x10000000 /* Memory width x16 */ ++#define FLASHCTL_MWx32 0x20000000 /* Memory width x32 (not supported) */ ++#define FLASHCTL_ATNR 0x00000000 /* Access type == no retry */ ++#define FLASHCTL_ATR 0x80000000 /* Access type == retry every */ ++#define FLASHCTL_ATR4 0xc0000000 /* Access type == retry every 4 */ ++ ++/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices. */ ++#define AR531X_FLASHCTL0 (AR531X_FLASHCTL + 0x00) ++#define AR531X_FLASHCTL1 (AR531X_FLASHCTL + 0x04) ++#define AR531X_FLASHCTL2 (AR531X_FLASHCTL + 0x08) ++ ++/* ARM SDRAM Controller -- just enough to determine memory size */ ++#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04) ++#define MEM_CFG1_AC0 0x00000700 /* bank 0: SDRAM addr check (added) */ ++#define MEM_CFG1_AC0_S 8 ++#define MEM_CFG1_AC1 0x00007000 /* bank 1: SDRAM addr check (added) */ ++#define MEM_CFG1_AC1_S 12 ++ ++/* GPIO Address Map */ ++#define AR531X_GPIO (AR531X_APBBASE + 0x2000) ++#define AR531X_GPIO_DO (AR531X_GPIO + 0x00) /* output register */ ++#define AR531X_GPIO_DI (AR531X_GPIO + 0x04) /* intput register */ ++#define AR531X_GPIO_CR (AR531X_GPIO + 0x08) /* control register */ ++ ++/* GPIO Control Register bit field definitions */ ++#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ ++#define GPIO_CR_O(x) (0 << (x)) /* mask for output */ ++#define GPIO_CR_I(x) (1 << (x)) /* mask for input */ ++#define GPIO_CR_INT(x) (1 << ((x)+8)) /* mask for interrupt */ ++#define GPIO_CR_UART(x) (1 << ((x)+16)) /* uart multiplex */ ++ ++ ++typedef unsigned int AR531X_REG; ++ ++#define sysRegRead(phys) \ ++ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) ++ ++#define sysRegWrite(phys, val) \ ++ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) ++ ++ ++/* ++ * This is board-specific data that is stored in a "fixed" location in flash. ++ * It is shared across operating systems, so it should not be changed lightly. ++ * The main reason we need it is in order to extract the ethernet MAC ++ * address(es). ++ */ ++struct ar531x_boarddata { ++ u32 magic; /* board data is valid */ ++#define AR531X_BD_MAGIC 0x35333131 /* "5311", for all 531x platforms */ ++ u16 cksum; /* checksum (starting with BD_REV 2) */ ++ u16 rev; /* revision of this struct */ ++#define BD_REV 4 ++ char boardName[64]; /* Name of board */ ++ u16 major; /* Board major number */ ++ u16 minor; /* Board minor number */ ++ u32 config; /* Board configuration */ ++#define BD_ENET0 0x00000001 /* ENET0 is stuffed */ ++#define BD_ENET1 0x00000002 /* ENET1 is stuffed */ ++#define BD_UART1 0x00000004 /* UART1 is stuffed */ ++#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ ++#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ ++#define BD_SYSLED 0x00000020 /* System LED stuffed */ ++#define BD_EXTUARTCLK 0x00000040 /* External UART clock */ ++#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ ++#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ ++#define BD_WLAN0 0x00000200 /* Enable WLAN0 */ ++#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ memCap for testing */ ++#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ ++#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ ++#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ ++#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ ++#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ ++#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ ++#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ ++ u16 resetConfigGpio; /* Reset factory GPIO pin */ ++ u16 sysLedGpio; /* System LED GPIO pin */ ++ ++ u32 cpuFreq; /* CPU core frequency in Hz */ ++ u32 sysFreq; /* System frequency in Hz */ ++ u32 cntFreq; /* Calculated C0_COUNT frequency */ ++ ++ u8 wlan0Mac[6]; ++ u8 enet0Mac[6]; ++ u8 enet1Mac[6]; ++ ++ u16 pciId; /* Pseudo PCIID for common code */ ++ u16 memCap; /* cap bank1 in MB */ ++ ++ /* version 3 */ ++ u8 wlan1Mac[6]; /* (ar5212) */ ++}; ++ ++#else ++ ++/* ++ * Add support for Cobra ++ * ++ * AR531XPLUSreg.h Register definitions for Atheros AR5311 and AR5312 chipsets. ++ * - WLAN registers are listed in ++ * hal/ar5211/ar5211Reg.h ++ * hal/ar5212/ar5212Reg.h ++ * - Ethernet registers are listed in ar531xenet.h ++ * - Standard UART is 16550 compatible. ++ */ ++ ++ ++/* ++ * Address map ++ */ ++#define AR531XPLUS_SDRAM0 0x00000000 /* DRAM */ ++#define AR531XPLUS_SPI_READ 0x08000000 /* SPI FLASH */ ++#define AR531XPLUS_WLAN0 0xB0000000 /* Wireless MMR */ ++#define AR531XPLUS_PCI 0xB0100000 /* PCI MMR */ ++#define AR531XPLUS_SDRAMCTL 0xB0300000 /* SDRAM MMR */ ++#define AR531XPLUS_LOCAL 0xB0400000 /* LOCAL BUS MMR */ ++#define AR531XPLUS_ENET0 0xB0500000 /* ETHERNET MMR */ ++#define AR531XPLUS_DSLBASE 0xB1000000 /* RESET CONTROL MMR */ ++#define AR531XPLUS_UART0 0xB1100003 /* UART MMR */ ++#define AR531XPLUS_SPI 0xB1300000 /* SPI FLASH MMR */ ++#define AR531XPLUS_FLASHBT 0xBfc00000 /* ro boot alias to FLASH */ ++#define AR531XPLUS_RAM1 0x40000000 /* ram alias */ ++#define AR531XPLUS_PCIEXT 0x80000000 /* pci external */ ++#define AR531XPLUS_RAM2 0xc0000000 /* ram alias */ ++#define AR531XPLUS_RAM3 0xe0000000 /* ram alias */ ++ ++#define AR531X_ENET0 AR531XPLUS_ENET0 ++#define AR531X_ENET1 0 ++/* ++ * Reset Register ++ */ ++#define AR531XPLUS_COLD_RESET (AR531XPLUS_DSLBASE + 0x0000) ++ ++/* Cold Reset */ ++#define RESET_COLD_AHB 0x00000001 ++#define RESET_COLD_APB 0x00000002 ++#define RESET_COLD_CPU 0x00000004 ++#define RESET_COLD_CPUWARM 0x00000008 ++#define RESET_SYSTEM (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB) /* full system */ ++ ++/* Warm Reset */ ++ ++#define AR531XPLUS_RESET (AR531XPLUS_DSLBASE + 0x0004) ++#define AR531X_RESET AR531XPLUS_RESET ++ ++#define RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ ++#define RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BaseBand */ ++#define RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ ++#define RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ ++#define RESET_MEMCTL 0x00000010 /* warm reset memory controller */ ++#define RESET_LOCAL 0x00000020 /* warm reset local bus */ ++#define RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ ++#define RESET_SPI 0x00000080 /* warm reset SPI interface */ ++#define RESET_UART0 0x00000100 /* warm reset UART0 */ ++#define RESET_IR_RSVD 0x00000200 /* warm reset IR interface */ ++#define RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ ++#define RESET_ENET0 0x00000800 /* cold reset ENET0 mac */ ++ ++#define AR531X_RESET_ENET0 RESET_ENET0 ++#define AR531X_RESET_EPHY0 RESET_EPHY0 ++#define AR531X_RESET_ENET1 0 ++#define AR531X_RESET_EPHY1 0 ++ ++/* ++ * AHB master arbitration control ++ */ ++#define AR531XPLUS_AHB_ARB_CTL (AR531XPLUS_DSLBASE + 0x0008) ++ ++#define ARB_CPU 0x00000001 /* CPU, default */ ++#define ARB_WLAN 0x00000002 /* WLAN */ ++#define ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ ++#define ARB_LOCAL 0x00000008 /* LOCAL */ ++#define ARB_PCI 0x00000010 /* PCI */ ++#define ARB_ETHERNET 0x00000020 /* Ethernet */ ++#define ARB_RETRY 0x00000100 /* retry policy, debug only */ ++ ++/* ++ * Config Register ++ */ ++#define AR531XPLUS_ENDIAN_CTL (AR531XPLUS_DSLBASE + 0x000c) ++ ++#define CONFIG_AHB 0x00000001 /* EC - AHB bridge endianess */ ++#define CONFIG_WLAN 0x00000002 /* WLAN byteswap */ ++#define CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */ ++#define CONFIG_PCI 0x00000008 /* PCI byteswap */ ++#define CONFIG_MEMCTL 0x00000010 /* Memory controller endianess */ ++#define CONFIG_LOCAL 0x00000020 /* Local bus byteswap */ ++#define CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ ++ ++#define CONFIG_MERGE 0x00000200 /* CPU write buffer merge */ ++#define CONFIG_CPU 0x00000400 /* CPU big endian */ ++#define CONFIG_PCIAHB 0x00000800 ++#define CONFIG_PCIAHB_BRIDGE 0x00001000 ++#define CONFIG_SPI 0x00008000 /* SPI byteswap */ ++#define CONFIG_CPU_DRAM 0x00010000 ++#define CONFIG_CPU_PCI 0x00020000 ++#define CONFIG_CPU_MMR 0x00040000 ++#define CONFIG_BIG 0x00000400 ++ ++ ++/* ++ * NMI control ++ */ ++#define AR531XPLUS_NMI_CTL (AR531XPLUS_DSLBASE + 0x0010) ++ ++#define NMI_EN 1 ++ ++/* ++ * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0). ++ */ ++#define AR531XPLUS_SREV (AR531XPLUS_DSLBASE + 0x0014) ++ ++#define AR531X_REV AR531XPLUS_SREV ++ ++#define REV_MAJ 0x00f0 ++#define REV_MAJ_S 4 ++#define REV_MIN 0x000f ++#define REV_MIN_S 0 ++#define REV_CHIP (REV_MAJ|REV_MIN) ++ ++#define AR531X_REV_MAJ REV_MAJ ++#define AR531X_REV_MAJ_S REV_MAJ_S ++#define AR531X_REV_MIN REV_MIN ++#define AR531X_REV_MIN_S REV_MIN_S ++#define REV_CHIP (REV_MAJ|REV_MIN) ++/* ++ * Need these defines to determine true number of ethernet MACs ++ */ ++#define AR5212_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ ++#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ ++#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ ++#define AR531X_RADIO_MASK_OFF 0xc8 ++#define AR531X_RADIO0_MASK 0x0003 ++#define AR531X_RADIO1_MASK 0x000c ++#define AR531X_RADIO1_S 2 ++ ++/* Major revision numbers, bits 7..4 of Revision ID register */ ++#define AR531X_REV_MAJ_AR5312 0x4 ++#define AR531X_REV_MAJ_AR2313 0x5 ++ ++/* ++ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that ++ * should be considered available. The AR5312 supports 2 enet MACS, ++ * even though many reference boards only actually use 1 of them ++ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch. ++ * The AR2312 supports 1 enet MAC. ++ */ ++#define AR531X_NUM_ENET_MAC 1 ++ ++/* ++ * Interface Enable ++ */ ++#define AR531XPLUS_IF_CTL (AR531XPLUS_DSLBASE + 0x0018) ++ ++#define IF_MASK 0x00000007 ++#define IF_DISABLED 0 ++#define IF_PCI 1 ++#define IF_TS_LOCAL 2 ++#define IF_ALL 3 /* only for emulation with separate pins */ ++#define IF_LOCAL_HOST 0x00000008 ++#define IF_PCI_HOST 0x00000010 ++#define IF_PCI_INTR 0x00000020 ++#define IF_PCI_CLK_MASK 0x00030000 ++#define IF_PCI_CLK_INPUT 0 ++#define IF_PCI_CLK_OUTPUT_LOW 1 ++#define IF_PCI_CLK_OUTPUT_CLK 2 ++#define IF_PCI_CLK_OUTPUT_HIGH 3 ++#define IF_PCI_CLK_SHIFT 16 ++ ++ ++/* Major revision numbers, bits 7..4 of Revision ID register */ ++#define REV_MAJ_AR5311 0x01 ++#define REV_MAJ_AR5312 0x04 ++#define REV_MAJ_AR5315 0x0B ++ ++/* ++ * APB Interrupt control ++ */ ++ ++#define AR531XPLUS_ISR (AR531XPLUS_DSLBASE + 0x0020) ++#define AR531XPLUS_IMR (AR531XPLUS_DSLBASE + 0x0024) ++#define AR531XPLUS_GISR (AR531XPLUS_DSLBASE + 0x0028) ++ ++#define ISR_UART0 0x0001 /* high speed UART */ ++#define ISR_I2C_RSVD 0x0002 /* I2C bus */ ++#define ISR_SPI 0x0004 /* SPI bus */ ++#define ISR_AHB 0x0008 /* AHB error */ ++#define ISR_APB 0x0010 /* APB error */ ++#define ISR_TIMER 0x0020 /* timer */ ++#define ISR_GPIO 0x0040 /* GPIO */ ++#define ISR_WD 0x0080 /* watchdog */ ++#define ISR_IR_RSVD 0x0100 /* IR */ ++ ++#define IMR_UART0 ISR_UART0 ++#define IMR_I2C_RSVD ISR_I2C_RSVD ++#define IMR_SPI ISR_SPI ++#define IMR_AHB ISR_AHB ++#define IMR_APB ISR_APB ++#define IMR_TIMER ISR_TIMER ++#define IMR_GPIO ISR_GPIO ++#define IMR_WD ISR_WD ++#define IMR_IR_RSVD ISR_IR_RSVD ++ ++#define GISR_MISC 0x0001 ++#define GISR_WLAN0 0x0002 ++#define GISR_MPEGTS_RSVD 0x0004 ++#define GISR_LOCALPCI 0x0008 ++#define GISR_WMACPOLL 0x0010 ++#define GISR_TIMER 0x0020 ++#define GISR_ETHERNET 0x0040 ++ ++/* ++ * Interrupt routing from IO to the processor IP bits ++ * Define our inter mask and level ++ */ ++#define AR531XPLUS_INTR_MISCIO SR_IBIT3 ++#define AR531XPLUS_INTR_WLAN0 SR_IBIT4 ++#define AR531XPLUS_INTR_ENET0 SR_IBIT5 ++#define AR531XPLUS_INTR_LOCALPCI SR_IBIT6 ++#define AR531XPLUS_INTR_WMACPOLL SR_IBIT7 ++#define AR531XPLUS_INTR_COMPARE SR_IBIT8 ++ ++/* ++ * Timers ++ */ ++#define AR531XPLUS_TIMER (AR531XPLUS_DSLBASE + 0x0030) ++#define AR531XPLUS_RELOAD (AR531XPLUS_DSLBASE + 0x0034) ++#define AR531XPLUS_WD (AR531XPLUS_DSLBASE + 0x0038) ++#define AR531XPLUS_WDC (AR531XPLUS_DSLBASE + 0x003c) ++ ++#define WDC_RESET 0x00000002 /* reset on watchdog */ ++#define WDC_NMI 0x00000001 /* NMI on watchdog */ ++#define WDC_IGNORE_EXPIRATION 0x00000000 ++ ++/* ++ * Interface Debug ++ */ ++#define AR531X_FLASHDBG (AR531X_RESETTMR + 0x0040) ++#define AR531X_MIIDBG (AR531X_RESETTMR + 0x0044) ++ ++ ++/* ++ * CPU Performance Counters ++ */ ++#define AR531XPLUS_PERFCNT0 (AR531XPLUS_DSLBASE + 0x0048) ++#define AR531XPLUS_PERFCNT1 (AR531XPLUS_DSLBASE + 0x004c) ++ ++#define PERF_DATAHIT 0x0001 /* Count Data Cache Hits */ ++#define PERF_DATAMISS 0x0002 /* Count Data Cache Misses */ ++#define PERF_INSTHIT 0x0004 /* Count Instruction Cache Hits */ ++#define PERF_INSTMISS 0x0008 /* Count Instruction Cache Misses */ ++#define PERF_ACTIVE 0x0010 /* Count Active Processor Cycles */ ++#define PERF_WBHIT 0x0020 /* Count CPU Write Buffer Hits */ ++#define PERF_WBMISS 0x0040 /* Count CPU Write Buffer Misses */ ++ ++#define PERF_EB_ARDY 0x0001 /* Count EB_ARdy signal */ ++#define PERF_EB_AVALID 0x0002 /* Count EB_AValid signal */ ++#define PERF_EB_WDRDY 0x0004 /* Count EB_WDRdy signal */ ++#define PERF_EB_RDVAL 0x0008 /* Count EB_RdVal signal */ ++#define PERF_VRADDR 0x0010 /* Count valid read address cycles */ ++#define PERF_VWADDR 0x0020 /* Count valid write address cycles */ ++#define PERF_VWDATA 0x0040 /* Count valid write data cycles */ ++ ++/* ++ * AHB Error Reporting. ++ */ ++#define AR531XPLUS_AHB_ERR0 (AR531XPLUS_DSLBASE + 0x0050) /* error */ ++#define AR531XPLUS_AHB_ERR1 (AR531XPLUS_DSLBASE + 0x0054) /* haddr */ ++#define AR531XPLUS_AHB_ERR2 (AR531XPLUS_DSLBASE + 0x0058) /* hwdata */ ++#define AR531XPLUS_AHB_ERR3 (AR531XPLUS_DSLBASE + 0x005c) /* hrdata */ ++#define AR531XPLUS_AHB_ERR4 (AR531XPLUS_DSLBASE + 0x0060) /* status */ ++ ++#define AHB_ERROR_DET 1 /* AHB Error has been detected, */ ++ /* write 1 to clear all bits in ERR0 */ ++#define AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */ ++#define AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */ ++ ++#define PROCERR_HMAST 0x0000000f ++#define PROCERR_HMAST_DFLT 0 ++#define PROCERR_HMAST_WMAC 1 ++#define PROCERR_HMAST_ENET 2 ++#define PROCERR_HMAST_PCIENDPT 3 ++#define PROCERR_HMAST_LOCAL 4 ++#define PROCERR_HMAST_CPU 5 ++#define PROCERR_HMAST_PCITGT 6 ++ ++#define PROCERR_HMAST_S 0 ++#define PROCERR_HWRITE 0x00000010 ++#define PROCERR_HSIZE 0x00000060 ++#define PROCERR_HSIZE_S 5 ++#define PROCERR_HTRANS 0x00000180 ++#define PROCERR_HTRANS_S 7 ++#define PROCERR_HBURST 0x00000e00 ++#define PROCERR_HBURST_S 9 ++ ++ ++ ++/* ++ * Clock Control ++ */ ++#define AR531XPLUS_PLLC_CTL (AR531XPLUS_DSLBASE + 0x0064) ++#define AR531XPLUS_PLLV_CTL (AR531XPLUS_DSLBASE + 0x0068) ++#define AR531XPLUS_CPUCLK (AR531XPLUS_DSLBASE + 0x006c) ++#define AR531XPLUS_AMBACLK (AR531XPLUS_DSLBASE + 0x0070) ++#define AR531XPLUS_SYNCCLK (AR531XPLUS_DSLBASE + 0x0074) ++#define AR531XPLUS_DSL_SLEEP_CTL (AR531XPLUS_DSLBASE + 0x0080) ++#define AR531XPLUS_DSL_SLEEP_DUR (AR531XPLUS_DSLBASE + 0x0084) ++ ++/* PLLc Control fields */ ++#define PLLC_REF_DIV_M 0x00000003 ++#define PLLC_REF_DIV_S 0 ++#define PLLC_FDBACK_DIV_M 0x0000007C ++#define PLLC_FDBACK_DIV_S 2 ++#define PLLC_ADD_FDBACK_DIV_M 0x00000080 ++#define PLLC_ADD_FDBACK_DIV_S 7 ++#define PLLC_CLKC_DIV_M 0x0001c000 ++#define PLLC_CLKC_DIV_S 14 ++#define PLLC_CLKM_DIV_M 0x00700000 ++#define PLLC_CLKM_DIV_S 20 ++ ++/* CPU CLK Control fields */ ++#define CPUCLK_CLK_SEL_M 0x00000003 ++#define CPUCLK_CLK_SEL_S 0 ++#define CPUCLK_CLK_DIV_M 0x0000000c ++#define CPUCLK_CLK_DIV_S 2 ++ ++/* AMBA CLK Control fields */ ++#define AMBACLK_CLK_SEL_M 0x00000003 ++#define AMBACLK_CLK_SEL_S 0 ++#define AMBACLK_CLK_DIV_M 0x0000000c ++#define AMBACLK_CLK_DIV_S 2 ++ ++#if defined(COBRA_EMUL) ++#define AR531XPLUS_AMBA_CLOCK_RATE 20000000 ++#define AR531XPLUS_CPU_CLOCK_RATE 40000000 ++#else ++#if defined(DEFAULT_PLL) ++#define AR531XPLUS_AMBA_CLOCK_RATE 40000000 ++#define AR531XPLUS_CPU_CLOCK_RATE 40000000 ++#else ++#define AR531XPLUS_AMBA_CLOCK_RATE 92000000 ++#define AR531XPLUS_CPU_CLOCK_RATE 184000000 ++#endif /* ! DEFAULT_PLL */ ++#endif /* ! COBRA_EMUL */ ++ ++#define AR531XPLUS_UART_CLOCK_RATE AR531XPLUS_AMBA_CLOCK_RATE ++#define AR531XPLUS_SDRAM_CLOCK_RATE AR531XPLUS_AMBA_CLOCK_RATE ++ ++/* ++ * The UART computes baud rate as: ++ * baud = clock / (16 * divisor) ++ * where divisor is specified as a High Byte (DLM) and a Low Byte (DLL). ++ */ ++#define DESIRED_BAUD_RATE 38400 ++ ++/* ++ * The WATCHDOG value is computed as ++ * 10 seconds * AR531X_WATCHDOG_CLOCK_RATE ++ */ ++#define DESIRED_WATCHDOG_SECONDS 10 ++#define AR531X_WATCHDOG_TIME \ ++ (DESIRED_WATCHDOG_SECONDS * AR531X_WATCHDOG_CLOCK_RATE) ++ ++ ++#define CLOCKCTL_UART0 0x0010 /* enable UART0 external clock */ ++ ++ ++ /* ++ * Applicable "PCICFG" bits for WLAN(s). Assoc status and LED mode. ++ */ ++#define AR531X_PCICFG (AR531X_RESETTMR + 0x00b0) ++#define ASSOC_STATUS_M 0x00000003 ++#define ASSOC_STATUS_NONE 0 ++#define ASSOC_STATUS_PENDING 1 ++#define ASSOC_STATUS_ASSOCIATED 2 ++#define LED_MODE_M 0x0000001c ++#define LED_BLINK_THRESHOLD_M 0x000000e0 ++#define LED_SLOW_BLINK_MODE 0x00000100 ++ ++/* ++ * GPIO ++ */ ++ ++#define AR531XPLUS_GPIO_DI (AR531XPLUS_DSLBASE + 0x0088) ++#define AR531XPLUS_GPIO_DO (AR531XPLUS_DSLBASE + 0x0090) ++#define AR531XPLUS_GPIO_CR (AR531XPLUS_DSLBASE + 0x0098) ++#define AR531XPLUS_GPIO_INT (AR531XPLUS_DSLBASE + 0x00a0) ++ ++#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ ++#define GPIO_CR_O(x) (1 << (x)) /* output */ ++#define GPIO_CR_I(x) (0 << (x)) /* input */ ++ ++#define GPIO_INT(x,Y) ((x) << (8 * (Y))) /* interrupt enable */ ++#define GPIO_INT_M(Y) ((0x3F) << (8 * (Y))) /* mask for int */ ++#define GPIO_INT_LVL(x,Y) ((x) << (8 * (Y) + 6)) /* interrupt level */ ++#define GPIO_INT_LVL_M(Y) ((0x3) << (8 * (Y) + 6)) /* mask for int level */ ++ ++#define AR531XPLUS_RESET_GPIO 5 ++#define AR531XPLUS_NUM_GPIO 22 ++ ++ ++/* ++ * PCI Clock Control ++ */ ++ ++#define AR531XPLUS_PCICLK (AR531XPLUS_DSLBASE + 0x00a4) ++ ++#define PCICLK_INPUT_M 0x3 ++#define PCICLK_INPUT_S 0 ++ ++#define PCICLK_PLLC_CLKM 0 ++#define PCICLK_PLLC_CLKM1 1 ++#define PCICLK_PLLC_CLKC 2 ++#define PCICLK_REF_CLK 3 ++ ++#define PCICLK_DIV_M 0xc ++#define PCICLK_DIV_S 2 ++ ++#define PCICLK_IN_FREQ 0 ++#define PCICLK_IN_FREQ_DIV_6 1 ++#define PCICLK_IN_FREQ_DIV_8 2 ++#define PCICLK_IN_FREQ_DIV_10 3 ++ ++/* ++ * Observation Control Register ++ */ ++#define AR531XPLUS_OCR (AR531XPLUS_DSLBASE + 0x00b0) ++#define OCR_GPIO0_IRIN 0x0040 ++#define OCR_GPIO1_IROUT 0x0080 ++#define OCR_GPIO3_RXCLR 0x0200 ++ ++/* ++ * General Clock Control ++ */ ++ ++#define AR531XPLUS_MISCCLK (AR531XPLUS_DSLBASE + 0x00b4) ++#define MISCCLK_PLLBYPASS_EN 0x00000001 ++#define MISCCLK_PROCREFCLK 0x00000002 ++ ++/* ++ * SDRAM Controller ++ * - No read or write buffers are included. ++ */ ++#define AR531XPLUS_MEM_CFG (AR531XPLUS_SDRAMCTL + 0x00) ++#define AR531XPLUS_MEM_CTRL (AR531XPLUS_SDRAMCTL + 0x0c) ++#define AR531XPLUS_MEM_REF (AR531XPLUS_SDRAMCTL + 0x10) ++ ++#define SDRAM_DATA_WIDTH_M 0x00006000 ++#define SDRAM_DATA_WIDTH_S 13 ++ ++#define SDRAM_COL_WIDTH_M 0x00001E00 ++#define SDRAM_COL_WIDTH_S 9 ++ ++#define SDRAM_ROW_WIDTH_M 0x000001E0 ++#define SDRAM_ROW_WIDTH_S 5 ++ ++#define SDRAM_BANKADDR_BITS_M 0x00000018 ++#define SDRAM_BANKADDR_BITS_S 3 ++ ++ ++/* ++ * SDRAM Memory Refresh (MEM_REF) value is computed as: ++ * MEMCTL_SREFR = (Tr * hclk_freq) / R ++ * where Tr is max. time of refresh of any single row ++ * R is number of rows in the DRAM ++ * For most 133MHz SDRAM parts, Tr=64ms, R=4096 or 8192 ++ */ ++#if defined(COBRA_EMUL) ++#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE 0x96 ++#else ++#if defined(DEFAULT_PLL) ++#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE 0x200 ++#else ++#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE 0x61a ++#endif /* ! DEFAULT_PLL */ ++#endif ++ ++#if defined(AR531XPLUS) ++ ++#define AR531XPLUS_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ ++#define AR531XPLUS_SDRAM_DATA_WIDTH 16 /* bits */ ++#define AR531XPLUS_SDRAM_COL_WIDTH 8 ++#define AR531XPLUS_SDRAM_ROW_WIDTH 12 ++ ++#else ++ ++#define AR531XPLUS_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ ++#define AR531XPLUS_SDRAM_DATA_WIDTH 16 ++#define AR531XPLUS_SDRAM_COL_WIDTH 8 ++#define AR531XPLUS_SDRAM_ROW_WIDTH 12 ++ ++#endif /* ! AR531XPLUS */ ++ ++/* ++ * SPI Flash Interface Registers ++ */ ++ ++#define AR531XPLUS_SPI_CTL (AR531XPLUS_SPI + 0x00) ++#define AR531XPLUS_SPI_OPCODE (AR531XPLUS_SPI + 0x04) ++#define AR531XPLUS_SPI_DATA (AR531XPLUS_SPI + 0x08) ++ ++#define SPI_CTL_START 0x00000100 ++#define SPI_CTL_BUSY 0x00010000 ++#define SPI_CTL_TXCNT_MASK 0x0000000f ++#define SPI_CTL_RXCNT_MASK 0x000000f0 ++#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff ++#define SPI_CTL_SIZE_MASK 0x00060000 ++ ++#define SPI_CTL_CLK_SEL_MASK 0x03000000 ++#define SPI_OPCODE_MASK 0x000000ff ++ ++/* ++ * PCI-MAC Configuration registers ++ */ ++#define PCI_MAC_RC (AR531XPLUS_PCI + 0x4000) ++#define PCI_MAC_SCR (AR531XPLUS_PCI + 0x4004) ++#define PCI_MAC_INTPEND (AR531XPLUS_PCI + 0x4008) ++#define PCI_MAC_SFR (AR531XPLUS_PCI + 0x400C) ++#define PCI_MAC_PCICFG (AR531XPLUS_PCI + 0x4010) ++#define PCI_MAC_SREV (AR531XPLUS_PCI + 0x4020) ++ ++#define PCI_MAC_RC_MAC 0x00000001 ++#define PCI_MAC_RC_BB 0x00000002 ++ ++#define PCI_MAC_SCR_SLMODE_M 0x00030000 ++#define PCI_MAC_SCR_SLMODE_S 16 ++#define PCI_MAC_SCR_SLM_FWAKE 0 ++#define PCI_MAC_SCR_SLM_FSLEEP 1 ++#define PCI_MAC_SCR_SLM_NORMAL 2 ++ ++#define PCI_MAC_SFR_SLEEP 0x00000001 ++ ++#define PCI_MAC_PCICFG_SPWR_DN 0x00010000 ++ ++ ++ ++ ++/* ++ * PCI Bus Interface Registers ++ */ ++#define AR531XPLUS_PCI_1MS_REG (AR531XPLUS_PCI + 0x0008) ++#define AR531XPLUS_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ ++ ++#define AR531XPLUS_PCI_MISC_CONFIG (AR531XPLUS_PCI + 0x000c) ++#define AR531XPLUS_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ ++#define AR531XPLUS_PCIMISC_CFG_SEL 0x00000002 /* mem or config cycles */ ++#define AR531XPLUS_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */ ++#define AR531XPLUS_PCIMISC_RST_MODE 0x00000030 ++#define AR531XPLUS_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */ ++#define AR531XPLUS_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */ ++#define AR531XPLUS_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */ ++#define AR531XPLUS_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */ ++#define AR531XPLUS_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */ ++#define AR531XPLUS_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */ ++#define AR531XPLUS_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */ ++#define AR531XPLUS_PCICACHE_DIS 0x00001000 /* PCI external access cache disable */ ++ ++#define AR531XPLUS_PCI_OUT_TSTAMP (AR531XPLUS_PCI + 0x0010) ++ ++#define AR531XPLUS_PCI_UNCACHE_CFG (AR531XPLUS_PCI + 0x0014) ++ ++#define AR531XPLUS_PCI_IN_EN (AR531XPLUS_PCI + 0x0100) ++#define AR531XPLUS_PCI_IN_EN0 0x01 /* Enable chain 0 */ ++#define AR531XPLUS_PCI_IN_EN1 0x02 /* Enable chain 1 */ ++#define AR531XPLUS_PCI_IN_EN2 0x04 /* Enable chain 2 */ ++#define AR531XPLUS_PCI_IN_EN3 0x08 /* Enable chain 3 */ ++ ++#define AR531XPLUS_PCI_IN_DIS (AR531XPLUS_PCI + 0x0104) ++#define AR531XPLUS_PCI_IN_DIS0 0x01 /* Disable chain 0 */ ++#define AR531XPLUS_PCI_IN_DIS1 0x02 /* Disable chain 1 */ ++#define AR531XPLUS_PCI_IN_DIS2 0x04 /* Disable chain 2 */ ++#define AR531XPLUS_PCI_IN_DIS3 0x08 /* Disable chain 3 */ ++ ++#define AR531XPLUS_PCI_IN_PTR (AR531XPLUS_PCI + 0x0200) ++ ++#define AR531XPLUS_PCI_OUT_EN (AR531XPLUS_PCI + 0x0400) ++#define AR531XPLUS_PCI_OUT_EN0 0x01 /* Enable chain 0 */ ++ ++#define AR531XPLUS_PCI_OUT_DIS (AR531XPLUS_PCI + 0x0404) ++#define AR531XPLUS_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ ++ ++#define AR531XPLUS_PCI_OUT_PTR (AR531XPLUS_PCI + 0x0408) ++ ++#define AR531XPLUS_PCI_INT_STATUS (AR531XPLUS_PCI + 0x0500) /* write one to clr */ ++#define AR531XPLUS_PCI_TXINT 0x00000001 /* Desc In Completed */ ++#define AR531XPLUS_PCI_TXOK 0x00000002 /* Desc In OK */ ++#define AR531XPLUS_PCI_TXERR 0x00000004 /* Desc In ERR */ ++#define AR531XPLUS_PCI_TXEOL 0x00000008 /* Desc In End-of-List */ ++#define AR531XPLUS_PCI_RXINT 0x00000010 /* Desc Out Completed */ ++#define AR531XPLUS_PCI_RXOK 0x00000020 /* Desc Out OK */ ++#define AR531XPLUS_PCI_RXERR 0x00000040 /* Desc Out ERR */ ++#define AR531XPLUS_PCI_RXEOL 0x00000080 /* Desc Out EOL */ ++#define AR531XPLUS_PCI_TXOOD 0x00000200 /* Desc In Out-of-Desc */ ++#define AR531XPLUS_PCI_MASK 0x0000FFFF /* Desc Mask */ ++#define AR531XPLUS_PCI_EXT_INT 0x02000000 ++#define AR531XPLUS_PCI_ABORT_INT 0x04000000 ++ ++#define AR531XPLUS_PCI_INT_MASK (AR531XPLUS_PCI + 0x0504) /* same as INT_STATUS */ ++ ++#define AR531XPLUS_PCI_INTEN_REG (AR531XPLUS_PCI + 0x0508) ++#define AR531XPLUS_PCI_INT_DISABLE 0x00 /* disable pci interrupts */ ++#define AR531XPLUS_PCI_INT_ENABLE 0x01 /* enable pci interrupts */ ++ ++#define AR531XPLUS_PCI_HOST_IN_EN (AR531XPLUS_PCI + 0x0800) ++#define AR531XPLUS_PCI_HOST_IN_DIS (AR531XPLUS_PCI + 0x0804) ++#define AR531XPLUS_PCI_HOST_IN_PTR (AR531XPLUS_PCI + 0x0810) ++#define AR531XPLUS_PCI_HOST_OUT_EN (AR531XPLUS_PCI + 0x0900) ++#define AR531XPLUS_PCI_HOST_OUT_DIS (AR531XPLUS_PCI + 0x0904) ++#define AR531XPLUS_PCI_HOST_OUT_PTR (AR531XPLUS_PCI + 0x0908) ++ ++ ++/* ++ * Local Bus Interface Registers ++ */ ++#define AR531XPLUS_LB_CONFIG (AR531XPLUS_LOCAL + 0x0000) ++#define AR531XPLUS_LBCONF_OE 0x00000001 /* =1 OE is low-true */ ++#define AR531XPLUS_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */ ++#define AR531XPLUS_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */ ++#define AR531XPLUS_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */ ++#define AR531XPLUS_LBCONF_WE 0x00000010 /* =1 Write En is low-true */ ++#define AR531XPLUS_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */ ++#define AR531XPLUS_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */ ++#define AR531XPLUS_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */ ++#define AR531XPLUS_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */ ++#define AR531XPLUS_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */ ++#define AR531XPLUS_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */ ++#define AR531XPLUS_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */ ++#define AR531XPLUS_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */ ++#define AR531XPLUS_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */ ++#define AR531XPLUS_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */ ++#define AR531XPLUS_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */ ++#define AR531XPLUS_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */ ++#define AR531XPLUS_LBCONF_INT 0x00020000 /* =1 Intr is low true */ ++#define AR531XPLUS_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */ ++#define AR531XPLUS_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */ ++#define AR531XPLUS_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */ ++#define AR531XPLUS_LBCONF_INT_CTR3 0x000C0000 /* GND drive, Vdd drive */ ++#define AR531XPLUS_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */ ++#define AR531XPLUS_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */ ++#define AR531XPLUS_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */ ++ ++#define AR531XPLUS_LB_CLKSEL (AR531XPLUS_LOCAL + 0x0004) ++#define AR531XPLUS_LBCLK_EXT 0x0001 /* use external clk for lb */ ++ ++#define AR531XPLUS_LB_1MS (AR531XPLUS_LOCAL + 0x0008) ++#define AR531XPLUS_LB1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ ++ ++#define AR531XPLUS_LB_MISCCFG (AR531XPLUS_LOCAL + 0x000C) ++#define AR531XPLUS_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */ ++#define AR531XPLUS_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */ ++#define AR531XPLUS_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */ ++#define AR531XPLUS_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */ ++#define AR531XPLUS_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */ ++#define AR531XPLUS_LBM_TIMEOUT_MASK 0x00FFFF80 ++#define AR531XPLUS_LBM_TIMEOUT_SHFT 7 ++#define AR531XPLUS_LBM_PORTMUX 0x07000000 ++ ++ ++#define AR531XPLUS_LB_RXTSOFF (AR531XPLUS_LOCAL + 0x0010) ++ ++#define AR531XPLUS_LB_TX_CHAIN_EN (AR531XPLUS_LOCAL + 0x0100) ++#define AR531XPLUS_LB_TXEN_0 0x01 ++#define AR531XPLUS_LB_TXEN_1 0x02 ++#define AR531XPLUS_LB_TXEN_2 0x04 ++#define AR531XPLUS_LB_TXEN_3 0x08 ++ ++#define AR531XPLUS_LB_TX_CHAIN_DIS (AR531XPLUS_LOCAL + 0x0104) ++#define AR531XPLUS_LB_TX_DESC_PTR (AR531XPLUS_LOCAL + 0x0200) ++ ++#define AR531XPLUS_LB_RX_CHAIN_EN (AR531XPLUS_LOCAL + 0x0400) ++#define AR531XPLUS_LB_RXEN 0x01 ++ ++#define AR531XPLUS_LB_RX_CHAIN_DIS (AR531XPLUS_LOCAL + 0x0404) ++#define AR531XPLUS_LB_RX_DESC_PTR (AR531XPLUS_LOCAL + 0x0408) ++ ++#define AR531XPLUS_LB_INT_STATUS (AR531XPLUS_LOCAL + 0x0500) ++#define AR531XPLUS_INT_TX_DESC 0x0001 ++#define AR531XPLUS_INT_TX_OK 0x0002 ++#define AR531XPLUS_INT_TX_ERR 0x0004 ++#define AR531XPLUS_INT_TX_EOF 0x0008 ++#define AR531XPLUS_INT_RX_DESC 0x0010 ++#define AR531XPLUS_INT_RX_OK 0x0020 ++#define AR531XPLUS_INT_RX_ERR 0x0040 ++#define AR531XPLUS_INT_RX_EOF 0x0080 ++#define AR531XPLUS_INT_TX_TRUNC 0x0100 ++#define AR531XPLUS_INT_TX_STARVE 0x0200 ++#define AR531XPLUS_INT_LB_TIMEOUT 0x0400 ++#define AR531XPLUS_INT_LB_ERR 0x0800 ++#define AR531XPLUS_INT_MBOX_WR 0x1000 ++#define AR531XPLUS_INT_MBOX_RD 0x2000 ++ ++/* Bit definitions for INT MASK are the same as INT_STATUS */ ++#define AR531XPLUS_LB_INT_MASK (AR531XPLUS_LOCAL + 0x0504) ++ ++#define AR531XPLUS_LB_INT_EN (AR531XPLUS_LOCAL + 0x0508) ++#define AR531XPLUS_LB_MBOX (AR531XPLUS_LOCAL + 0x0600) ++ ++ ++ ++/* ++ * IR Interface Registers ++ */ ++#define AR531XPLUS_IR_PKTDATA (AR531XPLUS_IR + 0x0000) ++ ++#define AR531XPLUS_IR_PKTLEN (AR531XPLUS_IR + 0x07fc) /* 0 - 63 */ ++ ++#define AR531XPLUS_IR_CONTROL (AR531XPLUS_IR + 0x0800) ++#define AR531XPLUS_IRCTL_TX 0x00000000 /* use as tranmitter */ ++#define AR531XPLUS_IRCTL_RX 0x00000001 /* use as receiver */ ++#define AR531XPLUS_IRCTL_SAMPLECLK_MASK 0x00003ffe /* Sample clk divisor mask */ ++#define AR531XPLUS_IRCTL_SAMPLECLK_SHFT 1 ++#define AR531XPLUS_IRCTL_OUTPUTCLK_MASK 0x03ffc000 /* Output clk divisor mask */ ++#define AR531XPLUS_IRCTL_OUTPUTCLK_SHFT 14 ++ ++#define AR531XPLUS_IR_STATUS (AR531XPLUS_IR + 0x0804) ++#define AR531XPLUS_IRSTS_RX 0x00000001 /* receive in progress */ ++#define AR531XPLUS_IRSTS_TX 0x00000002 /* transmit in progress */ ++ ++#define AR531XPLUS_IR_CONFIG (AR531XPLUS_IR + 0x0808) ++#define AR531XPLUS_IRCFG_INVIN 0x00000001 /* invert input polarity */ ++#define AR531XPLUS_IRCFG_INVOUT 0x00000002 /* invert output polarity */ ++#define AR531XPLUS_IRCFG_SEQ_START_WIN_SEL 0x00000004 /* 1 => 28, 0 => 7 */ ++#define AR531XPLUS_IRCFG_SEQ_START_THRESH 0x000000f0 /* */ ++#define AR531XPLUS_IRCFG_SEQ_END_UNIT_SEL 0x00000100 /* */ ++#define AR531XPLUS_IRCFG_SEQ_END_UNIT_THRESH 0x00007e00 /* */ ++#define AR531XPLUS_IRCFG_SEQ_END_WIN_SEL 0x00008000 /* */ ++#define AR531XPLUS_IRCFG_SEQ_END_WIN_THRESH 0x001f0000 /* */ ++#define AR531XPLUS_IRCFG_NUM_BACKOFF_WORDS 0x01e00000 /* */ ++ ++/* ++ * PCI memory constants: Memory area 1 and 2 are the same size - ++ * (twice the PCI_TLB_PAGE_SIZE). The definition of ++ * CPU_TO_PCI_MEM_SIZE is coupled with the TLB setup routine ++ * sysLib.c/sysTlbInit(), in that it assumes that 2 pages of size ++ * PCI_TLB_PAGE_SIZE are set up in the TLB for each PCI memory space. ++ */ ++ ++#define CPU_TO_PCI_MEM_BASE1 0xE0000000 ++#define CPU_TO_PCI_MEM_SIZE1 (2*PCI_TLB_PAGE_SIZE) ++ ++ ++/* TLB attributes for PCI transactions */ ++ ++#define PCI_MMU_PAGEMASK 0x00003FFF ++#define MMU_PAGE_UNCACHED 0x00000010 ++#define MMU_PAGE_DIRTY 0x00000004 ++#define MMU_PAGE_VALID 0x00000002 ++#define MMU_PAGE_GLOBAL 0x00000001 ++#define PCI_MMU_PAGEATTRIB (MMU_PAGE_UNCACHED|MMU_PAGE_DIRTY|\ ++ MMU_PAGE_VALID|MMU_PAGE_GLOBAL) ++#define PCI_MEMORY_SPACE1_VIRT 0xE0000000 /* Used for non-prefet mem */ ++#define PCI_MEMORY_SPACE1_PHYS 0x80000000 ++#define PCI_TLB_PAGE_SIZE 0x01000000 ++#define TLB_HI_MASK 0xFFFFE000 ++#define TLB_LO_MASK 0x3FFFFFFF ++#define PAGEMASK_SHIFT 11 ++#define TLB_LO_SHIFT 6 ++ ++#define PCI_MAX_LATENCY 0xFFF /* Max PCI latency */ ++ ++#define HOST_PCI_DEV_ID 3 ++#define HOST_PCI_MBAR0 0x10000000 ++#define HOST_PCI_MBAR1 0x20000000 ++#define HOST_PCI_MBAR2 0x30000000 ++ ++#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1 ++#define PCI_DEVICE_MEM_SPACE 0x800000 ++ ++ ++typedef unsigned int AR531X_REG; ++ ++#define sysRegRead(phys) \ ++ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) ++ ++#define sysRegWrite(phys, val) \ ++ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) ++ ++ ++ ++/* ++ * This is board-specific data that is stored in a "fixed" location in flash. ++ * It is shared across operating systems, so it should not be changed lightly. ++ * The main reason we need it is in order to extract the ethernet MAC ++ * address(es). ++ */ ++struct ar531x_boarddata { ++ u32 magic; /* board data is valid */ ++#define AR531X_BD_MAGIC 0x35333131 /* "5311", for all 531x platforms */ ++ u16 cksum; /* checksum (starting with BD_REV 2) */ ++ u16 rev; /* revision of this struct */ ++#define BD_REV 4 ++ char boardName[64]; /* Name of board */ ++ u16 major; /* Board major number */ ++ u16 minor; /* Board minor number */ ++ u32 config; /* Board configuration */ ++#define BD_ENET0 0x00000001 /* ENET0 is stuffed */ ++#define BD_ENET1 0x00000002 /* ENET1 is stuffed */ ++#define BD_UART1 0x00000004 /* UART1 is stuffed */ ++#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ ++#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ ++#define BD_SYSLED 0x00000020 /* System LED stuffed */ ++#define BD_EXTUARTCLK 0x00000040 /* External UART clock */ ++#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ ++#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ ++#define BD_WLAN0 0x00000200 /* Enable WLAN0 */ ++#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ memCap for testing */ ++#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ ++#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ ++#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ ++#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ ++#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ ++#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ ++#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ ++ u16 resetConfigGpio; /* Reset factory GPIO pin */ ++ u16 sysLedGpio; /* System LED GPIO pin */ ++ ++ u32 cpuFreq; /* CPU core frequency in Hz */ ++ u32 sysFreq; /* System frequency in Hz */ ++ u32 cntFreq; /* Calculated C0_COUNT frequency */ ++ ++ u8 wlan0Mac[6]; ++ u8 enet0Mac[6]; ++ u8 enet1Mac[6]; ++ ++ u16 pciId; /* Pseudo PCIID for common code */ ++ u16 memCap; /* cap bank1 in MB */ ++ ++ /* version 3 */ ++ u8 wlan1Mac[6]; /* (ar5212) */ ++}; ++ ++#endif ++ ++#endif /* AR531X_H */ +diff -urN linux-mips-orig/drivers/net/ath/ar531xlnx.h linux-mips-new/drivers/net/ath/ar531xlnx.h +--- linux-mips-orig/drivers/net/ath/ar531xlnx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ar531xlnx.h 2005-12-31 12:33:57.676538368 +0000 +@@ -0,0 +1,137 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * This file contains definitions needed in order to compile ++ * AR531X products for linux. Definitions that are largely ++ * AR531X-specific and independent of operating system belong ++ * in ar531x.h rather than this file. ++ */ ++#ifndef __AR531XLNX_H ++#define __AR531XLNX_H ++#include "ar531x.h" ++ ++#define MIPS_CPU_IRQ_BASE 0x00 ++#define AR531X_HIGH_PRIO 0x10 ++#define AR531X_MISC_IRQ_BASE 0x20 ++#define AR531X_GPIO_IRQ_BASE 0x30 ++ ++/* Software's idea of interrupts handled by "CPU Interrupt Controller" */ ++#if CONFIG_AR5315 ++#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 ++#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ ++#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ ++#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ ++#define AR531X_IRQ_LCBUS_PCI MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ ++#define AR531X_IRQ_WLAN0_POLL MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ ++#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ ++#else ++#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 ++#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ ++#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ ++#define AR531X_IRQ_ENET1_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ ++#define AR531X_IRQ_WLAN1_INTRS MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */ ++#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ ++#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ ++#endif ++ ++/* Miscellaneous interrupts, which share IP6 or IP2 */ ++#define AR531X_MISC_IRQ_NONE AR531X_MISC_IRQ_BASE+0 ++#define AR531X_MISC_IRQ_TIMER AR531X_MISC_IRQ_BASE+1 ++#define AR531X_MISC_IRQ_AHB_PROC AR531X_MISC_IRQ_BASE+2 ++#define AR531X_MISC_IRQ_AHB_DMA AR531X_MISC_IRQ_BASE+3 ++#define AR531X_MISC_IRQ_GPIO AR531X_MISC_IRQ_BASE+4 ++#define AR531X_MISC_IRQ_UART0 AR531X_MISC_IRQ_BASE+5 ++#define AR531X_MISC_IRQ_UART0_DMA AR531X_MISC_IRQ_BASE+6 ++#define AR531X_MISC_IRQ_WATCHDOG AR531X_MISC_IRQ_BASE+7 ++#define AR531X_MISC_IRQ_LOCAL AR531X_MISC_IRQ_BASE+8 ++#define AR531X_MISC_IRQ_COUNT 9 ++ ++/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */ ++#define AR531X_GPIO_IRQ_NONE AR531X_MISC_IRQ_BASE+0 ++#define AR531X_GPIO_IRQ(n) AR531X_MISC_IRQ_BASE+(n)+1 ++#define AR531X_GPIO_IRQ_COUNT 9 ++ ++#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr) ++#define PHYS_TO_K0(physaddr) KSEG0ADDR(physaddr) ++#define UNMAPPED_TO_PHYS(vaddr) PHYSADDR(vaddr) ++#define IS_UNMAPPED_VADDR(vaddr) \ ++ ((KSEGX(vaddr) == KSEG0) || (KSEGX(vaddr) == KSEG1)) ++ ++/* IOCTL commands for /proc/ar531x */ ++#define AR531X_CTRL_DO_BREAKPOINT 1 ++#define AR531X_CTRL_DO_MADWIFI 2 ++ ++/* ++ * Definitions for operating system portability. ++ * These are vxWorks-->Linux translations. ++ */ ++#define LOCAL static ++#define BOOL int ++#define TRUE 1 ++#define FALSE 0 ++#define UINT8 u8 ++#define UINT16 u16 ++#define UINT32 u32 ++#define PRINTF printk ++#if /* DEBUG */ 1 ++#define DEBUG_PRINTF printk ++#define printf printk ++#define INLINE ++#else ++DEBUG_PRINTF while (0) printk ++#define INLINE inline ++#endif ++#define sysUDelay(usecs) udelay(usecs) ++#define sysMsDelay(msecs) mdelay(msecs) ++typedef volatile UINT8 *VIRT_ADDR; ++#define MALLOC(sz) kmalloc(sz, GFP_KERNEL) ++#define MALLOC_NOSLEEP(sz) kmalloc(sz, GFP_ATOMIC) ++#define FREE(ptr) kfree((void *)ptr) ++#define BSP_BUG() do { printk("kernel BSP BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) ++#define BSP_BUG_ON(condition) do { if (unlikely((condition)!=0)) BSP_BUG(); } while(0) ++#define ASSERT(x) BSP_BUG_ON(!(x)) ++ ++extern struct ar531x_boarddata *ar531x_board_configuration; ++extern char *ar531x_radio_configuration; ++extern char *enet_mac_address_get(int MACUnit); ++ ++extern void kgdbInit(void); ++extern int kgdbEnabled(void); ++extern void breakpoint(void); ++extern int kgdbInterrupt(void); ++extern unsigned int ar531x_cpu_frequency(void); ++extern unsigned int ar531x_sys_frequency(void); ++ ++/* GPIO support */ ++extern struct irqaction spurious_gpio; ++extern unsigned int gpioIntMask; ++extern void ar531x_gpio_intr_init(int irq_base); ++extern void ar531x_gpio_ctrl_output(int gpio); ++extern void ar531x_gpio_ctrl_input(int gpio); ++extern void ar531x_gpio_set(int gpio, int val); ++extern int ar531x_gpio_get(int gpio); ++extern void ar531x_gpio_intr_enable(unsigned int irq); ++extern void ar531x_gpio_intr_disable(unsigned int irq); ++ ++/* Watchdog Timer support */ ++extern int watchdog_start(unsigned int milliseconds); ++extern int watchdog_stop(void); ++extern int watchdog_is_enabled(void); ++extern unsigned int watchdog_min_timer_reached(void); ++extern void watchdog_notify_alive(void); ++ ++#define A_DATA_CACHE_INVAL(start, length) \ ++ dma_cache_inv((UINT32)(start),(length)) ++ ++#define sysWbFlush() mb() ++ ++#define intDisable(x) cli() ++#define intEnable(x) sti() ++ ++#endif /* __AR531XLNX_H */ +diff -urN linux-mips-orig/drivers/net/ath/ipPhy.c linux-mips-new/drivers/net/ath/ipPhy.c +--- linux-mips-orig/drivers/net/ath/ipPhy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ipPhy.c 2005-12-31 12:33:57.677538216 +0000 +@@ -0,0 +1,833 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Manage the ICPLUS ethernet PHY. ++ * ++ * All definitions in this file are operating system independent! ++ */ ++ ++#if defined(linux) ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++#endif ++ ++#include "ae531xmac.h" ++#include "ae531xreg.h" ++#include "ipPhy.h" ++ ++/* PHY selections and access functions */ ++ ++typedef enum { ++ PHY_SRCPORT_INFO, ++ PHY_PORTINFO_SIZE, ++} PHY_CAP_TYPE; ++ ++typedef enum { ++ PHY_SRCPORT_NONE, ++ PHY_SRCPORT_VLANTAG, ++ PHY_SRCPORT_TRAILER, ++} PHY_SRCPORT_TYPE; ++ ++#ifdef DEBUG ++#define DRV_DEBUG 1 ++#endif ++#define DRV_DEBUG 1 ++ ++#if DRV_DEBUG ++#define DRV_DEBUG_PHYERROR 0x00000001 ++#define DRV_DEBUG_PHYCHANGE 0x00000002 ++#define DRV_DEBUG_PHYSETUP 0x00000004 ++ ++int ipPhyDebug = DRV_DEBUG_PHYERROR; ++ ++#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ ++{ \ ++ if (ipPhyDebug & (FLG)) { \ ++ logMsg(X0, X1, X2, X3, X4, X5, X6); \ ++ } \ ++} ++ ++#define DRV_MSG(x,a,b,c,d,e,f) \ ++ logMsg(x,a,b,c,d,e,f) ++ ++#define DRV_PRINT(FLG, X) \ ++{ \ ++ if (ipPhyDebug & (FLG)) { \ ++ printf X; \ ++ } \ ++} ++ ++#else /* !DRV_DEBUG */ ++#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6) ++#define DRV_MSG(x,a,b,c,d,e,f) ++#define DRV_PRINT(DBG_SW,X) ++#endif ++ ++#define IP_LAN_PORT_VLAN 1 ++#define IP_WAN_PORT_VLAN 2 ++ ++#define ENET_UNIT_DEFAULT 0 ++ ++/* ++ * Track per-PHY port information. ++ */ ++typedef struct { ++ BOOL isEnetPort; /* normal enet port */ ++ BOOL isPhyAlive; /* last known state of link */ ++ int ethUnit; /* MAC associated with this phy port */ ++ UINT32 phyBase; ++ UINT32 phyAddr; /* PHY registers associated with this phy port */ ++ UINT32 VLANTableSetting; /* Value to be written to VLAN table */ ++} ipPhyInfo_t; ++ ++/* ++ * Per-PHY information, indexed by PHY unit number. ++ */ ++ipPhyInfo_t ipPhyInfo[] = { ++ /* ++ * On AP30/AR5312, all PHYs are associated with MAC0. ++ * AP30/AR5312's MAC1 isn't used for anything. ++ * CONFIG_VENETDEV==1 (router) configuration: ++ * Ports 0,1,2, and 3 are "LAN ports" ++ * Port 4 is a WAN port ++ * Port 5 connects to MAC0 in the AR5312 ++ * CONFIG_VENETDEV==0 (bridge) configuration: ++ * Ports 0,1,2,3,4 are "LAN ports" ++ * Port 5 connects to the MAC0 in the AR5312 ++ */ ++ {TRUE, /* phy port 0 -- LAN port 0 */ ++ FALSE, ++ ENET_UNIT_DEFAULT, ++ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), ++ IP_PHY0_ADDR, ++ IP_LAN_PORT_VLAN ++ }, ++ ++ {TRUE, /* phy port 1 -- LAN port 1 */ ++ FALSE, ++ ENET_UNIT_DEFAULT, ++ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), ++ IP_PHY1_ADDR, ++ IP_LAN_PORT_VLAN ++ }, ++ ++ {TRUE, /* phy port 2 -- LAN port 2 */ ++ FALSE, ++ ENET_UNIT_DEFAULT, ++ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), ++ IP_PHY2_ADDR, ++ IP_LAN_PORT_VLAN ++ }, ++ ++ {TRUE, /* phy port 3 -- LAN port 3 */ ++ FALSE, ++ ENET_UNIT_DEFAULT, ++ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), ++ IP_PHY3_ADDR, ++ IP_LAN_PORT_VLAN ++ }, ++ ++ {TRUE, /* phy port 4 -- WAN port or LAN port 4 */ ++ FALSE, ++ ENET_UNIT_DEFAULT, ++ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), ++ IP_PHY4_ADDR, ++ IP_LAN_PORT_VLAN /* Send to all ports */ ++ }, ++ ++ {FALSE, /* phy port 5 -- CPU port (no RJ45 connector) */ ++ TRUE, ++ ENET_UNIT_DEFAULT, ++ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), ++ 0x00, ++ IP_LAN_PORT_VLAN /* Send to all ports */ ++ }, ++}; ++ ++#define IP_GLOBALREGBASE ((UINT32) (PHYS_TO_K1(AR531X_ENET0))) ++ ++#define IP_PHY_MAX (sizeof(ipPhyInfo) / sizeof(ipPhyInfo[0])) ++ ++/* Range of valid PHY IDs is [MIN..MAX] */ ++#define IP_ID_MIN 0 ++#define IP_ID_MAX (IP_PHY_MAX-1) ++ ++/* Convenience macros to access myPhyInfo */ ++#define IP_IS_ENET_PORT(phyUnit) (ipPhyInfo[phyUnit].isEnetPort) ++#define IP_IS_PHY_ALIVE(phyUnit) (ipPhyInfo[phyUnit].isPhyAlive) ++#define IP_ETHUNIT(phyUnit) (ipPhyInfo[phyUnit].ethUnit) ++#define IP_PHYBASE(phyUnit) (ipPhyInfo[phyUnit].phyBase) ++#define IP_PHYADDR(phyUnit) (ipPhyInfo[phyUnit].phyAddr) ++#define IP_VLAN_TABLE_SETTING(phyUnit) (ipPhyInfo[phyUnit].VLANTableSetting) ++ ++ ++#define IP_IS_ETHUNIT(phyUnit, ethUnit) \ ++ (IP_IS_ENET_PORT(phyUnit) && \ ++ IP_ETHUNIT(phyUnit) == (ethUnit)) ++ ++/* Forward references */ ++BOOL ip_phyIsLinkAlive(int phyUnit); ++LOCAL void ip_VLANInit(int ethUnit); ++LOCAL void ip_verifyReady(int ethUnit); ++#if DEBUG ++void ip_phyShow(int phyUnit); ++void ip_phySet(int phyUnit, UINT32 regnum, UINT32 value); ++void ip_globalSet(UINT32 phyAddr, UINT32 regnum, UINT32 value); ++#endif ++ ++/****************************************************************************** ++* ++* ip_phyIsLinkAlive - test to see if the specified link is alive ++* ++* RETURNS: ++* TRUE --> link is alive ++* FALSE --> link is down ++*/ ++BOOL ++ip_phyIsLinkAlive(int phyUnit) ++{ ++ UINT16 phyHwStatus; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS); ++ ++ if (phyHwStatus & IP_STATUS_LINK_PASS) { ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/****************************************************************************** ++* ++* ip_VLANInit - initialize "port-based VLANs" for the specified enet unit. ++*/ ++LOCAL void ++ip_VLANInit(int ethUnit) ++{ ++ int phyUnit; ++ UINT32 phyBase; ++ UINT32 phyReg; ++ ++ phyBase = IP_GLOBALREGBASE; ++ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (IP_ETHUNIT(phyUnit) != ethUnit) { ++ continue; ++ } ++ phyRegWrite(phyBase, IP_GLOBAL_PHY29_ADDR, ++ IP_GLOBAL_PHY29_24_REG + ((phyUnit == 5) ? (phyUnit + 1) : phyUnit), ++ IP_VLAN_TABLE_SETTING(phyUnit)); ++ ++ /* Send all packets to all ports */ ++ phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG); ++ phyReg = phyReg | ((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S); ++ phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG, phyReg); ++ } ++ phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG); ++ phyReg = phyReg | TAG_VLAN_ENABLE; ++ phyReg = phyReg & ~VID_INDX_SEL_M; ++ phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG, phyReg); ++ ++} ++ ++ ++LOCAL void ++ip_verifyReady(int ethUnit) ++{ ++ int phyUnit; ++ UINT32 phyBase = 0; ++ UINT32 phyAddr; ++ UINT16 phyID1; ++ UINT16 phyID2; ++ ++ /* ++ * The first read to the Phy port registers always fails and ++ * returns 0. So get things started with a bogus read. ++ */ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyID1 = phyRegRead(phyBase, phyAddr, IP_PHY_ID1); /* returns 0 */ ++ break; ++ } ++ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ /*******************/ ++ /* Verify phy port */ ++ /*******************/ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyID1 = phyRegRead(phyBase, phyAddr, IP_PHY_ID1); ++ if (phyID1 != IP_PHY_ID1_EXPECTATION) { ++ DRV_PRINT(DRV_DEBUG_PHYERROR, ++ ("Invalid PHY ID1 for enet%d port%d. Expected 0x%04x, read 0x%04x\n", ++ ethUnit, ++ phyUnit, ++ IP_PHY_ID1_EXPECTATION, ++ phyID1)); ++ return; ++ } ++ ++ phyID2 = phyRegRead(phyBase, phyAddr, IP_PHY_ID2); ++ if ((phyID2 & IP_OUI_LSB_MASK) != IP_OUI_LSB_EXPECTATION) { ++ DRV_PRINT(DRV_DEBUG_PHYERROR, ++ ("Invalid PHY ID2 for enet%d port %d. Expected 0x%04x, read 0x%04x\n", ++ ethUnit, ++ phyUnit, ++ IP_OUI_LSB_EXPECTATION, ++ phyID2)); ++ return; ++ } ++ ++ DRV_PRINT(DRV_DEBUG_PHYSETUP, ++ ("Found PHY enet%d port%d: model 0x%x revision 0x%x\n", ++ ethUnit, ++ phyUnit, ++ (phyID2 & IP_MODEL_NUM_MASK) >> IP_MODEL_NUM_SHIFT, ++ (phyID2 & IP_REV_NUM_MASK) >> IP_REV_NUM_SHIFT)); ++ ++ } ++} ++ ++ ++/****************************************************************************** ++* ++* ip_phySetup - reset and setup the PHY associated with ++* the specified MAC unit number. ++* ++* Resets the associated PHY port. ++* ++* RETURNS: ++* TRUE --> associated PHY is alive ++* FALSE --> no LINKs on this ethernet unit ++*/ ++ ++BOOL ++ip_phySetup(int ethUnit, UINT32 _phyBase) ++{ ++ int phyUnit; ++ UINT16 phyHwStatus; ++ UINT16 timeout; ++ int liveLinks = 0; ++ UINT32 phyBase = 0; ++ BOOL foundPhy = FALSE; ++ UINT32 phyAddr; ++ ++ /* Reset PHYs*/ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL, ++ IP_CTRL_SOFTWARE_RESET); ++ } ++ /* ++ * After the phy is reset, it takes a little while before ++ * it can respond properly. ++ */ ++ sysMsDelay(300); ++ /* Verify that the switch is what we think it is, and that it's ready */ ++ ip_verifyReady(ethUnit); ++ ++ /* See if there's any configuration data for this enet */ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (IP_ETHUNIT(phyUnit) != ethUnit) { ++ continue; ++ } ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ foundPhy = TRUE; ++ break; ++ } ++ ++ if (!foundPhy) { ++ return FALSE; /* No PHY's configured for this ethUnit */ ++ } ++ ++#ifdef COBRA_TODO ++ /* Initialize global switch settings */ ++ ++ /* Initialize the aging time */ ++ ++ /* Set the learning properties */ ++#endif ++ ++ /* start auto negogiation on each phy */ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyRegWrite(phyBase, phyAddr, IP_AUTONEG_ADVERT, ++ IP_ADVERTISE_ALL); ++ phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL, ++ IP_CTRL_AUTONEGOTIATION_ENABLE | IP_CTRL_START_AUTONEGOTIATION); ++ } ++ ++ /* ++ * Wait up to .75 seconds for ALL associated PHYs to finish ++ * autonegotiation. The only way we get out of here sooner is ++ * if ALL PHYs are connected AND finish autonegotiation. ++ */ ++ timeout=5; ++ for (phyUnit=0; (phyUnit < IP_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ for (;;) { ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS); ++ ++ if (IP_AUTONEG_DONE(phyHwStatus)) { ++ DRV_PRINT(DRV_DEBUG_PHYSETUP, ++ ("Port %d, Neg Success\n", phyUnit)); ++ break; ++ } ++ if (timeout == 0) { ++ DRV_PRINT(DRV_DEBUG_PHYSETUP, ++ ("Port %d, Negogiation timeout\n", phyUnit)); ++ break; ++ } ++ if (--timeout == 0) { ++ DRV_PRINT(DRV_DEBUG_PHYSETUP, ++ ("Port %d, Negogiation timeout\n", phyUnit)); ++ break; ++ } ++ ++ sysMsDelay(150); ++ } ++ } ++ ++ /* ++ * All PHYs have had adequate time to autonegotiate. ++ * Now initialize software status. ++ * ++ * It's possible that some ports may take a bit longer ++ * to autonegotiate; but we can't wait forever. They'll ++ * get noticed by mv_phyCheckStatusChange during regular ++ * polling activities. ++ */ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ if (ip_phyIsLinkAlive(phyUnit)) { ++ liveLinks++; ++ IP_IS_PHY_ALIVE(phyUnit) = TRUE; ++ } else { ++ IP_IS_PHY_ALIVE(phyUnit) = FALSE; ++ } ++ ++ DRV_PRINT(DRV_DEBUG_PHYSETUP, ++ ("eth%d: Phy Status=%4.4x\n", ++ ethUnit, ++ phyRegRead(IP_PHYBASE(phyUnit), ++ IP_PHYADDR(phyUnit), ++ IP_PHY_STATUS))); ++ } ++#if 0 ++ /* XXX Divy. Disable WAN/LAN seggregation. See bug 17866 */ ++ ip_VLANInit(ethUnit); ++#endif ++ return (liveLinks > 0); ++} ++ ++/****************************************************************************** ++* ++* ip_phyIsDuplexFull - Determines whether the phy ports associated with the ++* specified device are FULL or HALF duplex. ++* ++* RETURNS: ++* 1 --> FULL ++* 0 --> HALF ++*/ ++int ++ip_phyIsFullDuplex(int ethUnit) ++{ ++ int phyUnit; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ UINT16 phyHwStatus; ++ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ if (ip_phyIsLinkAlive(phyUnit)) { ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_LINK_PARTNER_ABILITY); ++ printk("ipPhy.c: phyHwStatus 0x%x\n",phyHwStatus); ++ if ((phyHwStatus & IP_LINK_100BASETX_FULL_DUPLEX) || ++ (phyHwStatus & IP_LINK_10BASETX_FULL_DUPLEX)) { ++ return TRUE; ++ } ++ } ++ return -1; ++ } ++ ++ return FALSE; ++ ++} ++ ++ ++/****************************************************************************** ++* ++* ip_phyIsSpeed100 - Determines the speed of phy ports associated with the ++* specified device. ++* ++* RETURNS: ++* TRUE --> 100Mbit ++* FALSE --> 10Mbit ++*/ ++ ++BOOL ++ip_phyIsSpeed100(int ethUnit) ++{ ++ int phyUnit; ++ UINT16 phyHwStatus; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ if (ip_phyIsLinkAlive(phyUnit)) { ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_LINK_PARTNER_ABILITY); ++ ++ if (phyHwStatus & IP_LINK_100BASETX) { ++ return TRUE; ++ } ++ } ++ } ++ ++ return FALSE; ++} ++ ++/***************************************************************************** ++* ++* ip_phyCheckStatusChange -- checks for significant changes in PHY state. ++* ++* A "significant change" is: ++* dropped link (e.g. ethernet cable unplugged) OR ++* autonegotiation completed + link (e.g. ethernet cable plugged in) ++* ++* When a PHY is plugged in, phyLinkGained is called. ++* When a PHY is unplugged, phyLinkLost is called. ++*/ ++ ++void ++ip_phyCheckStatusChange(int ethUnit) ++{ ++ ++ int phyUnit; ++ UINT16 phyHwStatus; ++ ipPhyInfo_t *lastStatus; ++ int linkCount = 0; ++ int lostLinks = 0; ++ int gainedLinks = 0; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { ++ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ lastStatus = &ipPhyInfo[phyUnit]; ++ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS); ++ ++ if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */ ++ /* See if we've lost link */ ++ if (phyHwStatus & IP_STATUS_LINK_PASS) { ++ linkCount++; ++ } else { ++ lostLinks++; ++#ifdef COBRA_TODO ++ mv_flushATUDB(phyUnit); ++#endif ++ DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n", ++ ethUnit, phyUnit)); ++ lastStatus->isPhyAlive = FALSE; ++ } ++ } else { /* last known link status was DEAD */ ++ /* Check for AutoNegotiation complete */ ++ if (IP_AUTONEG_DONE(phyHwStatus)) { ++ gainedLinks++; ++ linkCount++; ++ DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n", ++ ethUnit, phyUnit)); ++ lastStatus->isPhyAlive = TRUE; ++ } ++ } ++ } ++ ++ if (linkCount == 0) { ++ if (lostLinks) { ++ /* We just lost the last link for this MAC */ ++ phyLinkLost(ethUnit); ++ } ++ } else { ++ if (gainedLinks == linkCount) { ++ /* We just gained our first link(s) for this MAC */ ++ phyLinkGained(ethUnit); ++ } ++ } ++ ++} ++ ++#if DEBUG ++ ++/* Define the registers of interest for a phyShow command */ ++typedef struct ipRegisterTableEntry_s { ++ UINT32 regNum; ++ char *regIdString; ++} ipRegisterTableEntry_t; ++ ++ipRegisterTableEntry_t ipPhyRegisterTable[] = { ++ {IP_PHY_CONTROL, "PHY Control "}, ++ {IP_PHY_STATUS, "PHY Status "}, ++ {IP_PHY_ID1, "PHY Identifier 1 "}, ++ {IP_PHY_ID2, "PHY Identifier 2 "}, ++ {IP_AUTONEG_ADVERT, "Auto-Negotiation Advertisement "}, ++ {IP_LINK_PARTNER_ABILITY, "Link Partner Ability "}, ++ {IP_AUTONEG_EXPANSION, "Auto-Negotiation Expansion "}, ++}; ++int ipPhyNumRegs = sizeof(ipPhyRegisterTable) / sizeof(ipPhyRegisterTable[0]); ++ ++ ++ipRegisterTableEntry_t ipPhy29GlobalRegisterTable[] = { ++ {IP_GLOBAL_PHY29_18_REG, "29_18_REG "}, ++ {IP_GLOBAL_PHY29_19_REG, "29_19_REG "}, ++ {IP_GLOBAL_PHY29_20_REG, "29_20_REG "}, ++ {IP_GLOBAL_PHY29_21_REG, "29_21_REG "}, ++ {IP_GLOBAL_PHY29_22_REG, "29_22_REG "}, ++ {IP_GLOBAL_PHY29_23_REG, "29_23_REG "}, ++ {IP_GLOBAL_PHY29_24_REG, "29_24_REG "}, ++ {IP_GLOBAL_PHY29_25_REG, "29_25_REG "}, ++ {IP_GLOBAL_PHY29_26_REG, "29_26_REG "}, ++ {IP_GLOBAL_PHY29_27_REG, "29_27_REG "}, ++ {IP_GLOBAL_PHY29_28_REG, "29_28_REG "}, ++ {IP_GLOBAL_PHY29_29_REG, "29_29_REG "}, ++ {IP_GLOBAL_PHY29_30_REG, "29_30_REG "}, ++ {IP_GLOBAL_PHY29_31_REG, "29_31_REG "}, ++}; ++int ipPhy29GlobalNumRegs = ++ sizeof(ipPhy29GlobalRegisterTable) / sizeof(ipPhy29GlobalRegisterTable[0]); ++ ++ ++ipRegisterTableEntry_t ipPhy30GlobalRegisterTable[] = { ++ {IP_GLOBAL_PHY30_0_REG, "30_0_REG "}, ++ {IP_GLOBAL_PHY30_1_REG, "30_1_REG "}, ++ {IP_GLOBAL_PHY30_2_REG, "30_2_REG "}, ++ {IP_GLOBAL_PHY30_3_REG, "30_3_REG "}, ++ {IP_GLOBAL_PHY30_4_REG, "30_4_REG "}, ++ {IP_GLOBAL_PHY30_5_REG, "30_5_REG "}, ++ {IP_GLOBAL_PHY30_6_REG, "30_6_REG "}, ++ {IP_GLOBAL_PHY30_7_REG, "30_7_REG "}, ++ {IP_GLOBAL_PHY30_8_REG, "30_8_REG "}, ++ {IP_GLOBAL_PHY30_9_REG, "30_9_REG "}, ++ {IP_GLOBAL_PHY30_10_REG, "30_10_REG "}, ++ {IP_GLOBAL_PHY30_11_REG, "30_11_REG "}, ++ {IP_GLOBAL_PHY30_12_REG, "30_12_REG "}, ++ {IP_GLOBAL_PHY30_13_REG, "30_13_REG "}, ++ {IP_GLOBAL_PHY30_16_REG, "30_16_REG "}, ++ {IP_GLOBAL_PHY30_17_REG, "30_17_REG "}, ++ {IP_GLOBAL_PHY30_18_REG, "30_18_REG "}, ++ {IP_GLOBAL_PHY30_20_REG, "30_20_REG "}, ++ {IP_GLOBAL_PHY30_21_REG, "30_21_REG "}, ++ {IP_GLOBAL_PHY30_22_REG, "30_22_REG "}, ++ {IP_GLOBAL_PHY30_23_REG, "30_23_REG "}, ++ {IP_GLOBAL_PHY30_24_REG, "30_24_REG "}, ++ {IP_GLOBAL_PHY30_25_REG, "30_25_REG "}, ++ {IP_GLOBAL_PHY30_26_REG, "30_26_REG "}, ++ {IP_GLOBAL_PHY30_27_REG, "30_27_REG "}, ++ {IP_GLOBAL_PHY30_28_REG, "30_28_REG "}, ++ {IP_GLOBAL_PHY30_29_REG, "30_29_REG "}, ++ {IP_GLOBAL_PHY30_30_REG, "30_30_REG "}, ++ {IP_GLOBAL_PHY30_31_REG, "30_31_REG "}, ++}; ++int ipPhy30GlobalNumRegs = ++ sizeof(ipPhy30GlobalRegisterTable) / sizeof(ipPhy30GlobalRegisterTable[0]); ++ ++ipRegisterTableEntry_t ipPhy31GlobalRegisterTable[] = { ++ {IP_GLOBAL_PHY31_0_REG, "31_0_REG "}, ++ {IP_GLOBAL_PHY31_1_REG, "31_1_REG "}, ++ {IP_GLOBAL_PHY31_2_REG, "31_2_REG "}, ++ {IP_GLOBAL_PHY31_3_REG, "31_3_REG "}, ++ {IP_GLOBAL_PHY31_4_REG, "31_4_REG "}, ++ {IP_GLOBAL_PHY31_5_REG, "31_5_REG "}, ++ {IP_GLOBAL_PHY31_6_REG, "31_6_REG "}, ++}; ++ ++int ipPhy31GlobalNumRegs = ++ sizeof(ipPhy31GlobalRegisterTable) / sizeof(ipPhy31GlobalRegisterTable[0]); ++ ++ ++/***************************************************************************** ++* ++* ip_phyShow - Dump the state of a PHY. ++* There are two sets of registers for each phy port: ++* "phy registers" and ++* "switch port registers" ++* We dump 'em all, plus the switch global registers. ++*/ ++void ++ip_phyShow(int phyUnit) ++{ ++ int i; ++ UINT16 value; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ if (!ip_validPhyId(phyUnit)) { ++ return; ++ } ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ printf("PHY state for PHY%d (enet%d, phyBase 0x%8x, phyAddr 0x%x)\n", ++ phyUnit, ++ IP_ETHUNIT(phyUnit), ++ IP_PHYBASE(phyUnit), ++ IP_PHYADDR(phyUnit)); ++ ++ printf("PHY Registers:\n"); ++ for (i=0; i < ipPhyNumRegs; i++) { ++ ++ value = phyRegRead(phyBase, phyAddr, ipPhyRegisterTable[i].regNum); ++ ++ printf("Reg %02d (0x%02x) %s = 0x%08x\n", ++ ipPhyRegisterTable[i].regNum, ++ ipPhyRegisterTable[i].regNum, ++ ipPhyRegisterTable[i].regIdString, ++ value); ++ } ++ ++ phyBase = IP_GLOBALREGBASE; ++ ++ printf("Switch Global Registers:\n"); ++ printf("Phy29 Registers:\n"); ++ for (i=0; i < ipPhy29GlobalNumRegs; i++) { ++ ++ value = phyRegRead(phyBase, IP_GLOBAL_PHY29_ADDR, ++ ipPhy29GlobalRegisterTable[i].regNum); ++ ++ printf("Reg %02d (0x%02x) %s = 0x%08x\n", ++ ipPhy29GlobalRegisterTable[i].regNum, ++ ipPhy29GlobalRegisterTable[i].regNum, ++ ipPhy29GlobalRegisterTable[i].regIdString, ++ value); ++ } ++ ++ printf("Phy30 Registers:\n"); ++ for (i=0; i < ipPhy30GlobalNumRegs; i++) { ++ ++ value = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, ++ ipPhy30GlobalRegisterTable[i].regNum); ++ ++ printf("Reg %02d (0x%02x) %s = 0x%08x\n", ++ ipPhy30GlobalRegisterTable[i].regNum, ++ ipPhy30GlobalRegisterTable[i].regNum, ++ ipPhy30GlobalRegisterTable[i].regIdString, ++ value); ++ } ++ printf("Phy31 Registers:\n"); ++ for (i=0; i < ipPhy31GlobalNumRegs; i++) { ++ ++ value = phyRegRead(phyBase, IP_GLOBAL_PHY31_ADDR, ++ ipPhy31GlobalRegisterTable[i].regNum); ++ ++ printf("Reg %02d (0x%02x) %s = 0x%08x\n", ++ ipPhy31GlobalRegisterTable[i].regNum, ++ ipPhy31GlobalRegisterTable[i].regNum, ++ ipPhy31GlobalRegisterTable[i].regIdString, ++ value); ++ } ++} ++ ++/***************************************************************************** ++* ++* ip_phySet - Modify the value of a PHY register (debug only). ++*/ ++void ++ip_phySet(int phyUnit, UINT32 regnum, UINT32 value) ++{ ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ if (ip_validPhyId(phyUnit)) { ++ ++ phyBase = IP_PHYBASE(phyUnit); ++ phyAddr = IP_PHYADDR(phyUnit); ++ ++ phyRegWrite(phyBase, phyAddr, regnum, value); ++ } ++} ++ ++/***************************************************************************** ++* ++* ip_globalSet - Modify the value of a global register ++* (debug only). ++*/ ++void ++ip_globalSet(UINT32 phyAddr, UINT32 regnum, UINT32 value) ++{ ++ UINT32 phyBase; ++ ++ phyBase = IP_GLOBALREGBASE; ++ ++ phyRegWrite(phyBase, phyAddr, regnum, value); ++} ++ ++ ++#endif +diff -urN linux-mips-orig/drivers/net/ath/ipPhy.h linux-mips-new/drivers/net/ath/ipPhy.h +--- linux-mips-orig/drivers/net/ath/ipPhy.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/ipPhy.h 2005-12-31 12:33:57.678538064 +0000 +@@ -0,0 +1,172 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * icPhy.h - definitions for the ethernet PHY. ++ * This code supports a simple 1-port ethernet phy, ICPLUS, ++ * All definitions in this file are operating system independent! ++ */ ++ ++#ifndef IPPHY_H ++#define IPPHY_H ++ ++/*****************/ ++/* PHY Registers */ ++/*****************/ ++#define IP_PHY_CONTROL 0 ++#define IP_PHY_STATUS 1 ++#define IP_PHY_ID1 2 ++#define IP_PHY_ID2 3 ++#define IP_AUTONEG_ADVERT 4 ++#define IP_LINK_PARTNER_ABILITY 5 ++#define IP_AUTONEG_EXPANSION 6 ++ ++ ++/* IP_PHY_CONTROL fields */ ++#define IP_CTRL_SOFTWARE_RESET 0x8000 ++#define IP_CTRL_SPEED_100 0x2000 ++#define IP_CTRL_AUTONEGOTIATION_ENABLE 0x1000 ++#define IP_CTRL_START_AUTONEGOTIATION 0x0200 ++#define IP_CTRL_SPEED_FULL_DUPLEX 0x0100 ++ ++/* Phy status fields */ ++#define IP_STATUS_AUTO_NEG_DONE 0x0020 ++#define IP_STATUS_LINK_PASS 0x0004 ++ ++#define IP_AUTONEG_DONE(ip_phy_status) \ ++ (((ip_phy_status) & \ ++ (IP_STATUS_AUTO_NEG_DONE)) == \ ++ (IP_STATUS_AUTO_NEG_DONE)) ++ ++/* ICPLUS_PHY_ID1 fields */ ++#define IP_PHY_ID1_EXPECTATION 0x0243 /* OUI >> 6 */ ++ ++/* ICPLUS_PHY_ID2 fields */ ++#define IP_OUI_LSB_MASK 0xfc00 ++#define IP_OUI_LSB_EXPECTATION 0x0c00 ++#define IP_OUI_LSB_SHIFT 10 ++#define IP_MODEL_NUM_MASK 0x03f0 ++#define IP_MODEL_NUM_SHIFT 4 ++#define IP_REV_NUM_MASK 0x000f ++#define IP_REV_NUM_SHIFT 0 ++ ++/* Link Partner ability */ ++#define IP_LINK_100BASETX_FULL_DUPLEX 0x0100 ++#define IP_LINK_100BASETX 0x0080 ++#define IP_LINK_10BASETX_FULL_DUPLEX 0x0040 ++#define IP_LINK_10BASETX 0x0020 ++ ++/* Advertisement register. */ ++#define IP_ADVERTISE_100FULL 0x0100 ++#define IP_ADVERTISE_100HALF 0x0080 ++#define IP_ADVERTISE_10FULL 0x0040 ++#define IP_ADVERTISE_10HALF 0x0020 ++ ++#define IP_ADVERTISE_ALL (IP_ADVERTISE_10HALF | IP_ADVERTISE_10FULL | \ ++ IP_ADVERTISE_100HALF | IP_ADVERTISE_100FULL) ++ ++ ++#define IP_VLAN_TAG_VALID 0x81 ++#define IP_VLAN_TAG_SIZE 4 ++#define IP_VLAN_TAG_OFFSET 12 /* After DA & SA */ ++#define IP_SPECIAL_TAG_VALID 0x81 ++ ++/****************************/ ++/* Global Control Registers */ ++/****************************/ ++/* IP Global register doesn't have names based on functionality ++ * hence has to live with this names for now */ ++#define IP_GLOBAL_PHY29_18_REG 18 ++#define IP_GLOBAL_PHY29_19_REG 19 ++#define IP_GLOBAL_PHY29_20_REG 20 ++#define IP_GLOBAL_PHY29_21_REG 21 ++#define IP_GLOBAL_PHY29_22_REG 22 ++#define IP_GLOBAL_PHY29_23_REG 23 ++#define IP_GLOBAL_PHY29_24_REG 24 ++#define IP_GLOBAL_PHY29_25_REG 25 ++#define IP_GLOBAL_PHY29_26_REG 26 ++#define IP_GLOBAL_PHY29_27_REG 27 ++#define IP_GLOBAL_PHY29_28_REG 28 ++#define IP_GLOBAL_PHY29_29_REG 29 ++#define IP_GLOBAL_PHY29_30_REG 30 ++#define IP_GLOBAL_PHY29_31_REG 31 ++ ++ ++#define IP_GLOBAL_PHY30_0_REG 0 ++#define IP_GLOBAL_PHY30_1_REG 1 ++#define IP_GLOBAL_PHY30_2_REG 2 ++#define IP_GLOBAL_PHY30_3_REG 3 ++#define IP_GLOBAL_PHY30_4_REG 4 ++#define IP_GLOBAL_PHY30_5_REG 5 ++#define IP_GLOBAL_PHY30_6_REG 6 ++#define IP_GLOBAL_PHY30_7_REG 7 ++#define IP_GLOBAL_PHY30_8_REG 8 ++#define IP_GLOBAL_PHY30_9_REG 9 ++#define IP_GLOBAL_PHY30_10_REG 10 ++#define IP_GLOBAL_PHY30_11_REG 11 ++#define IP_GLOBAL_PHY30_12_REG 12 ++#define IP_GLOBAL_PHY30_13_REG 13 ++#define IP_GLOBAL_PHY30_16_REG 16 ++#define IP_GLOBAL_PHY30_17_REG 17 ++#define IP_GLOBAL_PHY30_18_REG 18 ++#define IP_GLOBAL_PHY30_20_REG 20 ++#define IP_GLOBAL_PHY30_21_REG 21 ++#define IP_GLOBAL_PHY30_22_REG 22 ++#define IP_GLOBAL_PHY30_23_REG 23 ++#define IP_GLOBAL_PHY30_24_REG 24 ++#define IP_GLOBAL_PHY30_25_REG 25 ++#define IP_GLOBAL_PHY30_26_REG 26 ++#define IP_GLOBAL_PHY30_27_REG 27 ++#define IP_GLOBAL_PHY30_28_REG 28 ++#define IP_GLOBAL_PHY30_29_REG 29 ++#define IP_GLOBAL_PHY30_30_REG 30 ++#define IP_GLOBAL_PHY30_31_REG 31 ++ ++#define IP_GLOBAL_PHY31_0_REG 0 ++#define IP_GLOBAL_PHY31_1_REG 1 ++#define IP_GLOBAL_PHY31_2_REG 2 ++#define IP_GLOBAL_PHY31_3_REG 3 ++#define IP_GLOBAL_PHY31_4_REG 4 ++#define IP_GLOBAL_PHY31_5_REG 5 ++#define IP_GLOBAL_PHY31_6_REG 6 ++ ++#define IP_GLOBAL_PHY29_31_REG 31 ++ ++ ++#define IP_VLAN0_OUTPUT_PORT_MASK_S 0 ++#define IP_VLAN1_OUTPUT_PORT_MASK_S 8 ++#define IP_VLAN2_OUTPUT_PORT_MASK_S 0 ++#define IP_VLAN3_OUTPUT_PORT_MASK_S 8 ++ ++/* Masks and shifts for 29.23 register */ ++#define IP_PORTX_ADD_TAG_S 11 ++#define IP_PORTX_REMOVE_TAG_S 6 ++#define IP_PORT5_ADD_TAG_S 1 ++#define IP_PORT5_REMOVE_TAG_S 0 ++ ++/* ++ * 30.9 Definitions ++ */ ++#define TAG_VLAN_ENABLE 0x0080 ++#define VID_INDX_SEL_M 0x0070 ++#define VID_INDX_SEL_S 4 ++ ++ ++/* PHY Addresses */ ++#define IP_PHY0_ADDR 0 ++#define IP_PHY1_ADDR 1 ++#define IP_PHY2_ADDR 2 ++#define IP_PHY3_ADDR 3 ++#define IP_PHY4_ADDR 4 ++ ++#define IP_GLOBAL_PHY29_ADDR 29 ++#define IP_GLOBAL_PHY30_ADDR 30 ++#define IP_GLOBAL_PHY31_ADDR 31 ++ ++ ++#endif +diff -urN linux-mips-orig/drivers/net/ath/kendSwitchPhy.c linux-mips-new/drivers/net/ath/kendSwitchPhy.c +--- linux-mips-orig/drivers/net/ath/kendSwitchPhy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/kendSwitchPhy.c 2005-12-31 12:33:57.678538064 +0000 +@@ -0,0 +1,286 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Manage the ethernet PHY. ++ * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL, ++ * and compatible PHYs, such as the Kendin KS8721B. ++ * All definitions in this file are operating system independent! ++ */ ++ ++#if defined(linux) ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++#endif ++ ++#if defined(__ECOS) ++#include "ae531xecos.h" ++#endif ++ ++ ++#include "ae531xmac.h" ++#include "ae531xreg.h" ++#include "rtPhy.h" ++ ++#define RT_MAX_PORTS 5 /* max addressable ports per MIIM */ ++ ++#if /* DEBUG */ 1 ++#define RT_DEBUG_ERROR 0x00000001 ++#define RT_DEBUG_PHYSETUP 0x00000002 ++#define RT_DEBUG_PHYCHANGE 0x00000004 ++ ++/* XXX: must hardcode this since same MIIM for all ethUnits */ ++const UINT32 phyBase = 0xb8100000; ++ ++int rtPhyDebug = RT_DEBUG_ERROR; ++ ++#define RT_PRINT(FLG, X) \ ++{ \ ++ if (rtPhyDebug & (FLG)) { \ ++ DEBUG_PRINTF X; \ ++ } \ ++} ++#else ++#define RT_PRINT(FLG, X) ++#endif ++ ++/* ++ * Track per-PHY state. ++ */ ++static BOOL rtPhyAlive[RT_MAX_PORTS]; ++ ++ ++/****************************************************************************** ++* ++* rt_phySetup - reset and setup the PHY associated with ++* the specified MAC unit number. ++* ++* Resets the associated PHY port. ++* ++* RETURNS: ++* TRUE --> associated PHY is alive ++* FALSE --> no LINKs on this ethernet unit ++*/ ++ ++BOOL ++rt_phySetup(int ethUnit, UINT32 phyBaseIgnored) ++{ ++ BOOL linkAlive = FALSE; ++ ++ /* Reset phy */ ++ if (ethUnit == 0) { ++ int i; ++ for (i=1; i<5; i++) { ++ phyRegWrite(phyBase, i, GEN_ctl, AUTONEGENA); ++ sysMsDelay(200); ++ if (phyRegRead(phyBase, i, GEN_sts) & (AUTOCMPLT | LINK)) { ++ rtPhyAlive[i] = TRUE; ++ } ++ else { ++ rtPhyAlive[i] = FALSE; ++ } ++ } ++ } ++ else { ++ phyRegWrite(phyBase, 5, GEN_ctl, AUTONEGENA); ++ sysMsDelay(200); ++ if (phyRegRead(phyBase, 5, GEN_sts) & (AUTOCMPLT | LINK)) { ++ rtPhyAlive[5] = TRUE; ++ } ++ else { ++ rtPhyAlive[5] = FALSE; ++ } ++ } ++ ++ return linkAlive; ++} ++ ++/****************************************************************************** ++* ++* rt_phyIsDuplexFull - Determines whether the phy ports associated with the ++* specified device are FULL or HALF duplex. ++* ++* RETURNS: ++* 1 --> FULL ++* 0 --> HALF ++*/ ++int ++rt_phyIsFullDuplex(int ethUnit) ++{ ++ UINT16 phyLpa = 0; ++ ++ if (ethUnit == 0) { ++ int i; ++ /* 4 ports connected. If any are half-duplex report half. */ ++ for (i=1; i<5; i++) { ++ phyLpa = phyRegRead(phyBase, i, AN_lpa); ++ if ( (!(phyLpa & (LPA_TXFD | LPA_10FD))) && ++ (phyLpa & (LPA_TX | LPA_10)) ) { ++ return 0; ++ } ++ } ++ return 1; ++ } ++ else { ++ phyLpa = phyRegRead(phyBase, 5, AN_lpa); ++ if (phyLpa & (LPA_TXFD | LPA_10FD) ) { ++ return 1; ++ } ++ else { ++ return 0; ++ } ++ } ++} ++ ++/****************************************************************************** ++* ++* rt_phyIsSpeed100 - Determines the speed of phy ports associated with the ++* specified device. ++* ++* RETURNS: ++* TRUE --> 100Mbit ++* FALSE --> 10Mbit ++*/ ++BOOL ++rt_phyIsSpeed100(int ethUnit) ++{ ++ UINT16 phyLpa; ++ ++ if (ethUnit == 0) { ++ int i; ++ /* 4 ports connected. If any are not 100 report 10. */ ++ for (i=1; i<5; i++) { ++ phyLpa = phyRegRead(phyBase, i, AN_lpa); ++ if ( (!(phyLpa & (LPA_TXFD | LPA_TX))) && ++ (phyLpa & (LPA_10FD | LPA_10)) ) { ++ printk("10\n"); ++ return FALSE; ++ } ++ } ++ printk("100\n"); ++ return TRUE; ++ } ++ else { ++ phyLpa = phyRegRead(phyBase, 5, AN_lpa); ++ if (phyLpa & (LPA_TXFD | LPA_TX) ) { ++ printk("100\n"); ++ return TRUE; ++ } ++ else { ++ printk("10\n"); ++ return FALSE; ++ } ++ } ++} ++ ++/***************************************************************************** ++* ++* rt_phyCheckStatusChange -- checks for significant changes in PHY state. ++* ++* A "significant change" is: ++* dropped link (e.g. ethernet cable unplugged) OR ++* autonegotiation completed + link (e.g. ethernet cable plugged in) ++* ++* When a PHY is plugged in, phyLinkGained is called. ++* When a PHY is unplugged, phyLinkLost is called. ++*/ ++void ++rt_phyCheckStatusChange(int ethUnit) ++{ ++ UINT16 phyHwStatus; ++ int i, loopLower, loopUpper; ++ ++ if (ethUnit == 0) { ++ loopLower = 1; ++ loopUpper = 4; ++ } ++ else { ++ loopLower = 5; ++ loopUpper = 5; ++ } ++ ++ for (i=loopLower; i<=loopUpper; i++) { ++ phyHwStatus = phyRegRead(phyBase, i, GEN_sts); ++ ++ if (rtPhyAlive[i]) { /* last known status was ALIVE */ ++ /* See if we've lost link */ ++ if (!(phyHwStatus & LINK)) { ++ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link down\n", ethUnit)); ++ rtPhyAlive[i] = FALSE; ++ phyLinkLost(ethUnit); ++ } ++ } else { /* last known status was DEAD */ ++ /* Check for AN complete */ ++ if ((phyHwStatus & (AUTOCMPLT | LINK)) == (AUTOCMPLT | LINK)) { ++ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link up\n", ethUnit)); ++ rtPhyAlive[i] = TRUE; ++ phyLinkGained(ethUnit); ++ } ++ } ++ } ++} ++ ++#if DEBUG ++ ++/* Define the PHY registers of interest for a phyShow command */ ++struct rtRegisterTable_s { ++ UINT32 regNum; ++ char *regIdString; ++} rtRegisterTable[] = ++{ ++ {GEN_ctl, "Basic Mode Control (GEN_ctl) "}, ++ {GEN_sts, "Basic Mode Status (GEN_sts) "}, ++ {GEN_id_hi, "PHY Identifier 1 (GET_id_hi) "}, ++ {GEN_id_lo, "PHY Identifier 2 (GET_id_lo) "}, ++ {AN_adv, "Auto-Neg Advertisement (AN_adv) "}, ++ {AN_lpa, "Auto-Neg Link Partner Ability "}, ++ {AN_exp, "Auto-Neg Expansion "}, ++}; ++ ++int rtNumRegs = sizeof(rtRegisterTable) / sizeof(rtRegisterTable[0]); ++ ++/* ++ * Dump the state of a PHY. ++ */ ++void ++rt_phyShow(int phyUnit) ++{ ++ int i; ++ UINT16 value; ++ int j, loopLower, loopUpper; ++ ++ printf("PHY state for ethphy%d\n", phyUnit); ++ ++ if (phyUnit == 0) { ++ loopLower = 1; ++ loopUpper = 4; ++ } ++ else { ++ loopLower = 5; ++ loopUpper = 5; ++ } ++ ++ for (j=loopLower; j<=loopUpper; j++) { ++ printk("PHY port %d:\n", j); ++ for (i=0; i link is alive ++* FALSE --> link is down ++*/ ++BOOL ++mv_phyIsLinkAlive(int phyUnit) ++{ ++ UINT16 phyHwStatus; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); ++ ++ if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) { ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/****************************************************************************** ++* ++* mv_VLANInit - initialize "port-based VLANs" for the specified enet unit. ++*/ ++LOCAL void ++mv_VLANInit(int ethUnit) ++{ ++ int phyUnit; ++ UINT32 phyBase; ++ UINT32 switchPortAddr; ++ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (MV_ETHUNIT(phyUnit) != ethUnit) { ++ continue; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); ++ ++ phyRegWrite(phyBase, switchPortAddr, MV_PORT_BASED_VLAN_MAP, ++ MV_VLAN_TABLE_SETTING(phyUnit)); ++ } ++} ++ ++#define phyPortConfigured(phyUnit) TRUE /* TBDFREEDOM2 */ ++ ++/****************************************************************************** ++* ++* mv_enableConfiguredPorts - enable whichever PHY ports are supposed ++* to be enabled according to administrative configuration. ++*/ ++LOCAL void ++mv_enableConfiguredPorts(int ethUnit) ++{ ++ int phyUnit; ++ UINT32 phyBase; ++ UINT32 switchPortAddr; ++ UINT16 portControl; ++ UINT16 portAssociationVector; ++ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (MV_ETHUNIT(phyUnit) != ethUnit) { ++ continue; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); ++ ++ if (phyPortConfigured(phyUnit)) { ++ ++ portControl = MV_PORT_CONTROL_PORT_STATE_FORWARDING; ++#if CONFIG_VENETDEV ++ if (!MV_IS_ENET_PORT(phyUnit)) { /* CPU port */ ++ portControl |= MV_PORT_CONTROL_INGRESS_TRAILER ++ | MV_PORT_CONTROL_EGRESS_MODE; ++ } ++#endif ++ phyRegWrite(phyBase, switchPortAddr, MV_PORT_CONTROL, portControl); ++ ++ portAssociationVector = 1 << phyUnit; ++ ++ phyRegWrite(phyBase, switchPortAddr, ++ MV_PORT_ASSOCIATION_VECTOR, portAssociationVector); ++ } ++ } ++} ++ ++/****************************************************************************** ++* ++* mv_verifyReady - validates that we're dealing with the device ++* we think we're dealing with, and that it's ready. ++*/ ++LOCAL void ++mv_verifyReady(int ethUnit) ++{ ++ int phyUnit; ++ UINT16 globalStatus; ++ UINT32 phyBase = 0; ++ UINT32 phyAddr; ++ UINT32 switchPortAddr; ++ UINT16 phyID1; ++ UINT16 phyID2; ++ UINT16 switchID; ++ ++ /* ++ * The first read to the Phy port registers always fails and ++ * returns 0. So get things started with a bogus read. ++ */ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ (void)phyRegRead(phyBase, phyAddr, MV_PHY_ID1); /* returns 0 */ ++ break; ++ } ++ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ /*******************/ ++ /* Verify phy port */ ++ /*******************/ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ phyID1 = phyRegRead(phyBase, phyAddr, MV_PHY_ID1); ++ if (phyID1 != MV_PHY_ID1_EXPECTATION) { ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("Invalid PHY ID1 for ethmac%d port%d. Expected 0x%04x, read 0x%04x\n", ++ ethUnit, ++ phyUnit, ++ MV_PHY_ID1_EXPECTATION, ++ phyID1)); ++ return; ++ } ++ ++ phyID2 = phyRegRead(phyBase, phyAddr, MV_PHY_ID2); ++ if ((phyID2 & MV_OUI_LSB_MASK) != MV_OUI_LSB_EXPECTATION) { ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("Invalid PHY ID2 for ethmac%d port %d. Expected 0x%04x, read 0x%04x\n", ++ ethUnit, ++ phyUnit, ++ MV_OUI_LSB_EXPECTATION, ++ phyID2)); ++ return; ++ } ++ ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("Found PHY ethmac%d port%d: model 0x%x revision 0x%x\n", ++ ethUnit, ++ phyUnit, ++ (phyID2 & MV_MODEL_NUM_MASK) >> MV_MODEL_NUM_SHIFT, ++ (phyID2 & MV_REV_NUM_MASK) >> MV_REV_NUM_SHIFT)); ++ ++ ++ /**********************/ ++ /* Verify switch port */ ++ /**********************/ ++ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); ++ ++ switchID = phyRegRead(phyBase, switchPortAddr, MV_SWITCH_ID); ++ if ((switchID & MV_SWITCH_ID_DEV_MASK) != ++ MV_SWITCH_ID_DEV_EXPECTATION) { ++ ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("Invalid switch ID for ethmac%d port %d. Expected 0x%04x, read 0x%04x\n", ++ ethUnit, ++ phyUnit, ++ MV_SWITCH_ID_DEV_EXPECTATION, ++ switchID)); ++ return; ++ } ++ ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("Found PHY switch for enet %d port %d deviceID 0x%x revision 0x%x\n", ++ ethUnit, ++ phyUnit, ++ (switchID & MV_SWITCH_ID_DEV_MASK) >> MV_SWITCH_ID_DEV_SHIFT, ++ (switchID & MV_SWITCH_ID_REV_MASK) >> MV_SWITCH_ID_REV_SHIFT)) ++ } ++ ++ /*******************************/ ++ /* Verify that switch is ready */ ++ /*******************************/ ++ if (phyBase) { ++ globalStatus = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_SWITCH_GLOBAL_STATUS); ++ ++ if (!(globalStatus & MV_SWITCH_STATUS_READY_MASK)) { ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("PHY switch for ethmac%d NOT ready!\n", ++ ethUnit)); ++ } ++ } else { ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("No ports configured for ethmac%d\n", ethUnit)); ++ } ++} ++ ++/****************************************************************************** ++* ++* mv_phySetup - reset and setup the PHY switch. ++* ++* Resets each PHY port. ++* ++* RETURNS: ++* TRUE --> at least 1 PHY with LINK ++* FALSE --> no LINKs on this ethernet unit ++*/ ++BOOL ++mv_phySetup(int ethUnit, UINT32 phyBase) ++{ ++ int phyUnit; ++ int liveLinks = 0; ++ BOOL foundPhy = FALSE; ++ UINT32 phyAddr; ++ UINT16 atuControl; ++ ++ /* ++ * Allow platform-specific code to determine the default Ethernet MAC ++ * at run-time. If phyEthMacDefault returns a negative value, use the ++ * static mvPhyInfo table "as is". But if phyEthMacDefault returns a ++ * non-negative value, use it as the default ethernet unit. ++ */ ++ { ++ int ethMacDefault = phyEthMacDefault(); ++ ++ if (ethMacDefault >= 0) { ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ MV_ETHUNIT(phyUnit)=ethMacDefault; ++ } ++ } ++ } ++ ++ /* ++ * See if there's any configuration data for this enet, ++ * and set up phyBase in table. ++ */ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (MV_ETHUNIT(phyUnit) != ethUnit) { ++ continue; ++ } ++ ++ MV_PHYBASE(phyUnit) = phyBase; ++ foundPhy = TRUE; ++ } ++ ++ if (!foundPhy) { ++ return FALSE; /* No PHY's configured for this ethUnit */ ++ } ++ ++ /* Verify that the switch is what we think it is, and that it's ready */ ++ mv_verifyReady(ethUnit); ++ ++ /* Initialize global switch settings */ ++ atuControl = MV_ATUCTRL_AGE_TIME_DEFAULT << MV_ATUCTRL_AGE_TIME_SHIFT; ++ atuControl |= MV_ATUCTRL_ATU_SIZE_DEFAULT << MV_ATUCTRL_ATU_SIZE_SHIFT; ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_CONTROL, atuControl); ++ ++ /* Reset PHYs and start autonegoation on each. */ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (MV_ETHUNIT(phyUnit) != ethUnit) { ++ continue; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ phyRegWrite(phyBase, phyAddr, MV_PHY_CONTROL, ++ MV_CTRL_SOFTWARE_RESET | MV_CTRL_AUTONEGOTIATION_ENABLE); ++ } ++ ++#if 0 /* Don't wait -- we'll detect shortly after the link comes up */ ++{ ++ int timeout; ++ UINT16 phyHwStatus; ++ ++ /* ++ * Wait 5 seconds for ALL associated PHYs to finish autonegotiation. ++ */ ++ timeout=50; ++ for (phyUnit=0; (phyUnit < MV_PHY_MAX) && (timeout > 0); phyUnit++) { ++ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ for (;;) { ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); ++ ++ if (MV_AUTONEG_DONE(phyHwStatus)) { ++ break; ++ } ++ ++ if (--timeout == 0) { ++ break; ++ } ++ ++ sysMsDelay(100); ++ } ++ } ++} ++#endif ++ ++ /* ++ * All PHYs have had adequate time to autonegotiate. ++ * Now initialize software status. ++ * ++ * It's possible that some ports may take a bit longer ++ * to autonegotiate; but we can't wait forever. They'll ++ * get noticed by mv_phyCheckStatusChange during regular ++ * polling activities. ++ */ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ if (mv_phyIsLinkAlive(phyUnit)) { ++ liveLinks++; ++ MV_IS_PHY_ALIVE(phyUnit) = TRUE; ++ } else { ++ MV_IS_PHY_ALIVE(phyUnit) = FALSE; ++ } ++ ++ MV_PRINT(MV_DEBUG_PHYSETUP, ++ ("ethmac%d: Phy Status=%4.4x\n", ++ ethUnit, ++ phyRegRead(MV_PHYBASE(phyUnit), ++ MV_PHYADDR(phyUnit), ++ MV_PHY_SPECIFIC_STATUS))); ++ } ++ ++ mv_VLANInit(ethUnit); ++ ++ mv_enableConfiguredPorts(ethUnit); ++ ++ return (liveLinks > 0); ++} ++ ++ ++/****************************************************************************** ++* ++* mv_phyIsDuplexFull - Determines whether the phy ports associated with the ++* specified device are FULL or HALF duplex. ++* ++* RETURNS: ++* 1 --> at least one associated PHY in FULL DUPLEX ++* 0 --> all half duplex ++* -1 --> No links ++*/ ++int ++mv_phyIsFullDuplex(int ethUnit) ++{ ++ int phyUnit; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ UINT16 phyHwStatus; ++ int oneIsReady=0; ++ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ if (mv_phyIsLinkAlive(phyUnit)) { ++ oneIsReady = 1; ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); ++ ++ if (phyHwStatus & MV_STATUS_RESOLVED_DUPLEX_FULL) { ++ return 1; ++ } ++ } ++ } ++ if (oneIsReady) ++ return 0; ++ else ++ return -1; ++} ++ ++/****************************************************************************** ++* ++* mv_phyIsSpeed100 - Determines the speed of a phy port ++* ++* RETURNS: ++* TRUE --> PHY operating at 100 Mbit ++* FALSE --> link down, or not operating at 100 Mbit ++*/ ++BOOL ++mv_phyIsSpeed100(int phyUnit) ++{ ++ UINT16 phyHwStatus; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ if (MV_IS_ENET_PORT(phyUnit)) { ++ if (mv_phyIsLinkAlive(phyUnit)) { ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); ++ ++ if (phyHwStatus & MV_STATUS_RESOLVED_SPEED_100) { ++ return TRUE; ++ } ++ } ++ } ++ ++ return FALSE; ++} ++ ++#if CONFIG_VENETDEV ++/****************************************************************************** ++* ++* mv_phyDetermineSource - Examine a received frame's Egress Trailer ++* to determine whether it came from a LAN or WAN port. ++* ++* RETURNS: ++* Sets *pFromLAN: 1-->LAN, 0-->WAN ++* Modifies *pLen to remove PHY trailer from frame ++*/ ++void ++mv_phyDetermineSource(char *data, int len, int *pFromLAN) ++{ ++ unsigned char *phyTrailer; ++ unsigned char incomingPort; ++ ++ phyTrailer = &data[len - MV_PHY_TRAILER_SIZE]; ++ ASSERT(phyTrailer[0] == MV_EGRESS_TRAILER_VALID); ++ ++ incomingPort = phyTrailer[1]; ++ if (MV_IS_LAN_PORT(incomingPort)) { ++ *pFromLAN = 1; ++ } else { ++ ASSERT(MV_IS_WAN_PORT(incomingPort)); ++ *pFromLAN = 0; ++ } ++} ++ ++ ++/****************************************************************************** ++* ++* mv_phySetDestinationPort - Set the Ingress Trailer to force the ++* frame to be sent to LAN or WAN, as specified. ++* ++*/ ++void ++mv_phySetDestinationPort(char *data, int len, int fromLAN) ++{ ++ char *phyTrailer; ++ ++ phyTrailer = &data[len]; ++ if (fromLAN) { ++ /* LAN ports: Use default settings, as per mvPhyInfo */ ++ phyTrailer[0] = 0x00; ++ phyTrailer[1] = 0x00; ++ } else { ++ /* WAN port: Direct to WAN port */ ++ phyTrailer[0] = MV_INGRESS_TRAILER_OVERRIDE; ++ phyTrailer[1] = 1 << MV_WAN_PORT; ++ } ++ phyTrailer[2] = 0x00; ++ phyTrailer[3] = 0x00; ++} ++#endif ++ ++ ++/***************************************************************************** ++* ++* Validate that the specified PHY unit number is a valid PHY ID. ++* Print a message if it is invalid. ++* RETURNS ++* TRUE --> valid ++* FALSE --> invalid ++*/ ++LOCAL BOOL ++mv_validPhyId(int phyUnit) ++{ ++ if ((phyUnit >= MV_ID_MIN) && (phyUnit <= MV_ID_MAX)) { ++ return TRUE; ++ } else { ++ PRINTF("PHY unit number must be in the range [%d..%d]\n", ++ MV_ID_MIN, MV_ID_MAX); ++ return FALSE; ++ } ++} ++ ++ ++/***************************************************************************** ++* ++* mv_waitWhileATUBusy - spins until the ATU completes ++* its previous operation. ++*/ ++LOCAL void ++mv_waitWhileATUBusy(UINT32 phyBase) ++{ ++ BOOL isBusy; ++ UINT16 ATUOperation; ++ ++ do { ++ ++ ATUOperation = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_ATU_OPERATION); ++ ++ isBusy = (ATUOperation & MV_ATU_BUSY_MASK) == MV_ATU_IS_BUSY; ++ ++ } while(isBusy); ++} ++ ++/***************************************************************************** ++* ++* mv_flushATUDB - flushes ALL entries in the Address Translation Unit ++* DataBase associated with phyUnit. [Since we use a single DB for ++* all PHYs, this flushes the entire shared DataBase.] ++* ++* The current implementation flushes even more than absolutely needed -- ++* it flushes all entries for all phyUnits on the same ethernet as the ++* specified phyUnit. ++* ++* It is called only when a link failure is detected on a port that was ++* previously working. In other words, when the cable is unplugged. ++*/ ++void ++mv_flushATUDB(int phyUnit) ++{ ++ UINT32 phyBase; ++ ++ if (!mv_validPhyId(phyUnit)) { ++ PRINTF("Invalid port number: %d\n", phyUnit); ++ return; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ ++ /* Wait for previous operation (if any) to complete */ ++ mv_waitWhileATUBusy(phyBase); ++ ++ /* Tell hardware to flush all entries */ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, ++ MV_ATU_OP_FLUSH_ALL | MV_ATU_IS_BUSY); ++ ++ mv_waitWhileATUBusy(phyBase); ++} ++ ++/***************************************************************************** ++* ++* mv_phyCheckStatusChange -- checks for significant changes in PHY state. ++* ++* A "significant change" is: ++* dropped link (e.g. ethernet cable unplugged) OR ++* autonegotiation completed + link (e.g. ethernet cable plugged in) ++*/ ++void ++mv_phyCheckStatusChange(int ethUnit) ++{ ++ int phyUnit; ++ UINT16 phyHwStatus; ++ mvPhyInfo_t *lastStatus; ++ int linkCount = 0; ++ int lostLinks = 0; ++ int gainedLinks = 0; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { ++ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ lastStatus = &mvPhyInfo[phyUnit]; ++ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); ++ ++ if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */ ++ /* See if we've lost link */ ++ if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) { ++ linkCount++; ++ } else { ++ lostLinks++; ++ mv_flushATUDB(phyUnit); ++ MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d down\n", ++ ethUnit, phyUnit)); ++ lastStatus->isPhyAlive = FALSE; ++ } ++ } else { /* last known link status was DEAD */ ++ /* Check for AutoNegotiation complete */ ++ if (MV_AUTONEG_DONE(phyHwStatus)) { ++ gainedLinks++; ++ linkCount++; ++ MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d up\n", ++ ethUnit, phyUnit)); ++ lastStatus->isPhyAlive = TRUE; ++ } ++ } ++ } ++ ++ if (linkCount == 0) { ++ if (lostLinks) { ++ /* We just lost the last link for this MAC */ ++ phyLinkLost(ethUnit); ++ } ++ } else { ++ if (gainedLinks == linkCount) { ++ /* We just gained our first link(s) for this MAC */ ++ phyLinkGained(ethUnit); ++ } ++ } ++} ++ ++#if DEBUG ++ ++/* Define the registers of interest for a phyShow command */ ++typedef struct mvRegisterTableEntry_s { ++ UINT32 regNum; ++ char *regIdString; ++} mvRegisterTableEntry_t; ++ ++mvRegisterTableEntry_t mvPhyRegisterTable[] = { ++ {MV_PHY_CONTROL, "PHY Control "}, ++ {MV_PHY_STATUS, "PHY Status "}, ++ {MV_PHY_ID1, "PHY Identifier 1 "}, ++ {MV_PHY_ID2, "PHY Identifier 2 "}, ++ {MV_AUTONEG_ADVERT, "Auto-Negotiation Advertisement "}, ++ {MV_LINK_PARTNER_ABILITY, "Link Partner Ability "}, ++ {MV_AUTONEG_EXPANSION, "Auto-Negotiation Expansion "}, ++ {MV_NEXT_PAGE_TRANSMIT, "Next Page Transmit "}, ++ {MV_LINK_PARTNER_NEXT_PAGE, "Link Partner Next Page "}, ++ {MV_PHY_SPECIFIC_CONTROL_1, "PHY-Specific Control Register 1 "}, ++ {MV_PHY_SPECIFIC_STATUS, "PHY-Specific Status "}, ++ {MV_PHY_INTERRUPT_ENABLE, "PHY Interrupt Enable "}, ++ {MV_PHY_INTERRUPT_STATUS, "PHY Interrupt Status "}, ++ {MV_PHY_INTERRUPT_PORT_SUMMARY, "PHY Interrupt Port Summary "}, ++ {MV_RECEIVE_ERROR_COUNTER, "Receive Error Counter "}, ++ {MV_LED_PARALLEL_SELECT, "LED Parallel Select "}, ++ {MV_LED_STREAM_SELECT_LEDS, "LED Stream Select "}, ++ {MV_PHY_LED_CONTROL, "PHY LED Control "}, ++ {MV_PHY_MANUAL_LED_OVERRIDE, "PHY Manual LED Override "}, ++ {MV_VCT_CONTROL, "VCT Control "}, ++ {MV_VCT_STATUS, "VCT Status "}, ++ {MV_PHY_SPECIFIC_CONTROL_2, "PHY-Specific Control Register 2 "}, ++}; ++int mvPhyNumRegs = sizeof(mvPhyRegisterTable) / sizeof(mvPhyRegisterTable[0]); ++ ++ ++mvRegisterTableEntry_t mvSwitchPortRegisterTable[] = { ++ {MV_PORT_STATUS, "Port Status "}, ++ {MV_SWITCH_ID, "Switch ID "}, ++ {MV_PORT_CONTROL, "Port Control "}, ++ {MV_PORT_BASED_VLAN_MAP, "Port-Based VLAN Map "}, ++ {MV_PORT_ASSOCIATION_VECTOR, "Port Association Vector "}, ++ {MV_RX_COUNTER, "RX Counter "}, ++ {MV_TX_COUNTER, "TX Counter "}, ++}; ++int mvSwitchPortNumRegs = ++ sizeof(mvSwitchPortRegisterTable) / sizeof(mvSwitchPortRegisterTable[0]); ++ ++ ++mvRegisterTableEntry_t mvSwitchGlobalRegisterTable[] = { ++ {MV_SWITCH_GLOBAL_STATUS, "Switch Global Status "}, ++ {MV_SWITCH_MAC_ADDR0, "Switch MAC Addr 0 & 1 "}, ++ {MV_SWITCH_MAC_ADDR2, "Switch MAC Addr 2 & 3 "}, ++ {MV_SWITCH_MAC_ADDR4, "Switch MAC Addr 4 & 5 "}, ++ {MV_SWITCH_GLOBAL_CONTROL, "Switch Global Control "}, ++ {MV_ATU_CONTROL, "ATU Control "}, ++ {MV_ATU_OPERATION, "ATU Operation "}, ++ {MV_ATU_DATA, "ATU Data "}, ++ {MV_ATU_MAC_ADDR0, "ATU MAC Addr 0 & 1 "}, ++ {MV_ATU_MAC_ADDR2, "ATU MAC Addr 2 & 3 "}, ++ {MV_ATU_MAC_ADDR4, "ATU MAC Addr 4 & 5 "}, ++}; ++int mvSwitchGlobalNumRegs = ++ sizeof(mvSwitchGlobalRegisterTable) / sizeof(mvSwitchGlobalRegisterTable[0]); ++ ++void my_mvPhyShow(int ethUnit) ++{ ++ int phyUnit; ++ for (phyUnit=0; (phyUnit < MV_PHY_MAX); phyUnit++) { ++ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { ++ continue; ++ } ++ mv_phyShow(phyUnit); ++ } ++} ++ ++/***************************************************************************** ++* ++* mv_phyShow - Dump the state of a PHY. ++* There are two sets of registers for each phy port: ++* "phy registers" and ++* "switch port registers" ++* We dump 'em all, plus the switch global registers. ++*/ ++void ++mv_phyShow(int phyUnit) ++{ ++ int i; ++ UINT16 value; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ UINT32 switchPortAddr; ++ ++ if (!mv_validPhyId(phyUnit)) { ++ return; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); ++ ++ printk("PHY state for PHY%d (ethmac%d, phyBase 0x%8x, phyAddr 0x%x, switchAddr 0x%x)\n", ++ phyUnit, ++ MV_ETHUNIT(phyUnit), ++ MV_PHYBASE(phyUnit), ++ MV_PHYADDR(phyUnit), ++ MV_SWITCH_PORT_ADDR(phyUnit)); ++ ++ printk("PHY Registers:\n"); ++ for (i=0; i < mvPhyNumRegs; i++) { ++ ++ value = phyRegRead(phyBase, phyAddr, mvPhyRegisterTable[i].regNum); ++ ++ printk("Reg %02d (0x%02x) %s = 0x%08x\n", ++ mvPhyRegisterTable[i].regNum, ++ mvPhyRegisterTable[i].regNum, ++ mvPhyRegisterTable[i].regIdString, ++ value); ++ } ++ ++ printk("Switch Port Registers:\n"); ++ for (i=0; i < mvSwitchPortNumRegs; i++) { ++ ++ value = phyRegRead(phyBase, switchPortAddr, ++ mvSwitchPortRegisterTable[i].regNum); ++ ++ printk("Reg %02d (0x%02x) %s = 0x%08x\n", ++ mvSwitchPortRegisterTable[i].regNum, ++ mvSwitchPortRegisterTable[i].regNum, ++ mvSwitchPortRegisterTable[i].regIdString, ++ value); ++ } ++ ++ printk("Switch Global Registers:\n"); ++ for (i=0; i < mvSwitchGlobalNumRegs; i++) { ++ ++ value = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ mvSwitchGlobalRegisterTable[i].regNum); ++ ++ printk("Reg %02d (0x%02x) %s = 0x%08x\n", ++ mvSwitchGlobalRegisterTable[i].regNum, ++ mvSwitchGlobalRegisterTable[i].regNum, ++ mvSwitchGlobalRegisterTable[i].regIdString, ++ value); ++ } ++} ++ ++/***************************************************************************** ++* ++* mv_phySet - Modify the value of a PHY register (debug only). ++*/ ++void ++mv_phySet(int phyUnit, UINT32 regnum, UINT32 value) ++{ ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ if (mv_validPhyId(phyUnit)) { ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ phyAddr = MV_PHYADDR(phyUnit); ++ ++ phyRegWrite(phyBase, phyAddr, regnum, value); ++ } ++} ++ ++ ++/***************************************************************************** ++* ++* mv_switchPortSet - Modify the value of a switch port register (debug only). ++*/ ++void ++mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value) ++{ ++ UINT32 phyBase; ++ UINT32 switchPortAddr; ++ ++ if (mv_validPhyId(phyUnit)) { ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); ++ ++ phyRegWrite(phyBase, switchPortAddr, regnum, value); ++ } ++} ++ ++/***************************************************************************** ++* ++* mv_switchGlobalSet - Modify the value of a switch global register ++* (debug only). ++*/ ++void ++mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value) ++{ ++ UINT32 phyBase; ++ ++ if (mv_validPhyId(phyUnit)) { ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, regnum, value); ++ } ++} ++ ++/***************************************************************************** ++* ++* mv_showATUDB - Dump the contents of the Address Translation Unit DataBase ++* for the PHY switch associated with the specified phy. ++*/ ++void ++mv_showATUDB(int phyUnit) ++{ ++ UINT32 phyBase; ++ UINT16 ATUData; ++ UINT16 ATUMac0; ++ UINT16 ATUMac2; ++ UINT16 ATUMac4; ++ int portVec; ++ int entryState; ++ ++ if (!mv_validPhyId(phyUnit)) { ++ printk("Invalid port number: %d\n", phyUnit); ++ return; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ ++ /* Wait for previous operation (if any) to complete */ ++ mv_waitWhileATUBusy(phyBase); ++ ++ /* Initialize ATU MAC to all 1's */ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0, 0xffff); ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2, 0xffff); ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4, 0xffff); ++ ++ printk(" MAC ADDRESS EntryState PortVector\n"); ++ ++ for(;;) { ++ /* Tell hardware to get next MAC info */ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, ++ MV_ATU_OP_GET_NEXT | MV_ATU_IS_BUSY); ++ ++ mv_waitWhileATUBusy(phyBase); ++ ++ ATUData = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_DATA); ++ entryState = (ATUData & MV_ENTRYSTATE_MASK) >> MV_ENTRYSTATE_SHIFT; ++ ++ if (entryState == 0) { ++ /* We've hit the end of the list */ ++ break; ++ } ++ ++ ATUMac0 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0); ++ ATUMac2 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2); ++ ATUMac4 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4); ++ ++ portVec = (ATUData & MV_PORTVEC_MASK) >> MV_PORTVEC_SHIFT; ++ ++ printk("%02x:%02x:%02x:%02x:%02x:%02x 0x%02x 0x%02x\n", ++ ATUMac0 >> 8, /* MAC byte 0 */ ++ ATUMac0 & 0xff, /* MAC byte 1 */ ++ ATUMac2 >> 8, /* MAC byte 2 */ ++ ATUMac2 & 0xff, /* MAC byte 3 */ ++ ATUMac4 >> 8, /* MAC byte 4 */ ++ ATUMac4 & 0xff, /* MAC byte 5 */ ++ entryState, ++ portVec); ++ } ++} ++ ++LOCAL BOOL countingGoodFrames; ++ ++/***************************************************************************** ++* ++* mv_countGoodFrames - starts counting GOOD RX/TX frames per port ++*/ ++void ++mv_countGoodFrames(int phyUnit) ++{ ++ UINT32 phyBase; ++ UINT16 globalControl; ++ ++ if (mv_validPhyId(phyUnit)) { ++ /* ++ * Guarantee that counters are cleared by ++ * forcing CtrMode to toggle and end on GOODFRAMES. ++ */ ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ ++ /* Read current Switch Global Control Register */ ++ globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_SWITCH_GLOBAL_CONTROL); ++ ++ /* Set CtrMode to count BAD frames */ ++ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | ++ MV_CTRMODE_BADFRAMES); ++ ++ /* Push new value out to hardware */ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_SWITCH_GLOBAL_CONTROL, globalControl); ++ ++ /* Now toggle CtrMode to count GOOD frames */ ++ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | ++ MV_CTRMODE_GOODFRAMES); ++ ++ /* Push new value out to hardware */ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_SWITCH_GLOBAL_CONTROL, globalControl); ++ ++ countingGoodFrames = TRUE; ++ } ++} ++ ++/***************************************************************************** ++* ++* mv_countBadFrames - starts counting BAD RX/TX frames per port ++*/ ++void ++mv_countBadFrames(int phyUnit) ++{ ++ UINT32 phyBase; ++ UINT16 globalControl; ++ ++ if (mv_validPhyId(phyUnit)) { ++ /* ++ * Guarantee that counters are cleared by ++ * forcing CtrMode to toggle and end on BADFRAMES. ++ */ ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ ++ /* Read current Switch Global Control Register */ ++ globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_SWITCH_GLOBAL_CONTROL); ++ ++ /* Set CtrMode to count GOOD frames */ ++ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | ++ MV_CTRMODE_GOODFRAMES); ++ ++ /* Push new value out to hardware */ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_SWITCH_GLOBAL_CONTROL, globalControl); ++ ++ /* Now toggle CtrMode to count BAD frames */ ++ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | ++ MV_CTRMODE_BADFRAMES); ++ ++ /* Push new value out to hardware */ ++ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, ++ MV_SWITCH_GLOBAL_CONTROL, globalControl); ++ ++ countingGoodFrames = FALSE; ++ } ++} ++ ++/***************************************************************************** ++* ++* mv_showFrameCounts - shows current GOOD/BAD Frame counts ++*/ ++void ++mv_showFrameCounts(int phyUnit) ++{ ++ UINT16 rxCounter; ++ UINT16 txCounter; ++ UINT32 phyBase; ++ UINT32 switchPortAddr; ++ ++ if (!mv_validPhyId(phyUnit)) { ++ return; ++ } ++ ++ phyBase = MV_PHYBASE(phyUnit); ++ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); ++ ++ rxCounter = phyRegRead(phyBase, switchPortAddr, MV_RX_COUNTER); ++ ++ txCounter = phyRegRead(phyBase, switchPortAddr, MV_TX_COUNTER); ++ ++ printk("port%d %s frames: receive: %05d transmit: %05d\n", ++ phyUnit, ++ (countingGoodFrames ? "good" : "error"), ++ rxCounter, ++ txCounter); ++} ++#endif +diff -urN linux-mips-orig/drivers/net/ath/mvPhy.h linux-mips-new/drivers/net/ath/mvPhy.h +--- linux-mips-orig/drivers/net/ath/mvPhy.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/mvPhy.h 2005-12-31 12:33:57.727530616 +0000 +@@ -0,0 +1,162 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * mvPhy.h - definitions for the ethernet PHY -- Marvell 88E6060 ++ * All definitions in this file are operating system independent! ++ */ ++ ++#ifndef MVPHY_H ++#define MVPHY_H ++ ++/*****************/ ++/* PHY Registers */ ++/*****************/ ++#define MV_PHY_CONTROL 0 ++#define MV_PHY_STATUS 1 ++#define MV_PHY_ID1 2 ++#define MV_PHY_ID2 3 ++#define MV_AUTONEG_ADVERT 4 ++#define MV_LINK_PARTNER_ABILITY 5 ++#define MV_AUTONEG_EXPANSION 6 ++#define MV_NEXT_PAGE_TRANSMIT 7 ++#define MV_LINK_PARTNER_NEXT_PAGE 8 ++#define MV_PHY_SPECIFIC_CONTROL_1 16 ++#define MV_PHY_SPECIFIC_STATUS 17 ++#define MV_PHY_INTERRUPT_ENABLE 18 ++#define MV_PHY_INTERRUPT_STATUS 19 ++#define MV_PHY_INTERRUPT_PORT_SUMMARY 20 ++#define MV_RECEIVE_ERROR_COUNTER 21 ++#define MV_LED_PARALLEL_SELECT 22 ++#define MV_LED_STREAM_SELECT_LEDS 23 ++#define MV_PHY_LED_CONTROL 24 ++#define MV_PHY_MANUAL_LED_OVERRIDE 25 ++ ++#define MV_VCT_CONTROL 26 ++#define MV_VCT_STATUS 27 ++#define MV_PHY_SPECIFIC_CONTROL_2 28 ++ ++/* MV_PHY_CONTROL fields */ ++#define MV_CTRL_SOFTWARE_RESET 0x8000 ++#define MV_CTRL_AUTONEGOTIATION_ENABLE 0x1000 ++#define MV_CTRL_FULL_DUPLEX 0x0100 ++#define MV_CTRL_100_MBPS 0x2000 ++ ++/* MV_PHY_ID1 fields */ ++#define MV_PHY_ID1_EXPECTATION 0x0141 /* OUI >> 6 */ ++ ++/* MV_PHY_ID2 fields */ ++#define MV_OUI_LSB_MASK 0xfc00 ++#define MV_OUI_LSB_EXPECTATION 0x0c00 ++#define MV_OUI_LSB_SHIFT 10 ++#define MV_MODEL_NUM_MASK 0x03f0 ++#define MV_MODEL_NUM_SHIFT 4 ++#define MV_REV_NUM_MASK 0x000f ++#define MV_REV_NUM_SHIFT 0 ++ ++/* MV_PHY_SPECIFIC_STATUS fields */ ++#define MV_STATUS_RESOLVED_SPEED_100 0x4000 ++#define MV_STATUS_RESOLVED_DUPLEX_FULL 0x2000 ++#define MV_STATUS_RESOLVED 0x0800 ++#define MV_STATUS_REAL_TIME_LINK_UP 0x0400 ++ ++/* Check if autonegotiation is complete and link is up */ ++#define MV_AUTONEG_DONE(mv_phy_specific_status) \ ++ (((mv_phy_specific_status) & \ ++ (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP)) == \ ++ (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP)) ++ ++ ++/*************************/ ++/* Switch Port Registers */ ++/*************************/ ++#define MV_PORT_STATUS 0 ++#define MV_SWITCH_ID 3 ++#define MV_PORT_CONTROL 4 ++#define MV_PORT_BASED_VLAN_MAP 6 ++#define MV_PORT_ASSOCIATION_VECTOR 11 ++#define MV_RX_COUNTER 16 ++#define MV_TX_COUNTER 17 ++ ++/* MV_SWITCH_ID fields */ ++#define MV_SWITCH_ID_DEV_MASK 0xfff0 ++#define MV_SWITCH_ID_DEV_EXPECTATION 0x0600 ++#define MV_SWITCH_ID_DEV_SHIFT 4 ++#define MV_SWITCH_ID_REV_MASK 0x000f ++#define MV_SWITCH_ID_REV_SHIFT 0 ++ ++/* MV_PORT_CONTROL fields */ ++#define MV_PORT_CONTROL_PORT_STATE_MASK 0x0003 ++#define MV_PORT_CONTROL_PORT_STATE_DISABLED 0x0000 ++#define MV_PORT_CONTROL_PORT_STATE_FORWARDING 0x0003 ++ ++#define MV_PORT_CONTROL_EGRESS_MODE 0x0100 /* Receive */ ++#define MV_PORT_CONTROL_INGRESS_TRAILER 0x4000 /* Transmit */ ++ ++#define MV_EGRESS_TRAILER_VALID 0x80 ++#define MV_INGRESS_TRAILER_OVERRIDE 0x80 ++ ++#define MV_PHY_TRAILER_SIZE 4 ++ ++ ++/***************************/ ++/* Switch Global Registers */ ++/***************************/ ++#define MV_SWITCH_GLOBAL_STATUS 0 ++#define MV_SWITCH_MAC_ADDR0 1 ++#define MV_SWITCH_MAC_ADDR2 2 ++#define MV_SWITCH_MAC_ADDR4 3 ++#define MV_SWITCH_GLOBAL_CONTROL 4 ++#define MV_ATU_CONTROL 10 ++#define MV_ATU_OPERATION 11 ++#define MV_ATU_DATA 12 ++#define MV_ATU_MAC_ADDR0 13 ++#define MV_ATU_MAC_ADDR2 14 ++#define MV_ATU_MAC_ADDR4 15 ++ ++/* MV_SWITCH_GLOBAL_STATUS fields */ ++#define MV_SWITCH_STATUS_READY_MASK 0x0800 ++ ++/* MV_SWITCH_GLOBAL_CONTROL fields */ ++#define MV_CTRMODE_MASK 0x0100 ++#define MV_CTRMODE_GOODFRAMES 0x0000 ++#define MV_CTRMODE_BADFRAMES 0x0100 ++ ++/* MV_ATU_CONTROL fields */ ++#define MV_ATUCTRL_ATU_SIZE_MASK 0x3000 ++#define MV_ATUCTRL_ATU_SIZE_SHIFT 12 ++#define MV_ATUCTRL_ATU_SIZE_DEFAULT 2 /* 1024 entry database */ ++#define MV_ATUCTRL_AGE_TIME_MASK 0x0ff0 ++#define MV_ATUCTRL_AGE_TIME_SHIFT 4 ++#define MV_ATUCTRL_AGE_TIME_DEFAULT 19 /* 19 * 16 = 304 seconds */ ++ ++/* MV_ATU_OPERATION fields */ ++#define MV_ATU_BUSY_MASK 0x8000 ++#define MV_ATU_IS_BUSY 0x8000 ++#define MV_ATU_IS_FREE 0x0000 ++#define MV_ATU_OP_MASK 0x7000 ++#define MV_ATU_OP_FLUSH_ALL 0x1000 ++#define MV_ATU_OP_GET_NEXT 0x4000 ++ ++/* MV_ATU_DATA fields */ ++#define MV_ENTRYPRI_MASK 0xc000 ++#define MV_ENTRYPRI_SHIFT 14 ++#define MV_PORTVEC_MASK 0x03f0 ++#define MV_PORTVEC_SHIFT 4 ++#define MV_ENTRYSTATE_MASK 0x000f ++#define MV_ENTRYSTATE_SHIFT 0 ++ ++/* PHY Address for the switch itself */ ++#define MV_SWITCH_GLOBAL_ADDR 0x1f ++ ++BOOL mv_phySetup(int ethUnit, UINT32 phyBase); ++void mv_phyCheckStatusChange(int ethUnit); ++BOOL mv_phyIsSpeed100(int ethUnit); ++int mv_phyIsFullDuplex(int ethUnit); ++ ++#endif /* MVPHY_H */ +diff -urN linux-mips-orig/drivers/net/ath/rtPhy.c linux-mips-new/drivers/net/ath/rtPhy.c +--- linux-mips-orig/drivers/net/ath/rtPhy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-mips-new/drivers/net/ath/rtPhy.c 2005-12-31 12:33:57.727530616 +0000 +@@ -0,0 +1,272 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. ++ */ ++ ++/* ++ * Manage the ethernet PHY. ++ * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL, ++ * and compatible PHYs, such as the Kendin KS8721B. ++ * All definitions in this file are operating system independent! ++ */ ++ ++#if defined(linux) ++#include ++#include ++#include ++#include ++#include ++ ++#include "ar531xlnx.h" ++#endif ++ ++#if defined(__ECOS) ++#include "ae531xecos.h" ++#endif ++ ++ ++#include "ae531xmac.h" ++#include "ae531xreg.h" ++#include "rtPhy.h" ++ ++#if /* DEBUG */ 1 ++#define RT_DEBUG_ERROR 0x00000001 ++#define RT_DEBUG_PHYSETUP 0x00000002 ++#define RT_DEBUG_PHYCHANGE 0x00000004 ++ ++int rtPhyDebug = RT_DEBUG_ERROR; ++ ++#define RT_PRINT(FLG, X) \ ++{ \ ++ if (rtPhyDebug & (FLG)) { \ ++ DEBUG_PRINTF X; \ ++ } \ ++} ++#else ++#define RT_PRINT(FLG, X) ++#endif ++ ++/* ++ * Track per-PHY port information. ++ */ ++typedef struct { ++ BOOL phyAlive; /* last known state of link */ ++ UINT32 phyBase; ++ UINT32 phyAddr; ++} rtPhyInfo_t; ++ ++#define ETH_PHY_ADDR 1 ++ ++/* ++ * This table defines the mapping from phy units to ++ * per-PHY information. ++ * ++ * This table is somewhat board-dependent. ++ */ ++rtPhyInfo_t rtPhyInfo[] = { ++ {phyAlive: FALSE, /* PHY 0 */ ++ phyBase: 0, /* filled in by rt_phySetup */ ++ phyAddr: ETH_PHY_ADDR}, ++ ++ {phyAlive: FALSE, /* PHY 1 */ ++ phyBase: 0, /* filled in by rt_phySetup */ ++ phyAddr: ETH_PHY_ADDR} ++}; ++ ++/* Convert from phy unit# to (phyBase, phyAddr) pair */ ++#define RT_PHYBASE(phyUnit) (rtPhyInfo[phyUnit].phyBase) ++#define RT_PHYADDR(phyUnit) (rtPhyInfo[phyUnit].phyAddr) ++ ++ ++/****************************************************************************** ++* ++* rt_phySetup - reset and setup the PHY associated with ++* the specified MAC unit number. ++* ++* Resets the associated PHY port. ++* ++* RETURNS: ++* TRUE --> associated PHY is alive ++* FALSE --> no LINKs on this ethernet unit ++*/ ++ ++BOOL ++rt_phySetup(int ethUnit, UINT32 phyBase) ++{ ++ BOOL linkAlive = FALSE; ++ UINT32 phyAddr; ++ ++ RT_PHYBASE(ethUnit) = phyBase; ++ ++ phyAddr = RT_PHYADDR(ethUnit); ++ ++ /* Reset phy */ ++ phyRegWrite(phyBase, phyAddr, GEN_ctl, PHY_SW_RST | AUTONEGENA); ++ ++ sysMsDelay(1500); ++ ++ return linkAlive; ++} ++ ++/****************************************************************************** ++* ++* rt_phyIsDuplexFull - Determines whether the phy ports associated with the ++* specified device are FULL or HALF duplex. ++* ++* RETURNS: ++* 1 --> FULL ++* 0 --> HALF ++*/ ++int ++rt_phyIsFullDuplex(int ethUnit) ++{ ++ UINT16 phyCtl; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ phyBase = RT_PHYBASE(ethUnit); ++ phyAddr = RT_PHYADDR(ethUnit); ++ ++ phyCtl = phyRegRead(phyBase, phyAddr, GEN_ctl); ++ ++ if (phyCtl & DUPLEX) { ++ return 1; ++ } else { ++ return 0; ++ } ++} ++ ++/****************************************************************************** ++* ++* rt_phyIsSpeed100 - Determines the speed of phy ports associated with the ++* specified device. ++* ++* RETURNS: ++* TRUE --> 100Mbit ++* FALSE --> 10Mbit ++*/ ++BOOL ++rt_phyIsSpeed100(int phyUnit) ++{ ++ UINT16 phyLpa; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ phyBase = RT_PHYBASE(phyUnit); ++ phyAddr = RT_PHYADDR(phyUnit); ++ ++ phyLpa = phyRegRead(phyBase, phyAddr, AN_lpa); ++ ++ if (phyLpa & (LPA_TXFD | LPA_TX)) { ++ return TRUE; ++ } else { ++ return FALSE; ++ } ++} ++ ++/***************************************************************************** ++* ++* rt_phyCheckStatusChange -- checks for significant changes in PHY state. ++* ++* A "significant change" is: ++* dropped link (e.g. ethernet cable unplugged) OR ++* autonegotiation completed + link (e.g. ethernet cable plugged in) ++* ++* On AR5311, there is a 1-to-1 mapping of ethernet units to PHYs. ++* When a PHY is plugged in, phyLinkGained is called. ++* When a PHY is unplugged, phyLinkLost is called. ++*/ ++void ++rt_phyCheckStatusChange(int ethUnit) ++{ ++ UINT16 phyHwStatus; ++ rtPhyInfo_t *lastStatus = &rtPhyInfo[ethUnit]; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ phyBase = RT_PHYBASE(ethUnit); ++ phyAddr = RT_PHYADDR(ethUnit); ++ ++ phyHwStatus = phyRegRead(phyBase, phyAddr, GEN_sts); ++ ++ if (lastStatus->phyAlive) { /* last known status was ALIVE */ ++ /* See if we've lost link */ ++ if (!(phyHwStatus & LINK)) { ++ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link down\n", ethUnit)); ++ lastStatus->phyAlive = FALSE; ++ phyLinkLost(ethUnit); ++ } ++ } else { /* last known status was DEAD */ ++ /* Check for AN complete */ ++ if ((phyHwStatus & (AUTOCMPLT | LINK)) == (AUTOCMPLT | LINK)) { ++ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link up\n", ethUnit)); ++ lastStatus->phyAlive = TRUE; ++ phyLinkGained(ethUnit); ++ } ++ } ++} ++ ++#if DEBUG ++ ++/* Define the PHY registers of interest for a phyShow command */ ++struct rtRegisterTable_s { ++ UINT32 regNum; ++ char *regIdString; ++} rtRegisterTable[] = ++{ ++ {GEN_ctl, "Basic Mode Control (GEN_ctl) "}, ++ {GEN_sts, "Basic Mode Status (GEN_sts) "}, ++ {GEN_id_hi, "PHY Identifier 1 (GET_id_hi) "}, ++ {GEN_id_lo, "PHY Identifier 2 (GET_id_lo) "}, ++ {AN_adv, "Auto-Neg Advertisement (AN_adv) "}, ++ {AN_lpa, "Auto-Neg Link Partner Ability "}, ++ {AN_exp, "Auto-Neg Expansion "}, ++}; ++ ++int rtNumRegs = sizeof(rtRegisterTable) / sizeof(rtRegisterTable[0]); ++ ++/* ++ * Dump the state of a PHY. ++ */ ++void ++rt_phyShow(int phyUnit) ++{ ++ int i; ++ UINT16 value; ++ UINT32 phyBase; ++ UINT32 phyAddr; ++ ++ phyBase = RT_PHYBASE(phyUnit); ++ phyAddr = RT_PHYADDR(phyUnit); ++ ++ printf("PHY state for ethphy%d\n", phyUnit); ++ ++ for (i=0; i ++#include ++ ++#include ++ ++extern int prom_argc; ++extern int *_prom_argv; ++ ++/* ++ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. ++ * This macro take care of sign extension. ++ */ ++#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)])) ++ ++char arcs_cmdline[CL_SIZE]; ++#ifdef CONFIG_CMDLINE_BOOL ++char __initdata cfg_cmdline[] = CONFIG_CMDLINE; ++#endif ++ ++char * __init prom_getcmdline(void) ++{ ++ return &(arcs_cmdline[0]); ++} ++ ++ ++void __init prom_init_cmdline(void) ++{ ++ char *cp, *end; ++ int actr; ++ char *env_cmdline = prom_getenv("kernel_args"); ++ size_t len; ++ ++ actr = 1; /* Always ignore argv[0] */ ++ ++ cp = end = &(arcs_cmdline[0]); ++ end += sizeof(arcs_cmdline); ++ ++ if (env_cmdline) { ++ len = strlen(env_cmdline); ++ if (len > end - cp - 1) ++ len = end - cp - 1; ++ strncpy(cp, env_cmdline, len); ++ cp += len; ++ *cp++ = ' '; ++ } ++#ifdef CONFIG_CMDLINE_BOOL ++ else { ++ len = strlen(cfg_cmdline); ++ if (len > end - cp - 1) ++ len = end - cp - 1; ++ strncpy(cp, cfg_cmdline, len); ++ cp += len; ++ *cp++ = ' '; ++ } ++#endif ++ ++ while(actr < prom_argc) { ++ len = strlen(prom_argv(actr)); ++ if (len > end - cp - 1) ++ break; ++ strncpy(cp, prom_argv(actr), len); ++ cp += len; ++ *cp++ = ' '; ++ actr++; ++ } ++ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ ++ --cp; ++ *cp = '\0'; ++} +diff -urN linux.old/arch/mips/ar7/init.c linux.dev/arch/mips/ar7/init.c +--- linux.old/arch/mips/ar7/init.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/init.c 2005-11-10 01:10:45.795571500 +0100 +@@ -0,0 +1,199 @@ ++/* ++ * Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * PROM library initialisation code. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++int prom_argc; ++int *_prom_argv, *_prom_envp; ++ ++/* max # of Adam2 environment variables */ ++#define MAX_ENV_ENTRY 80 ++ ++static t_env_var local_envp[MAX_ENV_ENTRY]; ++static int env_type = 0; ++int init_debug = 0; ++ ++unsigned int max_env_entry; ++ ++extern char *prom_psp_getenv(char *envname); ++ ++static inline char *prom_adam2_getenv(char *envname) ++{ ++ /* ++ * Return a pointer to the given environment variable. ++ * In 64-bit mode: we're using 64-bit pointers, but all pointers ++ * in the PROM structures are only 32-bit, so we need some ++ * workarounds, if we are running in 64-bit mode. ++ */ ++ int i; ++ t_env_var *env = (t_env_var *) local_envp; ++ ++ if (strcmp("bootloader", envname) == 0) ++ return "Adam2"; ++ ++ i = strlen(envname); ++ while (env->name) { ++ if(strncmp(envname, env->name, i) == 0) { ++ return(env->val); ++ } ++ env++; ++ } ++ ++ return NULL; ++} ++ ++/* XXX "bootloader" won't be returned. ++ * Better make it an element of local_envp */ ++static inline t_env_var * ++prom_adam2_iterenv(t_env_var *env) { ++ if (!env) ++ env = local_envp; ++ else ++ env++; ++ if (env - local_envp > MAX_ENV_ENTRY || !env->name) ++ return 0; ++ return env; ++} ++ ++char *prom_getenv(char *envname) ++{ ++ if (env_type == 1) ++ return prom_psp_getenv(envname); ++ else ++ return prom_adam2_getenv(envname); ++} ++ ++t_env_var * ++prom_iterenv(t_env_var *last) ++{ ++ if (env_type == 1) ++ return 0; /* not yet implemented */ ++ return prom_adam2_iterenv(last); ++} ++ ++static inline unsigned char str2hexnum(unsigned char c) ++{ ++ if (c >= '0' && c <= '9') ++ return c - '0'; ++ if (c >= 'a' && c <= 'f') ++ return c - 'a' + 10; ++ return 0; /* foo */ ++} ++ ++static inline void str2eaddr(unsigned char *ea, unsigned char *str) ++{ ++ int i; ++ ++ for (i = 0; i < 6; i++) { ++ unsigned char num; ++ ++ if((*str == '.') || (*str == ':')) ++ str++; ++ num = str2hexnum(*str++) << 4; ++ num |= (str2hexnum(*str++)); ++ ea[i] = num; ++ } ++} ++ ++int get_ethernet_addr(char *ethernet_addr) ++{ ++ char *ethaddr_str; ++ ++ ethaddr_str = prom_getenv("ethaddr"); ++ if (!ethaddr_str) { ++ printk("ethaddr not set in boot prom\n"); ++ return -1; ++ } ++ str2eaddr(ethernet_addr, ethaddr_str); ++ ++ if (init_debug > 1) { ++ int i; ++ printk("get_ethernet_addr: "); ++ for (i=0; i<5; i++) ++ printk("%02x:", (unsigned char)*(ethernet_addr+i)); ++ printk("%02x\n", *(ethernet_addr+i)); ++ } ++ ++ return 0; ++} ++ ++struct psbl_rec { ++ unsigned int psbl_size; ++ unsigned int env_base; ++ unsigned int env_size; ++ unsigned int ffs_base; ++ unsigned int ffs_size; ++}; ++ ++static const char psp_env_version[] = "TIENV0.8"; ++ ++int __init prom_init(int argc, char **argv, char **envp) ++{ ++ int i; ++ ++ t_env_var *env = (t_env_var *) envp; ++ struct psbl_rec *psbl = (struct psbl_rec *)(KSEG1ADDR(0x94000300)); ++ void *psp_env = (void *)KSEG1ADDR(psbl->env_base); ++ ++ prom_argc = argc; ++ _prom_argv = (int *)argv; ++ _prom_envp = (int *)envp; ++ ++ if(strcmp(psp_env, psp_env_version) == 0) { ++ /* PSPBOOT */ ++ ++ env_type = 1; ++ _prom_envp = psp_env; ++ max_env_entry = (psbl->env_size / 16) - 1; ++ } else { ++ /* Copy what we need locally so we are not dependent on ++ * bootloader RAM. In Adam2, the environment parameters ++ * are in flash but the table that references them is in ++ * RAM ++ */ ++ ++ for(i=0; i < MAX_ENV_ENTRY; i++, env++) { ++ if (env->name) { ++ local_envp[i].name = env->name; ++ local_envp[i].val = env->val; ++ } else { ++ local_envp[i].name = NULL; ++ local_envp[i].val = NULL; ++ } ++ } ++ } ++ ++ set_io_port_base(0); ++ ++ prom_printf("\nLINUX started...\n"); ++ prom_init_cmdline(); ++ prom_meminit(); ++ ++ return 0; ++} +diff -urN linux.old/arch/mips/ar7/int-handler.S linux.dev/arch/mips/ar7/int-handler.S +--- linux.old/arch/mips/ar7/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/int-handler.S 2005-11-10 01:12:43.938955000 +0100 +@@ -0,0 +1,63 @@ ++/* ++ * Copyright 2004 PMC-Sierra Inc. ++ * Author: Manish Lachwani (lachwani@pmc-sierra.com) ++ * Adaption for AR7: Enrik Berkhan ++ * ++ * First-level interrupt dispatcher for the TI AR7 ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++#define __ASSEMBLY__ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * First level interrupt dispatcher for TI AR7 based boards ++ */ ++ ++ .align 5 ++ NESTED(ar7IRQ, PT_SIZE, sp) ++ SAVE_ALL ++ CLI ++ .set at ++ ++ mfc0 t0, CP0_CAUSE ++ mfc0 t2, CP0_STATUS ++ ++ and t0, t2 ++ ++ andi t1, t0, STATUSF_IP2 /* hw0 hardware interrupt */ ++ bnez t1, ll_hw0_irq ++ ++ andi t1, t0, STATUSF_IP7 /* R4k CPU timer */ ++ bnez t1, ll_timer_irq ++ ++ .set reorder ++ ++ /* wrong alarm or masked ... */ ++ j spurious_interrupt ++ nop ++ END(ar7IRQ) ++ ++ .align 5 ++ ++ll_hw0_irq: ++ li a0, 2 ++ move a1, sp ++ jal do_IRQ ++ j ret_from_irq ++ ++ll_timer_irq: ++ li a0, 7 ++ move a1, sp ++ jal do_IRQ ++ j ret_from_irq ++ ++ +diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c +--- linux.old/arch/mips/ar7/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/irq.c 2005-11-10 01:12:43.938955000 +0100 +@@ -0,0 +1,427 @@ ++/* ++ * Nitin Dhingra, iamnd@ti.com ++ * Copyright (C) 2002 Texas Instruments, Inc. All rights reserved. ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ * ++ * Routines for generic manipulation of the interrupts found on the Texas ++ * Instruments avalanche board ++ * ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define shutdown_avalanche_irq disable_avalanche_irq ++#define mask_and_ack_avalanche_irq disable_avalanche_irq ++ ++static unsigned int startup_avalanche_irq(unsigned int irq); ++static void end_avalanche_irq(unsigned int irq); ++void enable_avalanche_irq(unsigned int irq_nr); ++void disable_avalanche_irq(unsigned int irq_nr); ++void ar7_hw0_interrupt(int interrupt, void *dev, struct pt_regs *regs); ++ ++static struct hw_interrupt_type avalanche_irq_type = { ++ "AR7", ++ startup_avalanche_irq, ++ shutdown_avalanche_irq, ++ enable_avalanche_irq, ++ disable_avalanche_irq, ++ mask_and_ack_avalanche_irq, ++ end_avalanche_irq, ++ NULL ++}; ++ ++static int ar7_irq_base; ++ ++static struct irqaction ar7_hw0_action = { ++ ar7_hw0_interrupt, 0, 0, "AR7 on hw0", NULL, NULL ++}; ++ ++struct avalanche_ictrl_regs *avalanche_hw0_icregs; /* Interrupt control regs (primary) */ ++struct avalanche_exctrl_regs *avalanche_hw0_ecregs; /* Exception control regs (secondary) */ ++struct avalanche_ipace_regs *avalanche_hw0_ipaceregs; ++struct avalanche_channel_int_number *avalanche_hw0_chregs; /* Channel control registers */ ++ ++/* ++ This remaps interrupts to exist on other channels than the default ++ channels. essentially we can use the line # as the index for this ++ array ++ */ ++ ++static unsigned long line_to_channel[AVINTNUM(AVALANCHE_INT_END_PRIMARY)]; ++unsigned long uni_secondary_interrupt = 0; ++ ++static void end_avalanche_irq(unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) ++ enable_avalanche_irq(irq); ++} ++ ++void disable_avalanche_irq(unsigned int irq_nr) ++{ ++ unsigned long flags; ++ unsigned long chan_nr=0; ++ ++ save_and_cli(flags); ++ ++ /* irq_nr represents the line number for the interrupt. We must ++ * disable the channel number associated with that line number. ++ */ ++ ++ if(irq_nr > AVALANCHE_INT_END_PRIMARY_REG2) ++ chan_nr = AVINTNUM(irq_nr); /*CHECK THIS ALSO*/ ++ else ++ chan_nr = line_to_channel[AVINTNUM(irq_nr)];/* WE NEED A LINE TO CHANNEL MAPPING FUNCTION HERE*/ ++ ++ /* disable the interrupt channel bit */ ++ ++ /* primary interrupt #'s 0-31 */ ++ ++ if(chan_nr <= AVINTNUM(AVALANCHE_INT_END_PRIMARY_REG1)) ++ avalanche_hw0_icregs->intecr1 = (1 << chan_nr); ++ ++ /* primary interrupt #'s 32-39 */ ++ ++ else if ((chan_nr <= AVINTNUM(AVALANCHE_INT_END_PRIMARY_REG2)) && ++ (chan_nr > AVINTNUM(AVALANCHE_INT_END_PRIMARY_REG1))) ++ avalanche_hw0_icregs->intecr2 = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_SECONDARY))); ++ ++ else /* secondary interrupt #'s 0-31 */ ++ avalanche_hw0_ecregs->exiecr = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_PRIMARY))); ++ ++ restore_flags(flags); ++} ++ ++void enable_avalanche_irq(unsigned int irq_nr) ++{ ++ unsigned long flags; ++ unsigned long chan_nr=0; ++ ++ save_and_cli(flags); ++ ++ /* irq_nr represents the line number for the interrupt. We must ++ * disable the channel number associated with that line number. ++ */ ++ ++ if(irq_nr > AVALANCHE_INT_END_PRIMARY_REG2) ++ chan_nr = AVINTNUM(irq_nr); ++ else ++ chan_nr = line_to_channel[AVINTNUM(irq_nr)]; ++ ++ /* enable the interrupt channel bit */ ++ ++ /* primary interrupt #'s 0-31 */ ++ if(chan_nr <= AVINTNUM(AVALANCHE_INT_END_PRIMARY_REG1)) ++ avalanche_hw0_icregs->intesr1 = (1 << chan_nr); ++ ++ /* primary interrupt #'s 32 throuth 39 */ ++ else if ((chan_nr <= AVINTNUM(AVALANCHE_INT_END_PRIMARY_REG2)) && ++ (chan_nr > AVINTNUM(AVALANCHE_INT_END_PRIMARY_REG1))) ++ avalanche_hw0_icregs->intesr2 = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_SECONDARY))); ++ ++ else /* secondary interrupt #'s 0-31 */ ++ avalanche_hw0_ecregs->exiesr = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_PRIMARY))); ++ ++ restore_flags(flags); ++} ++ ++static unsigned int startup_avalanche_irq(unsigned int irq) ++{ ++ enable_avalanche_irq(irq); ++ return 0; /* never anything pending */ ++} ++ ++void __init ar7_irq_init(int base) ++{ ++ int i; ++ ++ avalanche_hw0_icregs = (struct avalanche_ictrl_regs *)AVALANCHE_ICTRL_REGS_BASE; ++ avalanche_hw0_ecregs = (struct avalanche_exctrl_regs *)AVALANCHE_ECTRL_REGS_BASE; ++ avalanche_hw0_ipaceregs = (struct avalanche_ipace_regs *)AVALANCHE_IPACE_REGS_BASE; ++ avalanche_hw0_chregs = (struct avalanche_channel_int_number *)AVALANCHE_CHCTRL_REGS_BASE; ++ ++ /* Disable interrupts and clear pending ++ */ ++ ++ avalanche_hw0_icregs->intecr1 = 0xffffffff; /* disable interrupts 0:31 */ ++ avalanche_hw0_icregs->intcr1 = 0xffffffff; /* clear interrupts 0:31 */ ++ avalanche_hw0_icregs->intecr2 = 0xff; /* disable interrupts 32:39 */ ++ avalanche_hw0_icregs->intcr2 = 0xff; /* clear interrupts 32:39 */ ++ avalanche_hw0_ecregs->exiecr = 0xffffffff; /* disable secondary interrupts 0:31 */ ++ avalanche_hw0_ecregs->excr = 0xffffffff; /* clear secondary interrupts 0:31 */ ++ ++ ++ // avalanche_hw0_ipaceregs->ipacep = (2*get_avalanche_vbus_freq()/1000000)*4; ++ /* hack for speeding up the pacing. */ ++ printk("the pacing pre-scalar has been set as 600.\n"); ++ avalanche_hw0_ipaceregs->ipacep = 600; ++ /* Channel to line mapping, Line to Channel mapping */ ++ ++ for(i = 0; i < 40; i++) ++ avalanche_int_set(i,i); ++ ++ ar7_irq_base = base; ++ for (i = base; i <= base+40; i++) ++ { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = 0; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &avalanche_irq_type; ++ } ++ ++ setup_irq(2, &ar7_hw0_action); ++ set_c0_status(IE_IRQ0); ++ ++ return; ++} ++ ++void ar7_hw0_interrupt(int interrupt, void *dev, struct pt_regs *regs) ++{ ++ int irq; ++ unsigned long int_line_number, status; ++ int i, chan_nr = 0; ++ ++ int_line_number = ((avalanche_hw0_icregs->pintir >> 16) & 0x3F); ++ chan_nr = ((avalanche_hw0_icregs->pintir) & 0x3F); ++ ++ if(chan_nr < 32) /* primary 0-31 */ ++ { ++ if( chan_nr != uni_secondary_interrupt) ++ avalanche_hw0_icregs->intcr1 = (1< 31)) /* primary 32-39 */ ++ { ++ avalanche_hw0_icregs->intcr2 = (1<<(chan_nr-32)); ++ } ++ ++ ++ /* If the Priority Interrupt Index Register returns 40 then no ++ * interrupts are pending ++ */ ++ ++ if(chan_nr == 40) ++ return; ++ ++ if(chan_nr == uni_secondary_interrupt) /* secondary 0-31 */ ++ { ++ status = avalanche_hw0_ecregs->exsr; ++ for(i=0; i < 32; i++) ++ { ++ if (status & 1<excr = 1 << i; ++ break; ++ } ++ } ++ irq = i+40; ++ ++ /* clear the universal secondary interrupt */ ++ avalanche_hw0_icregs->intcr1 = 1 << uni_secondary_interrupt; ++ ++ } ++ else ++ irq = chan_nr; ++ ++ do_IRQ(irq + ar7_irq_base, regs); ++ return; ++} ++ ++void avalanche_int_set(int channel, int line) ++{ ++ switch(channel) ++ { ++ case(0): ++ avalanche_hw0_chregs->cintnr0 = line; ++ break; ++ case(1): ++ avalanche_hw0_chregs->cintnr1 = line; ++ break; ++ case(2): ++ avalanche_hw0_chregs->cintnr2 = line; ++ break; ++ case(3): ++ avalanche_hw0_chregs->cintnr3 = line; ++ break; ++ case(4): ++ avalanche_hw0_chregs->cintnr4 = line; ++ break; ++ case(5): ++ avalanche_hw0_chregs->cintnr5 = line; ++ break; ++ case(6): ++ avalanche_hw0_chregs->cintnr6 = line; ++ break; ++ case(7): ++ avalanche_hw0_chregs->cintnr7 = line; ++ break; ++ case(8): ++ avalanche_hw0_chregs->cintnr8 = line; ++ break; ++ case(9): ++ avalanche_hw0_chregs->cintnr9 = line; ++ break; ++ case(10): ++ avalanche_hw0_chregs->cintnr10 = line; ++ break; ++ case(11): ++ avalanche_hw0_chregs->cintnr11 = line; ++ break; ++ case(12): ++ avalanche_hw0_chregs->cintnr12 = line; ++ break; ++ case(13): ++ avalanche_hw0_chregs->cintnr13 = line; ++ break; ++ case(14): ++ avalanche_hw0_chregs->cintnr14 = line; ++ break; ++ case(15): ++ avalanche_hw0_chregs->cintnr15 = line; ++ break; ++ case(16): ++ avalanche_hw0_chregs->cintnr16 = line; ++ break; ++ case(17): ++ avalanche_hw0_chregs->cintnr17 = line; ++ break; ++ case(18): ++ avalanche_hw0_chregs->cintnr18 = line; ++ break; ++ case(19): ++ avalanche_hw0_chregs->cintnr19 = line; ++ break; ++ case(20): ++ avalanche_hw0_chregs->cintnr20 = line; ++ break; ++ case(21): ++ avalanche_hw0_chregs->cintnr21 = line; ++ break; ++ case(22): ++ avalanche_hw0_chregs->cintnr22 = line; ++ break; ++ case(23): ++ avalanche_hw0_chregs->cintnr23 = line; ++ break; ++ case(24): ++ avalanche_hw0_chregs->cintnr24 = line; ++ break; ++ case(25): ++ avalanche_hw0_chregs->cintnr25 = line; ++ break; ++ case(26): ++ avalanche_hw0_chregs->cintnr26 = line; ++ break; ++ case(27): ++ avalanche_hw0_chregs->cintnr27 = line; ++ break; ++ case(28): ++ avalanche_hw0_chregs->cintnr28 = line; ++ break; ++ case(29): ++ avalanche_hw0_chregs->cintnr29 = line; ++ break; ++ case(30): ++ avalanche_hw0_chregs->cintnr30 = line; ++ break; ++ case(31): ++ avalanche_hw0_chregs->cintnr31 = line; ++ break; ++ case(32): ++ avalanche_hw0_chregs->cintnr32 = line; ++ break; ++ case(33): ++ avalanche_hw0_chregs->cintnr33 = line; ++ break; ++ case(34): ++ avalanche_hw0_chregs->cintnr34 = line; ++ break; ++ case(35): ++ avalanche_hw0_chregs->cintnr35 = line; ++ break; ++ case(36): ++ avalanche_hw0_chregs->cintnr36 = line; ++ break; ++ case(37): ++ avalanche_hw0_chregs->cintnr37 = line; ++ break; ++ case(38): ++ avalanche_hw0_chregs->cintnr38 = line; ++ break; ++ case(39): ++ avalanche_hw0_chregs->cintnr39 = line; ++ break; ++ default: ++ printk("Error: Unknown Avalanche interrupt channel\n"); ++ } ++ ++ line_to_channel[line] = channel; /* Suraj check */ ++ ++ if (channel == UNIFIED_SECONDARY_INTERRUPT) ++ uni_secondary_interrupt = line; ++ ++} ++ ++ ++#define AVALANCHE_MAX_PACING_BLK 3 ++#define AVALANCHE_PACING_LOW_VAL 2 ++#define AVALANCHE_PACING_HIGH_VAL 63 ++ ++int avalanche_request_pacing(int irq_nr, unsigned int blk_num, ++ unsigned int pace_value) ++{ ++ unsigned int blk_offset; ++ unsigned long flags; ++ ++ if(irq_nr < MIPS_EXCEPTION_OFFSET && ++ irq_nr >= AVALANCHE_INT_END_PRIMARY) ++ return (0); ++ ++ if(blk_num > AVALANCHE_MAX_PACING_BLK) ++ return(-1); ++ ++ if(pace_value > AVALANCHE_PACING_HIGH_VAL && ++ pace_value < AVALANCHE_PACING_LOW_VAL) ++ return(-1); ++ ++ blk_offset = blk_num*8; ++ ++ save_and_cli(flags); ++ ++ /* disable the interrupt pacing, if enabled previously */ ++ avalanche_hw0_ipaceregs->ipacemax &= ~(0xff << blk_offset); ++ ++ /* clear the pacing map */ ++ avalanche_hw0_ipaceregs->ipacemap &= ~(0xff << blk_offset); ++ ++ /* setup the new values */ ++ avalanche_hw0_ipaceregs->ipacemap |= ((AVINTNUM(irq_nr)) << blk_offset); ++ avalanche_hw0_ipaceregs->ipacemax |= ((0x80 | pace_value) << blk_offset); ++ ++ restore_flags(flags); ++ ++ return(0); ++} +diff -urN linux.old/arch/mips/ar7/memory.c linux.dev/arch/mips/ar7/memory.c +--- linux.old/arch/mips/ar7/memory.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/memory.c 2005-11-10 01:14:16.372731750 +0100 +@@ -0,0 +1,103 @@ ++/* ++ * Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++extern char _ftext; ++extern int preserve_adam2; ++ ++void __init prom_meminit(void) ++{ ++ char *memsize_str; ++ unsigned long memsize, adam2size; ++ ++ /* assume block before kernel is used by bootloader */ ++ adam2size = __pa(&_ftext) - PHYS_OFFSET; ++ ++ memsize_str = prom_getenv("memsize"); ++ if (!memsize_str) { ++ memsize = 0x02000000; ++ } else { ++ memsize = simple_strtol(memsize_str, NULL, 0); ++ } ++ ++#if 0 ++ add_memory_region(0x00000000, PHYS_OFFSET, BOOT_MEM_RESERVED); ++#endif ++ add_memory_region(PHYS_OFFSET, adam2size, BOOT_MEM_ROM_DATA); ++ add_memory_region(PHYS_OFFSET+adam2size, memsize-adam2size, ++ BOOT_MEM_RAM); ++} ++ ++unsigned long __init prom_free_prom_memory (void) ++{ ++ int i; ++ unsigned long freed = 0; ++ unsigned long addr; ++ ++ if (preserve_adam2) { ++ char *firstfree_str = prom_getenv("firstfreeaddress"); ++ unsigned long firstfree = 0; ++ ++ if (firstfree_str) ++ firstfree = simple_strtol(firstfree_str, NULL, 0); ++ ++ if (firstfree && firstfree < (unsigned long)&_ftext) { ++ printk("Preserving ADAM2 memory.\n"); ++ } else if (firstfree) { ++ printk("Can't preserve ADAM2 memory, " ++ "firstfreeaddress = %08lx.\n", firstfree); ++ preserve_adam2 = 0; ++ } else { ++ printk("Can't preserve ADAM2 memory, " ++ "firstfreeaddress unknown!\n"); ++ preserve_adam2 = 0; ++ } ++ } ++ ++ if (!preserve_adam2) { ++ for (i = 0; i < boot_mem_map.nr_map; i++) { ++ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) ++ continue; ++ ++ addr = boot_mem_map.map[i].addr; ++ while (addr < boot_mem_map.map[i].addr ++ + boot_mem_map.map[i].size) { ++ ClearPageReserved(virt_to_page(__va(addr))); ++ set_page_count(virt_to_page(__va(addr)), 1); ++ free_page((unsigned long)__va(addr)); ++ addr += PAGE_SIZE; ++ freed += PAGE_SIZE; ++ } ++ } ++ printk("Freeing prom memory: %ldkb freed\n", freed >> 10); ++ } ++ return freed >> PAGE_SHIFT; ++} +diff -urN linux.old/arch/mips/ar7/misc.c linux.dev/arch/mips/ar7/misc.c +--- linux.old/arch/mips/ar7/misc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/misc.c 2005-11-10 01:12:43.946955500 +0100 +@@ -0,0 +1,322 @@ ++#include ++#include ++#include ++#include ++ ++#define TRUE 1 ++ ++static unsigned int avalanche_vbus_freq; ++ ++REMOTE_VLYNQ_DEV_RESET_CTRL_FN p_remote_vlynq_dev_reset_ctrl = NULL; ++ ++/***************************************************************************** ++ * Reset Control Module. ++ *****************************************************************************/ ++void avalanche_reset_ctrl(unsigned int module_reset_bit, ++ AVALANCHE_RESET_CTRL_T reset_ctrl) ++{ ++ volatile unsigned int *reset_reg = (unsigned int*) AVALANCHE_RST_CTRL_PRCR; ++ ++ if(module_reset_bit >= 32 && module_reset_bit < 64) ++ return; ++ ++ if(module_reset_bit >= 64) ++ { ++ if(p_remote_vlynq_dev_reset_ctrl) { ++ p_remote_vlynq_dev_reset_ctrl(module_reset_bit - 64, reset_ctrl); ++ return; ++ } ++ else ++ return; ++ } ++ ++ if(reset_ctrl == OUT_OF_RESET) ++ *reset_reg |= 1 << module_reset_bit; ++ else ++ *reset_reg &= ~(1 << module_reset_bit); ++ return; ++} ++ ++AVALANCHE_RESET_CTRL_T avalanche_get_reset_status(unsigned int module_reset_bit) ++{ ++ volatile unsigned int *reset_reg = (unsigned int*) AVALANCHE_RST_CTRL_PRCR; ++ ++ return (((*reset_reg) & (1 << module_reset_bit)) ? OUT_OF_RESET : IN_RESET ); ++} ++ ++void avalanche_sys_reset(AVALANCHE_SYS_RST_MODE_T mode) ++{ ++ volatile unsigned int *sw_reset_reg = (unsigned int*) AVALANCHE_RST_CTRL_SWRCR; ++ *sw_reset_reg = mode; ++} ++ ++#define AVALANCHE_RST_CTRL_RSR_MASK 0x3 ++ ++AVALANCHE_SYS_RESET_STATUS_T avalanche_get_sys_last_reset_status() ++{ ++ volatile unsigned int *sys_reset_status = (unsigned int*) AVALANCHE_RST_CTRL_RSR; ++ ++ return ( (AVALANCHE_SYS_RESET_STATUS_T) (*sys_reset_status & AVALANCHE_RST_CTRL_RSR_MASK) ); ++} ++ ++ ++/***************************************************************************** ++ * Power Control Module ++ *****************************************************************************/ ++#define AVALANCHE_GLOBAL_POWER_DOWN_MASK 0x3FFFFFFF /* bit 31, 30 masked */ ++#define AVALANCHE_GLOBAL_POWER_DOWN_BIT 30 /* shift to bit 30, 31 */ ++ ++ ++void avalanche_power_ctrl(unsigned int module_power_bit, AVALANCHE_POWER_CTRL_T power_ctrl) ++{ ++ volatile unsigned int *power_reg = (unsigned int*)AVALANCHE_POWER_CTRL_PDCR; ++ ++ if (power_ctrl == POWER_CTRL_POWER_DOWN) ++ /* power down the module */ ++ *power_reg |= (1 << module_power_bit); ++ else ++ /* power on the module */ ++ *power_reg &= (~(1 << module_power_bit)); ++} ++ ++AVALANCHE_POWER_CTRL_T avalanche_get_power_status(unsigned int module_power_bit) ++{ ++ volatile unsigned int *power_status_reg = (unsigned int*)AVALANCHE_POWER_CTRL_PDCR; ++ ++ return (((*power_status_reg) & (1 << module_power_bit)) ? POWER_CTRL_POWER_DOWN : POWER_CTRL_POWER_UP); ++} ++ ++void avalanche_set_global_power_mode(AVALANCHE_SYS_POWER_MODE_T power_mode) ++{ ++ volatile unsigned int *power_status_reg = (unsigned int*)AVALANCHE_POWER_CTRL_PDCR; ++ ++ *power_status_reg &= AVALANCHE_GLOBAL_POWER_DOWN_MASK; ++ *power_status_reg |= ( power_mode << AVALANCHE_GLOBAL_POWER_DOWN_BIT); ++} ++ ++AVALANCHE_SYS_POWER_MODE_T avalanche_get_global_power_mode(void) ++{ ++ volatile unsigned int *power_status_reg = (unsigned int*)AVALANCHE_POWER_CTRL_PDCR; ++ ++ return((AVALANCHE_SYS_POWER_MODE_T) (((*power_status_reg) & (~AVALANCHE_GLOBAL_POWER_DOWN_MASK)) ++ >> AVALANCHE_GLOBAL_POWER_DOWN_BIT)); ++} ++ ++/***************************************************************************** ++ * GPIO Control ++ *****************************************************************************/ ++ ++/**************************************************************************** ++ * FUNCTION: avalanche_gpio_init ++ ***************************************************************************/ ++void avalanche_gpio_init(void) ++{ ++ spinlock_t closeLock; ++ unsigned int closeFlag; ++ volatile unsigned int *reset_reg = (unsigned int*) AVALANCHE_RST_CTRL_PRCR; ++ spin_lock_irqsave(&closeLock, closeFlag); ++ *reset_reg |= (1 << AVALANCHE_GPIO_RESET_BIT); ++ spin_unlock_irqrestore(&closeLock, closeFlag); ++} ++ ++/**************************************************************************** ++ * FUNCTION: avalanche_gpio_ctrl ++ ***************************************************************************/ ++int avalanche_gpio_ctrl(unsigned int gpio_pin, ++ AVALANCHE_GPIO_PIN_MODE_T pin_mode, ++ AVALANCHE_GPIO_PIN_DIRECTION_T pin_direction) ++{ ++ spinlock_t closeLock; ++ unsigned int closeFlag; ++ volatile unsigned int *gpio_ctrl = (unsigned int*)AVALANCHE_GPIO_ENBL; ++ ++ if(gpio_pin >= 32) ++ return(-1); ++ ++ spin_lock_irqsave(&closeLock, closeFlag); ++ ++ if(pin_mode == GPIO_PIN) ++ { ++ *gpio_ctrl |= (1 << gpio_pin); ++ ++ gpio_ctrl = (unsigned int*)AVALANCHE_GPIO_DIR; ++ ++ if(pin_direction == GPIO_INPUT_PIN) ++ *gpio_ctrl |= (1 << gpio_pin); ++ else ++ *gpio_ctrl &= ~(1 << gpio_pin); ++ } ++ else /* FUNCTIONAL PIN */ ++ { ++ *gpio_ctrl &= ~(1 << gpio_pin); ++ } ++ ++ spin_unlock_irqrestore(&closeLock, closeFlag); ++ ++ return (0); ++} ++ ++/**************************************************************************** ++ * FUNCTION: avalanche_gpio_out ++ ***************************************************************************/ ++int avalanche_gpio_out_bit(unsigned int gpio_pin, int value) ++{ ++ spinlock_t closeLock; ++ unsigned int closeFlag; ++ volatile unsigned int *gpio_out = (unsigned int*) AVALANCHE_GPIO_DATA_OUT; ++ ++ if(gpio_pin >= 32) ++ return(-1); ++ ++ spin_lock_irqsave(&closeLock, closeFlag); ++ if(value == TRUE) ++ *gpio_out |= 1 << gpio_pin; ++ else ++ *gpio_out &= ~(1 << gpio_pin); ++ spin_unlock_irqrestore(&closeLock, closeFlag); ++ ++ return(0); ++} ++ ++/**************************************************************************** ++ * FUNCTION: avalanche_gpio_in ++ ***************************************************************************/ ++int avalanche_gpio_in_bit(unsigned int gpio_pin) ++{ ++ spinlock_t closeLock; ++ unsigned int closeFlag; ++ volatile unsigned int *gpio_in = (unsigned int*) AVALANCHE_GPIO_DATA_IN; ++ int ret_val = 0; ++ ++ if(gpio_pin >= 32) ++ return(-1); ++ ++ spin_lock_irqsave(&closeLock, closeFlag); ++ ret_val = ((*gpio_in) & (1 << gpio_pin)); ++ spin_unlock_irqrestore(&closeLock, closeFlag); ++ ++ return (ret_val); ++} ++ ++/**************************************************************************** ++ * FUNCTION: avalanche_gpio_out_val ++ ***************************************************************************/ ++int avalanche_gpio_out_value(unsigned int out_val, unsigned int out_mask, ++ unsigned int reg_index) ++{ ++ spinlock_t closeLock; ++ unsigned int closeFlag; ++ volatile unsigned int *gpio_out = (unsigned int*) AVALANCHE_GPIO_DATA_OUT; ++ ++ if(reg_index > 0) ++ return(-1); ++ ++ spin_lock_irqsave(&closeLock, closeFlag); ++ *gpio_out &= ~out_mask; ++ *gpio_out |= out_val; ++ spin_unlock_irqrestore(&closeLock, closeFlag); ++ ++ return(0); ++} ++ ++/**************************************************************************** ++ * FUNCTION: avalanche_gpio_in_value ++ ***************************************************************************/ ++int avalanche_gpio_in_value(unsigned int* in_val, unsigned int reg_index) ++{ ++ spinlock_t closeLock; ++ unsigned int closeFlag; ++ volatile unsigned int *gpio_in = (unsigned int*) AVALANCHE_GPIO_DATA_IN; ++ ++ if(reg_index > 0) ++ return(-1); ++ ++ spin_lock_irqsave(&closeLock, closeFlag); ++ *in_val = *gpio_in; ++ spin_unlock_irqrestore(&closeLock, closeFlag); ++ ++ return (0); ++} ++ ++/*********************************************************************** ++ * ++ * Wakeup Control Module for TNETV1050 Communication Processor ++ * ++ ***********************************************************************/ ++ ++#define AVALANCHE_WAKEUP_POLARITY_BIT 16 ++ ++void avalanche_wakeup_ctrl(AVALANCHE_WAKEUP_INTERRUPT_T wakeup_int, ++ AVALANCHE_WAKEUP_CTRL_T wakeup_ctrl, ++ AVALANCHE_WAKEUP_POLARITY_T wakeup_polarity) ++{ ++ volatile unsigned int *wakeup_status_reg = (unsigned int*) AVALANCHE_WAKEUP_CTRL_WKCR; ++ ++ /* enable/disable */ ++ if (wakeup_ctrl == WAKEUP_ENABLED) ++ /* enable wakeup */ ++ *wakeup_status_reg |= wakeup_int; ++ else ++ /* disable wakeup */ ++ *wakeup_status_reg &= (~wakeup_int); ++ ++ /* set polarity */ ++ if (wakeup_polarity == WAKEUP_ACTIVE_LOW) ++ *wakeup_status_reg |= (wakeup_int << AVALANCHE_WAKEUP_POLARITY_BIT); ++ else ++ *wakeup_status_reg &= ~(wakeup_int << AVALANCHE_WAKEUP_POLARITY_BIT); ++} ++ ++void avalanche_set_vbus_freq(unsigned int new_vbus_freq) ++{ ++ avalanche_vbus_freq = new_vbus_freq; ++} ++ ++unsigned int avalanche_get_vbus_freq() ++{ ++ return(avalanche_vbus_freq); ++} ++ ++unsigned int avalanche_get_chip_version_info() ++{ ++ return(*(volatile unsigned int*)AVALANCHE_CVR); ++} ++ ++SET_MDIX_ON_CHIP_FN_T p_set_mdix_on_chip_fn = NULL; ++ ++int avalanche_set_mdix_on_chip(unsigned int base_addr, unsigned int operation) ++{ ++ if(p_set_mdix_on_chip_fn) ++ return (p_set_mdix_on_chip_fn(base_addr, operation)); ++ else ++ return(-1); ++} ++ ++unsigned int avalanche_is_mdix_on_chip(void) ++{ ++ return(p_set_mdix_on_chip_fn ? 1:0); ++} ++ ++EXPORT_SYMBOL(avalanche_reset_ctrl); ++EXPORT_SYMBOL(avalanche_get_reset_status); ++EXPORT_SYMBOL(avalanche_sys_reset); ++EXPORT_SYMBOL(avalanche_get_sys_last_reset_status); ++EXPORT_SYMBOL(avalanche_power_ctrl); ++EXPORT_SYMBOL(avalanche_get_power_status); ++EXPORT_SYMBOL(avalanche_set_global_power_mode); ++EXPORT_SYMBOL(avalanche_get_global_power_mode); ++EXPORT_SYMBOL(avalanche_set_mdix_on_chip); ++EXPORT_SYMBOL(avalanche_is_mdix_on_chip); ++ ++EXPORT_SYMBOL(avalanche_gpio_init); ++EXPORT_SYMBOL(avalanche_gpio_ctrl); ++EXPORT_SYMBOL(avalanche_gpio_out_bit); ++EXPORT_SYMBOL(avalanche_gpio_in_bit); ++EXPORT_SYMBOL(avalanche_gpio_out_value); ++EXPORT_SYMBOL(avalanche_gpio_in_value); ++ ++EXPORT_SYMBOL(avalanche_set_vbus_freq); ++EXPORT_SYMBOL(avalanche_get_vbus_freq); ++ ++EXPORT_SYMBOL(avalanche_get_chip_version_info); ++ +diff -urN linux.old/arch/mips/ar7/platform.h linux.dev/arch/mips/ar7/platform.h +--- linux.old/arch/mips/ar7/platform.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/platform.h 2005-11-10 01:10:45.799571750 +0100 +@@ -0,0 +1,65 @@ ++#ifndef _PLATFORM_H_ ++#define _PLATFORM_H_ ++ ++#include ++ ++ ++/* Important: The definition of ENV_SPACE_SIZE should match with that in ++ * PSPBoot. (/psp_boot/inc/psbl/env.h) ++ */ ++#ifdef CONFIG_MIPS_AVALANCHE_TICFG ++#define ENV_SPACE_SIZE (10 * 1024) ++#endif ++ ++#ifdef CONFIG_MIPS_TNETV1050SDB ++#define TNETV1050SDB ++#define DUAL_FLASH ++#endif ++ ++#ifdef CONFIG_MIPS_AR7DB ++#define TNETD73XX_BOARD ++#define AR7DB ++#endif ++ ++#ifdef CONFIG_MIPS_AR7RD ++#define TNETD73XX_BOARD ++#define AR7RD ++#endif ++ ++#ifdef CONFIG_AR7WRD ++#define TNETD73XX_BOARD ++#define AR7WRD ++#endif ++ ++#ifdef CONFIG_MIPS_AR7VWI ++#define TNETD73XX_BOARD ++#define AR7VWi ++#endif ++ ++/* Merging from the DEV_DSL-PSPL4.3.2.7_Patch release. */ ++#ifdef CONFIG_MIPS_AR7VW ++#define TNETD73XX_BOARD ++#define AR7WRD ++#endif ++ ++#ifdef CONFIG_MIPS_AR7WI ++#define TNETD73XX_BOARD ++#define AR7Wi ++#endif ++ ++#ifdef CONFIG_MIPS_AR7V ++#define TNETD73XX_BOARD ++#define AR7V ++#endif ++ ++#ifdef CONFIG_MIPS_AR7V ++#define TNETD73XX_BOARD ++#define AR7V ++#endif ++ ++#ifdef CONFIG_MIPS_WA1130 ++#define AVALANCHE ++#define WLAN ++#endif ++ ++#endif +diff -urN linux.old/arch/mips/ar7/promlib.c linux.dev/arch/mips/ar7/promlib.c +--- linux.old/arch/mips/ar7/promlib.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/promlib.c 2005-11-10 01:14:16.372731750 +0100 +@@ -0,0 +1,48 @@ ++/* ++ * Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * Putting things on the screen/serial line using Adam2 facilities. ++ */ ++ ++#include ++#include ++ ++#define AVALANCHE_YAMON_FUNCTION_BASE (KSEG1ADDR(0x10000500)) ++#define AVALANCHE_YAMON_PROM_PRINT_COUNT_ADDR \ ++ (AVALANCHE_YAMON_FUNCTION_BASE + 1 * 0x4) ++#define AVALANCHE_YAMON_PROM_EXIT \ ++ (AVALANCHE_YAMON_FUNCTION_BASE + 8 * 0x4) ++ ++void prom_putchar(char c) ++{ ++ static char buf[1]; ++ void (*prom_print_str)(unsigned int dummy, char *s, int len) = ++ (void *)(*(uint32_t *)AVALANCHE_YAMON_PROM_PRINT_COUNT_ADDR); ++ ++ buf[0] = c; ++ prom_print_str(1, buf, 1); ++ return; ++} ++ ++void adam2_exit(int retval) ++{ ++ void (*yamon_exit)(int retval) = ++ (void *)(*(uint32_t *)AVALANCHE_YAMON_PROM_EXIT); ++ ++ yamon_exit(retval); ++ return; ++} +diff -urN linux.old/arch/mips/ar7/psp_env.c linux.dev/arch/mips/ar7/psp_env.c +--- linux.old/arch/mips/ar7/psp_env.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/psp_env.c 2005-11-10 01:10:45.799571750 +0100 +@@ -0,0 +1,350 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "platform.h" ++ ++#define ENV_CELL_SIZE 16 ++ ++/* control field decode */ ++#define ENV_GARBAGE_BIT 0x01 /* Env is garbage if this bit is off */ ++#define ENV_DYNAMIC_BIT 0x02 /* Env is dynamic if this bit is off */ ++ ++#define ENV_CTRL_MASK 0x03 ++#define ENV_PREFINED (ENV_GARBAGE_BIT | ENV_DYNAMIC_BIT) ++#define ENV_DYNAMIC (ENV_GARBAGE_BIT) ++ ++struct env_variable { ++ unsigned char varNum; ++ unsigned char ctrl; ++ unsigned short chksum; ++ unsigned char numCells; ++ unsigned char data[ENV_CELL_SIZE - 5]; /* The data section starts ++ * here, continues for ++ * numCells. ++ */ ++}; ++ ++extern unsigned int max_env_entry; ++ ++/* Internal macros */ ++#define get_next_block(var) ((struct env_variable *)( (char*)(var) + (var)->numCells * ENV_CELL_SIZE)) ++ ++typedef enum ENV_VARS { ++ env_vars_start = 0, ++ CPUFREQ, ++ MEMSZ, ++ FLASHSZ, ++ MODETTY0, ++ MODETTY1, ++ PROMPT, ++ BOOTCFG, ++ HWA_0, ++#if !defined (AVALANCHE) || defined(TNETC401B) ++ HWA_1, ++#endif ++#if !defined(TNETV1020_BOARD) ++ HWA_RNDIS, ++#endif ++#if defined (TNETD73XX_BOARD) ++ HWA_3, ++#endif ++ IPA, ++ IPA_SVR, ++ BLINE_MAC0, ++#if !defined (AVALANCHE) || defined(TNETC401B) ++ BLINE_MAC1, ++#endif ++#if !defined(TNETV1020_BOARD) ++ BLINE_RNDIS, ++#endif ++#if defined (TNETD73XX_BOARD) ++ BLINE_ATM, ++#endif ++#if !defined(TNETV1020_BOARD) ++ USB_PID, ++ USB_VID, ++ USB_EPPOLLI, ++#endif ++ IPA_GATEWAY, ++ SUBNET_MASK, ++#if defined (TNETV1050_BOARD) ++ BLINE_ESWITCH, ++#endif ++#if !defined(TNETV1020_BOARD) ++ USB_SERIAL, ++ HWA_HRNDIS, /* Host (PC) side RNDIS address */ ++#endif ++ REMOTE_USER, ++ REMOTE_PASS, ++ REMOTE_DIR, ++ SYSFREQ, ++ LINK_TIMEOUT, ++#ifndef AVALANCHE /* Avalanche boards use only one mac port */ ++ MAC_PORT, ++#endif ++ PATH, ++ HOSTNAME, ++#ifdef WLAN ++ HW_REV_MAJOR, ++ HW_REV_MINOR, ++ HW_PATCH, ++ SW_PATCH, ++ SERIAL_NUMBER, ++#endif ++ TFTPCFG, ++#if defined (TNETV1050_BOARD) ++ HWA_ESWITCH, ++#endif ++ /* ++ * Add new env variables here. ++ * NOTE: New environment variables should always be placed at the end, ie ++ * just before env_vars_end. ++ */ ++ ++ env_vars_end ++} ENV_VARS; ++ ++ ++struct env_description { ++ ENV_VARS idx; ++ char *nm; ++ char *alias; ++}; ++ ++#define ENVSTR(x) #x ++#define _ENV_ENTRY(x) {.idx = x, .nm = ENVSTR(x), .alias = NULL} ++ ++struct env_description env_ns[] = { ++ _ENV_ENTRY(env_vars_start), /* start. */ ++ _ENV_ENTRY(CPUFREQ), ++ _ENV_ENTRY(MEMSZ), ++ _ENV_ENTRY(FLASHSZ), ++ _ENV_ENTRY(MODETTY0), ++ _ENV_ENTRY(MODETTY1), ++ _ENV_ENTRY(PROMPT), ++ _ENV_ENTRY(BOOTCFG), ++ _ENV_ENTRY(HWA_0), ++#if !defined (AVALANCHE) || defined(TNETC401B) ++ _ENV_ENTRY(HWA_1), ++#endif ++#if !defined(TNETV1020_BOARD) ++ _ENV_ENTRY(HWA_RNDIS), ++#endif ++#if defined (TNETD73XX_BOARD) ++ _ENV_ENTRY(HWA_3), ++#endif ++ _ENV_ENTRY(IPA), ++ _ENV_ENTRY(IPA_SVR), ++ _ENV_ENTRY(IPA_GATEWAY), ++ _ENV_ENTRY(SUBNET_MASK), ++ _ENV_ENTRY(BLINE_MAC0), ++#if !defined (AVALANCHE) || defined(TNETC401B) ++ _ENV_ENTRY(BLINE_MAC1), ++#endif ++#if !defined(TNETV1020_BOARD) ++ _ENV_ENTRY(BLINE_RNDIS), ++#endif ++#if defined (TNETD73XX_BOARD) ++ _ENV_ENTRY(BLINE_ATM), ++#endif ++#if !defined(TNETV1020_BOARD) ++ _ENV_ENTRY(USB_PID), ++ _ENV_ENTRY(USB_VID), ++ _ENV_ENTRY(USB_EPPOLLI), ++#endif ++#if defined (TNETV1050_BOARD) ++ _ENV_ENTRY(BLINE_ESWITCH), ++#endif ++#if !defined(TNETV1020_BOARD) ++ _ENV_ENTRY(USB_SERIAL), ++ _ENV_ENTRY(HWA_HRNDIS), ++#endif ++ _ENV_ENTRY(REMOTE_USER), ++ _ENV_ENTRY(REMOTE_PASS), ++ _ENV_ENTRY(REMOTE_DIR), ++ _ENV_ENTRY(SYSFREQ), ++ _ENV_ENTRY(LINK_TIMEOUT), ++#ifndef AVALANCHE /* Avalanche boards use only one mac port */ ++ _ENV_ENTRY(MAC_PORT), ++#endif ++ _ENV_ENTRY(PATH), ++ _ENV_ENTRY(HOSTNAME), ++#ifdef WLAN ++ _ENV_ENTRY(HW_REV_MAJOR), ++ _ENV_ENTRY(HW_REV_MINOR), ++ _ENV_ENTRY(HW_PATCH), ++ _ENV_ENTRY(SW_PATCH), ++ _ENV_ENTRY(SERIAL_NUMBER), ++#endif ++ _ENV_ENTRY(TFTPCFG), ++#if defined (TNETV1050_BOARD) ++ _ENV_ENTRY(HWA_ESWITCH), ++#endif ++ /* ++ * Add new entries below this. ++ */ ++ /* Adam2 environment name alias. */ ++ { .idx = IPA, .nm = "my_ipaddress" }, ++ { .idx = CPUFREQ, .nm = "cpufrequency" }, ++ { .idx = SYSFREQ, .nm = "sysfrequency" }, ++ { .idx = HWA_0, .nm = "maca" }, ++#ifndef AVALANCHE ++ { .idx = HWA_1, .nm = "macb" }, ++#endif ++ { .idx = MODETTY0, .nm = "modetty0" }, ++ { .idx = MODETTY1, .nm = "modetty1" }, ++ { .idx = MEMSZ, .nm = "memsize" }, ++ ++ _ENV_ENTRY(env_vars_end) /* delimiter. */ ++}; ++ ++static inline int var_to_idx(const char* var) ++{ ++ int ii; ++ ++ /* go over the list of pre-defined environment variables */ ++ for (ii = env_vars_start; env_ns[ii].idx != env_vars_end; ii++){ ++ /* check if the env variable is listed */ ++ if (strcmp(env_ns[ii].nm, var) == 0) { ++ return env_ns[ii].idx; ++ } ++ ++ /* if an alias is present, check if the alias matches ++ * the description ++ */ ++ if (env_ns[ii].alias != NULL) { ++ if (strcmp(env_ns[ii].alias, var) == 0) { ++ return env_ns[ii].idx; ++ } ++ } ++ } ++ return 0; ++} ++ ++extern int *_prom_envp; ++ ++/* FIXME: reading from the flash is extremly unstable. Sometime a read returns garbage, ++ * the next read some seconds later is ok. It looks like something is hidding or ++ * overlay the flash address at 0xb0000000. Is this possible? ++ * ++ * The readb() and while() usage below is a attempt of a workarround - with limited success. ++ */ ++ ++static inline struct env_variable* get_var_by_number(int index) ++{ ++ struct env_variable *env_var = (struct env_variable *)_prom_envp; ++ volatile unsigned char nr; ++ int i; ++ ++ env_var++; /* skip signature */ ++ ++ i = 0; ++ nr = readb(&(env_var->varNum)); ++ ++ while (i < max_env_entry && nr != 0xFF) { ++ if ((env_var->ctrl & ENV_CTRL_MASK) == ENV_PREFINED) { ++ if (nr == index) { ++ return env_var; ++ } ++ } ++ i++; ++ env_var = get_next_block(env_var); ++ nr = readb(&(env_var->varNum)); ++ } ++ ++ return NULL; ++} ++ ++static inline struct env_variable* get_var_by_name(char *var) ++{ ++ struct env_variable *env_var = (struct env_variable *)_prom_envp; ++ volatile unsigned char nr; ++ int i; ++ ++ env_var++; /* skip signature */ ++ ++ nr = readb(&(env_var->varNum)); ++ i = 0; ++ ++ while (i < max_env_entry && nr != 0xFF) { ++ if ((env_var->ctrl & ENV_CTRL_MASK) == ENV_DYNAMIC) { ++ if (strcmp(var, env_var->data) == 0) ++ return env_var; ++ } ++ i++; ++ env_var = get_next_block(env_var); ++ nr = readb(&(env_var->varNum)); ++ } ++ return NULL; ++} ++ ++static inline struct env_variable* get_var(char *var) ++{ ++ int index = var_to_idx(var); ++ ++ if (index) ++ return get_var_by_number(index); ++ else ++ return get_var_by_name(var); ++ ++ return NULL; ++} ++ ++static inline char *get_value(struct env_variable* env_var) ++{ ++ unsigned char *name; ++ unsigned char *value; ++ unsigned short chksum; ++ int i; ++ ++ chksum = env_var->varNum + env_var->ctrl + env_var->numCells; ++ ++ if ((env_var->ctrl & ENV_CTRL_MASK) == ENV_DYNAMIC) { ++ name = env_var->data; ++ value = env_var->data + strlen(name) + 1; ++ ++ for(i = 0; i < strlen(name); i++) ++ chksum += name[i]; ++ } else ++ value = env_var->data; ++ ++ for (i = 0; i < strlen(value); i++) ++ chksum += value[i]; ++ ++ chksum += env_var->chksum; ++ chksum = ~(chksum); ++ ++ if(chksum != 0) { ++ return NULL; ++ } ++ ++ return value; ++} ++ ++struct psbl_rec { ++ unsigned int psbl_size; ++ unsigned int env_base; ++ unsigned int env_size; ++ unsigned int ffs_base; ++ unsigned int ffs_size; ++}; ++ ++char *prom_psp_getenv(char *envname) ++{ ++ struct env_variable* env_var; ++ char *value; ++ ++ if (strcmp("bootloader", envname) == 0) ++ return "PSPBoot"; ++ ++ if (!(env_var = get_var(envname))) ++ return NULL; ++ ++ value = get_value(env_var); ++ ++ return value; ++} +diff -urN linux.old/arch/mips/ar7/reset.c linux.dev/arch/mips/ar7/reset.c +--- linux.old/arch/mips/ar7/reset.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/reset.c 2005-11-10 01:14:16.372731750 +0100 +@@ -0,0 +1,98 @@ ++/* ++ * Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ * ++ * Reset the AR7 boards. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++int preserve_adam2 = 1; ++ ++extern void adam2_exit(int retval); ++ ++static void ar7_machine_restart(char *command); ++static void ar7_machine_halt(void); ++static void ar7_machine_power_off(void); ++ ++static void ar7_machine_restart(char *command) ++{ ++ volatile uint32_t *softres_reg = (void *)(KSEG1ADDR(0x08611600 + 0x4)); ++ ++ *softres_reg = 1; ++} ++ ++static void ar7_machine_halt(void) ++{ ++ ++ if (preserve_adam2) { ++ set_c0_status(ST0_BEV); ++ adam2_exit(0); ++ } else { ++ /* I'd like to have Alt-SysRq-b work in this state. ++ * What's missing here? The timer interrupt is still running. ++ * Why doesn't the UART work anymore? */ ++ while(1) { ++ __asm__(".set\tmips3\n\t" ++ "wait\n\t" ++ ".set\tmips0"); ++ } ++ } ++} ++ ++static void ar7_machine_power_off(void) ++{ ++ volatile uint32_t *power_reg = (void *)(KSEG1ADDR(0x08610A00)); ++ uint32_t power_state = *power_reg; ++ ++ /* add something to turn LEDs off? */ ++ ++ power_state &= ~(3 << 30); ++ power_state |= (3 << 30); /* power down */ ++ *power_reg = power_state; ++ ++ printk("after power down?\n"); ++} ++ ++void ar7_reboot_setup(void) ++{ ++ _machine_restart = ar7_machine_restart; ++ _machine_halt = ar7_machine_halt; ++ _machine_power_off = ar7_machine_power_off; ++} ++ ++static int __init ar7_do_preserve_adam2(char *s) ++{ ++ if (!strcmp(s, "no") || !strcmp(s, "0")) ++ preserve_adam2 = 0; ++ else ++ preserve_adam2 = 1; ++ return 1; ++} ++ ++__setup("adam2=", ar7_do_preserve_adam2); +diff -urN linux.old/arch/mips/ar7/setup.c linux.dev/arch/mips/ar7/setup.c +--- linux.old/arch/mips/ar7/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/setup.c 2005-11-10 01:12:43.946955500 +0100 +@@ -0,0 +1,143 @@ ++/* ++ * Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_KGDB ++extern void rs_kgdb_hook(int); ++extern void breakpoint(void); ++int remote_debug = 0; ++#endif ++ ++extern void ar7_reboot_setup(void); ++extern void ar7_irq_init(int); ++extern asmlinkage void ar7IRQ(void); ++ ++void ar7_time_init(void) ++{ ++ /* XXX runtime */ ++ mips_hpt_frequency = CONFIG_AR7_CPU * 500000; ++} ++ ++void ar7_timer_setup(struct irqaction *irq) ++{ ++ setup_irq(7, irq); ++ set_c0_status(IE_IRQ5); ++} ++ ++void __init init_IRQ(void) ++{ ++ init_generic_irq(); ++ mips_cpu_irq_init(0); ++ ar7_irq_init(8); ++ ++ /* Now safe to set the exception vector. */ ++ set_except_vector(0, ar7IRQ); ++ ++#ifdef CONFIG_KGDB ++ if (remote_debug) ++ { ++ set_debug_traps(); ++ breakpoint(); ++ } ++#endif ++} ++ ++const char *get_system_type(void) ++{ ++ return "Texas Instruments AR7"; ++} ++ ++void __init ar7_setup(void) ++{ ++#ifdef CONFIG_KGDB ++ int rs_putDebugChar(char); ++ char rs_getDebugChar(void); ++ extern int (*generic_putDebugChar)(char); ++ extern char (*generic_getDebugChar)(void); ++#endif ++ char *argptr; ++#ifdef CONFIG_SERIAL_CONSOLE ++ argptr = prom_getcmdline(); ++ if ((argptr = strstr(argptr, "console=")) == NULL) { ++ char console[20]; ++ char *s; ++ int i = 0; ++ ++ s = prom_getenv("modetty0"); ++ strcpy(console, "38400"); ++ ++ if (s != NULL) { ++ while (s[i] >= '0' && s[i] <= '9') ++ i++; ++ ++ if (i > 0) { ++ strncpy(console, s, i); ++ console[i] = 0; ++ } ++ } ++ ++ argptr = prom_getcmdline(); ++ strcat(argptr, " console=ttyS0,"); ++ strcat(argptr, console); ++ } ++#endif ++ ++#ifdef CONFIG_KGDB ++ argptr = prom_getcmdline(); ++ if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { ++ int line; ++ argptr += strlen("kgdb=ttyS"); ++ if (*argptr != '0' && *argptr != '1') ++ printk("KGDB: Uknown serial line /dev/ttyS%c, " ++ "falling back to /dev/ttyS1\n", *argptr); ++ line = *argptr == '0' ? 0 : 1; ++ printk("KGDB: Using serial line /dev/ttyS%d for session\n", ++ line ? 1 : 0); ++ ++ rs_kgdb_hook(line); ++ generic_putDebugChar = rs_putDebugChar; ++ generic_getDebugChar = rs_getDebugChar; ++ ++ prom_printf("KGDB: Using serial line /dev/ttyS%d for session, " ++ "please connect your debugger\n", line ? 1 : 0); ++ ++ remote_debug = 1; ++ /* Breakpoints are in init_IRQ() */ ++ } ++#endif ++ ++ argptr = prom_getcmdline(); ++ if ((argptr = strstr(argptr, "nofpu")) != NULL) ++ cpu_data[0].options &= ~MIPS_CPU_FPU; ++ ++ ar7_reboot_setup(); ++ ++ board_time_init = ar7_time_init; ++ board_timer_setup = ar7_timer_setup; ++} +diff -urN linux.old/arch/mips/ar7/tnetd73xx_misc.c linux.dev/arch/mips/ar7/tnetd73xx_misc.c +--- linux.old/arch/mips/ar7/tnetd73xx_misc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/ar7/tnetd73xx_misc.c 2005-11-10 01:12:43.946955500 +0100 +@@ -0,0 +1,921 @@ ++/****************************************************************************** ++ * FILE PURPOSE: TNETD73xx Misc modules API Source ++ ****************************************************************************** ++ * FILE NAME: tnetd73xx_misc.c ++ * ++ * DESCRIPTION: Clock Control, Reset Control, Power Management, GPIO ++ * FSER Modules API ++ * As per TNETD73xx specifications ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - Sharath Kumar PSP TII ++ * 14 Feb 03 - Anant Gole PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#include ++#include ++#include ++ ++/* TNETD73XX Revision */ ++u32 tnetd73xx_get_revision(void) ++{ ++ /* Read Chip revision register - This register is from GPIO module */ ++ return ( (u32) REG32_DATA(TNETD73XX_CVR)); ++} ++ ++/***************************************************************************** ++ * Reset Control Module ++ *****************************************************************************/ ++ ++ ++void tnetd73xx_reset_ctrl(TNETD73XX_RESET_MODULE_T reset_module, TNETD73XX_RESET_CTRL_T reset_ctrl) ++{ ++ u32 reset_status; ++ ++ /* read current reset register */ ++ REG32_READ(TNETD73XX_RST_CTRL_PRCR, reset_status); ++ ++ if (reset_ctrl == OUT_OF_RESET) ++ { ++ /* bring module out of reset */ ++ reset_status |= (1 << reset_module); ++ } ++ else ++ { ++ /* put module in reset */ ++ reset_status &= (~(1 << reset_module)); ++ } ++ ++ /* write to the reset register */ ++ REG32_WRITE(TNETD73XX_RST_CTRL_PRCR, reset_status); ++} ++ ++ ++TNETD73XX_RESET_CTRL_T tnetd73xx_get_reset_status (TNETD73XX_RESET_MODULE_T reset_module) ++{ ++ u32 reset_status; ++ ++ REG32_READ(TNETD73XX_RST_CTRL_PRCR, reset_status); ++ return ( (reset_status & (1 << reset_module)) ? OUT_OF_RESET : IN_RESET ); ++} ++ ++void tnetd73xx_sys_reset(TNETD73XX_SYS_RST_MODE_T mode) ++{ ++ REG32_WRITE(TNETD73XX_RST_CTRL_SWRCR, mode); ++} ++ ++#define TNETD73XX_RST_CTRL_RSR_MASK 0x3 ++ ++TNETD73XX_SYS_RESET_STATUS_T tnetd73xx_get_sys_last_reset_status() ++{ ++ u32 sys_reset_status; ++ ++ REG32_READ(TNETD73XX_RST_CTRL_RSR, sys_reset_status); ++ ++ return ( (TNETD73XX_SYS_RESET_STATUS_T) (sys_reset_status & TNETD73XX_RST_CTRL_RSR_MASK) ); ++} ++ ++ ++/***************************************************************************** ++ * Power Control Module ++ *****************************************************************************/ ++#define TNETD73XX_GLOBAL_POWER_DOWN_MASK 0x3FFFFFFF /* bit 31, 30 masked */ ++#define TNETD73XX_GLOBAL_POWER_DOWN_BIT 30 /* shift to bit 30, 31 */ ++ ++ ++void tnetd73xx_power_ctrl(TNETD73XX_POWER_MODULE_T power_module, TNETD73XX_POWER_CTRL_T power_ctrl) ++{ ++ u32 power_status; ++ ++ /* read current power down control register */ ++ REG32_READ(TNETD73XX_POWER_CTRL_PDCR, power_status); ++ ++ if (power_ctrl == POWER_CTRL_POWER_DOWN) ++ { ++ /* power down the module */ ++ power_status |= (1 << power_module); ++ } ++ else ++ { ++ /* power on the module */ ++ power_status &= (~(1 << power_module)); ++ } ++ ++ /* write to the reset register */ ++ REG32_WRITE(TNETD73XX_POWER_CTRL_PDCR, power_status); ++} ++ ++TNETD73XX_POWER_CTRL_T tnetd73xx_get_pwr_status(TNETD73XX_POWER_MODULE_T power_module) ++{ ++ u32 power_status; ++ ++ /* read current power down control register */ ++ REG32_READ(TNETD73XX_POWER_CTRL_PDCR, power_status); ++ ++ return ( (power_status & (1 << power_module)) ? POWER_CTRL_POWER_DOWN : POWER_CTRL_POWER_UP ); ++} ++ ++void tnetd73xx_set_global_pwr_mode(TNETD73XX_SYS_POWER_MODE_T power_mode) ++{ ++ u32 power_status; ++ ++ /* read current power down control register */ ++ REG32_READ(TNETD73XX_POWER_CTRL_PDCR, power_status); ++ ++ power_status &= TNETD73XX_GLOBAL_POWER_DOWN_MASK; ++ power_status |= ( power_mode << TNETD73XX_GLOBAL_POWER_DOWN_BIT); ++ ++ /* write to power down control register */ ++ REG32_WRITE(TNETD73XX_POWER_CTRL_PDCR, power_status); ++} ++ ++TNETD73XX_SYS_POWER_MODE_T tnetd73xx_get_global_pwr_mode() ++{ ++ u32 power_status; ++ ++ /* read current power down control register */ ++ REG32_READ(TNETD73XX_POWER_CTRL_PDCR, power_status); ++ ++ power_status &= (~TNETD73XX_GLOBAL_POWER_DOWN_MASK); ++ power_status = ( power_status >> TNETD73XX_GLOBAL_POWER_DOWN_BIT); ++ ++ return ( (TNETD73XX_SYS_POWER_MODE_T) power_status ); ++} ++ ++ ++/***************************************************************************** ++ * Wakeup Control ++ *****************************************************************************/ ++ ++#define TNETD73XX_WAKEUP_POLARITY_BIT 16 ++ ++void tnetd73xx_wakeup_ctrl(TNETD73XX_WAKEUP_INTERRUPT_T wakeup_int, ++ TNETD73XX_WAKEUP_CTRL_T wakeup_ctrl, ++ TNETD73XX_WAKEUP_POLARITY_T wakeup_polarity) ++{ ++ u32 wakeup_status; ++ ++ /* read the wakeup control register */ ++ REG32_READ(TNETD73XX_POWER_CTRL_WKCR, wakeup_status); ++ ++ /* enable/disable */ ++ if (wakeup_ctrl == WAKEUP_ENABLED) ++ { ++ /* enable wakeup */ ++ wakeup_status |= wakeup_int; ++ } ++ else ++ { ++ /* disable wakeup */ ++ wakeup_status &= (~wakeup_int); ++ } ++ ++ /* set polarity */ ++ if (wakeup_polarity == WAKEUP_ACTIVE_LOW) ++ { ++ wakeup_status |= (wakeup_int << TNETD73XX_WAKEUP_POLARITY_BIT); ++ } ++ else ++ { ++ wakeup_status &= ~(wakeup_int << TNETD73XX_WAKEUP_POLARITY_BIT); ++ } ++ ++ /* write the wakeup control register */ ++ REG32_WRITE(TNETD73XX_POWER_CTRL_WKCR, wakeup_status); ++} ++ ++ ++/***************************************************************************** ++ * FSER Control ++ *****************************************************************************/ ++ ++void tnetd73xx_fser_ctrl(TNETD73XX_FSER_MODE_T fser_mode) ++{ ++ REG32_WRITE(TNETD73XX_FSER_BASE, fser_mode); ++} ++ ++/***************************************************************************** ++ * Clock Control ++ *****************************************************************************/ ++ ++#define MIN(x,y) ( ((x) < (y)) ? (x) : (y) ) ++#define MAX(x,y) ( ((x) > (y)) ? (x) : (y) ) ++#define ABS(x) ( ((signed)(x) > 0) ? (x) : (-(x)) ) ++#define CEIL(x,y) ( ((x) + (y) / 2) / (y) ) ++ ++#define CLKC_CLKCR(x) (TNETD73XX_CLOCK_CTRL_BASE + 0x20 + (0x20 * (x))) ++#define CLKC_CLKPLLCR(x) (TNETD73XX_CLOCK_CTRL_BASE + 0x30 + (0x20 * (x))) ++ ++#define CLKC_PRE_DIVIDER 0x0000001F ++#define CLKC_POST_DIVIDER 0x001F0000 ++ ++#define CLKC_PLL_STATUS 0x1 ++#define CLKC_PLL_FACTOR 0x0000F000 ++ ++#define BOOTCR_PLL_BYPASS (1 << 5) ++#define BOOTCR_MIPS_ASYNC_MODE (1 << 25) ++ ++#define MIPS_PLL_SELECT 0x00030000 ++#define SYSTEM_PLL_SELECT 0x0000C000 ++#define USB_PLL_SELECT 0x000C0000 ++#define ADSLSS_PLL_SELECT 0x00C00000 ++ ++#define MIPS_AFECLKI_SELECT 0x00000000 ++#define MIPS_REFCLKI_SELECT 0x00010000 ++#define MIPS_XTAL3IN_SELECT 0x00020000 ++ ++#define SYSTEM_AFECLKI_SELECT 0x00000000 ++#define SYSTEM_REFCLKI_SELECT 0x00004000 ++#define SYSTEM_XTAL3IN_SELECT 0x00008000 ++#define SYSTEM_MIPSPLL_SELECT 0x0000C000 ++ ++#define USB_SYSPLL_SELECT 0x00000000 ++#define USB_REFCLKI_SELECT 0x00040000 ++#define USB_XTAL3IN_SELECT 0x00080000 ++#define USB_MIPSPLL_SELECT 0x000C0000 ++ ++#define ADSLSS_AFECLKI_SELECT 0x00000000 ++#define ADSLSS_REFCLKI_SELECT 0x00400000 ++#define ADSLSS_XTAL3IN_SELECT 0x00800000 ++#define ADSLSS_MIPSPLL_SELECT 0x00C00000 ++ ++#define SYS_MAX CLK_MHZ(150) ++#define SYS_MIN CLK_MHZ(1) ++ ++#define MIPS_SYNC_MAX SYS_MAX ++#define MIPS_ASYNC_MAX CLK_MHZ(160) ++#define MIPS_MIN CLK_MHZ(1) ++ ++#define USB_MAX CLK_MHZ(100) ++#define USB_MIN CLK_MHZ(1) ++ ++#define ADSL_MAX CLK_MHZ(180) ++#define ADSL_MIN CLK_MHZ(1) ++ ++#define PLL_MUL_MAXFACTOR 15 ++#define MAX_DIV_VALUE 32 ++#define MIN_DIV_VALUE 1 ++ ++#define MIN_PLL_INP_FREQ CLK_MHZ(8) ++#define MAX_PLL_INP_FREQ CLK_MHZ(100) ++ ++#define DIVIDER_LOCK_TIME 10100 ++#define PLL_LOCK_TIME 10100 * 75 ++ ++ ++ ++ /**************************************************************************** ++ * DATA PURPOSE: PRIVATE Variables ++ **************************************************************************/ ++ static u32 *clk_src[4]; ++ static u32 mips_pll_out; ++ static u32 sys_pll_out; ++ static u32 afeclk_inp; ++ static u32 refclk_inp; ++ static u32 xtal_inp; ++ static u32 present_min; ++ static u32 present_max; ++ ++ /* Forward References */ ++ static u32 find_gcd(u32 min, u32 max); ++ static u32 compute_prediv( u32 divider, u32 min, u32 max); ++ static void get_val(u32 base_freq, u32 output_freq,u32 *multiplier, u32 *divider); ++ static u32 get_base_frequency(TNETD73XX_CLKC_ID_T clk_id); ++ static void find_approx(u32 *,u32 *,u32); ++ ++ /**************************************************************************** ++ * FUNCTION: tnetd73xx_clkc_init ++ **************************************************************************** ++ * Description: The routine initializes the internal variables depending on ++ * on the sources selected for different clocks. ++ ***************************************************************************/ ++void tnetd73xx_clkc_init(u32 afeclk, u32 refclk, u32 xtal3in) ++{ ++ ++ u32 choice; ++ ++ afeclk_inp = afeclk; ++ refclk_inp = refclk; ++ xtal_inp = xtal3in; ++ ++ choice = REG32_DATA(TNETD73XX_DCL_BOOTCR) & MIPS_PLL_SELECT; ++ switch(choice) ++ { ++ case MIPS_AFECLKI_SELECT: ++ clk_src[CLKC_MIPS] = &afeclk_inp; ++ break; ++ ++ case MIPS_REFCLKI_SELECT: ++ clk_src[CLKC_MIPS] = &refclk_inp; ++ break; ++ ++ case MIPS_XTAL3IN_SELECT: ++ clk_src[CLKC_MIPS] = &xtal_inp; ++ break; ++ ++ default : ++ clk_src[CLKC_MIPS] = 0; ++ ++ } ++ ++ choice = REG32_DATA(TNETD73XX_DCL_BOOTCR) & SYSTEM_PLL_SELECT; ++ switch(choice) ++ { ++ case SYSTEM_AFECLKI_SELECT: ++ clk_src[CLKC_SYS] = &afeclk_inp; ++ break; ++ ++ case SYSTEM_REFCLKI_SELECT: ++ clk_src[CLKC_SYS] = &refclk_inp; ++ break; ++ ++ case SYSTEM_XTAL3IN_SELECT: ++ clk_src[CLKC_SYS] = &xtal_inp; ++ break; ++ ++ case SYSTEM_MIPSPLL_SELECT: ++ clk_src[CLKC_SYS] = &mips_pll_out; ++ break; ++ ++ default : ++ clk_src[CLKC_SYS] = 0; ++ ++ } ++ ++ ++ choice = REG32_DATA(TNETD73XX_DCL_BOOTCR) & ADSLSS_PLL_SELECT; ++ switch(choice) ++ { ++ case ADSLSS_AFECLKI_SELECT: ++ clk_src[CLKC_ADSLSS] = &afeclk_inp; ++ break; ++ ++ case ADSLSS_REFCLKI_SELECT: ++ clk_src[CLKC_ADSLSS] = &refclk_inp; ++ break; ++ ++ case ADSLSS_XTAL3IN_SELECT: ++ clk_src[CLKC_ADSLSS] = &xtal_inp; ++ break; ++ ++ case ADSLSS_MIPSPLL_SELECT: ++ clk_src[CLKC_ADSLSS] = &mips_pll_out; ++ break; ++ ++ default : ++ clk_src[CLKC_ADSLSS] = 0; ++ ++ } ++ ++ ++ choice = REG32_DATA(TNETD73XX_DCL_BOOTCR) & USB_PLL_SELECT; ++ switch(choice) ++ { ++ case USB_SYSPLL_SELECT: ++ clk_src[CLKC_USB] = &sys_pll_out ; ++ break; ++ ++ case USB_REFCLKI_SELECT: ++ clk_src[CLKC_USB] = &refclk_inp; ++ break; ++ ++ case USB_XTAL3IN_SELECT: ++ clk_src[CLKC_USB] = &xtal_inp; ++ break; ++ ++ case USB_MIPSPLL_SELECT: ++ clk_src[CLKC_USB] = &mips_pll_out; ++ break; ++ ++ default : ++ clk_src[CLKC_USB] = 0; ++ ++ } ++} ++ ++ ++ ++/**************************************************************************** ++ * FUNCTION: tnetd73xx_clkc_set_freq ++ **************************************************************************** ++ * Description: The above routine is called to set the output_frequency of the ++ * selected clock(using clk_id) to the required value given ++ * by the variable output_freq. ++ ***************************************************************************/ ++TNETD73XX_ERR tnetd73xx_clkc_set_freq ++( ++ TNETD73XX_CLKC_ID_T clk_id, ++ u32 output_freq ++ ) ++{ ++ u32 base_freq; ++ u32 multiplier; ++ u32 divider; ++ u32 min_prediv; ++ u32 max_prediv; ++ u32 prediv; ++ u32 postdiv; ++ u32 temp; ++ ++ /* check if PLLs are bypassed*/ ++ if(REG32_DATA(TNETD73XX_DCL_BOOTCR) & BOOTCR_PLL_BYPASS) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ ++ /*check if the requested output_frequency is in valid range*/ ++ switch( clk_id ) ++ { ++ case CLKC_SYS: ++ if( output_freq < SYS_MIN || output_freq > SYS_MAX) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ present_min = SYS_MIN; ++ present_max = SYS_MAX; ++ break; ++ ++ case CLKC_MIPS: ++ if((output_freq < MIPS_MIN) || ++ (output_freq > ((REG32_DATA(TNETD73XX_DCL_BOOTCR) & BOOTCR_MIPS_ASYNC_MODE) ? MIPS_ASYNC_MAX: MIPS_SYNC_MAX))) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ present_min = MIPS_MIN; ++ present_max = (REG32_DATA(TNETD73XX_DCL_BOOTCR) & BOOTCR_MIPS_ASYNC_MODE) ? MIPS_ASYNC_MAX: MIPS_SYNC_MAX; ++ break; ++ ++ case CLKC_USB: ++ if( output_freq < USB_MIN || output_freq > USB_MAX) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ present_min = USB_MIN; ++ present_max = USB_MAX; ++ break; ++ ++ case CLKC_ADSLSS: ++ if( output_freq < ADSL_MIN || output_freq > ADSL_MAX) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ present_min = ADSL_MIN; ++ present_max = ADSL_MAX; ++ break; ++ } ++ ++ ++ base_freq = get_base_frequency(clk_id); ++ ++ ++ /* check for minimum base frequency value */ ++ if( base_freq < MIN_PLL_INP_FREQ) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ ++ get_val(output_freq, base_freq, &multiplier, ÷r); ++ ++ /* check multiplier range */ ++ if( (multiplier > PLL_MUL_MAXFACTOR) || (multiplier <= 0) ) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ ++ /* check divider value */ ++ if( divider == 0 ) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ ++ /*compute minimum and maximum predivider values */ ++ min_prediv = MAX(base_freq / MAX_PLL_INP_FREQ + 1, divider / MAX_DIV_VALUE + 1); ++ max_prediv = MIN(base_freq / MIN_PLL_INP_FREQ, MAX_DIV_VALUE); ++ ++ /*adjust the value of divider so that it not less than minimum predivider value*/ ++ if (divider < min_prediv) ++ { ++ temp = CEIL(min_prediv, divider); ++ if ((temp * multiplier) > PLL_MUL_MAXFACTOR) ++ { ++ return TNETD73XX_ERR_ERROR ; ++ } ++ else ++ { ++ multiplier = temp * multiplier; ++ divider = min_prediv; ++ } ++ ++ } ++ ++ /* compute predivider and postdivider values */ ++ prediv = compute_prediv (divider, min_prediv, max_prediv); ++ postdiv = CEIL(divider,prediv); ++ ++ /*return fail if postdivider value falls out of range */ ++ if(postdiv > MAX_DIV_VALUE) ++ { ++ return TNETD73XX_ERR_ERROR; ++ } ++ ++ ++ /*write predivider and postdivider values*/ ++ /* pre-Divider and post-divider are 5 bit N+1 dividers */ ++ REG32_WRITE(CLKC_CLKCR(clk_id), ((postdiv -1) & 0x1F) << 16 | ((prediv -1) & 0x1F) ); ++ ++ /*wait for divider output to stabilise*/ ++ for(temp =0; temp < DIVIDER_LOCK_TIME; temp++); ++ ++ /*write to PLL clock register*/ ++ ++ if(clk_id == CLKC_SYS) ++ { ++ /* but before writing put DRAM to hold mode */ ++ REG32_DATA(TNETD73XX_EMIF_SDRAM_CFG) |= 0x80000000; ++ } ++ /*Bring PLL into div mode */ ++ REG32_WRITE(CLKC_CLKPLLCR(clk_id), 0x4); ++ ++ /*compute the word to be written to PLLCR ++ *corresponding to multiplier value ++ */ ++ multiplier = (((multiplier - 1) & 0xf) << 12)| ((255 <<3) | 0x0e); ++ ++ /* wait till PLL enters div mode */ ++ while(REG32_DATA(CLKC_CLKPLLCR(clk_id)) & CLKC_PLL_STATUS) ++ /*nothing*/; ++ ++ REG32_WRITE(CLKC_CLKPLLCR(clk_id), multiplier); ++ ++ while(!REG32_DATA(CLKC_CLKPLLCR(clk_id)) & CLKC_PLL_STATUS) ++ /*nothing*/; ++ ++ ++ /*wait for External pll to lock*/ ++ for(temp =0; temp < PLL_LOCK_TIME; temp++); ++ ++ if(clk_id == CLKC_SYS) ++ { ++ /* Bring DRAM out of hold */ ++ REG32_DATA(TNETD73XX_EMIF_SDRAM_CFG) &= ~0x80000000; ++ } ++ ++ return TNETD73XX_ERR_OK ; ++} ++ ++/**************************************************************************** ++ * FUNCTION: tnetd73xx_clkc_get_freq ++ **************************************************************************** ++ * Description: The above routine is called to get the output_frequency of the ++ * selected clock( clk_id) ++ ***************************************************************************/ ++u32 tnetd73xx_clkc_get_freq ++( ++ TNETD73XX_CLKC_ID_T clk_id ++ ) ++{ ++ ++ u32 clk_ctrl_register; ++ u32 clk_pll_setting; ++ u32 clk_predivider; ++ u32 clk_postdivider; ++ u16 pll_factor; ++ u32 base_freq; ++ u32 divider; ++ ++ base_freq = get_base_frequency(clk_id); ++ ++ clk_ctrl_register = REG32_DATA(CLKC_CLKCR(clk_id)); ++ ++ /* pre-Divider and post-divider are 5 bit N+1 dividers */ ++ clk_predivider = (CLKC_PRE_DIVIDER & clk_ctrl_register) + 1; ++ clk_postdivider = ((CLKC_POST_DIVIDER & clk_ctrl_register) >> 16) + 1; ++ ++ divider = clk_predivider * clk_postdivider; ++ ++ ++ if( (REG32_DATA(TNETD73XX_DCL_BOOTCR) & BOOTCR_PLL_BYPASS)) ++ { ++ return (CEIL(base_freq, divider)); /* PLLs bypassed.*/ ++ } ++ ++ ++ else ++ { ++ /* return the current clock speed based upon the PLL setting */ ++ clk_pll_setting = REG32_DATA(CLKC_CLKPLLCR(clk_id)); ++ ++ /* Get the PLL multiplication factor */ ++ pll_factor = ((clk_pll_setting & CLKC_PLL_FACTOR) >> 12) + 1; ++ ++ /* Check if we're in divide mode or multiply mode */ ++ if((clk_pll_setting & 0x1) == 0) ++ { ++ /* We're in divide mode */ ++ if(pll_factor < 0x10) ++ return (CEIL(base_freq >> 1, divider)); ++ else ++ return (CEIL(base_freq >> 2, divider)); ++ } ++ ++ else /* We're in PLL mode */ ++ { ++ /* See if PLLNDIV & PLLDIV are set */ ++ if((clk_pll_setting & 0x0800) && (clk_pll_setting & 0x2)) ++ { ++ if(clk_pll_setting & 0x1000) ++ { ++ /* clk = base_freq * k/2 */ ++ return(CEIL((base_freq * pll_factor) >> 1, divider)); ++ } ++ else ++ { ++ /* clk = base_freq * (k-1) / 4)*/ ++ return(CEIL((base_freq * (pll_factor - 1)) >>2, divider)); ++ } ++ } ++ else ++ { ++ if(pll_factor < 0x10) ++ { ++ /* clk = base_freq * k */ ++ return(CEIL(base_freq * pll_factor, divider)); ++ } ++ ++ else ++ { ++ /* clk = base_freq */ ++ return(CEIL(base_freq, divider)); ++ } ++ } ++ } ++ return(0); /* Should never reach here */ ++ ++ } ++ ++} ++ ++ ++/* local helper functions */ ++ ++/**************************************************************************** ++ * FUNCTION: get_base_frequency ++ **************************************************************************** ++ * Description: The above routine is called to get base frequency of the clocks. ++ ***************************************************************************/ ++ ++static u32 get_base_frequency(TNETD73XX_CLKC_ID_T clk_id) ++{ ++ /* update the current MIPs PLL output value, if the required ++ * source is MIPS PLL ++ */ ++ if ( clk_src[clk_id] == &mips_pll_out) ++ { ++ *clk_src[clk_id] = tnetd73xx_clkc_get_freq(CLKC_MIPS); ++ } ++ ++ ++ /* update the current System PLL output value, if the required ++ * source is system PLL ++ */ ++ if ( clk_src[clk_id] == &sys_pll_out) ++ { ++ *clk_src[clk_id] = tnetd73xx_clkc_get_freq(CLKC_SYS); ++ } ++ ++ return (*clk_src[clk_id]); ++ ++} ++ ++ ++ ++/**************************************************************************** ++ * FUNCTION: find_gcd ++ **************************************************************************** ++ * Description: The above routine is called to find gcd of 2 numbers. ++ ***************************************************************************/ ++static u32 find_gcd ++( ++ u32 min, ++ u32 max ++ ) ++{ ++ if (max % min == 0) ++ { ++ return min; ++ } ++ else ++ { ++ return find_gcd(max % min, min); ++ } ++} ++ ++/**************************************************************************** ++ * FUNCTION: compute_prediv ++ **************************************************************************** ++ * Description: The above routine is called to compute predivider value ++ ***************************************************************************/ ++static u32 compute_prediv(u32 divider, u32 min, u32 max) ++{ ++ u16 prediv; ++ ++ /* return the divider itself it it falls within the range of predivider*/ ++ if (min <= divider && divider <= max) ++ { ++ return divider; ++ } ++ ++ /* find a value for prediv such that it is a factor of divider */ ++ for (prediv = max; prediv >= min ; prediv--) ++ { ++ if ( (divider % prediv) == 0 ) ++ { ++ return prediv; ++ } ++ } ++ ++ /* No such factor exists, return min as prediv */ ++ return min; ++} ++ ++/**************************************************************************** ++ * FUNCTION: get_val ++ **************************************************************************** ++ * Description: This routine is called to get values of divider and multiplier. ++ ***************************************************************************/ ++ ++static void get_val(u32 output_freq, u32 base_freq,u32 *multiplier, u32 *divider) ++{ ++ u32 temp_mul; ++ u32 temp_div; ++ u32 gcd; ++ u32 min_freq; ++ u32 max_freq; ++ ++ /* find gcd of base_freq, output_freq */ ++ min_freq = (base_freq < output_freq) ? base_freq : output_freq; ++ max_freq = (base_freq > output_freq) ? base_freq : output_freq; ++ gcd = find_gcd(min_freq , max_freq); ++ ++ if(gcd == 0) ++ return; /* ERROR */ ++ ++ /* compute values of multiplier and divider */ ++ temp_mul = output_freq / gcd; ++ temp_div = base_freq / gcd; ++ ++ ++ /* set multiplier such that 1 <= multiplier <= PLL_MUL_MAXFACTOR */ ++ if( temp_mul > PLL_MUL_MAXFACTOR ) ++ { ++ if((temp_mul / temp_div) > PLL_MUL_MAXFACTOR) ++ return; ++ ++ find_approx(&temp_mul,&temp_div,base_freq); ++ } ++ ++ *multiplier = temp_mul; ++ *divider = temp_div; ++} ++ ++/**************************************************************************** ++ * FUNCTION: find_approx ++ **************************************************************************** ++ * Description: This function gets the approx value of num/denom. ++ ***************************************************************************/ ++ ++static void find_approx(u32 *num,u32 *denom,u32 base_freq) ++{ ++ u32 num1; ++ u32 denom1; ++ u32 num2; ++ u32 denom2; ++ int32_t closest; ++ int32_t prev_closest; ++ u32 temp_num; ++ u32 temp_denom; ++ u32 normalize; ++ u32 gcd; ++ u32 output_freq; ++ ++ num1 = *num; ++ denom1 = *denom; ++ ++ prev_closest = 0x7fffffff; /* maximum possible value */ ++ num2 = num1; ++ denom2 = denom1; ++ ++ /* start with max */ ++ for(temp_num = 15; temp_num >=1; temp_num--) ++ { ++ ++ temp_denom = CEIL(temp_num * denom1, num1); ++ output_freq = (temp_num * base_freq) / temp_denom; ++ ++ if(temp_denom < 1) ++ { ++ break; ++ } ++ else ++ { ++ normalize = CEIL(num1,temp_num); ++ closest = (ABS((num1 * (temp_denom) ) - (temp_num * denom1))) * normalize; ++ if(closest < prev_closest && output_freq > present_min && output_freq ++int avalanche_request_pacing(int irq_nr, unsigned int blk_num, unsigned int pace_value); ++#endif ++ ++ + EXPORT_SYMBOL(mips_machtype); + #ifdef CONFIG_EISA + EXPORT_SYMBOL(EISA_bus); +@@ -103,3 +109,10 @@ + #endif + + EXPORT_SYMBOL(get_wchan); ++ ++#ifdef CONFIG_AR7 ++EXPORT_SYMBOL_NOVERS(avalanche_request_pacing); ++EXPORT_SYMBOL_NOVERS(prom_getenv); ++EXPORT_SYMBOL_NOVERS(prom_iterenv); ++#endif ++ +diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c +--- linux.old/arch/mips/kernel/setup.c 2005-10-21 16:43:16.396956500 +0200 ++++ linux.dev/arch/mips/kernel/setup.c 2005-11-10 01:14:16.376732000 +0100 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + struct cpuinfo_mips cpu_data[NR_CPUS]; + EXPORT_SYMBOL(cpu_data); +@@ -88,7 +89,7 @@ + struct boot_mem_map boot_mem_map; + + unsigned char aux_device_present; +-extern char _ftext, _etext, _fdata, _edata, _end; ++extern char _ftext, _etext, _fdata, _edata, _fbss, _end; + + static char command_line[CL_SIZE]; + char saved_command_line[CL_SIZE]; +@@ -116,6 +117,7 @@ + + static struct resource code_resource = { "Kernel code" }; + static struct resource data_resource = { "Kernel data" }; ++static struct resource bss_resource = { "Kernel bss" }; + + asmlinkage void __init + init_arch(int argc, char **argv, char **envp, int *prom_vec) +@@ -272,7 +274,7 @@ + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long start, end; + +- if (boot_mem_map.map[i].type != BOOT_MEM_RAM) ++ if (boot_mem_map.map[i].type == BOOT_MEM_RESERVED) + continue; + + start = PFN_UP(boot_mem_map.map[i].addr); +@@ -320,7 +322,8 @@ + #endif + + /* Initialize the boot-time allocator with low memory only. */ +- bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); ++ bootmap_size = init_bootmem_node(NODE_DATA(0), first_usable_pfn, ++ PFN_UP(PHYS_OFFSET), max_low_pfn); + + /* + * Register fully available low RAM pages with the bootmem allocator. +@@ -371,11 +374,12 @@ + continue; + + /* Register lowmem ranges */ +- free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); ++ free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn), ++ size< 0x0fffffff) { /* maximum for single J instruction */ ++ /* lui k0, 0x0000 */ ++ *(volatile u32 *)(KSEG0+0x200) = 0x3c1a0000 | (handler >> 16); ++ /* ori k0, 0x0000 */ ++ *(volatile u32 *)(KSEG0+0x204) = 0x375a0000 | (handler & 0xffff); ++ /* jr k0 */ ++ *(volatile u32 *)(KSEG0+0x208) = 0x03400008; ++ /* nop */ ++ *(volatile u32 *)(KSEG0+0x20C) = 0x00000000; ++ flush_icache_range(KSEG0+0x200, KSEG0+0x210); ++ } else { + *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | + (0x03ffffff & (handler >> 2)); +- flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); ++ flush_icache_range(KSEG0+0x200, KSEG0+0x204); ++ } + } + return (void *)old_handler; + } +diff -urN linux.old/arch/mips/mm/init.c linux.dev/arch/mips/mm/init.c +--- linux.old/arch/mips/mm/init.c 2004-02-18 14:36:30.000000000 +0100 ++++ linux.dev/arch/mips/mm/init.c 2005-11-10 01:14:16.376732000 +0100 +@@ -235,10 +235,13 @@ + #endif + } + ++#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT) ++#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn) ++ + void __init paging_init(void) + { + unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; +- unsigned long max_dma, high, low; ++ unsigned long max_dma, high, low, start; + + pagetable_init(); + +@@ -247,7 +250,8 @@ + #endif + + max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; +- low = max_low_pfn; ++ start = START_PFN; ++ low = MAX_LOW_PFN - start; + high = highend_pfn; + + #ifdef CONFIG_ISA +@@ -270,7 +274,8 @@ + zones_size[ZONE_HIGHMEM] = high - low; + #endif + +- free_area_init(zones_size); ++ free_area_init_node(0, NODE_DATA(0), 0, zones_size, ++ start << PAGE_SHIFT, 0); + } + + #define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +@@ -283,7 +288,7 @@ + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long addr, end; + +- if (boot_mem_map.map[i].type != BOOT_MEM_RAM) ++ if (boot_mem_map.map[i].type == BOOT_MEM_RESERVED) + /* not usable memory */ + continue; + +@@ -313,16 +318,17 @@ + max_mapnr = num_physpages = highend_pfn; + num_mappedpages = max_low_pfn; + #else +- max_mapnr = num_mappedpages = num_physpages = max_low_pfn; ++ max_mapnr = num_mappedpages = num_physpages = MAX_LOW_PFN - START_PFN; + #endif +- high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); +- +- totalram_pages += free_all_bootmem(); ++ ++ high_memory = (void *) __va(MAX_LOW_PFN * PAGE_SIZE); ++ ++ totalram_pages += free_all_bootmem_node(NODE_DATA(0)); + totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ + + reservedpages = ram = 0; +- for (tmp = 0; tmp < max_low_pfn; tmp++) +- if (page_is_ram(tmp)) { ++ for (tmp = 0; tmp < max_mapnr; tmp++) ++ if (page_is_ram(START_PFN + tmp)) { + ram++; + if (PageReserved(mem_map+tmp)) + reservedpages++; +@@ -377,13 +383,13 @@ + #endif + + extern char __init_begin, __init_end; +-extern void prom_free_prom_memory(void) __init; ++extern unsigned long prom_free_prom_memory(void) __init; + + void free_initmem(void) + { + unsigned long addr; + +- prom_free_prom_memory (); ++ totalram_pages += prom_free_prom_memory (); + + addr = (unsigned long) &__init_begin; + while (addr < (unsigned long) &__init_end) { +diff -urN linux.old/drivers/char/Config.in linux.dev/drivers/char/Config.in +--- linux.old/drivers/char/Config.in 2005-10-21 16:43:16.440959250 +0200 ++++ linux.dev/drivers/char/Config.in 2005-11-10 01:10:45.843574500 +0100 +@@ -188,6 +188,14 @@ + tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL + fi + ++if [ "$CONFIG_AR7" = "y" ]; then ++ bool 'VLYNQ support for the TI SOC' CONFIG_AR7_VLYNQ ++ dep_bool 'VLYNQ clock source Internal' CONFIG_VLYNQ_CLK_LOCAL $CONFIG_AR7_VLYNQ ++ ++ define_int CONFIG_AR7_VLYNQ_PORTS 2 ++ tristate 'ADAM2 environment support (read-only)' CONFIG_AR7_ADAM2 ++fi ++ + source drivers/i2c/Config.in + + mainmenu_option next_comment +diff -urN linux.old/drivers/char/Config.in.orig linux.dev/drivers/char/Config.in.orig +--- linux.old/drivers/char/Config.in.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/Config.in.orig 2005-11-10 01:10:45.863575750 +0100 +@@ -0,0 +1,414 @@ ++# ++# Character device configuration ++# ++mainmenu_option next_comment ++comment 'Character devices' ++ ++bool 'Virtual terminal' CONFIG_VT ++if [ "$CONFIG_VT" = "y" ]; then ++ bool ' Support for console on virtual terminal' CONFIG_VT_CONSOLE ++ if [ "$CONFIG_GSC_LASI" = "y" ]; then ++ bool ' Support for Lasi/Dino PS2 port' CONFIG_GSC_PS2 ++ fi ++fi ++tristate 'Standard/generic (8250/16550 and compatible UARTs) serial support' CONFIG_SERIAL ++if [ "$CONFIG_SERIAL" = "y" ]; then ++ bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE ++ if [ "$CONFIG_GSC_LASI" = "y" ]; then ++ bool ' serial port on GSC support' CONFIG_SERIAL_GSC ++ fi ++ if [ "$CONFIG_IA64" = "y" ]; then ++ bool ' Support for serial port described by EFI HCDP table' CONFIG_SERIAL_HCDP ++ fi ++ if [ "$CONFIG_ARCH_ACORN" = "y" ]; then ++ tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL ++ tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL ++ fi ++fi ++dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL ++if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then ++ bool ' Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS ++ bool ' Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ ++ bool ' Autodetect IRQ on standard ports (unsafe)' CONFIG_SERIAL_DETECT_IRQ ++ bool ' Support special multiport boards' CONFIG_SERIAL_MULTIPORT ++ bool ' Support the Bell Technologies HUB6 card' CONFIG_HUB6 ++fi ++bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD ++if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then ++ tristate ' Computone IntelliPort Plus serial support' CONFIG_COMPUTONE ++ tristate ' Comtrol Rocketport support' CONFIG_ROCKETPORT ++ tristate ' Cyclades async mux support' CONFIG_CYCLADES ++ if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_CYCLADES" != "n" ]; then ++ bool ' Cyclades-Z interrupt mode operation (EXPERIMENTAL)' CONFIG_CYZ_INTR ++ fi ++ if [ "$CONFIG_X86_64" != "y" ]; then ++ tristate ' Digiboard Intelligent Async Support' CONFIG_DIGIEPCA ++ if [ "$CONFIG_DIGIEPCA" = "n" ]; then ++ tristate ' Digiboard PC/Xx Support' CONFIG_DIGI ++ fi ++ fi ++ dep_tristate ' Hayes ESP serial port support' CONFIG_ESPSERIAL $CONFIG_ISA ++ tristate ' Moxa Intellio support' CONFIG_MOXA_INTELLIO ++ tristate ' Moxa SmartIO support' CONFIG_MOXA_SMARTIO ++ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then ++ dep_tristate ' Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m ++ fi ++ tristate ' Microgate SyncLink card support' CONFIG_SYNCLINK ++ tristate ' SyncLink Multiport support' CONFIG_SYNCLINKMP ++ tristate ' HDLC line discipline support' CONFIG_N_HDLC ++ tristate ' SDL RISCom/8 card support' CONFIG_RISCOM8 ++ if [ "$CONFIG_X86_64" != "y" ]; then ++ tristate ' Specialix IO8+ card support' CONFIG_SPECIALIX ++ if [ "$CONFIG_SPECIALIX" != "n" ]; then ++ bool ' Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS ++ fi ++ tristate ' Specialix SX (and SI) card support' CONFIG_SX ++ tristate ' Specialix RIO system support' CONFIG_RIO ++ if [ "$CONFIG_RIO" != "n" ]; then ++ bool ' Support really old RIO/PCI cards' CONFIG_RIO_OLDPCI ++ fi ++ fi ++ bool ' Stallion multiport serial support' CONFIG_STALDRV ++ if [ "$CONFIG_STALDRV" = "y" ]; then ++ tristate ' Stallion EasyIO or EC8/32 support' CONFIG_STALLION ++ tristate ' Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION ++ fi ++ if [ "$CONFIG_PARISC" = "y" ]; then ++ if [ "$CONFIG_PDC_CONSOLE" != "y" ]; then ++ bool ' Serial MUX support' CONFIG_SERIAL_MUX CONFIG_SERIAL_NONSTANDARD ++ fi ++ if [ "$CONFIG_SERIAL_MUX" != "y" ]; then ++ bool ' PDC software console support' CONFIG_PDC_CONSOLE CONFIG_SERIAL_NONSTANDARD ++ fi ++ fi ++ if [ "$CONFIG_MIPS" = "y" ]; then ++ bool ' TX3912/PR31700 serial port support' CONFIG_SERIAL_TX3912 ++ dep_bool ' Console on TX3912/PR31700 serial port' CONFIG_SERIAL_TX3912_CONSOLE $CONFIG_SERIAL_TX3912 ++ bool ' TMPTX39XX/49XX serial port support' CONFIG_SERIAL_TXX9 ++ dep_bool ' Console on TMPTX39XX/49XX serial port' CONFIG_SERIAL_TXX9_CONSOLE $CONFIG_SERIAL_TXX9 ++ if [ "$CONFIG_SOC_AU1X00" = "y" ]; then ++ bool ' Enable Au1x00 UART Support' CONFIG_AU1X00_UART ++ if [ "$CONFIG_AU1X00_UART" = "y" ]; then ++ bool ' Enable Au1x00 serial console' CONFIG_AU1X00_SERIAL_CONSOLE ++ fi ++ dep_tristate ' Au1x00 USB TTY Device support' CONFIG_AU1X00_USB_TTY $CONFIG_SOC_AU1X00 ++ if [ "$CONFIG_AU1000_USB_TTY" != "y" ]; then ++ dep_tristate ' Au1x00 USB Raw Device support' CONFIG_AU1X00_USB_RAW $CONFIG_SOC_AU1X00 ++ fi ++ if [ "$CONFIG_AU1X00_USB_TTY" != "n" -o \ ++ "$CONFIG_AU1X00_USB_RAW" != "n" ]; then ++ define_bool CONFIG_AU1X00_USB_DEVICE y ++ fi ++ fi ++ bool ' TXx927 SIO support' CONFIG_TXX927_SERIAL ++ if [ "$CONFIG_TXX927_SERIAL" = "y" ]; then ++ bool ' TXx927 SIO Console support' CONFIG_TXX927_SERIAL_CONSOLE ++ fi ++ if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then ++ bool ' Support for BCM1xxx onchip DUART' CONFIG_SIBYTE_SB1250_DUART ++ if [ "$CONFIG_SIBYTE_SB1250_DUART" = "y" ]; then ++ bool ' Console on BCM1xxx DUART' CONFIG_SIBYTE_SB1250_DUART_CONSOLE ++ if [ "$CONFIG_SIBYTE_SB1250_DUART_CONSOLE" = "y" ]; then ++ define_bool CONFIG_SERIAL_CONSOLE y ++ fi ++ fi ++ fi ++ fi ++ if [ "$CONFIG_DECSTATION" = "y" ]; then ++ bool ' DECstation serial support' CONFIG_SERIAL_DEC ++ dep_bool ' Support for console on a DECstation serial port' CONFIG_SERIAL_DEC_CONSOLE $CONFIG_SERIAL_DEC ++ dep_bool ' DZ11 serial support' CONFIG_DZ $CONFIG_SERIAL_DEC $CONFIG_MIPS32 ++ dep_bool ' Z85C30 serial support' CONFIG_ZS $CONFIG_SERIAL_DEC $CONFIG_TC ++ fi ++ if [ "$CONFIG_SGI_IP22" = "y" ]; then ++ bool ' SGI Zilog85C30 serial support' CONFIG_IP22_SERIAL ++ fi ++ if [ "$CONFIG_IA64" = "y" ]; then ++ bool ' SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL ++ if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then ++ bool ' SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE ++ fi ++ if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then ++ bool ' SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL ++ fi ++ fi ++fi ++if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then ++ tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232 ++fi ++if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then ++ bool 'DC21285 serial port support' CONFIG_SERIAL_21285 ++ if [ "$CONFIG_SERIAL_21285" = "y" ]; then ++ if [ "$CONFIG_OBSOLETE" = "y" ]; then ++ bool ' Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD ++ fi ++ bool ' Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE ++ fi ++ if [ "$CONFIG_PARISC" = "y" ]; then ++ bool ' PDC software console support' CONFIG_PDC_CONSOLE ++ fi ++fi ++if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then ++ bool 'Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD ++ if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then ++ define_bool CONFIG_IT8172_CIR y ++ else ++ bool ' Enable PS2 Keyboard Support' CONFIG_PC_KEYB ++ fi ++ bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0 ++ bool 'Enable Smart Card Reader 1 Support ' CONFIG_IT8172_SCR1 ++fi ++if [ "$CONFIG_MIPS_IVR" = "y" ]; then ++ bool 'Enable Qtronix 990P Keyboard Support' CONFIG_QTRONIX_KEYBOARD ++ if [ "$CONFIG_QTRONIX_KEYBOARD" = "y" ]; then ++ define_bool CONFIG_IT8172_CIR y ++ fi ++ bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0 ++fi ++if [ "$CONFIG_CPU_VR41XX" = "y" ]; then ++ bool 'NEC VR4100 series Keyboard Interface Unit Support ' CONFIG_VR41XX_KIU ++fi ++bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS ++if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then ++ int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 ++fi ++if [ "$CONFIG_PARPORT" != "n" ]; then ++ dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT ++ if [ "$CONFIG_PRINTER" != "n" ]; then ++ bool ' Support for console on line printer' CONFIG_LP_CONSOLE ++ fi ++ dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT ++ dep_tristate 'Texas Instruments parallel link cable support' CONFIG_TIPAR $CONFIG_PARPORT ++fi ++ ++if [ "$CONFIG_PPC64" = "y" ] ; then ++ bool 'pSeries Hypervisor Virtual Console support' CONFIG_HVC_CONSOLE ++fi ++if [ "$CONFIG_ALL_PPC" = "y" ]; then ++ tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL ++fi ++ ++if [ "$CONFIG_AR7" = "y" ]; then ++ bool 'VLYNQ support for the TI SOC' CONFIG_AR7_VLYNQ ++ dep_bool 'VLYNQ clock source Internal' CONFIG_VLYNQ_CLK_LOCAL $CONFIG_AR7_VLYNQ ++ ++ define_int CONFIG_AR7_VLYNQ_PORTS 2 ++fi ++ ++source drivers/i2c/Config.in ++ ++mainmenu_option next_comment ++comment 'Mice' ++tristate 'Bus Mouse Support' CONFIG_BUSMOUSE ++if [ "$CONFIG_BUSMOUSE" != "n" ]; then ++ dep_tristate ' ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE $CONFIG_BUSMOUSE ++ dep_tristate ' Logitech busmouse support' CONFIG_LOGIBUSMOUSE $CONFIG_BUSMOUSE ++ dep_tristate ' Microsoft busmouse support' CONFIG_MS_BUSMOUSE $CONFIG_BUSMOUSE ++ if [ "$CONFIG_ADB" = "y" -a "$CONFIG_ADB_KEYBOARD" = "y" ]; then ++ dep_tristate ' Apple Desktop Bus mouse support (old driver)' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE ++ fi ++# if [ "$CONFIG_DECSTATION" = "y" ]; then ++# dep_bool ' MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS ++# fi ++fi ++ ++tristate 'Mouse Support (not serial and bus mice)' CONFIG_MOUSE ++if [ "$CONFIG_MOUSE" != "n" ]; then ++ bool ' PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE ++ tristate ' C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE ++ tristate ' PC110 digitizer pad support' CONFIG_PC110_PAD ++ tristate ' MK712 touch screen support' CONFIG_MK712_MOUSE ++fi ++endmenu ++ ++source drivers/char/joystick/Config.in ++ ++tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE ++if [ "$CONFIG_QIC02_TAPE" != "n" ]; then ++ bool ' Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF ++ if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then ++ comment ' Edit configuration parameters in ./include/linux/tpqic02.h!' ++ else ++ comment ' Setting runtime QIC-02 configuration is done with qic02conf' ++ comment ' from the tpqic02-support package. It is available at' ++ comment ' metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/' ++ fi ++fi ++ ++tristate 'IPMI top-level message handler' CONFIG_IPMI_HANDLER ++dep_mbool ' Generate a panic event to all BMCs on a panic' CONFIG_IPMI_PANIC_EVENT $CONFIG_IPMI_HANDLER ++dep_tristate ' Device interface for IPMI' CONFIG_IPMI_DEVICE_INTERFACE $CONFIG_IPMI_HANDLER ++dep_tristate ' IPMI KCS handler' CONFIG_IPMI_KCS $CONFIG_IPMI_HANDLER ++dep_tristate ' IPMI Watchdog Timer' CONFIG_IPMI_WATCHDOG $CONFIG_IPMI_HANDLER ++ ++mainmenu_option next_comment ++comment 'Watchdog Cards' ++bool 'Watchdog Timer Support' CONFIG_WATCHDOG ++if [ "$CONFIG_WATCHDOG" != "n" ]; then ++ bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT ++ tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT ++ tristate ' Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT ++ tristate ' ALi M7101 PMU on ALi 1535D+ Watchdog Timer' CONFIG_ALIM1535_WDT ++ tristate ' ALi M7101 PMU Watchdog Timer' CONFIG_ALIM7101_WDT ++ tristate ' AMD "Elan" SC520 Watchdog Timer' CONFIG_SC520_WDT ++ tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG ++ if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then ++ tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG ++ if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then ++ tristate ' NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG ++ fi ++ fi ++ tristate ' Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT ++ tristate ' IB700 SBC Watchdog Timer' CONFIG_IB700_WDT ++ tristate ' ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT ++ tristate ' Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO ++ tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD ++ tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT ++ dep_tristate ' SC1200 Watchdog Timer (EXPERIMENTAL)' CONFIG_SC1200_WDT $CONFIG_EXPERIMENTAL ++ tristate ' NatSemi SCx200 Watchdog' CONFIG_SCx200_WDT ++ tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG ++ tristate ' W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT ++ tristate ' WDT Watchdog timer' CONFIG_WDT ++ tristate ' WDT PCI Watchdog timer' CONFIG_WDTPCI ++ if [ "$CONFIG_WDT" != "n" ]; then ++ bool ' WDT501 features' CONFIG_WDT_501 ++ if [ "$CONFIG_WDT_501" = "y" ]; then ++ bool ' Fan Tachometer' CONFIG_WDT_501_FAN ++ fi ++ fi ++ tristate ' ZF MachZ Watchdog' CONFIG_MACHZ_WDT ++ if [ "$CONFIG_SGI_IP22" = "y" ]; then ++ dep_tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 ++ fi ++ if [ "$CONFIG_8xx" = "y" ]; then ++ tristate ' MPC8xx Watchdog Timer' CONFIG_8xx_WDT ++ fi ++fi ++endmenu ++ ++if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then ++ tristate 'NetWinder thermometer support' CONFIG_DS1620 ++ tristate 'NetWinder Button' CONFIG_NWBUTTON ++ if [ "$CONFIG_NWBUTTON" != "n" ]; then ++ bool ' Reboot Using Button' CONFIG_NWBUTTON_REBOOT ++ fi ++ tristate 'NetWinder flash support' CONFIG_NWFLASH ++fi ++tristate 'NatSemi SCx200 Support' CONFIG_SCx200 ++dep_tristate ' NatSemi SCx200 GPIO Support' CONFIG_SCx200_GPIO $CONFIG_SCx200 ++ ++if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then ++ bool 'SGI SN2 fetchop support' CONFIG_FETCHOP ++fi ++ ++if [ "$CONFIG_X86" = "y" -o "$CONFIG_X86_64" = "y" ]; then ++ dep_tristate 'AMD 768/8111 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI ++fi ++if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then ++ dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI ++fi ++if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" -o \ ++ "$CONFIG_X86_64" = "y" ]; then ++ dep_tristate 'Intel/AMD/VIA HW Random Number Generator support' CONFIG_HW_RANDOM $CONFIG_PCI ++fi ++dep_tristate 'AMD 76x native power management (Experimental)' CONFIG_AMD_PM768 $CONFIG_PCI ++tristate '/dev/nvram support' CONFIG_NVRAM ++tristate 'Enhanced Real Time Clock Support' CONFIG_RTC ++if [ "$CONFIG_IA64" = "y" ]; then ++ bool 'EFI Real Time Clock Services' CONFIG_EFI_RTC ++fi ++if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then ++ bool 'Tadpole ANA H8 Support (OBSOLETE)' CONFIG_H8 ++fi ++if [ "$CONFIG_SGI_IP22" = "y" ]; then ++ tristate 'Dallas DS1286 RTC support' CONFIG_DS1286 ++fi ++if [ "$CONFIG_SGI_IP27" = "y" ]; then ++ tristate 'SGI M48T35 RTC support' CONFIG_SGI_IP27_RTC ++fi ++if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then ++ tristate 'Dallas DS1742 RTC support' CONFIG_DS1742 ++fi ++ ++tristate 'Double Talk PC internal speech card support' CONFIG_DTLK ++tristate 'Siemens R3964 line discipline' CONFIG_R3964 ++tristate 'Applicom intelligent fieldbus card support' CONFIG_APPLICOM ++if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then ++ dep_tristate 'Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)' CONFIG_SONYPI $CONFIG_PCI ++fi ++ ++mainmenu_option next_comment ++comment 'Ftape, the floppy tape device driver' ++tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE ++if [ "$CONFIG_FTAPE" != "n" ]; then ++ source drivers/char/ftape/Config.in ++fi ++ ++endmenu ++ ++if [ "$CONFIG_GART_IOMMU" = "y" ]; then ++ bool '/dev/agpgart (AGP Support)' CONFIG_AGP ++ define_bool CONFIG_AGP_AMD_K8 y ++else ++ tristate '/dev/agpgart (AGP Support)' CONFIG_AGP ++fi ++if [ "$CONFIG_AGP" != "n" ]; then ++ bool ' Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL ++ bool ' Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810 ++ bool ' VIA chipset support' CONFIG_AGP_VIA ++ bool ' AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD ++ if [ "$CONFIG_GART_IOMMU" != "y" ]; then ++ bool ' AMD Opteron/Athlon64 on-CPU GART support' CONFIG_AGP_AMD_K8 ++ fi ++ bool ' Generic SiS support' CONFIG_AGP_SIS ++ bool ' ALI chipset support' CONFIG_AGP_ALI ++ bool ' Serverworks LE/HE support' CONFIG_AGP_SWORKS ++ if [ "$CONFIG_X86" = "y" ]; then ++ bool ' NVIDIA chipset support' CONFIG_AGP_NVIDIA ++ fi ++ if [ "$CONFIG_IA64" = "y" ]; then ++ bool ' Intel 460GX support' CONFIG_AGP_I460 ++ bool ' HP ZX1 AGP support' CONFIG_AGP_HP_ZX1 ++ fi ++ bool ' ATI IGP chipset support' CONFIG_AGP_ATI ++fi ++ ++mainmenu_option next_comment ++comment 'Direct Rendering Manager (XFree86 DRI support)' ++bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM ++if [ "$CONFIG_DRM" = "y" ]; then ++ bool ' Build drivers for old (XFree 4.0) DRM' CONFIG_DRM_OLD ++ if [ "$CONFIG_DRM_OLD" = "y" ]; then ++ comment 'DRM 4.0 drivers' ++ source drivers/char/drm-4.0/Config.in ++ else ++ comment 'DRM 4.1 drivers' ++ define_bool CONFIG_DRM_NEW y ++ source drivers/char/drm/Config.in ++ fi ++fi ++ ++if [ "$CONFIG_X86" = "y" ]; then ++ tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE ++fi ++ ++endmenu ++ ++if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then ++ source drivers/char/pcmcia/Config.in ++fi ++if [ "$CONFIG_SOC_AU1X00" = "y" ]; then ++ tristate ' Alchemy Au1x00 GPIO device support' CONFIG_AU1X00_GPIO ++ tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1X00_ADS7846 ++ #tristate ' Alchemy Au1550 PSC SPI support' CONFIG_AU1550_PSC_SPI ++fi ++if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then ++ tristate ' ITE GPIO' CONFIG_ITE_GPIO ++fi ++ ++if [ "$CONFIG_X86" = "y" ]; then ++ tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE ++ dep_tristate 'HP OB600 C/CT Pop-up mouse support' CONFIG_OBMOUSE $CONFIG_INPUT_MOUSEDEV ++fi ++ ++endmenu +diff -urN linux.old/drivers/char/Makefile linux.dev/drivers/char/Makefile +--- linux.old/drivers/char/Makefile 2005-10-21 16:43:16.460960500 +0200 ++++ linux.dev/drivers/char/Makefile 2005-11-10 01:10:45.871576250 +0100 +@@ -240,6 +240,13 @@ + obj-y += joystick/js.o + endif + ++# ++# Texas Intruments VLYNQ driver ++# ++ ++subdir-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq ++obj-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq/avalanche_vlynq.o ++ + obj-$(CONFIG_FETCHOP) += fetchop.o + obj-$(CONFIG_BUSMOUSE) += busmouse.o + obj-$(CONFIG_DTLK) += dtlk.o +@@ -340,6 +347,11 @@ + obj-y += ipmi/ipmi.o + endif + ++subdir-$(CONFIG_AR7_ADAM2) += ticfg ++ifeq ($(CONFIG_AR7_ADAM2),y) ++ obj-y += ticfg/ticfg.o ++endif ++ + include $(TOPDIR)/Rules.make + + fastdep: +diff -urN linux.old/drivers/char/Makefile.orig linux.dev/drivers/char/Makefile.orig +--- linux.old/drivers/char/Makefile.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/Makefile.orig 2005-11-10 01:10:45.871576250 +0100 +@@ -0,0 +1,374 @@ ++# ++# Makefile for the kernel character device drivers. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++# Note 2! The CFLAGS definitions are now inherited from the ++# parent makes.. ++# ++ ++# ++# This file contains the font map for the default (hardware) font ++# ++FONTMAPFILE = cp437.uni ++ ++O_TARGET := char.o ++ ++obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o ++ ++# All of the (potential) objects that export symbols. ++# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. ++ ++export-objs := busmouse.o console.o keyboard.o sysrq.o \ ++ misc.o pty.o random.o selection.o serial.o \ ++ sonypi.o tty_io.o tty_ioctl.o generic_serial.o \ ++ au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \ ++ scx200.o fetchop.o ++ ++mod-subdirs := joystick ftape drm drm-4.0 pcmcia ++ ++list-multi := ++ ++KEYMAP =defkeymap.o ++KEYBD =pc_keyb.o ++CONSOLE =console.o ++SERIAL =serial.o ++ ++ifeq ($(ARCH),s390) ++ KEYMAP = ++ KEYBD = ++ CONSOLE = ++ SERIAL = ++endif ++ ++ifeq ($(ARCH),mips) ++ ifneq ($(CONFIG_PC_KEYB),y) ++ KEYBD = ++ endif ++ ifeq ($(CONFIG_VR41XX_KIU),y) ++ ifeq ($(CONFIG_IBM_WORKPAD),y) ++ KEYMAP = ibm_workpad_keymap.o ++ endif ++ ifeq ($(CONFIG_VICTOR_MPC30X),y) ++ KEYMAP = victor_mpc30x_keymap.o ++ endif ++ KEYBD = vr41xx_keyb.o ++ endif ++endif ++ ++ifeq ($(ARCH),s390x) ++ KEYMAP = ++ KEYBD = ++ CONSOLE = ++ SERIAL = ++endif ++ ++ifeq ($(ARCH),m68k) ++ ifdef CONFIG_AMIGA ++ KEYBD = amikeyb.o ++ else ++ ifndef CONFIG_MAC ++ KEYBD = ++ endif ++ endif ++ SERIAL = ++endif ++ ++ifeq ($(ARCH),parisc) ++ ifdef CONFIG_GSC_PS2 ++ KEYBD = hp_psaux.o hp_keyb.o ++ else ++ KEYBD = ++ endif ++ ifdef CONFIG_SERIAL_MUX ++ CONSOLE += mux.o ++ endif ++ ifdef CONFIG_PDC_CONSOLE ++ CONSOLE += pdc_console.o ++ endif ++endif ++ ++ifdef CONFIG_Q40 ++ KEYBD += q40_keyb.o ++ SERIAL = serial.o ++endif ++ ++ifdef CONFIG_APOLLO ++ KEYBD += dn_keyb.o ++endif ++ ++ifeq ($(ARCH),parisc) ++ ifdef CONFIG_GSC_PS2 ++ KEYBD = hp_psaux.o hp_keyb.o ++ else ++ KEYBD = ++ endif ++ ifdef CONFIG_PDC_CONSOLE ++ CONSOLE += pdc_console.o ++ endif ++endif ++ ++ifeq ($(ARCH),arm) ++ ifneq ($(CONFIG_PC_KEYMAP),y) ++ KEYMAP = ++ endif ++ ifneq ($(CONFIG_PC_KEYB),y) ++ KEYBD = ++ endif ++endif ++ ++ifeq ($(ARCH),sh) ++ KEYMAP = ++ KEYBD = ++ CONSOLE = ++ ifeq ($(CONFIG_SH_HP600),y) ++ KEYMAP = defkeymap.o ++ KEYBD = scan_keyb.o hp600_keyb.o ++ CONSOLE = console.o ++ endif ++ ifeq ($(CONFIG_SH_DMIDA),y) ++ # DMIDA does not connect the HD64465 PS/2 keyboard port ++ # but we allow for USB keyboards to be plugged in. ++ KEYMAP = defkeymap.o ++ KEYBD = # hd64465_keyb.o pc_keyb.o ++ CONSOLE = console.o ++ endif ++ ifeq ($(CONFIG_SH_EC3104),y) ++ KEYMAP = defkeymap.o ++ KEYBD = ec3104_keyb.o ++ CONSOLE = console.o ++ endif ++ ifeq ($(CONFIG_SH_DREAMCAST),y) ++ KEYMAP = defkeymap.o ++ KEYBD = ++ CONSOLE = console.o ++ endif ++endif ++ ++ifeq ($(CONFIG_DECSTATION),y) ++ KEYMAP = ++ KEYBD = ++endif ++ ++ifeq ($(CONFIG_BAGET_MIPS),y) ++ KEYBD = ++ SERIAL = vac-serial.o ++endif ++ ++ifeq ($(CONFIG_NINO),y) ++ SERIAL = ++endif ++ ++ifneq ($(CONFIG_SUN_SERIAL),) ++ SERIAL = ++endif ++ ++ifeq ($(CONFIG_QTRONIX_KEYBOARD),y) ++ KEYBD = qtronix.o ++ KEYMAP = qtronixmap.o ++endif ++ ++ifeq ($(CONFIG_DUMMY_KEYB),y) ++ KEYBD = dummy_keyb.o ++endif ++ ++obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o ++obj-$(CONFIG_SERIAL) += $(SERIAL) ++obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o ++obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o ++obj-$(CONFIG_SERIAL_21285) += serial_21285.o ++obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o ++obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o ++obj-$(CONFIG_TS_AU1X00_ADS7846) += au1000_ts.o ++obj-$(CONFIG_SERIAL_DEC) += decserial.o ++ ++ifndef CONFIG_SUN_KEYBOARD ++ obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD) ++else ++ obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP) ++endif ++ ++obj-$(CONFIG_HIL) += hp_keyb.o ++obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o ++obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o ++obj-$(CONFIG_ROCKETPORT) += rocket.o ++obj-$(CONFIG_MOXA_SMARTIO) += mxser.o ++obj-$(CONFIG_MOXA_INTELLIO) += moxa.o ++obj-$(CONFIG_DIGI) += pcxx.o ++obj-$(CONFIG_DIGIEPCA) += epca.o ++obj-$(CONFIG_CYCLADES) += cyclades.o ++obj-$(CONFIG_STALLION) += stallion.o ++obj-$(CONFIG_ISTALLION) += istallion.o ++obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o ++obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o ++obj-$(CONFIG_RISCOM8) += riscom8.o ++obj-$(CONFIG_ISI) += isicom.o ++obj-$(CONFIG_ESPSERIAL) += esp.o ++obj-$(CONFIG_SYNCLINK) += synclink.o ++obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o ++obj-$(CONFIG_N_HDLC) += n_hdlc.o ++obj-$(CONFIG_SPECIALIX) += specialix.o ++obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o ++obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o ++obj-$(CONFIG_SX) += sx.o generic_serial.o ++obj-$(CONFIG_RIO) += rio/rio.o generic_serial.o ++obj-$(CONFIG_SH_SCI) += sh-sci.o generic_serial.o ++obj-$(CONFIG_SERIAL167) += serial167.o ++obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o ++obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o ++obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o ++obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o ++obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o ++obj-$(CONFIG_TXX927_SERIAL) += serial_txx927.o ++obj-$(CONFIG_SERIAL_TXX9) += generic_serial.o serial_txx9.o ++obj-$(CONFIG_IP22_SERIAL) += sgiserial.o ++obj-$(CONFIG_AU1X00_UART) += au1x00-serial.o ++obj-$(CONFIG_SGI_L1_SERIAL) += sn_serial.o ++ ++subdir-$(CONFIG_RIO) += rio ++subdir-$(CONFIG_INPUT) += joystick ++ ++obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o ++obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o ++obj-$(CONFIG_PRINTER) += lp.o ++obj-$(CONFIG_TIPAR) += tipar.o ++obj-$(CONFIG_OBMOUSE) += obmouse.o ++ ++ifeq ($(CONFIG_INPUT),y) ++obj-y += joystick/js.o ++endif ++ ++# ++# Texas Intruments VLYNQ driver ++# ++ ++subdir-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq ++obj-$(CONFIG_AR7_VLYNQ) += avalanche_vlynq/avalanche_vlynq.o ++ ++obj-$(CONFIG_FETCHOP) += fetchop.o ++obj-$(CONFIG_BUSMOUSE) += busmouse.o ++obj-$(CONFIG_DTLK) += dtlk.o ++obj-$(CONFIG_R3964) += n_r3964.o ++obj-$(CONFIG_APPLICOM) += applicom.o ++obj-$(CONFIG_SONYPI) += sonypi.o ++obj-$(CONFIG_MS_BUSMOUSE) += msbusmouse.o ++obj-$(CONFIG_82C710_MOUSE) += qpmouse.o ++obj-$(CONFIG_AMIGAMOUSE) += amigamouse.o ++obj-$(CONFIG_ATARIMOUSE) += atarimouse.o ++obj-$(CONFIG_ADBMOUSE) += adbmouse.o ++obj-$(CONFIG_PC110_PAD) += pc110pad.o ++obj-$(CONFIG_MK712_MOUSE) += mk712.o ++obj-$(CONFIG_RTC) += rtc.o ++obj-$(CONFIG_GEN_RTC) += genrtc.o ++obj-$(CONFIG_EFI_RTC) += efirtc.o ++obj-$(CONFIG_MIPS_RTC) += mips_rtc.o ++obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o ++ifeq ($(CONFIG_PPC),) ++ obj-$(CONFIG_NVRAM) += nvram.o ++endif ++obj-$(CONFIG_TOSHIBA) += toshiba.o ++obj-$(CONFIG_I8K) += i8k.o ++obj-$(CONFIG_DS1286) += ds1286.o ++obj-$(CONFIG_DS1620) += ds1620.o ++obj-$(CONFIG_DS1742) += ds1742.o ++obj-$(CONFIG_INTEL_RNG) += i810_rng.o ++obj-$(CONFIG_AMD_RNG) += amd768_rng.o ++obj-$(CONFIG_HW_RANDOM) += hw_random.o ++obj-$(CONFIG_AMD_PM768) += amd76x_pm.o ++obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o ++ ++obj-$(CONFIG_ITE_GPIO) += ite_gpio.o ++obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o ++obj-$(CONFIG_AU1550_PSC_SPI) += au1550_psc_spi.o ++obj-$(CONFIG_AU1X00_USB_TTY) += au1000_usbtty.o ++obj-$(CONFIG_AU1X00_USB_RAW) += au1000_usbraw.o ++obj-$(CONFIG_COBALT_LCD) += lcd.o ++ ++obj-$(CONFIG_QIC02_TAPE) += tpqic02.o ++ ++subdir-$(CONFIG_FTAPE) += ftape ++subdir-$(CONFIG_DRM_OLD) += drm-4.0 ++subdir-$(CONFIG_DRM_NEW) += drm ++subdir-$(CONFIG_PCMCIA) += pcmcia ++subdir-$(CONFIG_AGP) += agp ++ ++ifeq ($(CONFIG_FTAPE),y) ++obj-y += ftape/ftape.o ++endif ++ ++obj-$(CONFIG_H8) += h8.o ++obj-$(CONFIG_PPDEV) += ppdev.o ++obj-$(CONFIG_DZ) += dz.o ++obj-$(CONFIG_NWBUTTON) += nwbutton.o ++obj-$(CONFIG_NWFLASH) += nwflash.o ++obj-$(CONFIG_SCx200) += scx200.o ++obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o ++ ++# Only one watchdog can succeed. We probe the hardware watchdog ++# drivers first, then the softdog driver. This means if your hardware ++# watchdog dies or is 'borrowed' for some reason the software watchdog ++# still gives you some cover. ++ ++obj-$(CONFIG_PCWATCHDOG) += pcwd.o ++obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o ++obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o ++obj-$(CONFIG_IB700_WDT) += ib700wdt.o ++obj-$(CONFIG_MIXCOMWD) += mixcomwd.o ++obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o ++obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o ++obj-$(CONFIG_SC520_WDT) += sc520_wdt.o ++obj-$(CONFIG_WDT) += wdt.o ++obj-$(CONFIG_WDTPCI) += wdt_pci.o ++obj-$(CONFIG_21285_WATCHDOG) += wdt285.o ++obj-$(CONFIG_977_WATCHDOG) += wdt977.o ++obj-$(CONFIG_I810_TCO) += i810-tco.o ++obj-$(CONFIG_MACHZ_WDT) += machzwd.o ++obj-$(CONFIG_SH_WDT) += shwdt.o ++obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o ++obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o ++obj-$(CONFIG_ALIM1535_WDT) += alim1535d_wdt.o ++obj-$(CONFIG_INDYDOG) += indydog.o ++obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o ++obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o ++obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o ++obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o ++obj-$(CONFIG_INDYDOG) += indydog.o ++obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o ++ ++subdir-$(CONFIG_MWAVE) += mwave ++ifeq ($(CONFIG_MWAVE),y) ++ obj-y += mwave/mwave.o ++endif ++ ++subdir-$(CONFIG_IPMI_HANDLER) += ipmi ++ifeq ($(CONFIG_IPMI_HANDLER),y) ++ obj-y += ipmi/ipmi.o ++endif ++ ++include $(TOPDIR)/Rules.make ++ ++fastdep: ++ ++conmakehash: conmakehash.c ++ $(HOSTCC) $(HOSTCFLAGS) -o conmakehash conmakehash.c ++ ++consolemap_deftbl.c: $(FONTMAPFILE) conmakehash ++ ./conmakehash $(FONTMAPFILE) > consolemap_deftbl.c ++ ++consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h ++ ++.DELETE_ON_ERROR: ++ ++defkeymap.c: defkeymap.map ++ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ ++ ++qtronixmap.c: qtronixmap.map ++ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ ++ ++ibm_workpad_keymap.c: ibm_workpad_keymap.map ++ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ ++ ++victor_mpc30x_keymap.c: victor_mpc30x_keymap.map ++ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ +diff -urN linux.old/drivers/char/avalanche_vlynq/Makefile linux.dev/drivers/char/avalanche_vlynq/Makefile +--- linux.old/drivers/char/avalanche_vlynq/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/avalanche_vlynq/Makefile 2005-11-10 01:10:45.871576250 +0100 +@@ -0,0 +1,16 @@ ++# ++# Makefile for the linux kernel. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++# Note 2! The CFLAGS definitions are now in the main makefile... ++ ++O_TARGET := avalanche_vlynq.o ++ ++export-objs := vlynq_board.o ++ ++obj-y += vlynq_drv.o vlynq_hal.o vlynq_board.o ++ ++include $(TOPDIR)/Rules.make +diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_board.c linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c +--- linux.old/drivers/char/avalanche_vlynq/vlynq_board.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c 2005-11-10 01:10:45.871576250 +0100 +@@ -0,0 +1,184 @@ ++/* ++ * Jeff Harrell, jharrell@ti.com ++ * Copyright (C) 2001 Texas Instruments, Inc. All rights reserved. ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * Texas Instruments Sangam specific setup. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#define SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR 30 /* MSB - 1 bit */ ++#define SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR 31 /* MSB bit */ ++#define SYS_VLYNQ_OPTIONS 0x7F; /* all options*/ ++ ++/* These defines are board specific */ ++ ++ ++#define VLYNQ0_REMOTE_WINDOW1_OFFSET (0x0C000000) ++#define VLYNQ0_REMOTE_WINDOW1_SIZE (0x500) ++ ++ ++#define VLYNQ1_REMOTE_WINDOW1_OFFSET (0x0C000000) ++#define VLYNQ1_REMOTE_WINDOW1_SIZE (0x500) ++ ++ ++extern VLYNQ_DEV vlynqDevice0, vlynqDevice1; ++int vlynq_init_status[2] = {0, 0}; ++EXPORT_SYMBOL(vlynq_init_status); ++static int reset_hack = 1; ++ ++void vlynq_ar7wrd_dev_init() ++{ ++ *(unsigned long*) AVALANCHE_GPIO_ENBL |= (1<<18); ++ vlynq_delay(20000); ++ *(unsigned long*) AVALANCHE_GPIO_DIR &= ~(1<<18); ++ vlynq_delay(20000); ++ *(unsigned long*) AVALANCHE_GPIO_DATA_OUT&= ~(1<<18); ++ vlynq_delay(50000); ++ *(unsigned long*) AVALANCHE_GPIO_DATA_OUT|= (1<<18); ++ vlynq_delay(50000); ++ ++ /* Initialize the MIPS host vlynq driver for a given vlynq interface */ ++ vlynqDevice0.dev_idx = 0; /* first vlynq module - this parameter is for reference only */ ++ vlynqDevice0.module_base = AVALANCHE_LOW_VLYNQ_CONTROL_BASE; /* vlynq0 module base address */ ++ ++#if defined(CONFIG_VLYNQ_CLK_LOCAL) ++ vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_LOCAL; ++#else ++ vlynqDevice0.clk_source = VLYNQ_CLK_SOURCE_REMOTE; ++#endif ++ vlynqDevice0.clk_div = 0x01; /* board/hardware specific */ ++ vlynqDevice0.state = VLYNQ_DRV_STATE_UNINIT; /* uninitialized module */ ++ ++ /* Populate vlynqDevice0.local_mem & Vlynq0.remote_mem based on system configuration */ ++ /*Local memory configuration */ ++ ++ /* Demiurg : not good !*/ ++#if 0 ++ vlynqDevice0.local_mem.Txmap= AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE & ~(0xc0000000) ; /* physical address */ ++ vlynqDevice0.remote_mem.RxOffset[0]= VLYNQ0_REMOTE_WINDOW1_OFFSET; /* This is specific to the board on the other end */ ++ vlynqDevice0.remote_mem.RxSize[0]=VLYNQ0_REMOTE_WINDOW1_SIZE; ++#endif ++ ++ /* Demiurg : This is how it should be ! */ ++ vlynqDevice0.local_mem.Txmap = PHYSADDR(AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE); ++#define VLYNQ_ACX111_MEM_OFFSET 0xC0000000 /* Physical address of ACX111 memory */ ++#define VLYNQ_ACX111_MEM_SIZE 0x00040000 /* Total size of the ACX111 memory */ ++#define VLYNQ_ACX111_REG_OFFSET 0xF0000000 /* PHYS_ADDR of ACX111 control registers */ ++#define VLYNQ_ACX111_REG_SIZE 0x00022000 /* Size of ACX111 registers area, MAC+PHY */ ++#define ACX111_VL1_REMOTE_SIZE 0x1000000 ++ vlynqDevice0.remote_mem.RxOffset[0] = VLYNQ_ACX111_MEM_OFFSET; ++ vlynqDevice0.remote_mem.RxSize[0] = VLYNQ_ACX111_MEM_SIZE ; ++ vlynqDevice0.remote_mem.RxOffset[1] = VLYNQ_ACX111_REG_OFFSET; ++ vlynqDevice0.remote_mem.RxSize[1] = VLYNQ_ACX111_REG_SIZE ; ++ vlynqDevice0.remote_mem.Txmap = 0; ++ vlynqDevice0.local_mem.RxOffset[0] = AVALANCHE_SDRAM_BASE; ++ vlynqDevice0.local_mem.RxSize[0] = ACX111_VL1_REMOTE_SIZE; ++ ++ ++ /* Local interrupt configuration */ ++ vlynqDevice0.local_irq.intLocal = VLYNQ_INT_LOCAL; /* Host handles vlynq interrupts*/ ++ vlynqDevice0.local_irq.intRemote = VLYNQ_INT_ROOT_ISR; /* vlynq root isr used */ ++ vlynqDevice0.local_irq.map_vector = SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR; ++ vlynqDevice0.local_irq.intr_ptr = 0; /* Since remote interrupts part of vlynq root isr this is unused */ ++ ++ /* Remote interrupt configuration */ ++ vlynqDevice0.remote_irq.intLocal = VLYNQ_INT_REMOTE; /* MIPS handles interrupts */ ++ vlynqDevice0.remote_irq.intRemote = VLYNQ_INT_ROOT_ISR; /* Not significant since MIPS handles interrupts */ ++ vlynqDevice0.remote_irq.map_vector = SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR; ++ vlynqDevice0. remote_irq.intr_ptr = AVALANCHE_INTC_BASE; /* Not significant since MIPS handles interrupts */ ++ ++ if(reset_hack != 1) ++ printk("About to re-init the VLYNQ.\n"); ++ ++ if(vlynq_init(&vlynqDevice0,VLYNQ_INIT_PERFORM_ALL)== 0) ++ { ++ /* Suraj added the following to keep the 1130 going. */ ++ vlynq_interrupt_vector_set(&vlynqDevice0, 0 /* intr vector line running into 1130 vlynq */, ++ 0 /* intr mapped onto the interrupt register on remote vlynq and this vlynq */, ++ VLYNQ_REMOTE_DVC, 0 /* polarity active high */, 0 /* interrupt Level triggered */); ++ ++ /* System wide interrupt is 80 for 1130, please note. */ ++ vlynq_init_status[0] = 1; ++ reset_hack = 2; ++ } ++ else ++ { ++ if(reset_hack == 1) ++ printk("VLYNQ INIT FAILED: Please try cold reboot. \n"); ++ else ++ printk("Failed to initialize the VLYNQ interface at insmod.\n"); ++ ++ } ++} ++ ++void vlynq_dev_init(void) ++{ ++ volatile unsigned int *reset_base = (unsigned int *) AVALANCHE_RESET_CONTROL_BASE; ++ ++ *reset_base &= ~((1 << AVALANCHE_LOW_VLYNQ_RESET_BIT)); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT)); */ ++ ++ vlynq_delay(20000); ++ ++ /* Bring vlynq out of reset if not already done */ ++ *reset_base |= (1 << AVALANCHE_LOW_VLYNQ_RESET_BIT); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT); */ ++ vlynq_delay(20000); /* Allowing sufficient time to VLYNQ to settle down.*/ ++ ++ vlynq_ar7wrd_dev_init( ); ++ ++} ++ ++/* This function is board specific and should be ported for each board. */ ++void remote_vlynq_dev_reset_ctrl(unsigned int module_reset_bit, ++ AVALANCHE_RESET_CTRL_T reset_ctrl) ++{ ++ if(module_reset_bit >= 32) ++ return; ++ ++ switch(module_reset_bit) ++ { ++ case 0: ++ if(OUT_OF_RESET == reset_ctrl) ++ { ++ if(reset_hack) return; ++ ++ vlynq_delay(20000); ++ printk("Un-resetting the remote device.\n"); ++ vlynq_dev_init(); ++ printk("Re-initialized the VLYNQ.\n"); ++ reset_hack = 2; ++ } ++ else if(IN_RESET == reset_ctrl) ++ { ++ *(unsigned long*) AVALANCHE_GPIO_DATA_OUT &= ~(1<<18); ++ ++ vlynq_delay(20000); ++ printk("Resetting the remote device.\n"); ++ reset_hack = 0; ++ } ++ else ++ ; ++ break; ++ ++ default: ++ break; ++ ++ } ++} ++ +diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c +--- linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c 2005-11-10 01:10:45.891577500 +0100 +@@ -0,0 +1,243 @@ ++/****************************************************************************** ++ * FILE PURPOSE: Vlynq Linux Device Driver Source ++ ****************************************************************************** ++ * FILE NAME: vlynq_drv.c ++ * ++ * DESCRIPTION: Vlynq Linux Device Driver Source ++ * ++ * REVISION HISTORY: ++ * ++ * Date Description Author ++ *----------------------------------------------------------------------------- ++ * 17 July 2003 Initial Creation Anant Gole ++ * 17 Dec 2003 Updates Sharath Kumar ++ * ++ * (C) Copyright 2003, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define TI_VLYNQ_VERSION "0.2" ++ ++/* debug on ? */ ++#define VLYNQ_DEBUG ++ ++/* Macro for debug and error printf's */ ++#ifdef VLYNQ_DEBUG ++#define DBGPRINT printk ++#else ++#define DBGPRINT(x) ++#endif ++ ++#define ERRPRINT printk ++ ++/* Define the max vlynq ports this driver will support. ++ Device name strings are statically added here */ ++#define MAX_VLYNQ_PORTS 2 ++ ++ ++/* Type define for VLYNQ private structure */ ++typedef struct vlynqPriv{ ++ int irq; ++ VLYNQ_DEV *vlynqDevice; ++}VLYNQ_PRIV; ++ ++extern int vlynq_init_status[2]; ++ ++/* Extern Global variable for vlynq devices used in initialization of the vlynq device ++ * These variables need to be populated/initialized by the system as part of initialization ++ * process. The vlynq enumerator can run at initialization and populate these globals ++ */ ++ ++VLYNQ_DEV vlynqDevice0; ++VLYNQ_DEV vlynqDevice1; ++ ++/* Defining dummy macro AVALANCHE_HIGH_VLYNQ_INT to take ++ * care of compilation in case of single vlynq device ++ */ ++ ++#ifndef AVALANCHE_HIGH_VLYNQ_INT ++#define AVALANCHE_HIGH_VLYNQ_INT 0 ++#endif ++ ++ ++ ++/* vlynq private object */ ++VLYNQ_PRIV vlynq_priv[CONFIG_AR7_VLYNQ_PORTS] = { ++ { LNXINTNUM(AVALANCHE_LOW_VLYNQ_INT),&vlynqDevice0}, ++ { LNXINTNUM(AVALANCHE_HIGH_VLYNQ_INT),&vlynqDevice1}, ++}; ++ ++extern void vlynq_dev_init(void); ++ ++ ++/* =================================== all the operations */ ++ ++static int ++vlynq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ return 0; ++} ++ ++static struct file_operations vlynq_fops = { ++ owner: THIS_MODULE, ++ ioctl: vlynq_ioctl, ++}; ++ ++/* Vlynq device object */ ++static struct miscdevice vlynq_dev [MAX_VLYNQ_PORTS] = { ++ { MISC_DYNAMIC_MINOR , "vlynq0", &vlynq_fops }, ++ { MISC_DYNAMIC_MINOR , "vlynq1", &vlynq_fops }, ++}; ++ ++ ++/* Proc read function */ ++static int ++vlynq_read_link_proc(char *buf, char **start, off_t offset, int count, int *eof, void *unused) ++{ ++ int instance; ++ int len = 0; ++ ++ len += sprintf(buf +len,"VLYNQ Devices : %d\n",CONFIG_AR7_VLYNQ_PORTS); ++ ++ for(instance =0;instance < CONFIG_AR7_VLYNQ_PORTS;instance++) ++ { ++ int link_state; ++ char *link_msg[] = {" DOWN "," UP "}; ++ ++ if(vlynq_init_status[instance] == 0) ++ link_state = 0; ++ ++ else if (vlynq_link_check(vlynq_priv[instance].vlynqDevice)) ++ link_state = 1; ++ ++ else ++ link_state = 0; ++ ++ len += sprintf(buf + len, "VLYNQ %d: Link state: %s\n",instance,link_msg[link_state]); ++ ++ } ++ /* Print info about vlynq device 1 */ ++ ++ return len; ++} ++ ++ ++/* Proc function to display driver version */ ++static int ++vlynq_read_ver_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) ++{ ++ int instance; ++ int len=0; ++ ++ len += sprintf(buf +len,"\nTI Linux VLYNQ Driver Version %s\n",TI_VLYNQ_VERSION); ++ return len; ++} ++ ++ ++ ++ ++/* Wrapper for vlynq ISR */ ++static void lnx_vlynq_root_isr(int irq, void * arg, struct pt_regs *regs) ++{ ++ vlynq_root_isr(arg); ++} ++ ++/* =================================== init and cleanup */ ++ ++int vlynq_init_module(void) ++{ ++ int ret; ++ int unit = 0; ++ int instance_count = CONFIG_AR7_VLYNQ_PORTS; ++ volatile int *ptr; ++ ++ vlynq_dev_init(); ++ ++ DBGPRINT("Vlynq CONFIG_AR7_VLYNQ_PORTS=%d\n", CONFIG_AR7_VLYNQ_PORTS); ++ /* If num of configured vlynq ports > supported by driver return error */ ++ if (instance_count > MAX_VLYNQ_PORTS) ++ { ++ ERRPRINT("ERROR: vlynq_init_module(): Max %d supported\n", MAX_VLYNQ_PORTS); ++ return (-1); ++ } ++ ++ /* register the misc device */ ++ for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++) ++ { ++ ret = misc_register(&vlynq_dev[unit]); ++ ++ if(ret < 0) ++ { ++ ERRPRINT("ERROR:Could not register vlynq device:%d\n",unit); ++ continue; ++ } ++ else ++ DBGPRINT("Vlynq Device %s registered with minor no %d as misc device. Result=%d\n", ++ vlynq_dev[unit].name, vlynq_dev[unit].minor, ret); ++#if 0 ++ ++ DBGPRINT("Calling vlynq init\n"); ++ ++ /* Read the global variable for VLYNQ device structure and initialize vlynq driver */ ++ ret = vlynq_init(vlynq_priv[unit].vlynqDevice,VLYNQ_INIT_PERFORM_ALL ); ++#endif ++ ++ if(vlynq_init_status[unit] == 0) ++ { ++ printk("VLYNQ %d : init failed\n",unit); ++ continue; ++ } ++ ++ /* Check link before proceeding */ ++ if (!vlynq_link_check(vlynq_priv[unit].vlynqDevice)) ++ { ++ DBGPRINT("\nError: Vlynq link not available.trying once before Exiting"); ++ } ++ else ++ { ++ DBGPRINT("Vlynq instance:%d Link UP\n",unit); ++ ++ /* Install the vlynq local root ISR */ ++ request_irq(vlynq_priv[unit].irq,lnx_vlynq_root_isr,0,vlynq_dev[unit].name,vlynq_priv[unit].vlynqDevice); ++ } ++ } ++ ++ proc_mkdir("avalanche", NULL); ++ /* Creating proc entry for the devices */ ++ create_proc_read_entry("avalanche/vlynq_link", 0, NULL, vlynq_read_link_proc, NULL); ++ create_proc_read_entry("avalanche/vlynq_ver", 0, NULL, vlynq_read_ver_proc, NULL); ++ ++ return 0; ++} ++ ++void vlynq_cleanup_module(void) ++{ ++ int unit = 0; ++ ++ for (unit = 0; unit < CONFIG_AR7_VLYNQ_PORTS; unit++) ++ { ++ DBGPRINT("vlynq_cleanup_module(): Unregistring misc device %s\n",vlynq_dev[unit].name); ++ misc_deregister(&vlynq_dev[unit]); ++ } ++ ++ remove_proc_entry("avalanche/vlynq_link", NULL); ++ remove_proc_entry("avalanche/vlynq_ver", NULL); ++} ++ ++ ++module_init(vlynq_init_module); ++module_exit(vlynq_cleanup_module); ++ +diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c +--- linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c 2005-11-10 01:10:45.975582750 +0100 +@@ -0,0 +1,1214 @@ ++/*************************************************************************** ++**+----------------------------------------------------------------------+** ++**| **** |** ++**| **** |** ++**| ******o*** |** ++**| ********_///_**** |** ++**| ***** /_//_/ **** |** ++**| ** ** (__/ **** |** ++**| ********* |** ++**| **** |** ++**| *** |** ++**| |** ++**| Copyright (c) 2003 Texas Instruments Incorporated |** ++**| ALL RIGHTS RESERVED |** ++**| |** ++**| Permission is hereby granted to licensees of Texas Instruments |** ++**| Incorporated (TI) products to use this computer program for the sole |** ++**| purpose of implementing a licensee product based on TI products. |** ++**| No other rights to reproduce, use, or disseminate this computer |** ++**| program, whether in part or in whole, are granted. |** ++**| |** ++**| TI makes no representation or warranties with respect to the |** ++**| performance of this computer program, and specifically disclaims |** ++**| any responsibility for any damages, special or consequential, |** ++**| connected with the use of this program. |** ++**| |** ++**+----------------------------------------------------------------------+** ++***************************************************************************/ ++ ++/*************************************************************************** ++ * ------------------------------------------------------------------------------ ++ * Module : vlynq_hal.c ++ * Description : This file implements VLYNQ HAL API. ++ * ------------------------------------------------------------------------------ ++ ***************************************************************************/ ++ ++#include ++#include ++#include ++ ++/**** Local Function prototypes *******/ ++static int vlynqInterruptInit(VLYNQ_DEV *pdev); ++static void vlynq_configClock(VLYNQ_DEV *pdev); ++ ++/*** Second argument must be explicitly type casted to ++ * (VLYNQ_DEV*) inside the following functions */ ++static void vlynq_local_module_isr(void *arg1, void *arg2, void *arg3); ++static void vlynq_remote_module_isr(void *arg1, void *arg2, void *arg3); ++ ++ ++volatile int vlynq_delay_value = 0; ++ ++/* Code adopted from original vlynq driver */ ++void vlynq_delay(unsigned int clktime) ++{ ++ int i = 0; ++ volatile int *ptr = &vlynq_delay_value; ++ *ptr = 0; ++ ++ /* We are assuming that the each cycle takes about ++ * 23 assembly instructions. */ ++ for(i = 0; i < (clktime + 23)/23; i++) ++ { ++ *ptr = *ptr + 1; ++ } ++} ++ ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynq_configClock() ++ * Description: Configures clock settings based on input parameters ++ * Adapted from original vlyna driver from Cable ++ */ ++static void vlynq_configClock(VLYNQ_DEV * pdev) ++{ ++ unsigned int tmp; ++ ++ switch( pdev->clk_source) ++ { ++ case VLYNQ_CLK_SOURCE_LOCAL: /* we output the clock, clk_div in range [1..8]. */ ++ tmp = ((pdev->clk_div - 1) << 16) | VLYNQ_CTL_CLKDIR_MASK ; ++ VLYNQ_CTRL_REG = tmp; ++ VLYNQ_R_CTRL_REG = 0ul; ++ break; ++ case VLYNQ_CLK_SOURCE_REMOTE: /* we need to set the clock pin as input */ ++ VLYNQ_CTRL_REG = 0ul; ++ tmp = ((pdev->clk_div - 1) << 16) | VLYNQ_CTL_CLKDIR_MASK ; ++ VLYNQ_R_CTRL_REG = tmp; ++ break; ++ default: /* do nothing about the clock, but clear other bits. */ ++ tmp = ~(VLYNQ_CTL_CLKDIR_MASK | VLYNQ_CTL_CLKDIV_MASK); ++ VLYNQ_CTRL_REG &= tmp; ++ break; ++ } ++} ++ ++ /* ---------------------------------------------------------------------------- ++ * Function : vlynq_link_check() ++ * Description: This function checks the current VLYNQ for a link. ++ * An arbitrary amount of time is allowed for the link to come up . ++ * Returns 0 for "no link / failure " and 1 for "link available". ++ * ----------------------------------------------------------------------------- ++ */ ++unsigned int vlynq_link_check( VLYNQ_DEV * pdev) ++{ ++ /*sleep for 64 cycles, allow link to come up*/ ++ vlynq_delay(64); ++ ++ /* check status register return OK if link is found. */ ++ if (VLYNQ_STATUS_REG & VLYNQ_STS_LINK_MASK) ++ { ++ return 1; /* Link Available */ ++ } ++ else ++ { ++ return 0; /* Link Failure */ ++ } ++} ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynq_init() ++ * Description: Initialization function accepting paramaters for VLYNQ module ++ * initialization. The Options bitmap decides what operations are performed ++ * as a part of initialization. The Input parameters are obtained through the ++ * sub fields of VLYNQ_DEV structure. ++ */ ++ ++int vlynq_init(VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options) ++{ ++ unsigned int map; ++ unsigned int val=0,cnt,tmp; ++ unsigned int counter=0; ++ VLYNQ_INTERRUPT_CNTRL *intSetting=NULL; ++ ++ /* validate arguments */ ++ if( VLYNQ_OUTRANGE(pdev->clk_source, VLYNQ_CLK_SOURCE_REMOTE, VLYNQ_CLK_SOURCE_NONE) || ++ VLYNQ_OUTRANGE(pdev->clk_div, 8, 1) ) ++ { ++ return VLYNQ_INVALID_ARG; ++ } ++ ++ /** perform all sanity checks first **/ ++ if(pdev->state != VLYNQ_DRV_STATE_UNINIT) ++ return VLYNQ_INVALID_DRV_STATE; ++ ++ /** Initialize local and remote register set addresses- additional ++ * provision to access the registers directly if need be */ ++ pdev->local = (VLYNQ_REG_SET*)pdev->module_base; ++ pdev->remote = (VLYNQ_REG_SET*) (pdev->module_base + VLYNQ_REMOTE_REGS_OFFSET); ++ ++ /* Detect faulty int configuration that might induce int pkt looping */ ++ if ( (options & VLYNQ_INIT_LOCAL_INTERRUPTS) && (options & VLYNQ_INIT_REMOTE_INTERRUPTS) ) ++ { ++ /* case when both local and remote are configured */ ++ if((pdev->local_irq.intLocal== VLYNQ_INT_REMOTE ) /* interrupts transfered to remote from local */ ++ && (pdev->remote_irq.intLocal== VLYNQ_INT_REMOTE) /* interrupts transfered from remote to local */ ++ && ((pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) || (pdev->remote_irq.intRemote == VLYNQ_INT_ROOT_ISR)) ) ++ { ++ return (VLYNQ_INT_CONFIG_ERR); ++ } ++ } ++ ++ pdev->state = VLYNQ_DRV_STATE_ININIT; ++ pdev->intCount = 0; ++ pdev->isrCount = 0; ++ ++ /*** Its assumed that the vlynq module has been brought out of reset ++ * before invocation of vlynq_init. Since, this operation is board specific ++ * it must be handled outside this generic driver */ ++ ++ /* Assert reset the remote device, call reset_cb, ++ * reset CB holds Reset according to the device needs. */ ++ VLYNQ_RESETCB(VLYNQ_RESET_ASSERT); ++ ++ /* Handle VLYNQ clock, HW default (Sense On Reset) is ++ * usually input for all the devices. */ ++ if (options & VLYNQ_INIT_CONFIG_CLOCK) ++ { ++ vlynq_configClock(pdev); ++ } ++ ++ /* Call reset_cb again. It will release the remote device ++ * from reset, and wait for a while. */ ++ VLYNQ_RESETCB(VLYNQ_RESET_DEASSERT); ++ ++ if(options & VLYNQ_INIT_CHECK_LINK ) ++ { ++ /* Check for link up during initialization*/ ++ while( counter < 25 ) ++ { ++ /* loop around giving a chance for link status to settle down */ ++ counter++; ++ if(vlynq_link_check(pdev)) ++ { ++ /* Link is up exit loop*/ ++ break; ++ } ++ ++ vlynq_delay(4000); ++ }/*end of while counter loop */ ++ ++ if(!vlynq_link_check(pdev)) ++ { ++ /* Handle this case as abort */ ++ pdev->state = VLYNQ_DRV_STATE_ERROR; ++ VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL); ++ return VLYNQ_LINK_DOWN; ++ }/* end of if not vlynq_link_check conditional block */ ++ ++ }/*end of if options & VLYNQ_INIT_CHECK_LINK conditional block */ ++ ++ ++ if (options & VLYNQ_INIT_LOCAL_MEM_REGIONS) ++ { ++ /* Initialise local memory regions . This initialization lets ++ * the local host access remote device memory regions*/ ++ int i; ++ ++ /* configure the VLYNQ portal window to a PHYSICAL ++ * address of the local CPU */ ++ VLYNQ_ALIGN4(pdev->local_mem.Txmap); ++ VLYNQ_TXMAP_REG = (pdev->local_mem.Txmap); ++ ++ /*This code assumes input parameter is itself a physical address */ ++ for(i=0; i < VLYNQ_MAX_MEMORY_REGIONS ; i++) ++ { ++ /* Physical address on the remote */ ++ map = i+1; ++ VLYNQ_R_RXMAP_SIZE_REG(map) = 0; ++ if( pdev->remote_mem.RxSize[i]) ++ { ++ VLYNQ_ALIGN4(pdev->remote_mem.RxOffset[i]); ++ VLYNQ_ALIGN4(pdev->remote_mem.RxSize[i]); ++ VLYNQ_R_RXMAP_OFFSET_REG(map) = pdev->remote_mem.RxOffset[i]; ++ VLYNQ_R_RXMAP_SIZE_REG(map) = pdev->remote_mem.RxSize[i]; ++ } ++ } ++ } ++ ++ if(options & VLYNQ_INIT_REMOTE_MEM_REGIONS ) ++ { ++ int i; ++ ++ /* Initialise remote memory regions. This initialization lets remote ++ * device access local host memory regions. It configures the VLYNQ portal ++ * window to a PHYSICAL address of the remote */ ++ VLYNQ_ALIGN4(pdev->remote_mem.Txmap); ++ VLYNQ_R_TXMAP_REG = pdev->remote_mem.Txmap; ++ ++ for( i=0; ilocal_mem.RxSize[i]) ++ { ++ VLYNQ_ALIGN4(pdev->local_mem.RxOffset[i]); ++ VLYNQ_ALIGN4(pdev->local_mem.RxSize[i]); ++ VLYNQ_RXMAP_OFFSET_REG(map) = (pdev->local_mem.RxOffset[i]); ++ VLYNQ_RXMAP_SIZE_REG(map) = (pdev->local_mem.RxSize[i]); ++ } ++ } ++ } ++ ++ /* Adapted from original vlynq driver from cable - Calculate VLYNQ bus width */ ++ pdev->width = 3 + VLYNQ_STATUS_FLD_WIDTH(VLYNQ_STATUS_REG) ++ + VLYNQ_STATUS_FLD_WIDTH(VLYNQ_R_STATUS_REG); ++ ++ /* chance to initialize the device, e.g. to boost VLYNQ ++ * clock by modifying pdev->clk_div or and verify the width. */ ++ VLYNQ_RESETCB(VLYNQ_RESET_LINKESTABLISH); ++ ++ /* Handle VLYNQ clock, HW default (Sense On Reset) is ++ * usually input for all the devices. */ ++ if(options & VLYNQ_INIT_CONFIG_CLOCK ) ++ { ++ vlynq_configClock(pdev); ++ } ++ ++ /* last check for link*/ ++ if(options & VLYNQ_INIT_CHECK_LINK ) ++ { ++ /* Final Check for link during initialization*/ ++ while( counter < 25 ) ++ { ++ /* loop around giving a chance for link status to settle down */ ++ counter++; ++ if(vlynq_link_check(pdev)) ++ { ++ /* Link is up exit loop*/ ++ break; ++ } ++ ++ vlynq_delay(4000); ++ }/*end of while counter loop */ ++ ++ if(!vlynq_link_check(pdev)) ++ { ++ /* Handle this case as abort */ ++ pdev->state = VLYNQ_DRV_STATE_ERROR; ++ VLYNQ_RESETCB( VLYNQ_RESET_INITFAIL); ++ return VLYNQ_LINK_DOWN; ++ }/* end of if not vlynq_link_check conditional block */ ++ ++ } /* end of if options & VLYNQ_INIT_CHECK_LINK */ ++ ++ if(options & VLYNQ_INIT_LOCAL_INTERRUPTS ) ++ { ++ /* Configure local interrupt settings */ ++ intSetting = &(pdev->local_irq); ++ ++ /* Map local module status interrupts to interrupt vector*/ ++ val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ; ++ ++ /* enable local module status interrupts */ ++ val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT; ++ ++ if ( intSetting->intLocal == VLYNQ_INT_LOCAL ) ++ { ++ /*set the intLocal bit*/ ++ val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT; ++ } ++ ++ /* Irrespective of whether interrupts are handled locally, program ++ * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1 ++ * i.e remote packets are set intPending register->which will result in ++ * same packet being sent out) has been done already ++ */ ++ ++ if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR) ++ { ++ /* Set the int2Cfg register, so that remote interrupt ++ * packets are written to intPending register */ ++ val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT; ++ ++ /* Set intPtr register to point to intPending register */ ++ VLYNQ_INT_PTR_REG = VLYNQ_INT_PENDING_REG_PTR ; ++ } ++ else ++ { ++ /*set the interrupt pointer register*/ ++ VLYNQ_INT_PTR_REG = intSetting->intr_ptr; ++ /* Dont bother to modify int2Cfg as it would be zero */ ++ } ++ ++ /** Clear bits related to INT settings in control register **/ ++ VLYNQ_CTRL_REG = VLYNQ_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK); ++ ++ /** Or the bits to be set with Control register **/ ++ VLYNQ_CTRL_REG = VLYNQ_CTRL_REG | val; ++ ++ /* initialise local ICB */ ++ if(vlynqInterruptInit(pdev)==VLYNQ_MEMALLOC_FAIL) ++ return VLYNQ_MEMALLOC_FAIL; ++ ++ /* Install handler for local module status interrupts. By default when ++ * local interrupt setting is initialised, the local module status are ++ * enabled and handler hooked up */ ++ if(vlynq_install_isr(pdev, intSetting->map_vector, vlynq_local_module_isr, ++ pdev, NULL, NULL) == VLYNQ_INVALID_ARG) ++ return VLYNQ_INVALID_ARG; ++ } /* end of init local interrupts */ ++ ++ if(options & VLYNQ_INIT_REMOTE_INTERRUPTS ) ++ { ++ /* Configure remote interrupt settings from configuration */ ++ intSetting = &(pdev->remote_irq); ++ ++ /* Map remote module status interrupts to remote interrupt vector*/ ++ val = intSetting->map_vector << VLYNQ_CTL_INTVEC_SHIFT ; ++ /* enable remote module status interrupts */ ++ val |= 0x01 << VLYNQ_CTL_INTEN_SHIFT; ++ ++ if ( intSetting->intLocal == VLYNQ_INT_LOCAL ) ++ { ++ /*set the intLocal bit*/ ++ val |= 0x01 << VLYNQ_CTL_INTLOCAL_SHIFT; ++ } ++ ++ /* Irrespective of whether interrupts are handled locally, program ++ * int2Cfg. Error checking for accidental loop(when intLocal=0 and int2Cfg=1 ++ * i.e remote packets are set intPending register->which will result in ++ * same packet being sent out) has been done already ++ */ ++ ++ if (intSetting->intRemote == VLYNQ_INT_ROOT_ISR) ++ { ++ /* Set the int2Cfg register, so that remote interrupt ++ * packets are written to intPending register */ ++ val |= 0x01 << VLYNQ_CTL_INT2CFG_SHIFT; ++ /* Set intPtr register to point to intPending register */ ++ VLYNQ_R_INT_PTR_REG = VLYNQ_R_INT_PENDING_REG_PTR ; ++ } ++ else ++ { ++ /*set the interrupt pointer register*/ ++ VLYNQ_R_INT_PTR_REG = intSetting->intr_ptr; ++ /* Dont bother to modify int2Cfg as it would be zero */ ++ } ++ ++ if( (intSetting->intLocal == VLYNQ_INT_REMOTE) && ++ (options & VLYNQ_INIT_LOCAL_INTERRUPTS) && ++ (pdev->local_irq.intRemote == VLYNQ_INT_ROOT_ISR) ) ++ { ++ /* Install handler for remote module status interrupts. By default when ++ * remote interrupts are forwarded to local root_isr then remote_module_isr is ++ * enabled and handler hooked up */ ++ if(vlynq_install_isr(pdev,intSetting->map_vector,vlynq_remote_module_isr, ++ pdev, NULL, NULL) == VLYNQ_INVALID_ARG) ++ return VLYNQ_INVALID_ARG; ++ } ++ ++ ++ /** Clear bits related to INT settings in control register **/ ++ VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG & (~VLYNQ_CTL_INTFIELDS_CLEAR_MASK); ++ ++ /** Or the bits to be set with the remote Control register **/ ++ VLYNQ_R_CTRL_REG = VLYNQ_R_CTRL_REG | val; ++ ++ } /* init remote interrupt settings*/ ++ ++ if(options & VLYNQ_INIT_CLEAR_ERRORS ) ++ { ++ /* Clear errors during initialization */ ++ tmp = VLYNQ_STATUS_REG & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK); ++ VLYNQ_STATUS_REG = tmp; ++ tmp = VLYNQ_R_STATUS_REG & (VLYNQ_STS_RERROR_MASK | VLYNQ_STS_LERROR_MASK); ++ VLYNQ_R_STATUS_REG = tmp; ++ } ++ ++ /* clear int status */ ++ val = VLYNQ_INT_STAT_REG; ++ VLYNQ_INT_STAT_REG = val; ++ ++ /* finish initialization */ ++ pdev->state = VLYNQ_DRV_STATE_RUN; ++ VLYNQ_RESETCB( VLYNQ_RESET_INITOK); ++ return VLYNQ_SUCCESS; ++ ++} ++ ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynqInterruptInit() ++ * Description: This local function is used to set up the ICB table for the ++ * VLYNQ_STATUS_REG vlynq module. The input parameter "pdev" points the vlynq ++ * device instance whose ICB is allocated. ++ * Return : returns VLYNQ_SUCCESS or vlynq error for failure ++ * ----------------------------------------------------------------------------- ++ */ ++static int vlynqInterruptInit(VLYNQ_DEV *pdev) ++{ ++ int i, numslots; ++ ++ /* Memory allocated statically. ++ * Initialise ICB,free list.Indicate primary slot empty. ++ * Intialise intVector <==> map_vector translation table*/ ++ for(i=0; i < VLYNQ_NUM_INT_BITS; i++) ++ { ++ pdev->pIntrCB[i].isr = NULL; ++ pdev->pIntrCB[i].next = NULL; /*nothing chained */ ++ pdev->vector_map[i] = -1; /* indicates unmapped */ ++ } ++ ++ /* In the ICB slots, [VLYNQ_NUM_INT_BITS i.e 32 to ICB array size) are expansion slots ++ * required only when interrupt chaining/sharing is supported. In case ++ * of chained interrupts the list starts from primary slot and the ++ * additional slots are obtained from the common free area */ ++ ++ /* Initialise freelist */ ++ ++ numslots = VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS; ++ ++ if (numslots > VLYNQ_NUM_INT_BITS) ++ { ++ pdev->freelist = &(pdev->pIntrCB[VLYNQ_NUM_INT_BITS]); ++ ++ for(i = VLYNQ_NUM_INT_BITS; i < (numslots-1) ; i++) ++ { ++ pdev->pIntrCB[i].next = &(pdev->pIntrCB[i+1]); ++ pdev->pIntrCB[i].isr = NULL; ++ } ++ pdev->pIntrCB[i].next=NULL; /* Indicate end of freelist*/ ++ pdev->pIntrCB[i].isr=NULL; ++ } ++ else ++ { ++ pdev->freelist = NULL; ++ } ++ ++ /** Reset mapping for IV 0-7 **/ ++ VLYNQ_IVR_03TO00_REG = 0; ++ VLYNQ_IVR_07TO04_REG = 0; ++ ++ return VLYNQ_SUCCESS; ++} ++ ++/** remember that hooking up of root ISR handler with the interrupt controller ++ * is not done as a part of this driver. Typically, it must be done after ++ * invoking vlynq_init*/ ++ ++ ++ /* ---------------------------------------------------------------------------- ++ * ISR with the SOC interrupt controller. This ISR typically scans ++ * the Int PENDING/SET register in the VLYNQ module and calls the ++ * appropriate ISR associated with the correponding vector number. ++ * ----------------------------------------------------------------------------- ++ */ ++void vlynq_root_isr(void *arg) ++{ ++ int source; /* Bit position of pending interrupt, start from 0 */ ++ unsigned int interrupts, clrInterrupts; ++ VLYNQ_DEV * pdev; ++ VLYNQ_INTR_CNTRL_ICB *entry; ++ ++ pdev=(VLYNQ_DEV*)(arg); /*obtain the vlynq device pointer*/ ++ ++ interrupts = VLYNQ_INT_STAT_REG; /* Get the list of pending interrupts */ ++ VLYNQ_INT_STAT_REG = interrupts; /* clear the int CR register */ ++ clrInterrupts = interrupts; /* save them for further analysis */ ++ ++ debugPrint("vlynq_root_isr: dev %u. INTCR = 0x%08lx\n", pdev->dev_idx, clrInterrupts,0,0,0,0); ++ ++ /* Scan interrupt bits */ ++ source =0; ++ while( clrInterrupts != 0) ++ { ++ /* test if bit is set? */ ++ if( 0x1ul & clrInterrupts) ++ { ++ entry = &(pdev->pIntrCB[source]); /* Get the ISR entry */ ++ pdev->intCount++; /* update interrupt count */ ++ if(entry->isr != NULL) ++ { ++ do ++ { ++ pdev->isrCount++; /* update isr invocation count */ ++ /* Call the user ISR and update the count for ISR */ ++ entry->isrCount++; ++ entry->isr(entry->arg1, entry->arg2, entry->arg3); ++ if (entry->next == NULL) break; ++ entry = entry->next; ++ ++ } while (entry->isr != NULL); ++ } ++ else ++ { ++ debugPrint(" ISR not installed for vlynq vector:%d\n",source,0,0,0,0,0); ++ } ++ } ++ clrInterrupts >>= 1; /* Next source bit */ ++ ++source; ++ } /* endWhile clrInterrupts != 0 */ ++} ++ ++ ++ /* ---------------------------------------------------------------------------- ++ * Function : vlynq_local__module_isr() ++ * Description: This ISR is attached to the local VLYNQ interrupt vector ++ * by the Vlynq Driver when local interrupts are being handled. i.e. ++ * intLocal=1. This ISR handles local Vlynq module status interrupts only ++ * AS a part of this ISR, user callback in VLYNQ_DEV structure ++ * is invoked. ++ * VLYNQ_DEV is passed as arg1. arg2 and arg3 are unused. ++ * ----------------------------------------------------------------------------- ++ */ ++static void vlynq_local_module_isr(void *arg1,void *arg2, void *arg3) ++{ ++ VLYNQ_REPORT_CB func; ++ unsigned int dwStatRegVal; ++ VLYNQ_DEV * pdev; ++ ++ pdev = (VLYNQ_DEV*) arg1; ++ /* Callback function is read from the device pointer that is passed as an argument */ ++ func = pdev->report_cb; ++ ++ /* read local status register */ ++ dwStatRegVal = VLYNQ_STATUS_REG; ++ ++ /* clear pending events */ ++ VLYNQ_STATUS_REG = dwStatRegVal; ++ ++ /* invoke user callback */ ++ if( func != NULL) ++ func( pdev, VLYNQ_LOCAL_DVC, dwStatRegVal); ++ ++} ++ ++ /* ---------------------------------------------------------------------------- ++ * Function : vlynq_remote_module_isr() ++ * Description: This ISR is attached to the remote VLYNQ interrupt vector ++ * by the Vlynq Driver when remote interrupts are being handled locally. i.e. ++ * intLocal=1. This ISR handles local Vlynq module status interrupts only ++ * AS a part of this ISR, user callback in VLYNQ_DEV structure ++ * is invoked. ++ * The parameters irq,regs ar unused. ++ * ----------------------------------------------------------------------------- ++ */ ++static void vlynq_remote_module_isr(void *arg1,void *arg2, void *arg3) ++{ ++ VLYNQ_REPORT_CB func; ++ unsigned int dwStatRegVal; ++ VLYNQ_DEV * pdev; ++ ++ ++ pdev = (VLYNQ_DEV*) arg1; ++ ++ /* Callback function is read from the device pointer that is passed as an argument */ ++ func = pdev->report_cb; ++ ++ /* read local status register */ ++ dwStatRegVal = VLYNQ_R_STATUS_REG; ++ ++ /* clear pending events */ ++ VLYNQ_R_STATUS_REG = dwStatRegVal; ++ ++ /* invoke user callback */ ++ if( func != NULL) ++ func( pdev, VLYNQ_REMOTE_DVC, dwStatRegVal); ++ ++} ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynq_interrupt_get_count() ++ * Description: This function returns the number of times a particular intr ++ * has been invoked. ++ * ++ * It returns 0, if erroneous map_vector is specified or if the corres isr ++ * has not been registered with VLYNQ. ++ */ ++unsigned int vlynq_interrupt_get_count(VLYNQ_DEV *pdev, ++ unsigned int map_vector) ++{ ++ VLYNQ_INTR_CNTRL_ICB *entry; ++ unsigned int count = 0; ++ ++ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) ++ return count; ++ ++ entry = &(pdev->pIntrCB[map_vector]); ++ ++ if (entry) ++ count = entry->isrCount; ++ ++ return (count); ++} ++ ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynq_install_isr() ++ * Description: This function installs ISR for Vlynq interrupt vector ++ * bits(in IntPending register). This function should be used only when ++ * Vlynq interrupts are being handled locally(remote may be programmed to send ++ * interrupt packets).Also, the int2cfg should be 1 and the least significant ++ * 8 bits of the Interrupt Pointer Register must point to Interrupt ++ * Pending/Set Register). ++ * If host int2cfg=0 and the Interrupt Pointer register contains ++ * the address of the interrupt set register in the interrupt controller ++ * module of the local device , then the ISR for the remote interrupt must be ++ * directly registered with the Interrupt controller and must not use this API ++ * Note: this function simply installs the ISR in ICB It doesnt modify ++ * any register settings ++ */ ++int ++vlynq_install_isr(VLYNQ_DEV *pdev, ++ unsigned int map_vector, ++ VLYNQ_INTR_CNTRL_ISR isr, ++ void *arg1, void *arg2, void *arg3) ++{ ++ VLYNQ_INTR_CNTRL_ICB *entry; ++ ++ if ( (map_vector > (VLYNQ_NUM_INT_BITS-1)) || (isr == NULL) ) ++ return VLYNQ_INVALID_ARG; ++ ++ entry = &(pdev->pIntrCB[map_vector]); ++ ++ if(entry->isr == NULL) ++ { ++ entry->isr = isr; ++ entry->arg1 = arg1; ++ entry->arg2 = arg2; ++ entry->arg3 = arg3; ++ entry->next = NULL; ++ } ++ else ++ { ++ /** No more empty slots,return error */ ++ if(pdev->freelist == NULL) ++ return VLYNQ_MEMALLOC_FAIL; ++ ++ while(entry->next != NULL) ++ { ++ entry = entry->next; ++ } ++ ++ /* Append new node to the chain */ ++ entry->next = pdev->freelist; ++ /* Remove the appended node from freelist */ ++ pdev->freelist = pdev->freelist->next; ++ entry= entry->next; ++ ++ /*** Set the ICB fields ***/ ++ entry->isr = isr; ++ entry->arg1 = arg1; ++ entry->arg2 = arg2; ++ entry->arg3 = arg3; ++ entry->next = NULL; ++ } ++ ++ return VLYNQ_SUCCESS; ++} ++ ++ ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynq_uninstall_isr ++ * Description: This function is used to uninstall a previously ++ * registered ISR. In case of shared/chained interrupts, the ++ * void * arg parameter must uniquely identify the ISR to be ++ * uninstalled. ++ * Note: this function simply uninstalls the ISR in ICB ++ * It doesnt modify any register settings ++ */ ++int ++vlynq_uninstall_isr(VLYNQ_DEV *pdev, ++ unsigned int map_vector, ++ void *arg1, void *arg2, void *arg3) ++{ ++ VLYNQ_INTR_CNTRL_ICB *entry,*temp; ++ ++ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) ++ return VLYNQ_INVALID_ARG; ++ ++ entry = &(pdev->pIntrCB[map_vector]); ++ ++ if(entry->isr == NULL ) ++ return VLYNQ_ISR_NON_EXISTENT; ++ ++ if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) ) ++ { ++ if(entry->next == NULL) ++ { ++ entry->isr=NULL; ++ return VLYNQ_SUCCESS; ++ } ++ else ++ { ++ temp = entry->next; ++ /* Copy next node in the chain to prim.slot */ ++ entry->isr = temp->isr; ++ entry->arg1 = temp->arg1; ++ entry->arg2 = temp->arg2; ++ entry->arg3 = temp->arg3; ++ entry->next = temp->next; ++ /* Free the just copied node */ ++ temp->isr = NULL; ++ temp->arg1 = NULL; ++ temp->arg2 = NULL; ++ temp->arg3 = NULL; ++ temp->next = pdev->freelist; ++ pdev->freelist = temp; ++ return VLYNQ_SUCCESS; ++ } ++ } ++ else ++ { ++ temp = entry; ++ while ( (entry = temp->next) != NULL) ++ { ++ if ( (entry->arg1 == arg1) && (entry->arg2 == arg2) && (entry->arg3 == arg3) ) ++ { ++ /* remove node from chain */ ++ temp->next = entry->next; ++ /* Add the removed node to freelist */ ++ entry->isr = NULL; ++ entry->arg1 = NULL; ++ entry->arg2 = NULL; ++ entry->arg3 = NULL; ++ entry->next = pdev->freelist; ++ entry->isrCount = 0; ++ pdev->freelist = entry; ++ return VLYNQ_SUCCESS; ++ } ++ temp = entry; ++ } ++ ++ return VLYNQ_ISR_NON_EXISTENT; ++ } ++} ++ ++ ++ ++ ++/* ---------------------------------------------------------------------------- ++ * function : vlynq_interrupt_vector_set() ++ * description:configures interrupt vector mapping,interrupt type ++ * polarity -all in one go. ++ */ ++int ++vlynq_interrupt_vector_set(VLYNQ_DEV *pdev, /* vlynq device */ ++ unsigned int int_vector, /* int vector on vlynq device */ ++ unsigned int map_vector, /* bit for this interrupt */ ++ VLYNQ_DEV_TYPE dev_type, /* local or remote device */ ++ VLYNQ_INTR_POLARITY pol, /* polarity of interrupt */ ++ VLYNQ_INTR_TYPE type) /* pulsed/level interrupt */ ++{ ++ volatile unsigned int * vecreg; ++ unsigned int val=0; ++ unsigned int bytemask=0XFF; ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ ++ /* validate the number of interrupts supported */ ++ if (int_vector >= VLYNQ_IVR_MAXIVR) ++ return VLYNQ_INVALID_ARG; ++ ++ if(map_vector > (VLYNQ_NUM_INT_BITS - 1) ) ++ return VLYNQ_INVALID_ARG; ++ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /* Update the intVector<==> bit position translation table */ ++ pdev->vector_map[map_vector] = int_vector; ++ ++ /* val has been initialised to zero. we only have to turn on appropriate bits*/ ++ if(type == VLYNQ_INTR_PULSED) ++ val |= VLYNQ_IVR_INTTYPE_MASK; ++ ++ if(pol == VLYNQ_INTR_ACTIVE_LOW) ++ val |= VLYNQ_IVR_INTPOL_MASK; ++ ++ val |= map_vector; ++ ++ /** clear the correct byte position and then or val **/ ++ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); ++ ++ /** write to correct byte position in vecreg*/ ++ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; ++ ++ /* Setting a interrupt vector, leaves the interrupt disabled ++ * which must be enabled subsequently */ ++ ++ return VLYNQ_SUCCESS; ++} ++ ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynq_interrupt_vector_cntl() ++ * Description:enables/disable interrupt ++ */ ++int vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev, ++ unsigned int int_vector, ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int enable) ++{ ++ volatile unsigned int *vecReg; ++ unsigned int val=0; ++ unsigned int intenMask=0x80; ++ ++ /* validate the number of interrupts supported */ ++ if (int_vector >= VLYNQ_IVR_MAXIVR) ++ return VLYNQ_INVALID_ARG; ++ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecReg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecReg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /** Clear the correct byte position and then or val **/ ++ *vecReg = (*vecReg) & ( ~(intenMask << ( (int_vector %4)*8) ) ); ++ ++ if(enable) ++ { ++ val |= VLYNQ_IVR_INTEN_MASK; ++ /** Write to correct byte position in vecReg*/ ++ *vecReg = (*vecReg) | (val << ( (int_vector % 4)*8) ) ; ++ } ++ ++ return VLYNQ_SUCCESS; ++ ++}/* end of function vlynq_interrupt_vector_cntl */ ++ ++ ++ ++/* ---------------------------------------------------------------------------- ++ * Function : vlynq_interrupt_vector_map() ++ * Description:Configures interrupt vector mapping alone ++ */ ++int ++vlynq_interrupt_vector_map( VLYNQ_DEV *pdev, ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int int_vector, ++ unsigned int map_vector) ++{ ++ volatile unsigned int * vecreg; ++ unsigned int val=0; ++ unsigned int bytemask=0x1f; /* mask to turn off bits corresponding to int vector */ ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ ++ /* validate the number of interrupts supported */ ++ if (int_vector >= VLYNQ_IVR_MAXIVR) ++ return VLYNQ_INVALID_ARG; ++ ++ if(map_vector > (VLYNQ_NUM_INT_BITS - 1) ) ++ return VLYNQ_INVALID_ARG; ++ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /* Update the intVector<==> bit position translation table */ ++ pdev->vector_map[map_vector] = int_vector; ++ ++ /** val has been initialised to zero. we only have to turn on ++ * appropriate bits*/ ++ val |= map_vector; ++ ++ /** clear the correct byte position and then or val **/ ++ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); ++ ++ /** write to correct byte position in vecreg*/ ++ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; ++ ++ return VLYNQ_SUCCESS; ++} ++ ++ ++/* ---------------------------------------------------------------------------- ++ * function : vlynq_interrupt_set_polarity() ++ * description:configures interrupt polarity . ++ */ ++int ++vlynq_interrupt_set_polarity( VLYNQ_DEV *pdev , ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector, ++ VLYNQ_INTR_POLARITY pol) ++{ ++ volatile unsigned int * vecreg; ++ int int_vector; ++ unsigned int val=0; ++ unsigned int bytemask=0x20; /** mask to turn off bits corresponding to int polarity */ ++ ++ /* get the int_vector from map_vector */ ++ int_vector = pdev->vector_map[map_vector]; ++ ++ if(int_vector == -1) ++ return VLYNQ_INTVEC_MAP_NOT_FOUND; ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /* val has been initialised to zero. we only have to turn on ++ * appropriate bits, if need be*/ ++ ++ /** clear the correct byte position and then or val **/ ++ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); ++ ++ if( pol == VLYNQ_INTR_ACTIVE_LOW) ++ { ++ val |= VLYNQ_IVR_INTPOL_MASK; ++ /** write to correct byte position in vecreg*/ ++ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; ++ } ++ ++ return VLYNQ_SUCCESS; ++} ++ ++int vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev , ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector) ++{ ++ volatile unsigned int * vecreg; ++ int int_vector; ++ unsigned int val=0; ++ ++ /* get the int_vector from map_vector */ ++ int_vector = pdev->vector_map[map_vector]; ++ ++ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) ++ return(-1); ++ ++ if(int_vector == -1) ++ return VLYNQ_INTVEC_MAP_NOT_FOUND; ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /** read the information into val **/ ++ val = (*vecreg) & ((VLYNQ_IVR_INTPOL_MASK << ( (int_vector %4)*8) ) ); ++ ++ return (val ? (VLYNQ_INTR_ACTIVE_LOW) : (VLYNQ_INTR_ACTIVE_HIGH)); ++} ++ ++ ++/* ---------------------------------------------------------------------------- ++ * function : vlynq_interrupt_set_type() ++ * description:configures interrupt type . ++ */ ++int vlynq_interrupt_set_type( VLYNQ_DEV *pdev, ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector, ++ VLYNQ_INTR_TYPE type) ++{ ++ volatile unsigned int * vecreg; ++ unsigned int val=0; ++ int int_vector; ++ ++ /** mask to turn off bits corresponding to interrupt type */ ++ unsigned int bytemask=0x40; ++ ++ /* get the int_vector from map_vector */ ++ int_vector = pdev->vector_map[map_vector]; ++ if(int_vector == -1) ++ return VLYNQ_INTVEC_MAP_NOT_FOUND; ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /** val has been initialised to zero. we only have to turn on ++ * appropriate bits if need be*/ ++ ++ /** clear the correct byte position and then or val **/ ++ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); ++ ++ if( type == VLYNQ_INTR_PULSED) ++ { ++ val |= VLYNQ_IVR_INTTYPE_MASK; ++ /** write to correct byte position in vecreg*/ ++ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; ++ } ++ ++ return VLYNQ_SUCCESS; ++} ++ ++/* ---------------------------------------------------------------------------- ++ * function : vlynq_interrupt_get_type() ++ * description:returns interrupt type . ++ */ ++int vlynq_interrupt_get_type( VLYNQ_DEV *pdev, VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector) ++{ ++ volatile unsigned int * vecreg; ++ unsigned int val=0; ++ int int_vector; ++ ++ if (map_vector > (VLYNQ_NUM_INT_BITS-1)) ++ return(-1); ++ ++ /* get the int_vector from map_vector */ ++ int_vector = pdev->vector_map[map_vector]; ++ if(int_vector == -1) ++ return VLYNQ_INTVEC_MAP_NOT_FOUND; ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /** Read the correct bit position into val **/ ++ val = (*vecreg) & ((VLYNQ_IVR_INTTYPE_MASK << ( (int_vector %4)*8) ) ); ++ ++ return (val ? (VLYNQ_INTR_PULSED) : (VLYNQ_INTR_LEVEL)); ++} ++ ++/* ---------------------------------------------------------------------------- ++ * function : vlynq_interrupt_enable() ++ * description:Enable interrupt by writing to IVR register. ++ */ ++int vlynq_interrupt_enable( VLYNQ_DEV *pdev, ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector) ++{ ++ volatile unsigned int * vecreg; ++ unsigned int val=0; ++ int int_vector; ++ ++ /** mask to turn off bits corresponding to interrupt enable */ ++ unsigned int bytemask=0x80; ++ ++ /* get the int_vector from map_vector */ ++ int_vector = pdev->vector_map[map_vector]; ++ if(int_vector == -1) ++ return VLYNQ_INTVEC_MAP_NOT_FOUND; ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /** val has been initialised to zero. we only have to turn on ++ * bit corresponding to interrupt enable*/ ++ val |= VLYNQ_IVR_INTEN_MASK; ++ ++ /** clear the correct byte position and then or val **/ ++ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); ++ ++ /** write to correct byte position in vecreg*/ ++ *vecreg = (*vecreg) | (val << ( (int_vector % 4)*8) ) ; ++ ++ return VLYNQ_SUCCESS; ++} ++ ++ ++/* ---------------------------------------------------------------------------- ++ * function : vlynq_interrupt_disable() ++ * description:Disable interrupt by writing to IVR register. ++ */ ++int ++vlynq_interrupt_disable( VLYNQ_DEV *pdev, ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector) ++{ ++ volatile unsigned int * vecreg; ++ int int_vector; ++ ++ /** mask to turn off bits corresponding to interrupt enable */ ++ unsigned int bytemask=0x80; ++ ++ /* get the int_vector from map_vector */ ++ int_vector = pdev->vector_map[map_vector]; ++ if(int_vector == -1) ++ return VLYNQ_INTVEC_MAP_NOT_FOUND; ++ ++ /* use the lower 8 bits of val to set the value , shift it to ++ * appropriate byte position in the ivr and write it to the ++ * corresponding register */ ++ if (dev_type == VLYNQ_LOCAL_DVC) ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_IVR_OFFSET(int_vector)); ++ } ++ else ++ { ++ vecreg = (volatile unsigned int *) (VLYNQ_R_IVR_OFFSET(int_vector)); ++ } ++ ++ /* We disable the interrupt by simply turning off the bit ++ * corresponding to Interrupt enable. ++ * Clear the interrupt enable bit in the correct byte position **/ ++ *vecreg = (*vecreg) & ( ~(bytemask << ( (int_vector %4)*8) ) ); ++ ++ /* Dont have to set any bit positions */ ++ ++ return VLYNQ_SUCCESS; ++ ++} ++ ++ ++ ++ +diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c +--- linux.old/drivers/char/serial.c 2005-10-21 16:43:20.709226000 +0200 ++++ linux.dev/drivers/char/serial.c 2005-11-10 01:10:46.015585250 +0100 +@@ -419,7 +419,40 @@ + return 0; + } + +-#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD) ++#if defined(CONFIG_AR7) ++ ++static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) ++{ ++ return (inb(info->port + (offset * 4)) & 0xff); ++} ++ ++ ++static _INLINE_ unsigned int serial_inp(struct async_struct *info, int offset) ++{ ++#ifdef CONFIG_SERIAL_NOPAUSE_IO ++ return (inb(info->port + (offset * 4)) & 0xff); ++#else ++ return (inb_p(info->port + (offset * 4)) & 0xff); ++#endif ++} ++ ++static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) ++{ ++ outb(value, info->port + (offset * 4)); ++} ++ ++ ++static _INLINE_ void serial_outp(struct async_struct *info, int offset, ++ int value) ++{ ++#ifdef CONFIG_SERIAL_NOPAUSE_IO ++ outb(value, info->port + (offset * 4)); ++#else ++ outb_p(value, info->port + (offset * 4)); ++#endif ++} ++ ++#elif defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD) + + #include + +@@ -478,8 +511,10 @@ + * needed for certain old 386 machines, I've left these #define's + * in.... + */ ++#ifndef CONFIG_AR7 + #define serial_inp(info, offset) serial_in(info, offset) + #define serial_outp(info, offset, value) serial_out(info, offset, value) ++#endif + + + /* +@@ -1728,7 +1763,15 @@ + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) ++#ifdef CONFIG_AR7 ++ quot = (CONFIG_AR7_SYS*500000) / baud; ++ ++ if ((quot%16)>7) ++ quot += 8; ++ quot /=16; ++#else + quot = baud_base / baud; ++#endif + } + /* If the quotient is zero refuse the change */ + if (!quot && old_termios) { +@@ -5540,8 +5583,10 @@ + state->irq = irq_cannonicalize(state->irq); + if (state->hub6) + state->io_type = SERIAL_IO_HUB6; ++#ifndef CONFIG_AR7 + if (state->port && check_region(state->port,8)) + continue; ++#endif + #ifdef CONFIG_MCA + if ((state->flags & ASYNC_BOOT_ONLYMCA) && !MCA_bus) + continue; +@@ -5997,7 +6042,15 @@ + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; ++#ifdef CONFIG_AR7 ++ quot = (CONFIG_AR7_SYS*500000) / baud; ++ ++ if ((quot%16)>7) ++ quot += 8; ++ quot /=16; ++#else + quot = state->baud_base / baud; ++#endif + cval = cflag & (CSIZE | CSTOPB); + #if defined(__powerpc__) || defined(__alpha__) + cval >>= 8; +diff -urN linux.old/drivers/char/ticfg/Makefile linux.dev/drivers/char/ticfg/Makefile +--- linux.old/drivers/char/ticfg/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/ticfg/Makefile 2005-11-10 01:10:46.051587500 +0100 +@@ -0,0 +1,6 @@ ++ ++O_TARGET := ticfg.o ++ ++obj-$(CONFIG_AR7_ADAM2) := adam2_env.o ++ ++include $(TOPDIR)/Rules.make +diff -urN linux.old/drivers/char/ticfg/adam2_env.c linux.dev/drivers/char/ticfg/adam2_env.c +--- linux.old/drivers/char/ticfg/adam2_env.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/char/ticfg/adam2_env.c 2005-11-10 01:10:46.051587500 +0100 +@@ -0,0 +1,85 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#undef ADAM2_ENV_DEBUG ++ ++#ifdef ADAM2_ENV_DEBUG ++#define DPRINTK(args...) do { printk(args); } while(0); ++#else ++#define DPRINTK(args...) do { } while(0); ++#endif ++ ++#define ADAM2_ENV_DIR "ticfg" ++#define ADAM2_ENV_NAME "env" ++ ++static struct proc_dir_entry *adam2_env_proc_dir; ++static struct proc_dir_entry *adam2_env_proc_ent; ++ ++static int ++adam2_proc_read_env(char *page, char **start, off_t pos, int count, ++ int *eof, void *data) ++{ ++ int len; ++ t_env_var *env; ++ ++ if (pos > 0) ++ return 0; ++ ++ len=0; ++ for (env = prom_iterenv(0); env; env = prom_iterenv(env)) { ++ if (env->val) { ++ /* XXX check for page len */ ++ len += sprintf(page + len, "%s\t%s\n", ++ env->name, env->val); ++ } ++ } ++ ++ *eof=1; ++ return len; ++} ++ ++static int __init ++adam2_env_init(void) ++{ ++ ++ DPRINTK("%s\n", __FUNCTION__); ++ ++ adam2_env_proc_dir = proc_mkdir(ADAM2_ENV_DIR, NULL); ++ if (!adam2_env_proc_dir) { ++ printk(KERN_ERR "%s: Unable to create /proc/%s entry\n", ++ __FUNCTION__, ADAM2_ENV_DIR); ++ return -ENOMEM; ++ } ++ ++ adam2_env_proc_ent = ++ create_proc_entry(ADAM2_ENV_NAME, 0444, adam2_env_proc_dir); ++ if (!adam2_env_proc_ent) { ++ printk(KERN_ERR "%s: Unable to create /proc/%s/%s entry\n", ++ __FUNCTION__, ADAM2_ENV_DIR, ADAM2_ENV_NAME); ++ remove_proc_entry(ADAM2_ENV_DIR, NULL); ++ return -ENOMEM; ++ } ++ adam2_env_proc_ent->read_proc = adam2_proc_read_env; ++ ++ return 0; ++} ++ ++static ++void __exit ++adam2_env_cleanup(void) ++{ ++ remove_proc_entry(ADAM2_ENV_NAME, adam2_env_proc_dir); ++ remove_proc_entry(ADAM2_ENV_DIR, NULL); ++} ++ ++module_init(adam2_env_init); ++module_exit(adam2_env_cleanup); ++ ++MODULE_LICENSE("GPL"); +diff -urN linux.old/include/asm-mips/addrspace.h linux.dev/include/asm-mips/addrspace.h +--- linux.old/include/asm-mips/addrspace.h 2002-11-29 00:53:15.000000000 +0100 ++++ linux.dev/include/asm-mips/addrspace.h 2005-11-10 01:14:16.400733500 +0100 +@@ -11,6 +11,8 @@ + #ifndef __ASM_MIPS_ADDRSPACE_H + #define __ASM_MIPS_ADDRSPACE_H + ++#include ++ + /* + * Configure language + */ +@@ -102,4 +104,11 @@ + #define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) + #define PHYS_TO_XKPHYS(cm,a) (0x8000000000000000 | ((cm)<<59) | (a)) + ++#ifdef CONFIG_AR7_MEMORY ++#define PHYS_OFFSET ((unsigned long)(CONFIG_AR7_MEMORY)) ++#else ++#define PHYS_OFFSET (0) ++#endif ++#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) ++ + #endif /* __ASM_MIPS_ADDRSPACE_H */ +diff -urN linux.old/include/asm-mips/ar7/adam2_env.h linux.dev/include/asm-mips/ar7/adam2_env.h +--- linux.old/include/asm-mips/ar7/adam2_env.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/adam2_env.h 2005-11-10 01:10:46.067588500 +0100 +@@ -0,0 +1,13 @@ ++#ifndef _INCLUDE_ASM_AR7_ADAM2_ENV_H_ ++#define _INCLUDE_ASM_AR7_ADAM2_ENV_H_ ++ ++/* Environment variable */ ++typedef struct { ++ char *name; ++ char *val; ++} t_env_var; ++ ++char *prom_getenv(char *); ++t_env_var *prom_iterenv(t_env_var *); ++ ++#endif /* _INCLUDE_ASM_AR7_ADAM2_ENV_H_ */ +diff -urN linux.old/include/asm-mips/ar7/ar7.h linux.dev/include/asm-mips/ar7/ar7.h +--- linux.old/include/asm-mips/ar7/ar7.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/ar7.h 2005-11-10 01:10:46.067588500 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * $Id$ ++ * Copyright (C) $Date$ $Author$ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++#ifndef _AR7_H ++#define _AR7_H ++ ++#include ++#include ++ ++#define AVALANCHE_VECS_KSEG0 (KSEG0ADDR(CONFIG_AR7_MEMORY)) ++ ++#define AR7_UART0_REGS_BASE (KSEG1ADDR(0x08610E00)) ++#define AR7_UART1_REGS_BASE (KSEG1ADDR(0x08610F00)) ++#define AR7_BASE_BAUD ( 3686400 / 16 ) ++ ++#endif +diff -urN linux.old/include/asm-mips/ar7/avalanche_intc.h linux.dev/include/asm-mips/ar7/avalanche_intc.h +--- linux.old/include/asm-mips/ar7/avalanche_intc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/avalanche_intc.h 2005-11-10 01:10:46.067588500 +0100 +@@ -0,0 +1,292 @@ ++ /* ++ * Nitin Dhingra, iamnd@ti.com ++ * Copyright (C) 2000 Texas Instruments Inc. ++ * ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ * ++ * Defines of the Sead board specific address-MAP, registers, etc. ++ * ++ */ ++#ifndef _AVALANCHE_INTC_H ++#define _AVALANCHE_INTC_H ++ ++#include ++ ++/* ----- */ ++ ++#define KSEG1_BASE 0xA0000000 ++#define KSEG_INV_MASK 0x1FFFFFFF /* Inverted mask for kseg address */ ++#define PHYS_ADDR(addr) ((addr) & KSEG_INV_MASK) ++#define PHYS_TO_K1(addr) (PHYS_ADDR(addr)|KSEG1_BASE) ++#define AVALANCHE_INTC_BASE PHYS_TO_K1(0x08612400) ++ ++/* ----- */ ++ ++#define MIPS_EXCEPTION_OFFSET 8 ++ ++/****************************************************************************** ++ Avalanche Interrupt number ++******************************************************************************/ ++#define AVINTNUM(x) ((x) - MIPS_EXCEPTION_OFFSET) ++ ++/******************************************************************************* ++*Linux Interrupt number ++*******************************************************************************/ ++#define LNXINTNUM(x)((x) + MIPS_EXCEPTION_OFFSET) ++ ++ ++ ++#define AVALANCHE_INT_END_PRIMARY (40 + MIPS_EXCEPTION_OFFSET) ++#define AVALANCHE_INT_END_SECONDARY (32 + MIPS_EXCEPTION_OFFSET) ++ ++#define AVALANCHE_INT_END_PRIMARY_REG1 (31 + MIPS_EXCEPTION_OFFSET) ++#define AVALANCHE_INT_END_PRIMARY_REG2 (39 + MIPS_EXCEPTION_OFFSET) ++ ++#define AVALANCHE_INTC_END (AVINTNUM(AVALANCHE_INT_END_PRIMARY) + \ ++ AVINTNUM(AVALANCHE_INT_END_SECONDARY) + \ ++ MIPS_EXCEPTION_OFFSET) ++ ++#if defined(CONFIG_AR7_VLYNQ) ++#define AVALANCHE_INT_END_LOW_VLYNQ (AVALANCHE_INTC_END + 32) ++#define AVALANCHE_INT_END_VLYNQ (AVALANCHE_INTC_END + 32 * CONFIG_AR7_VLYNQ_PORTS) ++#define AVALANCHE_INT_END AVALANCHE_INT_END_VLYNQ ++#else ++#define AVALANCHE_INT_END AVALANCHE_INTC_END ++#endif ++ ++ ++/* ++ * Avalanche interrupt controller register base (primary) ++ */ ++#define AVALANCHE_ICTRL_REGS_BASE AVALANCHE_INTC_BASE ++ ++/****************************************************************************** ++ * Avalanche exception controller register base (secondary) ++ ******************************************************************************/ ++#define AVALANCHE_ECTRL_REGS_BASE (AVALANCHE_ICTRL_REGS_BASE + 0x80) ++ ++ ++/****************************************************************************** ++ * Avalanche Interrupt pacing register base (secondary) ++ ******************************************************************************/ ++#define AVALANCHE_IPACE_REGS_BASE (AVALANCHE_ICTRL_REGS_BASE + 0xA0) ++ ++ ++ ++/****************************************************************************** ++ * Avalanche Interrupt Channel Control register base ++ *****************************************************************************/ ++#define AVALANCHE_CHCTRL_REGS_BASE (AVALANCHE_ICTRL_REGS_BASE + 0x200) ++ ++ ++struct avalanche_ictrl_regs /* Avalanche Interrupt control registers */ ++{ ++ volatile unsigned long intsr1; /* Interrupt Status/Set Register 1 0x00 */ ++ volatile unsigned long intsr2; /* Interrupt Status/Set Register 2 0x04 */ ++ volatile unsigned long unused1; /*0x08 */ ++ volatile unsigned long unused2; /*0x0C */ ++ volatile unsigned long intcr1; /* Interrupt Clear Register 1 0x10 */ ++ volatile unsigned long intcr2; /* Interrupt Clear Register 2 0x14 */ ++ volatile unsigned long unused3; /*0x18 */ ++ volatile unsigned long unused4; /*0x1C */ ++ volatile unsigned long intesr1; /* Interrupt Enable (Set) Register 1 0x20 */ ++ volatile unsigned long intesr2; /* Interrupt Enable (Set) Register 2 0x24 */ ++ volatile unsigned long unused5; /*0x28 */ ++ volatile unsigned long unused6; /*0x2C */ ++ volatile unsigned long intecr1; /* Interrupt Enable Clear Register 1 0x30 */ ++ volatile unsigned long intecr2; /* Interrupt Enable Clear Register 2 0x34 */ ++ volatile unsigned long unused7; /* 0x38 */ ++ volatile unsigned long unused8; /* 0x3c */ ++ volatile unsigned long pintir; /* Priority Interrupt Index Register 0x40 */ ++ volatile unsigned long intmsr; /* Priority Interrupt Mask Index Reg 0x44 */ ++ volatile unsigned long unused9; /* 0x48 */ ++ volatile unsigned long unused10; /* 0x4C */ ++ volatile unsigned long intpolr1; /* Interrupt Polarity Mask register 10x50 */ ++ volatile unsigned long intpolr2; /* Interrupt Polarity Mask register 20x54 */ ++ volatile unsigned long unused11; /* 0x58 */ ++ volatile unsigned long unused12; /*0x5C */ ++ volatile unsigned long inttypr1; /* Interrupt Type Mask register 10x60 */ ++ volatile unsigned long inttypr2; /* Interrupt Type Mask register 20x64 */ ++}; ++ ++struct avalanche_exctrl_regs /* Avalanche Exception control registers */ ++{ ++ volatile unsigned long exsr; /* Exceptions Status/Set register 0x80 */ ++ volatile unsigned long reserved; /*0x84 */ ++ volatile unsigned long excr; /* Exceptions Clear Register 0x88 */ ++ volatile unsigned long reserved1; /*0x8c */ ++ volatile unsigned long exiesr; /* Exceptions Interrupt Enable (set) 0x90 */ ++ volatile unsigned long reserved2; /*0x94 */ ++ volatile unsigned long exiecr; /* Exceptions Interrupt Enable(clear)0x98 */ ++}; ++struct avalanche_ipace_regs ++{ ++ ++ volatile unsigned long ipacep; /* Interrupt pacing register 0xa0 */ ++ volatile unsigned long ipacemap; /*Interrupt Pacing Map Register 0xa4 */ ++ volatile unsigned long ipacemax; /*Interrupt Pacing Max Register 0xa8 */ ++}; ++struct avalanche_channel_int_number ++{ ++ volatile unsigned long cintnr0; /* Channel Interrupt Number Register0x200 */ ++ volatile unsigned long cintnr1; /* Channel Interrupt Number Register0x204 */ ++ volatile unsigned long cintnr2; /* Channel Interrupt Number Register0x208 */ ++ volatile unsigned long cintnr3; /* Channel Interrupt Number Register0x20C */ ++ volatile unsigned long cintnr4; /* Channel Interrupt Number Register0x210 */ ++ volatile unsigned long cintnr5; /* Channel Interrupt Number Register0x214 */ ++ volatile unsigned long cintnr6; /* Channel Interrupt Number Register0x218 */ ++ volatile unsigned long cintnr7; /* Channel Interrupt Number Register0x21C */ ++ volatile unsigned long cintnr8; /* Channel Interrupt Number Register0x220 */ ++ volatile unsigned long cintnr9; /* Channel Interrupt Number Register0x224 */ ++ volatile unsigned long cintnr10; /* Channel Interrupt Number Register0x228 */ ++ volatile unsigned long cintnr11; /* Channel Interrupt Number Register0x22C */ ++ volatile unsigned long cintnr12; /* Channel Interrupt Number Register0x230 */ ++ volatile unsigned long cintnr13; /* Channel Interrupt Number Register0x234 */ ++ volatile unsigned long cintnr14; /* Channel Interrupt Number Register0x238 */ ++ volatile unsigned long cintnr15; /* Channel Interrupt Number Register0x23C */ ++ volatile unsigned long cintnr16; /* Channel Interrupt Number Register0x240 */ ++ volatile unsigned long cintnr17; /* Channel Interrupt Number Register0x244 */ ++ volatile unsigned long cintnr18; /* Channel Interrupt Number Register0x248 */ ++ volatile unsigned long cintnr19; /* Channel Interrupt Number Register0x24C */ ++ volatile unsigned long cintnr20; /* Channel Interrupt Number Register0x250 */ ++ volatile unsigned long cintnr21; /* Channel Interrupt Number Register0x254 */ ++ volatile unsigned long cintnr22; /* Channel Interrupt Number Register0x358 */ ++ volatile unsigned long cintnr23; /* Channel Interrupt Number Register0x35C */ ++ volatile unsigned long cintnr24; /* Channel Interrupt Number Register0x260 */ ++ volatile unsigned long cintnr25; /* Channel Interrupt Number Register0x264 */ ++ volatile unsigned long cintnr26; /* Channel Interrupt Number Register0x268 */ ++ volatile unsigned long cintnr27; /* Channel Interrupt Number Register0x26C */ ++ volatile unsigned long cintnr28; /* Channel Interrupt Number Register0x270 */ ++ volatile unsigned long cintnr29; /* Channel Interrupt Number Register0x274 */ ++ volatile unsigned long cintnr30; /* Channel Interrupt Number Register0x278 */ ++ volatile unsigned long cintnr31; /* Channel Interrupt Number Register0x27C */ ++ volatile unsigned long cintnr32; /* Channel Interrupt Number Register0x280 */ ++ volatile unsigned long cintnr33; /* Channel Interrupt Number Register0x284 */ ++ volatile unsigned long cintnr34; /* Channel Interrupt Number Register0x288 */ ++ volatile unsigned long cintnr35; /* Channel Interrupt Number Register0x28C */ ++ volatile unsigned long cintnr36; /* Channel Interrupt Number Register0x290 */ ++ volatile unsigned long cintnr37; /* Channel Interrupt Number Register0x294 */ ++ volatile unsigned long cintnr38; /* Channel Interrupt Number Register0x298 */ ++ volatile unsigned long cintnr39; /* Channel Interrupt Number Register0x29C */ ++}; ++ ++struct avalanche_interrupt_line_to_channel ++{ ++ unsigned long int_line0; /* Start of primary interrupts */ ++ unsigned long int_line1; ++ unsigned long int_line2; ++ unsigned long int_line3; ++ unsigned long int_line4; ++ unsigned long int_line5; ++ unsigned long int_line6; ++ unsigned long int_line7; ++ unsigned long int_line8; ++ unsigned long int_line9; ++ unsigned long int_line10; ++ unsigned long int_line11; ++ unsigned long int_line12; ++ unsigned long int_line13; ++ unsigned long int_line14; ++ unsigned long int_line15; ++ unsigned long int_line16; ++ unsigned long int_line17; ++ unsigned long int_line18; ++ unsigned long int_line19; ++ unsigned long int_line20; ++ unsigned long int_line21; ++ unsigned long int_line22; ++ unsigned long int_line23; ++ unsigned long int_line24; ++ unsigned long int_line25; ++ unsigned long int_line26; ++ unsigned long int_line27; ++ unsigned long int_line28; ++ unsigned long int_line29; ++ unsigned long int_line30; ++ unsigned long int_line31; ++ unsigned long int_line32; ++ unsigned long int_line33; ++ unsigned long int_line34; ++ unsigned long int_line35; ++ unsigned long int_line36; ++ unsigned long int_line37; ++ unsigned long int_line38; ++ unsigned long int_line39; ++}; ++ ++ ++/* Interrupt Line #'s (Sangam peripherals) */ ++ ++/*------------------------------*/ ++/* Sangam primary interrupts */ ++/*------------------------------*/ ++ ++#define UNIFIED_SECONDARY_INTERRUPT 0 ++#define AVALANCHE_EXT_INT_0 1 ++#define AVALANCHE_EXT_INT_1 2 ++/* Line #3 Reserved */ ++/* Line #4 Reserved */ ++#define AVALANCHE_TIMER_0_INT 5 ++#define AVALANCHE_TIMER_1_INT 6 ++#define AVALANCHE_UART0_INT 7 ++#define AVALANCHE_UART1_INT 8 ++#define AVALANCHE_PDMA_INT0 9 ++#define AVALANCHE_PDMA_INT1 10 ++/* Line #11 Reserved */ ++/* Line #12 Reserved */ ++/* Line #13 Reserved */ ++/* Line #14 Reserved */ ++#define AVALANCHE_ATM_SAR_INT 15 ++/* Line #16 Reserved */ ++/* Line #17 Reserved */ ++/* Line #18 Reserved */ ++#define AVALANCHE_MAC0_INT 19 ++/* Line #20 Reserved */ ++#define AVALANCHE_VLYNQ0_INT 21 ++#define AVALANCHE_CODEC_WAKE_INT 22 ++/* Line #23 Reserved */ ++#define AVALANCHE_USB_INT 24 ++#define AVALANCHE_VLYNQ1_INT 25 ++/* Line #26 Reserved */ ++/* Line #27 Reserved */ ++#define AVALANCHE_MAC1_INT 28 ++#define AVALANCHE_I2CM_INT 29 ++#define AVALANCHE_PDMA_INT2 30 ++#define AVALANCHE_PDMA_INT3 31 ++/* Line #32 Reserved */ ++/* Line #33 Reserved */ ++/* Line #34 Reserved */ ++/* Line #35 Reserved */ ++/* Line #36 Reserved */ ++#define AVALANCHE_VDMA_VT_RX_INT 37 ++#define AVALANCHE_VDMA_VT_TX_INT 38 ++#define AVALANCHE_ADSLSS_INT 39 ++ ++/*-----------------------------------*/ ++/* Sangam Secondary Interrupts */ ++/*-----------------------------------*/ ++#define PRIMARY_INTS 40 ++ ++#define EMIF_INT (7 + PRIMARY_INTS) ++ ++ ++extern void avalanche_int_set(int channel, int line); ++ ++ ++#endif /* _AVALANCHE_INTC_H */ +diff -urN linux.old/include/asm-mips/ar7/avalanche_misc.h linux.dev/include/asm-mips/ar7/avalanche_misc.h +--- linux.old/include/asm-mips/ar7/avalanche_misc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/avalanche_misc.h 2005-11-10 01:10:46.067588500 +0100 +@@ -0,0 +1,174 @@ ++#ifndef _AVALANCHE_MISC_H_ ++#define _AVALANCHE_MISC_H_ ++ ++typedef enum AVALANCHE_ERR_t ++{ ++ AVALANCHE_ERR_OK = 0, /* OK or SUCCESS */ ++ AVALANCHE_ERR_ERROR = -1, /* Unspecified/Generic ERROR */ ++ ++ /* Pointers and args */ ++ AVALANCHE_ERR_INVARG = -2, /* Invaild argument to the call */ ++ AVALANCHE_ERR_NULLPTR = -3, /* NULL pointer */ ++ AVALANCHE_ERR_BADPTR = -4, /* Bad (out of mem) pointer */ ++ ++ /* Memory issues */ ++ AVALANCHE_ERR_ALLOC_FAIL = -10, /* allocation failed */ ++ AVALANCHE_ERR_FREE_FAIL = -11, /* free failed */ ++ AVALANCHE_ERR_MEM_CORRUPT = -12, /* corrupted memory */ ++ AVALANCHE_ERR_BUF_LINK = -13, /* buffer linking failed */ ++ ++ /* Device issues */ ++ AVALANCHE_ERR_DEVICE_TIMEOUT = -20, /* device timeout on read/write */ ++ AVALANCHE_ERR_DEVICE_MALFUNC = -21, /* device malfunction */ ++ ++ AVALANCHE_ERR_INVID = -30 /* Invalid ID */ ++ ++} AVALANCHE_ERR; ++ ++/***************************************************************************** ++ * Reset Control Module ++ *****************************************************************************/ ++ ++typedef enum AVALANCHE_RESET_MODULE_tag ++{ ++ RESET_MODULE_UART0 = 0, ++ RESET_MODULE_UART1 = 1, ++ RESET_MODULE_I2C = 2, ++ RESET_MODULE_TIMER0 = 3, ++ RESET_MODULE_TIMER1 = 4, ++ RESET_MODULE_GPIO = 6, ++ RESET_MODULE_ADSLSS = 7, ++ RESET_MODULE_USBS = 8, ++ RESET_MODULE_SAR = 9, ++ RESET_MODULE_VDMA_VT = 11, ++ RESET_MODULE_FSER = 12, ++ RESET_MODULE_VLYNQ1 = 16, ++ RESET_MODULE_EMAC0 = 17, ++ RESET_MODULE_DMA = 18, ++ RESET_MODULE_BIST = 19, ++ RESET_MODULE_VLYNQ0 = 20, ++ RESET_MODULE_EMAC1 = 21, ++ RESET_MODULE_MDIO = 22, ++ RESET_MODULE_ADSLSS_DSP = 23, ++ RESET_MODULE_EPHY = 26 ++} AVALANCHE_RESET_MODULE_T; ++ ++typedef enum AVALANCHE_RESET_CTRL_tag ++{ ++ IN_RESET = 0, ++ OUT_OF_RESET ++} AVALANCHE_RESET_CTRL_T; ++ ++typedef enum AVALANCHE_SYS_RST_MODE_tag ++{ ++ RESET_SOC_WITH_MEMCTRL = 1, /* SW0 bit in SWRCR register */ ++ RESET_SOC_WITHOUT_MEMCTRL = 2 /* SW1 bit in SWRCR register */ ++} AVALANCHE_SYS_RST_MODE_T; ++ ++typedef enum AVALANCHE_SYS_RESET_STATUS_tag ++{ ++ HARDWARE_RESET = 0, ++ SOFTWARE_RESET0, /* Caused by writing 1 to SW0 bit in SWRCR register */ ++ WATCHDOG_RESET, ++ SOFTWARE_RESET1 /* Caused by writing 1 to SW1 bit in SWRCR register */ ++} AVALANCHE_SYS_RESET_STATUS_T; ++ ++AVALANCHE_RESET_CTRL_T avalanche_get_reset_status(AVALANCHE_RESET_MODULE_T reset_module); ++void avalanche_sys_reset(AVALANCHE_SYS_RST_MODE_T mode); ++AVALANCHE_SYS_RESET_STATUS_T avalanche_get_sys_last_reset_status(void); ++ ++typedef int (*REMOTE_VLYNQ_DEV_RESET_CTRL_FN)(unsigned int reset_module, AVALANCHE_RESET_CTRL_T reset_ctrl); ++ ++/***************************************************************************** ++ * Power Control Module ++ *****************************************************************************/ ++ ++typedef enum AVALANCHE_POWER_CTRL_tag ++{ ++ POWER_CTRL_POWER_UP = 0, ++ POWER_CTRL_POWER_DOWN ++} AVALANCHE_POWER_CTRL_T; ++ ++typedef enum AVALANCHE_SYS_POWER_MODE_tag ++{ ++ GLOBAL_POWER_MODE_RUN = 0, /* All system is up */ ++ GLOBAL_POWER_MODE_IDLE, /* MIPS is power down, all peripherals working */ ++ GLOBAL_POWER_MODE_STANDBY, /* Chip in power down, but clock to ADSKL subsystem is running */ ++ GLOBAL_POWER_MODE_POWER_DOWN /* Total chip is powered down */ ++} AVALANCHE_SYS_POWER_MODE_T; ++ ++void avalanche_power_ctrl(unsigned int power_module, AVALANCHE_POWER_CTRL_T power_ctrl); ++AVALANCHE_POWER_CTRL_T avalanche_get_power_status(unsigned int power_module); ++void avalanche_set_global_power_mode(AVALANCHE_SYS_POWER_MODE_T power_mode); ++AVALANCHE_SYS_POWER_MODE_T avalanche_get_global_power_mode(void); ++ ++/***************************************************************************** ++ * Wakeup Control ++ *****************************************************************************/ ++ ++typedef enum AVALANCHE_WAKEUP_INTERRUPT_tag ++{ ++ WAKEUP_INT0 = 1, ++ WAKEUP_INT1 = 2, ++ WAKEUP_INT2 = 4, ++ WAKEUP_INT3 = 8 ++} AVALANCHE_WAKEUP_INTERRUPT_T; ++ ++typedef enum TNETV1050_WAKEUP_CTRL_tag ++{ ++ WAKEUP_DISABLED = 0, ++ WAKEUP_ENABLED ++} AVALANCHE_WAKEUP_CTRL_T; ++ ++typedef enum TNETV1050_WAKEUP_POLARITY_tag ++{ ++ WAKEUP_ACTIVE_HIGH = 0, ++ WAKEUP_ACTIVE_LOW ++} AVALANCHE_WAKEUP_POLARITY_T; ++ ++void avalanche_wakeup_ctrl(AVALANCHE_WAKEUP_INTERRUPT_T wakeup_int, ++ AVALANCHE_WAKEUP_CTRL_T wakeup_ctrl, ++ AVALANCHE_WAKEUP_POLARITY_T wakeup_polarity); ++ ++/***************************************************************************** ++ * GPIO Control ++ *****************************************************************************/ ++ ++typedef enum AVALANCHE_GPIO_PIN_MODE_tag ++{ ++ FUNCTIONAL_PIN = 0, ++ GPIO_PIN = 1 ++} AVALANCHE_GPIO_PIN_MODE_T; ++ ++typedef enum AVALANCHE_GPIO_PIN_DIRECTION_tag ++{ ++ GPIO_OUTPUT_PIN = 0, ++ GPIO_INPUT_PIN = 1 ++} AVALANCHE_GPIO_PIN_DIRECTION_T; ++ ++typedef enum { GPIO_FALSE, GPIO_TRUE } AVALANCHE_GPIO_BOOL_T; ++ ++void avalanche_gpio_init(void); ++int avalanche_gpio_ctrl(unsigned int gpio_pin, ++ AVALANCHE_GPIO_PIN_MODE_T pin_mode, ++ AVALANCHE_GPIO_PIN_DIRECTION_T pin_direction); ++int avalanche_gpio_ctrl_with_link_count(unsigned int gpio_pin, ++ AVALANCHE_GPIO_PIN_MODE_T pin_mode, ++ AVALANCHE_GPIO_PIN_DIRECTION_T pin_direction); ++int avalanche_gpio_out_bit(unsigned int gpio_pin, int value); ++int avalanche_gpio_in_bit(unsigned int gpio_pin); ++int avalanche_gpio_out_value(unsigned int out_val, unsigned int set_mask, unsigned int reg_index); ++int avalanche_gpio_out_value_with_link_count(unsigned int out_val, unsigned int set_mask, unsigned int reg_index); ++int avalanche_gpio_in_value(unsigned int *in_val, unsigned int reg_index); ++ ++unsigned int avalanche_get_chip_version_info(void); ++ ++unsigned int avalanche_get_vbus_freq(void); ++void avalanche_set_vbus_freq(unsigned int); ++ ++ ++typedef int (*SET_MDIX_ON_CHIP_FN_T)(unsigned int base_addr, unsigned int operation); ++int avalanche_set_mdix_on_chip(unsigned int base_addr, unsigned int operation); ++unsigned int avalanche_is_mdix_on_chip(void); ++ ++#endif +diff -urN linux.old/include/asm-mips/ar7/avalanche_regs.h linux.dev/include/asm-mips/ar7/avalanche_regs.h +--- linux.old/include/asm-mips/ar7/avalanche_regs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/avalanche_regs.h 2005-11-10 01:10:46.071588750 +0100 +@@ -0,0 +1,567 @@ ++/* ++ * $Id$ ++ * Avalanche Register Descriptions ++ * ++ * Jeff Harrell, jharrell@ti.com ++ * 2000 (c) Texas Instruments Inc. ++ */ ++ ++#ifndef __AVALANCHE_REGS_H ++#define __AVALANCHE_REGS_H ++ ++#include ++#include ++ ++/*----------------------------------------*/ ++/* Base offsets within the Avalanche ASIC */ ++/*----------------------------------------*/ ++ ++#define BBIF_SPACE0 (KSEG1ADDR(0x01000000)) ++#define BBIF_SPACE1 (KSEG1ADDR(0x01800000)) ++#define BBIF_CONTROL (KSEG1ADDR(0x02000000)) ++#define ATM_SAR_BASE (KSEG1ADDR(0x03000000)) ++#define USB_MCU_BASE (KSEG1ADDR(0x03400000)) ++#define DES_BASE (KSEG1ADDR(0x08600000)) ++#define ETH_MACA_BASE (KSEG1ADDR(0x08610000)) ++#define ETH_MACB_BASE (KSEG1ADDR(0x08612800)) ++#define MEM_CTRLR_BASE (KSEG1ADDR(0x08610800)) ++#define GPIO_BASE (KSEG1ADDR(0x08610900)) ++#define CLK_CTRL_BASE (KSEG1ADDR(0x08610A00)) ++#define WATCH_DOG_BASE (KSEG1ADDR(0x08610B00)) ++#define TMR1_BASE (KSEG1ADDR(0x08610C00)) ++#define TRM2_BASE (KSEG1ADDR(0x08610D00)) ++#define UARTA_BASE (KSEG1ADDR(0x08610E00)) ++#define UARTB_BASE (KSEG1ADDR(0x08610F00)) ++#define I2C_BASE (KSEG1ADDR(0x08611000)) ++#define DEV_ID_BASE (KSEG1ADDR(0x08611100)) ++#define USB_BASE (KSEG1ADDR(0x08611200)) ++#define PCI_CONFIG_BASE (KSEG1ADDR(0x08611300)) ++#define DMA_BASE (KSEG1ADDR(0x08611400)) ++#define RESET_CTRL_BASE (KSEG1ADDR(0x08611600)) ++#define DSL_IF_BASE (KSEG1ADDR(0x08611B00)) ++#define INT_CTL_BASE (KSEG1ADDR(0x08612400)) ++#define PHY_BASE (KSEG1ADDR(0x1E000000)) ++ ++/*---------------------------------*/ ++/* Device ID, chip version number */ ++/*---------------------------------*/ ++ ++#define AVALANCHE_CHVN (*(volatile unsigned int *)(DEV_ID_BASE+0x14)) ++#define AVALANCHE_DEVID1 (*(volatile unsigned int *)(DEV_ID_BASE+0x18)) ++#define AVALANCHE_DEVID2 (*(volatile unsigned int *)(DEV_ID_BASE+0x1C)) ++ ++/*----------------------------------*/ ++/* Reset Control VW changed to ptrs */ ++/*----------------------------------*/ ++ ++#define AVALANCHE_PRCR (*(volatile unsigned int *)(RESET_CTRL_BASE + 0x0)) /* Peripheral reset control */ ++#define AVALANCHE_SWRCR (*(volatile unsigned int *)(RESET_CTRL_BASE + 0x4)) /* Software reset control */ ++#define AVALANCHE_RSR (*(volatile unsigned int *)(RESET_CTRL_BASE + 0x8)) /* Reset status register */ ++ ++/* reset control bits */ ++ ++#define AV_RST_UART0 (1<<0) /* Brings UART0 out of reset */ ++#define AV_RST_UART1 (1<<1) /* Brings UART1 out of reset */ ++#define AV_RST_IICM (1<<2) /* Brings the I2CM out of reset */ ++#define AV_RST_TIMER0 (1<<3) /* Brings Timer 0 out of reset */ ++#define AV_RST_TIMER1 (1<<4) /* Brings Timer 1 out of reset */ ++#define AV_RST_DES (1<<5) /* Brings the DES module out of reset */ ++#define AV_RST_GPIO (1<<6) /* Brings the GPIO module out of reset (see note below) */ ++/* ++ JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE ++ If you reset the GPIO interface all of the directions (i/o) of the UART B ++ interface pins are inputs and must be reconfigured so as not to lose the ++ serial console interface ++ JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE ++*/ ++#define AV_RST_BBIF (1<<7) /* Brings the Broadband interface out of reset */ ++#define AV_RST_USB (1<<8) /* Brings the USB module out of reset */ ++#define AV_RST_SAR (1<<9) /* Brings the SAR out of reset */ ++#define AV_RST_HDLC (1<<10) /* Brings the HDLC module out of reset */ ++#define AV_RST_PCI (1<<16) /* Brings the PCI module out of reset */ ++#define AV_RST_ETH_MAC0 (1<<17) /* Brings the Ethernet MAC0 out of reset */ ++#define AV_RST_PICO_DMA (1<<18) /* Brings the PICO DMA module out of reset */ ++#define AV_RST_BIST (1<<19) /* Brings the BIST module out of reset */ ++#define AV_RST_DSP (1<<20) /* Brings the DSP sub system out of reset */ ++#define AV_RST_ETH_MAC1 (1<<21) /* Brings the Ethernet MAC1 out of reset */ ++ ++/*----------------------*/ ++/* Physical interfaces */ ++/*----------------------*/ ++ ++/* Phy loopback */ ++#define PHY_LOOPBACK 1 ++ ++ ++/* Phy 0 */ ++#define PHY0BASE (PHY_BASE) ++#define PHY0RST (*(volatile unsigned char *) (PHY0BASE)) /* reset */ ++#define PHY0CTRL (*(volatile unsigned char *) (PHY0BASE+0x5)) /* control */ ++#define PHY0RACPCTRL (*(volatile unsigned char *) (PHY0BASE+0x50)) /* RACP control/status */ ++#define PHY0TACPCTRL (*(volatile unsigned char *) (PHY0BASE+0x60)) /* TACP idle/unassigned cell hdr */ ++#define PHY0RACPINT (*(volatile unsigned char *) (PHY0BASE+0x51)) /* RACP interrupt enable/Status */ ++ ++ ++/* Phy 1 */ ++ ++#define PHY1BASE (PHY_BASE + 0x100000) ++#define PHY1RST (*(volatile unsigned char *) (PHY1BASE)) /* reset */ ++#define PHY1CTRL (*(volatile unsigned char *) (PHY1BASE+0x5)) /* control */ ++#define PHY1RACPCTRL (*(volatile unsigned char *) (PHY1BASE+0x50)) ++#define PHY1TACPCTRL (*(volatile unsigned char *) (PHY1BASE+0x60)) ++#define PHY1RACPINT (*(volatile unsigned char *) (PHY1BASE+0x51)) ++ ++/* Phy 2 */ ++ ++#define PHY2BASE (PHY_BASE + 0x200000) ++#define PHY2RST (*(volatile unsigned char *) (PHY2BASE)) /* reset */ ++#define PHY2CTRL (*(volatile unsigned char *) (PHY2BASE+0x5)) /* control */ ++#define PHY2RACPCTRL (*(volatile unsigned char *) (PHY2BASE+0x50)) ++#define PHY2TACPCTRL (*(volatile unsigned char *) (PHY2BASE+0x60)) ++#define PHY2RACPINT (*(volatile unsigned char *) (PHY2BASE+0x51)) ++ ++/*-------------------*/ ++/* Avalanche ATM SAR */ ++/*-------------------*/ ++ ++#define AVSAR_SYSCONFIG (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000000)) /* SAR system config register */ ++#define AVSAR_SYSSTATUS (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000004)) /* SAR system status register */ ++#define AVSAR_INT_ENABLE (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000008)) /* SAR interrupt enable register */ ++#define AVSAR_CONN_VPI_VCI (*(volatile unsigned int*)(ATM_SAR_BASE+0x0000000c)) /* VPI/VCI connection config */ ++#define AVSAR_CONN_CONFIG (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000010)) /* Connection config register */ ++#define AVSAR_OAM_CONFIG (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000018)) /* OAM configuration register */ ++ ++/* Transmit completion ring registers */ ++ ++#define AVSAR_TCRAPTR (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000100)) ++#define AVSAR_TCRASIZE (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000104)) ++#define AVSAR_TCRAINTTHRESH (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000108)) ++#define AVSAR_TCRATOTENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x0000010c)) ++#define AVSAR_TCRAFREEENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000110)) ++#define AVSAR_TCRAPENDENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000114)) ++#define AVSAR_TCRAENTINC (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000118)) ++#define AVSAR_TCRBPTR (*(volatile unsigned int *)(ATM_SAR_BASE+0x0000011c)) ++#define AVSAR_TCRBSIZE (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000120)) ++#define AVSAR_TCRBINTTHRESH (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000124)) ++#define AVSAR_TCRBTOTENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000128)) ++#define AVSAR_TCRBFREEENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x0000012c)) ++#define AVSAR_TCRBPENDENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000130)) ++#define AVSAR_TCRBENTINC (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000134)) ++ ++/* Transmit Queue Packet registers */ ++#define AVSAR_TXQUEUE_PKT0 (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000140)) ++#define AVSAR_TXQUEUE_PKT1 (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000144)) ++#define AVSAR_TXQUEUE_PKT2 (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000148)) ++#define AVSAR_TX_FLUSH (*(volatile unsigned int *)(ATM_SAR_BASE+0x0000014C)) ++/* Receive completion ring registers */ ++ ++#define AVSAR_RCRAPTR (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000200)) ++#define AVSAR_RCRASIZE (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000204)) ++#define AVSAR_RCRAINTTHRESH (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000208)) ++#define AVSAR_RCRATOTENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x0000020c)) ++#define AVSAR_RCRAFREEENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000210)) ++#define AVSAR_RCRAPENDENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000214)) ++#define AVSAR_RCRAENTINC (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000218)) ++#define AVSAR_RCRBPTR (*(volatile unsigned int *)(ATM_SAR_BASE+0x0000021c)) ++#define AVSAR_RCRBSIZE (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000220)) ++#define AVSAR_RCRBINTTHRESH (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000224)) ++#define AVSAR_RCRBTOTENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000228)) ++#define AVSAR_RCRBFREEENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x0000022c)) ++#define AVSAR_RCRBPENDENT (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000230)) ++#define AVSAR_RCRBENTINC (*(volatile unsigned int *)(ATM_SAR_BASE+0x00000234)) ++ ++#define AVSAR_RXFBL_ADD0 (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000240)) /* Rx Free buffer list add 0 */ ++#define AVSAR_RXFBL_ADD1 (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000244)) /* Rx Free buffer list add 1 */ ++#define AVSAR_RXFBL_ADD2 (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000248)) /* Rx Free buffer list add 2 */ ++#define AVSAR_RXFBLSIZE_0 (*(volatile unsigned int*)(ATM_SAR_BASE+0x0000028c)) /* Rx Free buffer list size 0 */ ++#define AVSAR_RXFBLSIZE_1 (*(volatile unsigned int*)(ATM_SAR_BASE+0x0000029c)) /* Rx Free buffer list size 1 */ ++#define AVSAR_RXFBLSIZE_2 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000002ac)) /* Rx Free buffer list size 2 */ ++#define AVSAR_RXFBLSIZE_3 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000002bc)) /* Rx Free buffer list size 3 */ ++ ++ ++#if defined(CONFIG_MIPS_EVM3D) || defined(CONFIG_MIPS_AR5D01) || defined(CONFIG_MIPS_AR5W01) ++ ++#define AVSAR_SAR_FREQUENCY (*(volatile unsigned int*)(ATM_SAR_BASE+0x00010480)) ++#define AVSAR_OAM_CC_SINK (*(volatile unsigned int*)(ATM_SAR_BASE+0x00010484)) ++#define AVSAR_OAM_AIS_RDI_RX (*(volatile unsigned int*)(ATM_SAR_BASE+0x00010488)) ++#define AVSAR_OAM_CPID0 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104E0)) ++#define AVSAR_OAM_LLID0 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104F0)) ++#define AVSAR_OAM_CPID1 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104E4)) ++#define AVSAR_OAM_LLID1 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104F4)) ++#define AVSAR_OAM_CPID2 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104E8)) ++#define AVSAR_OAM_LLID2 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104F8)) ++#define AVSAR_OAM_CPID3 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104EC)) ++#define AVSAR_OAM_LLID3 (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104FC)) ++#define AVSAR_OAM_CORR_TAG (*(volatile unsigned int*)(ATM_SAR_BASE+0x00010500)) ++#define AVSAR_OAM_FAR_COUNT (*(volatile unsigned int*)(ATM_SAR_BASE+0x00010520)) ++#define AVSAR_OAM_NEAR_COUNT (*(volatile unsigned int*)(ATM_SAR_BASE+0x00010540)) ++#define AVSAR_OAM_CONFIG_REG (*(volatile unsigned int*)(ATM_SAR_BASE+0x00000018)) ++#define AVSAR_FAIRNESS_REG (*(volatile unsigned int*)(ATM_SAR_BASE+0x000104B8)) ++#define AVSAR_UBR_PCR_REG (*(volatile unsigned int*)(ATM_SAR_BASE+0x00010490)) ++ ++ ++/* ++ ++#define OAM_CPID_ADD 0xa30104e0 ++ ++#define OAM_LLID_ADD 0xa30104f0 ++ ++#define OAM_LLID_VAL 0xffffffff ++ ++#define OAM_CORR_TAG 0xa3010500 ++ ++#define OAM_FAR_COUNT_ADD 0xa3010520 ++ ++#define OAM_NEAR_COUNT_ADD 0xa3010540 ++ ++#define OAM_CONFIG_REG_ADD 0xa3000018 ++*/ ++ ++ ++#else /* CONFIG_MIPS_EVM3 || CONFIG_MIPS_ACPEP */ ++ ++#define AVSAR_SAR_FREQUENCY (*(volatile unsigned int*)(ATM_SAR_BASE+0x00012000)) ++#define AVSAR_OAM_CC_SINK (*(volatile unsigned int*)(ATM_SAR_BASE+0x00012004)) ++#define AVSAR_OAM_AIS_RDI_RX (*(volatile unsigned int*)(ATM_SAR_BASE+0x00012008)) ++#define AVSAR_OAM_CPID (*(volatile unsigned int*)(ATM_SAR_BASE+0x00012300)) ++ ++#endif /* CONFIG_MIPS_EVM3D || CONFIG_MIPS_AR5D01 || CONFIG_MIPS_AR5W01 */ ++ ++ ++#define AVSAR_STATE_RAM (ATM_SAR_BASE + 0x010000) /* SAR state RAM */ ++#define AVSAR_PDSP_BASE (ATM_SAR_BASE + 0x020000) /* SAR PDSP base address */ ++#define AVSAR_TXDMA_BASE (ATM_SAR_BASE + 0x030000) /* Transmit DMA state base */ ++#define AVSAR_TDMASTATE6 0x18 /* Transmit DMA state word 6 */ ++#define AVSAR_RXDMA_BASE (ATM_SAR_BASE + 0x040000) /* Receive DMA state base */ ++#define AVSAR_RDMASTATE0 0x0 /* Receive DMA state word 0 */ ++ ++/*------------------------------------------*/ ++/* DSL Interface */ ++/*------------------------------------------*/ ++ ++#define AVDSL_TX_EN (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000000)) ++#define AVDSL_RX_EN (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000004)) ++#define AVDSL_POLL (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000008)) ++ ++/* Fast */ ++ ++#define AVDSL_TX_FIFO_ADDR0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x0000000C)) ++#define AVDSL_TX_FIFO_BASE0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000010)) ++#define AVDSL_TX_FIFO_LEN0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000014)) ++#define AVDSL_TX_FIFO_PR0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000018)) ++#define AVDSL_RX_FIFO_ADDR0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x0000001C)) ++#define AVDSL_RX_FIFO_BASE0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000020)) ++#define AVDSL_RX_FIFO_LEN0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000024)) ++#define AVDSL_RX_FIFO_PR0 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000028)) ++ ++/* Interleaved */ ++ ++#define AVDSL_TX_FIFO_ADDR1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x0000002C)) ++#define AVDSL_TX_FIFO_BASE1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000030)) ++#define AVDSL_TX_FIFO_LEN1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000034)) ++#define AVDSL_TX_FIFO_PR1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000038)) ++#define AVDSL_RX_FIFO_ADDR1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x0000003C)) ++#define AVDSL_RX_FIFO_BASE1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000040)) ++#define AVDSL_RX_FIFO_LEN1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000044)) ++#define AVDSL_RX_FIFO_PR1 (*(volatile unsigned int *)(DSL_IF_BASE + 0x00000048)) ++ ++/*------------------------------------------*/ ++/* Broadband I/F */ ++/*------------------------------------------*/ ++ ++#define AVBBIF_BBIF_CNTRL (*(volatile unsigned int *)(BBIF_CONTROL + 0x00000000)) ++#define AVBBIF_ADDR_TRANS_0 (*(volatile unsigned int *)(BBIF_CONTROL + 0x00000004)) ++#define AVBBIF_ADDR_TRANS_1 (*(volatile unsigned int *)(BBIF_CONTROL + 0x00000008)) ++#define AVBBIF_ADDR_XB_MX_BL (*(volatile unsigned int *)(BBIF_CONTROL + 0x0000000C)) ++#define AVBBIF_INFIFO_LVL (*(volatile unsigned int *)(BBIF_CONTROL + 0x00000010)) ++#define AVBBIF_OUTFIFO_LVL (*(volatile unsigned int *)(BBIF_CONTROL + 0x00000014)) ++ ++#define AVBBIF_DISABLED 0x0 ++#define AVBBIF_LBT4040_INT 0x1 ++#define AVBBIF_XBUS 0x2 ++#define AVBBIF_LBT4040_EXT 0x4 ++ ++#define AVBBIF_ADDR_MASK0 0xff000000 /* handles upper bits of BBIF 0 address */ ++#define AVBBIF_ADDR_MASK1 0xff800000 /* handles upper bits of BBIF 1 address */ ++#define AVBBIF_TRANS_MASK 0xff000000 ++/*------------------------------------------*/ ++/* GPIO I/F */ ++/*------------------------------------------*/ ++ ++#define GPIO_DATA_INPUT (*(volatile unsigned int *)(GPIO_BASE + 0x00000000)) ++#define GPIO_DATA_OUTPUT (*(volatile unsigned int *)(GPIO_BASE + 0x00000004)) ++#define GPIO_DATA_DIR (*(volatile unsigned int *)(GPIO_BASE + 0x00000008)) /* 0=output 1=input */ ++#define GPIO_DATA_ENABLE (*(volatile unsigned int *)(GPIO_BASE + 0x0000000C)) /* 0=GPIO Mux 1=GPIO */ ++ ++#define GPIO_0 (1<<21) ++#define GPIO_1 (1<<22) ++#define GPIO_2 (1<<23) ++#define GPIO_3 (1<<24) ++#define EINT_1 (1<<18) ++ ++/* ++ JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE ++ If you reset the GPIO interface all of the directions (i/o) of the UART B ++ interface pins are inputs and must be reconfigured so as not to lose the ++ serial console interface ++ JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE JAH NOTE ++*/ ++ ++/*------------------------------------------*/ ++/* CLK_CTRL */ ++/*------------------------------------------*/ ++#define PERIPH_CLK_CTL (*(volatile unsigned int *)(CLK_CTRL_BASE + 0x00000004)) ++ ++#define PCLK_0_HALF_VBUS (0<<16) ++#define PCLK_EQ_INPUT (1<<16) ++#define BBIF_CLK_HALF_VBUS (0<<17) ++#define BBIF_CLK_EQ_VBUS (1<<17) ++#define BBIF_CLK_EQ_BBCLK (3<<17) ++#define DSP_MODCLK_DSPCLKI (0<<20) ++#define DSP_MODCLK_REFCLKI (1<<20) ++#define USB_CLK_EQ_USBCLKI (0<<21) ++#define USB_CLK_EQ_REFCLKI (1<<21) ++ ++/*------------------------------------------*/ ++/* PCI Control Registers */ ++/*------------------------------------------*/ ++#define PCIC_CONTROL (*(volatile unsigned int *)(PCI_CONFIG_BASE)) ++#define PCIC_CONTROL_CFG_DONE (1<<0) ++#define PCIC_CONTROL_DIS_SLAVE_TO (1<<1) ++#define PCIC_CONTROL_FORCE_DELAY_READ (1<<2) ++#define PCIC_CONTROL_FORCE_DELAY_READ_LINE (1<<3) ++#define PCIC_CONTROL_FORCE_DELAY_READ_MULT (1<<4) ++#define PCIC_CONTROL_MEM_SPACE_EN (1<<5) ++#define PCIC_CONTROL_MEM_MASK (1<<6) ++#define PCIC_CONTROL_IO_SPACE_EN (1<<7) ++#define PCIC_CONTROL_IO_MASK (1<<8) ++/* PCIC_CONTROL_RESERVED (1<<9) */ ++#define PCIC_CONTROL_BASE0_EN (1<<10) ++#define PCIC_CONTROL_BASE1_EN (1<<11) ++#define PCIC_CONTROL_BASE2_EN (1<<12) ++#define PCIC_CONTROL_HOLD_MASTER_WRITE (1<<13) ++#define PCIC_CONTROL_ARBITER_EN (1<<14) ++#define PCIC_INT_SOURCE (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000004)) ++#define PCIC_INT_SOURCE_PWR_MGMT (1<<0) ++#define PCIC_INT_SOURCE_PCI_TARGET (1<<1) ++#define PCIC_INT_SOURCE_PCI_MASTER (1<<2) ++#define PCIC_INT_SOURCE_POWER_WAKEUP (1<<3) ++#define PCIC_INT_SOURCE_PMEIN (1<<4) ++/* PCIC_INT_SOURCE_RESERVED (1<<5) */ ++/* PCIC_INT_SOURCE_RESERVED (1<<6) */ ++#define PCIC_INT_SOURCE_PIC_INTA (1<<7) ++#define PCIC_INT_SOURCE_PIC_INTB (1<<8) ++#define PCIC_INT_SOURCE_PIC_INTC (1<<9) ++#define PCIC_INT_SOURCE_PIC_INTD (1<<10) ++#define PCIC_INT_SOURCE_SOFT_INT0 (1<<11) ++#define PCIC_INT_SOURCE_SOFT_INT1 (1<<12) ++#define PCIC_INT_SOURCE_SOFT_INT2 (1<<13) ++#define PCIC_INT_SOURCE_SOFT_INT3 (1<<14) ++#define PCIC_INT_CLEAR (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000008)) ++#define PCIC_INT_CLEAR_PM (1<<0) ++#define PCIC_INT_CLEAR_PCI_TARGET (1<<1) ++#define PCIC_INT_CLEAR_PCI_MASTER (1<<2) ++/* PCIC_INT_CLEAR_RESERVED (1<<3) */ ++#define PCIC_INT_CLEAR_PMEIN (1<<4) ++/* PCIC_INT_CLEAR_RESERVED (1<<5) */ ++/* PCIC_INT_CLEAR_RESERVED (1<<6) */ ++#define PCIC_INT_CLEAR_PCI_INTA (1<<7) ++#define PCIC_INT_CLEAR_PCI_INTB (1<<8) ++#define PCIC_INT_CLEAR_PCI_INTC (1<<9) ++#define PCIC_INT_CLEAR_PCI_INTD (1<<10) ++#define PCIC_INT_CLEAR_SOFT_INT0 (1<<11) ++#define PCIC_INT_CLEAR_SOFT_INT1 (1<<12) ++#define PCIC_INT_CLEAR_SOFT_INT2 (1<<13) ++#define PCIC_INT_CLEAR_SOFT_INT3 (1<<14) ++#define PCIC_INT_EN_AVAL (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x0000000c)) ++#define PCIC_INT_EN_AVAL_PM (1<<0) ++#define PCIC_INT_EN_AVAL_PCI_TARGET (1<<1) ++#define PCIC_INT_EN_AVAL_PCI_MASTER (1<<2) ++/* PCIC_INT_EN_AVAL_RESERVED (1<<3) */ ++#define PCIC_INT_EN_AVAL_PMEIN (1<<4) ++/* PCIC_INT_EN_AVAL_RESERVED (1<<5) */ ++/* PCIC_INT_EN_AVAL_RESERVED (1<<6) */ ++#define PCIC_INT_EN_AVAL_PCI_INTA (1<<7) ++#define PCIC_INT_EN_AVAL_PCI_INTB (1<<8) ++#define PCIC_INT_EN_AVAL_PCI_INTC (1<<9) ++#define PCIC_INT_EN_AVAL_PCI_INTD (1<<10) ++#define PCIC_INT_EN_AVAL_SOFT_INT0 (1<<11) ++#define PCIC_INT_EN_AVAL_SOFT_INT1 (1<<12) ++#define PCIC_INT_EN_AVAL_SOFT_INT2 (1<<13) ++#define PCIC_INT_EN_AVAL_SOFT_INT3 (1<<14) ++#define PCIC_INT_EN_PCI (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000010)) ++#define PCIC_INT_EN_PCI_PM (1<<0) ++#define PCIC_INT_EN_PCI_PCI_TARGET (1<<1) ++#define PCIC_INT_EN_PCI_PCI_MASTER (1<<2) ++/* PCIC_INT_EN_PCI_RESERVED (1<<3) */ ++#define PCIC_INT_EN_PCI_PMEIN (1<<4) ++/* PCIC_INT_EN_PCI_RESERVED (1<<5) */ ++/* PCIC_INT_EN_PCI_RESERVED (1<<6) */ ++#define PCIC_INT_EN_PCI_PCI_INTA (1<<7) ++#define PCIC_INT_EN_PCI_PCI_INTB (1<<8) ++#define PCIC_INT_EN_PCI_PCI_INTC (1<<9) ++#define PCIC_INT_EN_PCI_PCI_INTD (1<<10) ++#define PCIC_INT_EN_PCI_SOFT_INT0 (1<<11) ++#define PCIC_INT_EN_PCI_SOFT_INT1 (1<<12) ++#define PCIC_INT_EN_PCI_SOFT_INT2 (1<<13) ++#define PCIC_INT_EN_PCI_SOFT_INT3 (1<<14) ++#define PCIC_INT_SWSET (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000014)) ++#define PCIC_INT_SWSET_SOFT_INT0 (1<<0) ++#define PCIC_INT_SWSET_SOFT_INT1 (1<<1) ++#define PCIC_INT_SWSET_SOFT_INT2 (1<<2) ++#define PCIC_INT_SWSET_SOFT_INT3 (1<<3) ++#define PCIC_PM_CTL (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000018)) ++#define PCIC_PM_CTL_PWR_STATE_MASK (0x02) ++/* PCIC_PM_CTL_RESERVED (1<<2) */ ++/* PCIC_PM_CTL_RESERVED (1<<3) */ ++/* PCIC_PM_CTL_RESERVED (1<<4) */ ++/* PCIC_PM_CTL_RESERVED (1<<5) */ ++/* PCIC_PM_CTL_RESERVED (1<<6) */ ++/* PCIC_PM_CTL_RESERVED (1<<7) */ ++/* PCIC_PM_CTL_RESERVED (1<<8) */ ++/* PCIC_PM_CTL_RESERVED (1<<9) */ ++#define PCIC_PM_CTL_PWR_SUPPORT (1<<10) ++#define PCIC_PM_CTL_PMEIN (1<<11) ++#define PCIC_PM_CTL_CAP_MASK (*(volatile unsigned short int *)(PCI_CONFIG_BASE + 0x0000001a)) ++#define PCIC_PM_CONSUME (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x0000001c)) ++#define PCIC_PM_CONSUME_D0 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x0000001c)) ++#define PCIC_PM_CONSUME_D1 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x0000001d)) ++#define PCIC_PM_CONSUME_D2 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x0000001e)) ++#define PCIC_PM_CONSUME_D3 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x0000001f)) ++#define PCIC_PM_DISSAPATED (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000020)) ++#define PCIC_PM_DISSAPATED_D0 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x00000020)) ++#define PCIC_PM_DISSAPATED_D1 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x00000021)) ++#define PCIC_PM_DISSAPATED_D2 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x00000022)) ++#define PCIC_PM_DISSAPATED_D3 (*(volatile unsigned char *)(PCI_CONFIG_BASE + 0x00000023)) ++#define PCIC_PM_DATA_SCALE (*(volatile unsigned short int *)(PCI_CONFIG_BASE + 0x00000024)) ++#define PCIC_VEND_DEV_ID (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000028)) ++#define PCIC_SUB_VEND_DEV_ID (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x0000002c)) ++#define PCIC_CLASS_REV_ID (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000030)) ++#define PCIC_MAX_MIN (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000034)) ++#define PCIC_MAST_MEM_AT0 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x0000003c)) ++#define PCIC_MAST_MEM_AT1 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000040)) ++#define PCIC_MAST_MEM_AT2 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000044)) ++#define PCIC_SLAVE_MASK0 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x0000004c)) ++#define PCIC_SLAVE_MASK1 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000050)) ++#define PCIC_SLAVE_MASK2 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000054)) ++#define PCIC_SLAVE_BASE_AT0 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000058)) ++#define PCIC_SLAVE_BASE_AT1 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x0000005c)) ++#define PCIC_SLAVE_BASE_AT2 (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000060)) ++#define PCIC_CONF_COMMAND (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000090)) ++#define PCIC_CONF_ADDR (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000094)) ++#define PCIC_CONF_DATA (*(volatile unsigned int *)(PCI_CONFIG_BASE + 0x00000098)) ++ ++/*------------------------------------------*/ ++/* IIC_INTERFACE */ ++/*------------------------------------------*/ ++#define I2C_DATA_HI (*(volatile unsigned int *)(I2C_BASE + 0x0)) ++#define I2C_DATA_LOW (*(volatile unsigned int *)(I2C_BASE + 0x4)) ++#define I2C_CONFIG (*(volatile unsigned int *)(I2C_BASE + 0x8)) ++#define I2C_DATA_READ (*(volatile unsigned int *)(I2C_BASE + 0xC)) ++#define I2C_CLOCK_DIV (*(volatile unsigned int *)(I2C_BASE + 0x10)) ++ ++#define I2CWRITE 0x200 ++#define I2CREAD 0x300 ++#define I2C_END_BURST 0x400 ++ ++/* read bits */ ++#define I2C_READ_ERROR 0x8000 ++#define I2C_READ_COMPLETE 0x4000 ++#define I2C_READ_BUSY 0x2000 ++ ++/* device types */ ++#define I2C_IO_EXPANDER 0x2 ++#define I2C_RTC 0xd ++ ++/* device Addresses on I2C bus (EVM3) */ ++#define SEVEN_SEGMENT_DISP 0x23 /* Device type = 0x2, Addr = 3 */ ++#define EVM3_RTC 0xd0 /* Device type = 0xd, Addr = 0 */ ++#define EVM3_RTC_I2C_ADDR 0x0 ++ ++/*------------------------------------------*/ ++/* Ethernet MAC register offset definitions */ ++/*------------------------------------------*/ ++#define VMAC_DMACONFIG(X) (*(volatile unsigned int *)(X + 0x00000000)) ++#define VMAC_INTSTS(X) (*(volatile unsigned int *)(X + 0x00000004)) ++#define VMAC_INTMASK(X) (*(volatile unsigned int *)(X + 0x00000008)) ++ ++#define VMAC_WRAPCLK(X) (*(volatile unsigned int *)(X + 0x00000340)) ++#define VMAC_STATSBASE(X) (*(volatile unsigned int *)(X + 0x00000400)) ++ ++#define VMAC_TCRPTR(X) (*(volatile unsigned int *)(X + 0x00000100)) ++#define VMAC_TCRSIZE(X) (*(volatile unsigned int *)(X + 0x00000104)) ++#define VMAC_TCRINTTHRESH(X) (*(volatile unsigned int *)(X + 0x00000108)) ++#define VMAC_TCRTOTENT(X) (*(volatile unsigned int *)(X + 0x0000010C)) ++#define VMAC_TCRFREEENT(X) (*(volatile unsigned int *)(X + 0x00000110)) ++#define VMAC_TCRPENDENT(X) (*(volatile unsigned int *)(X + 0x00000114)) ++#define VMAC_TCRENTINC(X) (*(volatile unsigned int *)(X + 0x00000118)) ++#define VMAC_TXISRPACE(X) (*(volatile unsigned int *)(X + 0x0000011c)) ++ ++ ++#define VMAC_TDMASTATE0(X) (*(volatile unsigned int *)(X + 0x00000120)) ++#define VMAC_TDMASTATE1(X) (*(volatile unsigned int *)(X + 0x00000124)) ++#define VMAC_TDMASTATE2(X) (*(volatile unsigned int *)(X + 0x00000128)) ++#define VMAC_TDMASTATE3(X) (*(volatile unsigned int *)(X + 0x0000012C)) ++#define VMAC_TDMASTATE4(X) (*(volatile unsigned int *)(X + 0x00000130)) ++#define VMAC_TDMASTATE5(X) (*(volatile unsigned int *)(X + 0x00000134)) ++#define VMAC_TDMASTATE6(X) (*(volatile unsigned int *)(X + 0x00000138)) ++#define VMAC_TDMASTATE7(X) (*(volatile unsigned int *)(X + 0x0000013C)) ++#define VMAC_TXPADDCNT(X) (*(volatile unsigned int *)(X + 0x00000140)) ++#define VMAC_TXPADDSTART(X) (*(volatile unsigned int *)(X + 0x00000144)) ++#define VMAC_TXPADDEND(X) (*(volatile unsigned int *)(X + 0x00000148)) ++#define VMAC_TXQFLUSH(X) (*(volatile unsigned int *)(X + 0x0000014C)) ++ ++#define VMAC_RCRPTR(X) (*(volatile unsigned int *)(X + 0x00000200)) ++#define VMAC_RCRSIZE(X) (*(volatile unsigned int *)(X + 0x00000204)) ++#define VMAC_RCRINTTHRESH(X) (*(volatile unsigned int *)(X + 0x00000208)) ++#define VMAC_RCRTOTENT(X) (*(volatile unsigned int *)(X + 0x0000020C)) ++#define VMAC_RCRFREEENT(X) (*(volatile unsigned int *)(X + 0x00000210)) ++#define VMAC_RCRPENDENT(X) (*(volatile unsigned int *)(X + 0x00000214)) ++#define VMAC_RCRENTINC(X) (*(volatile unsigned int *)(X + 0x00000218)) ++#define VMAC_RXISRPACE(X) (*(volatile unsigned int *)(X + 0x0000021c)) ++ ++#define VMAC_RDMASTATE0(X) (*(volatile unsigned int *)(X + 0x00000220)) ++#define VMAC_RDMASTATE1(X) (*(volatile unsigned int *)(X + 0x00000224)) ++#define VMAC_RDMASTATE2(X) (*(volatile unsigned int *)(X + 0x00000228)) ++#define VMAC_RDMASTATE3(X) (*(volatile unsigned int *)(X + 0x0000022C)) ++#define VMAC_RDMASTATE4(X) (*(volatile unsigned int *)(X + 0x00000230)) ++#define VMAC_RDMASTATE5(X) (*(volatile unsigned int *)(X + 0x00000234)) ++#define VMAC_RDMASTATE6(X) (*(volatile unsigned int *)(X + 0x00000238)) ++#define VMAC_RDMASTATE7(X) (*(volatile unsigned int *)(X + 0x0000023C)) ++#define VMAC_FBLADDCNT(X) (*(volatile unsigned int *)(X + 0x00000240)) ++#define VMAC_FBLADDSTART(X) (*(volatile unsigned int *)(X + 0x00000244)) ++#define VMAC_FBLADDEND(X) (*(volatile unsigned int *)(X + 0x00000248)) ++#define VMAC_RXONOFF(X) (*(volatile unsigned int *)(X + 0x0000024C)) ++ ++#define VMAC_FBL0NEXTD(X) (*(volatile unsigned int *)(X + 0x00000280)) ++#define VMAC_FBL0LASTD(X) (*(volatile unsigned int *)(X + 0x00000284)) ++#define VMAC_FBL0COUNTD(X) (*(volatile unsigned int *)(X + 0x00000288)) ++#define VMAC_FBL0BUFSIZE(X) (*(volatile unsigned int *)(X + 0x0000028C)) ++ ++#define VMAC_MACCONTROL(X) (*(volatile unsigned int *)(X + 0x00000300)) ++#define VMAC_MACSTATUS(X) (*(volatile unsigned int *)(X + 0x00000304)) ++#define VMAC_MACADDRHI(X) (*(volatile unsigned int *)(X + 0x00000308)) ++#define VMAC_MACADDRLO(X) (*(volatile unsigned int *)(X + 0x0000030C)) ++#define VMAC_MACHASH1(X) (*(volatile unsigned int *)(X + 0x00000310)) ++#define VMAC_MACHASH2(X) (*(volatile unsigned int *)(X + 0x00000314)) ++ ++#define VMAC_WRAPCLK(X) (*(volatile unsigned int *)(X + 0x00000340)) ++#define VMAC_BOFTEST(X) (*(volatile unsigned int *)(X + 0x00000344)) ++#define VMAC_PACTEST(X) (*(volatile unsigned int *)(X + 0x00000348)) ++#define VMAC_PAUSEOP(X) (*(volatile unsigned int *)(X + 0x0000034C)) ++ ++#define VMAC_MDIOCONTROL(X) (*(volatile unsigned int *)(X + 0x00000380)) ++#define VMAC_MDIOUSERACCESS(X) (*(volatile unsigned int *)(X +0x00000384)) ++#define VMAC_MDIOACK(X) (*(volatile unsigned int *)(X + 0x00000388)) ++#define VMAC_MDIOLINK(X) (*(volatile unsigned int *)(X + 0x0000038C)) ++#define VMAC_MDIOMACPHY(X) (*(volatile unsigned int *)(X + 0x00000390)) ++ ++#define VMAC_STATS_BASE(X) (X + 0x00000400) ++ ++#endif __AVALANCHE_REGS_H ++ ++ ++ ++ ++ ++ +diff -urN linux.old/include/asm-mips/ar7/avalanche_types.h linux.dev/include/asm-mips/ar7/avalanche_types.h +--- linux.old/include/asm-mips/ar7/avalanche_types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/avalanche_types.h 2005-11-10 01:10:46.071588750 +0100 +@@ -0,0 +1,126 @@ ++/*------------------------------------------------------------------------------------------*\ ++\*------------------------------------------------------------------------------------------*/ ++#ifndef _avalanche_types_h_ ++#define _avalanche_types_h_ ++ ++/*--- #include ---*/ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++#ifndef FALSE ++#define FALSE 0 ++#endif ++#ifndef NULL ++#define NULL (void *)0 ++#endif ++ ++/*------------------------------------------------------------------------------------------*\ ++ * Typen für Texas GPL Module ++\*------------------------------------------------------------------------------------------*/ ++#ifndef __UINT8_T__ ++typedef unsigned char UINT8; ++#define __UINT8_T__ ++#endif ++ ++#ifndef __UCHAR_T__ ++typedef unsigned char UCHAR; ++#define __UCHAR_T__ ++#endif ++ ++#ifndef __INT8_T__ ++typedef signed char INT8; ++#define __INT8_T__ ++#endif ++ ++#ifndef __UINT16_T__ ++typedef unsigned short UINT16; ++#define __UINT16_T__ ++#endif ++ ++#ifndef __USHORT_T__ ++typedef unsigned short USHORT; ++#define __USHORT_T__ ++#endif ++ ++#ifndef __INT16_T__ ++typedef signed short INT16; ++#define __INT16_T__ ++#endif ++ ++#ifndef __UINT32_T__ ++typedef unsigned int UINT32; ++#define __UINT32_T__ ++#endif ++ ++#ifndef __UINT_T__ ++typedef unsigned int UINT; ++#define __UINT_T__ ++#endif ++ ++#ifndef __INT32_T__ ++typedef signed int INT32; ++#define __INT32_T__ ++#endif ++ ++#ifndef __ULONG_T__ ++typedef unsigned long ULONG; ++#define __ULONG_T__ ++#endif ++ ++#ifndef __BOOL_T__ ++typedef int BOOL; ++#define __BOOL_T__ ++#endif ++ ++#ifndef __STATUS_T__ ++typedef int STATUS; ++#define __STATUS_T__ ++#endif ++ ++/*------------------------------------------------------------------------------------------*\ ++\*------------------------------------------------------------------------------------------*/ ++typedef void (*p_vlynq_intr_cntrl_isr_t)(void *,void *,void *); ++typedef INT32 (*p_vlynq_interrupt_vector_set_t)(void *, UINT32, UINT32, INT32, INT32, INT32); ++typedef INT32 (*p_vlynq_interrupt_vector_cntl_t)(void *, UINT32, INT32, UINT32); ++typedef UINT32 (*p_vlynq_interrupt_get_count_t)(void *, UINT32); ++typedef INT32 (*p_vlynq_install_isr_t)(void *, UINT32, p_vlynq_intr_cntrl_isr_t, void *, void *, void *); ++typedef INT32 (*p_vlynq_uninstall_isr_t)(void *, UINT32, void *, void *, void *); ++typedef void (*p_vlynq_root_isr_t)(void *); ++typedef void (*p_vlynq_delay_t)(UINT32); ++typedef INT32 (*p_vlynq_interrupt_vector_map_t)(void *, INT32, UINT32, UINT32); ++typedef INT32 (*p_vlynq_interrupt_set_polarity_t)(void *, INT32, UINT32, INT32); ++typedef INT32 (*p_vlynq_interrupt_get_polarity_t)(void *, INT32, UINT32); ++typedef INT32 (*p_vlynq_interrupt_set_type_t)(void *, INT32, UINT32, INT32); ++typedef INT32 (*p_vlynq_interrupt_get_type_t)(void *, INT32, UINT32); ++typedef INT32 (*p_vlynq_interrupt_enable_t)(void *, INT32, UINT32); ++typedef INT32 (*p_vlynq_interrupt_disable_t)(void *, INT32, UINT32); ++ ++/*------------------------------------------------------------------------------------------*\ ++\*------------------------------------------------------------------------------------------*/ ++extern p_vlynq_interrupt_vector_set_t p_vlynq_interrupt_vector_set; ++extern p_vlynq_interrupt_vector_cntl_t p_vlynq_interrupt_vector_cntl; ++extern p_vlynq_interrupt_get_count_t p_vlynq_interrupt_get_count; ++extern p_vlynq_install_isr_t p_vlynq_install_isr; ++extern p_vlynq_uninstall_isr_t p_vlynq_uninstall_isr; ++extern p_vlynq_root_isr_t p_vlynq_root_isr; ++extern p_vlynq_delay_t p_vlynq_delay; ++extern p_vlynq_interrupt_vector_map_t p_vlynq_interrupt_vector_map; ++extern p_vlynq_interrupt_set_polarity_t p_vlynq_interrupt_set_polarity; ++extern p_vlynq_interrupt_get_polarity_t p_vlynq_interrupt_get_polarity; ++extern p_vlynq_interrupt_set_type_t p_vlynq_interrupt_set_type; ++extern p_vlynq_interrupt_get_type_t p_vlynq_interrupt_get_type; ++extern p_vlynq_interrupt_enable_t p_vlynq_interrupt_enable; ++extern p_vlynq_interrupt_disable_t p_vlynq_interrupt_disable; ++extern void *p_vlynqDevice0; ++extern void *p_vlynqDevice1; ++ ++/*------------------------------------------------------------------------------------------*\ ++\*------------------------------------------------------------------------------------------*/ ++enum _avalanche_need_ { ++ avalanche_need_vlynq, ++ avalanche_need_auto_mdix ++}; ++ ++int avalanche_need(enum _avalanche_need_); ++ ++#endif /*--- #ifndef _avalanche_types_h_ ---*/ +diff -urN linux.old/include/asm-mips/ar7/if_port.h linux.dev/include/asm-mips/ar7/if_port.h +--- linux.old/include/asm-mips/ar7/if_port.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/if_port.h 2005-11-10 01:10:46.071588750 +0100 +@@ -0,0 +1,26 @@ ++/******************************************************************************* ++ * FILE PURPOSE: Interface port id Header file ++ ******************************************************************************* ++ * FILE NAME: if_port.h ++ * ++ * DESCRIPTION: Header file carrying information about port ids of interfaces ++ * ++ * ++ * (C) Copyright 2003, Texas Instruments, Inc ++ ******************************************************************************/ ++#ifndef _IF_PORT_H_ ++#define _IF_PORT_H_ ++ ++#define AVALANCHE_CPMAC_LOW_PORT_ID 0 ++#define AVALANCHE_CPMAC_HIGH_PORT_ID 1 ++#define AVALANCHE_USB_PORT_ID 2 ++#define AVALANCHE_WLAN_PORT_ID 3 ++ ++ ++#define AVALANCHE_MARVELL_BASE_PORT_ID 4 ++ ++/* The marvell ports occupy port ids from 4 to 8 */ ++/* so the next port id number should start at 9 */ ++ ++ ++#endif /* _IF_PORT_H_ */ +diff -urN linux.old/include/asm-mips/ar7/sangam.h linux.dev/include/asm-mips/ar7/sangam.h +--- linux.old/include/asm-mips/ar7/sangam.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/sangam.h 2005-11-10 01:10:46.071588750 +0100 +@@ -0,0 +1,180 @@ ++#ifndef _SANGAM_H_ ++#define _SANGAM_H_ ++ ++#include ++#include ++ ++/*---------------------------------------------------- ++ * Sangam's Module Base Addresses ++ *--------------------------------------------------*/ ++#define AVALANCHE_ADSL_SUB_SYS_MEM_BASE (KSEG1ADDR(0x01000000)) /* AVALANCHE ADSL Mem Base */ ++#define AVALANCHE_BROADBAND_INTERFACE__BASE (KSEG1ADDR(0x02000000)) /* AVALANCHE BBIF */ ++#define AVALANCHE_ATM_SAR_BASE (KSEG1ADDR(0x03000000)) /* AVALANCHE ATM SAR */ ++#define AVALANCHE_USB_SLAVE_BASE (KSEG1ADDR(0x03400000)) /* AVALANCHE USB SLAVE */ ++#define AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE (KSEG1ADDR(0x04000000)) /* AVALANCHE VLYNQ 0 Mem map */ ++#define AVALANCHE_LOW_CPMAC_BASE (KSEG1ADDR(0x08610000)) /* AVALANCHE CPMAC 0 */ ++#define AVALANCHE_EMIF_CONTROL_BASE (KSEG1ADDR(0x08610800)) /* AVALANCHE EMIF */ ++#define AVALANCHE_GPIO_BASE (KSEG1ADDR(0x08610900)) /* AVALANCHE GPIO */ ++#define AVALANCHE_CLOCK_CONTROL_BASE (KSEG1ADDR(0x08610A00)) /* AVALANCHE Clock Control */ ++#define AVALANCHE_WATCHDOG_TIMER_BASE (KSEG1ADDR(0x08610B00)) /* AVALANCHE Watch Dog Timer */ ++#define AVALANCHE_TIMER0_BASE (KSEG1ADDR(0x08610C00)) /* AVALANCHE Timer 1 */ ++#define AVALANCHE_TIMER1_BASE (KSEG1ADDR(0x08610D00)) /* AVALANCHE Timer 2 */ ++#define AVALANCHE_UART0_REGS_BASE (KSEG1ADDR(0x08610E00)) /* AVALANCHE UART 0 */ ++#define AVALANCHE_UART1_REGS_BASE (KSEG1ADDR(0x08610F00)) /* AVALANCHE UART 0 */ ++#define AVALANCHE_I2C_BASE (KSEG1ADDR(0x08611000)) /* AVALANCHE I2C */ ++#define AVALANCHE_USB_SLAVE_CONTROL_BASE (KSEG1ADDR(0x08611200)) /* AVALANCHE USB DMA */ ++#define AVALANCHE_MCDMA0_CTRL_BASE (KSEG1ADDR(0x08611400)) /* AVALANCHE MC DMA 0 (channels 0-3) */ ++#define AVALANCHE_RESET_CONTROL_BASE (KSEG1ADDR(0x08611600)) /* AVALANCHE Reset Control */ ++#define AVALANCHE_BIST_CONTROL_BASE (KSEG1ADDR(0x08611700)) /* AVALANCHE BIST Control */ ++#define AVALANCHE_LOW_VLYNQ_CONTROL_BASE (KSEG1ADDR(0x08611800)) /* AVALANCHE VLYNQ0 Control */ ++#define AVALANCHE_DEVICE_CONFIG_LATCH_BASE (KSEG1ADDR(0x08611A00)) /* AVALANCHE Device Config Latch */ ++#define AVALANCHE_HIGH_VLYNQ_CONTROL_BASE (KSEG1ADDR(0x08611C00)) /* AVALANCHE VLYNQ1 Control */ ++#define AVALANCHE_MDIO_BASE (KSEG1ADDR(0x08611E00)) /* AVALANCHE MDIO */ ++#define AVALANCHE_FSER_BASE (KSEG1ADDR(0x08612000)) /* AVALANCHE FSER base */ ++#define AVALANCHE_INTC_BASE (KSEG1ADDR(0x08612400)) /* AVALANCHE INTC */ ++#define AVALANCHE_HIGH_CPMAC_BASE (KSEG1ADDR(0x08612800)) /* AVALANCHE CPMAC 1 */ ++#define AVALANCHE_HIGH_VLYNQ_MEM_MAP_BASE (KSEG1ADDR(0x0C000000)) /* AVALANCHE VLYNQ 1 Mem map */ ++ ++#define AVALANCHE_SDRAM_BASE 0x14000000UL ++ ++ ++/*---------------------------------------------------- ++ * Sangam Interrupt Map (Primary Interrupts) ++ *--------------------------------------------------*/ ++ ++#define AVALANCHE_UNIFIED_SECONDARY_INT 0 ++#define AVALANCHE_EXT_INT_0 1 ++#define AVALANCHE_EXT_INT_1 2 ++/* Line# 3 to 4 are reserved */ ++#define AVALANCHE_TIMER_0_INT 5 ++#define AVALANCHE_TIMER_1_INT 6 ++#define AVALANCHE_UART0_INT 7 ++#define AVALANCHE_UART1_INT 8 ++#define AVALANCHE_DMA_INT0 9 ++#define AVALANCHE_DMA_INT1 10 ++/* Line# 11 to 14 are reserved */ ++#define AVALANCHE_ATM_SAR_INT 15 ++/* Line# 16 to 18 are reserved */ ++#define AVALANCHE_LOW_CPMAC_INT 19 ++/* Line# 20 is reserved */ ++#define AVALANCHE_LOW_VLYNQ_INT 21 ++#define AVALANCHE_CODEC_WAKEUP_INT 22 ++/* Line# 23 is reserved */ ++#define AVALANCHE_USB_SLAVE_INT 24 ++#define AVALANCHE_HIGH_VLYNQ_INT 25 ++/* Line# 26 to 27 are reserved */ ++#define AVALANCHE_UNIFIED_PHY_INT 28 ++#define AVALANCHE_I2C_INT 29 ++#define AVALANCHE_DMA_INT2 30 ++#define AVALANCHE_DMA_INT3 31 ++/* Line# 32 is reserved */ ++#define AVALANCHE_HIGH_CPMAC_INT 33 ++/* Line# 34 to 36 is reserved */ ++#define AVALANCHE_VDMA_VT_RX_INT 37 ++#define AVALANCHE_VDMA_VT_TX_INT 38 ++#define AVALANCHE_ADSL_SUB_SYSTEM_INT 39 ++ ++ ++#define AVALANCHE_EMIF_INT 47 ++ ++ ++ ++/*----------------------------------------------------------- ++ * Sangam's Reset Bits ++ *---------------------------------------------------------*/ ++ ++#define AVALANCHE_UART0_RESET_BIT 0 ++#define AVALANCHE_UART1_RESET_BIT 1 ++#define AVALANCHE_I2C_RESET_BIT 2 ++#define AVALANCHE_TIMER0_RESET_BIT 3 ++#define AVALANCHE_TIMER1_RESET_BIT 4 ++/* Reset bit 5 is reserved. */ ++#define AVALANCHE_GPIO_RESET_BIT 6 ++#define AVALANCHE_ADSL_SUB_SYS_RESET_BIT 7 ++#define AVALANCHE_USB_SLAVE_RESET_BIT 8 ++#define AVALANCHE_ATM_SAR_RESET_BIT 9 ++/* Reset bit 10 is reserved. */ ++#define AVALANCHE_VDMA_VT_RESET_BIT 11 ++#define AVALANCHE_FSER_RESET_BIT 12 ++/* Reset bit 13 to 15 are reserved */ ++#define AVALANCHE_HIGH_VLYNQ_RESET_BIT 16 ++#define AVALANCHE_LOW_CPMAC_RESET_BIT 17 ++#define AVALANCHE_MCDMA_RESET_BIT 18 ++#define AVALANCHE_BIST_RESET_BIT 19 ++#define AVALANCHE_LOW_VLYNQ_RESET_BIT 20 ++#define AVALANCHE_HIGH_CPMAC_RESET_BIT 21 ++#define AVALANCHE_MDIO_RESET_BIT 22 ++#define AVALANCHE_ADSL_SUB_SYS_DSP_RESET_BIT 23 ++/* Reset bit 24 to 25 are reserved */ ++#define AVALANCHE_LOW_EPHY_RESET_BIT 26 ++/* Reset bit 27 to 31 are reserved */ ++ ++ ++#define AVALANCHE_POWER_MODULE_USBSP 0 ++#define AVALANCHE_POWER_MODULE_WDTP 1 ++#define AVALANCHE_POWER_MODULE_UT0P 2 ++#define AVALANCHE_POWER_MODULE_UT1P 3 ++#define AVALANCHE_POWER_MODULE_IICP 4 ++#define AVALANCHE_POWER_MODULE_VDMAP 5 ++#define AVALANCHE_POWER_MODULE_GPIOP 6 ++#define AVALANCHE_POWER_MODULE_VLYNQ1P 7 ++#define AVALANCHE_POWER_MODULE_SARP 8 ++#define AVALANCHE_POWER_MODULE_ADSLP 9 ++#define AVALANCHE_POWER_MODULE_EMIFP 10 ++#define AVALANCHE_POWER_MODULE_ADSPP 12 ++#define AVALANCHE_POWER_MODULE_RAMP 13 ++#define AVALANCHE_POWER_MODULE_ROMP 14 ++#define AVALANCHE_POWER_MODULE_DMAP 15 ++#define AVALANCHE_POWER_MODULE_BISTP 16 ++#define AVALANCHE_POWER_MODULE_TIMER0P 18 ++#define AVALANCHE_POWER_MODULE_TIMER1P 19 ++#define AVALANCHE_POWER_MODULE_EMAC0P 20 ++#define AVALANCHE_POWER_MODULE_EMAC1P 22 ++#define AVALANCHE_POWER_MODULE_EPHYP 24 ++#define AVALANCHE_POWER_MODULE_VLYNQ0P 27 ++ ++ ++ ++ ++ ++/* ++ * Sangam board vectors ++ */ ++ ++#define AVALANCHE_VECS (KSEG1ADDR(AVALANCHE_SDRAM_BASE)) ++#define AVALANCHE_VECS_KSEG0 (KSEG0ADDR(AVALANCHE_SDRAM_BASE)) ++ ++/*----------------------------------------------------------------------------- ++ * Sangam's system register. ++ * ++ *---------------------------------------------------------------------------*/ ++#define AVALANCHE_DCL_BOOTCR (KSEG1ADDR(0x08611A00)) ++#define AVALANCHE_EMIF_SDRAM_CFG (AVALANCHE_EMIF_CONTROL_BASE + 0x8) ++#define AVALANCHE_RST_CTRL_PRCR (KSEG1ADDR(0x08611600)) ++#define AVALANCHE_RST_CTRL_SWRCR (KSEG1ADDR(0x08611604)) ++#define AVALANCHE_RST_CTRL_RSR (KSEG1ADDR(0x08611600)) ++ ++#define AVALANCHE_POWER_CTRL_PDCR (KSEG1ADDR(0x08610A00)) ++#define AVALANCHE_WAKEUP_CTRL_WKCR (KSEG1ADDR(0x08610A0C)) ++ ++#define AVALANCHE_GPIO_DATA_IN (AVALANCHE_GPIO_BASE + 0x0) ++#define AVALANCHE_GPIO_DATA_OUT (AVALANCHE_GPIO_BASE + 0x4) ++#define AVALANCHE_GPIO_DIR (AVALANCHE_GPIO_BASE + 0x8) ++#define AVALANCHE_GPIO_ENBL (AVALANCHE_GPIO_BASE + 0xC) ++#define AVALANCHE_CVR (AVALANCHE_GPIO_BASE + 0x14) ++ ++/* ++ * Yamon Prom print address. ++ */ ++#define AVALANCHE_YAMON_FUNCTION_BASE (KSEG1ADDR(0x10000500)) ++#define AVALANCHE_YAMON_PROM_PRINT_COUNT_ADDR (AVALANCHE_YAMON_FUNCTION_BASE + 0x4) /* print_count function */ ++#define AVALANCHE_YAMON_PROM_PRINT_ADDR (AVALANCHE_YAMON_FUNCTION_BASE + 0x34) ++ ++#define AVALANCHE_BASE_BAUD ( 3686400 / 16 ) ++ ++#define AVALANCHE_GPIO_PIN_COUNT 32 ++#define AVALANCHE_GPIO_OFF_MAP {0xF34FFFC0} ++ ++#include "sangam_boards.h" ++ ++#endif /*_SANGAM_H_ */ +diff -urN linux.old/include/asm-mips/ar7/sangam_boards.h linux.dev/include/asm-mips/ar7/sangam_boards.h +--- linux.old/include/asm-mips/ar7/sangam_boards.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/sangam_boards.h 2005-11-10 01:10:46.071588750 +0100 +@@ -0,0 +1,77 @@ ++#ifndef _SANGAM_BOARDS_H ++#define _SANGAM_BOARDS_H ++ ++// Let us define board specific information here. ++ ++ ++#if defined(CONFIG_AR7DB) ++ ++#define AFECLK_FREQ 35328000 ++#define REFCLK_FREQ 25000000 ++#define OSC3_FREQ 24000000 ++#define AVALANCHE_LOW_CPMAC_PHY_MASK 0x80000000 ++#define AVALANCHE_HIGH_CPMAC_PHY_MASK 0x55555555 ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0x80000000 ++ ++#endif ++ ++ ++#if defined(CONFIG_AR7RD) ++#define AFECLK_FREQ 35328000 ++#define REFCLK_FREQ 25000000 ++#define OSC3_FREQ 24000000 ++#define AVALANCHE_LOW_CPMAC_PHY_MASK 0x80000000 ++#define AVALANCHE_HIGH_CPMAC_PHY_MASK 0x2 ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0x80000000 ++#endif ++ ++ ++#if defined(CONFIG_AR7WI) ++#define AFECLK_FREQ 35328000 ++#define REFCLK_FREQ 25000000 ++#define OSC3_FREQ 24000000 ++#define AVALANCHE_LOW_CPMAC_PHY_MASK 0x80000000 ++#define AVALANCHE_HIGH_CPMAC_PHY_MASK 0x2 ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0x80000000 ++#endif ++ ++ ++#if defined(CONFIG_AR7V) ++#define AFECLK_FREQ 35328000 ++#define REFCLK_FREQ 25000000 ++#define OSC3_FREQ 24000000 ++#define AVALANCHE_LOW_CPMAC_PHY_MASK 0x80000000 ++#define AVALANCHE_HIGH_CPMAC_PHY_MASK 0x2 ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0x80000000 ++#endif ++ ++ ++#if defined(CONFIG_AR7WRD) ++#define AFECLK_FREQ 35328000 ++#define REFCLK_FREQ 25000000 ++#define OSC3_FREQ 24000000 ++#define AVALANCHE_LOW_CPMAC_PHY_MASK 0x80000000 ++#define AVALANCHE_HIGH_CPMAC_PHY_MASK 0x00010000 ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0x80000000 ++#endif ++ ++ ++#if defined(CONFIG_AR7VWI) ++#define AFECLK_FREQ 35328000 ++#define REFCLK_FREQ 25000000 ++#define OSC3_FREQ 24000000 ++#define AVALANCHE_LOW_CPMAC_PHY_MASK 0x80000000 ++#define AVALANCHE_HIGH_CPMAC_PHY_MASK 0x00010000 ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0x80000000 ++#endif ++ ++ ++#if defined CONFIG_SEAD2 ++#define AVALANCHE_LOW_CPMAC_PHY_MASK 0xAAAAAAAA ++#define AVALANCHE_HIGH_CPMAC_PHY_MASK 0x55555555 ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0 ++#include ++#endif ++ ++ ++#endif +diff -urN linux.old/include/asm-mips/ar7/tnetd73xx.h linux.dev/include/asm-mips/ar7/tnetd73xx.h +--- linux.old/include/asm-mips/ar7/tnetd73xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/tnetd73xx.h 2005-11-10 01:10:46.075589000 +0100 +@@ -0,0 +1,338 @@ ++/****************************************************************************** ++ * FILE PURPOSE: TNETD73xx Common Header File ++ ****************************************************************************** ++ * FILE NAME: tnetd73xx.h ++ * ++ * DESCRIPTION: shared typedef's, constants and API for TNETD73xx ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++/* ++ * ++ * ++ * These are const, typedef, and api definitions for tnetd73xx. ++ * ++ * NOTES: ++ * 1. This file may be included into both C and Assembly files. ++ * - for .s files, please do #define _ASMLANGUAGE in your ASM file to ++ * avoid C data types (typedefs) below; ++ * - for .c files, you don't have to do anything special. ++ * ++ * 2. This file has a number of sections for each SOC subsystem. When adding ++ * a new constant, find the subsystem you are working on and follow the ++ * name pattern. If you are adding another typedef for your interface, please, ++ * place it with other typedefs and function prototypes. ++ * ++ * 3. Please, DO NOT add any macros or types that are local to a subsystem to avoid ++ * cluttering. Include such items directly into the module's .c file or have a ++ * local .h file to pass data between smaller modules. This file defines only ++ * shared items. ++ */ ++ ++#ifndef __TNETD73XX_H__ ++#define __TNETD73XX_H__ ++ ++#ifndef _ASMLANGUAGE /* This part not for assembly language */ ++ ++extern unsigned int tnetd73xx_mips_freq; ++extern unsigned int tnetd73xx_vbus_freq; ++ ++#include "tnetd73xx_err.h" ++ ++#endif /* _ASMLANGUAGE */ ++ ++ ++/******************************************************************************************* ++* Emerald core specific ++******************************************************************************************** */ ++ ++#ifdef BIG_ENDIAN ++#elif defined(LITTLE_ENDIAN) ++#else ++#error Need to define endianism ++#endif ++ ++#ifndef KSEG_MSK ++#define KSEG_MSK 0xE0000000 /* Most significant 3 bits denote kseg choice */ ++#endif ++ ++#ifndef KSEG_INV_MASK ++#define KSEG_INV_MASK 0x1FFFFFFF /* Inverted mask for kseg address */ ++#endif ++ ++#ifndef KSEG0_BASE ++#define KSEG0_BASE 0x80000000 ++#endif ++ ++#ifndef KSEG1_BASE ++#define KSEG1_BASE 0xA0000000 ++#endif ++ ++#ifndef KSEG0 ++#define KSEG0(addr) (((__u32)(addr) & ~KSEG_MSK) | KSEG0_BASE) ++#endif ++ ++#ifndef KSEG1 ++#define KSEG1(addr) (((__u32)(addr) & ~KSEG_MSK) | KSEG1_BASE) ++#endif ++ ++#ifndef KUSEG ++#define KUSEG(addr) ((__u32)(addr) & ~KSEG_MSK) ++#endif ++ ++#ifndef PHYS_ADDR ++#define PHYS_ADDR(addr) ((addr) & KSEG_INV_MASK) ++#endif ++ ++#ifndef PHYS_TO_K0 ++#define PHYS_TO_K0(addr) (PHYS_ADDR(addr)|KSEG0_BASE) ++#endif ++ ++#ifndef PHYS_TO_K1 ++#define PHYS_TO_K1(addr) (PHYS_ADDR(addr)|KSEG1_BASE) ++#endif ++ ++#ifndef REG8_ADDR ++#define REG8_ADDR(addr) (volatile __u8 *)(PHYS_TO_K1(addr)) ++#define REG8_DATA(addr) (*(volatile __u8 *)(PHYS_TO_K1(addr))) ++#define REG8_WRITE(addr, data) REG8_DATA(addr) = data; ++#define REG8_READ(addr, data) data = (__u8) REG8_DATA(addr); ++#endif ++ ++#ifndef REG16_ADDR ++#define REG16_ADDR(addr) (volatile __u16 *)(PHYS_TO_K1(addr)) ++#define REG16_DATA(addr) (*(volatile __u16 *)(PHYS_TO_K1(addr))) ++#define REG16_WRITE(addr, data) REG16_DATA(addr) = data; ++#define REG16_READ(addr, data) data = (__u16) REG16_DATA(addr); ++#endif ++ ++#ifndef REG32_ADDR ++#define REG32_ADDR(addr) (volatile __u32 *)(PHYS_TO_K1(addr)) ++#define REG32_DATA(addr) (*(volatile __u32 *)(PHYS_TO_K1(addr))) ++#define REG32_WRITE(addr, data) REG32_DATA(addr) = data; ++#define REG32_READ(addr, data) data = (__u32) REG32_DATA(addr); ++#endif ++ ++#ifdef _LINK_KSEG0_ /* Application is linked into KSEG0 space */ ++#define VIRT_ADDR(addr) PHYS_TO_K0(PHYS_ADDR(addr)) ++#endif ++ ++#ifdef _LINK_KSEG1_ /* Application is linked into KSEG1 space */ ++#define VIRT_ADDR(addr) PHYS_TO_K1(PHYS_ADDR(addr)) ++#endif ++ ++#if !defined(_LINK_KSEG0_) && !defined(_LINK_KSEG1_) ++#error You must define _LINK_KSEG0_ or _LINK_KSEG1_ to compile the code. ++#endif ++ ++/* TNETD73XX chip definations */ ++ ++#define FREQ_1MHZ 1000000 ++#define TNETD73XX_MIPS_FREQ tnetd73xx_mips_freq /* CPU clock frequency */ ++#define TNETD73XX_VBUS_FREQ tnetd73xx_vbus_freq /* originally (TNETD73XX_MIPS_FREQ/2) */ ++ ++#ifdef AR7SEAD2 ++#define TNETD73XX_MIPS_FREQ_DEFAULT 25000000 /* 25 Mhz for sead2 board crystal */ ++#else ++#define TNETD73XX_MIPS_FREQ_DEFAULT 125000000 /* 125 Mhz */ ++#endif ++#define TNETD73XX_VBUS_FREQ_DEFAULT (TNETD73XX_MIPS_FREQ_DEFAULT / 2) /* Sync mode */ ++ ++ ++ ++/* Module base addresses */ ++#define TNETD73XX_ADSLSS_BASE PHYS_TO_K1(0x01000000) /* ADSLSS Module */ ++#define TNETD73XX_BBIF_CTRL_BASE PHYS_TO_K1(0x02000000) /* BBIF Control */ ++#define TNETD73XX_ATMSAR_BASE PHYS_TO_K1(0x03000000) /* ATM SAR */ ++#define TNETD73XX_USB_BASE PHYS_TO_K1(0x03400000) /* USB Module */ ++#define TNETD73XX_VLYNQ0_BASE PHYS_TO_K1(0x04000000) /* VLYNQ0 Module */ ++#define TNETD73xx_EMAC0_BASE PHYS_TO_K1(0x08610000) /* EMAC0 Module*/ ++#define TNETD73XX_EMIF_BASE PHYS_TO_K1(0x08610800) /* EMIF Module */ ++#define TNETD73XX_GPIO_BASE PHYS_TO_K1(0x08610900) /* GPIO control */ ++#define TNETD73XX_CLOCK_CTRL_BASE PHYS_TO_K1(0x08610A00) /* Clock Control */ ++#define TNETD73XX_WDTIMER_BASE PHYS_TO_K1(0x08610B00) /* WDTIMER Module */ ++#define TNETD73XX_TIMER0_BASE PHYS_TO_K1(0x08610C00) /* TIMER0 Module */ ++#define TNETD73XX_TIMER1_BASE PHYS_TO_K1(0x08610D00) /* TIMER1 Module */ ++#define TNETD73XX_UARTA_BASE PHYS_TO_K1(0x08610E00) /* UART A */ ++#define TNETD73XX_UARTB_BASE PHYS_TO_K1(0x08610F00) /* UART B */ ++#define TNETD73XX_I2C_BASE PHYS_TO_K1(0x08611000) /* I2C Module */ ++#define TNETD73XX_USB_DMA_BASE PHYS_TO_K1(0x08611200) /* USB Module */ ++#define TNETD73XX_MCDMA_BASE PHYS_TO_K1(0x08611400) /* MC-DMA */ ++#define TNETD73xx_VDMAVT_BASE PHYS_TO_K1(0x08611500) /* VDMAVT Control */ ++#define TNETD73XX_RST_CTRL_BASE PHYS_TO_K1(0x08611600) /* Reset Control */ ++#define TNETD73xx_BIST_CTRL_BASE PHYS_TO_K1(0x08611700) /* BIST Control */ ++#define TNETD73xx_VLYNQ0_CTRL_BASE PHYS_TO_K1(0x08611800) /* VLYNQ0 Control */ ++#define TNETD73XX_DCL_BASE PHYS_TO_K1(0x08611A00) /* Device Configuration Latch */ ++#define TNETD73xx_VLYNQ1_CTRL_BASE PHYS_TO_K1(0x08611C00) /* VLYNQ1 Control */ ++#define TNETD73xx_MDIO_BASE PHYS_TO_K1(0x08611E00) /* MDIO Control */ ++#define TNETD73XX_FSER_BASE PHYS_TO_K1(0x08612000) /* FSER Control */ ++#define TNETD73XX_INTC_BASE PHYS_TO_K1(0x08612400) /* Interrupt Controller */ ++#define TNETD73xx_EMAC1_BASE PHYS_TO_K1(0x08612800) /* EMAC1 Module*/ ++#define TNETD73XX_VLYNQ1_BASE PHYS_TO_K1(0x0C000000) /* VLYNQ1 Module */ ++ ++/* BBIF Registers */ ++#define TNETD73XX_BBIF_ADSLADR (TNETD73XX_BBIF_CTRL_BASE + 0x0) ++ ++/* Device Configuration Latch Registers */ ++#define TNETD73XX_DCL_BOOTCR (TNETD73XX_DCL_BASE + 0x0) ++#define TNETD73XX_DCL_DPLLSELR (TNETD73XX_DCL_BASE + 0x10) ++#define TNETD73XX_DCL_SPEEDCTLR (TNETD73XX_DCL_BASE + 0x14) ++#define TNETD73XX_DCL_SPEEDPWDR (TNETD73XX_DCL_BASE + 0x18) ++#define TNETD73XX_DCL_SPEEDCAPR (TNETD73XX_DCL_BASE + 0x1C) ++ ++/* GPIO Control */ ++#define TNETD73XX_GPIODINR (TNETD73XX_GPIO_BASE + 0x0) ++#define TNETD73XX_GPIODOUTR (TNETD73XX_GPIO_BASE + 0x4) ++#define TNETD73XX_GPIOPDIRR (TNETD73XX_GPIO_BASE + 0x8) ++#define TNETD73XX_GPIOENR (TNETD73XX_GPIO_BASE + 0xC) ++#define TNETD73XX_CVR (TNETD73XX_GPIO_BASE + 0x14) ++#define TNETD73XX_DIDR1 (TNETD73XX_GPIO_BASE + 0x18) ++#define TNETD73XX_DIDR2 (TNETD73XX_GPIO_BASE + 0x1C) ++ ++/* Reset Control */ ++#define TNETD73XX_RST_CTRL_PRCR (TNETD73XX_RST_CTRL_BASE + 0x0) ++#define TNETD73XX_RST_CTRL_SWRCR (TNETD73XX_RST_CTRL_BASE + 0x4) ++#define TNETD73XX_RST_CTRL_RSR (TNETD73XX_RST_CTRL_BASE + 0x8) ++ ++/* Power Control */ ++#define TNETD73XX_POWER_CTRL_PDCR (TNETD73XX_CLOCK_CTRL_BASE + 0x0) ++#define TNETD73XX_POWER_CTRL_PCLKCR (TNETD73XX_CLOCK_CTRL_BASE + 0x4) ++#define TNETD73XX_POWER_CTRL_PDUCR (TNETD73XX_CLOCK_CTRL_BASE + 0x8) ++#define TNETD73XX_POWER_CTRL_WKCR (TNETD73XX_CLOCK_CTRL_BASE + 0xC) ++ ++/* Clock Control */ ++#define TNETD73XX_CLK_CTRL_SCLKCR (TNETD73XX_CLOCK_CTRL_BASE + 0x20) ++#define TNETD73XX_CLK_CTRL_SCLKPLLCR (TNETD73XX_CLOCK_CTRL_BASE + 0x30) ++#define TNETD73XX_CLK_CTRL_MCLKCR (TNETD73XX_CLOCK_CTRL_BASE + 0x40) ++#define TNETD73XX_CLK_CTRL_MCLKPLLCR (TNETD73XX_CLOCK_CTRL_BASE + 0x50) ++#define TNETD73XX_CLK_CTRL_UCLKCR (TNETD73XX_CLOCK_CTRL_BASE + 0x60) ++#define TNETD73XX_CLK_CTRL_UCLKPLLCR (TNETD73XX_CLOCK_CTRL_BASE + 0x70) ++#define TNETD73XX_CLK_CTRL_ACLKCR0 (TNETD73XX_CLOCK_CTRL_BASE + 0x80) ++#define TNETD73XX_CLK_CTRL_ACLKPLLCR0 (TNETD73XX_CLOCK_CTRL_BASE + 0x90) ++#define TNETD73XX_CLK_CTRL_ACLKCR1 (TNETD73XX_CLOCK_CTRL_BASE + 0xA0) ++#define TNETD73XX_CLK_CTRL_ACLKPLLCR1 (TNETD73XX_CLOCK_CTRL_BASE + 0xB0) ++ ++/* EMIF control */ ++#define TNETD73XX_EMIF_SDRAM_CFG ( TNETD73XX_EMIF_BASE + 0x08 ) ++ ++/* UART */ ++#ifdef AR7SEAD2 ++#define TNETD73XX_UART_FREQ 3686400 ++#else ++#define TNETD73XX_UART_FREQ TNETD73XX_VBUS_FREQ ++#endif ++ ++/* Interrupt Controller */ ++ ++/* Primary interrupts */ ++#define TNETD73XX_INTC_UNIFIED_SECONDARY 0 /* Unified secondary interrupt */ ++#define TNETD73XX_INTC_EXTERNAL0 1 /* External Interrupt Line 0 */ ++#define TNETD73XX_INTC_EXTERNAL1 2 /* External Interrupt Line 1 */ ++#define TNETD73XX_INTC_RESERVED3 3 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED4 4 /* Reserved */ ++#define TNETD73XX_INTC_TIMER0 5 /* TIMER 0 int */ ++#define TNETD73XX_INTC_TIMER1 6 /* TIMER 1 int */ ++#define TNETD73XX_INTC_UART0 7 /* UART 0 int */ ++#define TNETD73XX_INTC_UART1 8 /* UART 1 int */ ++#define TNETD73XX_INTC_MCDMA0 9 /* MCDMA 0 int */ ++#define TNETD73XX_INTC_MCDMA1 10 /* MCDMA 1 int */ ++#define TNETD73XX_INTC_RESERVED11 11 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED12 12 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED13 13 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED14 14 /* Reserved */ ++#define TNETD73XX_INTC_ATMSAR 15 /* ATM SAR int */ ++#define TNETD73XX_INTC_RESERVED16 16 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED17 17 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED18 18 /* Reserved */ ++#define TNETD73XX_INTC_EMAC0 19 /* EMAC 0 int */ ++#define TNETD73XX_INTC_RESERVED20 20 /* Reserved */ ++#define TNETD73XX_INTC_VLYNQ0 21 /* VLYNQ 0 int */ ++#define TNETD73XX_INTC_CODEC 22 /* CODEC int */ ++#define TNETD73XX_INTC_RESERVED23 23 /* Reserved */ ++#define TNETD73XX_INTC_USBSLAVE 24 /* USB Slave int */ ++#define TNETD73XX_INTC_VLYNQ1 25 /* VLYNQ 1 int */ ++#define TNETD73XX_INTC_RESERVED26 26 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED27 27 /* Reserved */ ++#define TNETD73XX_INTC_ETH_PHY 28 /* Ethernet PHY */ ++#define TNETD73XX_INTC_I2C 29 /* I2C int */ ++#define TNETD73XX_INTC_MCDMA2 30 /* MCDMA 2 int */ ++#define TNETD73XX_INTC_MCDMA3 31 /* MCDMA 3 int */ ++#define TNETD73XX_INTC_RESERVED32 32 /* Reserved */ ++#define TNETD73XX_INTC_EMAC1 33 /* EMAC 1 int */ ++#define TNETD73XX_INTC_RESERVED34 34 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED35 35 /* Reserved */ ++#define TNETD73XX_INTC_RESERVED36 36 /* Reserved */ ++#define TNETD73XX_INTC_VDMAVTRX 37 /* VDMAVTRX */ ++#define TNETD73XX_INTC_VDMAVTTX 38 /* VDMAVTTX */ ++#define TNETD73XX_INTC_ADSLSS 39 /* ADSLSS */ ++ ++/* Secondary interrupts */ ++#define TNETD73XX_INTC_SEC0 40 /* Secondary */ ++#define TNETD73XX_INTC_SEC1 41 /* Secondary */ ++#define TNETD73XX_INTC_SEC2 42 /* Secondary */ ++#define TNETD73XX_INTC_SEC3 43 /* Secondary */ ++#define TNETD73XX_INTC_SEC4 44 /* Secondary */ ++#define TNETD73XX_INTC_SEC5 45 /* Secondary */ ++#define TNETD73XX_INTC_SEC6 46 /* Secondary */ ++#define TNETD73XX_INTC_EMIF 47 /* EMIF */ ++#define TNETD73XX_INTC_SEC8 48 /* Secondary */ ++#define TNETD73XX_INTC_SEC9 49 /* Secondary */ ++#define TNETD73XX_INTC_SEC10 50 /* Secondary */ ++#define TNETD73XX_INTC_SEC11 51 /* Secondary */ ++#define TNETD73XX_INTC_SEC12 52 /* Secondary */ ++#define TNETD73XX_INTC_SEC13 53 /* Secondary */ ++#define TNETD73XX_INTC_SEC14 54 /* Secondary */ ++#define TNETD73XX_INTC_SEC15 55 /* Secondary */ ++#define TNETD73XX_INTC_SEC16 56 /* Secondary */ ++#define TNETD73XX_INTC_SEC17 57 /* Secondary */ ++#define TNETD73XX_INTC_SEC18 58 /* Secondary */ ++#define TNETD73XX_INTC_SEC19 59 /* Secondary */ ++#define TNETD73XX_INTC_SEC20 60 /* Secondary */ ++#define TNETD73XX_INTC_SEC21 61 /* Secondary */ ++#define TNETD73XX_INTC_SEC22 62 /* Secondary */ ++#define TNETD73XX_INTC_SEC23 63 /* Secondary */ ++#define TNETD73XX_INTC_SEC24 64 /* Secondary */ ++#define TNETD73XX_INTC_SEC25 65 /* Secondary */ ++#define TNETD73XX_INTC_SEC26 66 /* Secondary */ ++#define TNETD73XX_INTC_SEC27 67 /* Secondary */ ++#define TNETD73XX_INTC_SEC28 68 /* Secondary */ ++#define TNETD73XX_INTC_SEC29 69 /* Secondary */ ++#define TNETD73XX_INTC_SEC30 70 /* Secondary */ ++#define TNETD73XX_INTC_SEC31 71 /* Secondary */ ++ ++/* These ugly macros are to access the -1 registers, like config1 */ ++#define MFC0_SEL1_OPCODE(dst, src)\ ++ .word (0x40000000 | ((dst)<<16) | ((src)<<11) | 1);\ ++ nop; \ ++ nop; \ ++ nop ++ ++#define MTC0_SEL1_OPCODE(dst, src)\ ++ .word (0x40800000 | ((dst)<<16) | ((src)<<11) | 1);\ ++ nop; \ ++ nop; \ ++ nop ++ ++ ++/* Below are Jade core specific */ ++#define CFG0_4K_IL_MASK 0x00380000 ++#define CFG0_4K_IL_SHIFT 19 ++#define CFG0_4K_IA_MASK 0x00070000 ++#define CFG0_4K_IA_SHIFT 16 ++#define CFG0_4K_IS_MASK 0x01c00000 ++#define CFG0_4K_IS_SHIFT 22 ++ ++#define CFG0_4K_DL_MASK 0x00001c00 ++#define CFG0_4K_DL_SHIFT 10 ++#define CFG0_4K_DA_MASK 0x00000380 ++#define CFG0_4K_DA_SHIFT 7 ++#define CFG0_4K_DS_MASK 0x0000E000 ++#define CFG0_4K_DS_SHIFT 13 ++ ++ ++ ++#endif /* __TNETD73XX_H_ */ +diff -urN linux.old/include/asm-mips/ar7/tnetd73xx_err.h linux.dev/include/asm-mips/ar7/tnetd73xx_err.h +--- linux.old/include/asm-mips/ar7/tnetd73xx_err.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/tnetd73xx_err.h 2005-11-10 01:10:46.075589000 +0100 +@@ -0,0 +1,42 @@ ++/****************************************************************************** ++ * FILE PURPOSE: TNETD73xx Error Definations Header File ++ ****************************************************************************** ++ * FILE NAME: tnetd73xx_err.h ++ * ++ * DESCRIPTION: Error definations for TNETD73XX ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++ ++#ifndef __TNETD73XX_ERR_H__ ++#define __TNETD73XX_ERR_H__ ++ ++typedef enum TNETD73XX_ERR_t ++{ ++ TNETD73XX_ERR_OK = 0, /* OK or SUCCESS */ ++ TNETD73XX_ERR_ERROR = -1, /* Unspecified/Generic ERROR */ ++ ++ /* Pointers and args */ ++ TNETD73XX_ERR_INVARG = -2, /* Invaild argument to the call */ ++ TNETD73XX_ERR_NULLPTR = -3, /* NULL pointer */ ++ TNETD73XX_ERR_BADPTR = -4, /* Bad (out of mem) pointer */ ++ ++ /* Memory issues */ ++ TNETD73XX_ERR_ALLOC_FAIL = -10, /* allocation failed */ ++ TNETD73XX_ERR_FREE_FAIL = -11, /* free failed */ ++ TNETD73XX_ERR_MEM_CORRUPT = -12, /* corrupted memory */ ++ TNETD73XX_ERR_BUF_LINK = -13, /* buffer linking failed */ ++ ++ /* Device issues */ ++ TNETD73XX_ERR_DEVICE_TIMEOUT = -20, /* device timeout on read/write */ ++ TNETD73XX_ERR_DEVICE_MALFUNC = -21, /* device malfunction */ ++ ++ TNETD73XX_ERR_INVID = -30 /* Invalid ID */ ++ ++} TNETD73XX_ERR; ++ ++#endif /* __TNETD73XX_ERR_H__ */ +diff -urN linux.old/include/asm-mips/ar7/tnetd73xx_misc.h linux.dev/include/asm-mips/ar7/tnetd73xx_misc.h +--- linux.old/include/asm-mips/ar7/tnetd73xx_misc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/tnetd73xx_misc.h 2005-11-10 01:10:46.075589000 +0100 +@@ -0,0 +1,239 @@ ++/****************************************************************************** ++ * FILE PURPOSE: TNETD73xx Misc modules API Header ++ ****************************************************************************** ++ * FILE NAME: tnetd73xx_misc.h ++ * ++ * DESCRIPTION: Clock Control, Reset Control, Power Management, GPIO ++ * FSER Modules API ++ * As per TNETD73xx specifications ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - Sharath Kumar PSP TII ++ * 14 Feb 03 - Anant Gole PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __TNETD73XX_MISC_H__ ++#define __TNETD73XX_MISC_H__ ++ ++/***************************************************************************** ++ * Reset Control Module ++ *****************************************************************************/ ++ ++typedef enum TNETD73XX_RESET_MODULE_tag ++{ ++ RESET_MODULE_UART0 = 0, ++ RESET_MODULE_UART1 = 1, ++ RESET_MODULE_I2C = 2, ++ RESET_MODULE_TIMER0 = 3, ++ RESET_MODULE_TIMER1 = 4, ++ RESET_MODULE_GPIO = 6, ++ RESET_MODULE_ADSLSS = 7, ++ RESET_MODULE_USBS = 8, ++ RESET_MODULE_SAR = 9, ++ RESET_MODULE_VDMA_VT = 11, ++ RESET_MODULE_FSER = 12, ++ RESET_MODULE_VLYNQ1 = 16, ++ RESET_MODULE_EMAC0 = 17, ++ RESET_MODULE_DMA = 18, ++ RESET_MODULE_BIST = 19, ++ RESET_MODULE_VLYNQ0 = 20, ++ RESET_MODULE_EMAC1 = 21, ++ RESET_MODULE_MDIO = 22, ++ RESET_MODULE_ADSLSS_DSP = 23, ++ RESET_MODULE_EPHY = 26 ++} TNETD73XX_RESET_MODULE_T; ++ ++typedef enum TNETD73XX_RESET_CTRL_tag ++{ ++ IN_RESET = 0, ++ OUT_OF_RESET ++} TNETD73XX_RESET_CTRL_T; ++ ++typedef enum TNETD73XX_SYS_RST_MODE_tag ++{ ++ RESET_SOC_WITH_MEMCTRL = 1, /* SW0 bit in SWRCR register */ ++ RESET_SOC_WITHOUT_MEMCTRL = 2 /* SW1 bit in SWRCR register */ ++} TNETD73XX_SYS_RST_MODE_T; ++ ++typedef enum TNETD73XX_SYS_RESET_STATUS_tag ++{ ++ HARDWARE_RESET = 0, ++ SOFTWARE_RESET0, /* Caused by writing 1 to SW0 bit in SWRCR register */ ++ WATCHDOG_RESET, ++ SOFTWARE_RESET1 /* Caused by writing 1 to SW1 bit in SWRCR register */ ++} TNETD73XX_SYS_RESET_STATUS_T; ++ ++void tnetd73xx_reset_ctrl(TNETD73XX_RESET_MODULE_T reset_module, ++ TNETD73XX_RESET_CTRL_T reset_ctrl); ++TNETD73XX_RESET_CTRL_T tnetd73xx_get_reset_status(TNETD73XX_RESET_MODULE_T reset_module); ++void tnetd73xx_sys_reset(TNETD73XX_SYS_RST_MODE_T mode); ++TNETD73XX_SYS_RESET_STATUS_T tnetd73xx_get_sys_last_reset_status(void); ++ ++/***************************************************************************** ++ * Power Control Module ++ *****************************************************************************/ ++ ++typedef enum TNETD73XX_POWER_MODULE_tag ++{ ++ POWER_MODULE_USBSP = 0, ++ POWER_MODULE_WDTP = 1, ++ POWER_MODULE_UT0P = 2, ++ POWER_MODULE_UT1P = 3, ++ POWER_MODULE_IICP = 4, ++ POWER_MODULE_VDMAP = 5, ++ POWER_MODULE_GPIOP = 6, ++ POWER_MODULE_VLYNQ1P = 7, ++ POWER_MODULE_SARP = 8, ++ POWER_MODULE_ADSLP = 9, ++ POWER_MODULE_EMIFP = 10, ++ POWER_MODULE_ADSPP = 12, ++ POWER_MODULE_RAMP = 13, ++ POWER_MODULE_ROMP = 14, ++ POWER_MODULE_DMAP = 15, ++ POWER_MODULE_BISTP = 16, ++ POWER_MODULE_TIMER0P = 18, ++ POWER_MODULE_TIMER1P = 19, ++ POWER_MODULE_EMAC0P = 20, ++ POWER_MODULE_EMAC1P = 22, ++ POWER_MODULE_EPHYP = 24, ++ POWER_MODULE_VLYNQ0P = 27, ++} TNETD73XX_POWER_MODULE_T; ++ ++typedef enum TNETD73XX_POWER_CTRL_tag ++{ ++ POWER_CTRL_POWER_UP = 0, ++ POWER_CTRL_POWER_DOWN ++} TNETD73XX_POWER_CTRL_T; ++ ++typedef enum TNETD73XX_SYS_POWER_MODE_tag ++{ ++ GLOBAL_POWER_MODE_RUN = 0, /* All system is up */ ++ GLOBAL_POWER_MODE_IDLE, /* MIPS is power down, all peripherals working */ ++ GLOBAL_POWER_MODE_STANDBY, /* Chip in power down, but clock to ADSKL subsystem is running */ ++ GLOBAL_POWER_MODE_POWER_DOWN /* Total chip is powered down */ ++} TNETD73XX_SYS_POWER_MODE_T; ++ ++void tnetd73xx_power_ctrl(TNETD73XX_POWER_MODULE_T power_module, TNETD73XX_POWER_CTRL_T power_ctrl); ++TNETD73XX_POWER_CTRL_T tnetd73xx_get_pwr_status(TNETD73XX_POWER_MODULE_T power_module); ++void tnetd73xx_set_global_pwr_mode(TNETD73XX_SYS_POWER_MODE_T power_mode); ++TNETD73XX_SYS_POWER_MODE_T tnetd73xx_get_global_pwr_mode(void); ++ ++/***************************************************************************** ++ * Wakeup Control ++ *****************************************************************************/ ++ ++typedef enum TNETD73XX_WAKEUP_INTERRUPT_tag ++{ ++ WAKEUP_INT0 = 1, ++ WAKEUP_INT1 = 2, ++ WAKEUP_INT2 = 4, ++ WAKEUP_INT3 = 8 ++} TNETD73XX_WAKEUP_INTERRUPT_T; ++ ++typedef enum TNETD73XX_WAKEUP_CTRL_tag ++{ ++ WAKEUP_DISABLED = 0, ++ WAKEUP_ENABLED ++} TNETD73XX_WAKEUP_CTRL_T; ++ ++typedef enum TNETD73XX_WAKEUP_POLARITY_tag ++{ ++ WAKEUP_ACTIVE_HIGH = 0, ++ WAKEUP_ACTIVE_LOW ++} TNETD73XX_WAKEUP_POLARITY_T; ++ ++void tnetd73xx_wakeup_ctrl(TNETD73XX_WAKEUP_INTERRUPT_T wakeup_int, ++ TNETD73XX_WAKEUP_CTRL_T wakeup_ctrl, ++ TNETD73XX_WAKEUP_POLARITY_T wakeup_polarity); ++ ++/***************************************************************************** ++ * FSER Control ++ *****************************************************************************/ ++ ++typedef enum TNETD73XX_FSER_MODE_tag ++{ ++ FSER_I2C = 0, ++ FSER_UART = 1 ++} TNETD73XX_FSER_MODE_T; ++ ++void tnetd73xx_fser_ctrl(TNETD73XX_FSER_MODE_T fser_mode); ++ ++/***************************************************************************** ++ * Clock Control ++ *****************************************************************************/ ++ ++#define CLK_MHZ(x) ( (x) * 1000000 ) ++ ++typedef enum TNETD73XX_CLKC_ID_tag ++{ ++ CLKC_SYS = 0, ++ CLKC_MIPS, ++ CLKC_USB, ++ CLKC_ADSLSS ++} TNETD73XX_CLKC_ID_T; ++ ++void tnetd73xx_clkc_init(__u32 afeclk, __u32 refclk, __u32 xtal3in); ++TNETD73XX_ERR tnetd73xx_clkc_set_freq(TNETD73XX_CLKC_ID_T clk_id, __u32 output_freq); ++__u32 tnetd73xx_clkc_get_freq(TNETD73XX_CLKC_ID_T clk_id); ++ ++/***************************************************************************** ++ * GPIO Control ++ *****************************************************************************/ ++ ++typedef enum TNETD73XX_GPIO_PIN_tag ++{ ++ GPIO_UART0_RD = 0, ++ GPIO_UART0_TD = 1, ++ GPIO_UART0_RTS = 2, ++ GPIO_UART0_CTS = 3, ++ GPIO_FSER_CLK = 4, ++ GPIO_FSER_D = 5, ++ GPIO_EXT_AFE_SCLK = 6, ++ GPIO_EXT_AFE_TX_FS = 7, ++ GPIO_EXT_AFE_TXD = 8, ++ GPIO_EXT_AFE_RS_FS = 9, ++ GPIO_EXT_AFE_RXD1 = 10, ++ GPIO_EXT_AFE_RXD0 = 11, ++ GPIO_EXT_AFE_CDIN = 12, ++ GPIO_EXT_AFE_CDOUT = 13, ++ GPIO_EPHY_SPEED100 = 14, ++ GPIO_EPHY_LINKON = 15, ++ GPIO_EPHY_ACTIVITY = 16, ++ GPIO_EPHY_FDUPLEX = 17, ++ GPIO_EINT0 = 18, ++ GPIO_EINT1 = 19, ++ GPIO_MBSP0_TCLK = 20, ++ GPIO_MBSP0_RCLK = 21, ++ GPIO_MBSP0_RD = 22, ++ GPIO_MBSP0_TD = 23, ++ GPIO_MBSP0_RFS = 24, ++ GPIO_MBSP0_TFS = 25, ++ GPIO_MII_DIO = 26, ++ GPIO_MII_DCLK = 27, ++} TNETD73XX_GPIO_PIN_T; ++ ++typedef enum TNETD73XX_GPIO_PIN_MODE_tag ++{ ++ FUNCTIONAL_PIN = 0, ++ GPIO_PIN = 1 ++} TNETD73XX_GPIO_PIN_MODE_T; ++ ++typedef enum TNETD73XX_GPIO_PIN_DIRECTION_tag ++{ ++ GPIO_OUTPUT_PIN = 0, ++ GPIO_INPUT_PIN = 1 ++} TNETD73XX_GPIO_PIN_DIRECTION_T; ++ ++void tnetd73xx_gpio_init(void); ++void tnetd73xx_gpio_ctrl(TNETD73XX_GPIO_PIN_T gpio_pin, ++ TNETD73XX_GPIO_PIN_MODE_T pin_mode, ++ TNETD73XX_GPIO_PIN_DIRECTION_T pin_direction); ++void tnetd73xx_gpio_out(TNETD73XX_GPIO_PIN_T gpio_pin, int value); ++int tnetd73xx_gpio_in(TNETD73XX_GPIO_PIN_T gpio_pin); ++ ++/* TNETD73XX Revision */ ++__u32 tnetd73xx_get_revision(void); ++ ++#endif /* __TNETD73XX_MISC_H__ */ +diff -urN linux.old/include/asm-mips/ar7/vlynq.h linux.dev/include/asm-mips/ar7/vlynq.h +--- linux.old/include/asm-mips/ar7/vlynq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/vlynq.h 2005-11-10 01:10:46.095590250 +0100 +@@ -0,0 +1,610 @@ ++/*************************************************************************** ++**+----------------------------------------------------------------------+** ++**| **** |** ++**| **** |** ++**| ******o*** |** ++**| ********_///_**** |** ++**| ***** /_//_/ **** |** ++**| ** ** (__/ **** |** ++**| ********* |** ++**| **** |** ++**| *** |** ++**| |** ++**| Copyright (c) 2003 Texas Instruments Incorporated |** ++**| ALL RIGHTS RESERVED |** ++**| |** ++**| Permission is hereby granted to licensees of Texas Instruments |** ++**| Incorporated (TI) products to use this computer program for the sole |** ++**| purpose of implementing a licensee product based on TI products. |** ++**| No other rights to reproduce, use, or disseminate this computer |** ++**| program, whether in part or in whole, are granted. |** ++**| |** ++**| TI makes no representation or warranties with respect to the |** ++**| performance of this computer program, and specifically disclaims |** ++**| any responsibility for any damages, special or consequential, |** ++**| connected with the use of this program. |** ++**| |** ++**+----------------------------------------------------------------------+** ++***************************************************************************/ ++ ++/********************************************************************************* ++ * ------------------------------------------------------------------------------ ++ * Module : vlynq_hal.h ++ * Description : ++ * This header file provides the set of functions exported by the ++ * VLYNQ HAL. This file is included from the SOC specific VLYNQ driver wrapper. ++ * ------------------------------------------------------------------------------ ++ *********************************************************************************/ ++ ++#ifndef _VLYNQ_HAL_H_ ++#define _VLYNQ_HAL_H_ ++ ++/* Enable/Disable debug feature */ ++#undef VLYNQ_DEBUG ++ ++#ifdef VLYNQ_DEBUG /* This needs to be OS abstracted - for testing use vxworks/linux calls */ ++#define debugPrint(format,args...) ++#else ++#define debugPrint(format,args...) ++#endif ++ ++ /* number of VLYNQ memory regions supported */ ++#define VLYNQ_MAX_MEMORY_REGIONS 0x04 ++ ++ /* Max.number of external interrupt inputs supported by VLYNQ module */ ++#define VLYNQ_IVR_MAXIVR 0x08 ++ ++#define VLYNQ_CLK_DIV_MAX 0x08 ++#define VLYNQ_CLK_DIV_MIN 0x01 ++ ++ ++/*** the total number of entries allocated for ICB would be ++ * 32(for 32 bits in IntPending register) + VLYNQ_IVR_CHAIN_SLOTS*/ ++#define VLYNQ_IVR_CHAIN_SLOTS 10 ++ ++ ++/* Error defines */ ++#define VLYNQ_SUCCESS 0 ++ ++#define VLYNQ_ERRCODE_BASE 0 /* Chosen by system */ ++#define VLYNQ_INVALID_ARG -(VLYNQ_ERRCODE_BASE+1) ++#define VLYNQ_INVALID_DRV_STATE -(VLYNQ_ERRCODE_BASE+2) ++#define VLYNQ_INT_CONFIG_ERR -(VLYNQ_ERRCODE_BASE+3) ++#define VLYNQ_LINK_DOWN -(VLYNQ_ERRCODE_BASE+4) ++#define VLYNQ_MEMALLOC_FAIL -(VLYNQ_ERRCODE_BASE+5) ++#define VLYNQ_ISR_NON_EXISTENT -(VLYNQ_ERRCODE_BASE+6) ++#define VLYNQ_INTVEC_MAP_NOT_FOUND -(VLYNQ_ERRCODE_BASE+7) ++ ++/* Vlynq Defines and Macros */ ++ ++#define VLYNQ_NUM_INT_BITS 32 /* 32 bit interrupt staus register */ ++ ++/* Base address of module */ ++#define VLYNQ_BASE (pdev->module_base) ++ ++#define VLYNQ_REMOTE_REGS_OFFSET 0x0080 ++ ++#define VLYNQ_REV_OFFSET 0x0000 ++#define VLYNQ_CTRL_OFFSET 0x0004 ++#define VLYNQ_STATUS_OFFSET 0x0008 ++#define VLYNQ_INT_STAT_OFFSET 0x0010 ++#define VLYNQ_INT_PEND_OFFSET 0x0014 ++#define VLYNQ_INT_PTR_OFFSET 0x0018 ++#define VLYNQ_TXMAP_OFFSET 0x001c ++ ++#define VLYNQ_RX0MAP_SIZE_REG_OFFSET 0x0020 ++#define VLYNQ_RX0MAP_OFFSET_REG_OFFSET 0x0024 ++ ++#define VLYNQ_CHIP_VER_OFFSET 0x0040 ++#define VLYNQ_IVR_REGS_OFFSET 0x0060 ++ ++#define VLYNQ_INT_PENDING_REG_PTR 0x14 ++#define VLYNQ_R_INT_PENDING_REG_PTR VLYNQ_REMOTE_REGS_OFFSET + 0x14 ++ ++#define VLYNQ_REV_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_REV_OFFSET)) ++#define VLYNQ_CTRL_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_CTRL_OFFSET)) ++#define VLYNQ_STATUS_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_STATUS_OFFSET)) ++#define VLYNQ_INT_STAT_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_STAT_OFFSET)) ++#define VLYNQ_INT_PEND_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_PEND_OFFSET)) ++#define VLYNQ_INT_PTR_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_INT_PTR_OFFSET)) ++#define VLYNQ_TXMAP_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_TXMAP_OFFSET)) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_RXMAP_SIZE_REG(map) \ ++ *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_RX0MAP_SIZE_REG_OFFSET+( (map-1)<<3))) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_RXMAP_OFFSET_REG(map) \ ++ *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_RX0MAP_OFFSET_REG_OFFSET+( (map-1)<<3))) ++ ++#define VLYNQ_CHIP_VER_REG *((volatile unsigned int *)(VLYNQ_BASE+VLYNQ_CHIP_VER_OFFSET)) ++ ++/* 0 =< ivr <= 31; currently ivr < VLYNQ_IVR_MAXIVR=8) */ ++#define VLYNQ_IVR_OFFSET(ivr) \ ++ (VLYNQ_BASE + VLYNQ_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3) ) ++ ++#define VLYNQ_IVR_03TO00_REG *((volatile unsigned int*) (VLYNQ_IVR_OFFSET(0)) ) ++#define VLYNQ_IVR_07TO04_REG *((volatile unsigned int*) (VLYNQ_IVR_OFFSET(4)) ) ++/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/ ++ ++#define VLYNQ_IVR_INTEN(ivr) (((unsigned int)(0x80)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTTYPE(ivr) (((unsigned int)(0x40)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTPOL(ivr) (((unsigned int)(0x20)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTVEC(ivr) (((unsigned int)(0x1F)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTALL(ivr) (((unsigned int)(0xFF)) << ((((unsigned)(ivr)) % 4) * 8)) ++ ++ ++ ++/********************************* ++ * Remote VLYNQ register set * ++ *********************************/ ++ ++#define VLYNQ_R_REV_OFFSET 0x0080 ++#define VLYNQ_R_CTRL_OFFSET 0x0084 ++#define VLYNQ_R_STATUS_OFFSET 0x0088 ++#define VLYNQ_R_INT_STAT_OFFSET 0x0090 ++#define VLYNQ_R_INT_PEND_OFFSET 0x0094 ++#define VLYNQ_R_INT_PTR_OFFSET 0x0098 ++#define VLYNQ_R_TXMAP_OFFSET 0x009c ++ ++#define VLYNQ_R_RX0MAP_SIZE_REG_OFFSET 0x00A0 ++#define VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET 0x00A4 ++ ++#define VLYNQ_R_CHIP_VER_OFFSET 0x00C0 ++#define VLYNQ_R_IVR_REGS_OFFSET 0x00E0 ++ ++#define VLYNQ_R_REV_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_REV_OFFSET)) ++#define VLYNQ_R_CTRL_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_CTRL_OFFSET)) ++#define VLYNQ_R_STATUS_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_STATUS_OFFSET)) ++#define VLYNQ_R_INT_STAT_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_STAT_OFFSET)) ++#define VLYNQ_R_INT_PEND_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_PEND_OFFSET)) ++#define VLYNQ_R_INT_PTR_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_INT_PTR_OFFSET)) ++#define VLYNQ_R_TXMAP_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_TXMAP_OFFSET)) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_R_RXMAP_SIZE_REG(map) \ ++ *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_SIZE_REG_OFFSET + ((map-1)<<3))) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_R_RXMAP_OFFSET_REG(map) \ ++ *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET + ((map-1)<<3))) ++ ++#define VLYNQ_R_CHIP_VER_REG *((volatile unsigned int *)(VLYNQ_BASE + VLYNQ_R_CHIP_VER_OFFSET) ++ ++#define VLYNQ_R_IVR_OFFSET(ivr) \ ++ (VLYNQ_BASE + VLYNQ_R_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3)) ++ ++ ++/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/ ++#define VLYNQ_R_IVR_03TO00_REG *((volatile unsigned int*) (VLYNQ_R_IVR_OFFSET(0)) ) ++#define VLYNQ_R_IVR_07TO04_REG *((volatile unsigned int*) (VLYNQ_R_IVR_OFFSET(4)) ) ++ ++ ++/****End of remote register set definition******/ ++ ++ ++/*** Masks for individual register fields ***/ ++ ++#define VLYNQ_MODULE_ID_MASK 0xffff0000 ++#define VLYNQ_MAJOR_REV_MASK 0x0000ff00 ++#define VLYNQ_MINOR_REV_MASK 0x000000ff ++ ++ ++#define VLYNQ_CTL_ILOOP_MASK 0x00000002 ++#define VLYNQ_CTL_INT2CFG_MASK 0x00000080 ++#define VLYNQ_CTL_INTVEC_MASK 0x00001f00 ++#define VLYNQ_CTL_INTEN_MASK 0x00002000 ++#define VLYNQ_CTL_INTLOCAL_MASK 0x00004000 ++#define VLYNQ_CTL_CLKDIR_MASK 0x00008000 ++#define VLYNQ_CTL_CLKDIV_MASK 0x00070000 ++#define VLYNQ_CTL_MODE_MASK 0x00e00000 ++ ++ ++#define VLYNQ_STS_LINK_MASK 0x00000001 /* Link is active */ ++#define VLYNQ_STS_MPEND_MASK 0x00000002 /* Pending master requests */ ++#define VLYNQ_STS_SPEND_MASK 0x00000004 /* Pending slave requests */ ++#define VLYNQ_STS_NFEMPTY0_MASK 0x00000008 /* Master data FIFO not empty */ ++#define VLYNQ_STS_NFEMPTY1_MASK 0x00000010 /* Master command FIFO not empty */ ++#define VLYNQ_STS_NFEMPTY2_MASK 0x00000020 /* Slave data FIFO not empty */ ++#define VLYNQ_STS_NFEMPTY3_MASK 0x00000040 /* Slave command FIFO not empty */ ++#define VLYNQ_STS_LERROR_MASK 0x00000080 /* Local error, w/c */ ++#define VLYNQ_STS_RERROR_MASK 0x00000100 /* remote error w/c */ ++#define VLYNQ_STS_OFLOW_MASK 0x00000200 ++#define VLYNQ_STS_IFLOW_MASK 0x00000400 ++#define VLYNQ_STS_MODESUP_MASK 0x00E00000 /* Highest mode supported */ ++#define VLYNQ_STS_SWIDTH_MASK 0x07000000 /* Used for reading the width of VLYNQ bus */ ++#define VLYNQ_STS_DEBUG_MASK 0xE0000000 ++ ++#define VLYNQ_CTL_INTVEC_SHIFT 0x08 ++#define VLYNQ_CTL_INTEN_SHIFT 0x0D ++#define VLYNQ_CTL_INT2CFG_SHIFT 0x07 ++#define VLYNQ_CTL_INTLOCAL_SHIFT 0x0E ++ ++#define VLYNQ_CTL_INTFIELDS_CLEAR_MASK 0x7F80 ++ ++#define VLYNQ_CHIPVER_DEVREV_MASK 0xffff0000 ++#define VLYNQ_CHIPVER_DEVID_MASK 0x0000ffff ++ ++#define VLYNQ_IVR_INTEN_MASK 0x80 ++#define VLYNQ_IVR_INTTYPE_MASK 0x40 ++#define VLYNQ_IVR_INTPOL_MASK 0x20 ++ ++ ++/**** Helper macros ****/ ++ ++#define VLYNQ_RESETCB(arg) \ ++ if( pdev->reset_cb != NULL) \ ++ { \ ++ (pdev->reset_cb)(pdev, (arg)); \ ++ } ++ ++#define VLYNQ_STATUS_FLD_WIDTH(sts) (((sts) & VLYNQ_STS_SWIDTH_MASK) >> 24 ) ++#define VLYNQ_CTL_INTVEC(x) (((x) & 31) << 8 ) ++ ++#define VLYNQ_INRANGE(x,hi,lo) (((x) <= (hi)) && ((x) >= (lo))) ++#define VLYNQ_OUTRANGE(x,hi,lo) (((x) > (hi)) || ((x) < (lo))) ++ ++#define VLYNQ_ALIGN4(x) (x)=(x)&(~3) ++ ++ ++/************************************* ++ * Enums * ++ *************************************/ ++ ++/* Initialization options define what operations are ++ * undertaken during vlynq module initialization */ ++typedef enum ++{ ++ /* Init host local memory regions.This allows ++ * local host access remote memory regions */ ++ VLYNQ_INIT_LOCAL_MEM_REGIONS = 0x01, ++ /* Init host remote memory regions.This allows ++ * remote device access local memory regions */ ++ VLYNQ_INIT_REMOTE_MEM_REGIONS =0x02, ++ /* Init local interrupt config*/ ++ VLYNQ_INIT_LOCAL_INTERRUPTS =0x04, ++ /* Init remote interrupt config*/ ++ VLYNQ_INIT_REMOTE_INTERRUPTS =0x08, ++ /* Check link during initialization*/ ++ VLYNQ_INIT_CHECK_LINK =0x10, ++ /* configure clock during init */ ++ VLYNQ_INIT_CONFIG_CLOCK =0x20, ++ /* Clear errors during init */ ++ VLYNQ_INIT_CLEAR_ERRORS =0x40, ++ /* All options */ ++ VLYNQ_INIT_PERFORM_ALL =0x7F ++}VLYNQ_INIT_OPTIONS; ++ ++ ++/* VLYNQ_DEV_TYPE identifies local or remote device */ ++typedef enum ++{ ++ VLYNQ_LOCAL_DVC = 0, /* vlynq local device (SOC's vlynq module) */ ++ VLYNQ_REMOTE_DVC = 1 /* vlynq remote device (remote vlynq module) */ ++}VLYNQ_DEV_TYPE; ++ ++ ++/* VLYNQ_CLK_SOURCE identifies the vlynq module clock source */ ++typedef enum ++{ ++ VLYNQ_CLK_SOURCE_NONE = 0, /* do not initialize clock generator*/ ++ VLYNQ_CLK_SOURCE_LOCAL = 1, /* clock is generated by local machine */ ++ VLYNQ_CLK_SOURCE_REMOTE = 2 /* clock is generated by remote machine */ ++}VLYNQ_CLK_SOURCE; ++ ++ ++/* VLYNQ_DRV_STATE indicates the current driver state */ ++typedef enum ++{ ++ VLYNQ_DRV_STATE_UNINIT = 0, /* driver is uninitialized */ ++ VLYNQ_DRV_STATE_ININIT = 1, /* VLYNQ is being initialized */ ++ VLYNQ_DRV_STATE_RUN = 2, /* VLYNQ is running properly */ ++ VLYNQ_DRV_STATE_HOLD = 3, /* driver stopped temporarily */ ++ VLYNQ_DRV_STATE_ERROR = 4 /* driver stopped on unrecoverable error */ ++}VLYNQ_DRV_STATE; ++ ++ ++/* VLYNQ_BUS_WIDTH identifies the vlynq module bus width */ ++typedef enum ++{ ++ VLYNQ_BUS_WIDTH_3 = 3, ++ VLYNQ_BUS_WIDTH_5 = 5, ++ VLYNQ_BUS_WIDTH_7 = 7, ++ VLYNQ_BUS_WIDTH_9 = 9 ++}VLYNQ_BUS_WIDTH; ++ ++ ++/* VLYNQ_LOCAL_INT_CONFIG indicates whether the local vlynq ++ * interrupts are processed by the host or passed on to the ++ * remote device. ++ */ ++typedef enum ++{ ++ VLYNQ_INT_REMOTE = 0, /* Interrupt packets sent to remote, intlocal=0 */ ++ VLYNQ_INT_LOCAL = 1 /* Interrupts are handled locally, intlocal=1 */ ++}VLYNQ_LOCAL_INT_CONFIG; ++ ++ ++/* VLYNQ_REMOTE_INT_CONFIG indicates whether the remote ++ * interrupts are to be handled by the SOC system ISR ++ * or via the vlynq root ISR ++ */ ++typedef enum ++{ ++ VLYNQ_INT_ROOT_ISR = 0, /* remote ints handled via vlynq root ISR */ ++ VLYNQ_INT_SYSTEM_ISR = 1 /* remote ints handled via system ISR */ ++}VLYNQ_REMOTE_INT_CONFIG; ++ ++ ++/* VLYNQ_INTR_POLARITY - vlynq interrupt polarity setting */ ++typedef enum ++{ ++ VLYNQ_INTR_ACTIVE_HIGH = 0, ++ VLYNQ_INTR_ACTIVE_LOW = 1 ++}VLYNQ_INTR_POLARITY; ++ ++ ++/* VLYNQ_INTR_TYPE - vlynq interrupt type */ ++typedef enum ++{ ++ VLYNQ_INTR_LEVEL = 0, ++ VLYNQ_INTR_PULSED = 1 ++}VLYNQ_INTR_TYPE; ++ ++ ++/* VLYNQ_RESET_MODE - vlynq reset mode */ ++typedef enum ++{ ++ VLYNQ_RESET_ASSERT, /* hold device in reset state */ ++ VLYNQ_RESET_DEASSERT, /* release device from reset state */ ++ VLYNQ_RESET_INITFAIL, /* handle the device in case driver initialization fails */ ++ VLYNQ_RESET_LINKESTABLISH, /* handle the device in case driver established link */ ++ VLYNQ_RESET_INITFAIL2, /* Driver initialization failed but VLYNQ link exist. */ ++ VLYNQ_RESET_INITOK /* Driver initialization finished OK. */ ++}VLYNQ_RESET_MODE; ++ ++ ++ ++/************************************* ++ * Typedefs * ++ *************************************/ ++ ++struct VLYNQ_DEV_t; /*forward declaration*/ ++ ++/*--------Function Pointers defintions -----------*/ ++ ++/* prototype for interrupt handler definition */ ++typedef void (*VLYNQ_INTR_CNTRL_ISR)(void *arg1,void *arg2,void *arg3); ++ ++typedef void ++(*VLYNQ_RESET_REMOTE)(struct VLYNQ_DEV_t *pDev, VLYNQ_RESET_MODE mode); ++ ++typedef void ++(*VLYNQ_REPORT_CB)( struct VLYNQ_DEV_t *pDev, /* This VLYNQ */ ++ VLYNQ_DEV_TYPE aSrcDvc, /* Event Cause -local/remote? */ ++ unsigned int dwStatRegVal); /* Value of the relevant status register */ ++ ++ ++/*-------Structure Definitions------------*/ ++ ++typedef struct VLYNQ_MEMORY_MAP_t ++{ ++ unsigned int Txmap; ++ unsigned int RxOffset[VLYNQ_MAX_MEMORY_REGIONS]; ++ unsigned int RxSize[VLYNQ_MAX_MEMORY_REGIONS]; ++}VLYNQ_MEMORY_MAP; ++ ++ ++/**VLYNQ_INTERRUPT_CNTRL - defines the vlynq module interrupt ++ * settings in vlynq Control register */ ++typedef struct VLYNQ_INTERRUPT_CNTRL_t ++{ ++ /* vlynq interrupts handled by host or remote - maps to ++ * intLocal bit in vlynq control register */ ++ VLYNQ_LOCAL_INT_CONFIG intLocal; ++ ++ /* remote interrupts handled by vlynq isr or host system ++ * interrupt controller - maps to the int2Cfg in vlynq ++ * control register */ ++ VLYNQ_REMOTE_INT_CONFIG intRemote; ++ ++ /* bit in pending/set register used for module interrupts*/ ++ unsigned int map_vector; ++ ++ /* used only if remote interrupts are to be handled by system ISR*/ ++ unsigned int intr_ptr; ++ ++}VLYNQ_INTERRUPT_CNTRL; ++ ++ ++/* VLYNQ_INTR_CNTRL_ICB - defines the Interrupt control block which hold ++ * the interrupt dispatch table. The vlynq_root_isr() indexes into this ++ * table to identify the ISR to be invoked ++ */ ++typedef struct VLYNQ_INTR_CNTRL_ICB_t ++{ ++ VLYNQ_INTR_CNTRL_ISR isr; /* Clear errors during initialization */ ++ void *arg1 ; /* Arg 1 for the ISR */ ++ void *arg2 ; /* Arg 2 for the ISR */ ++ void *arg3 ; /* Arg 3 for the ISR */ ++ unsigned int isrCount; /* number of ISR invocations so far */ ++ struct VLYNQ_INTR_CNTRL_ICB_t *next; ++}VLYNQ_INTR_CNTRL_ICB; ++ ++/* overlay of vlynq register set */ ++typedef struct VLYNQ_REG_SET_t ++{ ++ unsigned int revision; /*offset : 0x00 */ ++ unsigned int control; /* 0x04*/ ++ unsigned int status; /* 0x08*/ ++ unsigned int pad1; /* 0x0c*/ ++ unsigned int intStatus; /*0x10*/ ++ unsigned int intPending; /*0x14*/ ++ unsigned int intPtr; /*0x18*/ ++ unsigned int txMap; /*0x1C*/ ++ unsigned int rxSize1; /*0x20*/ ++ unsigned int rxOffset1; /*0x24*/ ++ unsigned int rxSize2; /*0x28*/ ++ unsigned int rxOffset2; /*0x2C*/ ++ unsigned int rxSize3; /*0x30*/ ++ unsigned int rxOffset3; /*0x34*/ ++ unsigned int rxSize4; /*0x38*/ ++ unsigned int rxOffset4; /*0x3C*/ ++ unsigned int chipVersion; /*0x40*/ ++ unsigned int pad2[8]; ++ unsigned int ivr30; /*0x60*/ ++ unsigned int ivr74; /*0x64*/ ++ unsigned int pad3[7]; ++}VLYNQ_REG_SET; ++ ++ ++typedef struct VLYNQ_DEV_t ++{ ++ /** module index:1,2,3... used for debugging purposes */ ++ unsigned int dev_idx; ++ ++ /*VLYNQ module base address */ ++ unsigned int module_base; ++ ++ /* clock source selection */ ++ VLYNQ_CLK_SOURCE clk_source; ++ ++ /* Clock Divider.Val=1 to 8. VLYNQ_clk = VBUSCLK/clk_div */ ++ unsigned int clk_div; ++ ++ /* State of the VLYNQ driver, set to VLYNQ_DRV_STATE_UNINIT, when initializing */ ++ VLYNQ_DRV_STATE state; ++ ++ /* Valid VLYNQ bus width, filled by driver */ ++ VLYNQ_BUS_WIDTH width; ++ ++ /* local memory mapping */ ++ VLYNQ_MEMORY_MAP local_mem; ++ ++ /* remote memory mapping */ ++ VLYNQ_MEMORY_MAP remote_mem; ++ ++ /* Local module interrupt params */ ++ VLYNQ_INTERRUPT_CNTRL local_irq; ++ ++ /* remote module interrupt params */ ++ VLYNQ_INTERRUPT_CNTRL remote_irq; ++ ++ /*** ICB related fields **/ ++ ++ /* Sizeof of ICB = VLYNQ_NUM_INT_BITS(for 32 bits in IntPending) + ++ * expansion slots for shared interrupts*/ ++ VLYNQ_INTR_CNTRL_ICB pIntrCB[VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS]; ++ VLYNQ_INTR_CNTRL_ICB *freelist; ++ ++ /* table holding mapping between intVector and the bit position the interrupt ++ * is mapped to(mapVector)*/ ++ char vector_map[32]; ++ ++ /* user callback for vlynq events, NULL if unused */ ++ VLYNQ_REPORT_CB report_cb; ++ ++ /* user callback for resetting/realeasing remote device */ ++ VLYNQ_RESET_REMOTE reset_cb; ++ ++ /*** Handles provided for direct access to register set if need be ++ * Must be intialized to point to appropriate address during ++ * vlynq_init */ ++ volatile VLYNQ_REG_SET * local; ++ volatile VLYNQ_REG_SET * remote; ++ ++ unsigned int intCount; /* number of interrupts generated so far */ ++ unsigned int isrCount; /* number of ISR invocations so far */ ++}VLYNQ_DEV; ++ ++ ++typedef struct VLYNQ_ISR_ARGS_t ++{ ++ int irq; ++ void * arg; ++ void * regset; ++}VLYNQ_ISR_ARGS; ++ ++ ++/**************************************** ++ * Function Prototypes * ++ * API exported by generic vlynq driver * ++ ****************************************/ ++/* Initialization function */ ++int vlynq_init( VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options); ++ ++/* Check vlynq link */ ++unsigned int vlynq_link_check( VLYNQ_DEV * pdev); ++ ++/* Set interrupt vector in local or remote device */ ++int vlynq_interrupt_vector_set( VLYNQ_DEV *pdev, ++ unsigned int int_vector, ++ unsigned int map_vector, ++ VLYNQ_DEV_TYPE dev, ++ VLYNQ_INTR_POLARITY pol, ++ VLYNQ_INTR_TYPE type); ++ ++ ++int vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev, ++ unsigned int int_vector, ++ VLYNQ_DEV_TYPE dev, ++ unsigned int enable); ++ ++unsigned int vlynq_interrupt_get_count( VLYNQ_DEV *pdev, ++ unsigned int map_vector); ++ ++int vlynq_install_isr( VLYNQ_DEV *pdev, ++ unsigned int map_vector, ++ VLYNQ_INTR_CNTRL_ISR isr, ++ void *arg1, void *arg2, void *arg3); ++ ++int vlynq_uninstall_isr( VLYNQ_DEV *pdev, ++ unsigned int map_vector, ++ void *arg1, void *arg2, void *arg3); ++ ++ ++void vlynq_root_isr(void *arg); ++ ++void vlynq_delay(unsigned int clktime); ++ ++/* The following functions, provide better granularity in setting ++ * interrupt parameters. (for better support of linux INT Controller) ++ * Note: The interrupt source is identified by "map_vector"- the bit ++ * position in interrupt status register*/ ++ ++int vlynq_interrupt_vector_map(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ unsigned int int_vector, ++ unsigned int map_vector); ++ ++int vlynq_interrupt_set_polarity(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ unsigned int map_vector, ++ VLYNQ_INTR_POLARITY pol); ++ ++int vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev , ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector); ++ ++int vlynq_interrupt_set_type(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ unsigned int map_vector, ++ VLYNQ_INTR_TYPE type); ++ ++int vlynq_interrupt_get_type( VLYNQ_DEV *pdev, ++ VLYNQ_DEV_TYPE dev_type, ++ unsigned int map_vector); ++ ++int vlynq_interrupt_enable(VLYNQ_DEV* pdev, ++ VLYNQ_DEV_TYPE dev, ++ unsigned int map_vector); ++ ++int vlynq_interrupt_disable(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ unsigned int map_vector); ++ ++ ++ ++ ++ ++#endif /* _VLYNQ_HAL_H_ */ +diff -urN linux.old/include/asm-mips/ar7/vlynq_hal.h linux.dev/include/asm-mips/ar7/vlynq_hal.h +--- linux.old/include/asm-mips/ar7/vlynq_hal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/vlynq_hal.h 2005-11-10 01:10:46.095590250 +0100 +@@ -0,0 +1,606 @@ ++/*************************************************************************** ++**+----------------------------------------------------------------------+** ++**| **** |** ++**| **** |** ++**| ******o*** |** ++**| ********_///_**** |** ++**| ***** /_//_/ **** |** ++**| ** ** (__/ **** |** ++**| ********* |** ++**| **** |** ++**| *** |** ++**| |** ++**| Copyright (c) 2003 Texas Instruments Incorporated |** ++**| ALL RIGHTS RESERVED |** ++**| |** ++**| Permission is hereby granted to licensees of Texas Instruments |** ++**| Incorporated (TI) products to use this computer program for the sole |** ++**| purpose of implementing a licensee product based on TI products. |** ++**| No other rights to reproduce, use, or disseminate this computer |** ++**| program, whether in part or in whole, are granted. |** ++**| |** ++**| TI makes no representation or warranties with respect to the |** ++**| performance of this computer program, and specifically disclaims |** ++**| any responsibility for any damages, special or consequential, |** ++**| connected with the use of this program. |** ++**| |** ++**+----------------------------------------------------------------------+** ++***************************************************************************/ ++ ++/********************************************************************************* ++ * ------------------------------------------------------------------------------ ++ * Module : vlynq_hal.h ++ * Description : ++ * This header file provides the set of functions exported by the ++ * VLYNQ HAL. This file is included from the SOC specific VLYNQ driver wrapper. ++ * ------------------------------------------------------------------------------ ++ *********************************************************************************/ ++ ++#ifndef _VLYNQ_HAL_H_ ++#define _VLYNQ_HAL_H_ ++ ++#include ++#include ++ ++#ifndef PRIVATE ++#define PRIVATE static ++#endif ++ ++#ifndef GLOBAL ++#define GLOBAL ++#endif ++ ++/* Enable/Disable debug feature */ ++#undef VLYNQ_DEBUG ++ ++#ifdef VLYNQ_DEBUG /* This needs to be OS abstracted - for testing use vxworks/linux calls */ ++#define debugPrint(format,args...) ++#else ++#define debugPrint(format,args...) ++#endif ++ ++/* Error defines */ ++#define VLYNQ_SUCCESS 0 ++ ++#define VLYNQ_ERRCODE_BASE 0 /* Chosen by system */ ++#define VLYNQ_INVALID_ARG -(VLYNQ_ERRCODE_BASE+1) ++#define VLYNQ_INVALID_DRV_STATE -(VLYNQ_ERRCODE_BASE+2) ++#define VLYNQ_INT_CONFIG_ERR -(VLYNQ_ERRCODE_BASE+3) ++#define VLYNQ_LINK_DOWN -(VLYNQ_ERRCODE_BASE+4) ++#define VLYNQ_MEMALLOC_FAIL -(VLYNQ_ERRCODE_BASE+5) ++#define VLYNQ_ISR_NON_EXISTENT -(VLYNQ_ERRCODE_BASE+6) ++#define VLYNQ_INTVEC_MAP_NOT_FOUND -(VLYNQ_ERRCODE_BASE+7) ++ ++/* Vlynq Defines and Macros */ ++ ++#define VLYNQ_NUM_INT_BITS 32 /* 32 bit interrupt staus register */ ++ ++/* Base address of module */ ++#define VLYNQ_BASE (pdev->module_base) ++ ++#define VLYNQ_REMOTE_REGS_OFFSET 0x0080 ++ ++#define VLYNQ_REV_OFFSET 0x0000 ++#define VLYNQ_CTRL_OFFSET 0x0004 ++#define VLYNQ_STATUS_OFFSET 0x0008 ++#define VLYNQ_INT_STAT_OFFSET 0x0010 ++#define VLYNQ_INT_PEND_OFFSET 0x0014 ++#define VLYNQ_INT_PTR_OFFSET 0x0018 ++#define VLYNQ_TXMAP_OFFSET 0x001c ++ ++#define VLYNQ_RX0MAP_SIZE_REG_OFFSET 0x0020 ++#define VLYNQ_RX0MAP_OFFSET_REG_OFFSET 0x0024 ++ ++#define VLYNQ_CHIP_VER_OFFSET 0x0040 ++#define VLYNQ_IVR_REGS_OFFSET 0x0060 ++ ++#define VLYNQ_INT_PENDING_REG_PTR 0x14 ++#define VLYNQ_R_INT_PENDING_REG_PTR VLYNQ_REMOTE_REGS_OFFSET + 0x14 ++ ++#define VLYNQ_REV_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_REV_OFFSET)) ++#define VLYNQ_CTRL_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_CTRL_OFFSET)) ++#define VLYNQ_STATUS_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_STATUS_OFFSET)) ++#define VLYNQ_INT_STAT_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_INT_STAT_OFFSET)) ++#define VLYNQ_INT_PEND_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_INT_PEND_OFFSET)) ++#define VLYNQ_INT_PTR_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_INT_PTR_OFFSET)) ++#define VLYNQ_TXMAP_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_TXMAP_OFFSET)) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_RXMAP_SIZE_REG(map) \ ++ *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_RX0MAP_SIZE_REG_OFFSET+( (map-1)<<3))) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_RXMAP_OFFSET_REG(map) \ ++ *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_RX0MAP_OFFSET_REG_OFFSET+( (map-1)<<3))) ++ ++#define VLYNQ_CHIP_VER_REG *((volatile UINT32 *)(VLYNQ_BASE+VLYNQ_CHIP_VER_OFFSET)) ++ ++/* 0 =< ivr <= 31; currently ivr < VLYNQ_IVR_MAXIVR=8) */ ++#define VLYNQ_IVR_OFFSET(ivr) \ ++ (VLYNQ_BASE + VLYNQ_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3) ) ++ ++#define VLYNQ_IVR_03TO00_REG *((volatile UINT32*) (VLYNQ_IVR_OFFSET(0)) ) ++#define VLYNQ_IVR_07TO04_REG *((volatile UINT32*) (VLYNQ_IVR_OFFSET(4)) ) ++/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/ ++ ++#define VLYNQ_IVR_INTEN(ivr) (((UINT32)(0x80)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTTYPE(ivr) (((UINT32)(0x40)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTPOL(ivr) (((UINT32)(0x20)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTVEC(ivr) (((UINT32)(0x1F)) << ((((unsigned)(ivr)) % 4) * 8)) ++#define VLYNQ_IVR_INTALL(ivr) (((UINT32)(0xFF)) << ((((unsigned)(ivr)) % 4) * 8)) ++ ++ ++ ++/********************************* ++ * Remote VLYNQ register set * ++ *********************************/ ++ ++#define VLYNQ_R_REV_OFFSET 0x0080 ++#define VLYNQ_R_CTRL_OFFSET 0x0084 ++#define VLYNQ_R_STATUS_OFFSET 0x0088 ++#define VLYNQ_R_INT_STAT_OFFSET 0x0090 ++#define VLYNQ_R_INT_PEND_OFFSET 0x0094 ++#define VLYNQ_R_INT_PTR_OFFSET 0x0098 ++#define VLYNQ_R_TXMAP_OFFSET 0x009c ++ ++#define VLYNQ_R_RX0MAP_SIZE_REG_OFFSET 0x00A0 ++#define VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET 0x00A4 ++ ++#define VLYNQ_R_CHIP_VER_OFFSET 0x00C0 ++#define VLYNQ_R_IVR_REGS_OFFSET 0x00E0 ++ ++#define VLYNQ_R_REV_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_REV_OFFSET)) ++#define VLYNQ_R_CTRL_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_CTRL_OFFSET)) ++#define VLYNQ_R_STATUS_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_STATUS_OFFSET)) ++#define VLYNQ_R_INT_STAT_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_INT_STAT_OFFSET)) ++#define VLYNQ_R_INT_PEND_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_INT_PEND_OFFSET)) ++#define VLYNQ_R_INT_PTR_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_INT_PTR_OFFSET)) ++#define VLYNQ_R_TXMAP_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_TXMAP_OFFSET)) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_R_RXMAP_SIZE_REG(map) \ ++ *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_SIZE_REG_OFFSET + ((map-1)<<3))) ++ ++/** map takes on values between 1 to VLYNQ_MAX_MEMORY_REGIONS **/ ++#define VLYNQ_R_RXMAP_OFFSET_REG(map) \ ++ *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_RX0MAP_OFFSET_REG_OFFSET + ((map-1)<<3))) ++ ++#define VLYNQ_R_CHIP_VER_REG *((volatile UINT32 *)(VLYNQ_BASE + VLYNQ_R_CHIP_VER_OFFSET) ++ ++#define VLYNQ_R_IVR_OFFSET(ivr) \ ++ (VLYNQ_BASE + VLYNQ_R_IVR_REGS_OFFSET +((((unsigned)(ivr)) & 31) & ~3)) ++ ++ ++/*** Can be extended for 11TO08...31TO28 when all 31 are supported**/ ++#define VLYNQ_R_IVR_03TO00_REG *((volatile UINT32*) (VLYNQ_R_IVR_OFFSET(0)) ) ++#define VLYNQ_R_IVR_07TO04_REG *((volatile UINT32*) (VLYNQ_R_IVR_OFFSET(4)) ) ++ ++ ++/****End of remote register set definition******/ ++ ++ ++/*** Masks for individual register fields ***/ ++ ++#define VLYNQ_MODULE_ID_MASK 0xffff0000 ++#define VLYNQ_MAJOR_REV_MASK 0x0000ff00 ++#define VLYNQ_MINOR_REV_MASK 0x000000ff ++ ++ ++#define VLYNQ_CTL_ILOOP_MASK 0x00000002 ++#define VLYNQ_CTL_INT2CFG_MASK 0x00000080 ++#define VLYNQ_CTL_INTVEC_MASK 0x00001f00 ++#define VLYNQ_CTL_INTEN_MASK 0x00002000 ++#define VLYNQ_CTL_INTLOCAL_MASK 0x00004000 ++#define VLYNQ_CTL_CLKDIR_MASK 0x00008000 ++#define VLYNQ_CTL_CLKDIV_MASK 0x00070000 ++#define VLYNQ_CTL_MODE_MASK 0x00e00000 ++ ++ ++#define VLYNQ_STS_LINK_MASK 0x00000001 /* Link is active */ ++#define VLYNQ_STS_MPEND_MASK 0x00000002 /* Pending master requests */ ++#define VLYNQ_STS_SPEND_MASK 0x00000004 /* Pending slave requests */ ++#define VLYNQ_STS_NFEMPTY0_MASK 0x00000008 /* Master data FIFO not empty */ ++#define VLYNQ_STS_NFEMPTY1_MASK 0x00000010 /* Master command FIFO not empty */ ++#define VLYNQ_STS_NFEMPTY2_MASK 0x00000020 /* Slave data FIFO not empty */ ++#define VLYNQ_STS_NFEMPTY3_MASK 0x00000040 /* Slave command FIFO not empty */ ++#define VLYNQ_STS_LERROR_MASK 0x00000080 /* Local error, w/c */ ++#define VLYNQ_STS_RERROR_MASK 0x00000100 /* remote error w/c */ ++#define VLYNQ_STS_OFLOW_MASK 0x00000200 ++#define VLYNQ_STS_IFLOW_MASK 0x00000400 ++#define VLYNQ_STS_MODESUP_MASK 0x00E00000 /* Highest mode supported */ ++#define VLYNQ_STS_SWIDTH_MASK 0x07000000 /* Used for reading the width of VLYNQ bus */ ++#define VLYNQ_STS_DEBUG_MASK 0xE0000000 ++ ++#define VLYNQ_CTL_INTVEC_SHIFT 0x08 ++#define VLYNQ_CTL_INTEN_SHIFT 0x0D ++#define VLYNQ_CTL_INT2CFG_SHIFT 0x07 ++#define VLYNQ_CTL_INTLOCAL_SHIFT 0x0E ++ ++#define VLYNQ_CTL_INTFIELDS_CLEAR_MASK 0x7F80 ++ ++#define VLYNQ_CHIPVER_DEVREV_MASK 0xffff0000 ++#define VLYNQ_CHIPVER_DEVID_MASK 0x0000ffff ++ ++#define VLYNQ_IVR_INTEN_MASK 0x80 ++#define VLYNQ_IVR_INTTYPE_MASK 0x40 ++#define VLYNQ_IVR_INTPOL_MASK 0x20 ++ ++ ++/**** Helper macros ****/ ++ ++#define VLYNQ_RESETCB(arg) \ ++ if( pdev->reset_cb != NULL) \ ++ { \ ++ (pdev->reset_cb)(pdev, (arg)); \ ++ } ++ ++#define VLYNQ_STATUS_FLD_WIDTH(sts) (((sts) & VLYNQ_STS_SWIDTH_MASK) >> 24 ) ++#define VLYNQ_CTL_INTVEC(x) (((x) & 31) << 8 ) ++ ++#define VLYNQ_INRANGE(x,hi,lo) (((x) <= (hi)) && ((x) >= (lo))) ++#define VLYNQ_OUTRANGE(x,hi,lo) (((x) > (hi)) || ((x) < (lo))) ++ ++#define VLYNQ_ALIGN4(x) (x)=(x)&(~3) ++ ++ ++/************************************* ++ * Enums * ++ *************************************/ ++ ++/* Initialization options define what operations are ++ * undertaken during vlynq module initialization */ ++typedef enum ++{ ++ /* Init host local memory regions.This allows ++ * local host access remote memory regions */ ++ VLYNQ_INIT_LOCAL_MEM_REGIONS = 0x01, ++ /* Init host remote memory regions.This allows ++ * remote device access local memory regions */ ++ VLYNQ_INIT_REMOTE_MEM_REGIONS =0x02, ++ /* Init local interrupt config*/ ++ VLYNQ_INIT_LOCAL_INTERRUPTS =0x04, ++ /* Init remote interrupt config*/ ++ VLYNQ_INIT_REMOTE_INTERRUPTS =0x08, ++ /* Check link during initialization*/ ++ VLYNQ_INIT_CHECK_LINK =0x10, ++ /* configure clock during init */ ++ VLYNQ_INIT_CONFIG_CLOCK =0x20, ++ /* Clear errors during init */ ++ VLYNQ_INIT_CLEAR_ERRORS =0x40, ++ /* All options */ ++ VLYNQ_INIT_PERFORM_ALL =0x7F ++}VLYNQ_INIT_OPTIONS; ++ ++ ++/* VLYNQ_DEV_TYPE identifies local or remote device */ ++typedef enum ++{ ++ VLYNQ_LOCAL_DVC = 0, /* vlynq local device (SOC's vlynq module) */ ++ VLYNQ_REMOTE_DVC = 1 /* vlynq remote device (remote vlynq module) */ ++}VLYNQ_DEV_TYPE; ++ ++ ++/* VLYNQ_CLK_SOURCE identifies the vlynq module clock source */ ++typedef enum ++{ ++ VLYNQ_CLK_SOURCE_NONE = 0, /* do not initialize clock generator*/ ++ VLYNQ_CLK_SOURCE_LOCAL = 1, /* clock is generated by local machine */ ++ VLYNQ_CLK_SOURCE_REMOTE = 2 /* clock is generated by remote machine */ ++}VLYNQ_CLK_SOURCE; ++ ++ ++/* VLYNQ_DRV_STATE indicates the current driver state */ ++typedef enum ++{ ++ VLYNQ_DRV_STATE_UNINIT = 0, /* driver is uninitialized */ ++ VLYNQ_DRV_STATE_ININIT = 1, /* VLYNQ is being initialized */ ++ VLYNQ_DRV_STATE_RUN = 2, /* VLYNQ is running properly */ ++ VLYNQ_DRV_STATE_HOLD = 3, /* driver stopped temporarily */ ++ VLYNQ_DRV_STATE_ERROR = 4 /* driver stopped on unrecoverable error */ ++}VLYNQ_DRV_STATE; ++ ++ ++/* VLYNQ_BUS_WIDTH identifies the vlynq module bus width */ ++typedef enum ++{ ++ VLYNQ_BUS_WIDTH_3 = 3, ++ VLYNQ_BUS_WIDTH_5 = 5, ++ VLYNQ_BUS_WIDTH_7 = 7, ++ VLYNQ_BUS_WIDTH_9 = 9 ++}VLYNQ_BUS_WIDTH; ++ ++ ++/* VLYNQ_LOCAL_INT_CONFIG indicates whether the local vlynq ++ * interrupts are processed by the host or passed on to the ++ * remote device. ++ */ ++typedef enum ++{ ++ VLYNQ_INT_REMOTE = 0, /* Interrupt packets sent to remote, intlocal=0 */ ++ VLYNQ_INT_LOCAL = 1 /* Interrupts are handled locally, intlocal=1 */ ++}VLYNQ_LOCAL_INT_CONFIG; ++ ++ ++/* VLYNQ_REMOTE_INT_CONFIG indicates whether the remote ++ * interrupts are to be handled by the SOC system ISR ++ * or via the vlynq root ISR ++ */ ++typedef enum ++{ ++ VLYNQ_INT_ROOT_ISR = 0, /* remote ints handled via vlynq root ISR */ ++ VLYNQ_INT_SYSTEM_ISR = 1 /* remote ints handled via system ISR */ ++}VLYNQ_REMOTE_INT_CONFIG; ++ ++ ++/* VLYNQ_INTR_POLARITY - vlynq interrupt polarity setting */ ++typedef enum ++{ ++ VLYNQ_INTR_ACTIVE_HIGH = 0, ++ VLYNQ_INTR_ACTIVE_LOW = 1 ++}VLYNQ_INTR_POLARITY; ++ ++ ++/* VLYNQ_INTR_TYPE - vlynq interrupt type */ ++typedef enum ++{ ++ VLYNQ_INTR_LEVEL = 0, ++ VLYNQ_INTR_PULSED = 1 ++}VLYNQ_INTR_TYPE; ++ ++ ++/* VLYNQ_RESET_MODE - vlynq reset mode */ ++typedef enum ++{ ++ VLYNQ_RESET_ASSERT, /* hold device in reset state */ ++ VLYNQ_RESET_DEASSERT, /* release device from reset state */ ++ VLYNQ_RESET_INITFAIL, /* handle the device in case driver initialization fails */ ++ VLYNQ_RESET_LINKESTABLISH, /* handle the device in case driver established link */ ++ VLYNQ_RESET_INITFAIL2, /* Driver initialization failed but VLYNQ link exist. */ ++ VLYNQ_RESET_INITOK /* Driver initialization finished OK. */ ++}VLYNQ_RESET_MODE; ++ ++ ++ ++/************************************* ++ * Typedefs * ++ *************************************/ ++ ++struct VLYNQ_DEV_t; /*forward declaration*/ ++ ++/*--------Function Pointers defintions -----------*/ ++ ++/* prototype for interrupt handler definition */ ++typedef void (*VLYNQ_INTR_CNTRL_ISR)(void *arg1,void *arg2,void *arg3); ++ ++typedef void ++(*VLYNQ_RESET_REMOTE)(struct VLYNQ_DEV_t *pDev, VLYNQ_RESET_MODE mode); ++ ++typedef void ++(*VLYNQ_REPORT_CB)( struct VLYNQ_DEV_t *pDev, /* This VLYNQ */ ++ VLYNQ_DEV_TYPE aSrcDvc, /* Event Cause -local/remote? */ ++ UINT32 dwStatRegVal); /* Value of the relevant status register */ ++ ++ ++/*-------Structure Definitions------------*/ ++ ++typedef struct VLYNQ_MEMORY_MAP_t ++{ ++ UINT32 Txmap; ++ UINT32 RxOffset[VLYNQ_MAX_MEMORY_REGIONS]; ++ UINT32 RxSize[VLYNQ_MAX_MEMORY_REGIONS]; ++}VLYNQ_MEMORY_MAP; ++ ++ ++/**VLYNQ_INTERRUPT_CNTRL - defines the vlynq module interrupt ++ * settings in vlynq Control register */ ++typedef struct VLYNQ_INTERRUPT_CNTRL_t ++{ ++ /* vlynq interrupts handled by host or remote - maps to ++ * intLocal bit in vlynq control register */ ++ VLYNQ_LOCAL_INT_CONFIG intLocal; ++ ++ /* remote interrupts handled by vlynq isr or host system ++ * interrupt controller - maps to the int2Cfg in vlynq ++ * control register */ ++ VLYNQ_REMOTE_INT_CONFIG intRemote; ++ ++ /* bit in pending/set register used for module interrupts*/ ++ UINT32 map_vector; ++ ++ /* used only if remote interrupts are to be handled by system ISR*/ ++ UINT32 intr_ptr; ++ ++}VLYNQ_INTERRUPT_CNTRL; ++ ++ ++/* VLYNQ_INTR_CNTRL_ICB - defines the Interrupt control block which hold ++ * the interrupt dispatch table. The vlynq_root_isr() indexes into this ++ * table to identify the ISR to be invoked ++ */ ++typedef struct VLYNQ_INTR_CNTRL_ICB_t ++{ ++ VLYNQ_INTR_CNTRL_ISR isr; /* Clear errors during initialization */ ++ void *arg1 ; /* Arg 1 for the ISR */ ++ void *arg2 ; /* Arg 2 for the ISR */ ++ void *arg3 ; /* Arg 3 for the ISR */ ++ UINT32 isrCount; /* number of ISR invocations so far */ ++ struct VLYNQ_INTR_CNTRL_ICB_t *next; ++}VLYNQ_INTR_CNTRL_ICB; ++ ++/* overlay of vlynq register set */ ++typedef struct VLYNQ_REG_SET_t ++{ ++ UINT32 revision; /*offset : 0x00 */ ++ UINT32 control; /* 0x04*/ ++ UINT32 status; /* 0x08*/ ++ UINT32 pad1; /* 0x0c*/ ++ UINT32 intStatus; /*0x10*/ ++ UINT32 intPending; /*0x14*/ ++ UINT32 intPtr; /*0x18*/ ++ UINT32 txMap; /*0x1C*/ ++ UINT32 rxSize1; /*0x20*/ ++ UINT32 rxOffset1; /*0x24*/ ++ UINT32 rxSize2; /*0x28*/ ++ UINT32 rxOffset2; /*0x2C*/ ++ UINT32 rxSize3; /*0x30*/ ++ UINT32 rxOffset3; /*0x34*/ ++ UINT32 rxSize4; /*0x38*/ ++ UINT32 rxOffset4; /*0x3C*/ ++ UINT32 chipVersion; /*0x40*/ ++ UINT32 pad2[8]; ++ UINT32 ivr30; /*0x60*/ ++ UINT32 ivr74; /*0x64*/ ++ UINT32 pad3[7]; ++}VLYNQ_REG_SET; ++ ++ ++typedef struct VLYNQ_DEV_t ++{ ++ /** module index:1,2,3... used for debugging purposes */ ++ UINT32 dev_idx; ++ ++ /*VLYNQ module base address */ ++ UINT32 module_base; ++ ++ /* clock source selection */ ++ VLYNQ_CLK_SOURCE clk_source; ++ ++ /* Clock Divider.Val=1 to 8. VLYNQ_clk = VBUSCLK/clk_div */ ++ UINT32 clk_div; ++ ++ /* State of the VLYNQ driver, set to VLYNQ_DRV_STATE_UNINIT, when initializing */ ++ VLYNQ_DRV_STATE state; ++ ++ /* Valid VLYNQ bus width, filled by driver */ ++ VLYNQ_BUS_WIDTH width; ++ ++ /* local memory mapping */ ++ VLYNQ_MEMORY_MAP local_mem; ++ ++ /* remote memory mapping */ ++ VLYNQ_MEMORY_MAP remote_mem; ++ ++ /* Local module interrupt params */ ++ VLYNQ_INTERRUPT_CNTRL local_irq; ++ ++ /* remote module interrupt params */ ++ VLYNQ_INTERRUPT_CNTRL remote_irq; ++ ++ /*** ICB related fields **/ ++ ++ /* Sizeof of ICB = VLYNQ_NUM_INT_BITS(for 32 bits in IntPending) + ++ * expansion slots for shared interrupts*/ ++ VLYNQ_INTR_CNTRL_ICB pIntrCB[VLYNQ_NUM_INT_BITS + VLYNQ_IVR_CHAIN_SLOTS]; ++ VLYNQ_INTR_CNTRL_ICB *freelist; ++ ++ /* table holding mapping between intVector and the bit position the interrupt ++ * is mapped to(mapVector)*/ ++ INT8 vector_map[32]; ++ ++ /* user callback for vlynq events, NULL if unused */ ++ VLYNQ_REPORT_CB report_cb; ++ ++ /* user callback for resetting/realeasing remote device */ ++ VLYNQ_RESET_REMOTE reset_cb; ++ ++ /*** Handles provided for direct access to register set if need be ++ * Must be intialized to point to appropriate address during ++ * vlynq_init */ ++ volatile VLYNQ_REG_SET * local; ++ volatile VLYNQ_REG_SET * remote; ++ ++ UINT32 intCount; /* number of interrupts generated so far */ ++ UINT32 isrCount; /* number of ISR invocations so far */ ++}VLYNQ_DEV; ++ ++ ++typedef struct VLYNQ_ISR_ARGS_t ++{ ++ int irq; ++ void * arg; ++ void * regset; ++}VLYNQ_ISR_ARGS; ++ ++ ++/**************************************** ++ * Function Prototypes * ++ * API exported by generic vlynq driver * ++ ****************************************/ ++/* Initialization function */ ++GLOBAL INT32 vlynq_init( VLYNQ_DEV *pdev, VLYNQ_INIT_OPTIONS options); ++ ++/* Check vlynq link */ ++GLOBAL UINT32 vlynq_link_check( VLYNQ_DEV * pdev); ++ ++/* Set interrupt vector in local or remote device */ ++GLOBAL INT32 vlynq_interrupt_vector_set( VLYNQ_DEV *pdev, ++ UINT32 int_vector, ++ UINT32 map_vector, ++ VLYNQ_DEV_TYPE dev, ++ VLYNQ_INTR_POLARITY pol, ++ VLYNQ_INTR_TYPE type); ++ ++ ++GLOBAL INT32 vlynq_interrupt_vector_cntl( VLYNQ_DEV *pdev, ++ UINT32 int_vector, ++ VLYNQ_DEV_TYPE dev, ++ UINT32 enable); ++ ++GLOBAL UINT32 vlynq_interrupt_get_count( VLYNQ_DEV *pdev, ++ UINT32 map_vector); ++ ++GLOBAL INT32 vlynq_install_isr( VLYNQ_DEV *pdev, ++ UINT32 map_vector, ++ VLYNQ_INTR_CNTRL_ISR isr, ++ void *arg1, void *arg2, void *arg3); ++ ++GLOBAL INT32 vlynq_uninstall_isr( VLYNQ_DEV *pdev, ++ UINT32 map_vector, ++ void *arg1, void *arg2, void *arg3); ++ ++ ++GLOBAL void vlynq_root_isr(void *arg); ++ ++GLOBAL void vlynq_delay(UINT32 clktime); ++ ++/* The following functions, provide better granularity in setting ++ * interrupt parameters. (for better support of linux INT Controller) ++ * Note: The interrupt source is identified by "map_vector"- the bit ++ * position in interrupt status register*/ ++ ++GLOBAL INT32 vlynq_interrupt_vector_map(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ UINT32 int_vector, ++ UINT32 map_vector); ++ ++GLOBAL INT32 vlynq_interrupt_set_polarity(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ UINT32 map_vector, ++ VLYNQ_INTR_POLARITY pol); ++ ++GLOBAL INT32 vlynq_interrupt_get_polarity( VLYNQ_DEV *pdev , ++ VLYNQ_DEV_TYPE dev_type, ++ UINT32 map_vector); ++ ++GLOBAL INT32 vlynq_interrupt_set_type(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ UINT32 map_vector, ++ VLYNQ_INTR_TYPE type); ++ ++GLOBAL INT32 vlynq_interrupt_get_type( VLYNQ_DEV *pdev, ++ VLYNQ_DEV_TYPE dev_type, ++ UINT32 map_vector); ++ ++GLOBAL INT32 vlynq_interrupt_enable(VLYNQ_DEV* pdev, ++ VLYNQ_DEV_TYPE dev, ++ UINT32 map_vector); ++ ++GLOBAL INT32 vlynq_interrupt_disable(VLYNQ_DEV * pdev, ++ VLYNQ_DEV_TYPE dev, ++ UINT32 map_vector); ++ ++ ++ ++ ++ ++#endif /* _VLYNQ_HAL_H_ */ +diff -urN linux.old/include/asm-mips/ar7/vlynq_hal_params.h linux.dev/include/asm-mips/ar7/vlynq_hal_params.h +--- linux.old/include/asm-mips/ar7/vlynq_hal_params.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/asm-mips/ar7/vlynq_hal_params.h 2005-11-10 01:10:46.095590250 +0100 +@@ -0,0 +1,50 @@ ++/*************************************************************************** ++**+----------------------------------------------------------------------+** ++**| **** |** ++**| **** |** ++**| ******o*** |** ++**| ********_///_**** |** ++**| ***** /_//_/ **** |** ++**| ** ** (__/ **** |** ++**| ********* |** ++**| **** |** ++**| *** |** ++**| |** ++**| Copyright (c) 2003 Texas Instruments Incorporated |** ++**| ALL RIGHTS RESERVED |** ++**| |** ++**| Permission is hereby granted to licensees of Texas Instruments |** ++**| Incorporated (TI) products to use this computer program for the sole |** ++**| purpose of implementing a licensee product based on TI products. |** ++**| No other rights to reproduce, use, or disseminate this computer |** ++**| program, whether in part or in whole, are granted. |** ++**| |** ++**| TI makes no representation or warranties with respect to the |** ++**| performance of this computer program, and specifically disclaims |** ++**| any responsibility for any damages, special or consequential, |** ++**| connected with the use of this program. |** ++**| |** ++**+----------------------------------------------------------------------+** ++***************************************************************************/ ++ ++/* This file defines Vlynq module parameters*/ ++ ++#ifndef _VLYNQ_HAL_PARAMS_H ++#define _VLYNQ_HAL_PARAMS_H ++ ++ /* number of VLYNQ memory regions supported */ ++#define VLYNQ_MAX_MEMORY_REGIONS 0x04 ++ ++ /* Max.number of external interrupt inputs supported by VLYNQ module */ ++#define VLYNQ_IVR_MAXIVR 0x08 ++ ++#define VLYNQ_CLK_DIV_MAX 0x08 ++#define VLYNQ_CLK_DIV_MIN 0x01 ++ ++ ++/*** the total number of entries allocated for ICB would be ++ * 32(for 32 bits in IntPending register) + VLYNQ_IVR_CHAIN_SLOTS*/ ++#define VLYNQ_IVR_CHAIN_SLOTS 10 ++ ++ ++#endif /* _VLYNQ_HAL_PARAMS_H */ +diff -urN linux.old/include/asm-mips/io.h linux.dev/include/asm-mips/io.h +--- linux.old/include/asm-mips/io.h 2003-08-25 13:44:43.000000000 +0200 ++++ linux.dev/include/asm-mips/io.h 2005-11-10 01:14:16.400733500 +0100 +@@ -61,9 +61,9 @@ + * Change "struct page" to physical address. + */ + #ifdef CONFIG_64BIT_PHYS_ADDR +-#define page_to_phys(page) ((u64)(page - mem_map) << PAGE_SHIFT) ++#define page_to_phys(page) (((u64)(page - mem_map) << PAGE_SHIFT) + PHYS_OFFSET) + #else +-#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) ++#define page_to_phys(page) (((page - mem_map) << PAGE_SHIFT) + PHYS_OFFSET) + #endif + + #define IO_SPACE_LIMIT 0xffff +diff -urN linux.old/include/asm-mips/irq.h linux.dev/include/asm-mips/irq.h +--- linux.old/include/asm-mips/irq.h 2003-08-25 13:44:43.000000000 +0200 ++++ linux.dev/include/asm-mips/irq.h 2005-11-10 01:12:43.950955750 +0100 +@@ -14,7 +14,20 @@ + #include + #include + ++#ifdef CONFIG_AR7 ++/* MIPS has 8 irqs ++ * AR7 has 40 primary and 32 secondary irqs ++ * vlynq0 has 32 irqs ++ * vlynq1 has 32 irqs ++ */ ++#ifdef CONFIG_AR7_VLYNQ ++#define NR_IRQS (80 + 32 * CONFIG_AR7_VLYNQ_PORTS) ++#else ++#define NR_IRQS 80 ++#endif ++#else + #define NR_IRQS 128 /* Largest number of ints of all machines. */ ++#endif + + #ifdef CONFIG_I8259 + static inline int irq_cannonicalize(int irq) +diff -urN linux.old/include/asm-mips/mips-boards/prom.h linux.dev/include/asm-mips/mips-boards/prom.h +--- linux.old/include/asm-mips/mips-boards/prom.h 2001-09-09 19:43:02.000000000 +0200 ++++ linux.dev/include/asm-mips/mips-boards/prom.h 2005-11-10 01:14:16.436735750 +0100 +@@ -33,7 +33,7 @@ + extern void prom_init_cmdline(void); + extern void prom_meminit(void); + extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); +-extern void prom_free_prom_memory (void); ++extern unsigned long prom_free_prom_memory (void); + extern void mips_display_message(const char *str); + extern void mips_display_word(unsigned int num); + extern int get_ethernet_addr(char *ethernet_addr); +diff -urN linux.old/include/asm-mips/page.h linux.dev/include/asm-mips/page.h +--- linux.old/include/asm-mips/page.h 2004-02-18 14:36:32.000000000 +0100 ++++ linux.dev/include/asm-mips/page.h 2005-11-10 01:14:16.436735750 +0100 +@@ -12,6 +12,7 @@ + + #include + #include ++#include + + #ifdef __KERNEL__ + +@@ -129,7 +130,7 @@ + + #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) + #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) +-#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT)) ++#define virt_to_page(kaddr) (mem_map + ((__pa(kaddr)-PHYS_OFFSET) >> PAGE_SHIFT)) + #define VALID_PAGE(page) ((page - mem_map) < max_mapnr) + + #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ +diff -urN linux.old/include/asm-mips/pgtable-32.h linux.dev/include/asm-mips/pgtable-32.h +--- linux.old/include/asm-mips/pgtable-32.h 2004-02-18 14:36:32.000000000 +0100 ++++ linux.dev/include/asm-mips/pgtable-32.h 2005-11-10 01:14:16.436735750 +0100 +@@ -108,7 +108,7 @@ + * and a page entry and page directory to the page they refer to. + */ + +-#ifdef CONFIG_CPU_VR41XX ++#if defined(CONFIG_CPU_VR41XX) + #define mk_pte(page, pgprot) \ + ({ \ + pte_t __pte; \ +@@ -123,13 +123,14 @@ + ({ \ + pte_t __pte; \ + \ +- pte_val(__pte) = ((phys_t)(page - mem_map) << PAGE_SHIFT) | \ +- pgprot_val(pgprot); \ ++ pte_val(__pte) = (((phys_t)(page - mem_map) << PAGE_SHIFT) + \ ++ PHYS_OFFSET) | pgprot_val(pgprot); \ + \ + __pte; \ + }) + #endif + ++ + static inline pte_t mk_pte_phys(phys_t physpage, pgprot_t pgprot) + { + #ifdef CONFIG_CPU_VR41XX +@@ -175,12 +176,12 @@ + set_pte(ptep, __pte(0)); + } + +-#ifdef CONFIG_CPU_VR41XX ++#if defined(CONFIG_CPU_VR41XX) + #define pte_page(x) (mem_map+((unsigned long)(((x).pte_low >> (PAGE_SHIFT+2))))) + #define __mk_pte(page_nr,pgprot) __pte(((page_nr) << (PAGE_SHIFT+2)) | pgprot_val(pgprot)) + #else +-#define pte_page(x) (mem_map+((unsigned long)(((x).pte_low >> PAGE_SHIFT)))) +-#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot)) ++#define pte_page(x) (mem_map+((unsigned long)((((x).pte_low-PHYS_OFFSET) >> PAGE_SHIFT)))) ++#define __mk_pte(page_nr,pgprot) __pte((((page_nr) << PAGE_SHIFT)+PHYS_OFFSET)|pgprot_val(pgprot)) + #endif + + #endif +diff -urN linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.h +--- linux.old/include/asm-mips/serial.h 2005-01-19 15:10:12.000000000 +0100 ++++ linux.dev/include/asm-mips/serial.h 2005-11-10 01:14:16.436735750 +0100 +@@ -65,6 +65,16 @@ + + #define C_P(card,port) (((card)<<6|(port)<<3) + 1) + ++#ifdef CONFIG_AR7 ++#include ++#include ++#define AR7_SERIAL_PORT_DEFNS \ ++ { 0, AR7_BASE_BAUD, AR7_UART0_REGS_BASE, LNXINTNUM(AVALANCHE_UART0_INT), STD_COM_FLAGS }, \ ++ { 0, AR7_BASE_BAUD, AR7_UART1_REGS_BASE, LNXINTNUM(AVALANCHE_UART1_INT), STD_COM_FLAGS }, ++#else ++#define AR7_SERIAL_PORT_DEFNS ++#endif ++ + #ifdef CONFIG_MIPS_JAZZ + #define _JAZZ_SERIAL_INIT(int, base) \ + { .baud_base = JAZZ_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \ +@@ -468,6 +478,7 @@ + #endif + + #define SERIAL_PORT_DFNS \ ++ AR7_SERIAL_PORT_DEFNS \ + ATLAS_SERIAL_PORT_DEFNS \ + AU1000_SERIAL_PORT_DEFNS \ + COBALT_SERIAL_PORT_DEFNS \ diff --git a/openwrt/target/linux/ar7-2.4/patches/001-flash_map.patch b/openwrt/target/linux/ar7-2.4/patches/001-flash_map.patch new file mode 100644 index 0000000000..83bc103bef --- /dev/null +++ b/openwrt/target/linux/ar7-2.4/patches/001-flash_map.patch @@ -0,0 +1,307 @@ +diff -urN linux.old/drivers/mtd/maps/ar7-flash.c linux.dev/drivers/mtd/maps/ar7-flash.c +--- linux.old/drivers/mtd/maps/ar7-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/mtd/maps/ar7-flash.c 2005-07-22 04:35:26.624453992 +0200 +@@ -0,0 +1,267 @@ ++/* ++ * $Id$ ++ * ++ * Normal mappings of chips in physical memory ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define WINDOW_ADDR CONFIG_MTD_AR7_START ++#define WINDOW_SIZE CONFIG_MTD_AR7_LEN ++#define BUSWIDTH CONFIG_MTD_AR7_BUSWIDTH ++ ++#include ++extern char *prom_getenv(char *name); ++ ++static int create_mtd_partitions(void); ++static void __exit ar7_mtd_cleanup(void); ++ ++#define MAX_NUM_PARTITIONS 5 ++static struct mtd_partition ar7_partinfo[MAX_NUM_PARTITIONS]; ++ ++static struct mtd_info *ar7_mtd_info; ++ ++__u8 ar7_read8(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readb(map->map_priv_1 + ofs); ++} ++ ++__u16 ar7_read16(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readw(map->map_priv_1 + ofs); ++} ++ ++__u32 ar7_read32(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readl(map->map_priv_1 + ofs); ++} ++ ++void ar7_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++} ++ ++void ar7_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void ar7_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void ar7_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void ar7_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++struct map_info ar7_map = { ++ name: "Physically mapped flash", ++ size: WINDOW_SIZE, ++ buswidth: BUSWIDTH, ++ read8: ar7_read8, ++ read16: ar7_read16, ++ read32: ar7_read32, ++ copy_from: ar7_copy_from, ++ write8: ar7_write8, ++ write16: ar7_write16, ++ write32: ar7_write32, ++ copy_to: ar7_copy_to ++}; ++ ++int __init ar7_mtd_init(void) ++{ ++ int partitions; ++ ++ printk(KERN_NOTICE "ar7 flash device: 0x%lx at 0x%lx.\n", (unsigned long)WINDOW_SIZE, (unsigned long)WINDOW_ADDR); ++ ar7_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); ++ ++ if (!ar7_map.map_priv_1) { ++ printk("Failed to ioremap\n"); ++ return -EIO; ++ } ++ ++ ar7_mtd_info = do_map_probe("cfi_probe", &ar7_map); ++ if (!ar7_mtd_info) ++ { ++ ar7_mtd_cleanup(); ++ return -ENXIO; ++ } ++ ++ ar7_mtd_info->module = THIS_MODULE; ++ ++ if (!(partitions = create_mtd_partitions())) ++ add_mtd_device(ar7_mtd_info); ++ else ++ add_mtd_partitions(ar7_mtd_info, ar7_partinfo, partitions); ++ ++ return 0; ++} ++ ++static char *strdup(char *str) ++{ ++ int n = strlen(str)+1; ++ char *s = kmalloc(n, GFP_KERNEL); ++ if (!s) return NULL; ++ return strcpy(s, str); ++} ++ ++ ++static int create_mtd_partitions(void) ++{ ++ unsigned int offset; ++ unsigned int size; ++ unsigned int found = 0; ++ unsigned int p = 0; ++ unsigned char *flash_base; ++ unsigned char *flash_end; ++ char *env_ptr; ++ char *base_ptr; ++ char *end_ptr; ++ unsigned int adam2_size = 0x20000; ++ unsigned int config_offset = WINDOW_SIZE; ++ unsigned int rootfs_start = 0xe0000; ++ ++ printk("Parsing ADAM2 partition map...\n"); ++ ++ do { ++ char env_name[20]; ++ ++ /* get base and end addresses of flash file system from environment */ ++ sprintf(env_name, "mtd%1u", p); ++ printk("Looking for mtd device :%s:\n", env_name); ++ ++ env_ptr = prom_getenv(env_name); ++ if(env_ptr == NULL) { ++ /* No more partitions to find */ ++ break; ++ } ++ ++ /* Extract the start and stop addresses of the partition */ ++ base_ptr = strtok(env_ptr, ","); ++ end_ptr = strtok(NULL, ","); ++ if ((base_ptr == NULL) || (end_ptr == NULL)) { ++ printk("ADAM2 partition error: Invalid %s start,end.\n", env_name); ++ break; ++ } ++ ++ flash_base = (unsigned char*) simple_strtol(base_ptr, NULL, 0); ++ flash_end = (unsigned char*) simple_strtol(end_ptr, NULL, 0); ++ if((!flash_base) || (!flash_end)) { ++ printk("ADAM2 partition error: Invalid %s start,end.\n", env_name); ++ break; ++ } ++ ++ offset = virt_to_bus(flash_base) - WINDOW_ADDR; ++ size = flash_end - flash_base; ++ printk("Found a %s image (0x%x), with size (0x%x).\n",env_name, offset, size); ++ ++ ++ if (offset == 0) { ++ printk("Assuming adam2 size of 0x%x\n", size); ++ adam2_size = size; // boot loader ++ } else if (offset > 0x120000) { ++ if (config_offset > offset) ++ config_offset = offset; // reserved at the end of the flash chip ++ } else if (offset > 0x30000) { ++ printk("Assuming default rootfs offset of 0x%x\n", offset); ++ rootfs_start = offset; // probably root fs ++ } ++ ++ p++; ++ } while (p < MAX_NUM_PARTITIONS); ++ ++ p = 0; ++ ++ ar7_partinfo[p].name = strdup("adam2"); ++ ar7_partinfo[p].offset = 0; ++ ar7_partinfo[p].size = adam2_size; ++ ar7_partinfo[p++].mask_flags = 0; ++ ++ ar7_partinfo[p].name = strdup("linux"); ++ ar7_partinfo[p].offset = adam2_size; ++ ar7_partinfo[p].size = config_offset - adam2_size; ++ ar7_partinfo[p++].mask_flags = 0; ++ ++ if (ar7_read32(&ar7_map, adam2_size) == 0xfeedfa42) { ++ rootfs_start = ar7_read32(&ar7_map, adam2_size + 4) + adam2_size + 28; ++ printk("Setting new rootfs offset to %08x\n", rootfs_start); ++ } ++ ++ ar7_partinfo[p].name = strdup("rootfs"); ++ ar7_partinfo[p].offset = rootfs_start; ++ ar7_partinfo[p].size = config_offset - rootfs_start; ++ ++ ar7_partinfo[p++].mask_flags = 0; ++ ++ ar7_partinfo[p].name = strdup("config"); ++ ar7_partinfo[p].offset = config_offset; ++ ar7_partinfo[p].size = WINDOW_SIZE - config_offset; ++ ar7_partinfo[p++].mask_flags = 0; ++ ++ if (ar7_read32(&ar7_map, rootfs_start) == SQUASHFS_MAGIC) { ++ int newsize, newoffset; ++ squashfs_super_block sb; ++ ++ ar7_copy_from(&ar7_map, &sb, rootfs_start, sizeof(sb)); ++ printk("Squashfs detected (size = 0x%08x)\n", sb.bytes_used); ++ ++ newoffset = rootfs_start + sb.bytes_used; ++ ++ if ((newoffset % ar7_mtd_info->erasesize) > 0) ++ newoffset += ar7_mtd_info->erasesize - (newoffset % ar7_mtd_info->erasesize); ++ ++ ar7_partinfo[p - 2].size = newoffset - rootfs_start; ++ ++ ar7_partinfo[p].name = strdup("OpenWrt"); ++ ar7_partinfo[p].offset = newoffset; ++ ar7_partinfo[p].size = config_offset - newoffset; ++ ar7_partinfo[p++].mask_flags = 0; ++ } else { ++ printk("Unknown filesystem. Moving rootfs partition to next erase block"); ++ if ((rootfs_start % ar7_mtd_info->erasesize) > 0) { ++ ar7_partinfo[p - 2].offset += ar7_mtd_info->erasesize - (rootfs_start % ar7_mtd_info->erasesize); ++ ar7_partinfo[p - 2].size -= ar7_mtd_info->erasesize - (rootfs_start % ar7_mtd_info->erasesize); ++ } ++ } ++ ++ return p; ++} ++ ++static void __exit ar7_mtd_cleanup(void) ++{ ++ if (ar7_mtd_info) { ++ del_mtd_partitions(ar7_mtd_info); ++ del_mtd_device(ar7_mtd_info); ++ map_destroy(ar7_mtd_info); ++ } ++ ++ if (ar7_map.map_priv_1) { ++ iounmap((void *)ar7_map.map_priv_1); ++ ar7_map.map_priv_1 = 0; ++ } ++} ++ ++module_init(ar7_mtd_init); ++module_exit(ar7_mtd_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Felix Fietkau"); ++MODULE_DESCRIPTION("AR7 CFI map driver"); +diff -urN linux.old/drivers/mtd/maps/Config.in linux.dev/drivers/mtd/maps/Config.in +--- linux.old/drivers/mtd/maps/Config.in 2005-07-21 05:36:32.414242296 +0200 ++++ linux.dev/drivers/mtd/maps/Config.in 2005-07-21 06:29:04.067118232 +0200 +@@ -48,6 +48,21 @@ + fi + + if [ "$CONFIG_MIPS" = "y" ]; then ++ if [ "$CONFIG_AR7" = "y" ]; then ++ dep_tristate ' Flash chip mapping on Texas Instruments AR7' CONFIG_MTD_AR7 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS ++ dep_bool ' Use defaults for Texas Instruments AR7' CONFIG_MTD_AR7_DEFAULTS $CONFIG_MTD_AR7 ++ if [ "$CONFIG_MTD_AR7" = "y" -o "$CONFIG_MTD_AR7" = "m" ]; then ++ if [ "$CONFIG_MTD_AR7_DEFAULTS" = "y" ]; then ++ define_hex CONFIG_MTD_AR7_START 0x10000000 ++ define_hex CONFIG_MTD_AR7_LEN 0x400000 ++ define_int CONFIG_MTD_AR7_BUSWIDTH 2 ++ else ++ hex ' Physical start address of flash mapping' CONFIG_MTD_AR7_START 0x10000000 ++ hex ' Physical length of flash mapping' CONFIG_MTD_AR7_LEN 0x400000 ++ int ' Bus width in octets' CONFIG_MTD_AR7_BUSWIDTH 2 ++ fi ++ fi ++ fi + dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000 + dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500 + dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100 +diff -urN linux.old/drivers/mtd/maps/Makefile linux.dev/drivers/mtd/maps/Makefile +--- linux.old/drivers/mtd/maps/Makefile 2005-07-21 05:36:32.414242296 +0200 ++++ linux.dev/drivers/mtd/maps/Makefile 2005-07-21 06:56:33.265401984 +0200 +@@ -10,6 +10,7 @@ + endif + + # Chip mappings ++obj-$(CONFIG_MTD_AR7) += ar7-flash.o + obj-$(CONFIG_MTD_CDB89712) += cdb89712.o + obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o + obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o diff --git a/openwrt/target/linux/ar7-2.4/patches/002-led_driver.patch b/openwrt/target/linux/ar7-2.4/patches/002-led_driver.patch new file mode 100644 index 0000000000..81fe153cc3 --- /dev/null +++ b/openwrt/target/linux/ar7-2.4/patches/002-led_driver.patch @@ -0,0 +1,1915 @@ +diff -urN linux.dev/drivers/char/Config.in linux.dev2/drivers/char/Config.in +--- linux.dev/drivers/char/Config.in 2005-10-21 17:02:20.199991500 +0200 ++++ linux.dev2/drivers/char/Config.in 2005-10-21 18:03:44.541778750 +0200 +@@ -133,6 +133,10 @@ + fi + fi + fi ++if [ "$CONFIG_AR7" = "y" ]; then ++ bool 'Enable LED support' CONFIG_AR7_LED ++fi ++ + if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then + tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232 + fi +diff -urN linux.dev/drivers/char/Makefile linux.dev2/drivers/char/Makefile +--- linux.dev/drivers/char/Makefile 2005-10-21 17:02:20.199991500 +0200 ++++ linux.dev2/drivers/char/Makefile 2005-10-21 18:03:44.541778750 +0200 +@@ -190,6 +190,12 @@ + obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP) + endif + ++# ++# Texas Intruments LED driver ++# ++obj-$(CONFIG_AR7_LED) += avalanche_led/avalanche_led.o ++subdir-$(CONFIG_AR7_LED) += avalanche_led ++ + obj-$(CONFIG_HIL) += hp_keyb.o + obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o + obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o +diff -urN linux.dev/drivers/char/avalanche_led/Makefile linux.dev2/drivers/char/avalanche_led/Makefile +--- linux.dev/drivers/char/avalanche_led/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/drivers/char/avalanche_led/Makefile 2005-10-21 18:03:44.513777000 +0200 +@@ -0,0 +1,23 @@ ++# File: drivers/char/avalanche_led/Makefile ++# ++# Makefile for the Linux LED device driver. ++# ++ ++ ++O_TARGET := avalanche_led.o ++obj-m := avalanche_led.o ++list-multi := avalanche_led.o ++ ++EXTRA_CFLAGS := -I$(TOPDIR)/include/asm/ar7 ++ ++export-objs := ledmod.o leds.o ++ ++avalanche_led-objs := ledmod.o gpio.o uartled.o leds.o ++ ++include $(TOPDIR)/Rules.make ++ ++avalanche_led.o: $(avalanche_led-objs) ++ $(LD) -r -o $@ $(avalanche_led-objs) ++ ++clean: ++ rm -f core *.o *.a *.s +diff -urN linux.dev/drivers/char/avalanche_led/gpio.c linux.dev2/drivers/char/avalanche_led/gpio.c +--- linux.dev/drivers/char/avalanche_led/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/drivers/char/avalanche_led/gpio.c 2005-10-21 18:03:44.513777000 +0200 +@@ -0,0 +1,382 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++#if defined CONFIG_AR7WRD || defined CONFIG_AR7RD ++ ++#define AR7_RESET_FILE "led_mod/ar7reset" ++#define AR7_VERSION_FILE "led_mod/hardware_version" ++#define AR7_RESET_GPIO 11 ++#define RESET_POLL_TIME 1 ++#define RESET_HOLD_TIME 4 ++#define NO_OF_LEDS ++ ++static struct proc_dir_entry *reset_file; ++static int res_state = 0; ++static int count; ++static struct timer_list *pTimer = NULL; ++static ssize_t proc_read_reset_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp); ++ ++static ssize_t proc_read_hwversion_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp); ++ ++struct file_operations reset_fops = { ++ read: proc_read_reset_fops ++ }; ++struct file_operations hardware_version_fops = { ++ read: proc_read_hwversion_fops ++ }; ++#endif ++ ++static spinlock_t device_lock; ++led_reg_t temp[15]; ++ ++static void gpio_led_on( unsigned long param ) ++{ ++ unsigned int flags; ++ ++ spin_lock_irqsave(&device_lock, flags); ++ ++ tnetd73xx_gpio_out(param,FALSE); ++ spin_unlock_irqrestore(&device_lock, flags); ++} ++ ++static void gpio_led_off ( unsigned long param ) ++{ ++ unsigned int flags = 0x00; ++ ++ spin_lock_irqsave(&device_lock, flags); ++ ++ tnetd73xx_gpio_out(param,TRUE); ++ spin_unlock_irqrestore(&device_lock, flags); ++} ++ ++static void gpio_led_init( unsigned long param) ++{ ++ tnetd73xx_gpio_ctrl(param,GPIO_PIN,GPIO_OUTPUT_PIN); ++} ++ ++static void board_gpio_reset(void) ++{ ++ /* Initialize the link mask */ ++ device_lock = SPIN_LOCK_UNLOCKED; ++ return; ++} ++ ++#if defined CONFIG_AR7WRD || defined CONFIG_AR7RD ++ ++static ssize_t proc_read_hwversion_fops(struct file *filp, char *buf, ++ size_t count, loff_t *offp) ++{ ++ char line[8]; ++ int len = 0; ++ if( *offp != 0 ) ++ return 0; ++ ++ len = sprintf(line, "%d%d.%d%d%d%d\n", tnetd73xx_gpio_in(20), ++ tnetd73xx_gpio_in(21), tnetd73xx_gpio_in(22), ++ tnetd73xx_gpio_in(23), tnetd73xx_gpio_in(24), ++ tnetd73xx_gpio_in(25)); ++ ++ copy_to_user(buf, line, len); ++ *offp = len; ++ return len; ++} ++ ++static ssize_t proc_read_reset_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp) ++{ ++ char * pdata = NULL; ++ char line[3]; ++ int len = 0; ++ if( *offp != 0 ) ++ return 0; ++ ++ pdata = buf; ++ len = sprintf(line,"%d\n", res_state ); ++//wwzh ++// res_state = 0; ++ copy_to_user(buf,line,len ); ++ *offp = len; ++ return len; ++} ++ ++static void reset_timer_func(unsigned long data) ++{ ++//wwzh ++#if 0 ++ count = (tnetd73xx_gpio_in(AR7_RESET_GPIO) == 0) ? count + 1: 0; ++ if( count >= RESET_HOLD_TIME/RESET_POLL_TIME ) ++#endif ++ if (tnetd73xx_gpio_in(AR7_RESET_GPIO) == 0) ++ res_state = 1; ++ else ++ res_state = 0; ++ pTimer->expires = jiffies + HZ*RESET_POLL_TIME; ++ add_timer (pTimer); ++ return; ++} ++ ++static void hardware_version_init(void) ++{ ++ static struct proc_dir_entry *hardware_version_file; ++ hardware_version_file = create_proc_entry(AR7_VERSION_FILE, 0777, NULL); ++ if(hardware_version_file == NULL) ++ return; ++ ++ hardware_version_file->owner = THIS_MODULE; ++ hardware_version_file->proc_fops = &hardware_version_fops; ++ ++ tnetd73xx_gpio_ctrl(20,GPIO_PIN,GPIO_INPUT_PIN); ++ tnetd73xx_gpio_ctrl(21,GPIO_PIN,GPIO_INPUT_PIN); ++ tnetd73xx_gpio_ctrl(22,GPIO_PIN,GPIO_INPUT_PIN); ++ tnetd73xx_gpio_ctrl(23,GPIO_PIN,GPIO_INPUT_PIN); ++ tnetd73xx_gpio_ctrl(24,GPIO_PIN,GPIO_INPUT_PIN); ++ tnetd73xx_gpio_ctrl(25,GPIO_PIN,GPIO_INPUT_PIN); ++ ++ return; ++} ++ ++static void reset_init(void) ++{ ++ /* Create board reset proc file */ ++ reset_file = create_proc_entry( AR7_RESET_FILE, 0777, NULL); ++ if( reset_file == NULL) ++ goto reset_file; ++ reset_file->owner = THIS_MODULE; ++ reset_file->proc_fops = &reset_fops; ++ ++ /* Initialise GPIO 11 for input */ ++ tnetd73xx_gpio_ctrl(AR7_RESET_GPIO,GPIO_PIN,GPIO_INPUT_PIN); ++ ++ /* Create a timer which fires every seconds */ ++ pTimer = kmalloc(sizeof(struct timer_list),GFP_KERNEL); ++ init_timer( pTimer ); ++ pTimer->function = reset_timer_func; ++ pTimer->data = 0; ++ /* Start the timer */ ++ reset_timer_func(0); ++ return ; ++ ++ reset_file: ++ remove_proc_entry("AR7_RESET_FILE",NULL); ++ return; ++} ++#endif ++/*************wwzh****************/ ++#if 1 ++extern unsigned int sys_mod_state; ++extern unsigned int wan_mod_state; ++extern unsigned int wlan_mod_state; ++void sys_led_init(void) ++{ ++ tnetd73xx_gpio_ctrl(4, GPIO_PIN, GPIO_OUTPUT_PIN); ++ tnetd73xx_gpio_ctrl(5, GPIO_PIN, GPIO_OUTPUT_PIN); ++ tnetd73xx_gpio_ctrl(8, GPIO_PIN, GPIO_OUTPUT_PIN); ++ ++ tnetd73xx_gpio_out(4, FALSE); ++ tnetd73xx_gpio_out(5, TRUE); ++ tnetd73xx_gpio_out(8, TRUE); ++ ++ ++ sys_mod_state = 2; ++ ++} ++void wan_led_init(void) ++{ ++ ++ tnetd73xx_gpio_ctrl(2, GPIO_PIN, GPIO_OUTPUT_PIN); ++ tnetd73xx_gpio_ctrl(3, GPIO_PIN, GPIO_OUTPUT_PIN); ++ ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, FALSE); ++ ++ wan_mod_state = 1; ++} ++//wwzh wireless ++#if 0 ++void wlan_led_init(void) ++{ ++ //unsigned long i = 0; ++ tnetd73xx_gpio_ctrl(12, GPIO_PIN, GPIO_OUTPUT_PIN); ++ tnetd73xx_gpio_ctrl(13, GPIO_PIN, GPIO_OUTPUT_PIN); ++ ++ tnetd73xx_gpio_out(12, FALSE); ++ tnetd73xx_gpio_out(13, TRUE); ++ //for (i = 0; i < 0x20000000; i++); ++ wlan_mod_state = 1; ++} ++#endif ++ ++#endif ++/*************end ****************/ ++ ++void board_gpio_init(void) ++{ ++ ++ board_gpio_reset(); ++/**************wwzh*************/ ++ sys_led_init(); ++ wan_led_init(); ++ ++ //junzhao 2004.3.15 ++ hardware_version_init(); ++ ++ //wlan_led_init(); ++ ++ /* Register Device MAX_LED_ID + 1 for reset to factory default */ ++ temp[0].param = 0; ++ temp[0].init = reset_init; ++ temp[0].onfunc = 0; ++ temp[0].offfunc = 0; ++ register_led_drv( MAX_LED_ID + 1 , &temp[0]); ++//wwzh for wireless led ++#if 1 ++ /* Register led 12 WiFi 6 */ ++ temp[1].param = 6; ++ temp[1].init = gpio_led_init; ++ temp[1].onfunc = gpio_led_on; ++ temp[1].offfunc = gpio_led_off; ++ register_led_drv( 12 , &temp[1]); ++ ++#endif ++ ++#if 0 ++/**************end ************/ ++#if defined(CONFIG_AR5D01) ++ /* Register led 1 GPIO0 */ ++ temp[0].param = GPIO_0; ++ temp[0].init = gpio_led_init; ++ temp[0].onfunc = gpio_led_on; ++ temp[0].offfunc = gpio_led_off; ++ register_led_drv( 1 , &temp[0]); ++ ++ /* Register led 2 EINT1 */ ++ temp[1].param = EINT_1; ++ temp[1].init = gpio_led_init; ++ temp[1].onfunc = gpio_led_on; ++ temp[1].offfunc = gpio_led_off; ++ register_led_drv( 2 , &temp[1]); ++ ++ /* Register led 5 EINT1 */ ++ temp[2].param = GPIO_1; ++ temp[2].init = gpio_led_init; ++ temp[2].onfunc = gpio_led_on; ++ temp[2].offfunc = gpio_led_off; ++ register_led_drv( 5 , &temp[2]); ++#endif ++ ++#if defined(CONFIG_AR5W01) ++ /* Register led 5 GPIO_1 */ ++ temp[0].param = GPIO_1; ++ temp[0].init = gpio_led_init; ++ temp[0].onfunc = gpio_led_on; ++ temp[0].offfunc = gpio_led_off; ++ register_led_drv( 5 , &temp[0]); ++ ++ /* Register led 7 GPIO_0 */ ++ temp[1].param = GPIO_0; ++ temp[1].init = gpio_led_init; ++ temp[1].onfunc = gpio_led_on; ++ temp[1].offfunc = gpio_led_off; ++ register_led_drv( 7 , &temp[1]); ++#endif ++ ++//wwzh #if defined(CONFIG_AR7RD) ++#if defined CONFIG_AR7WRD || defined CONFIG_AR7RD ++ /* Register led 5 Green PPPOE GPIO 13 */ ++ temp[0].param = 13; ++ temp[0].init = gpio_led_init; ++ temp[0].onfunc = gpio_led_on; ++ temp[0].offfunc = gpio_led_off; ++ register_led_drv( 5 , &temp[0]); ++ ++ /* Register led 7 Green USB GPIO 12 */ ++ temp[1].param = 12; ++ temp[1].init = gpio_led_init; ++ temp[1].onfunc = gpio_led_on; ++ temp[1].offfunc = gpio_led_off; ++ register_led_drv( 7 , &temp[1]); ++ ++ /* Register Device MAX_LED_ID + 1 for reset to factory default */ ++ temp[2].param = 0; ++ temp[2].init = reset_init; ++ temp[2].onfunc = 0; ++ temp[2].offfunc = 0; ++ register_led_drv( MAX_LED_ID + 1 , &temp[2]); ++ ++ /* Register led 8 RED DSL GPIO 10 */ ++ temp[3].param = 10; ++ temp[3].init = gpio_led_init; ++ temp[3].onfunc = gpio_led_on; ++ temp[3].offfunc = gpio_led_off; ++ register_led_drv( 8 , &temp[3]); ++ ++ /* Register led 9 RED PPPoE down GPIO 9 */ ++ temp[4].param = 9; ++ temp[4].init = gpio_led_init; ++ temp[4].onfunc = gpio_led_on; ++ temp[4].offfunc = gpio_led_off; ++ register_led_drv( 9 , &temp[4]); ++ ++ /* Register led 10 DSL down GPIO 8 */ ++ temp[5].param = 8; ++ temp[5].init = gpio_led_init; ++ temp[5].onfunc = gpio_led_on; ++ temp[5].offfunc = gpio_led_off; ++ register_led_drv( 10 , &temp[5]); ++ ++ /* Register led 11 Power GPIO 7 */ ++ temp[6].param = 7; ++ temp[6].init = gpio_led_init; ++ temp[6].onfunc = gpio_led_on; ++ temp[6].offfunc = gpio_led_off; ++ register_led_drv( 11 , &temp[6]); ++ ++ /* Register led 12 WiFi 6 */ ++ temp[7].param = 6; ++ temp[7].init = gpio_led_init; ++ temp[7].onfunc = gpio_led_on; ++ temp[7].offfunc = gpio_led_off; ++ register_led_drv( 12 , &temp[7]); ++ ++ /* Register led 13 ELINK(AA1313) GPIO 15 */ ++ temp[8].param = 15; ++ temp[8].init = gpio_led_init; ++ temp[8].onfunc = gpio_led_on; ++ temp[8].offfunc = gpio_led_off; ++ register_led_drv( 13 , &temp[8]); ++ ++ /* Register led 14 EACT(Y13) GPIO 16 */ ++ temp[9].param = 16; ++ temp[9].init = gpio_led_init; ++ temp[9].onfunc = gpio_led_on; ++ temp[9].offfunc = gpio_led_off; ++ register_led_drv( 14 , &temp[9]); ++ ++#endif ++/**************wwzh**************/ ++#endif ++/**************end **************/ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ +diff -urN linux.dev/drivers/char/avalanche_led/ledmod.c linux.dev2/drivers/char/avalanche_led/ledmod.c +--- linux.dev/drivers/char/avalanche_led/ledmod.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/drivers/char/avalanche_led/ledmod.c 2005-10-21 18:03:44.513777000 +0200 +@@ -0,0 +1,1116 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define LED_ON 1 ++#define LED_OFF 2 ++#define LED_BLINK 3 ++#define LED_FLASH 4 ++ ++#define LED_BLINK_UP 5 ++#define LED_BLINK_DOWN 6 ++ ++extern void avalanche_leds_init(void); ++ ++/***********wwzh**************/ ++unsigned int sys_mod_state; ++unsigned int wan_mod_state; ++unsigned int wlan_mod_state; ++ ++struct timer_list *pWanTimer = NULL; ++struct timer_list *pWlanTimer = NULL; ++/***********end **************/ ++ ++typedef struct state_entry{ ++ unsigned char mode; ++ unsigned char led; ++ void (*handler)(struct state_entry *pState); ++ unsigned long param; ++}state_entry_t; ++ ++typedef struct mod_entry{ ++ state_entry_t *states[MAX_STATE_ID]; ++}mod_entry_t; ++ ++static mod_entry_t *modArr[MAX_MOD_ID]; ++static struct proc_dir_entry *led_proc_dir,*led_file; ++ ++/* index of the array is the led number HARDWARE SPECIFIC*/ ++typedef struct led_data{ ++ led_reg_t *led; ++ int state; ++ struct timer_list *pTimer; ++ unsigned char timer_running; ++ unsigned long param; ++}led_data_t; ++ ++led_data_t led_arr[MAX_LED_ID + 1]; ++/*!!! The last device is actually being used for ar7 reset to factory default */ ++ ++ ++static spinlock_t config_lock; ++ ++static void board_led_link_up( state_entry_t *pState ); ++static void board_led_link_down( state_entry_t *pState ); ++static void board_led_activity_on( state_entry_t *pState ); ++static void board_led_activity_off( state_entry_t *pState ); ++static void led_timer_func(unsigned long data); ++ ++extern void board_gpio_init(void); ++extern void uart_led_init(void); ++ ++static ssize_t proc_read_led_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp); ++static ssize_t proc_write_led_fops(struct file *filp,const char *buffer, ++ size_t count , loff_t *offp); ++static int config_led( unsigned long y); ++ ++struct file_operations led_fops = { ++ read: proc_read_led_fops, ++ write: proc_write_led_fops, ++ }; ++ ++static int led_atoi( char *name) ++{ ++ int val = 0; ++ for(;;name++) ++ { ++ switch(*name) ++ { ++ case '0'...'9': ++ val = val*10+(*name - '0'); ++ break; ++ default: ++ return val; ++ } ++ } ++} ++ ++static int free_memory(void) ++{ ++ int i, j; ++ ++ for( i = 0; i < MAX_MOD_ID ; i++) ++ { ++ if( modArr[i] != NULL ) ++ { ++ for( j = 0; j < MAX_STATE_ID ; j++ ) ++ { ++ if( modArr[i]->states[j] != NULL ) ++ kfree( modArr[i]->states[j]); ++ } ++ kfree(modArr[i]); ++ modArr[i] = NULL; ++ } ++ } ++ return 0; ++} ++ ++static int led_on( state_entry_t *pState ) ++{ ++ if( led_arr[pState->led].led == NULL) ++ return -1; ++ led_arr[pState->led].led->onfunc( led_arr[pState->led].led->param); ++ return 0; ++} ++ ++static int led_off( state_entry_t *pState ) ++{ ++ if( led_arr[pState->led].led == NULL) ++ return -1; ++ led_arr[pState->led].led->offfunc( led_arr[pState->led].led->param); ++ return 0; ++} ++ ++static void board_led_link_up( state_entry_t *pState ) ++{ ++ led_arr[pState->led].state = LED_ON; ++ if( led_arr[pState->led].timer_running == 0 ) ++ led_on(pState); ++ return; ++} ++ ++static void board_led_link_down( state_entry_t *pState ) ++{ ++ led_arr[pState->led].state = LED_OFF; ++ if( led_arr[pState->led].timer_running == 0 ) ++ led_off(pState); ++ return; ++} ++ ++static void add_led_timer(state_entry_t *pState) ++{ ++ led_arr[pState->led].pTimer->expires = jiffies + HZ*(pState->param)/1000; ++ led_arr[pState->led].param = pState->param; ++ led_arr[pState->led].pTimer->data = pState; ++ add_timer (led_arr[pState->led].pTimer); ++} ++ ++static void board_led_activity_on(state_entry_t *pState) ++{ ++ if(led_arr[pState->led].timer_running == 0) ++ { ++ led_on(pState); ++ add_led_timer(pState); ++ led_arr[pState->led].timer_running = 1; ++ led_arr[pState->led].state = LED_BLINK_UP; ++ } ++ else if( led_arr[pState->led].timer_running > 0xF0) ++ { ++ led_arr[pState->led].state = LED_BLINK_UP; ++ led_arr[pState->led].pTimer->expires = jiffies + HZ*(pState->param)/1000; ++ led_arr[pState->led].param = pState->param; ++ led_arr[pState->led].pTimer->data = pState; ++ } ++ return; ++} ++ ++static void board_led_activity_off(state_entry_t *pState) ++{ ++ if(led_arr[pState->led].timer_running == 0) ++ { ++ led_off(pState); ++ add_led_timer(pState); ++ led_arr[pState->led].timer_running = 1; ++ led_arr[pState->led].state = LED_BLINK_UP; ++ } ++ else if( led_arr[pState->led].timer_running > 0xF0) ++ { ++ led_arr[pState->led].state = LED_BLINK_UP; ++ led_arr[pState->led].pTimer->expires = jiffies + HZ*(pState->param)/1000; ++ led_arr[pState->led].param = pState->param; ++ led_arr[pState->led].pTimer->data = pState; ++ } ++ return; ++} ++ ++static void board_led_link_flash(state_entry_t *pState) ++{ ++ if(led_on(pState)) ++ return; ++ if(led_arr[pState->led].timer_running == 0) ++ add_led_timer(pState); ++ else ++ led_arr[pState->led].param = pState->param; ++ led_arr[pState->led].timer_running = 0xFF; ++ led_arr[pState->led].state = LED_FLASH; ++ return; ++} ++ ++static void led_timer_func(unsigned long data) ++{ ++ state_entry_t *pState = NULL; ++ mod_entry_t *pMod = NULL; ++ unsigned int flags; ++ ++ spin_lock_irqsave(&config_lock, flags); ++ ++ pState = (state_entry_t *)data; ++ ++ if( led_arr[pState->led].state == LED_BLINK_DOWN ) ++ { ++ led_arr[pState->led].timer_running = 0; ++ if( pState->mode == 2 ) ++ led_arr[pState->led].state = LED_OFF; ++ else ++ led_arr[pState->led].state = LED_ON; ++ } ++ else if( led_arr[pState->led].state == LED_BLINK_UP ) ++ { ++ led_arr[pState->led].pTimer->expires = jiffies + HZ*(led_arr[pState->led].param)/1000; ++ led_arr[pState->led].pTimer->data = pState; ++ add_timer (led_arr[pState->led].pTimer); ++ if( pState->mode == 2 ) ++ { ++ led_off(pState); ++ led_arr[pState->led].state = LED_BLINK_DOWN; ++ } ++ else ++ { ++ led_on(pState); ++ led_arr[pState->led].state = LED_BLINK_DOWN; ++ } ++ led_arr[pState->led].timer_running = 1; ++ } ++ else if( led_arr[pState->led].state == LED_FLASH ) ++ { ++ led_arr[pState->led].pTimer->expires = jiffies + HZ*(led_arr[pState->led].param)/1000; ++ led_arr[pState->led].pTimer->data = pState; ++ add_timer (led_arr[pState->led].pTimer); ++ ++ if( led_arr[pState->led].timer_running == 0xFF ) ++ { ++ led_off(pState); ++ led_arr[pState->led].timer_running--; ++ } ++ else ++ { ++ led_on(pState); ++ led_arr[pState->led].timer_running++; ++ } ++ spin_unlock_irqrestore(&config_lock, flags); ++ return; ++ } ++ else if(led_arr[pState->led].state == LED_OFF) ++ { ++ led_off(pState); ++ led_arr[pState->led].timer_running = 0; ++ } ++ else if( led_arr[pState->led].state == LED_ON ) ++ { ++ led_on(pState); ++ led_arr[pState->led].timer_running = 0; ++ } ++ spin_unlock_irqrestore(&config_lock, flags); ++ return; ++} ++/************wwzh*****************/ ++#if 0 ++/************end *****************/ ++static ssize_t proc_read_led_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp) ++{ ++ char * pdata = NULL; ++ int i = 0, j = 0, len = 0, totallen = 0; ++ char line[255]; ++ ++ if( *offp != 0 ) ++ return 0; ++ ++ pdata = buf; ++ len += sprintf(line,"LEDS Registered for use are:"); ++ for( i = 0; i< MAX_LED_ID; i++) ++ if( led_arr[i].led != NULL ) ++ len += sprintf(&line[len]," %d ", i ); ++ line[len++] = '\n'; ++ ++ copy_to_user(pdata, line,len ); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ len = sprintf(line,"USER MODULE INFORMATION:\n"); ++ copy_to_user(pdata, line,len ); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ for( i = 0; i< MAX_MOD_ID; i++) ++ { ++ if( modArr[i] != NULL ) ++ { ++ len = sprintf(line," Module ID = %d \n" , i); ++ copy_to_user(pdata, line,len ); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ for( j = 0; j < MAX_STATE_ID; j++) ++ { ++ if( modArr[i]->states[j] != NULL) ++ { ++ len = sprintf(line , ++ " State = %d , Led = %d," , j , modArr[i]->states[j]->led); ++ copy_to_user(pdata, line,len ); ++ pdata += len; ++ totallen += len; ++ ++ len = 0; ++ switch( modArr[i]->states[j]->mode ) ++ { ++ case 1: ++ len = sprintf(line ," Mode = OFF\n"); ++ break; ++ case 2: ++ len = sprintf(line ," Mode = BLINK_ON , On Time(ms) = %d\n" , ++ (unsigned int)modArr[i]->states[j]->param); ++ break; ++ case 3: ++ len = sprintf(line ," Mode = BLINK_OFF , Off Time(ms) = %d\n" , ++ (unsigned int)modArr[i]->states[j]->param); ++ break; ++ case 4: ++ len = sprintf(line ," Mode = ON \n"); ++ break; ++ case 5: ++ len = sprintf(line ," Mode = FLASH , Time Period(ms) = %d\n" , ++ (unsigned int)modArr[i]->states[j]->param); ++ break; ++ default: ++ break; ++ ++ } ++ copy_to_user(pdata, line,len ); ++ pdata += len; ++ totallen += len; ++ ++ len = 0; ++ } ++ } ++ } ++ } ++ /* Return with configuration information for LEDs */ ++ *offp = totallen; ++ return totallen; ++} ++static ssize_t proc_write_led_fops(struct file *filp,const char *buffer, ++ size_t count , loff_t *offp) ++{ ++ char *pdata = NULL, *ptemp = NULL; ++ char line[10],temp[10]; ++ int i = 0; ++ int mod = 0xFFFF , state = 0xFFFF; ++ int flag = 0; ++ ++ /* Check if this write is for configuring stuff */ ++ if( *(int *)(buffer) == 0xFFEEDDCC ) ++ { ++ printk("<1>proc write:Calling Configuration\n"); ++ config_led((unsigned long)(buffer + sizeof(int)) ); ++ return count; ++ } ++ ++ if( count >= 10) ++ { ++ printk("<1>proc write:Input too long,max length = %d\n",10); ++ return count; ++ } ++ memset( temp, 0x00 , 10); ++ memset( line, 0x00 , 10); ++ copy_from_user(line,buffer,count); ++ line[count] = 0x00; ++ pdata = line; ++ ptemp = temp; ++ while( flag == 0) ++ { ++ if( i > 10 ) ++ break; ++ if( ((*pdata) >= '0' ) && ((*pdata) <= '9') ) ++ { ++ *ptemp = *pdata ; ++ ptemp++; ++ } ++ else if( (*pdata) == ',' ) ++ { ++ *ptemp = 0x00; ++ flag = 1; ++ } ++ pdata++; ++ i++; ++ }; ++ if( flag == 1) ++ mod = led_atoi( temp); ++ else ++ return count; ++ ++ ptemp = temp; ++ *ptemp = 0x00; ++ flag = 0; ++ while( flag == 0) ++ { ++ if( i > 10 ) ++ break; ++ if( ((*pdata) >= '0' ) && ((*pdata) <= '9') ) ++ { ++ *ptemp = *pdata ; ++ ptemp++; ++ } ++ else if( (*pdata) == 0x00 ) ++ { ++ *ptemp = 0x00; ++ flag = 1; ++ } ++ pdata++; ++ i++; ++ }; ++ if( flag == 1) ++ state = led_atoi( temp); ++ else ++ return count; ++ if( (mod == 0xFFFF) || (state == 0xFFFF)) ++ return count; ++ else ++ led_operation( mod , state ); ++ return count; ++} ++ ++/************wwzh*******************/ ++#else ++ ++#define TRUE 1 ++#define FALSE 0 ++#define FLICK_TIME (HZ*100/1000) ++static unsigned int wan_txrx_state = 0; ++static unsigned int wlan_txrx_state = 0; ++ ++void led_operation( int mod , int state) ++{ ++ ++ unsigned int flags; ++ ++ spin_lock_irqsave(&config_lock, flags); ++ ++ if( (mod >= MAX_MOD_ID) || ( state >= MAX_STATE_ID) ) ++ { ++ spin_unlock_irqrestore(&config_lock, flags); ++ return; ++ } ++ if ( modArr[mod] == NULL ) ++ { ++ spin_unlock_irqrestore(&config_lock, flags); ++ return; ++ } ++ if( modArr[mod]->states[state] == NULL ) ++ { ++ spin_unlock_irqrestore(&config_lock, flags); ++ return; ++ } ++ /* Call the function handler */ ++ modArr[mod]->states[state]->handler(modArr[mod]->states[state]); ++ ++ spin_unlock_irqrestore(&config_lock, flags); ++} ++ ++static void wan_led_func(unsigned long data) ++{ ++ if (wan_txrx_state == 0) ++ { ++ tnetd73xx_gpio_out(2, TRUE); ++ tnetd73xx_gpio_out(3, FALSE); ++ wan_txrx_state = 1; ++ } ++ else ++ { ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, FALSE); ++ wan_txrx_state = 0; ++ } ++ pWanTimer->expires = jiffies + FLICK_TIME; ++ add_timer(pWanTimer); ++} ++//wwzh for wireless ++#if 0 ++static void wlan_led_func(unsigned long data) ++{ ++ if (wlan_txrx_state == 0) ++ { ++ tnetd73xx_gpio_out(12, TRUE); ++ tnetd73xx_gpio_out(13, FALSE); ++ wlan_txrx_state = 1; ++ } ++ else ++ { ++ tnetd73xx_gpio_out(12, FALSE); ++ tnetd73xx_gpio_out(13, FALSE); ++ wlan_txrx_state = 0; ++ ++ } ++ pWlanTimer->expires = jiffies + FLICK_TIME; ++ add_timer(pWlanTimer); ++} ++#endif ++ ++void led_active(int mod, int state) ++{ ++ unsigned int flags = 0; ++ ++//printk("mod = %d state = %d\n", mod, state); ++ spin_lock_irqsave(&config_lock, flags); ++ if ((mod >= 5) || (state >= 5)) ++ { ++ spin_unlock_irqrestore(&config_lock, flags); ++ return; ++ } ++ ++ switch (mod) ++ { ++ case 2: /*system led */ ++ sys_mod_state = state; ++ switch (state) ++ { ++ case 1: ++ break; ++ case 2: /*sys led flashing green */ ++ tnetd73xx_gpio_out(4, FALSE); ++ tnetd73xx_gpio_out(5, TRUE); ++ tnetd73xx_gpio_out(8, TRUE); ++ break; ++ case 3: /*sys led solid green */ ++ tnetd73xx_gpio_out(4, TRUE); ++ tnetd73xx_gpio_out(5, TRUE); ++ tnetd73xx_gpio_out(8, TRUE); ++ ++ break; ++ case 4: /*sys fail red */ ++ tnetd73xx_gpio_out(4, TRUE); ++ tnetd73xx_gpio_out(5, FALSE); ++ tnetd73xx_gpio_out(8, FALSE); ++ break; ++ default: ++ break; ++ } ++ break; ++ case 3: /*wan led */ ++ wan_mod_state = state; ++ switch (state) ++ { ++ case 1: /*no wan interface*/ ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, FALSE); ++ break; ++ case 2: /*wan connected */ ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(2, TRUE); ++ tnetd73xx_gpio_out(3, FALSE); ++ break; ++ case 3: /*rx/tx activity */ ++ if (pWanTimer != NULL) ++ break; ++ ++ pWanTimer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); ++ init_timer(pWanTimer); ++ ++ pWanTimer->function = wan_led_func; ++ pWanTimer->data = 0; ++ pWanTimer->expires = jiffies + FLICK_TIME; ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, FALSE); ++ wan_txrx_state = 0; ++ add_timer(pWanTimer); ++ ++ break; ++ case 4: /*no ipaddress */ ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(2, FALSE); ++ tnetd73xx_gpio_out(3, TRUE); ++ break; ++ default: ++ if (pWanTimer) ++ { ++ del_timer(pWanTimer); ++ kfree(pWanTimer); ++ pWanTimer = NULL; ++ } ++ break; ++ } ++ break; ++ //wwzh for wireless ++ #if 0 ++ case 4: /*wlan led */ ++ wlan_mod_state = state; ++ switch (state) ++ { ++ case 1: /* wlan off */ ++ if (pWlanTimer) ++ { ++ del_timer(pWlanTimer); ++ kfree(pWlanTimer); ++ pWlanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(12, FALSE); ++ tnetd73xx_gpio_out(13, FALSE); ++ break; ++ case 2: /* wlan ready */ ++ if (pWlanTimer) ++ { ++ del_timer(pWlanTimer); ++ kfree(pWlanTimer); ++ pWlanTimer = NULL; ++ } ++ tnetd73xx_gpio_out(12, TRUE); ++ tnetd73xx_gpio_out(13, FALSE); ++ break; ++ case 3: /* wlan rx/tx activity */ ++ if (pWlanTimer != NULL) ++ break; ++ ++ pWlanTimer = kmalloc(sizeof(struct timer_list), GFP_KERNEL); ++ init_timer(pWlanTimer); ++ ++ pWlanTimer->function = wlan_led_func; ++ pWlanTimer->data = 0; ++ pWlanTimer->expires = jiffies + FLICK_TIME; ++ tnetd73xx_gpio_out(12, FALSE); ++ tnetd73xx_gpio_out(13, FALSE); ++ wlan_txrx_state = 0; ++ add_timer(pWlanTimer); ++ ++ break; ++ default: ++ if (pWlanTimer) ++ { ++ del_timer(pWlanTimer); ++ kfree(pWlanTimer); ++ pWlanTimer = NULL; ++ } ++ ++ break; ++ } ++ break; ++ #endif //for wireless ++ default: ++ break; ++ } ++ spin_unlock_irqrestore(&config_lock, flags); ++} ++static ssize_t proc_read_led_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp) ++{ ++ char *pdata = NULL; ++ int i = 0, j = 0, len = 0, totallen = 0; ++ char line[255]; ++ ++ if (*offp != 0) ++ return 0; ++ pdata = buf; ++ len = sprintf(line, "USER MODULE INFORMATION:\n"); ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ ++ //*******add Module 1 , this Module is ADSL ********/ ++ for (i = 0; i < MAX_MOD_ID; i++) ++ { ++ if (modArr[i] != NULL) ++ { ++ len = sprintf(line, " Module ID = %d\n", i); ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ for(j = 0; j < MAX_STATE_ID; j++) ++ { ++ if (modArr[i]->states[j] != NULL) ++ { ++ len = sprintf(line, "State =%d, Led = %d,", j, modArr[i]->states[j]->led); ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ switch(modArr[i]->states[j]->mode) ++ { ++ case 1: ++ len = sprintf(line, "Mode = OFF\n"); ++ break; ++ case 2: ++ len = sprintf(line, "Mode = BLINK_ON, On Time(ms) = %d\n", (unsigned int)modArr[i]->states[j]->param); ++ break; ++ case 3: ++ len = sprintf(line, "Mode = BLINK_OFF, Off Time(ms) = %d\n", (unsigned int)modArr[i]->states[j]->param); ++ break; ++ case 4: ++ len = sprintf(line, "Mode = On\n"); ++ break; ++ case 5: ++ len = sprintf(line, "Mode = FLASH, Time Period(ms) = %d\n", (unsigned int)modArr[i]->states[j]->param); ++ break; ++ default: ++ break; ++ } ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ } ++ } ++ } ++ ++ } ++ ++ len = sprintf(line, "Module ID = 2(system led)\n"); ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ switch(sys_mod_state) ++ { ++ case 1: ++ len = sprintf(line, "State = OFF\n"); ++ break; ++ case 2: ++ len = sprintf(line, "State = Booting\n"); ++ break; ++ case 3: ++ len = sprintf(line, "State = System Ready\n"); ++ break; ++ case 4: ++ len = sprintf(line, "State = System Failure\n"); ++ break; ++ default: ++ break; ++ } ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ ++ len = sprintf(line, "Module ID = 3(WAN led)\n"); ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ switch(wan_mod_state) ++ { ++ case 1: ++ len = sprintf(line, "State = OFF\n"); ++ break; ++ case 2: ++ len = sprintf(line, "State = Wan Connected\n"); ++ break; ++ case 3: ++ len = sprintf(line, "State = Wan Tx/Rx Activity\n"); ++ break; ++ case 4: ++ len = sprintf(line, "State = Wan Connect Failure\n"); ++ break; ++ default: ++ break; ++ } ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ ++//wwzh for wireless ++#if 0 ++ len = sprintf(line, "Module ID = 4(WLAN led)\n"); ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++ switch(wlan_mod_state) ++ { ++ case 1: ++ len = sprintf(line, "State = OFF\n"); ++ break; ++ case 2: ++ len = sprintf(line, "State = wlan Ready\n"); ++ break; ++ case 3: ++ len = sprintf(line, "State = wlan rx/tx activity\n"); ++ break; ++ default: ++ break; ++ } ++ copy_to_user(pdata, line, len); ++ pdata += len; ++ totallen += len; ++ len = 0; ++#endif //for wireless ++ ++ *offp = totallen; ++ return totallen; ++} ++static ssize_t proc_write_led_fops(struct file *filp,const char *buffer, ++ size_t count , loff_t *offp) ++{ ++ char *pdata = NULL, *ptemp = NULL; ++ char line[10], temp[10]; ++ int i = 0; ++ int mod = 0xffff, state = 0xffff; ++ int flag = 0; ++ ++ /* Check if this write is for configuring ADSL */ ++ if( *(int *)(buffer) == 0xFFEEDDCC ) ++ { ++ printk("<1>proc write:Calling Configuration\n"); ++ config_led((unsigned long)(buffer + sizeof(int)) ); ++ return count; ++ } ++ ++ if (count > 10) ++ { ++ printk("<1> proc write: Input too long, max length = 10\n"); ++ return count; ++ } ++ memset(temp, 0x00, 10); ++ memset(line, 0x00, 10); ++ copy_from_user(line, buffer, count); ++ line[count] = 0x00; ++ pdata = line; ++ ptemp = temp; ++ ++ while (flag == 0) ++ { ++ if (i > 10) ++ break; ++ if (((*pdata) >= '0') && ((*pdata) <= '9')) ++ { ++ *ptemp = *pdata; ++ ptemp++; ++ } ++ else if ((*pdata) == ',') ++ { ++ *ptemp = 0x00; ++ flag = 1; ++ } ++ pdata++; ++ i++; ++ } ++ if (flag == 1) ++ mod = led_atoi(temp); ++ else ++ return count; ++ ++ ptemp = temp; ++ *ptemp = 0x00; ++ flag = 0; ++ ++ while(flag == 0) ++ { ++ if (i > 10) ++ break; ++ if (((*pdata) >= '0') && ((*pdata) <= '9')) ++ { ++ *ptemp = *pdata; ++ ptemp++; ++ } ++ else if ((*pdata) == 0x00) ++ { ++ *ptemp = 0x00; ++ flag = 1; ++ } ++ pdata++; ++ i++; ++ } ++ if (flag == 1) ++ state = led_atoi(temp); ++ else ++ return count; ++ if ((mod == 0xFFFF) || (state == 0xFFFF)) ++ return count; ++ else ++ { ++ if (mod != 4) ++ led_active(mod, state); ++ else ++ led_operation(mod, state); ++ } ++ return 1; ++} ++#endif ++/************end *******************/ ++static int config_led(unsigned long y) ++{ ++ config_elem_t *pcfg = NULL; ++ char *pdata = NULL; ++ int i; ++ int length = 0 , number = 0; ++ unsigned int flags; ++ ++ spin_lock_irqsave(&config_lock, flags); ++ ++ /* ioctl to configure */ ++ length = *((int*)y); ++ pdata = (char *)y + sizeof(int); ++ number = (length - sizeof(int))/sizeof(config_elem_t); ++ pcfg = (config_elem_t *)(pdata); ++ ++ /* Check if an earlier configuration exists IF yes free it up */ ++ free_memory(); ++ ++ for ( i = 0 ; i < number ; i++ ) ++ { ++ /* If no structure has been allocated for the module do so */ ++ if ( modArr[pcfg->name] == NULL ) ++ { ++ printk("<1>module = %d\n",pcfg->name); ++ if( pcfg->name >= MAX_MOD_ID) ++ { ++ printk("<1>Exiting Configuration: Module ID too large %d\n",pcfg->name); ++ free_memory(); ++ spin_unlock_irqrestore(&config_lock, flags); ++ return -1; ++ } ++ modArr[pcfg->name] = kmalloc(sizeof(mod_entry_t),GFP_KERNEL); ++ if(modArr[pcfg->name] == NULL) ++ { ++ printk("<1>Exiting Configuration: Error in allocating memory\n"); ++ free_memory(); ++ spin_unlock_irqrestore(&config_lock, flags); ++ return -1; ++ } ++ memset( modArr[pcfg->name], 0x00, sizeof(mod_entry_t)); ++ } ++ ++ /* if no structure is allocated previously for this state ++ allocate a structure, if it's already there fill it up */ ++ if( modArr[pcfg->name]->states[pcfg->state] == NULL) ++ { ++ printk("<1>STATE = %d\n",pcfg->state); ++ if( pcfg->state >= MAX_STATE_ID) ++ { ++ printk("<1>Exiting Configuration: State ID too large\n"); ++ free_memory(); ++ spin_unlock_irqrestore(&config_lock, flags); ++ return -1; ++ } ++ modArr[pcfg->name]->states[pcfg->state] = ++ kmalloc(sizeof(state_entry_t),GFP_KERNEL); ++ if( modArr[pcfg->name]->states[pcfg->state] == NULL) ++ { ++ free_memory(); ++ spin_unlock_irqrestore(&config_lock, flags); ++ return -1; ++ } ++ memset( modArr[pcfg->name]->states[pcfg->state], 0x00, sizeof(state_entry_t)); ++ } ++ /* Fill up the fields of the state */ ++ if( pcfg->led >= MAX_LED_ID) ++ { ++ printk("<1>led = %d\n",pcfg->led); ++ free_memory(); ++ spin_unlock_irqrestore(&config_lock, flags); ++ return -1; ++ } ++ modArr[pcfg->name]->states[pcfg->state]->led = pcfg->led; ++ modArr[pcfg->name]->states[pcfg->state]->mode = pcfg->mode; ++ modArr[pcfg->name]->states[pcfg->state]->param = pcfg->param; ++ switch(pcfg->mode) ++ { ++ case 1: ++ modArr[pcfg->name]->states[pcfg->state]->handler = board_led_link_down; ++ break; ++ case 2: ++ case 3: ++ case 5: ++ if( pcfg->mode == 2 ) ++ modArr[pcfg->name]->states[pcfg->state]->handler = board_led_activity_on; ++ else if( pcfg->mode == 3) ++ modArr[pcfg->name]->states[pcfg->state]->handler = board_led_activity_off; ++ else ++ modArr[pcfg->name]->states[pcfg->state]->handler = board_led_link_flash; ++ break; ++ case 4: ++ modArr[pcfg->name]->states[pcfg->state]->handler = board_led_link_up; ++ break; ++ default: ++ printk("<1>Exiting Configuration: Unknown LED Mode\n"); ++ free_memory(); ++ spin_unlock_irqrestore(&config_lock, flags); ++ return -1; ++ } ++ pcfg++; ++ } ++ spin_unlock_irqrestore(&config_lock, flags); ++ return 0; ++} ++ ++ ++int __init led_init(void) ++{ ++ ++ /* Clear our memory */ ++ memset(modArr,0x00,sizeof(mod_entry_t *)*MAX_MOD_ID); ++ memset(led_arr,0x00,sizeof(led_data_t *)*MAX_LED_ID); ++ ++ /* Create spin lock for config data structure */ ++ config_lock=SPIN_LOCK_UNLOCKED; ++ ++ /* Create directory */ ++ led_proc_dir = proc_mkdir("led", NULL); ++ if( led_proc_dir == NULL ) ++ goto out; ++ ++ /* Create adsl file */ ++ led_file = create_proc_entry("led", 0777, led_proc_dir); ++ if( led_file == NULL) ++ goto led_file; ++ led_file->owner = THIS_MODULE; ++ led_file->proc_fops = &led_fops; ++ ++ memset( modArr , 0x00 , sizeof(mod_entry_t *) * MAX_MOD_ID); ++ /* Reset the GPIO pins */ ++ board_gpio_init(); ++ ++ /* Register the UART controlled LEDS */ ++ uart_led_init(); ++ /* Create the usb proc file */ ++ avalanche_leds_init(); ++ return 0; ++ ++ led_file: ++ remove_proc_entry("led",led_proc_dir); ++ out: ++ return 0; ++ ++} ++ ++void led_exit() ++{ ++ remove_proc_entry("led", led_proc_dir); ++} ++ ++module_init(led_init); ++module_exit(led_exit); ++ ++void register_led_drv( int device , led_reg_t *pInfo) ++{ ++ unsigned int flags; ++ struct timer_list *pTimer = NULL; ++ ++ spin_lock_irqsave(&config_lock, flags); ++ ++ led_arr[device].led = pInfo; ++ if( led_arr[device].led->init != 0x00) ++ led_arr[device].led->init(led_arr[device].led->param); ++ if( led_arr[device].led->offfunc != 0x00) ++ led_arr[device].led->offfunc(led_arr[device].led->param); ++ ++ /* Create a timer for blinking */ ++ pTimer = kmalloc(sizeof(struct timer_list),GFP_KERNEL); ++ init_timer( pTimer ); ++ pTimer->function = led_timer_func; ++ pTimer->data = 0; ++ led_arr[device].pTimer = pTimer; ++ led_arr[device].timer_running = 0; ++ ++ spin_unlock_irqrestore(&config_lock, flags); ++ ++ return; ++} ++ ++void deregister_led_drv( int device) ++{ ++ unsigned int flags; ++ ++ spin_lock_irqsave(&config_lock, flags); ++ led_arr[device].led = NULL; ++ ++ if( led_arr[device].pTimer != NULL) ++ { ++ del_timer(led_arr[device].pTimer); ++ kfree(led_arr[device].pTimer); ++ } ++ spin_unlock_irqrestore(&config_lock, flags); ++ ++ return; ++} ++ ++EXPORT_SYMBOL_NOVERS(led_operation); ++EXPORT_SYMBOL_NOVERS(register_led_drv); ++EXPORT_SYMBOL_NOVERS(deregister_led_drv); ++ +diff -urN linux.dev/drivers/char/avalanche_led/leds.c linux.dev2/drivers/char/avalanche_led/leds.c +--- linux.dev/drivers/char/avalanche_led/leds.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/drivers/char/avalanche_led/leds.c 2005-10-21 18:03:44.513777000 +0200 +@@ -0,0 +1,133 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#if defined(CONFIG_AR5D01) || defined(CONFIG_AR5W01) || defined(CONFIG_AR7) ++ ++#define ETH_MASK 0x01 ++#define USB_MASK 0x02 ++ ++static struct proc_dir_entry *usb_file; ++static ssize_t proc_read_usb_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp); ++struct file_operations usb_fops = {read: proc_read_usb_fops}; ++ ++typedef struct mod_states{ ++ int module; ++ int activity; ++ int linkup; ++ int idle; ++}mod_states_t; ++ ++mod_states_t state_arr[] = { ++ { MOD_ETH,DEF_ETH_ACTIVITY,DEF_ETH_LINK_UP,DEF_ETH_IDLE }, ++ { MOD_USB,DEF_USB_ACTIVITY,DEF_USB_LINK_UP,DEF_USB_IDLE }, ++ { MOD_LAN,DEF_LAN_ACTIVITY,DEF_LAN_LINK_UP,DEF_LAN_IDLE } ++ }; ++ ++unsigned char device_links = 0; /* Bitmask with the devices that are up */ ++ ++ ++void avalanche_led_activity_pulse(unsigned long device) ++{ ++ /* If device link is not up return */ ++ if( !(device_links & (unsigned char)(1 << device))) ++ return; ++#ifdef MULTIPLEX_LED ++ led_operation( state_arr[2].module, state_arr[2].activity); ++#else ++ led_operation( state_arr[device].module, state_arr[device].activity); ++#endif ++} ++ ++void avalanche_led_link_up( unsigned long device ) ++{ ++ ++ /* If already UP ignore */ ++ if( device_links & (unsigned char)(1 << device)) ++ return; ++ /* Turn on the bit for the device */ ++ device_links |= (unsigned char)(1 << device); ++#ifdef MULTIPLEX_LED ++ led_operation( state_arr[2].module, state_arr[2].linkup); ++#else ++ led_operation( state_arr[device].module, state_arr[device].linkup); ++#endif ++} ++ ++void avalanche_led_link_down ( unsigned long device ) ++{ ++ ++ /* If already DOWN ignore */ ++ if( !(device_links & (unsigned char)(1 << device))) ++ return; ++ ++ /* Turn off the bit for the device */ ++ device_links &= ~(unsigned char)(1 << device); ++#ifdef MULTIPLEX_LED ++ /* If no links, then shut the LED off */ ++ if(!device_links) ++ led_operation( state_arr[2].module, state_arr[2].idle); ++#else ++ led_operation( state_arr[device].module, state_arr[device].idle); ++#endif ++} ++ ++static ssize_t proc_read_usb_fops(struct file *filp, ++ char *buf,size_t count , loff_t *offp) ++{ ++ char * pdata = NULL; ++ char line[3]; ++ if( *offp != 0 ) ++ return 0; ++ pdata = buf; ++ if( device_links & USB_MASK) ++ sprintf(line,"%s\n","1"); ++ else ++ sprintf(line,"%s\n","0"); ++ copy_to_user(pdata,line,2); ++ *offp = 2; ++ return 2; ++} ++ ++ ++void avalanche_leds_init(void) ++{ ++ /* Create usb link proc file */ ++ usb_file = create_proc_entry("avalanche/usb_link", 0444, NULL); ++ if( usb_file == NULL) ++ return; ++ usb_file->owner = THIS_MODULE; ++ usb_file->proc_fops = &usb_fops; ++ return; ++} ++ ++EXPORT_SYMBOL(avalanche_led_activity_pulse); ++EXPORT_SYMBOL(avalanche_led_link_up); ++EXPORT_SYMBOL(avalanche_led_link_down); ++ ++#else ++/* We make a dummy init routine for the platforms that do not support this led ++ API ++*/ ++ ++void avalanche_leds_init(void) ++{ ++} ++ ++#endif ++ ++ ++ ++ ++ +diff -urN linux.dev/drivers/char/avalanche_led/uartled.c linux.dev2/drivers/char/avalanche_led/uartled.c +--- linux.dev/drivers/char/avalanche_led/uartled.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/drivers/char/avalanche_led/uartled.c 2005-10-21 18:03:44.529778000 +0200 +@@ -0,0 +1,55 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#define UART_LED_REG (*(volatile unsigned int *)(UARTA_BASE + 0x10)) ++ ++static spinlock_t device_lock; ++led_reg_t temp1[2]; ++ ++static void uart_led_on(unsigned long param) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&device_lock,flags); ++ UART_LED_REG &= 0xFFFD; ++ spin_unlock_irqrestore(&device_lock, flags); ++} ++ ++static void uart_led_off ( unsigned long param ) ++{ ++ unsigned int flags = 0x00; ++ spin_lock_irqsave(&device_lock, flags); ++ UART_LED_REG |= 0x02; ++ spin_unlock_irqrestore(&device_lock, flags); ++} ++ ++void uart_led_init(void) ++{ ++ ++#if defined(CONFIG_AR5D01) ++ /* Register led 6 UART Pin 1 */ ++ temp1[0].param = 0; ++ temp1[0].init = NULL; ++ temp1[0].onfunc = uart_led_on; ++ temp1[0].offfunc = uart_led_off; ++ register_led_drv( 6 , &temp1[0]); ++#endif ++ ++#if defined(CONFIG_AR5W01) ++ /* Register led 8 UART Pin 1 */ ++ temp1[0].param = 0; ++ temp1[0].init = NULL; ++ temp1[0].onfunc = uart_led_on; ++ temp1[0].offfunc = uart_led_off; ++ register_led_drv( 8 , &temp1[0]); ++#endif ++ ++ /* Initialize the link mask */ ++ device_lock = SPIN_LOCK_UNLOCKED; ++ ++ return; ++} ++ +diff -urN linux.dev/include/asm-mips/ar7/led_config.h linux.dev2/include/asm-mips/ar7/led_config.h +--- linux.dev/include/asm-mips/ar7/led_config.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/include/asm-mips/ar7/led_config.h 2005-10-21 17:02:25.568327000 +0200 +@@ -0,0 +1,55 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED config Header ++ ****************************************************************************** ++ * FILE NAME: led_config.h ++ * ++ * DESCRIPTION: Header file for LED configuration parameters ++ * and data structures ++ * ++ * REVISION HISTORY: ++ * 11 Oct 03 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++ ++#ifndef __LED_CONFIG__ ++#define __LED_CONFIG__ ++ ++/* LED config parameters */ ++#define MAX_GPIO_PIN_NUM 64 ++#define MAX_GPIOS_PER_STATE 5 ++#define MAX_MODULE_ENTRIES 25 ++#define MAX_MODULE_INSTANCES 4 ++#define MAX_STATE_ENTRIES 25 ++#define MAX_LED_ENTRIES 25 ++ ++ ++/* LED modes */ ++#define LED_OFF 0 ++#define LED_ON 1 ++#define LED_ONESHOT_OFF 2 ++#define LED_ONESHOT_ON 3 ++#define LED_FLASH 4 ++#define LED_BLINK_CODE0 5 /*--- param1: on time, param2: blink nr , (param2 > 100 blink off) ---*/ ++#define LED_BLINK_CODE1 6 ++#define LED_BLINK_CODE2 7 ++ ++#define NUM_LED_MODES 8 ++ ++ ++ ++/* Data structure for LED configuration */ ++typedef struct led_config{ ++ unsigned char name[80]; ++ unsigned int instance; ++ unsigned int state; ++ unsigned int gpio[MAX_GPIOS_PER_STATE]; ++ unsigned int mode[MAX_GPIOS_PER_STATE]; ++ unsigned int gpio_num; ++ unsigned int param1; ++ unsigned int param2; ++}LED_CONFIG_T; ++ ++ ++#endif /* __LED_CONFIG__ */ +diff -urN linux.dev/include/asm-mips/ar7/led_hal.h linux.dev2/include/asm-mips/ar7/led_hal.h +--- linux.dev/include/asm-mips/ar7/led_hal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/include/asm-mips/ar7/led_hal.h 2005-10-21 17:02:25.568327000 +0200 +@@ -0,0 +1,30 @@ ++/****************************************************************************** ++ * FILE PURPOSE: - LED HAL module Header ++ ****************************************************************************** ++ * FILE NAME: led_hal.h ++ * ++ * DESCRIPTION: LED HAL API's. ++ * ++ * REVISION HISTORY: ++ * 11 Oct 03 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __LED_HAL__ ++#define __LED_HAL__ ++ ++/* Interface prototypes */ ++#include "led_config.h" ++ ++int avalanche_led_hal_init (int *gpio_off_value, int num_gpio_pins); ++int avalanche_led_config_set (LED_CONFIG_T * led_cfg); ++int avalanche_led_config_get (LED_CONFIG_T *led_cfg,int module_id,int instance, int state); ++void *avalanche_led_register (const char *module_name, int instance_num); ++void avalanche_led_action (void *handle, int state_id); ++void avalanche_led_late_actions(void); ++int avalanche_led_unregister (void *handle); ++void avalanche_led_free_all(void); ++void avalanche_led_hal_exit (void); ++ ++#endif /*__LED_HAL__ */ +diff -urN linux.dev/include/asm-mips/ar7/ledapp.h linux.dev2/include/asm-mips/ar7/ledapp.h +--- linux.dev/include/asm-mips/ar7/ledapp.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev2/include/asm-mips/ar7/ledapp.h 2005-10-21 18:03:44.573780750 +0200 +@@ -0,0 +1,59 @@ ++#ifndef __LED_APP__ ++#define __LED_APP__ ++ ++#define CONF_FILE "/etc/led.conf" ++#define LED_PROC_FILE "/proc/led_mod/led" ++ ++#define CONFIG_LED_MODULE ++ ++#define MAX_MOD_ID 25 ++#define MAX_STATE_ID 25 ++#define MAX_LED_ID 25 ++ ++#define MOD_ADSL 1 ++#define DEF_ADSL_IDLE 1 ++#define DEF_ADSL_TRAINING 2 ++#define DEF_ADSL_SYNC 3 ++#define DEF_ADSL_ACTIVITY 4 ++ ++#define MOD_WAN 2 ++#define DEF_WAN_IDLE 1 ++#define DEF_WAN_NEGOTIATE 2 ++#define DEF_WAN_SESSION 3 ++ ++#define MOD_LAN 3 ++#define DEF_LAN_IDLE 1 ++#define DEF_LAN_LINK_UP 2 ++#define DEF_LAN_ACTIVITY 3 ++ ++#define MOD_WLAN 4 ++#define DEF_WLAN_IDLE 1 ++#define DEF_WLAN_LINK_UP 2 ++#define DEF_WLAN_ACTIVITY 3 ++ ++#define MOD_USB 5 ++#define DEF_USB_IDLE 1 ++#define DEF_USB_LINK_UP 2 ++#define DEF_USB_ACTIVITY 3 ++ ++#define MOD_ETH 6 ++#define DEF_ETH_IDLE 1 ++#define DEF_ETH_LINK_UP 2 ++#define DEF_ETH_ACTIVITY 3 ++ ++typedef struct config_elem{ ++ unsigned char name; ++ unsigned char state; ++ unsigned char mode; ++ unsigned char led; ++ int param; ++}config_elem_t; ++ ++typedef struct led_reg{ ++ unsigned int param; ++ void (*init)(unsigned long param); ++ void (*onfunc)(unsigned long param); ++ void (*offfunc)(unsigned long param); ++}led_reg_t; ++ ++#endif diff --git a/openwrt/target/linux/ar7-2.4/patches/003-net_driver_cpmac.patch b/openwrt/target/linux/ar7-2.4/patches/003-net_driver_cpmac.patch new file mode 100644 index 0000000000..42b64584da --- /dev/null +++ b/openwrt/target/linux/ar7-2.4/patches/003-net_driver_cpmac.patch @@ -0,0 +1,13341 @@ +diff -urN linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.c +--- linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.c 2005-07-12 02:48:41.996601000 +0200 +@@ -0,0 +1,728 @@ ++#ifndef _INC_CPCOMMON_C ++#define _INC_CPCOMMON_C ++ ++#ifdef _CPHAL_CPMAC ++#include "cpremap_cpmac.c" ++#endif ++ ++#ifdef _CPHAL_AAL5 ++#include "cpremap_cpaal5.c" ++#endif ++ ++#ifdef _CPHAL_CPSAR ++#include "cpremap_cpsar.c" ++#endif ++ ++#ifdef _CPHAL_AAL2 ++#include "cpremap_cpaal2.c" ++#endif ++ ++/** ++@defgroup Common_Config_Params Common Configuration Parameters ++ ++This section documents the configuration parameters that are valid across ++all CPHAL devices. ++@{ ++*/ ++/** This is the debug level. The field is bit defined, such that the user ++should set to 1 all the bits corresponding to desired debug outputs. The following ++are the meanings for each debug bit: ++- bit0 (LSB): CPHAL Function Trace ++- b1 : OS Function call trace ++- b2 : Critical section entry/exit ++- b3 : Memory allocation/destruction ++- b4 : Detailed information in Rx path ++- b5 : Detailed information in Tx path ++- b6 : Extended error information ++- b7 : General info ++*/ ++static const char pszDebug[] = "debug"; ++/** CPU Frequency. */ ++/*static const char pszCpuFreq[] = "CpuFreq";*/ /*MJH-030403*/ ++/** Base address for the module. */ ++static const char pszBase[] = "base"; ++/** Reset bit for the module. */ ++static const char pszResetBit[] = "reset_bit"; ++/** Reset base address for the module. */ ++static const char pszResetBase[] = "ResetBase"; ++/** Interrupt line for the module. */ ++static const char pszIntLine[] = "int_line"; ++/** VLYNQ offset for the module. Disregard if not using VLYNQ. */ ++static const char pszOffset[] = "offset"; ++/** The OS may "Get" this parameter, which is a pointer ++ to a character string that indicates the version of CPHAL. */ ++static const char pszVer[] = "Version"; ++/*@}*/ ++ ++/** ++@defgroup Common_Control_Params Common Keys for [os]Control() ++ ++This section documents the keys used with the OS @c Control() interface that ++are required by CPHAL devices. ++ ++@{ ++*/ ++/** Used to wait for an integer number of clock ticks, given as an integer ++ pointer in the @p Value parameter. No actions are defined. */ ++static const char pszSleep[] = "Sleep"; ++/** Requests the OS to flush it's IO buffers. No actions are defined. */ ++static const char pszSioFlush[] = "SioFlush"; ++/*@}*/ ++ ++static const char pszStateChange[] = "StateChange"; ++static const char pszStatus[] = "Status"; ++ ++static const char pszGET[] = "Get"; ++static const char pszSET[] = "Set"; ++static const char pszCLEAR[] = "Clear"; ++static const char pszNULL[] = ""; ++static const char pszLocator[] = "Locator"; ++static const char pszOff[] = "Off"; ++static const char pszOn[] = "On"; ++static const char hcMaxFrags[] = "MaxFrags"; ++ ++#ifdef _CPHAL_CPMAC ++ ++/* New method for string constants */ ++const char hcClear[] = "Clear"; ++const char hcGet[] = "Get"; ++const char hcSet[] = "Set"; ++ ++const char hcTick[] = "Tick"; ++ ++static const CONTROL_KEY KeyCommon[] = ++ { ++ {"" , enCommonStart}, ++ {pszStatus , enStatus}, ++ {pszOff , enOff}, ++ {pszOn , enOn}, ++ {pszDebug , enDebug}, ++ {hcCpuFrequency , enCpuFreq}, /*MJH~030403*/ ++ {"" , enCommonEnd} ++ }; ++#endif ++ ++/** ++@defgroup Common_Statistics Statistics ++ ++A broad array of module statistics is available. Statistics values are accessed ++through the @c Control() interface of the CPHAL. There are 5 different levels ++of statistics, each of which correspond to a unique set of data. Furthermore, ++certain statistics data is indexed by using a channel number and Tx queue number. ++The following is a brief description of each statistics level, along with the ++indexes used for the level: ++ ++- Level 0: Hardware Statistics (index with channel) ++- Level 1: CPHAL Software Statistics (channel, queue) ++- Level 2: CPHAL Flags (channel, queue) ++- Level 3: CPHAL Channel Configuration (channel) ++- Level 4: CPHAL General Configuration (no index) ++ ++The caller requests statistics information by providing a Key string to the ++@c Control() API in the following format: "Stats;[Level #];[Ch #];[Queue #]". ++The only valid Action parameter for statistics usage is "Get". ++ ++Code Examples: ++@code ++unsigned int *StatsData; ++ ++# Get Level 0 stats for Channel 1 ++HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); ++ ++# Get Level 2 stats for Channel 0, Queue 0 ++HalFunc->Control(OsDev->HalDev, "Stats;2;0;0", "Get", &StatsData); ++ ++# Get Level 4 stats ++HalFunc->Control(OsDev->HalDev, "Stats;4", "Get", &StatsData); ++@endcode ++ ++The information returned in the Value parameter of @c Control() is an ++array of pointers to strings. The pointers are arranged in pairs. ++The first pointer is a pointer to a name string for a particular statistic. ++The next pointer is a pointer to a string containing the representation of ++the integer statistic value corresponding to the first pointer. This is followed ++by another pair of pointers, and so on, until a NULL pointer is encountered. The ++following is example code for processing the statistics data. Note that the OS ++is responsible for freeing the memory passed back through the Value parameter of ++@c Control(). ++ ++@code ++unsigned int *StatsData; ++ ++# Get Level 0 stats for Channel 1 ++HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); ++ ++# output Statistics data ++PrintStats(StatsData); ++ ++# the upper layer is responsible for freeing stats info ++free(&StatsPtr); ++ ++... ++ ++void PrintStats(unsigned int *StatsPtr) ++ { ++ while(*StatsPtr) ++ { ++ printf("%20s:", (char *)*StatsPtr); ++ StatsPtr++; ++ printf("%11s\n", (char *)*StatsPtr); ++ StatsPtr++; ++ } ++ MySioFlush(); ++ } ++@endcode ++ ++Within each statistics level, there are several statistics defined. The statistics that ++are common to every CPPI module are listed below. In addition, each module may define ++extra statistics in each level, which will be documented within the module-specific ++documentation appendices. ++ ++- Level 0 Statistics ++ - All level 0 statistics are module-specific. ++- Level 1 Statistics (CPHAL Software Statistics) ++ - DmaLenErrors: Incremented when the port DMA's more data than expected (per channel). (AAL5 Only) ++ - TxMisQCnt: Incremented when host queues a packet for transmission as the port finishes ++transmitting the previous last packet in the queue (per channel and queue). ++ - RxMisQCnt: Incremented when host queues adds buffers to a queue as the port finished the ++reception of the previous last packet in the queue (per channel). ++ - TxEOQCnt: Number of times the port has reached the end of the transmit queue (per channel and queue). ++ - RxEOQCnt: Number of times the port has reached the end of the receive queue (per channel). ++ - RxPacketsServiced: Number of received packets (per channel). ++ - TxPacketsServiced: Number of transmitted packets (per channel and queue). ++ - RxMaxServiced: Maximum number of packets that the CPHAL receive interrupt has serviced at a time (per channel). ++ - TxMaxServiced: Maximum number of packets that the CPHAL transmit interrupt has serviced at a time (per channel and queue). ++ - RxTotal: Total number of received packets, all channels. ++ - TxTotal: Total number of transmitted packets, all channels and queues. ++- Level 2 Statistics (CPHAL Flags) ++ - RcbPool: Pointer to receive descriptor pool (per channel). ++ - RxActQueueCount: Number of buffers currently available for receive (per channel). ++ - RxActQueueHead: Pointer to first buffer in receive queue (per channel). ++ - RxActQueueTail: Pointer to last buffer in receive queue (per channel). ++ - RxActive: 0 if inactive (no buffers available), or 1 if active (buffers available). ++ - RcbStart: Pointer to block of receive descriptors. ++ - RxTeardownPending: 1 if Rx teardown is pending but incomplete, 0 otherwise. ++ - TcbPool: Pointer to transmit descriptor pool (per channel and queue). ++ - TxActQueueCount: Number of buffers currently queued to be transmitted (per channel and queue). ++ - TxActQueueHead: Pointer to first buffer in transmit queue (per channel and queue). ++ - TxActQueueTail: Pointer to last buffer in transmit queue (per channel and queue). ++ - TxActive: 0 if inactive (no buffers to send), or 1 if active (buffers queued to send). ++ - TcbStart: Pointer to block of transmit descriptors. ++ - TxTeardownPending: 1 if Tx teardown is pending but incomplete, 0 otherwise. ++- Level 3 Statistics (CPHAL Channel Configuration) ++ - RxBufSize: Rx buffer size. ++ - RxBufferOffset: Rx buffer offset. ++ - RxNumBuffers: Number of Rx buffers. ++ - RxServiceMax: Maximum number of receive packets to service at a time. ++ - TxNumBuffers: Number of Tx buffer descriptors. ++ - TxNumQueues: Number of Tx queues to use. ++ - TxServiceMax: Maximum number of transmit packets to service at a time. ++- Level 4 Statistics (CPHAL General Configuration) ++ - Base Address: Base address of the module. ++ - Offset (VLYNQ): VLYNQ relative module offset. ++ - Interrupt Line: Interrupt number. ++ - Debug: Debug flag, 1 to enable debug. ++ - Inst: Instance number. ++*/ ++ ++/* ++ Data Type 0 = int display ++ Data Type 1 = hex display ++ Data Type 2 = channel structure, int display ++ Data Type 3 = queue index and int display ++ Data Type 4 = queue index and hex display ++*/ ++#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) /* +GSG 030307 */ ++static STATS_TABLE StatsTable0[] = ++ { ++#ifdef _CPHAL_AAL5 ++ /* Name , Data Ptr, Data Type */ ++ {"Crc Errors", 0, 0}, ++ {"Len Errors", 0, 0}, ++ {"Abort Errors", 0, 0}, ++ {"Starv Errors", 0, 0} ++#endif ++#ifdef _CPHAL_CPMAC ++ {"Rx Good Frames", 0, 0} ++#endif ++ }; ++ ++static STATS_TABLE StatsTable1[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"DmaLenErrors", 0, 0}, ++ {"TxMisQCnt", 0, 3}, ++ {"RxMisQCnt", 0, 0}, ++ {"TxEOQCnt", 0, 3}, ++ {"RxEOQCnt", 0, 0}, ++ {"RxPacketsServiced", 0, 0}, ++ {"TxPacketsServiced", 0, 3}, ++ {"RxMaxServiced", 0, 0}, ++ {"TxMaxServiced", 0, 3}, ++ {"RxTotal", 0, 0}, ++ {"TxTotal", 0, 0}, ++ }; ++ ++static STATS_TABLE StatsTable2[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"RcbPool", 0, 1}, ++ {"RxActQueueCount", 0, 0}, ++ {"RxActQueueHead", 0, 1}, ++ {"RxActQueueTail", 0, 1}, ++ {"RxActive", 0, 0}, ++ {"RcbStart", 0, 1}, ++ {"RxTeardownPending", 0, 0}, ++ {"TcbPool", 0, 4}, ++ {"TxActQueueCount", 0, 3}, ++ {"TxActQueueHead", 0, 4}, ++ {"TxActQueueTail", 0, 4}, ++ {"TxActive", 0, 3}, ++ {"TcbStart", 0, 4}, ++ {"TxTeardownPending", 0, 0} ++ }; ++ ++static STATS_TABLE StatsTable3[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"RxBufSize", 0, 2}, ++ {"RxBufferOffset", 0, 2}, ++ {"RxNumBuffers", 0, 2}, ++ {"RxServiceMax", 0, 2}, ++ {"TxNumBuffers", 0, 2}, ++ {"TxNumQueues", 0, 2}, ++ {"TxServiceMax", 0, 2}, ++#ifdef _CPHAL_AAL5 ++ {"CpcsUU", 0, 2}, ++ {"Gfc", 0, 2}, ++ {"Clp", 0, 2}, ++ {"Pti", 0, 2}, ++ {"DaMask", 0, 2}, ++ {"Priority", 0, 2}, ++ {"PktType", 0, 2}, ++ {"Vci", 0, 2}, ++ {"Vpi", 0, 2}, ++ {"CellRate", 0, 2}, ++ {"QosType", 0, 2}, ++ {"Mbs", 0, 2}, ++ {"Pcr", 0, 2} ++#endif ++ }; ++ ++static STATS_TABLE StatsTable4[] = ++ { ++ {"Base Address", 0, 1}, ++ {"Offset (VLYNQ)", 0, 0}, ++ {"Interrupt Line", 0, 0}, ++ {"Debug", 0, 0}, ++ {"Instance", 0, 0}, ++#ifdef _CPHAL_AAL5 ++ {"UniNni", 0, 0} ++#endif ++ }; ++ ++static STATS_DB StatsDb[] = ++ { ++ {(sizeof(StatsTable0)/sizeof(STATS_TABLE)), StatsTable0}, ++ {(sizeof(StatsTable1)/sizeof(STATS_TABLE)), StatsTable1}, ++ {(sizeof(StatsTable2)/sizeof(STATS_TABLE)), StatsTable2}, ++ {(sizeof(StatsTable3)/sizeof(STATS_TABLE)), StatsTable3}, ++ {(sizeof(StatsTable4)/sizeof(STATS_TABLE)), StatsTable4} ++ }; ++#endif /* +GSG 030307 */ ++ ++#ifdef _CPHAL_CPMAC /* +RC 3.02 */ ++static void resetWait(HAL_DEVICE *HalDev) ++ { /*+RC3.02*/ ++ const int TickReset=64; ++ osfuncSleep((int*)&TickReset); ++ } /*+RC3.02*/ ++#endif /* +RC 3.02 */ ++ ++/* I only define the reset base function for the modules ++ that can perform a reset. The AAL5 and AAL2 modules ++ do not perform a reset, that is done by the shared module ++ CPSAR */ ++#if defined(_CPHAL_CPSAR) || defined(_CPHAL_CPMAC) || defined(_CPHAL_VDMAVT) ++/* ++ * Determines the reset register address to be used for a particular device. ++ * It will search the current device entry for Locator information. If the ++ * device is a root device, there will be no Locator information, and the ++ * function will find and return the root reset register. If a Locator value ++ * is found, the function will search each VLYNQ device entry in the system ++ * looking for a matching Locator. Once it finds a VLYNQ device entry with ++ * a matching Locator, it will extract the "ResetBase" parameter from that ++ * VLYNQ device entry (thus every VLYNQ entry must have the ResetBase parameter). ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param ResetBase Pointer to integer address of reset register. ++ * ++ * @return 0 OK, Non-zero not OK ++ */ ++static int ResetBaseGet(HAL_DEVICE *HalDev, bit32u *ResetBase) ++ { ++ char *DeviceInfo = HalDev->DeviceInfo; ++ char *MyLocator, *NextLocator; ++ int Inst=1; ++ bit32u error_code; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]ResetBaseGet(HalDev:%08x, ResetBase:%08x)\n", (bit32u)HalDev, ResetBase); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &MyLocator); ++ if (error_code) ++ { ++ /* if no Locator value, device is on the root, so get the "reset" device */ ++ error_code = HalDev->OsFunc->DeviceFindInfo(0, "reset", &DeviceInfo); ++ if (error_code) ++ { ++ return(EC_VAL_DEVICE_NOT_FOUND); ++ } ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "base", ResetBase); ++ if (error_code) ++ { ++ return(EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ ++ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); ++ ++ /* found base address for root device, so we're done */ ++ return (EC_NO_ERRORS); ++ } ++ else ++ { ++ /* we have a Locator value, so the device is remote */ ++ ++ /* Find a vlynq device with a matching locator value */ ++ while ((HalDev->OsFunc->DeviceFindInfo(Inst, "vlynq", &DeviceInfo)) == EC_NO_ERRORS) ++ { ++ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &NextLocator); ++ if (error_code) ++ { ++ /* no Locator value for this VLYNQ, so move on */ ++ continue; ++ } ++ if (HalDev->OsFunc->Strcmpi(MyLocator, NextLocator)==0) ++ { ++ /* we have found a VLYNQ with a matching Locator, so extract the ResetBase */ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "ResetBase", ResetBase); ++ if (error_code) ++ { ++ return(EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); ++ ++ /* found base address for root device, so we're done */ ++ return (EC_NO_ERRORS); ++ } ++ Inst++; ++ } /* while */ ++ } /* else */ ++ ++ return (EC_NO_ERRORS); ++ } ++#endif ++ ++#ifndef _CPHAL_AAL2 /* + RC 3.02 */ ++static bit32u ConfigGetCommon(HAL_DEVICE *HalDev) ++ { ++ bit32u ParmValue; ++ bit32 error_code; ++ char *DeviceInfo = HalDev->DeviceInfo; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]ConfigGetCommon(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszBase, &ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ HalDev->dev_base = ((bit32u)PhysToVirtNoCache(ParmValue)); ++ ++#ifndef _CPHAL_AAL5 ++#ifndef _CPHAL_AAL2 ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszResetBit, &ParmValue); ++ if(error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BIT_NOT_FOUND); ++ } ++ HalDev->ResetBit = ParmValue; ++ ++ /* Get reset base address */ ++ error_code = ResetBaseGet(HalDev, &ParmValue); ++ if (error_code) ++ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BASE_NOT_FOUND); ++ HalDev->ResetBase = ParmValue; ++#endif ++#endif ++ ++#ifndef _CPHAL_CPSAR ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszIntLine,&ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_INTERRUPT_NOT_FOUND); ++ } ++ HalDev->interrupt = ParmValue; ++#endif ++ ++ /* only look for the offset if there is a Locator field, which indicates that ++ the module is a VLYNQ module */ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszLocator,&ParmValue); ++ if (!error_code) ++ { ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszOffset,&ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_OFFSET_NOT_FOUND); ++ } ++ HalDev->offset = ParmValue; ++ } ++ else ++ HalDev->offset = 0; ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszDebug, &ParmValue); ++ if (!error_code) HalDev->debug = ParmValue; ++ ++ return (EC_NO_ERRORS); ++ } ++#endif /* +RC 3.02 */ ++ ++#ifdef _CPHAL_CPMAC /* +RC 3.02 */ ++static void StatsInit(HAL_DEVICE *HalDev) /* +() RC3.02 */ ++ { ++ /* even though these statistics may be for multiple channels and ++ queues, i need only configure the pointer to the beginning ++ of the array, and I can index from there if necessary */ ++ ++#ifdef _CPHAL_AAL5 ++ StatsTable0[0].StatPtr = &HalDev->Stats.CrcErrors[0]; ++ StatsTable0[1].StatPtr = &HalDev->Stats.LenErrors[0]; ++ StatsTable0[2].StatPtr = &HalDev->Stats.AbortErrors[0]; ++ StatsTable0[3].StatPtr = &HalDev->Stats.StarvErrors[0]; ++ ++ StatsTable1[0].StatPtr = &HalDev->Stats.DmaLenErrors[0]; ++ StatsTable1[1].StatPtr = &HalDev->Stats.TxMisQCnt[0][0]; ++ StatsTable1[2].StatPtr = &HalDev->Stats.RxMisQCnt[0]; ++ StatsTable1[3].StatPtr = &HalDev->Stats.TxEOQCnt[0][0]; ++ StatsTable1[4].StatPtr = &HalDev->Stats.RxEOQCnt[0]; ++ StatsTable1[5].StatPtr = &HalDev->Stats.RxPacketsServiced[0]; ++ StatsTable1[6].StatPtr = &HalDev->Stats.TxPacketsServiced[0][0]; ++ StatsTable1[7].StatPtr = &HalDev->Stats.RxMaxServiced; ++ StatsTable1[8].StatPtr = &HalDev->Stats.TxMaxServiced[0][0]; ++ StatsTable1[9].StatPtr = &HalDev->Stats.RxTotal; ++ StatsTable1[10].StatPtr = &HalDev->Stats.TxTotal; ++#endif ++ ++#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) ++ StatsTable2[0].StatPtr = (bit32u *)&HalDev->RcbPool[0]; ++ StatsTable2[1].StatPtr = &HalDev->RxActQueueCount[0]; ++ StatsTable2[2].StatPtr = (bit32u *)&HalDev->RxActQueueHead[0]; ++ StatsTable2[3].StatPtr = (bit32u *)&HalDev->RxActQueueTail[0]; ++ StatsTable2[4].StatPtr = &HalDev->RxActive[0]; ++ StatsTable2[5].StatPtr = (bit32u *)&HalDev->RcbStart[0]; ++ StatsTable2[6].StatPtr = &HalDev->RxTeardownPending[0]; ++ StatsTable2[7].StatPtr = (bit32u *)&HalDev->TcbPool[0][0]; ++ StatsTable2[8].StatPtr = &HalDev->TxActQueueCount[0][0]; ++ StatsTable2[9].StatPtr = (bit32u *)&HalDev->TxActQueueHead[0][0]; ++ StatsTable2[10].StatPtr = (bit32u *)&HalDev->TxActQueueTail[0][0]; ++ StatsTable2[11].StatPtr = &HalDev->TxActive[0][0]; ++ StatsTable2[12].StatPtr = (bit32u *)&HalDev->TcbStart[0][0]; ++ StatsTable2[13].StatPtr = &HalDev->TxTeardownPending[0]; ++ ++ StatsTable3[0].StatPtr = &HalDev->ChData[0].RxBufSize; ++ StatsTable3[1].StatPtr = &HalDev->ChData[0].RxBufferOffset; ++ StatsTable3[2].StatPtr = &HalDev->ChData[0].RxNumBuffers; ++ StatsTable3[3].StatPtr = &HalDev->ChData[0].RxServiceMax; ++ StatsTable3[4].StatPtr = &HalDev->ChData[0].TxNumBuffers; ++ StatsTable3[5].StatPtr = &HalDev->ChData[0].TxNumQueues; ++ StatsTable3[6].StatPtr = &HalDev->ChData[0].TxServiceMax; ++#ifdef _CPHAL_AAL5 ++ StatsTable3[7].StatPtr = &HalDev->ChData[0].CpcsUU; ++ StatsTable3[8].StatPtr = &HalDev->ChData[0].Gfc; ++ StatsTable3[9].StatPtr = &HalDev->ChData[0].Clp; ++ StatsTable3[10].StatPtr = &HalDev->ChData[0].Pti; ++ StatsTable3[11].StatPtr = &HalDev->ChData[0].DaMask; ++ StatsTable3[12].StatPtr = &HalDev->ChData[0].Priority; ++ StatsTable3[13].StatPtr = &HalDev->ChData[0].PktType; ++ StatsTable3[14].StatPtr = &HalDev->ChData[0].Vci; ++ StatsTable3[15].StatPtr = &HalDev->ChData[0].Vpi; ++ StatsTable3[16].StatPtr = &HalDev->ChData[0].TxVc_CellRate; ++ StatsTable3[17].StatPtr = &HalDev->ChData[0].TxVc_QosType; ++ StatsTable3[18].StatPtr = &HalDev->ChData[0].TxVc_Mbs; ++ StatsTable3[19].StatPtr = &HalDev->ChData[0].TxVc_Pcr; ++#endif ++#endif ++ ++ StatsTable4[0].StatPtr = &HalDev->dev_base; ++ StatsTable4[1].StatPtr = &HalDev->offset; ++ StatsTable4[2].StatPtr = &HalDev->interrupt; ++ StatsTable4[3].StatPtr = &HalDev->debug; ++ StatsTable4[4].StatPtr = &HalDev->Inst; ++ } ++#endif /* +RC 3.02 */ ++ ++#ifndef _CPHAL_CPSAR /* +RC 3.02 */ ++#ifndef _CPHAL_AAL2 /* +RC 3.02 */ ++/* ++ * Returns statistics information. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return 0 ++ */ ++static int StatsGet(HAL_DEVICE *HalDev, void **StatPtr, int Index, int Ch, int Queue) ++ { ++ int Size; ++ bit32u *AddrPtr; ++ char *DataPtr; ++ STATS_TABLE *StatsTable; ++ int i, NumberOfStats; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]StatsGet(HalDev:%08x, StatPtr:%08x)\n", ++ (bit32u)HalDev, (bit32u)StatPtr); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ StatsTable = StatsDb[Index].StatTable; ++ NumberOfStats = StatsDb[Index].NumberOfStats; ++ ++ Size = sizeof(bit32u)*((NumberOfStats*2)+1); ++ Size += (NumberOfStats*11); ++ *StatPtr = (bit32u *)HalDev->OsFunc->Malloc(Size); ++ ++ AddrPtr = (bit32u *) *StatPtr; ++ DataPtr = (char *)AddrPtr; ++ DataPtr += sizeof(bit32u)*((NumberOfStats*2)+1); ++ ++ for (i=0; iOsFunc->Sprintf(DataPtr, "%d", (bit32u *)StatsTable[i].StatPtr[Ch]); ++ break; ++ case 1: ++ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", (bit32u *)StatsTable[i].StatPtr[Ch]); ++ break; ++ case 2: ++ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch * (sizeof(CHANNEL_INFO)/4)))); ++ break; ++ case 3: ++ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); ++ break; ++ case 4: ++ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); ++ break; ++ default: ++ /* invalid data type, due to CPHAL programming error */ ++ break; ++ } ++ } ++ else ++ { ++ /* invalid statistics pointer, probably was not initialized */ ++ } ++ DataPtr += HalDev->OsFunc->Strlen(DataPtr) + 1; ++ } ++ ++ *AddrPtr = (bit32u) 0; ++ ++ return (EC_NO_ERRORS); ++ } ++#endif /* +RC 3.02 */ ++#endif /* +RC 3.02 */ ++ ++#ifdef _CPHAL_CPMAC ++static void gpioFunctional(int base, int bit) ++ { /*+RC3.02*/ ++ bit32u GpioEnr = base + 0xC; ++ /* To make functional, set to zero */ ++ *(volatile bit32u *)(GpioEnr) &= ~(1 << bit); /*+RC3.02*/ ++ } /*+RC3.02*/ ++ ++ ++/*+RC3.02*/ ++/* Common function, Checks to see if GPIO should be in functional mode */ ++static void gpioCheck(HAL_DEVICE *HalDev, void *moduleDeviceInfo) ++ { /*+RC3.02*/ ++ int rc; ++ void *DeviceInfo; ++ char *pszMuxBits; ++ char pszMuxBit[20]; ++ char *pszTmp; ++ char szMuxBit[20]; ++ char *ptr; ++ int base; ++ int reset_bit; ++ int bit; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ ++ rc = OsFunc->DeviceFindParmValue(moduleDeviceInfo, "gpio_mux",&pszTmp); ++ if(rc) return; ++ /* gpio entry found, get GPIO register info and make functional */ ++ ++ /* temp copy until FinParmValue fixed */ ++ ptr = &szMuxBit[0]; ++ while ((*ptr++ = *pszTmp++)); ++ ++ pszMuxBits = &szMuxBit[0]; ++ ++ rc = OsFunc->DeviceFindInfo(0,"gpio",&DeviceInfo); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",&base); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit); ++ if(rc) return; ++ ++ /* If GPIO still in reset, then exit */ ++ if((VOLATILE32(HalDev->ResetBase) & (1 << reset_bit)) == 0) ++ return; ++ /* format for gpio_mux is gpio_mux = ;;...*/ ++ while (*pszMuxBits) ++ { ++ pszTmp = &pszMuxBit[0]; ++ if(*pszMuxBits == ';') pszMuxBits++; ++ while ((*pszMuxBits != ';') && (*pszMuxBits != '\0')) ++ { ++ osfuncSioFlush(); ++ /*If value not a number, skip */ ++ if((*pszMuxBits < '0') || (*pszMuxBits > '9')) ++ pszMuxBits++; ++ else ++ *pszTmp++ = *pszMuxBits++; ++ } ++ *pszTmp = '\0'; ++ bit = OsFunc->Strtoul(pszMuxBit, &pszTmp, 10); ++ gpioFunctional(base, bit); ++ resetWait(HalDev); /* not sure if this is needed */ ++ } ++ } /*+RC3.02*/ ++#endif /* CPMAC */ ++ ++#ifdef _CPHAL_AAL5 ++const char hcSarFrequency[] = "SarFreq"; ++#endif ++ ++#endif /* _INC */ +diff -urN linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.h +--- linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.h 2005-07-12 02:48:41.996601000 +0200 +@@ -0,0 +1,79 @@ ++#ifndef _INC_CPCOMMON_H ++#define _INC_CPCOMMON_H ++ ++#define VOLATILE32(addr) (*(volatile bit32u *)(addr)) ++#ifndef dbgPrintf ++#define dbgPrintf HalDev->OsFunc->Printf ++#endif ++ ++#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field ++ ++#define DBG(level) (HalDev->debug & (1<<(level))) ++/* ++#define DBG0() DBG(0) ++#define DBG1() DBG(1) ++#define DBG2() DBG(2) ++#define DBG3() DBG(3) ++#define DBG4() DBG(4) ++#define DBG5() DBG(5) ++#define DBG6() DBG(6) ++#define DBG7() DBG(7) ++*/ ++ ++/* ++ * List of defined actions for use with Control(). ++ */ ++typedef enum ++ { ++ enGET=0, /**< Get the value associated with a key */ ++ enSET, /**< Set the value associates with a key */ ++ enCLEAR, /**OsFunc->Control(HalDev->OsDev,"SioFlush",pszNULL,0) ++#define osfuncSleep(Ticks) HalDev->OsFunc->Control(HalDev->OsDev,pszSleep,pszNULL,Ticks) ++#define osfuncStateChange() HalDev->OsFunc->Control(HalDev->OsDev,pszStateChange,pszNULL,0) ++ ++#define CHANNEL_NAMES {"Ch0","Ch1","Ch2","Ch3","Ch4","Ch5","Ch6","Ch7","Ch8","Ch9","Ch10","Ch11","Ch12","Ch13","Ch14","Ch15"} ++ ++#endif ++ +diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpmac.c +--- linux.old/drivers/net/avalanche_cpmac/cpmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpmac.c 2005-07-22 01:03:12.609318544 +0200 +@@ -0,0 +1,2504 @@ ++/****************************************************************************** ++ * FILE PURPOSE: CPMAC Linux Network Device Driver Source ++ ****************************************************************************** ++ * FILE NAME: cpmac.c ++ * ++ * DESCRIPTION: CPMAC Network Device Driver Source ++ * ++ * REVISION HISTORY: ++ * ++ * Date Description Author ++ *----------------------------------------------------------------------------- ++ * 27 Nov 2002 Initial Creation Suraj S Iyer ++ * 09 Jun 2003 Updates for GA Suraj S Iyer ++ * 30 Sep 2003 Updates for LED, Reset stats Suraj S Iyer ++ * ++ * (C) Copyright 2003, Texas Instruments, Inc ++ *******************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++extern void build_psp_config(void); ++extern void psp_config_cleanup(void); ++ ++#include "cpmacHalLx.h" ++#include "cpmac.h" ++ ++static struct net_device *last_cpmac_device = NULL; ++static int cpmac_devices_installed = 0; ++ ++void xdump( u_char* cp, int length, char* prefix ); ++ ++unsigned int cpmac_cpu_freq = 0; ++ ++char cpmac_version[] = "1.5"; ++ ++char l3_align_array[] = {0x02, 0x01, 0x00, 0x03}; ++#define L3_ALIGN(i) l3_align_array[i] ++ ++char add_for_4byte_align[] = {0x04, 0x03, 0x02, 0x05}; ++#define ADD_FOR_4BYTE_ALIGN(i) add_for_4byte_align[i] ++ ++ ++#define TPID 0x8100 ++#define IS_802_1Q_FRAME(byte_ptr) (*(unsigned short*)byte_ptr == TPID) ++#define TPID_START_OFFSET 12 ++#define TCI_START_OFFSET 14 ++#define TCI_LENGTH 2 ++#define TPID_LENGTH 2 ++#define TPID_END_OFFSET (TPID_START_OFFSET + TPID_LENGTH) ++#define TCI_END_OFFSET (TCI_START_OFFSET + TCI_LENGTH) ++#define IS_VALID_VLAN_ID(byte_ptr) ((*(unsigned short*)byte_ptr) && 0xfff != 0) ++#define MAX_CLASSES 8 ++#define MAX_USER_PRIORITY 8 ++#define CONTROL_802_1Q_SIZE (TCI_LENGTH + TPID_LENGTH) ++ ++unsigned char user_priority_to_traffic_class_map[MAX_CLASSES][MAX_USER_PRIORITY] = ++{ ++ {0, 0, 0, 1, 1, 1, 1, 2}, ++ {0, 0, 0, 0, 0, 0, 0, 0}, ++ {0, 0, 0, 0, 0, 0, 0, 1}, ++ {0, 0, 0, 1, 1, 2, 2, 3}, ++ {0, 1, 1, 2, 2, 3, 3, 4}, ++ {0, 1, 1, 2, 3, 4, 4, 5}, ++ {0, 1, 2, 3, 4, 5, 5, 6}, ++ {0, 1, 2, 3, 4, 5, 6, 7} ++}; ++ ++#define GET_802_1P_CHAN(x,y) user_priority_to_traffic_class_map[x][(y & 0xe0)] ++ ++#if defined(CONFIG_MIPS_SEAD2) ++unsigned long temp_base_address[2] = {0xa8610000, 0xa8612800}; ++unsigned long temp_reset_value[2] = { 1<< 17,1<<21}; ++#define RESET_REG_PRCR (*(volatile unsigned int *)((0xa8611600 + 0x0))) ++#define VERSION(base) (*(volatile unsigned int *)(((base)|0xa0000000) + 0x0)) ++#endif ++ ++MODULE_AUTHOR("Maintainer: Suraj S Iyer "); ++MODULE_DESCRIPTION("Driver for TI CPMAC"); ++ ++static int cfg_link_speed = 0; ++MODULE_PARM(cfg_link_speed, "i"); ++MODULE_PARM_DESC(cfg_link_speed, "Fixed speed of the Link: <100/10>"); ++ ++static char *cfg_link_mode = NULL; ++MODULE_PARM(cfg_link_mode, "1-3s"); ++MODULE_PARM_DESC(cfg_link_mode, "Fixed mode of the Link: "); ++ ++int cpmac_debug_mode = 0; ++MODULE_PARM(debug_mode, "i"); ++MODULE_PARM_DESC(debug_mode, "Turn on the debug info: <0/1>. Default is 0 (off)"); ++ ++#define dbgPrint if (cpmac_debug_mode) printk ++#define errPrint printk ++ ++static int g_cfg_start_link_params = CFG_START_LINK_SPEED; ++static int g_init_enable_flag = 0; ++static int cfg_start_link_speed; ++static int cpmac_max_frame_size; ++ ++static struct net_device *g_dev_array[2]; ++static struct proc_dir_entry *gp_stats_file = NULL; ++ ++//----------------------------------------------------------------------------- ++// Statistics related private functions. ++//----------------------------------------------------------------------------- ++static int cpmac_p_update_statistics(struct net_device *p_dev, char *buf, int limit, int *len); ++static int cpmac_p_read_rfc2665_stats(char *buf, char **start, off_t offset, int count, int *eof, void *data); ++static int cpmac_p_read_link(char *buf, char **start, off_t offset, int count, int *eof, void *data); ++static int cpmac_p_read_stats(char* buf, char **start, off_t offset, int count, int *eof, void *data); ++static int cpmac_p_write_stats (struct file *fp, const char * buf, unsigned long count, void * data); ++static int cpmac_p_reset_statistics (struct net_device *p_dev); ++static int cpmac_p_get_version(char *buf, char **start, off_t offset, int count, int *eof, void *data); ++ ++static int cpmac_p_detect_manual_cfg(int, char*, int); ++static int cpmac_p_process_status_ind(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); ++ ++//----------------------------------------------------------------------------- ++// Timer related private functions. ++//----------------------------------------------------------------------------- ++static int cpmac_p_timer_init(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); ++// static int cpmac_timer_cleanup(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); ++static void cpmac_p_tick_timer_expiry(unsigned long p_cb_param); ++inline static int cpmac_p_start_timer(struct timer_list *p_timer, unsigned int delay_ticks); ++static int cpmac_p_stop_timer(struct timer_list *p_timer); ++ ++//------------------------------------------------------------------------------ ++// Device configuration and setup related private functions. ++//------------------------------------------------------------------------------ ++static int cpmac_p_probe_and_setup_device(CPMAC_PRIVATE_INFO_T *p_cpmac_priv, unsigned long *p_dev_flags); ++static int cpmac_p_setup_driver_params(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); ++inline static int cpmac_p_rx_buf_setup(CPMAC_RX_CHAN_INFO_T *p_rx_chan); ++ ++//----------------------------------------------------------------------------- ++// Net device related private functions. ++//----------------------------------------------------------------------------- ++static int cpmac_dev_init(struct net_device *p_dev); ++static int cpmac_dev_open( struct net_device *dev ); ++static int cpmac_dev_close(struct net_device *p_dev); ++static void cpmac_dev_mcast_set(struct net_device *p_dev); ++static int cpmac_dev_set_mac_addr(struct net_device *p_dev,void * addr); ++static int cpmac_dev_tx( struct sk_buff *skb, struct net_device *p_dev); ++static struct net_device_stats *cpmac_dev_get_net_stats (struct net_device *dev); ++ ++static int cpmac_p_dev_enable( struct net_device *p_dev); ++ ++ ++ ++/* Max. Reserved headroom in front of each packet so that the headers can be added to ++ * a packet. Worst case scenario would be PPPoE + 2684 LLC Encapsulation + Ethernet ++ * header. */ ++#define MAX_RESERVED_HEADROOM 20 ++ ++/* This is the MAX size of the static buffer for pure data. */ ++#define MAX_SIZE_STATIC_BUFFER 1600 ++ ++typedef struct DRIVER_BUFFER ++{ ++ /* Pointer to the allocated data buffer. This is the static data buffer ++ * allocated for the TI-Cache. 60 bytes out of the below buffer are required ++ * by the SKB shared info. We always reserve at least MAX_RESERVED_HEADROOM bytes ++ * so that the packets always have sufficient headroom. */ ++ char ptr_buffer[MAX_SIZE_STATIC_BUFFER + MAX_RESERVED_HEADROOM + 60]; ++ ++ /* List of the driver buffers. */ ++ struct DRIVER_BUFFER* ptr_next; ++}DRIVER_BUFFER; ++ ++typedef struct DRIVER_BUFFER_MCB ++{ ++ /* List of the driver buffers. */ ++ DRIVER_BUFFER* ptr_available_driver_buffers; ++ ++ /* The number of available buffers. */ ++ int num_available_buffers; ++}DRIVER_BUFFER_MCB; ++ ++DRIVER_BUFFER_MCB driver_mcb; ++int hybrid_mode = 0; ++ ++static union { ++ struct sk_buff_head list; ++ char pad[SMP_CACHE_BYTES]; ++} skb_head_pool[NR_CPUS]; ++ ++/************************************************************************** ++ * FUNCTION NAME : ti_release_skb ++ ************************************************************************** ++ * DESCRIPTION : ++ * This function is called from the ti_alloc_skb when there were no more ++ * data buffers available. The allocated SKB had to released back to the ++ * data pool. The reason why this function was moved from the fast path ++ * below was because '__skb_queue_head' is an inline function which adds ++ * a large code chunk on the fast path. ++ * ++ * NOTES : ++ * This function is called with interrupts disabled. ++ **************************************************************************/ ++static void ti_release_skb (struct sk_buff_head* list, struct sk_buff* skb) ++{ ++ __skb_queue_head(list, skb); ++ return; ++} ++ ++/************************************************************************** ++ * FUNCTION NAME : ti_alloc_skb ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function is called to allocate memory from the static allocated ++ * TI-Cached memory pool. ++ * ++ * RETURNS : ++ * Allocated static memory buffer - Success ++ * NULL - Error. ++ **************************************************************************/ ++struct sk_buff *ti_alloc_skb(unsigned int size,int gfp_mask) ++{ ++ register struct sk_buff* skb; ++ unsigned long flags; ++ struct sk_buff_head* list; ++ DRIVER_BUFFER* ptr_node = NULL; ++ ++ /* Critical Section Begin: Lock out interrupts. */ ++ local_irq_save(flags); ++ ++ /* Get the SKB Pool list associated with the processor and dequeue the head. */ ++ list = &skb_head_pool[smp_processor_id()].list; ++ skb = __skb_dequeue(list); ++ ++ /* Align the data size. */ ++ size = SKB_DATA_ALIGN(size); ++ ++ /* Did we get one. */ ++ if (skb != NULL) ++ { ++ /* YES. Now get a data block from the head of statically allocated block. */ ++ ptr_node = driver_mcb.ptr_available_driver_buffers; ++ if (ptr_node != NULL) ++ { ++ /* YES. Got a data block. Advance the free list pointer to the next available buffer. */ ++ driver_mcb.ptr_available_driver_buffers = ptr_node->ptr_next; ++ ptr_node->ptr_next = NULL; ++ ++ /* Decrement the number of available data buffers. */ ++ driver_mcb.num_available_buffers = driver_mcb.num_available_buffers - 1; ++ } ++ else ++ { ++ /* NO. Was unable to get a data block. So put the SKB back on the free list. ++ * This is slow path. */ ++#ifdef DEBUG_SKB ++ printk ("DEBUG: No Buffer memory available: Number of free buffer:%d.\n", ++ driver_mcb.num_available_buffers); ++#endif ++ ti_release_skb (list, skb); ++ } ++ } ++ ++ /* Critical Section End: Unlock interrupts. */ ++ local_irq_restore(flags); ++ ++ /* Did we get an SKB and data buffer. Proceed only if we were succesful in getting both else drop */ ++ if (skb != NULL && ptr_node != NULL) ++ { ++ /* XXX: does not include slab overhead */ ++ skb->truesize = size + sizeof(struct sk_buff); ++ ++ /* Load the data pointers. */ ++ skb->head = ptr_node->ptr_buffer; ++ skb->data = ptr_node->ptr_buffer + MAX_RESERVED_HEADROOM; ++ skb->tail = ptr_node->ptr_buffer + MAX_RESERVED_HEADROOM; ++ skb->end = ptr_node->ptr_buffer + size + MAX_RESERVED_HEADROOM; ++ ++ /* Set up other state */ ++ skb->len = 0; ++ skb->cloned = 0; ++ skb->data_len = 0; ++ ++ /* Mark the SKB indicating that the SKB is from the TI cache. */ ++ skb->cb[45] = 1; ++ ++ atomic_set(&skb->users, 1); ++ atomic_set(&(skb_shinfo(skb)->dataref), 1); ++ skb_shinfo(skb)->nr_frags = 0; ++ skb_shinfo(skb)->frag_list = NULL; ++ return skb; ++ } ++ else ++ { ++ /* Control comes here only when there is no statically allocated data buffers ++ * available. This case is handled using the mode selected ++ * ++ * 1. Hybrid Mode. ++ * In that case lets jump to the old allocation code. This way we ++ * can allocate a small number of data buffers upfront and the rest will hit ++ * this portion of the code, which is slow path. Note the number of hits here ++ * should be kept as low as possible to satisfy performance requirements. ++ * ++ * 2. Pure Static Mode. ++ * Return NULL the user should have tuned the number of static buffers for ++ * worst case scenario. So return NULL and let the drivers handle the error. */ ++ if (hybrid_mode == 1) ++ { ++ /* Hybrid Mode: Old allocation. */ ++ return dev_alloc_skb(size); ++ } ++ else ++ { ++ /* Pure Static Mode: No buffers available. */ ++ return NULL; ++ } ++ } ++} ++ ++/************************************************************************** ++ * FUNCTION NAME : ti_skb_release_fragment ++ ************************************************************************** ++ * DESCRIPTION : ++ * This function is called to release fragmented packets. This is NOT in ++ * the fast path and this function requires some work. ++ **************************************************************************/ ++static void ti_skb_release_fragment(struct sk_buff *skb) ++{ ++ if (skb_shinfo(skb)->nr_frags) ++ { ++ /* PANKAJ TODO: This portion has not been tested. */ ++ int i; ++#ifdef DEBUG_SKB ++ printk ("DEBUG: Releasing fragments in TI-Cached code.\n"); ++#endif ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) ++ printk ("DEBUG: Fragmented Page = 0x%p.\n", skb_shinfo(skb)->frags[i].page); ++ } ++ ++ /* Check if there were any fragments present and if so clean all the SKB's. ++ * This is required to recursivly clean the SKB's. */ ++ if (skb_shinfo(skb)->frag_list) ++ skb_drop_fraglist(skb); ++ ++ return; ++} ++ ++/************************************************************************** ++ * FUNCTION NAME : ti_skb_release_data ++ ************************************************************************** ++ * DESCRIPTION : ++ * The function is called to release the SKB back into the TI-Cached static ++ * memory pool. ++ **************************************************************************/ ++static void ti_skb_release_data(struct sk_buff *skb) ++{ ++ DRIVER_BUFFER* ptr_node; ++ unsigned long flags; ++ ++ /* The SKB data can be cleaned only if the packet has not been cloned and we ++ * are the only one holding a reference to the data. */ ++ if (!skb->cloned || atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) ++ { ++ /* Are there any fragments associated with the SKB ?*/ ++ if ((skb_shinfo(skb)->nr_frags != 0) || (skb_shinfo(skb)->frag_list != NULL)) ++ { ++ /* Slow Path: Try and clean up the fragments. */ ++ ti_skb_release_fragment (skb); ++ } ++ ++ /* Cleanup the SKB data memory. This is fast path. */ ++ ptr_node = (DRIVER_BUFFER *)skb->head; ++ ++ /* Critical Section: Lock out interrupts. */ ++ local_irq_save(flags); ++ ++ /* Add the data buffer to the list of available buffers. */ ++ ptr_node->ptr_next = driver_mcb.ptr_available_driver_buffers; ++ driver_mcb.ptr_available_driver_buffers = ptr_node; ++ ++ /* Increment the number of available data buffers. */ ++ driver_mcb.num_available_buffers = driver_mcb.num_available_buffers + 1; ++ ++ /* Criticial Section: Unlock interrupts. */ ++ local_irq_restore(flags); ++ } ++ return; ++} ++ ++ ++ ++ ++static unsigned char str2hexnum(unsigned char c) ++{ ++ if(c >= '0' && c <= '9') ++ return c - '0'; ++ if(c >= 'a' && c <= 'f') ++ return c - 'a' + 10; ++ if(c >= 'A' && c <= 'F') ++ return c - 'A' + 10; ++ return 0; ++} ++ ++static void str2eaddr(unsigned char *ea, unsigned char *str) ++{ ++ int i; ++ unsigned char num; ++ for(i = 0; i < 6; i++) { ++ if((*str == '.') || (*str == ':')) ++ str++; ++ num = str2hexnum(*str++) << 4; ++ num |= (str2hexnum(*str++)); ++ ea[i] = num; ++ } ++} ++ ++//----------------------------------------------------------------------------- ++// Statistics related private functions. ++//----------------------------------------------------------------------------- ++static int cpmac_p_update_statistics(struct net_device *p_dev, char *buf, int limit, int *p_len) ++{ ++ int ret_val = -1; ++ unsigned long rx_hal_errors = 0; ++ unsigned long rx_hal_discards = 0; ++ unsigned long tx_hal_errors = 0; ++ unsigned long ifOutDiscards = 0; ++ unsigned long ifInDiscards = 0; ++ unsigned long ifOutErrors = 0; ++ unsigned long ifInErrors = 0; ++ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ CPMAC_DEVICE_MIB_T *p_device_mib = p_cpmac_priv->device_mib; ++ CPMAC_DRV_STATS_T *p_stats = p_cpmac_priv->stats; ++ CPMAC_DEVICE_MIB_T local_mib; ++ CPMAC_DEVICE_MIB_T *p_local_mib = &local_mib; ++ ++ struct net_device_stats *p_net_dev_stats = &p_cpmac_priv->net_dev_stats; ++ ++ int len = 0; ++ int dev_mib_elem_count = 0; ++ ++ /* do not access the hardware if it is in the reset state. */ ++ if(!test_bit(0, &p_cpmac_priv->set_to_close)) ++ { ++ if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsDump", "Get", ++ p_local_mib) != 0) ++ { ++ errPrint("The stats dump for %s is failing.\n", p_dev->name); ++ return(ret_val); ++ } ++ ++ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsClear", "Set", NULL); ++ ++ dev_mib_elem_count = sizeof(CPMAC_DEVICE_MIB_T)/sizeof(unsigned long); ++ ++ /* Update the history of the stats. This takes care of any reset of the ++ * device and stats that might have taken place during the life time of ++ * the driver. ++ */ ++ while(dev_mib_elem_count--) ++ { ++ *((unsigned long*) p_device_mib + dev_mib_elem_count) += ++ *((unsigned long*) p_local_mib + dev_mib_elem_count); ++ } ++ } ++ ++ /* RFC2665, section 3.2.7, page 9 */ ++ rx_hal_errors = p_device_mib->ifInFragments + ++ p_device_mib->ifInCRCErrors + ++ p_device_mib->ifInAlignCodeErrors + ++ p_device_mib->ifInJabberFrames; ++ ++ /* RFC2233 */ ++ rx_hal_discards = p_device_mib->ifRxDMAOverruns; ++ ++ /* RFC2665, section 3.2.7, page 9 */ ++ tx_hal_errors = p_device_mib->ifExcessiveCollisionFrames + ++ p_device_mib->ifLateCollisions + ++ p_device_mib->ifCarrierSenseErrors + ++ p_device_mib->ifOutUnderrun; ++ ++ /* if not set, the short frames (< 64 bytes) are considered as errors */ ++ if(!p_cpmac_priv->flags & IFF_PRIV_SHORT_FRAMES) ++ rx_hal_errors += p_device_mib->ifInUndersizedFrames; ++ ++ /* if not set, the long frames ( > 1518) are considered as errors ++ * RFC2665, section 3.2.7, page 9. */ ++ if(!p_cpmac_priv->flags & IFF_PRIV_JUMBO_FRAMES) ++ rx_hal_errors += p_device_mib->ifInOversizedFrames; ++ ++ /* if not in promiscous, then non addr matching frames are discarded */ ++ /* CPMAC 2.0 Manual Section 2.8.1.14 */ ++ if(!p_dev->flags & IFF_PROMISC) ++ { ++ ifInDiscards += p_device_mib->ifInFilteredFrames; ++ } ++ ++ /* total rx discards = hal discards + driver discards. */ ++ ifInDiscards = rx_hal_discards + p_net_dev_stats->rx_dropped; ++ ifInErrors = rx_hal_errors; ++ ++ ifOutErrors = tx_hal_errors; ++ ifOutDiscards = p_net_dev_stats->tx_dropped; ++ ++ /* Let us update the net device stats struct. To be updated in the later releases.*/ ++ p_cpmac_priv->net_dev_stats.rx_errors = ifInErrors; ++ p_cpmac_priv->net_dev_stats.collisions = p_device_mib->ifCollisionFrames; ++ ++ if(buf == NULL || limit == 0) ++ { ++ return(0); ++ } ++ ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %ld\n", "ifSpeed", (long)p_cpmac_priv->link_speed); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "dot3StatsDuplexStatus", (long)p_cpmac_priv->link_mode); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifAdminStatus", (long)(p_dev->flags & IFF_UP ? 1:2)); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOperStatus", (long)(((p_dev->flags & IFF_UP) && netif_carrier_ok(p_dev)) ? 1:2)); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifLastChange", p_stats->start_tick); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInDiscards", ifInDiscards); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInErrors", ifInErrors); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutDiscards", ifOutDiscards); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutErrors", ifOutErrors); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInGoodFrames", p_device_mib->ifInGoodFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInBroadcasts", p_device_mib->ifInBroadcasts); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInMulticasts", p_device_mib->ifInMulticasts); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInPauseFrames", p_device_mib->ifInPauseFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInCRCErrors", p_device_mib->ifInCRCErrors); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInAlignCodeErrors", p_device_mib->ifInAlignCodeErrors); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInOversizedFrames", p_device_mib->ifInOversizedFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInJabberFrames", p_device_mib->ifInJabberFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInUndersizedFrames", p_device_mib->ifInUndersizedFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInFragments", p_device_mib->ifInFragments); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInFilteredFrames", p_device_mib->ifInFilteredFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInQosFilteredFrames", p_device_mib->ifInQosFilteredFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInOctets", p_device_mib->ifInOctets); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutGoodFrames", p_device_mib->ifOutGoodFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutBroadcasts", p_device_mib->ifOutBroadcasts); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutMulticasts", p_device_mib->ifOutMulticasts); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutPauseFrames", p_device_mib->ifOutPauseFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifDeferredTransmissions", p_device_mib->ifDeferredTransmissions); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifCollisionFrames", p_device_mib->ifCollisionFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifSingleCollisionFrames", p_device_mib->ifSingleCollisionFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifMultipleCollisionFrames", p_device_mib->ifMultipleCollisionFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifExcessiveCollisionFrames", p_device_mib->ifExcessiveCollisionFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifLateCollisions", p_device_mib->ifLateCollisions); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutUnderrun", p_device_mib->ifOutUnderrun); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifCarrierSenseErrors", p_device_mib->ifCarrierSenseErrors); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutOctets", p_device_mib->ifOutOctets); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "if64OctetFrames", p_device_mib->if64OctetFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "if65To127POctetFrames", p_device_mib->if65To127OctetFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "if128To255OctetFrames", p_device_mib->if128To255OctetFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "if256To511OctetFrames", p_device_mib->if256To511OctetFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "if512To1023OctetFrames", p_device_mib->if512To1023OctetFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "if1024ToUpOctetFrames", p_device_mib->if1024ToUPOctetFrames); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifNetOctets", p_device_mib->ifNetOctets); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxSofOverruns", p_device_mib->ifRxSofOverruns); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxMofOverruns", p_device_mib->ifRxMofOverruns); ++ if(len <= limit) ++ len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxDMAOverruns", p_device_mib->ifRxDMAOverruns); ++ ++ *p_len = len; ++ ++ return(0); ++} ++ ++ ++static int cpmac_p_read_rfc2665_stats(char* buf, char **start, off_t offset, ++ int count, int *eof, void *data) ++{ ++ int limit = count - 80; ++ int len = 0; ++ struct net_device *p_dev = (struct net_device*)data; ++ ++ cpmac_p_update_statistics(p_dev, buf, limit, &len); ++ ++ *eof = 1; ++ ++ return len; ++} ++ ++static int cpmac_p_read_link(char *buf, char **start, off_t offset, int count, ++ int *eof, void *data) ++{ ++ int len = 0; ++ ++ struct net_device *p_dev; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; ++ struct net_device *cpmac_dev_list[cpmac_devices_installed]; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal; ++ ++ int i; ++ int phy; /* what phy are we using? */ ++ ++ len += sprintf(buf+len, "CPMAC devices = %d\n",cpmac_devices_installed); ++ ++ p_dev = last_cpmac_device; ++ ++ /* Reverse the the device link list to list eth0,eth1...in correct order */ ++ for(i=0; i< cpmac_devices_installed; i++) ++ { ++ cpmac_dev_list[cpmac_devices_installed -(i+1)] = p_dev; ++ p_cpmac_priv = p_dev->priv; ++ p_dev = p_cpmac_priv->next_device; ++ } ++ ++ for(i=0; i< cpmac_devices_installed; i++) ++ { ++ p_dev = cpmac_dev_list[i]; ++ p_cpmac_priv = p_dev->priv; ++ p_drv_hal = p_cpmac_priv->drv_hal; ++ ++ /* This prints them out from high to low because of how the devices are linked */ ++ if(netif_carrier_ok(p_dev)) ++ { ++ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "PhyNum", "Get", &phy); ++ ++ ++ len += sprintf(buf+len,"eth%d: Link State: %s Phy:0x%x, Speed = %s, Duplex = %s\n", ++ p_cpmac_priv->instance_num, "UP", phy, ++ (p_cpmac_priv->link_speed == 100000000) ? "100":"10", ++ (p_cpmac_priv->link_mode == 2) ? "Half":"Full"); ++ ++ } ++ else ++ len += sprintf(buf+len,"eth%d: Link State: DOWN\n",p_cpmac_priv->instance_num); ++ ++ p_dev = p_cpmac_priv->next_device; ++ } ++ ++ return len; ++ ++} ++ ++static int cpmac_p_read_stats(char* buf, char **start, off_t offset, int count, ++ int *eof, void *data) ++{ ++ struct net_device *p_dev = last_cpmac_device; ++ int len = 0; ++ int limit = count - 80; ++ int i; ++ struct net_device *cpmac_dev_list[cpmac_devices_installed]; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; ++ CPMAC_DEVICE_MIB_T *p_device_mib; ++ ++ /* Reverse the the device link list to list eth0,eth1...in correct order */ ++ for(i=0; i< cpmac_devices_installed; i++) ++ { ++ cpmac_dev_list[cpmac_devices_installed - (i+1)] = p_dev; ++ p_cpmac_priv = p_dev->priv; ++ p_dev = p_cpmac_priv->next_device; ++ } ++ ++ for(i=0; i< cpmac_devices_installed; i++) ++ { ++ p_dev = cpmac_dev_list[i]; ++ ++ if(!p_dev) ++ goto proc_error; ++ ++ /* Get Stats */ ++ cpmac_p_update_statistics(p_dev, NULL, 0, NULL); ++ ++ p_cpmac_priv = p_dev->priv; ++ p_device_mib = p_cpmac_priv->device_mib; ++ ++ /* Transmit stats */ ++ if(len<=limit) ++ len+= sprintf(buf+len, "\nCpmac %d, Address %lx\n",i+1, p_dev->base_addr); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Transmit Stats\n"); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Tx Valid Bytes Sent :%lu\n",p_device_mib->ifOutOctets); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Tx Frames (Hardware) :%lu\n",p_device_mib->ifOutGoodFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Tx Frames (Software) :%lu\n",p_cpmac_priv->net_dev_stats.tx_packets); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Tx Broadcast Frames :%lu\n",p_device_mib->ifOutBroadcasts); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Tx Multicast Frames :%lu\n",p_device_mib->ifOutMulticasts); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Pause Frames Sent :%lu\n",p_device_mib->ifOutPauseFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Collisions :%lu\n",p_device_mib->ifCollisionFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Tx Error Frames :%lu\n",p_cpmac_priv->net_dev_stats.tx_errors); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Carrier Sense Errors :%lu\n",p_device_mib->ifCarrierSenseErrors); ++ if(len<=limit) ++ len+= sprintf(buf+len, "\n"); ++ ++ ++ /* Receive Stats */ ++ if(len<=limit) ++ len+= sprintf(buf+len, "\nCpmac %d, Address %lx\n",i+1,p_dev->base_addr); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Receive Stats\n"); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx Valid Bytes Received :%lu\n",p_device_mib->ifInOctets); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Rx Frames (Hardware) :%lu\n",p_device_mib->ifInGoodFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Rx Frames (Software) :%lu\n",p_cpmac_priv->net_dev_stats.rx_packets); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Rx Broadcast Frames :%lu\n",p_device_mib->ifInBroadcasts); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Good Rx Multicast Frames :%lu\n",p_device_mib->ifInMulticasts); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Pause Frames Received :%lu\n",p_device_mib->ifInPauseFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx CRC Errors :%lu\n",p_device_mib->ifInCRCErrors); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx Align/Code Errors :%lu\n",p_device_mib->ifInAlignCodeErrors); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx Jabbers :%lu\n",p_device_mib->ifInOversizedFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx Filtered Frames :%lu\n",p_device_mib->ifInFilteredFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx Fragments :%lu\n",p_device_mib->ifInFragments); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx Undersized Frames :%lu\n",p_device_mib->ifInUndersizedFrames); ++ if(len<=limit) ++ len+= sprintf(buf+len, " Rx Overruns :%lu\n",p_device_mib->ifRxDMAOverruns); ++ } ++ ++ ++ return len; ++ ++ proc_error: ++ *eof=1; ++ return len; ++} ++ ++static int cpmac_p_write_stats (struct file *fp, const char * buf, unsigned long count, void * data) ++{ ++ char local_buf[31]; ++ int ret_val = 0; ++ ++ if(count > 30) ++ { ++ printk("Error : Buffer Overflow\n"); ++ printk("Use \"echo 0 > cpmac_stat\" to reset the statistics\n"); ++ return -EFAULT; ++ } ++ ++ copy_from_user(local_buf,buf,count); ++ local_buf[count-1]='\0'; /* Ignoring last \n char */ ++ ret_val = count; ++ ++ if(strcmp("0",local_buf)==0) ++ { ++ struct net_device *p_dev = last_cpmac_device; ++ int i; ++ struct net_device *cpmac_dev_list[cpmac_devices_installed]; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; ++ ++ /* Valid command */ ++ printk("Resetting statistics for CPMAC interface.\n"); ++ ++ /* Reverse the the device link list to list eth0,eth1...in correct order */ ++ for(i=0; i< cpmac_devices_installed; i++) ++ { ++ cpmac_dev_list[cpmac_devices_installed - (i+1)] = p_dev; ++ p_cpmac_priv = p_dev->priv; ++ p_dev = p_cpmac_priv->next_device; ++ } ++ ++ for(i=0; i< cpmac_devices_installed; i++) ++ { ++ p_dev = cpmac_dev_list[i]; ++ if(!p_dev) ++ { ++ ret_val = -EFAULT; ++ break; ++ } ++ ++ cpmac_p_reset_statistics(p_dev); ++ } ++ } ++ else ++ { ++ printk("Error: Unknown operation on cpmac statistics\n"); ++ printk("Use \"echo 0 > cpmac_stats\" to reset the statistics\n"); ++ return -EFAULT; ++ } ++ ++ return ret_val; ++} ++ ++static int cpmac_p_reset_statistics(struct net_device *p_dev) ++{ ++ int ret_val = 0; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ ++ memset(p_cpmac_priv->device_mib, 0, sizeof(CPMAC_DEVICE_MIB_T)); ++ memset(p_cpmac_priv->stats, 0, sizeof(CPMAC_DRV_STATS_T)); ++ memset(&p_cpmac_priv->net_dev_stats, 0, sizeof(struct net_device_stats)); ++ ++ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsClear", "Set", NULL); ++ ++ return(ret_val); ++} ++ ++static int cpmac_p_get_version(char* buf, char **start, off_t offset, int count,int *eof, void *data) ++{ ++ int len = 0; ++ int limit = count - 80; ++ char *hal_version = NULL; ++ struct net_device *p_dev = last_cpmac_device; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ ++ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "Version", "Get", &hal_version); ++ ++ len += sprintf(buf+len, "Texas Instruments CPMAC driver version: %s\n", cpmac_version); ++ ++ if(len <= limit && hal_version) ++ len += sprintf(buf+len, "Texas Instruments CPMAC HAL version: %s\n", hal_version); ++ ++ return len; ++} ++ ++static struct net_device_stats *cpmac_dev_get_net_stats (struct net_device *p_dev) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = (CPMAC_PRIVATE_INFO_T *) p_dev->priv; ++ ++ cpmac_p_update_statistics(p_dev, NULL, 0, NULL); ++ ++ return &p_cpmac_priv->net_dev_stats; ++} ++ ++static int cpmac_p_detect_manual_cfg(int link_speed, char* link_mode, int debug) ++{ ++ char *pSpeed = NULL; ++ ++ if(debug == 1) ++ { ++ cpmac_debug_mode = 1; ++ dbgPrint("Enabled the debug print.\n"); ++ } ++ ++ if(!link_speed && !link_mode) ++ { ++ dbgPrint("No manual link params, defaulting to auto negotiation.\n"); ++ return (0); ++ } ++ ++ if(!link_speed || (link_speed != 10 && link_speed != 100)) ++ { ++ dbgPrint("Invalid or No value of link speed specified, defaulting to auto speed.\n"); ++ pSpeed = "auto"; ++ } ++ else if(link_speed == 10) ++ { ++ g_cfg_start_link_params &= ~(_CPMDIO_100); ++ pSpeed = "10 Mbps"; ++ } ++ else ++ { ++ g_cfg_start_link_params &= ~(_CPMDIO_10); ++ pSpeed = "100 Mbps"; ++ } ++ ++ if(!link_mode || (!strcmp(link_mode, "fd") && !strcmp(link_mode, "hd"))) ++ { ++ dbgPrint("Invalid or No value of link mode specified, defaulting to auto mode.\n"); ++ } ++ else if(!strcmp(link_mode, "hd")) ++ { ++ g_cfg_start_link_params &= ~(_CPMDIO_FD); ++ } ++ else ++ { ++ g_cfg_start_link_params &= ~(_CPMDIO_HD); ++ } ++ ++ dbgPrint("Link is manually set to the speed of %s speed and %s mode.\n", ++ pSpeed, link_mode ? link_mode : "auto"); ++ ++ return(0); ++} ++ ++//------------------------------------------------------------------------------ ++// Call back from the HAL. ++//------------------------------------------------------------------------------ ++static int cpmac_p_process_status_ind(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) ++{ ++ struct net_device *p_dev = p_cpmac_priv->owner; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ int status; ++ ++ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "Status", "Get", &status); ++ ++ /* We do not reflect the real link status if in loopback. ++ * After all, we want the packets to reach the hardware so ++ * that Send() should work. */ ++ if(p_dev->flags & IFF_LOOPBACK) ++ { ++ dbgPrint("Maintaining the link up loopback for %s.\n", p_dev->name); ++ netif_carrier_on(p_dev); ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON); ++//#endif ++ ++ return(0); ++ } ++ ++ if(status & CPMAC_STATUS_ADAPTER_CHECK) /* ???? */ ++ { ++ ; /* what to do ? */ ++ } ++ else if(status) ++ { ++ if(!netif_carrier_ok(p_dev)) ++ { ++ netif_carrier_on(p_cpmac_priv->owner); ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON); ++//#endif ++ dbgPrint("Found the Link for the CPMAC instance %s.\n", p_dev->name); ++ } ++ ++ if(netif_running(p_dev) & netif_queue_stopped(p_dev)) ++ { ++ netif_wake_queue(p_dev); ++ } ++ ++ p_cpmac_priv->link_speed = status & CPMAC_STATUS_LINK_SPEED ? 100000000:10000000; ++ p_cpmac_priv->link_mode = status & CPMAC_STATUS_LINK_DUPLEX? 3:2; ++ ++ } ++ else ++ { ++ if(netif_carrier_ok(p_dev)) ++ { ++ /* do we need to register synchronization issues with stats here. */ ++ p_cpmac_priv->link_speed = 100000000; ++ p_cpmac_priv->link_mode = 1; ++ ++ netif_carrier_off(p_dev); ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF); ++//#endif ++ ++ dbgPrint("Lost the Link for the CPMAC for %s.\n", p_dev->name); ++ } ++ ++ if(!netif_queue_stopped(p_dev)) ++ { ++ netif_stop_queue(p_dev); /* So that kernel does not keep on xmiting pkts. */ ++ } ++ } ++ ++ return(0); ++} ++ ++//----------------------------------------------------------------------------- ++// Timer related private functions. ++//----------------------------------------------------------------------------- ++static int cpmac_p_timer_init(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) ++{ ++ struct timer_list *p_timer = p_cpmac_priv->timer; ++ ++ init_timer(p_timer); ++ ++ p_timer = p_cpmac_priv->timer + TICK_TIMER; ++ p_timer->expires = 0; ++ p_timer->data = (unsigned long)p_cpmac_priv; ++ p_timer->function = cpmac_p_tick_timer_expiry; ++ ++ return(0); ++} ++ ++#if 0 ++static int cpmac_timer_cleanup(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) ++{ ++ struct timer_list *p_timer; ++ ++ p_timer = p_cpmac_priv->timer + TICK_TIMER; ++ ++ /* use spin lock to establish synchronization with the dispatch */ ++ if(p_timer->function) del_timer_sync(p_timer); ++ p_timer->function = NULL; ++ ++ return (0); ++} ++#endif ++ ++static int cpmac_p_start_timer(struct timer_list *p_timer, unsigned int delay_ticks) ++{ ++ p_timer->expires = jiffies + delay_ticks; ++ ++ if(p_timer->function) ++ { ++ add_timer(p_timer); ++ } ++ ++ return(0); ++} ++ ++static void cpmac_p_tick_timer_expiry(unsigned long p_cb_param) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = (CPMAC_PRIVATE_INFO_T*) p_cb_param; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ struct timer_list *p_timer = p_cpmac_priv->timer + TICK_TIMER; ++ ++ if(test_bit(0, &p_cpmac_priv->set_to_close)) ++ { ++ return; ++ } ++ ++ p_drv_hal->hal_funcs->Tick(p_drv_hal->hal_dev); ++ ++ cpmac_p_start_timer(p_timer, p_cpmac_priv->delay_ticks); ++} ++ ++static int cpmac_p_stop_timer(struct timer_list *p_timer) ++{ ++ /* Ideally we need to a set flag indicating not to start the timer again ++ before del_timer_sync() is called up. But here we assume that the ++ caller has set the p_cpmac_priv->set_to_close (ok for now). */ ++ del_timer_sync(p_timer); ++ ++ return(0); ++} ++ ++//------------------------------------------------------------------------------ ++// Device configuration and setup related private functions. ++//------------------------------------------------------------------------------ ++static int cpmac_p_probe_and_setup_device(CPMAC_PRIVATE_INFO_T *p_cpmac_priv, ++ unsigned long *p_dev_flags) ++{ ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; ++ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; ++ CPMAC_ABILITY_INFO_T *p_capability= p_cpmac_priv->ability_info; ++ unsigned int val = 0; ++ int channel = 0; ++ ++ p_cpmac_priv->flags = 0; ++ ++ p_capability->promiscous = CFG_PROMISCOUS; ++ p_capability->broadcast = CFG_BROADCAST; ++ p_capability->multicast = CFG_MULTICAST; ++ p_capability->all_multi = CFG_ALL_MULTI; ++ p_capability->jumbo_frames = CFG_JUMBO_FRAMES; ++ p_capability->short_frames = CFG_SHORT_FRAMES; ++ p_capability->auto_negotiation = CFG_AUTO_NEGOTIATION; ++ p_capability->link_speed = cfg_start_link_speed; ++ p_capability->loop_back = CFG_LOOP_BACK; ++ p_capability->tx_flow_control = CFG_TX_FLOW_CNTL; ++ p_capability->rx_flow_control = CFG_RX_FLOW_CNTL; ++ p_capability->tx_pacing = CFG_TX_PACING; ++ p_capability->rx_pass_crc = CFG_RX_PASS_CRC; ++ p_capability->qos_802_1q = CFG_QOS_802_1Q; ++ p_capability->tx_num_chan = CFG_TX_NUM_CHAN; ++ ++ /* Lets probe the device for the configured capabilities (netdev specific).*/ ++ ++ /* Following are set in the set_multi_list, when indicated by the kernel ++ * Promiscous and all multi. ++ */ ++ ++ if(p_capability->broadcast) ++ { ++ channel = 0; ++ val = 1; ++ if((p_hal_funcs->Control(p_hal_dev, pszRX_BROAD_EN, pszSet, &val) == 0) && ++ (p_hal_funcs->Control(p_hal_dev, pszRX_BROAD_CH, pszSet, &channel) == 0)) ++ *p_dev_flags |= IFF_BROADCAST; ++ else ++ p_capability->broadcast = 0; /* no broadcast capabilities */ ++ } ++ ++ if(p_capability->multicast) ++ { ++ val = 1; ++ channel = 0; ++ if((p_hal_funcs->Control(p_hal_dev, pszRX_MULT_EN, pszSet, &val) == 0) && ++ (p_hal_funcs->Control(p_hal_dev, pszRX_MULT_CH, pszSet, &channel) == 0)) ++ *p_dev_flags |= IFF_MULTICAST; ++ else ++ { ++ p_capability->multicast = 0; ++ p_capability->all_multi = 0; /* no multicast, no all-multi. */ ++ } ++ } ++ ++ if(p_capability->loop_back) ++ { ++ ; /* We do not put the device in loopback, if required use ioctl */ ++ } ++ ++ /* Lets probe the device for the configured capabilities (Non net device specific).*/ ++ ++ if(p_capability->jumbo_frames) ++ { ++ val = 0; ++ if(p_hal_funcs->Control(p_hal_dev, pszRX_NO_CHAIN, pszSet, &val) == 0) ++ p_cpmac_priv->flags |= IFF_PRIV_JUMBO_FRAMES; ++ else ++ p_capability->jumbo_frames = 0; ++ } ++ ++ if(p_capability->short_frames) ++ { ++ val = 1; ++ if(p_hal_funcs->Control(p_hal_dev, pszRX_CSF_EN, pszSet, &val) == 0) ++ p_cpmac_priv->flags |= IFF_PRIV_SHORT_FRAMES; ++ else ++ p_capability->short_frames = 0; ++ } ++ ++ val = g_cfg_start_link_params; ++ ++#ifdef CONFIG_AR7_MDIX ++ if( avalanche_is_mdix_on_chip() ) ++ { ++ val |= _CPMDIO_AUTOMDIX; ++ } ++#endif ++ ++ if(p_hal_funcs->Control(p_hal_dev,pszMdioConnect,pszSet, &val) !=0) ++ { ++ p_capability->link_speed = 0; ++ } ++ else ++ { ++ if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_HD | _CPMDIO_FD | _CPMDIO_10)) ++ p_cpmac_priv->flags |= IFF_PRIV_AUTOSPEED; ++ else if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_HD)) ++ p_cpmac_priv->flags |= IFF_PRIV_LINK100_HD; ++ else if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_FD)) ++ p_cpmac_priv->flags |= IFF_PRIV_LINK100_FD; ++ else if(g_cfg_start_link_params & (_CPMDIO_10 | _CPMDIO_HD)) ++ p_cpmac_priv->flags |= IFF_PRIV_LINK10_HD; ++ else if(g_cfg_start_link_params & (_CPMDIO_10 | _CPMDIO_FD)) ++ p_cpmac_priv->flags |= IFF_PRIV_LINK10_FD; ++ else ++ ; ++ } ++ ++ if(p_capability->tx_flow_control) ++ { ++ val = 1; ++ if(p_hal_funcs->Control(p_hal_dev,pszTX_FLOW_EN, pszSet, &val) ==0) ++ p_cpmac_priv->flags |= IFF_PRIV_TX_FLOW_CNTL; ++ else ++ p_capability->tx_flow_control = 0; ++ } ++ ++ if(p_capability->rx_flow_control) ++ { ++ val = 1; ++ if(p_hal_funcs->Control(p_hal_dev, pszRX_FLOW_EN, pszSet, &val) ==0) ++ p_cpmac_priv->flags |= IFF_PRIV_RX_FLOW_CNTL; ++ else ++ p_capability->rx_flow_control = 0; ++ } ++ ++ if(p_capability->tx_pacing) ++ { ++ val = 1; ++ if(p_hal_funcs->Control(p_hal_dev, pszTX_PACE, pszSet, &val) ==0) ++ p_cpmac_priv->flags |= IFF_PRIV_TX_PACING; ++ else ++ p_capability->tx_pacing = 0; ++ } ++ ++ if(p_capability->rx_pass_crc) ++ { ++ val = 1; ++ if(p_hal_funcs->Control(p_hal_dev, pszRX_PASS_CRC, pszSet, &val) == 0) ++ p_cpmac_priv->flags |= IFF_PRIV_RX_PASS_CRC; ++ else ++ p_capability->rx_pass_crc = 0; ++ } ++ ++ if(p_capability->qos_802_1q) ++ { ++ val = 1; ++ if(p_hal_funcs->Control(p_hal_dev, pszRX_QOS_EN, pszSet, &val) == 0) ++ p_cpmac_priv->flags |= IFF_PRIV_8021Q_EN; ++ else ++ { ++ p_capability->qos_802_1q = 0; ++ p_capability->tx_num_chan= 1; ++ } ++ } ++ ++ if(p_capability->tx_num_chan > 1) ++ { ++ int cfg_tx_num_chan = p_capability->tx_num_chan; ++ val = 0; ++#ifdef TEST ++ if(p_hal_funcs->Control(p_hal_dev, pszTX_NUM_CH, pszGet, &val) == 0) ++ cfg_tx_num_chan = cfg_tx_num_chan > val ? val : cfg_tx_num_chan; ++ else ++ cfg_tx_num_chan = 1; ++#endif ++ p_capability->tx_num_chan = cfg_tx_num_chan; ++ } ++ ++ return(0); ++} ++ ++static int cpmac_p_setup_driver_params(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) ++{ ++ int i=0; ++ int threshold = CFG_TX_NUM_BUF_SERVICE; ++ ++ char *tx_threshold_ptr = prom_getenv("threshold"); ++ ++ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info = p_cpmac_priv->tx_chan_info; ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info; ++ CPMAC_ABILITY_INFO_T *p_capability = p_cpmac_priv->ability_info; ++ ++ /* Timer stuff */ ++ p_cpmac_priv->timer_count = 1; /* should be < or = the MAX TIMER */ ++ p_cpmac_priv->timer_created = 0; ++ p_cpmac_priv->timer_access_hal = 1; ++ ++ for(i=0; i < MAX_TIMER; i++) ++ p_cpmac_priv->timer[i].function = NULL; ++ ++ p_cpmac_priv->enable_802_1q = p_capability->qos_802_1q; ++ ++ /* Tx channel related.*/ ++ p_tx_chan_info->cfg_chan = p_capability->tx_num_chan; ++ p_tx_chan_info->opened_chan = 0; ++ ++ if(tx_threshold_ptr) ++ threshold = simple_strtol(tx_threshold_ptr, (char **)NULL, 10); ++ ++ if((threshold <= 0) && tx_threshold_ptr) /* If threshold set to 0 then Enable the TX interrupt */ ++ { ++ threshold = CFG_TX_NUM_BUF_SERVICE; ++ p_tx_chan_info->tx_int_disable = 0; ++ ++ } ++ else ++ { ++ p_tx_chan_info->tx_int_disable = CFG_TX_INT_DISABLE; ++ } ++ ++ for(i=0; i < MAX_TX_CHAN; i++) ++ { ++ ++ ++ ++ p_tx_chan_info->chan[i].state = CHAN_CLOSE; ++ p_tx_chan_info->chan[i].num_BD = CFG_TX_NUM_BUF_DESC; ++ p_tx_chan_info->chan[i].buffer_size = cpmac_max_frame_size; ++ p_tx_chan_info->chan[i].buffer_offset = CFG_TX_BUF_OFFSET; ++ ++ ++ ++ p_tx_chan_info->chan[i].service_max = threshold; ++ } ++ ++ if (p_tx_chan_info->tx_int_disable) ++ printk("Cpmac driver Disable TX complete interrupt setting threshold to %d.\n",threshold); ++ else ++ printk("Cpmac driver Enable TX complete interrupt\n"); ++ ++ ++ /* Assuming just one rx channel for now */ ++ p_rx_chan_info->cfg_chan = 1; ++ p_rx_chan_info->opened_chan = 0; ++ p_rx_chan_info->chan->state = CHAN_CLOSE; ++ p_rx_chan_info->chan->num_BD = CFG_RX_NUM_BUF_DESC; ++ p_rx_chan_info->chan->buffer_size = cpmac_max_frame_size; ++ p_rx_chan_info->chan->buffer_offset = CFG_RX_BUF_OFFSET; ++ p_rx_chan_info->chan->service_max = CFG_RX_NUM_BUF_SERVICE; ++ ++ /* Set as per RFC 2665 */ ++ p_cpmac_priv->link_speed = 100000000; ++ p_cpmac_priv->link_mode = 1; ++ ++ p_cpmac_priv->loop_back = 0; ++ ++ return(0); ++} ++ ++inline static int cpmac_p_rx_buf_setup(CPMAC_RX_CHAN_INFO_T *p_rx_chan) ++{ ++ /* Number of ethernet packets & max pkt length */ ++ p_rx_chan->chan->tot_buf_size = p_rx_chan->chan->buffer_size + ++ 2*(CONTROL_802_1Q_SIZE) + ++ p_rx_chan->chan->buffer_offset + ++ ADD_FOR_4BYTE_ALIGN(p_rx_chan->chan->buffer_offset & 0x3); ++ ++ p_rx_chan->chan->tot_reserve_bytes = CONTROL_802_1Q_SIZE + ++ p_rx_chan->chan->buffer_offset + ++ L3_ALIGN(p_rx_chan->chan->buffer_offset & 0x3); ++ ++ return(0); ++} ++ ++//----------------------------------------------------------------------------- ++// Net device related private functions. ++//----------------------------------------------------------------------------- ++ ++/*************************************************************** ++ * cpmac_dev_init ++ * ++ * Returns: ++ * 0 on success, error code otherwise. ++ * Parms: ++ * dev The structure of the device to be ++ * init'ed. ++ * ++ * This function completes the initialization of the ++ * device structure and driver. It reserves the IO ++ * addresses and assignes the device's methods. ++ * ++ * ++ **************************************************************/ ++ ++static int cpmac_dev_init(struct net_device *p_dev) ++{ ++ int retVal = -1; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ int instance_num = p_cpmac_priv->instance_num; ++ unsigned long net_flags = 0; ++ char *mac_name = NULL; ++ char *mac_string = NULL; ++ ++ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info; ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal; ++ int i; ++ ++ int mem_size = sizeof(CPMAC_DRV_HAL_INFO_T) ++ + sizeof(CPMAC_TX_CHAN_INFO_T) ++ + sizeof(CPMAC_RX_CHAN_INFO_T) ++ + sizeof(CPMAC_ABILITY_INFO_T) ++ + sizeof(CPMAC_DEVICE_MIB_T) ++ + sizeof(CPMAC_DRV_STATS_T); ++ ++ ++#if defined(CONFIG_MIPS_SEAD2) ++ int prev_reset_val = RESET_REG_PRCR; ++ /* Bring the module out of reset */ ++ RESET_REG_PRCR |= temp_reset_value[p_cpmac_priv->instance_num]; ++ ++ /* Read the version id of the device to check if the device really exists */ ++ if( VERSION(temp_base_address[p_cpmac_priv->instance_num]) == 0) ++ { ++ printk(" CPMAC:Device not found\n"); ++ RESET_REG_PRCR = prev_reset_val; ++ return -ENODEV; ++ } ++ ++ RESET_REG_PRCR = prev_reset_val; ++#endif ++ ++ ++ if((p_drv_hal = kmalloc(mem_size, GFP_KERNEL)) == NULL) ++ { ++ errPrint("Failed to allocate memory; rewinding.\n"); ++ return(-1); ++ } ++ ++ memset(p_drv_hal, 0, mem_size); ++ ++ /* build the cpmac private object */ ++ p_cpmac_priv->drv_hal = p_drv_hal; ++ p_cpmac_priv->tx_chan_info = p_tx_chan_info ++ = (CPMAC_TX_CHAN_INFO_T*)((char*)p_drv_hal ++ + sizeof(CPMAC_DRV_HAL_INFO_T)); ++ p_cpmac_priv->rx_chan_info = p_rx_chan_info ++ = (CPMAC_RX_CHAN_INFO_T*)((char *)p_tx_chan_info ++ + sizeof(CPMAC_TX_CHAN_INFO_T)); ++ p_cpmac_priv->ability_info = (CPMAC_ABILITY_INFO_T *)((char *)p_rx_chan_info ++ + sizeof(CPMAC_RX_CHAN_INFO_T)); ++ p_cpmac_priv->device_mib = (CPMAC_DEVICE_MIB_T *)((char *)p_cpmac_priv->ability_info ++ + sizeof(CPMAC_ABILITY_INFO_T)); ++ p_cpmac_priv->stats = (CPMAC_DRV_STATS_T *)((char *)p_cpmac_priv->device_mib ++ + sizeof(CPMAC_DEVICE_MIB_T)); ++ ++ p_drv_hal->owner = p_cpmac_priv; ++ ++ ++ switch(instance_num) ++ { ++ ++ case 0: ++ mac_name="maca"; ++ ++ /* Also setting port information */ ++ p_dev->if_port = AVALANCHE_CPMAC_LOW_PORT_ID; ++ ++ break; ++ ++ case 1: ++ mac_name="macb"; ++ ++ /* Also setting port information */ ++ p_dev->if_port = AVALANCHE_CPMAC_HIGH_PORT_ID; ++ ++ break; ++ } ++ ++ if(mac_name) ++ mac_string=prom_getenv(mac_name); ++ ++ if(!mac_string) ++ { ++ mac_string="08.00.28.32.06.02"; ++ printk("Error getting mac from Boot enviroment for %s\n",p_dev->name); ++ printk("Using default mac address: %s\n",mac_string); ++ if(mac_name) ++ { ++ printk("Use Bootloader command:\n"); ++ printk(" setenv %s xx.xx.xx.xx.xx.xx\n",""); ++ printk("to set mac address\n"); ++ } ++ } ++ ++ str2eaddr(p_cpmac_priv->mac_addr,mac_string); ++ ++ for (i=0; i <= ETH_ALEN; i++) ++ { ++ /* This sets the hardware address */ ++ p_dev->dev_addr[i] = p_cpmac_priv->mac_addr[i]; ++ } ++ ++ p_cpmac_priv->set_to_close = 1; ++ p_cpmac_priv->non_data_irq_expected = 0; ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// if((p_cpmac_priv->led_handle = avalanche_led_register("cpmac", instance_num)) == NULL) ++// { ++// errPrint("Could not allocate handle for CPMAC[%d] LED.\n", instance_num); ++// goto cpmac_init_mod_error; ++// } ++//#endif ++ ++ if(cpmac_drv_init_module(p_drv_hal, p_dev, instance_num) != 0) ++ { ++ errPrint("Could not initialize the HAL for %s.\n", p_dev->name); ++ goto cpmac_init_mod_error; ++ } ++ ++ /* initialize the CPMAC device */ ++ if (cpmac_drv_init(p_drv_hal) == -1) ++ { ++ errPrint("HAL init failed for %s.\n", p_dev->name); ++ goto cpmac_init_device_error; ++ } ++ ++ if(cpmac_p_probe_and_setup_device(p_cpmac_priv, &net_flags) == -1) ++ { ++ errPrint("Failed to configure up %s.\n", p_dev->name); ++ goto cpmac_init_device_error; ++ } ++ ++ if(cpmac_p_setup_driver_params(p_cpmac_priv) == -1) ++ { ++ errPrint("Failed to set driver parameters for %s.\n", p_dev->name); ++ goto cpmac_init_device_error; ++ } ++ ++ cpmac_p_rx_buf_setup(p_rx_chan_info); ++ ++ /* initialize the timers for the net device */ ++ if(cpmac_p_timer_init(p_cpmac_priv) == -1) ++ { ++ errPrint("Failed to set timer(s) for %s.\n", p_dev->name); ++ goto cpmac_timer_init_error; ++ } ++ ++ p_dev->addr_len = 6; ++ ++ p_dev->open = &cpmac_dev_open; /* i.e. Start Device */ ++ p_dev->hard_start_xmit = &cpmac_dev_tx; ++ p_dev->stop = &cpmac_dev_close; ++ p_dev->get_stats = &cpmac_dev_get_net_stats; ++ ++ p_dev->set_multicast_list = &cpmac_dev_mcast_set; ++ p_dev->set_mac_address = cpmac_dev_set_mac_addr; ++ /* Knocking off the default broadcast and multicast flags. Allowing the ++ device configuration to control the flags. */ ++ p_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ p_dev->flags |= net_flags; ++ ++ netif_carrier_off(p_dev); ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF); ++//#endif ++ ++ /* Tasklet is initialized at the isr registeration time. */ ++ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "CpmacBase", "Get", &p_dev->base_addr); ++ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "CpmacSize", "Get", &p_cpmac_priv->dev_size); ++ ++ request_mem_region(p_dev->base_addr, p_cpmac_priv->dev_size, p_dev->name); ++ ++ retVal = 0; ++ ++ if(g_init_enable_flag) ++ cpmac_p_dev_enable(p_dev); ++ ++ return(retVal); ++ ++cpmac_timer_init_error: ++cpmac_init_device_error : ++ cpmac_drv_cleanup(p_drv_hal); ++ ++cpmac_init_mod_error: ++ kfree(p_drv_hal); ++ ++ return (retVal); ++ ++} /* cpmac_dev_init */ ++ ++ ++/*************************************************************** ++ * cpmac_p_dev_enable ++ * ++ * Returns: ++ * 0 on success, error code otherwise. ++ * Parms: ++ * dev Structure of device to be opened. ++ * ++ * This routine puts the driver and CPMAC adapter in a ++ * state where it is ready to send and receive packets. ++ * ++ * ++ **************************************************************/ ++int cpmac_p_dev_enable( struct net_device *p_dev) ++{ ++ int ret_val = 0; ++ int channel = 0; ++ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info; ++ int max_length = p_rx_chan_info->chan->tot_buf_size; ++ ++ p_cpmac_priv->set_to_close = 0; ++ ++ if((ret_val = cpmac_drv_start(p_drv_hal, p_cpmac_priv->tx_chan_info, ++ p_cpmac_priv->rx_chan_info, CHAN_SETUP))==-1) ++ { ++ errPrint("%s error: failed to start the device.\n", p_dev->name); ++ ret_val = -1; ++ } ++ else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev,"RX_UNICAST_SET", ++ "Set", &channel)!=0) ++ { ++ errPrint("%s error: device chan 0 could not be enabled.\n", p_dev->name); ++ ret_val = -1; ++ } ++ else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, pszRX_MAXLEN, pszSet, &max_length) != 0) ++ { ++ errPrint(" CPMAC registers can't be written \n"); ++ ret_val = -1; ++ } ++ else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "TxIntDisable", "Set", ++ &p_cpmac_priv->tx_chan_info->tx_int_disable) != 0) ++ { ++ errPrint(" CPMAC registers can't be written \n"); ++ ret_val = -1; ++ } ++ else ++ { ++ ; // Every thing went OK. ++ } ++ ++ return(ret_val); ++} /* cpmac_dev_enable */ ++ ++ ++static int cpmac_dev_open(struct net_device *p_dev) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; ++ ++ if(!g_init_enable_flag) ++ cpmac_p_dev_enable(p_dev); ++ ++ if(request_irq(p_isr_cb_param->intr, cpmac_hal_isr, SA_INTERRUPT, ++ "Cpmac Driver", p_isr_cb_param)) ++ { ++ errPrint("Failed to register the irq %d for Cpmac %s.\n", ++ p_isr_cb_param->intr, p_dev->name); ++ return (-1); ++ } ++ ++ netif_start_queue(p_dev); ++ ++ MOD_INC_USE_COUNT; ++ p_cpmac_priv->stats->start_tick = jiffies; ++ dbgPrint("Started the network queue for %s.\n", p_dev->name); ++ return(0); ++} ++ ++/*************************************************************** ++ * cpmac_p_dev_disable ++ * ++ * Returns: ++ * An error code. ++ * Parms: ++ * dev The device structure of the device to ++ * close. ++ * ++ * This function shuts down the adapter. ++ * ++ **************************************************************/ ++int cpmac_p_dev_disable(struct net_device *p_dev) ++{ ++ int ret_val = 0; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ ++ set_bit(0, &p_cpmac_priv->set_to_close); ++ set_bit(0, &p_cpmac_priv->non_data_irq_expected); ++ ++ /* The driver does not re-schedule the tasklet after kill is called. So, this ++ should take care of the bug in the kernel. */ ++ tasklet_kill(&p_cpmac_priv->cpmac_isr.tasklet); ++ ++ if(cpmac_drv_stop(p_drv_hal, p_cpmac_priv->tx_chan_info, ++ p_cpmac_priv->rx_chan_info, ++ CHAN_TEARDOWN | FREE_BUFFER | BLOCKING | COMPLETE) == -1) ++ { ++ ret_val = -1; ++ } ++ else ++ { ++ /* hope that the HAL closes down the tick timer.*/ ++ ++ dbgPrint("Device %s Closed.\n", p_dev->name); ++ p_cpmac_priv->stats->start_tick = jiffies; ++ ++ p_cpmac_priv->link_speed = 100000000; ++ p_cpmac_priv->link_mode = 1; ++ netif_carrier_off(p_dev); ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF); ++//#endif ++ ++ clear_bit(0, &p_cpmac_priv->non_data_irq_expected); ++ ++ } ++ ++ return (ret_val); ++ ++} /* cpmac_dev_close */ ++ ++ ++/*************************************************************** ++ * cpmac_dev_close ++ * ++ * Returns: ++ * An error code. ++ * Parms: ++ * dev The device structure of the device to ++ * close. ++ * ++ * This function shuts down the adapter. ++ * ++ **************************************************************/ ++static int cpmac_dev_close(struct net_device *p_dev) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; ++ ++ /* inform the upper layers. */ ++ netif_stop_queue(p_dev); ++ ++ if(!g_init_enable_flag) ++ cpmac_p_dev_disable(p_dev); ++ else ++ free_irq(p_isr_cb_param->intr, p_isr_cb_param); ++ ++ MOD_DEC_USE_COUNT; ++ ++ return(0); ++} ++ ++static void cpmac_dev_mcast_set(struct net_device *p_dev) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ CPMAC_ABILITY_INFO_T *p_capability = p_cpmac_priv->ability_info; ++ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; ++ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; ++ int val = 1; ++ int channel = 0; ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// if(netif_carrier_ok(p_dev)) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON); ++//#endif ++ ++ if(p_dev->flags & IFF_PROMISC) ++ { ++ if(p_capability->promiscous) ++ { ++ /* multi mode in the HAL, check this */ ++ val = 0; ++ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val); ++ ++ val = 1; ++ /* set the promiscous mode in the HAL */ ++ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val); ++ p_hal_funcs->Control(p_hal_dev, pszRX_PROM_CH, pszSet, &channel); ++ ++ dbgPrint("%s set in the Promisc mode.\n", p_dev->name); ++ } ++ else ++ { ++ errPrint("%s not configured for Promisc mode.\n", p_dev->name); ++ } ++ } ++ else if(p_dev->flags & IFF_ALLMULTI) ++ { ++ if(p_capability->all_multi) ++ { ++ val = 0; ++ /* disable the promiscous mode in the HAL */ ++ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, "Clear", &val); ++ ++ val = 1; ++ /* set the all multi mode in the HAL */ ++ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, pszSet, &val); ++ p_hal_funcs->Control(p_hal_dev, pszRX_MULT_CH, pszSet, &channel); ++ ++ dbgPrint("%s has been set to the ALL_MULTI mode.\n", p_dev->name); ++ } ++ else ++ { ++ errPrint("%s not configured for ALL MULTI mode.\n", p_dev->name); ++ } ++ } ++ else if(p_dev->mc_count) ++ { ++ if(p_capability->multicast) ++ { ++ struct dev_mc_list *p_dmi = p_dev->mc_list; ++ int count; ++ ++ val = 0; ++ /* clear all the previous data, we are going to populate new ones.*/ ++ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val); ++ /* disable the promiscous mode in the HAL */ ++ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val); ++ ++ for(count = 0; count < p_dev->mc_count; count++, p_dmi = p_dmi->next) ++ { ++ p_hal_funcs->Control(p_hal_dev, "RX_MULTI_SINGLE", "Set", p_dmi->dmi_addr); ++ } ++ ++ dbgPrint("%s configured for %d multicast addresses.\n", p_dev->name, p_dev->mc_count); ++ } ++ else ++ { ++ errPrint("%s has not been configuted for multicast handling.\n", p_dev->name); ++ } ++ } ++ else ++ { ++ val = 0; ++ /* clear all the previous data, we are going to populate new ones.*/ ++ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val); ++ /* disable the promiscous mode in the HAL */ ++ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val); ++ dbgPrint("Dev set to Unicast mode.\n"); ++ } ++} ++ ++static int cpmac_dev_set_mac_addr(struct net_device *p_dev,void * addr) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; ++ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; ++ struct sockaddr *sa = addr; ++ ++ memcpy(p_cpmac_priv->mac_addr,sa->sa_data,p_dev->addr_len); ++ memcpy(p_dev->dev_addr,sa->sa_data,p_dev->addr_len); ++ p_hal_funcs->Control(p_hal_dev, pszMacAddr, pszSet, p_cpmac_priv->mac_addr); ++ ++ return 0; ++ ++} ++ ++/* VLAN is handled by vlan/vconfig support. Here, we just check for the ++ * 802.1q configuration of the device and en-queue the packet accordingly. ++ * We do not do any 802.1q processing here. ++ */ ++static int cpmac_dev_tx( struct sk_buff *skb, struct net_device *p_dev) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ int channel = 0; ++ int ret_val = 0; ++ FRAGLIST send_frag_list[1]; ++ ++#ifdef CPMAC_8021Q_SUPPORT ++ if(skb->len < TCI_END_OFFSET) ++ { ++ /* Whee, frame shorter than 14 bytes !! We need to copy ++ * fragments to understand the frame. Too much work. ++ * Hmm, dump it. */ ++ ++ /* Free the buffer */ ++ goto cpmac_dev_tx_drop_pkt; ++ } ++ ++ /* 802.1p/q stuff */ ++ if(IS_802_1Q_FRAME(skb->data + TPID_START_OFFSET)) ++ { ++ /* IEEE 802.1q, section 8.8 and section 8.11.9 */ ++ if(!p_cpmac_priv->enable_802_1q) ++ { ++ /* free the buffer */ ++ goto cpmac_dev_tx_drop_pkt; ++ } ++ ++ channel = GET_802_1P_CHAN(p_cpmac_priv->tx_chan_info->opened_chan, ++ skb->data[TCI_START_OFFSET]); ++ ++ } ++ /* sending a non 802.1q frame, when configured for 802.1q: dump it.*/ ++ else if(p_cpmac_priv->enable_802_1q) ++ { ++ /* free the buffer */ ++ goto cpmac_dev_tx_drop_pkt; ++ } ++ else ++ { ++ ;/* it is the good old non 802.1q */ ++ } ++#endif ++ ++ send_frag_list->len = skb->len; ++ send_frag_list->data = skb->data; ++ ++#ifdef CPMAC_TEST ++ xdump(skb->data, skb->len, "send"); ++#endif ++ ++ dma_cache_wback_inv((unsigned long)skb->data, skb->len); ++ ++ if(p_drv_hal->hal_funcs->Send(p_drv_hal->hal_dev, send_frag_list, 1, ++ skb->len, skb, channel) != 0) ++ { ++ /* code here to stop the queue, when allowing tx timeout, perhaps next release.*/ ++ p_cpmac_priv->net_dev_stats.tx_errors++; ++#ifndef TI_SLOW_PATH ++ /* Free the skb in case of Send return error */ ++ dev_kfree_skb_any(skb); ++ p_cpmac_priv->net_dev_stats.tx_dropped++; ++ return 0; ++#endif ++ goto cpmac_dev_tx_drop_pkt; ++ } ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_TX_ACTIVITY); ++//#endif ++ ++ return(ret_val); ++ ++cpmac_dev_tx_drop_pkt: ++ ++ p_cpmac_priv->net_dev_stats.tx_dropped++; ++ ret_val = -1; ++ return (ret_val); ++ ++} /*cpmac_dev_tx */ ++ ++ ++//------------------------------------------------------------------------------ ++// Public functions : Called by outsiders to this file. ++//------------------------------------------------------------------------------ ++ ++ ++void *cpmac_hal_malloc_buffer(unsigned int size, void* mem_base, unsigned int mem_range, ++ OS_SETUP *p_os_setup, HAL_RECEIVEINFO *HalReceiveInfo, ++ OS_RECEIVEINFO **osReceiveInfo, OS_DEVICE *p_dev) ++{ ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = (CPMAC_RX_CHAN_INFO_T *)p_os_setup; ++ int tot_buf_size = p_rx_chan_info->chan->tot_buf_size; ++ int tot_reserve_bytes = p_rx_chan_info->chan->tot_reserve_bytes; ++ struct sk_buff *p_skb; ++ void *ret_ptr; ++ ++ /* use TI SKB private pool */ ++ p_skb = dev_alloc_skb(tot_buf_size); ++ ++ if(p_skb == NULL) ++ { ++ errPrint("Failed to allocate skb for %s.\n", ((struct net_device*)p_dev)->name); ++ return (NULL); ++ } ++ ++ p_skb->dev = p_dev; ++ skb_reserve(p_skb, tot_reserve_bytes); ++ ++ *osReceiveInfo = p_skb; ++ ++ ret_ptr = skb_put(p_skb, p_rx_chan_info->chan->buffer_size); ++ ++ return(ret_ptr); ++} ++ ++void cpmac_hal_isr(int irq, void *p_param, struct pt_regs *regs) ++{ ++ CPMAC_ISR_INFO_T *p_cb_param = (CPMAC_ISR_INFO_T*) p_param; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cb_param->owner; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_drv_hal->owner; ++ int pkts_to_handle = 0; ++ ++ if(p_cpmac_priv->non_data_irq_expected) ++ { ++ p_cb_param->hal_isr(p_drv_hal->hal_dev, &pkts_to_handle); ++ p_drv_hal->hal_funcs->PacketProcessEnd(p_drv_hal->hal_dev); ++ } ++ else if(!p_cpmac_priv->set_to_close) ++ tasklet_schedule(&((CPMAC_ISR_INFO_T*) p_param)->tasklet); ++ else ++ ; // back off from doing anything more. We are closing down. ++} ++ ++void cpmac_handle_tasklet(unsigned long data) ++{ ++ CPMAC_ISR_INFO_T *p_cb_param = (CPMAC_ISR_INFO_T*) data; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cb_param->owner; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_drv_hal->owner; ++ int pkts_to_handle; ++ ++ p_cb_param->hal_isr(p_drv_hal->hal_dev, &pkts_to_handle); ++ ++ if(test_bit(0, &p_cpmac_priv->non_data_irq_expected) || !pkts_to_handle) ++ p_drv_hal->hal_funcs->PacketProcessEnd(p_drv_hal->hal_dev); ++ else if(!test_bit(0, &p_cpmac_priv->set_to_close)) ++ tasklet_schedule(&p_cb_param->tasklet); ++ else ++ ; // Back off from processing packets we are closing down. ++} ++ ++int cpmac_hal_control(OS_DEVICE *p_dev, const char *key, ++ const char *action, void *value) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ int ret_val = -1; ++ ++ if(key == NULL) ++ { ++ dbgPrint("Encountered NULL key.\n"); ++ return (-1); ++ } ++ ++ if(cpmac_ci_strcmp(key, "Sleep") == 0 && value != NULL) ++ { ++ unsigned int clocks_per_tick = cpmac_cpu_freq/HZ; ++ unsigned int requested_clocks = *(unsigned int*)value; ++ unsigned int requested_ticks = (requested_clocks + clocks_per_tick - 1)/clocks_per_tick; ++ mdelay(requested_ticks); ++ ret_val = 0; ++ } ++ else if(cpmac_ci_strcmp(key, "StateChange") == 0) ++ { ++ ret_val = cpmac_p_process_status_ind(p_cpmac_priv); ++ } ++ else if(cpmac_ci_strcmp(key, "Tick") == 0 && action != NULL) ++ { ++ if(cpmac_ci_strcmp(action, "Set") == 0 && value != NULL) ++ { ++ if(*(unsigned int*)value == 0) ++ { ++ cpmac_p_stop_timer(p_cpmac_priv->timer + TICK_TIMER); ++ ret_val = 0; ++ } ++ else ++ { ++ unsigned int clocks_per_tick = cpmac_cpu_freq/HZ; ++ unsigned int requested_clocks = *(unsigned int*)value; ++ unsigned int requested_ticks = (requested_clocks + clocks_per_tick - 1)/clocks_per_tick; ++ ++ p_cpmac_priv->delay_ticks = requested_ticks; /* save it for re-triggering */ ++ ret_val = cpmac_p_start_timer(p_cpmac_priv->timer + TICK_TIMER, ++ p_cpmac_priv->delay_ticks); ++ } ++ } ++ else if(cpmac_ci_strcmp(action, "Clear") == 0) ++ { ++ ret_val = cpmac_p_stop_timer(p_cpmac_priv->timer + TICK_TIMER); ++ } ++ else ++ ; ++ } ++ else if(cpmac_ci_strcmp(key, "MacAddr") == 0 && action != NULL) ++ { ++ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) ++ { ++ *(char **)value = p_cpmac_priv->mac_addr; ++ ret_val = 0; ++ } ++ } ++ else if(cpmac_ci_strcmp(key, "CpuFreq") == 0) ++ { ++ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) ++ { ++ *(unsigned int *)value = cpmac_cpu_freq; ++ dbgPrint("Cpu frequency for cpmacs is %u\n",cpmac_cpu_freq); ++ ret_val = 0; ++ } ++ } ++ else if(cpmac_ci_strcmp(key, "SioFlush") == 0) ++ { ++ ret_val = 0; ++ dbgPrint("\n"); ++ } ++ else if(cpmac_ci_strcmp(key, "CpmacFrequency") == 0) ++ { ++ /* For Sangam cpmac clock is off the PBUS */ ++ /* OS Needs to supply CORRECT frequency */ ++ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) ++ { ++ *(unsigned int *)value = CONFIG_AR7_SYS * 1000 * 1000; ++ ret_val = 0; ++ } ++ } ++ /* For now, providing back the default values. */ ++ else if(cpmac_ci_strcmp(key, "MdioClockFrequency") == 0) ++ { ++ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) ++ { ++ *(unsigned int *)value = 2200000; /*DEFAULT */ ++ ret_val = 0; ++ } ++ } ++ /* For now, providing back the default values. */ ++ else if(cpmac_ci_strcmp(key, "MdioBusFrequency") == 0) ++ { ++ /* For Sangam MdioBusFreq is off the PBUS */ ++ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) ++ { ++ *(unsigned int *)value = CONFIG_AR7_SYS * 1000 * 1000; ++ ret_val = 0; ++ } ++ } ++ ++#if 0 ++#if defined(CONFIG_AVALANCHE_AUTO_MDIX) ++ /* supporting Mdio Mdix switching */ ++ else if(cpmac_ci_strcmp(key, hcMdioMdixSwitch) == 0) ++ { ++ /* For Sangam Mdio-switching action should be always "set"*/ ++ if(cpmac_ci_strcmp(action, hcSet) == 0 && value != NULL ) ++ { ++ unsigned int mdix = *((unsigned int *) value) ; ++ ++ if(mdix) ++ avalanche_set_phy_into_mdix_mode(); ++ ++ else ++ avalanche_set_phy_into_mdi_mode(); ++ ++ ret_val = 0; ++ } ++ ++ } ++#endif ++#endif ++ else if(cpmac_ci_strcmp(key, hcMdioMdixSwitch) == 0) ++ { ++ /* For Sangam Mdio-switching action should be always "set"*/ ++ if(cpmac_ci_strcmp(action, hcSet) == 0 && value != NULL ) ++ { ++ unsigned int mdix = *((unsigned int *) value) ; ++ ++#ifdef CONFIG_AR7_MDIX ++ avalanche_set_mdix_on_chip(0xa8610000 , mdix ? 1: 0); ++#endif ++ ++ ret_val = 0; ++ } ++ ++ } ++ ++ return(ret_val); ++} ++ ++ ++int cpmac_hal_receive(OS_DEVICE *p_dev, FRAGLIST *fragList, ++ unsigned int fragCount, ++ unsigned int packet_size, ++ HAL_RECEIVEINFO *hal_receive_info, ++ unsigned int mode) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ struct sk_buff *p_skb = fragList[0].OsInfo; ++ p_skb->len = fragList[0].len; ++ ++ /* invalidate the cache. */ ++ dma_cache_inv((unsigned long)p_skb->data, fragList[0].len); ++#ifdef CPMAC_TEST ++ xdump(p_skb->data, p_skb->len, "recv"); ++#endif ++#ifdef CPMAC_8021Q_SUPPORT ++ /* 802.1q stuff, just does the basic checking here. */ ++ if(!p_cpmac_priv->enable_802_1q && ++ p_skb->len > TCI_END_OFFSET && ++ IS_802_1Q_FRAME(p_skb->data + TPID_START_OFFSET)) ++ { ++ goto cpmac_hal_recv_frame_mismatch; ++ } ++#endif ++ if(fragCount > 1) ++ { ++ int len; ++ struct sk_buff *p_temp_skb; ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info; ++ int count; ++ ++ dbgPrint("Recv: It is multifragment for %s.\n", p_dev->name); ++ ++ p_skb = dev_alloc_skb(packet_size + ++ p_rx_chan_info->chan->tot_reserve_bytes); ++ if(p_skb == NULL) ++ { ++ p_cpmac_priv->net_dev_stats.rx_errors++; ++ goto cpmac_hal_recv_alloc_failed; ++ } ++ ++ p_skb->dev = p_dev; ++ skb_reserve(p_skb, p_rx_chan_info->chan->tot_reserve_bytes); ++ ++ for(count = 0; count < fragCount; count++) ++ { ++ p_temp_skb = fragList[count].OsInfo; ++ len = fragList[count].len; ++ ++ dma_cache_inv((unsigned long)p_temp_skb->data, len); ++ ++ memcpy(skb_put(p_skb, len), p_temp_skb->data, len); ++ dev_kfree_skb_any(p_temp_skb); ++ } ++ } ++ ++ ++#if defined(CONFIG_MIPS_AVALANCHE_MARVELL) ++ /* Fetch the receiving port information from EGRESS TRAILOR Bytes*/ ++ p_dev->if_port = (unsigned char)p_skb->data[packet_size -(EGRESS_TRAILOR_LEN-1)] + AVALANCHE_MARVELL_BASE_PORT_ID; ++ skb_trim(p_skb, packet_size - EGRESS_TRAILOR_LEN); ++#else ++ /* set length & tail */ ++ skb_trim(p_skb, packet_size); ++#endif ++ ++ p_skb->protocol = eth_type_trans(p_skb, p_dev); ++ ++ netif_rx(p_skb); ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_RX_ACTIVITY); ++//#endif ++ ++ p_cpmac_priv->net_dev_stats.rx_packets++; ++ p_cpmac_priv->net_dev_stats.rx_bytes += packet_size; ++ ++ p_drv_hal->hal_funcs->RxReturn(hal_receive_info,1); ++ ++ return(0); ++ ++cpmac_hal_recv_alloc_failed: ++ ++#ifdef CPMAC_8021Q_SUPPORT ++cpmac_hal_recv_frame_mismatch: ++#endif ++ ++ fragCount--; ++ ++ do ++ { ++ dev_kfree_skb_any(fragList[fragCount].OsInfo); ++ } ++ while(fragCount--); ++ ++ p_cpmac_priv->net_dev_stats.rx_dropped++; ++ ++ return(-1); ++} /*cpmac_receive*/ ++ ++ ++void cpmac_hal_tear_down_complete(OS_DEVICE*a, int b, int ch) ++{ ++ dbgPrint("what to do with this.\n"); ++} ++ ++ ++int cpmac_hal_send_complete(OS_SENDINFO *p_skb) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_skb->dev->priv; ++ ++ p_cpmac_priv->net_dev_stats.tx_packets++; ++ p_cpmac_priv->net_dev_stats.tx_bytes += p_skb->len; ++ ++ dev_kfree_skb_any(p_skb); ++ ++ return(0); ++} ++ ++ ++int cpmac_reset(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) ++{ ++ // code here to reset the device/hal. Not now. ++ ++ netif_wake_queue(p_cpmac_priv->owner); ++ return(0); ++} ++ ++#ifdef CPMAC_TEST ++ ++#define isprint(a) ((a >=' ')&&(a<= '~')) ++void xdump( u_char* cp, int length, char* prefix ) ++{ ++ int col, count; ++ u_char prntBuf[120]; ++ u_char* pBuf = prntBuf; ++ count = 0; ++ while(count < length){ ++ pBuf += sprintf( pBuf, "%s", prefix ); ++ for(col = 0;count + col < length && col < 16; col++){ ++ if (col != 0 && (col % 4) == 0) ++ pBuf += sprintf( pBuf, " " ); ++ pBuf += sprintf( pBuf, "%02X ", cp[count + col] ); ++ } ++ while(col++ < 16){ /* pad end of buffer with blanks */ ++ if ((col % 4) == 0) ++ sprintf( pBuf, " " ); ++ pBuf += sprintf( pBuf, " " ); ++ } ++ pBuf += sprintf( pBuf, " " ); ++ for(col = 0;count + col < length && col < 16; col++){ ++ if (isprint((int)cp[count + col])) ++ pBuf += sprintf( pBuf, "%c", cp[count + col] ); ++ else ++ pBuf += sprintf( pBuf, "." ); ++ } ++ sprintf( pBuf, "\n" ); ++ // SPrint(prntBuf); ++ printk(prntBuf); ++ count += col; ++ pBuf = prntBuf; ++ } ++ ++} /* close xdump(... */ ++#endif ++ ++ ++static int __init cpmac_dev_probe(void) ++{ ++ int retVal = 0; ++ int unit; ++ int instance_count = CONFIG_MIPS_CPMAC_PORTS; ++ ++ //cpmac_cpu_freq = avalanche_clkc_get_freq(CLKC_MIPS); ++ cpmac_cpu_freq = CONFIG_AR7_CPU * 1000 * 1000; ++ ++ build_psp_config(); ++ ++ for(unit = 0; unit < instance_count; unit++) ++ { ++ struct net_device *p_dev; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; ++ size_t dev_size; ++ int failed; ++ ++ dev_size = sizeof(struct net_device) ++ + sizeof(CPMAC_PRIVATE_INFO_T); ++ ++ ++ if((p_dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL)) == NULL) ++ { ++ dbgPrint( "Could not allocate memory for device.\n" ); ++ retVal = -ENOMEM; ++ break; ++ } ++ ++ memset(p_dev, 0, dev_size ); ++ ++ p_dev->priv = p_cpmac_priv ++ = (CPMAC_PRIVATE_INFO_T*)(((char *) p_dev) + sizeof(struct net_device)); ++ p_cpmac_priv->owner = p_dev; ++ ++ ether_setup(p_dev); ++ ++ p_cpmac_priv->instance_num = unit; ++ p_dev->init = cpmac_dev_init; ++ ++ g_dev_array[p_cpmac_priv->instance_num] = p_dev; ++ ++#if defined CONFIG_MIPS_CPMAC_INIT_BUF_MALLOC ++ g_init_enable_flag = 1; ++ printk("Cpmac driver is allocating buffer memory at init time.\n"); ++#endif ++ ++ /* This section gives a default value by the number of PHY in order to ++ * replace the default MACRO. */ ++ { ++ char *mac_port = prom_getenv("MAC_PORT"); /* Internal: 0, External: 1 */ ++ if(!mac_port || (0 != strcmp(mac_port, "0"))) { ++ printk("Using the MAC with external PHY\n"); ++ cfg_start_link_speed = _CPMDIO_NOPHY; ++ cpmac_max_frame_size = CPMAC_MAX_FRAME_SIZE + 4; ++ } ++ else { ++ printk("Using the MAC with internal PHY\n"); ++ cfg_start_link_speed = CFG_START_LINK_SPEED; ++ cpmac_max_frame_size = CPMAC_MAX_FRAME_SIZE; ++ } ++ g_cfg_start_link_params = cfg_start_link_speed; ++ } ++ ++ cpmac_p_detect_manual_cfg(cfg_link_speed, cfg_link_mode, cpmac_debug_mode); ++ ++ failed = register_netdev(p_dev); ++ if (failed) ++ { ++ dbgPrint("Could not register device for inst %d because of reason \ ++ code %d.\n", unit, failed); ++ retVal = -1; ++ kfree(p_dev); ++ break; ++ } ++ else ++ { ++ ++ char proc_name[100]; ++ int proc_category_name_len = 0; ++ ++ p_cpmac_priv->next_device = last_cpmac_device; ++ last_cpmac_device = p_dev; ++ ++ dbgPrint(" %s irq=%2d io=%04x\n",p_dev->name, (int) p_dev->irq, ++ (int) p_dev->base_addr); ++ ++ strcpy(proc_name, "avalanche/"); ++ strcat(proc_name, p_dev->name); ++ proc_category_name_len = strlen(proc_name); ++ ++ strcpy(proc_name + proc_category_name_len, "_rfc2665_stats"); ++ create_proc_read_entry(proc_name,0,NULL,cpmac_p_read_rfc2665_stats, p_dev); ++ ++ } ++ } ++ ++ if(retVal == 0) ++ { ++ /* To maintain backward compatibility with NSP. */ ++ gp_stats_file = create_proc_entry("avalanche/cpmac_stats", 0644, NULL); ++ if(gp_stats_file) ++ { ++ gp_stats_file->read_proc = cpmac_p_read_stats; ++ gp_stats_file->write_proc = cpmac_p_write_stats; ++ } ++ create_proc_read_entry("avalanche/cpmac_link", 0, NULL, cpmac_p_read_link, NULL); ++ create_proc_read_entry("avalanche/cpmac_ver", 0, NULL, cpmac_p_get_version, NULL); ++ ++ } ++ ++ cpmac_devices_installed = unit; ++ dbgPrint("Installed %d cpmac instances.\n", unit); ++ return ( (unit >= 0 ) ? 0 : -ENODEV ); ++ ++} /* init_module */ ++ ++ ++/*************************************************************** ++ * cleanup_module ++ * ++ * Returns: ++ * Nothing ++ * Parms: ++ * None ++ * ++ * Goes through the CpmacDevices list and frees the device ++ * structs and memory associated with each device (lists ++ * and buffers). It also ureserves the IO port regions ++ * associated with this device. ++ * ++ **************************************************************/ ++ ++void cpmac_exit(void) ++{ ++ struct net_device *p_dev; ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; ++ ++ while (cpmac_devices_installed) ++ { ++ char proc_name[100]; ++ int proc_category_name_len = 0; ++ ++ p_dev = last_cpmac_device; ++ p_cpmac_priv = (CPMAC_PRIVATE_INFO_T *) p_dev->priv; ++ ++ dbgPrint("Unloading %s irq=%2d io=%04x\n",p_dev->name, (int) p_dev->irq, (int) p_dev->base_addr); ++ ++ if(g_init_enable_flag) ++ cpmac_p_dev_disable(p_dev); ++ ++ cpmac_drv_cleanup(p_cpmac_priv->drv_hal); ++ ++//#if defined (CONFIG_MIPS_AVALANCHE_LED) ++// avalanche_led_unregister(p_cpmac_priv->led_handle); ++//#endif ++ strcpy(proc_name, "avalanche/"); ++ strcat(proc_name, p_dev->name); ++ proc_category_name_len = strlen(proc_name); ++ ++ strcpy(proc_name + proc_category_name_len, "_rfc2665_stats"); ++ remove_proc_entry(proc_name, NULL); ++ ++ release_mem_region(p_dev->base_addr, p_cpmac_priv->dev_size); ++ unregister_netdev(p_dev); ++ last_cpmac_device = p_cpmac_priv->next_device; ++ ++ kfree(p_cpmac_priv->drv_hal); ++ kfree(p_dev); ++ ++ cpmac_devices_installed--; ++ } ++ ++ if(gp_stats_file) ++ remove_proc_entry("avalanche/cpmac_stats", NULL); ++ ++ remove_proc_entry("avalanche/cpmac_link", NULL); ++ remove_proc_entry("avalanche/cpmac_ver", NULL); ++ ++ psp_config_cleanup(); ++} ++ ++ ++module_init(cpmac_dev_probe); ++module_exit(cpmac_exit); +diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpmac.h +--- linux.old/drivers/net/avalanche_cpmac/cpmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpmac.h 2005-07-12 02:48:42.043594000 +0200 +@@ -0,0 +1,379 @@ ++/****************************************************************************** ++ * FILE PURPOSE: CPMAC Linux Network Device Driver Header ++ ****************************************************************************** ++ * FILE NAME: cpmac.h ++ * ++ * DESCRIPTION: CPMAC Network Device Driver Header ++ * ++ * REVISION HISTORY: ++ * Date Name Details ++ *----------------------------------------------------------------------------- ++ * 27 Nov 2002 Suraj S Iyer Initial Create. ++ * 09 Jun 2003 Suraj S Iyer Preparing for GA. ++ * ++ * (C) Copyright 2003, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef CPMAC_H ++#define CPMAC_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "cpmacHalLx.h" ++/*----------------------------------------------------------------------------- ++ * Config macros. Use these to config the driver. ++ *---------------------------------------------------------------------------*/ ++#define CPMAC_MAX_FRAME_SIZE 1518 ++ ++#if defined(CONFIG_AR7WRD) || defined(CONFIG_AR7WI) || defined(CONFIG_AR7VWI)|| defined(CONFIG_AR7VW) ++#define CFG_RX_NUM_BUF_DESC 64 ++#define CFG_RX_NUM_BUF_SERVICE 32 ++#else ++#define CFG_RX_NUM_BUF_DESC 16 ++#define CFG_RX_NUM_BUF_SERVICE 8 ++#endif ++ ++#define CFG_RX_BUF_OFFSET 0 ++ ++#define CFG_TX_NUM_BUF_DESC 128 ++#define CFG_TX_NUM_BUF_SERVICE 20 ++#define CFG_TX_BUF_OFFSET 0 /* Lets not change this. */ ++#define CFG_TX_TIMEOUT 2000 /* ticks*/ ++#define CFG_TX_INT_DISABLE 1 /* Disable the Tx Complete interrupt */ ++ ++#define CFG_JUMBO_FRAMES 1 ++#define CFG_SHORT_FRAMES 1 ++#define CFG_PROMISCOUS 1 ++#define CFG_BROADCAST 1 ++#define CFG_MULTICAST 1 ++#define CFG_ALL_MULTI (1*(CFG_MULTICAST)) ++#define CFG_AUTO_NEGOTIATION 1 ++ ++#if defined (CONFIG_MIPS_AVALANCHE_MARVELL) ++#define EGRESS_TRAILOR_LEN 4 ++#define CFG_START_LINK_SPEED (_CPMDIO_NOPHY) ++#undef CPMAC_MAX_FRAME_SIZE ++#define CPMAC_MAX_FRAME_SIZE (1518 + EGRESS_TRAILOR_LEN) ++#else ++#define CFG_START_LINK_SPEED (_CPMDIO_10 | _CPMDIO_100 | _CPMDIO_HD | _CPMDIO_FD) /* auto nego */ ++#endif ++ ++#define CFG_LOOP_BACK 1 ++#define CFG_TX_FLOW_CNTL 0 ++#define CFG_RX_FLOW_CNTL 0 ++#define CFG_TX_PACING 0 ++#define CFG_RX_PASS_CRC 0 ++#define CFG_QOS_802_1Q 0 ++#define CFG_TX_NUM_CHAN 1 ++ ++ ++/*----------------------------------------------------------------------------- ++ * Private macros. ++ *---------------------------------------------------------------------------*/ ++#define MAX_TIMER 2 ++#define TX_TIMER 0 ++#define TICK_TIMER 0 ++#define MAX_TX_CHAN 8 ++ ++#define CPMAC_LINK_OFF 0 ++#define CPMAC_LINK_ON 1 ++/*#define CPMAC_SPEED_100 2 ++#define CPMAC_SPEED_10 3 ++#define CPMAC_FULL_DPLX 4 ++#define CPMAC_HALF_DPLX 5*/ ++#define CPMAC_RX_ACTIVITY 2 ++#define CPMAC_TX_ACTIVITY 3 ++ ++struct cpmac_timer_info; ++ ++typedef int (*CPMAC_HAL_ISR_FUNC_T)(HAL_DEVICE*, int*); ++typedef int (*CPMAC_TIMEOUT_CB_T)(struct cpmac_timer_info*); ++ ++typedef struct cpmac_ability_info ++{ ++ int promiscous; ++ int broadcast; ++ int multicast; ++ int all_multi; ++ int loop_back; ++ int jumbo_frames; ++ int short_frames; ++ int auto_negotiation; ++ int tx_flow_control; ++ int rx_flow_control; ++ int tx_pacing; ++ int link_speed; ++ int rx_pass_crc; ++ int qos_802_1q; ++ int tx_num_chan; ++} ++CPMAC_ABILITY_INFO_T; ++ ++#ifdef DEBUG ++typedef struct cpmac_timer_info ++{ ++ void *owner; ++ UINT32 delay_ticks; ++ WDOG_ID timer_id; ++ UINT32 is_running; ++ UINT32 timer_set_at; ++ CPMAC_TIMEOUT_CB_T timeout_CB; ++} CPMAC_TIMER_INFO_T; ++ ++typedef struct ++{ ++ void *owner; ++ unsigned int num_cl_desc; ++ CL_DESC *cl_desc_tbl; ++ M_CL_CONFIG *m_cl_blk_config; ++ NET_POOL *net_pool; ++ CL_POOL_ID clPoolId; ++ ++} CPMAC_NET_MEM_INFO_T; ++ ++#endif ++ ++typedef struct ++{ ++ void *owner; ++ CPMAC_HAL_ISR_FUNC_T hal_isr; ++ struct tasklet_struct tasklet; ++ int intr; ++ ++} CPMAC_ISR_INFO_T; ++ ++typedef struct cpmac_chan ++{ ++ int num_BD; ++ int buffer_size; ++ int buffer_offset; ++ int service_max; ++ int state; ++ int tot_buf_size; ++ int tot_reserve_bytes; ++ ++} CPMAC_CHAN_T; ++ ++#define CHAN_CLOSE 0 ++#define CHAN_OPENED 1 ++ ++typedef struct ++{ ++ int cfg_chan; ++ int dev_chan; ++ int opened_chan; ++ CPMAC_CHAN_T chan[1]; ++ int enable_802_1q; ++ ++} CPMAC_RX_CHAN_INFO_T; ++ ++typedef struct ++{ ++ int cfg_chan; ++ int dev_chan; ++ int opened_chan; ++ int tx_int_disable; ++ CPMAC_CHAN_T chan[MAX_TX_CHAN]; ++ ++} CPMAC_TX_CHAN_INFO_T; ++ ++ ++ ++typedef struct ++{ ++ void *owner; ++ HAL_FUNCTIONS *hal_funcs; ++ HAL_DEVICE *hal_dev; ++ OS_FUNCTIONS *os_funcs; ++// SEM_ID chan_teardown_sem; ++ int non_data_irq_expected; ++} CPMAC_DRV_HAL_INFO_T; ++ ++ ++typedef struct ++{ ++ unsigned long tx_discards; ++ unsigned long rx_discards; ++ unsigned long start_tick; ++ ++} CPMAC_DRV_STATS_T; ++ ++typedef struct ++{ ++ unsigned long ifInGoodFrames; ++ unsigned long ifInBroadcasts; ++ unsigned long ifInMulticasts; ++ unsigned long ifInPauseFrames; ++ unsigned long ifInCRCErrors; ++ unsigned long ifInAlignCodeErrors; ++ unsigned long ifInOversizedFrames; ++ unsigned long ifInJabberFrames; ++ unsigned long ifInUndersizedFrames; ++ unsigned long ifInFragments; ++ unsigned long ifInFilteredFrames; ++ unsigned long ifInQosFilteredFrames; ++ unsigned long ifInOctets; ++ unsigned long ifOutGoodFrames; ++ unsigned long ifOutBroadcasts; ++ unsigned long ifOutMulticasts; ++ unsigned long ifOutPauseFrames; ++ unsigned long ifDeferredTransmissions; ++ unsigned long ifCollisionFrames; ++ unsigned long ifSingleCollisionFrames; ++ unsigned long ifMultipleCollisionFrames; ++ unsigned long ifExcessiveCollisionFrames; ++ unsigned long ifLateCollisions; ++ unsigned long ifOutUnderrun; ++ unsigned long ifCarrierSenseErrors; ++ unsigned long ifOutOctets; ++ unsigned long if64OctetFrames; ++ unsigned long if65To127OctetFrames; ++ unsigned long if128To255OctetFrames; ++ unsigned long if256To511OctetFrames; ++ unsigned long if512To1023OctetFrames; ++ unsigned long if1024ToUPOctetFrames; ++ unsigned long ifNetOctets; ++ unsigned long ifRxSofOverruns; ++ unsigned long ifRxMofOverruns; ++ unsigned long ifRxDMAOverruns; ++ ++} CPMAC_DEVICE_MIB_T; ++ ++ ++typedef struct ++{ ++ void *owner; ++ int timer_count; ++ int timer_created; ++ struct timer_list timer[1]; ++ CPMAC_DRV_HAL_INFO_T *drv_hal; ++ unsigned int num_of_intr; ++ CPMAC_ISR_INFO_T cpmac_isr; ++ unsigned int link_speed; ++ unsigned int link_mode; ++ unsigned int enable_802_1q; ++ unsigned int timer_access_hal; ++ unsigned int loop_back; ++ CPMAC_RX_CHAN_INFO_T *rx_chan_info; ++ CPMAC_TX_CHAN_INFO_T *tx_chan_info; ++ CPMAC_ABILITY_INFO_T *ability_info; ++ CPMAC_DEVICE_MIB_T *device_mib; ++ CPMAC_DRV_STATS_T *stats; ++ unsigned int flags; ++ unsigned int delay_ticks; ++ char mac_addr[6]; ++ struct net_device_stats net_dev_stats; ++// rwlock_t rw_lock; ++ int set_to_close; ++ struct net_device *next_device; ++ unsigned int instance_num; ++ unsigned int non_data_irq_expected; ++ unsigned long dev_size; ++ void* led_handle; ++} CPMAC_PRIVATE_INFO_T; ++ ++ ++/* Private flags */ ++ ++/* bit 0 to 31, bit 32 is used to indicate set or reset */ ++ ++#define IFF_PRIV_SHORT_FRAMES 0x00010000 ++#define IFF_PRIV_JUMBO_FRAMES 0x00020000 ++#define IFF_PRIV_AUTOSPEED 0x00080000 ++#define IFF_PRIV_LINK10_HD 0x00100000 ++#define IFF_PRIV_LINK10_FD 0x00200000 ++#define IFF_PRIV_LINK100_HD 0x00400000 ++#define IFF_PRIV_LINK100_FD 0x00800000 ++#define IFF_PRIV_8021Q_EN 0x01000000 ++#define IFF_PRIV_NUM_TX_CHAN 0x02000000 ++#define IFF_PRIV_TX_FLOW_CNTL 0x04000000 ++#define IFF_PRIV_RX_FLOW_CNTL 0x08000000 ++#define IFF_PRIV_TX_PACING 0x10000000 ++#define IFF_PRIV_RX_PASS_CRC 0x20000000 ++ ++#define PRIVCSFLAGS 0x200 ++#define PRIVCGFLAGS 0x201 ++ ++ ++#define BLOCKING 1 ++#define CHAN_TEARDOWN 2 ++#define CHAN_SETUP 4 ++#define COMPLETE 8 ++#define FREE_BUFFER 16 ++ ++ ++static const char pszStats0[] = "Stats0"; ++static const char pszStats1[] = "Stats1"; ++static const char pszStats2[] = "Stats2"; ++static const char pszStats3[] = "Stats3"; ++static const char pszStats4[] = "Stats4"; ++static const char pszStatsDump[] = "StatsDump"; ++static const char pszStatsClear[] = "StatsClear"; ++static const char pszRX_PASS_CRC[] = "RX_PASS_CRC"; ++static const char pszRX_QOS_EN[] = "RX_QOS_EN"; ++static const char pszRX_NO_CHAIN[] = "RX_NO_CHAIN"; ++static const char pszRX_CMF_EN[] = "RX_CMF_EN"; ++static const char pszRX_CSF_EN[] = "RX_CSF_EN"; ++static const char pszRX_CEF_EN[] = "RX_CEF_EN"; ++static const char pszRX_CAF_EN[] = "RX_CAF_EN"; ++static const char pszRX_PROM_CH[] = "RX_PROM_CH"; ++static const char pszRX_BROAD_EN[] = "RX_BROAD_EN"; ++static const char pszRX_BROAD_CH[] = "RX_BROAD_CH"; ++static const char pszRX_MULT_EN[] = "RX_MULT_EN"; ++static const char pszRX_MULT_CH[] = "RX_MULT_CH"; ++static const char pszTX_PTYPE[] = "TX_PTYPE"; ++static const char pszTX_PACE[] = "TX_PACE"; ++static const char pszMII_EN[] = "MII_EN"; ++static const char pszTX_FLOW_EN[] = "TX_FLOW_EN"; ++static const char pszRX_FLOW_EN[] = "RX_FLOW_EN"; ++static const char pszRX_MAXLEN[] = "RX_MAXLEN"; ++static const char pszRX_FILTERLOWTHRESH[] = "RX_FILTERLOWTHRESH"; ++static const char pszRX0_FLOWTHRESH[] = "RX0_FLOWTHRESH"; ++static const char pszRX_UNICAST_SET[] = "RX_UNICAST_SET"; ++static const char pszRX_UNICAST_CLEAR[] = "RX_UNICAST_CLEAR"; ++static const char pszMdioConnect[] = "MdioConnect"; ++static const char pszMacAddr[] = "MacAddr"; ++static const char pszTick[] = "Tick"; ++static const char pszRX_MULTICAST[] = "RX_MULTICAST"; ++static const char pszRX_MULTI_ALL[] = "RX_MULTI_ALL"; ++static const char pszRX_MULTI_SINGLE[] = "RX_MULTI_SINGLE"; ++ ++static const char pszSet[] = "Set"; ++static const char pszGet[] = "Get"; ++static const char pszClear[] = "Clear"; ++ ++ ++void *cpmac_hal_malloc_buffer(unsigned int size, void *MemBase, unsigned int MemRange, ++ HAL_DEVICE *HalDev, HAL_RECEIVEINFO *HalReceiveInfo, ++ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev); ++ ++void cpmac_hal_tear_down_complete(OS_DEVICE*, int, int); ++int cpmac_hal_control(OS_DEVICE *p_END_obj, const char *key, ++ const char *action, void *value); ++int cpmac_hal_receive(OS_DEVICE *p_END_obj, FRAGLIST *fragList, ++ unsigned int FragCount, unsigned int pkt_len, ++ HAL_RECEIVEINFO *halReceiveInfo, ++ unsigned int mode); ++int cpmac_hal_send_complete(OS_SENDINFO*); ++ ++void cpmac_hal_isr(int irq, void *p_param, struct pt_regs *p_cb_param); ++void cpmac_handle_tasklet(unsigned long data); ++ ++inline static int cpmac_ci_strcmp(const char *s1, const char *s2) ++{ ++ while(*s1 && *s2) ++ { ++ if(tolower(*s1) != tolower(*s2)) ++ break; ++ s1++; ++ s2++; ++ } ++ ++ return(tolower(*s1) - tolower(*s2)); ++} ++ ++#endif +diff -urN linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.c linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.c +--- linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.c 2005-07-12 02:48:42.044593000 +0200 +@@ -0,0 +1,492 @@ ++/****************************************************************************** ++ * FILE PURPOSE: CPMAC Net Driver HAL support Source ++ ****************************************************************************** ++ * FILE NAME: cpmacHalLx.c ++ * ++ * DESCRIPTION: CPMAC Network Device Driver Source ++ * ++ * REVISION HISTORY: ++ * ++ * Date Description Author ++ *----------------------------------------------------------------------------- ++ * 27 Nov 2002 Initial Creation Suraj S Iyer ++ * 09 Jun 2003 Updates for GA Suraj S Iyer ++ * 18 Dec 2003 Updated for 5.7 Suraj S Iyer ++ * ++ * (C) Copyright 2003, Texas Instruments, Inc ++ *******************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "cpmacHalLx.h" ++#include "cpmac.h" ++ ++/* PSP config headers */ ++#include "psp_config_parse.h" ++#include "psp_config_mgr.h" ++ ++/* debug */ ++extern int cpmac_debug_mode; ++#define dbgPrint if (cpmac_debug_mode) printk ++#define errPrint printk ++ ++char CpmacSignature[] = "Cpmac driver"; ++static unsigned long irq_flags = 0; ++OS_SETUP *p_os_setup = NULL; ++ ++extern int avalanche_request_intr_pacing(int, unsigned int, unsigned int); ++extern int avalanche_free_intr_pacing(unsigned int blk_num); ++ ++/*---------------------------------------------------------------------------- ++ * Parameter extracting functionalities. ++ *--------------------------------------------------------------------------*/ ++static int os_find_parm_u_int(void *info_ptr, const char *param, unsigned int *val) ++{ ++ int ret_val = 0; ++ ++ if((ret_val = psp_config_get_param_uint(info_ptr, param, val)) == -1) ++ { ++ dbgPrint("Error: could not locate the requested \"%s\" param.\n",param); ++ ret_val = -1; ++ } ++ ++ return(ret_val); ++} ++ ++static int os_find_parm_val(void *info_ptr, const char *param, void *val) ++{ ++ int ret_val = 0; ++ ++ if(psp_config_get_param_string(info_ptr, param, val) == -1) ++ { ++ dbgPrint("Error: could not locate the requested \"%s\" param.\n",param); ++ ret_val = -1; ++ } ++ ++ return(ret_val); ++} ++ ++static int os_find_device(int unit, const char *find_name, void *device_info) ++{ ++ int ret_val = 0; ++ ++ if(psp_config_get((char *)find_name, unit, device_info) == -1) ++ { ++ dbgPrint("Error: could not locate the requested \"%s\" param.\n", find_name); ++ ret_val = -1; ++ } ++ ++ return(ret_val); ++} ++ ++/*--------------------------------------------------------------------------- ++ * Memory related OS abstraction. ++ *--------------------------------------------------------------------------*/ ++void os_free(void *mem_ptr) ++{ ++ kfree(mem_ptr); ++} ++ ++void os_free_buffer(OS_RECEIVEINFO *osReceiveInfo, void *mem_ptr) ++{ ++ dev_kfree_skb_any(osReceiveInfo); ++} ++ ++void os_free_dev(void *mem_ptr) ++{ ++ kfree(mem_ptr); ++} ++ ++void os_free_dma_xfer(void *mem_ptr) ++{ ++ kfree(mem_ptr); ++} ++ ++static void *os_malloc(unsigned int size) ++{ ++ return(kmalloc(size, GFP_KERNEL)); ++} ++ ++static void *os_malloc_dma_xfer(unsigned int size, ++ void *mem_base, ++ unsigned int mem_range) ++{ ++ return(kmalloc(size, GFP_KERNEL)); ++} ++ ++static void *os_malloc_dev(unsigned int size) ++{ ++ return(kmalloc(size, GFP_KERNEL)); ++} ++ ++ ++/*---------------------------------------------------------------------------- ++ * CRITICAL SECTION ENABLING/DISABLING. ++ *--------------------------------------------------------------------------*/ ++static void os_critical_on(void) ++{ ++ save_and_cli(irq_flags); ++} ++ ++static void os_critical_off(void) ++{ ++ restore_flags(irq_flags); ++} ++ ++/*---------------------------------------------------------------------------- ++ * Cache related abstraction ++ *--------------------------------------------------------------------------*/ ++static void os_cache_invalidate(void *mem_ptr, int size) ++{ ++ dma_cache_inv((unsigned long)mem_ptr, size); ++} ++ ++static void os_cache_writeback(void *mem_ptr, int size) ++{ ++ dma_cache_wback_inv((unsigned long)mem_ptr, size); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Support functions. ++ *---------------------------------------------------------------------------*/ ++ ++static void hal_drv_unregister_isr(OS_DEVICE *p_dev, int intr) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; ++ intr = LNXINTNUM(intr); ++ ++ free_irq(p_isr_cb_param->intr, p_isr_cb_param); ++ ++ dbgPrint("cpmac_hal_unregister called for the intr %d for unit %x and isr_cb_param %x.\n", ++ intr, p_cpmac_priv->instance_num, (unsigned int )&p_cpmac_priv->cpmac_isr); ++} ++ ++ ++static void hal_drv_register_isr(OS_DEVICE *p_dev, ++ CPMAC_HAL_ISR_FUNC_T hal_isr, int intr) ++{ ++ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; ++ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; ++ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; ++ intr = LNXINTNUM(intr); ++ ++ dbgPrint("osRegister called for the intr %d for device %x and p_isr_cb_param %x.\n", ++ intr, (bit32u)p_dev, (bit32u)p_isr_cb_param); ++ ++ p_isr_cb_param->owner = p_drv_hal; ++ p_isr_cb_param->hal_isr = hal_isr; ++ p_isr_cb_param->intr = intr; ++ ++ tasklet_init(&p_isr_cb_param->tasklet, cpmac_handle_tasklet, (unsigned long)p_isr_cb_param); ++ dbgPrint("Success in registering irq %d for Cpmac unit# %d.\n", intr, p_cpmac_priv->instance_num); ++} ++ ++/*--------------------------------------------------------------------------- ++ * FUNCTIONS called by the CPMAC Net Device. ++ *-------------------------------------------------------------------------*/ ++static int load_os_funcs(OS_FUNCTIONS *os_func) ++{ ++ dbgPrint("os_init_module: Start\n"); ++ if( os_func == 0 ) ++ { ++ return(sizeof(OS_FUNCTIONS)); ++ } ++ ++ os_func->Control = cpmac_hal_control; ++ os_func->CriticalOn = os_critical_on; ++ os_func->CriticalOff = os_critical_off; ++ os_func->DataCacheHitInvalidate = os_cache_invalidate; ++ os_func->DataCacheHitWriteback = os_cache_writeback; ++ os_func->DeviceFindInfo = os_find_device; ++ os_func->DeviceFindParmUint = os_find_parm_u_int; ++ os_func->DeviceFindParmValue= os_find_parm_val; ++ os_func->Free = os_free; ++ os_func->FreeRxBuffer = os_free_buffer; ++ os_func->FreeDev = os_free_dev; ++ os_func->FreeDmaXfer = os_free_dma_xfer; ++ os_func->IsrRegister = hal_drv_register_isr; ++ os_func->IsrUnRegister = hal_drv_unregister_isr; ++ os_func->Malloc = os_malloc; ++ os_func->MallocDev = os_malloc_dev; ++ os_func->MallocDmaXfer = os_malloc_dma_xfer; ++ os_func->MallocRxBuffer = cpmac_hal_malloc_buffer; ++ os_func->Memset = memset; ++ os_func->Printf = printk; ++ os_func->Receive = cpmac_hal_receive; ++ os_func->SendComplete = cpmac_hal_send_complete; ++ os_func->Strcmpi = cpmac_ci_strcmp; ++ os_func->TeardownComplete = cpmac_hal_tear_down_complete; ++ os_func->Strstr = strstr; ++ os_func->Strtoul = simple_strtol; ++ os_func->Sprintf = sprintf; ++ os_func->Strlen = strlen; ++ ++ dbgPrint("os_init_module: Leave\n"); ++ ++ return(0); ++} ++ ++ ++int cpmac_drv_init(CPMAC_DRV_HAL_INFO_T *p_drv_hal) ++{ ++ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; ++ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; ++ ++ return(p_hal_funcs->Init(p_hal_dev)); ++} ++ ++int cpmac_drv_cleanup(CPMAC_DRV_HAL_INFO_T *p_drv_hal) ++{ ++ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; ++ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; ++ ++ int ret_val = p_hal_funcs->Shutdown(p_hal_dev); ++ ++#if 0 ++ if(ret_val == 0) ++ kfree(p_hal_funcs); ++ else ++ ret_val = -1; ++#endif ++ ++ kfree(p_drv_hal->os_funcs); ++ ++ return (ret_val); ++} ++ ++int cpmac_drv_tx_setup(HAL_FUNCTIONS *p_hal_funcs, ++ HAL_DEVICE *p_hal_dev, ++ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info) ++{ ++ int ret_val = 0; ++ int count = 0; ++ CHANNEL_INFO chan_info; ++ ++ /* Let's setup the TX Channels. */ ++ for(count=0; count < p_tx_chan_info->cfg_chan; count++) ++ { ++ chan_info.Channel = count; ++ chan_info.Direction = DIRECTION_TX; ++ chan_info.TxNumBuffers = p_tx_chan_info->chan[count].num_BD; ++ chan_info.TxServiceMax = p_tx_chan_info->chan[count].service_max; ++ chan_info.TxNumQueues = 0; ++ ++ if((ret_val = p_hal_funcs->ChannelSetup(p_hal_dev, &chan_info, ++ NULL)) != 0) ++ { ++ errPrint("Error in opening channel %d for TX.\n", count); ++ ret_val = -1; ++ break; ++ } ++ ++ p_tx_chan_info->opened_chan++; ++ } ++ ++ return(ret_val); ++} ++ ++int cpmac_drv_rx_setup(HAL_FUNCTIONS *p_hal_funcs, ++ HAL_DEVICE *p_hal_dev, ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info) ++{ ++ int ret_val = 0; ++ CHANNEL_INFO chan_info; ++ ++ chan_info.Channel = 0; ++ chan_info.Direction = DIRECTION_RX; ++ chan_info.RxBufSize = p_rx_chan_info->chan[0].buffer_size; ++ chan_info.RxBufferOffset= p_rx_chan_info->chan[0].buffer_offset; ++ chan_info.RxNumBuffers = p_rx_chan_info->chan[0].num_BD; ++ chan_info.RxServiceMax = p_rx_chan_info->chan[0].service_max; ++ ++ if(p_hal_funcs->ChannelSetup(p_hal_dev, &chan_info, p_rx_chan_info) != 0) ++ { ++ errPrint("Error in opening channel %d for RX.\n", 0); ++ ret_val = -1; ++ } ++ ++ return(ret_val); ++} ++ ++int cpmac_drv_start(CPMAC_DRV_HAL_INFO_T *p_drv_hal, ++ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info, ++ unsigned int flags) ++{ ++ int ret_val = 0; ++ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; ++ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; ++ ++ dbgPrint("It is in cpmac_drv_start for %x.\n", (unsigned int)p_drv_hal); ++ ++ if(flags & CHAN_SETUP) ++ { ++ if(cpmac_drv_tx_setup(p_hal_funcs, p_hal_dev, ++ p_tx_chan_info)!=0) ++ { ++ errPrint("Failed to set up tx channel(s).\n"); ++ ret_val = -1; ++ } ++ else if(cpmac_drv_rx_setup(p_hal_funcs, p_hal_dev, ++ p_rx_chan_info)!=0) ++ { ++ errPrint("Failed to set up rx channel.\n"); ++ ret_val = -1; ++ } ++ else ++ { ++ ret_val = 0; ++ } ++ } ++ ++ /* Error in setting up the Channels, quit. */ ++ if((ret_val == 0) && (ret_val = p_hal_funcs->Open(p_hal_dev)) != 0) ++ { ++ errPrint("failed to open the HAL!!!.\n"); ++ ret_val = -1; ++ } ++ ++ return (ret_val); ++} /* cpmac_drv_start */ ++ ++ ++ ++int cpmac_drv_tx_teardown(HAL_FUNCTIONS *p_hal_funcs, ++ HAL_DEVICE *p_hal_dev, ++ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, ++ unsigned int flags) ++{ ++ int ret_val = 0; ++ int count = 0; ++ ++ /* Let's setup the TX Channels. */ ++ for(; p_tx_chan_info->opened_chan > 0; ++ p_tx_chan_info->opened_chan--, count++) ++ { ++ if(p_hal_funcs->ChannelTeardown(p_hal_dev, count, flags) != 0) ++ { ++ errPrint("Error in tearing down channel %d for TX.\n", count); ++ ret_val = -1; ++ break; ++ } ++ } ++ ++ return(ret_val); ++} ++ ++ ++int cpmac_drv_rx_teardown(HAL_FUNCTIONS *p_hal_funcs, ++ HAL_DEVICE *p_hal_dev, ++ unsigned int flags) ++{ ++ int ret_val = 0; ++ ++ if(p_hal_funcs->ChannelTeardown(p_hal_dev, 0, flags) != 0) ++ { ++ errPrint("Error in tearing down channel %d for RX.\n", 0); ++ ret_val = -1; ++ } ++ ++ return(ret_val); ++} ++ ++int cpmac_drv_stop(CPMAC_DRV_HAL_INFO_T *p_drv_hal, ++ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info, ++ unsigned int flags) ++{ ++ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; ++ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; ++ int ret_val = 0; ++ ++ if(flags & CHAN_TEARDOWN) ++ { ++ unsigned int chan_flags = 0; ++ ++ if(flags & FREE_BUFFER) chan_flags |= 0x4; /* full tear down */ ++ if(flags & BLOCKING) chan_flags |= 0x8; /* blocking call */ ++ ++ dbgPrint("The teardown flags are %d.\n", flags); ++ dbgPrint("The teardown chan flags are %d.\n", chan_flags); ++ ++ if(cpmac_drv_tx_teardown(p_hal_funcs, p_hal_dev, ++ p_tx_chan_info, chan_flags | 0x1) != 0) ++ { ++ ret_val = -1; ++ errPrint("The tx channel teardown failed.\n"); ++ } ++ else if(cpmac_drv_rx_teardown(p_hal_funcs, p_hal_dev, chan_flags | 0x2) != 0) ++ { ++ ret_val = -1; ++ errPrint("The rx channel teardown failed.\n"); ++ } ++ else ++ { ++ ; ++ } ++ } ++ ++ if(ret_val == 0) ++ { ++ int close_flags = 1; ++ ++ if(flags & FREE_BUFFER) close_flags = 2; ++// if(flags & COMPLETE) close_flags = 3; ++ ++ if(p_hal_funcs->Close(p_hal_dev, close_flags) != 0) ++ { ++ ret_val = -1; ++ } ++ } ++ ++ return(ret_val); ++} ++ ++int cpmac_drv_init_module(CPMAC_DRV_HAL_INFO_T *p_drv_hal, OS_DEVICE *p_os_dev, int inst) ++{ ++ int ret_val = -1; ++ int hal_func_size; ++ ++ dbgPrint("Entering the CpmacInitModule for the inst %d \n", inst); ++ ++ if((p_drv_hal->os_funcs = kmalloc(sizeof(OS_FUNCTIONS), GFP_KERNEL)) == NULL) ++ { ++ errPrint("Failed to allocate memory for OS_FUNCTIONS.\n"); ++ } ++ else if(load_os_funcs(p_drv_hal->os_funcs) != 0) ++ { ++ errPrint("Failed to load OS funcs.\n"); ++ os_free(p_drv_hal->os_funcs); ++ } ++ else if(halCpmacInitModule(&p_drv_hal->hal_dev, p_os_dev, ++ &p_drv_hal->hal_funcs, p_drv_hal->os_funcs, ++ sizeof(*p_drv_hal->os_funcs), ++ &hal_func_size, inst) != 0) ++ { ++ errPrint("halCpmacInitModule failed for inst %d \n", inst); ++ os_free(p_drv_hal->os_funcs); ++ } ++ else if(p_drv_hal->hal_funcs->Probe(p_drv_hal->hal_dev) != 0) ++ { ++ errPrint("halCpmacProbe failed for inst %d \n", inst); ++ os_free(p_drv_hal->os_funcs); ++ } ++ else ++ { ++ /* every thing went well. */ ++ ret_val = 0; ++ } ++ ++ return (ret_val); ++} +diff -urN linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.h linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.h +--- linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.h 2005-07-12 02:48:42.044593000 +0200 +@@ -0,0 +1,51 @@ ++/****************************************************************************** ++ * FILE PURPOSE: CPMAC Linux Device Driver HAL support Header ++ ****************************************************************************** ++ * FILE NAME: cpmacHalVx.h ++ * ++ * DESCRIPTION: CPMAC Linux Device Driver Header ++ * ++ * REVISION HISTORY: ++ * ++ * Date Description Author ++ *----------------------------------------------------------------------------- ++ * 27 Nov 2002 Initial Creation Suraj S Iyer ++ * 09 Jun 2003 Updates for GA Suraj S Iyer ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __CPMAC_HAL_LX_H ++#define __CPMAC_HAL_LX_H ++ ++ ++typedef struct net_device OS_DEVICE; ++typedef struct sk_buff OS_RECEIVEINFO; ++typedef struct sk_buff OS_SENDINFO; ++ ++#ifdef DEBUG ++typedef void HAL_RECEIVEINFO; ++typedef void HAL_DEVICE; ++typedef void OS_SETUP; ++#endif ++ ++#define OS_SETUP void ++#define HAL_DEVICE void ++#define HAL_RECEIVEINFO void ++ ++#define _CPHAL_CPMAC ++ ++#include "cpswhal_cpmac.h" ++#include "cpmac.h" ++ ++int cpmac_drv_start(CPMAC_DRV_HAL_INFO_T *, CPMAC_TX_CHAN_INFO_T*, ++ CPMAC_RX_CHAN_INFO_T *, unsigned int); ++int cpmac_drv_cleanup(CPMAC_DRV_HAL_INFO_T *); ++int cpmac_drv_init(CPMAC_DRV_HAL_INFO_T*); ++int cpmac_drv_close(CPMAC_DRV_HAL_INFO_T*); ++int cpmac_drv_open(CPMAC_DRV_HAL_INFO_T*); ++int cpmac_drv_init_module(CPMAC_DRV_HAL_INFO_T*, OS_DEVICE*, int); ++int cpmac_drv_stop(CPMAC_DRV_HAL_INFO_T *p_drv_hal,CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, ++ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info,unsigned int flags); ++ ++#endif +diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac_reg.h linux.dev/drivers/net/avalanche_cpmac/cpmac_reg.h +--- linux.old/drivers/net/avalanche_cpmac/cpmac_reg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpmac_reg.h 2005-07-12 02:48:42.045593000 +0200 +@@ -0,0 +1,406 @@ ++/**************************************************************************** ++ TNETD73xx Software Support ++ Copyright(c) 2000, Texas Instruments Incorporated. All Rights Reserved. ++ ++ FILE: cpmac_reg.h Register definitions for the CPMAC module ++ ++ DESCRIPTION: ++ This include file contains register definitions for the ++ CPMAC module. ++ ++ HISTORY: ++ 15Nov00 BEGR Original version written ++ 30May02 MICK Added bits for Int Vector ++ 19Sep02 MICK Added INT_ACK per Channel ++ 08Nov02 GDUN Updated to use base ++ 12Nov02 MICK Incorporated into CPHAL ++*****************************************************************************/ ++#ifndef _INC_CPMAC_REG ++#define _INC_CPMAC_REG ++ ++#ifndef MEM_PTR ++#define MEM_PTR volatile bit32u * ++#endif ++ ++/*************************************************************************** ++ * ++ * C P M A C M E M O R Y M A P ++ * ++ **************************************************************************/ ++ ++#define pCPMAC_TX_IDVER(base) ((MEM_PTR)(base+0x000)) ++#define CPMAC_TX_IDVER(base) (*pCPMAC_TX_IDVER(base)) ++#define pCPMAC_TX_CONTROL(base) ((MEM_PTR)(base+0x004)) ++#define CPMAC_TX_CONTROL(base) (*pCPMAC_TX_CONTROL(base)) ++#define pCPMAC_TX_TEARDOWN(base) ((MEM_PTR)(base+0x008)) ++#define CPMAC_TX_TEARDOWN(base) (*pCPMAC_TX_TEARDOWN(base)) ++#define pCPMAC_RX_IDVER(base) ((MEM_PTR)(base+0x010)) ++#define CPMAC_RX_IDVER(base) (*pCPMAC_RX_IDVER(base)) ++#define pCPMAC_RX_CONTROL(base) ((MEM_PTR)(base+0x014)) ++#define CPMAC_RX_CONTROL(base) (*pCPMAC_RX_CONTROL(base)) ++#define pCPMAC_RX_TEARDOWN(base) ((MEM_PTR)(base+0x018)) ++#define CPMAC_RX_TEARDOWN(base) (*pCPMAC_RX_TEARDOWN(base)) ++#define pCPMAC_RX_MBP_ENABLE(base) ((MEM_PTR)(base+0x100)) ++#define CPMAC_RX_MBP_ENABLE(base) (*pCPMAC_RX_MBP_ENABLE(base)) ++#define pCPMAC_RX_UNICAST_SET(base) ((MEM_PTR)(base+0x104)) ++#define CPMAC_RX_UNICAST_SET(base) (*pCPMAC_RX_UNICAST_SET(base)) ++#define pCPMAC_RX_UNICAST_CLEAR(base) ((MEM_PTR)(base+0x108)) ++#define CPMAC_RX_UNICAST_CLEAR(base) (*pCPMAC_RX_UNICAST_CLEAR(base)) ++#define pCPMAC_RX_MAXLEN(base) ((MEM_PTR)(base+0x10C)) ++#define CPMAC_RX_MAXLEN(base) (*pCPMAC_RX_MAXLEN(base)) ++#define pCPMAC_RX_BUFFER_OFFSET(base) ((MEM_PTR)(base+0x110)) ++#define CPMAC_RX_BUFFER_OFFSET(base) (*pCPMAC_RX_BUFFER_OFFSET(base)) ++#define pCPMAC_RX_FILTERLOWTHRESH(base) ((MEM_PTR)(base+0x114)) ++#define CPMAC_RX_FILTERLOWTHRESH(base) (*pCPMAC_RX_FILTERLOWTHRESH(base)) ++#define pCPMAC_RX0_FLOWTHRESH(base) ((MEM_PTR)(base+0x120)) ++#define CPMAC_RX0_FLOWTHRESH(base) (*pCPMAC_RX0_FLOWTHRESH(base)) ++#define pCPMAC_RX1_FLOWTHRESH(base) ((MEM_PTR)(base+0x124)) ++#define CPMAC_RX1_FLOWTHRESH(base) (*pCPMAC_RX1_FLOWTHRESH(base)) ++#define pCPMAC_RX2_FLOWTHRESH(base) ((MEM_PTR)(base+0x128)) ++#define CPMAC_RX2_FLOWTHRESH(base) (*pCPMAC_RX2_FLOWTHRESH(base)) ++#define pCPMAC_RX3_FLOWTHRESH(base) ((MEM_PTR)(base+0x12C)) ++#define CPMAC_RX3_FLOWTHRESH(base) (*pCPMAC_RX3_FLOWTHRESH(base)) ++#define pCPMAC_RX4_FLOWTHRESH(base) ((MEM_PTR)(base+0x130)) ++#define CPMAC_RX4_FLOWTHRESH(base) (*pCPMAC_RX4_FLOWTHRESH(base)) ++#define pCPMAC_RX5_FLOWTHRESH(base) ((MEM_PTR)(base+0x134)) ++#define CPMAC_RX5_FLOWTHRESH(base) (*pCPMAC_RX5_FLOWTHRESH(base)) ++#define pCPMAC_RX6_FLOWTHRESH(base) ((MEM_PTR)(base+0x138)) ++#define CPMAC_RX6_FLOWTHRESH(base) (*pCPMAC_RX6_FLOWTHRESH(base)) ++#define pCPMAC_RX7_FLOWTHRESH(base) ((MEM_PTR)(base+0x13C)) ++#define CPMAC_RX7_FLOWTHRESH(base) (*pCPMAC_RX7_FLOWTHRESH(base)) ++#define pCPMAC_RX0_FREEBUFFER(base) ((MEM_PTR)(base+0x140)) ++#define CPMAC_RX0_FREEBUFFER(base) (*pCPMAC_RX0_FREEBUFFER(base)) ++#define pCPMAC_RX1_FREEBUFFER(base) ((MEM_PTR)(base+0x144)) ++#define CPMAC_RX1_FREEBUFFER(base) (*pCPMAC_RX1_FREEBUFFER(base)) ++#define pCPMAC_RX2_FREEBUFFER(base) ((MEM_PTR)(base+0x148)) ++#define CPMAC_RX2_FREEBUFFER(base) (*pCPMAC_RX2_FREEBUFFER(base)) ++#define pCPMAC_RX3_FREEBUFFER(base) ((MEM_PTR)(base+0x14C)) ++#define CPMAC_RX3_FREEBUFFER(base) (*pCPMAC_RX3_FREEBUFFER(base)) ++#define pCPMAC_RX4_FREEBUFFER(base) ((MEM_PTR)(base+0x150)) ++#define CPMAC_RX4_FREEBUFFER(base) (*pCPMAC_RX4_FREEBUFFER(base)) ++#define pCPMAC_RX5_FREEBUFFER(base) ((MEM_PTR)(base+0x154)) ++#define CPMAC_RX5_FREEBUFFER(base) (*pCPMAC_RX5_FREEBUFFER(base)) ++#define pCPMAC_RX6_FREEBUFFER(base) ((MEM_PTR)(base+0x158)) ++#define CPMAC_RX6_FREEBUFFER(base) (*pCPMAC_RX6_FREEBUFFER(base)) ++#define pCPMAC_RX7_FREEBUFFER(base) ((MEM_PTR)(base+0x15C)) ++#define CPMAC_RX7_FREEBUFFER(base) (*pCPMAC_RX7_FREEBUFFER(base)) ++#define pCPMAC_MACCONTROL(base) ((MEM_PTR)(base+0x160)) ++#define CPMAC_MACCONTROL(base) (*pCPMAC_MACCONTROL(base)) ++#define pCPMAC_MACSTATUS(base) ((MEM_PTR)(base+0x164)) ++#define CPMAC_MACSTATUS(base) (*pCPMAC_MACSTATUS(base)) ++#define pCPMAC_EMCONTROL(base) ((MEM_PTR)(base+0x168)) ++#define CPMAC_EMCONTROL(base) (*pCPMAC_EMCONTROL(base)) ++#define pCPMAC_TX_INTSTAT_RAW(base) ((MEM_PTR)(base+0x170)) ++#define CPMAC_TX_INTSTAT_RAW(base) (*pCPMAC_TX_INTSTAT_RAW(base)) ++#define pCPMAC_TX_INTSTAT_MASKED(base) ((MEM_PTR)(base+0x174)) ++#define CPMAC_TX_INTSTAT_MASKED(base) (*pCPMAC_TX_INTSTAT_MASKED(base)) ++#define pCPMAC_TX_INTMASK_SET(base) ((MEM_PTR)(base+0x178)) ++#define CPMAC_TX_INTMASK_SET(base) (*pCPMAC_TX_INTMASK_SET(base)) ++#define pCPMAC_TX_INTMASK_CLEAR(base) ((MEM_PTR)(base+0x17C)) ++#define CPMAC_TX_INTMASK_CLEAR(base) (*pCPMAC_TX_INTMASK_CLEAR(base)) ++#define pCPMAC_MAC_IN_VECTOR(base) ((MEM_PTR)(base+0x180)) ++#define CPMAC_MAC_IN_VECTOR(base) (*pCPMAC_MAC_IN_VECTOR(base)) ++#define pCPMAC_MAC_EOI_VECTOR(base) ((MEM_PTR)(base+0x184)) ++#define CPMAC_MAC_EOI_VECTOR(base) (*pCPMAC_MAC_EOI_VECTOR(base)) ++#define pCPMAC_RX_INTSTAT_RAW(base) ((MEM_PTR)(base+0x190)) ++#define CPMAC_RX_INTSTAT_RAW(base) (*pCPMAC_RX_INTSTAT_RAW(base)) ++#define pCPMAC_RX_INTSTAT_MASKED(base) ((MEM_PTR)(base+0x194)) ++#define CPMAC_RX_INTSTAT_MASKED(base) (*pCPMAC_RX_INTSTAT_MASKED(base)) ++#define pCPMAC_RX_INTMASK_SET(base) ((MEM_PTR)(base+0x198)) ++#define CPMAC_RX_INTMASK_SET(base) (*pCPMAC_RX_INTMASK_SET(base)) ++#define pCPMAC_RX_INTMASK_CLEAR(base) ((MEM_PTR)(base+0x19C)) ++#define CPMAC_RX_INTMASK_CLEAR(base) (*pCPMAC_RX_INTMASK_CLEAR(base)) ++#define pCPMAC_MAC_INTSTAT_RAW(base) ((MEM_PTR)(base+0x1A0)) ++#define CPMAC_MAC_INTSTAT_RAW(base) (*pCPMAC_MAC_INTSTAT_RAW(base)) ++#define pCPMAC_MAC_INTSTAT_MASKED(base) ((MEM_PTR)(base+0x1A4)) ++#define CPMAC_MAC_INTSTAT_MASKED(base) (*pCPMAC_MAC_INTSTAT_MASKED(base)) ++#define pCPMAC_MAC_INTMASK_SET(base) ((MEM_PTR)(base+0x1A8)) ++#define CPMAC_MAC_INTMASK_SET(base) (*pCPMAC_MAC_INTMASK_SET(base)) ++#define pCPMAC_MAC_INTMASK_CLEAR(base) ((MEM_PTR)(base+0x1AC)) ++#define CPMAC_MAC_INTMASK_CLEAR(base) (*pCPMAC_MAC_INTMASK_CLEAR(base)) ++#define pCPMAC_MACADDRLO_0(base) ((MEM_PTR)(base+0x1B0)) ++#define CPMAC_MACADDRLO_0(base) (*pCPMAC_MACADDRLO_0(base)) ++#define pCPMAC_MACADDRLO_1(base) ((MEM_PTR)(base+0x1B4)) ++#define CPMAC_MACADDRLO_1(base) (*pCPMAC_MACADDRLO_1(base)) ++#define pCPMAC_MACADDRLO_2(base) ((MEM_PTR)(base+0x1B8)) ++#define CPMAC_MACADDRLO_2(base) (*pCPMAC_MACADDRLO_2(base)) ++#define pCPMAC_MACADDRLO_3(base) ((MEM_PTR)(base+0x1BC)) ++#define CPMAC_MACADDRLO_3(base) (*pCPMAC_MACADDRLO_3(base)) ++#define pCPMAC_MACADDRLO_4(base) ((MEM_PTR)(base+0x1C0)) ++#define CPMAC_MACADDRLO_4(base) (*pCPMAC_MACADDRLO_4(base)) ++#define pCPMAC_MACADDRLO_5(base) ((MEM_PTR)(base+0x1C4)) ++#define CPMAC_MACADDRLO_5(base) (*pCPMAC_MACADDRLO_5(base)) ++#define pCPMAC_MACADDRLO_6(base) ((MEM_PTR)(base+0x1C8)) ++#define CPMAC_MACADDRLO_6(base) (*pCPMAC_MACADDRLO_6(base)) ++#define pCPMAC_MACADDRLO_7(base) ((MEM_PTR)(base+0x1CC)) ++#define CPMAC_MACADDRLO_7(base) (*pCPMAC_MACADDRLO_7(base)) ++#define pCPMAC_MACADDRMID(base) ((MEM_PTR)(base+0x1D0)) ++#define CPMAC_MACADDRMID(base) (*pCPMAC_MACADDRMID(base)) ++#define pCPMAC_MACADDRHI(base) ((MEM_PTR)(base+0x1D4)) ++#define CPMAC_MACADDRHI(base) (*pCPMAC_MACADDRHI(base)) ++#define pCPMAC_MACHASH1(base) ((MEM_PTR)(base+0x1D8)) ++#define CPMAC_MACHASH1(base) (*pCPMAC_MACHASH1(base)) ++#define pCPMAC_MACHASH2(base) ((MEM_PTR)(base+0x1DC)) ++#define CPMAC_MACHASH2(base) (*pCPMAC_MACHASH2(base)) ++#define pCPMAC_BOFFTEST(base) ((MEM_PTR)(base+0x1E0)) ++#define CPMAC_BOFFTEST(base) (*pCPMAC_BOFFTEST(base)) ++#define pCPMAC_PACTEST(base) ((MEM_PTR)(base+0x1E4)) ++#define CPMAC_PACTEST(base) (*pCPMAC_PACTEST(base)) ++#define pCPMAC_RXPAUSE(base) ((MEM_PTR)(base+0x1E8)) ++#define CPMAC_RXPAUSE(base) (*pCPMAC_RXPAUSE(base)) ++#define pCPMAC_TXPAUSE(base) ((MEM_PTR)(base+0x1EC)) ++#define CPMAC_TXPAUSE(base) (*pCPMAC_TXPAUSE(base)) ++/* STATISTICS */ ++#define pCPMAC_RXGOODFRAMES(base) ((MEM_PTR)(base+0x200)) ++#define CPMAC_RXGOODFRAMES(base) (*pCPMAC_RXGOODFRAMES(base)) ++#define pCPMAC_RXBROADCASTFRAMES(base) ((MEM_PTR)(base+0x204)) ++#define CPMAC_RXBROADCASTFRAMES(base) (*pCPMAC_RXBROADCASTFRAMES(base)) ++#define pCPMAC_RXMULTICASTFRAMES(base) ((MEM_PTR)(base+0x208)) ++#define CPMAC_RXMULTICASTFRAMES(base) (*pCPMAC_RXMULTICASTFRAMES(base)) ++#define pCPMAC_RXPAUSEFRAMES(base) ((MEM_PTR)(base+0x20C)) ++#define CPMAC_RXPAUSEFRAMES(base) (*pCPMAC_RXPAUSEFRAMES(base)) ++#define pCPMAC_RXCRCERRORS(base) ((MEM_PTR)(base+0x210)) ++#define CPMAC_RXCRCERRORS(base) (*pCPMAC_RXCRCERRORS(base)) ++#define pCPMAC_RXALIGNCODEERRORS(base) ((MEM_PTR)(base+0x214)) ++#define CPMAC_RXALIGNCODEERRORS(base) (*pCPMAC_RXALIGNCODEERRORS(base)) ++#define pCPMAC_RXOVERSIZEDFRAMES(base) ((MEM_PTR)(base+0x218)) ++#define CPMAC_RXOVERSIZEDFRAMES(base) (*pCPMAC_RXOVERSIZEDFRAMES(base)) ++#define pCPMAC_RXJABBERFRAMES(base) ((MEM_PTR)(base+0x21C)) ++#define CPMAC_RXJABBERFRAMES(base) (*pCPMAC_RXJABBERFRAMES(base)) ++#define pCPMAC_RXUNDERSIZEDFRAMES(base) ((MEM_PTR)(base+0x220)) ++#define CPMAC_RXUNDERSIZEDFRAMES(base) (*pCPMAC_RXUNDERSIZEDFRAMES(base)) ++#define pCPMAC_RXFRAGMENTS(base) ((MEM_PTR)(base+0x224)) ++#define CPMAC_RXFRAGMENTS(base) (*pCPMAC_RXFRAGMENTS(base)) ++#define pCPMAC_RXFILTEREDFRAMES(base) ((MEM_PTR)(base+0x228)) ++#define CPMAC_RXFILTEREDFRAMES(base) (*pCPMAC_RXFILTEREDFRAMES(base)) ++#define pCPMAC_RXQOSFILTEREDFRAMES(base) ((MEM_PTR)(base+0x22C)) ++#define CPMAC_RXQOSFILTEREDFRAMES(base) (*pCPMAC_RXQOSFILTEREDFRAMES(base)) ++#define pCPMAC_RXOCTETS(base) ((MEM_PTR)(base+0x230)) ++#define CPMAC_RXOCTETS(base) (*pCPMAC_RXOCTETS(base)) ++#define pCPMAC_TXGOODFRAMES(base) ((MEM_PTR)(base+0x234)) ++#define CPMAC_TXGOODFRAMES(base) (*pCPMAC_TXGOODFRAMES(base)) ++#define pCPMAC_TXBROADCASTFRAMES(base) ((MEM_PTR)(base+0x238)) ++#define CPMAC_TXBROADCASTFRAMES(base) (*pCPMAC_TXBROADCASTFRAMES(base)) ++#define pCPMAC_TXMULTICASTFRAMES(base) ((MEM_PTR)(base+0x23C)) ++#define CPMAC_TXMULTICASTFRAMES(base) (*pCPMAC_TXMULTICASTFRAMES(base)) ++#define pCPMAC_TXPAUSEFRAMES(base) ((MEM_PTR)(base+0x240)) ++#define CPMAC_TXPAUSEFRAMES(base) (*pCPMAC_TXPAUSEFRAMES(base)) ++#define pCPMAC_TXDEFERREDFRAMES(base) ((MEM_PTR)(base+0x244)) ++#define CPMAC_TXDEFERREDFRAMES(base) (*pCPMAC_TXDEFERREDFRAMES(base)) ++#define pCPMAC_TXCOLLISIONFRAMES(base) ((MEM_PTR)(base+0x248)) ++#define CPMAC_TXCOLLISIONFRAMES(base) (*pCPMAC_TXCOLLISIONFRAMES(base)) ++#define pCPMAC_TXSINGLECOLLFRAMES(base) ((MEM_PTR)(base+0x24C)) ++#define CPMAC_TXSINGLECOLLFRAMES(base) (*pCPMAC_TXSINGLECOLLFRAMES(base)) ++#define pCPMAC_TXMULTCOLLFRAMES(base) ((MEM_PTR)(base+0x250)) ++#define CPMAC_TXMULTCOLLFRAMES(base) (*pCPMAC_TXMULTCOLLFRAMES(base)) ++#define pCPMAC_TXEXCESSIVECOLLISIONS(base) ((MEM_PTR)(base+0x254)) ++#define CPMAC_TXEXCESSIVECOLLISIONS(base) (*pCPMAC_TXEXCESSIVECOLLISIONS(base)) ++#define pCPMAC_TXLATECOLLISIONS(base) ((MEM_PTR)(base+0x258)) ++#define CPMAC_TXLATECOLLISIONS(base) (*pCPMAC_TXLATECOLLISIONS(base)) ++#define pCPMAC_TXUNDERRUN(base) ((MEM_PTR)(base+0x25C)) ++#define CPMAC_TXUNDERRUN(base) (*pCPMAC_TXUNDERRUN(base)) ++#define pCPMAC_TXCARRIERSENSEERRORS(base) ((MEM_PTR)(base+0x260)) ++#define CPMAC_TXCARRIERSENSEERRORS(base) (*pCPMAC_TXCARRIERSENSEERRORS(base)) ++#define pCPMAC_TXOCTETS(base) ((MEM_PTR)(base+0x264)) ++#define CPMAC_TXOCTETS(base) (*pCPMAC_TXOCTETS(base)) ++#define pCPMAC_64OCTETFRAMES(base) ((MEM_PTR)(base+0x268)) ++#define CPMAC_64OCTETFRAMES(base) (*pCPMAC_64OCTETFRAMES(base)) ++#define pCPMAC_65T127OCTETFRAMES(base) ((MEM_PTR)(base+0x26C)) ++#define CPMAC_65T127OCTETFRAMES(base) (*pCPMAC_65T127OCTETFRAMES(base)) ++#define pCPMAC_128T255OCTETFRAMES(base) ((MEM_PTR)(base+0x270)) ++#define CPMAC_128T255OCTETFRAMES(base) (*pCPMAC_128T255OCTETFRAMES(base)) ++#define pCPMAC_256T511OCTETFRAMES(base) ((MEM_PTR)(base+0x274)) ++#define CPMAC_256T511OCTETFRAMES(base) (*pCPMAC_256T511OCTETFRAMES(base)) ++#define pCPMAC_512T1023OCTETFRAMES(base) ((MEM_PTR)(base+0x278)) ++#define CPMAC_512T1023OCTETFRAMES(base) (*pCPMAC_512T1023OCTETFRAMES(base)) ++#define pCPMAC_1024TUPOCTETFRAMES(base) ((MEM_PTR)(base+0x27C)) ++#define CPMAC_1024TUPOCTETFRAMES(base) (*pCPMAC_1024TUPOCTETFRAMES(base)) ++#define pCPMAC_NETOCTETS(base) ((MEM_PTR)(base+0x280)) ++#define CPMAC_NETOCTETS(base) (*pCPMAC_NETOCTETS(base)) ++#define pCPMAC_RXSOFOVERRUNS(base) ((MEM_PTR)(base+0x284)) ++#define CPMAC_RXSOFOVERRUNS(base) (*pCPMAC_RXSOFOVERRUNS(base)) ++#define pCPMAC_RXMOFOVERRUNS(base) ((MEM_PTR)(base+0x288)) ++#define CPMAC_RXMOFOVERRUNS(base) (*pCPMAC_RXMOFOVERRUNS(base)) ++#define pCPMAC_RXDMAOVERRUNS(base) ((MEM_PTR)(base+0x28C)) ++#define CPMAC_RXDMAOVERRUNS(base) (*pCPMAC_RXDMAOVERRUNS(base)) ++ ++#define CPMAC_TX_HDP(base,ch) (*(MEM_PTR)(base+0x600+(4*ch))) ++#define pCPMAC_TX0_HDP(base) ((MEM_PTR)(base+0x600)) ++#define CPMAC_TX0_HDP(base) (*pCPMAC_TX0_HDP(base)) ++#define pCPMAC_TX1_HDP(base) ((MEM_PTR)(base+0x604)) ++#define CPMAC_TX1_HDP(base) (*pCPMAC_TX1_HDP(base)) ++#define pCPMAC_TX2_HDP(base) ((MEM_PTR)(base+0x608)) ++#define CPMAC_TX2_HDP(base) (*pCPMAC_TX2_HDP(base)) ++#define pCPMAC_TX3_HDP(base) ((MEM_PTR)(base+0x60C)) ++#define CPMAC_TX3_HDP(base) (*pCPMAC_TX3_HDP(base)) ++#define pCPMAC_TX4_HDP(base) ((MEM_PTR)(base+0x610)) ++#define CPMAC_TX4_HDP(base) (*pCPMAC_TX4_HDP(base)) ++#define pCPMAC_TX5_HDP(base) ((MEM_PTR)(base+0x614)) ++#define CPMAC_TX5_HDP(base) (*pCPMAC_TX5_HDP(base)) ++#define pCPMAC_TX6_HDP(base) ((MEM_PTR)(base+0x618)) ++#define CPMAC_TX6_HDP(base) (*pCPMAC_TX6_HDP(base)) ++#define pCPMAC_TX7_HDP(base) ((MEM_PTR)(base+0x61C)) ++#define CPMAC_TX7_HDP(base) (*pCPMAC_TX7_HDP(base)) ++#define CPMAC_RX_HDP(base,ch) (*(MEM_PTR)(base+0x620+(4*ch))) ++#define pCPMAC_RX0_HDP(base) ((MEM_PTR)(base+0x620)) ++#define CPMAC_RX0_HDP(base) (*pCPMAC_RX0_HDP(base)) ++#define pCPMAC_RX1_HDP(base) ((MEM_PTR)(base+0x624)) ++#define CPMAC_RX1_HDP(base) (*pCPMAC_RX1_HDP(base)) ++#define pCPMAC_RX2_HDP(base) ((MEM_PTR)(base+0x628)) ++#define CPMAC_RX2_HDP(base) (*pCPMAC_RX2_HDP(base)) ++#define pCPMAC_RX3_HDP(base) ((MEM_PTR)(base+0x62C)) ++#define CPMAC_RX3_HDP(base) (*pCPMAC_RX3_HDP(base)) ++#define pCPMAC_RX4_HDP(base) ((MEM_PTR)(base+0x630)) ++#define CPMAC_RX4_HDP(base) (*pCPMAC_RX4_HDP(base)) ++#define pCPMAC_RX5_HDP(base) ((MEM_PTR)(base+0x634)) ++#define CPMAC_RX5_HDP(base) (*pCPMAC_RX5_HDP(base)) ++#define pCPMAC_RX6_HDP(base) ((MEM_PTR)(base+0x638)) ++#define CPMAC_RX6_HDP(base) (*pCPMAC_RX6_HDP(base)) ++#define pCPMAC_RX7_HDP(base) ((MEM_PTR)(base+0x63C)) ++#define CPMAC_RX7_HDP(base) (*pCPMAC_RX7_HDP(base)) ++ ++ ++#define CPMAC_TX_INT_ACK(base,ch) (*(MEM_PTR)(base+0x640+(4*ch))) ++ ++#define pCPMAC_TX0_INT_ACK(base) ((MEM_PTR)(base+0x640)) ++#define CPMAC_TX0_INT_ACK(base) (*pCPMAC_TX0_INT_ACK(base)) ++#define pCPMAC_TX1_INT_ACK(base) ((MEM_PTR)(base+0x644)) ++#define CPMAC_TX1_INT_ACK(base) (*pCPMAC_TX1_INT_ACK(base)) ++#define pCPMAC_TX2_INT_ACK(base) ((MEM_PTR)(base+0x648)) ++#define CPMAC_TX2_INT_ACK(base) (*pCPMAC_TX2_INT_ACK(base)) ++#define pCPMAC_TX3_INT_ACK(base) ((MEM_PTR)(base+0x64C)) ++#define CPMAC_TX3_INT_ACK(base) (*pCPMAC_TX3_INT_ACK(base)) ++#define pCPMAC_TX4_INT_ACK(base) ((MEM_PTR)(base+0x650)) ++#define CPMAC_TX4_INT_ACK(base) (*pCPMAC_TX4_INT_ACK(base)) ++#define pCPMAC_TX5_INT_ACK(base) ((MEM_PTR)(base+0x654)) ++#define CPMAC_TX5_INT_ACK(base) (*pCPMAC_TX5_INT_ACK(base)) ++#define pCPMAC_TX6_INT_ACK(base) ((MEM_PTR)(base+0x658)) ++#define CPMAC_TX6_INT_ACK(base) (*pCPMAC_TX6_INT_ACK(base)) ++#define pCPMAC_TX7_INT_ACK(base) ((MEM_PTR)(base+0x65C)) ++#define CPMAC_TX7_INT_ACK(base) (*pCPMAC_TX7_INT_ACK(base)) ++#define CPMAC_RX_INT_ACK(base,ch) (*(MEM_PTR)(base+0x660+(4*ch))) ++ ++#define pCPMAC_RX0_INT_ACK(base) ((MEM_PTR)(base+0x660)) ++#define CPMAC_RX0_INT_ACK(base) (*pCPMAC_RX0_INT_ACK(base)) ++#define pCPMAC_RX1_INT_ACK(base) ((MEM_PTR)(base+0x664)) ++#define CPMAC_RX1_INT_ACK(base) (*pCPMAC_RX1_INT_ACK(base)) ++#define pCPMAC_RX2_INT_ACK(base) ((MEM_PTR)(base+0x668)) ++#define CPMAC_RX2_INT_ACK(base) (*pCPMAC_RX2_INT_ACK(base)) ++#define pCPMAC_RX3_INT_ACK(base) ((MEM_PTR)(base+0x66C)) ++#define CPMAC_RX3_INT_ACK(base) (*pCPMAC_RX3_INT_ACK(base)) ++#define pCPMAC_RX4_INT_ACK(base) ((MEM_PTR)(base+0x670)) ++#define CPMAC_RX4_INT_ACK(base) (*pCPMAC_RX4_INT_ACK(base)) ++#define pCPMAC_RX5_INT_ACK(base) ((MEM_PTR)(base+0x674)) ++#define CPMAC_RX5_INT_ACK(base) (*pCPMAC_RX5_INT_ACK(base)) ++#define pCPMAC_RX6_INT_ACK(base) ((MEM_PTR)(base+0x678)) ++#define CPMAC_RX6_INT_ACK(base) (*pCPMAC_RX6_INT_ACK(base)) ++#define pCPMAC_RX7_INT_ACK(base) ((MEM_PTR)(base+0x67C)) ++#define CPMAC_RX7_INT_ACK(base) (*pCPMAC_RX7_INT_ACK(base)) ++ ++/****************************************************************************/ ++/* */ ++/* R E G I S T E R B I T D E F I N I T I O N S */ ++/* */ ++/****************************************************************************/ ++ ++/* TX_CONTROL */ ++ ++#define TX_EN (1 << 0) ++ ++/* RX_CONTROL */ ++ ++#define RX_EN (1 << 0) ++ ++/* RX_MBP_ENABLE */ ++ ++#define RX_PASS_CRC (1 << 30) ++#define RX_QOS_EN (1 << 29) ++#define RX_NO_CHAIN (1 << 28) ++ ++#define RX_CMF_EN (1 << 24) ++#define RX_CSF_EN (1 << 23) ++#define RX_CEF_EN (1 << 22) ++#define RX_CAF_EN (1 << 21) ++ ++#define RX_PROM_CH(n) (n << 16) ++#define RX_PROM_CH_MASK RX_PROM_CH(7) ++#define RX_PROM_CH_7 RX_PROM_CH(7) ++#define RX_PROM_CH_6 RX_PROM_CH(6) ++#define RX_PROM_CH_5 RX_PROM_CH(5) ++#define RX_PROM_CH_4 RX_PROM_CH(4) ++#define RX_PROM_CH_3 RX_PROM_CH(3) ++#define RX_PROM_CH_2 RX_PROM_CH(2) ++#define RX_PROM_CH_1 RX_PROM_CH(1) ++#define RX_PROM_CH_0 RX_PROM_CH(0) ++ ++#define RX_BROAD_EN (1 << 13) ++ ++#define RX_BROAD_CH(n) (n << 8) ++#define RX_BROAD_CH_MASK RX_BROAD_CH(7) ++#define RX_BROAD_CH_7 RX_BROAD_CH(7) ++#define RX_BROAD_CH_6 RX_BROAD_CH(6) ++#define RX_BROAD_CH_5 RX_BROAD_CH(5) ++#define RX_BROAD_CH_4 RX_BROAD_CH(4) ++#define RX_BROAD_CH_3 RX_BROAD_CH(3) ++#define RX_BROAD_CH_2 RX_BROAD_CH(2) ++#define RX_BROAD_CH_1 RX_BROAD_CH(1) ++#define RX_BROAD_CH_0 RX_BROAD_CH(0) ++ ++#define RX_MULT_EN (1 << 5) ++ ++#define RX_MULT_CH(n) (n << 0) ++#define RX_MULT_CH_MASK RX_MULT_CH(7) ++#define RX_MULT_CH_7 RX_MULT_CH(7) ++#define RX_MULT_CH_6 RX_MULT_CH(6) ++#define RX_MULT_CH_5 RX_MULT_CH(5) ++#define RX_MULT_CH_4 RX_MULT_CH(4) ++#define RX_MULT_CH_3 RX_MULT_CH(3) ++#define RX_MULT_CH_2 RX_MULT_CH(2) ++#define RX_MULT_CH_1 RX_MULT_CH(1) ++#define RX_MULT_CH_0 RX_MULT_CH(0) ++ ++ ++ ++/* RX_UNICAST_SET */ ++ ++#define RX_CH7_EN (1 << 7) ++#define RX_CH6_EN (1 << 6) ++#define RX_CH5_EN (1 << 5) ++#define RX_CH4_EN (1 << 4) ++#define RX_CH3_EN (1 << 3) ++#define RX_CH2_EN (1 << 2) ++#define RX_CH1_EN (1 << 1) ++#define RX_CH0_EN (1 << 0) ++ ++ ++ ++/* MAC control */ ++#define TX_PTYPE (1 << 9) ++#define TX_PACE (1 << 6) ++#define MII_EN (1 << 5) ++#define TX_FLOW_EN (1 << 4) ++#define RX_FLOW_EN (1 << 3) ++#define MTEST (1 << 2) ++#define CTRL_LOOPBACK (1 << 1) ++#define FULLDUPLEX (1 << 0) ++ ++ ++/* IntVec definitions */ ++#define MAC_IN_VECTOR_STATUS_INT (1 << 19) ++#define MAC_IN_VECTOR_HOST_INT (1 << 18) ++#define MAC_IN_VECTOR_RX_INT_OR (1 << 17) ++#define MAC_IN_VECTOR_TX_INT_OR (1 << 16) ++#define MAC_IN_VECTOR_RX_INT_VEC (7 << 8) ++#define MAC_IN_VECTOR_TX_INT_VEC (7) ++ ++ ++/* MacStatus */ ++ ++#define TX_HOST_ERR_CODE (0xF << 20) ++#define TX_ERR_CH (0x7 << 16) ++#define RX_HOST_ERR_CODE (0xF << 12) ++#define RX_ERR_CH (0x7 << 8) ++#define RX_QOS_ACT (1 << 2) ++#define RX_FLOW_ACT (1 << 1) ++#define TX_FLOW_ACT (1 << 0) ++#endif _INC_CPMAC_REG +diff -urN linux.old/drivers/net/avalanche_cpmac/cpmdio.c linux.dev/drivers/net/avalanche_cpmac/cpmdio.c +--- linux.old/drivers/net/avalanche_cpmac/cpmdio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpmdio.c 2005-07-12 02:48:42.046593000 +0200 +@@ -0,0 +1,960 @@ ++/*************************************************************************** ++** TNETD53xx Software Support ++** Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved. ++** ++** FILE: cpmdio.c ++** ++** DESCRIPTION: ++** MDIO Polling State Machine API. Functions will enable mii-Phy ++** negotiation. ++** ++** HISTORY: ++** 01Jan01 Denis, Bill Original ++** 27Mar02 Michael Hanrahan (modified from emacmdio.c) ++** 07May02 Michael Hanrahan replaced clockwait for code delay ++** 10Jul02 Michael Hanrahan more debug, if fallback link is selected ++*****************************************************************************/ ++#define __CPHAL_CPMDIO ++ ++#include "mdio_reg.h" ++ ++#ifdef _CPHAL_CPMAC ++#define mdioPrintf PhyDev->HalDev->OsFunc->Printf ++#else ++#define mdioPrintf printf ++#endif ++ ++typedef struct _phy_device ++{ ++ bit32u miibase; ++ bit32u inst; ++ bit32u PhyState; ++ bit32u MdixMask; ++ bit32u PhyMask; ++ bit32u MLinkMask; ++ bit32u PhyMode; ++#ifdef _CPHAL_CPMAC ++ HAL_DEVICE *HalDev; ++#endif ++} _PHY_DEVICE; ++ ++static void _mdioDelayEmulate(PHY_DEVICE *PhyDev, int ClockWait); ++static void _mdioWaitForAccessComplete(PHY_DEVICE *PhyDev); ++static void _mdioUserAccess(PHY_DEVICE *PhyDev, bit32u method, bit32u regadr, bit32u phyadr, bit32u data); ++static bit32u _mdioUserAccessRead(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr); ++static void _mdioUserAccessWrite(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr, bit32u data); ++ ++static void _mdioDisablePhy(PHY_DEVICE *PhyDev,bit32u PhyNum); ++static void _mdioPhyTimeOut(PHY_DEVICE *PhyDev); ++static void _mdioResetPhy(PHY_DEVICE *PhyDev,bit32u PhyNum); ++ ++static void _mdioDumpPhy(PHY_DEVICE *PhyDev, bit32u p); ++static void _mdioDumpState(PHY_DEVICE *PhyDev); ++ ++/* Auto Mdix */ ++static void _mdioMdixDelay(PHY_DEVICE *PhyDev); ++static int _mdioMdixSupported(PHY_DEVICE *PhyDev); ++ ++static void _MdioDefaultState (PHY_DEVICE *PhyDev); ++static void _MdioFindingState (PHY_DEVICE *PhyDev); ++static void _MdioFoundState (PHY_DEVICE *PhyDev); ++static void _MdioInitState (PHY_DEVICE *PhyDev); ++static void _MdioLinkedState (PHY_DEVICE *PhyDev); ++static void _MdioLinkWaitState (PHY_DEVICE *PhyDev); ++static void _MdioLoopbackState (PHY_DEVICE *PhyDev); ++static void _MdioNwayStartState(PHY_DEVICE *PhyDev); ++static void _MdioNwayWaitState (PHY_DEVICE *PhyDev); ++ ++ ++ ++#ifndef TRUE ++#define TRUE (1==1) ++#endif ++ ++#ifndef FALSE ++#define FALSE (1==2) ++#endif ++ ++#define PHY_NOT_FOUND 0xFFFF /* Used in Phy Detection */ ++ ++/*PhyState breakout */ ++ ++#define PHY_DEV_OFFSET (0) ++#define PHY_DEV_SIZE (5) /* 5 Bits used */ ++#define PHY_DEV_MASK (0x1f<miibase) ++#define myMDIO_CONTROL MDIO_CONTROL (PhyDev->miibase) ++#define myMDIO_LINK MDIO_LINK (PhyDev->miibase) ++#define myMDIO_LINKINT MDIO_LINKINT (PhyDev->miibase) ++#define myMDIO_USERACCESS MDIO_USERACCESS(PhyDev->miibase, PhyDev->inst) ++#define myMDIO_USERPHYSEL MDIO_USERPHYSEL(PhyDev->miibase, PhyDev->inst) ++#define myMDIO_VER MDIO_VER (PhyDev->miibase) ++ ++#ifndef VOLATILE32 ++#define VOLATILE32(addr) (*((volatile bit32u *)(addr))) ++#endif ++ ++/************************************ ++*** ++*** Delays at least ClockWait cylces ++*** before returning ++*** ++**************************************/ ++void _mdioDelayEmulate(PHY_DEVICE *PhyDev, int ClockWait) ++ { ++#ifdef _CPHAL_CPMAC /*+RC3.02*/ ++ HAL_DEVICE *HalDev = PhyDev->HalDev; /*+RC3.02*/ ++ osfuncSleep((int*)&ClockWait); /*+RC3.02*/ ++#else /*+RC3.02*/ ++ volatile bit32u i=0; ++ while(ClockWait--) ++ { ++ i |= myMDIO_LINK; /* MDIO register access to burn cycles */ ++ } ++#endif ++ } ++ ++void _mdioWaitForAccessComplete(PHY_DEVICE *PhyDev) ++ { ++ while((myMDIO_USERACCESS & MDIO_USERACCESS_GO)!=0) ++ { ++ } ++ } ++ ++void _mdioUserAccess(PHY_DEVICE *PhyDev, bit32u method, bit32u regadr, bit32u phyadr, bit32u data) ++ { ++ bit32u control; ++ ++ control = MDIO_USERACCESS_GO | ++ (method) | ++ (((regadr) << 21) & MDIO_USERACCESS_REGADR) | ++ (((phyadr) << 16) & MDIO_USERACCESS_PHYADR) | ++ ((data) & MDIO_USERACCESS_DATA); ++ ++ myMDIO_USERACCESS = control; ++ } ++ ++ ++ ++/************************************ ++*** ++*** Waits for MDIO_USERACCESS to be ready and reads data ++*** If 'WaitForData' set, waits for read to complete and returns Data, ++*** otherwise returns 0 ++*** Note: 'data' is 16 bits but we use 32 bits ++*** to be consistent with rest of the code. ++*** ++**************************************/ ++bit32u _mdioUserAccessRead(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr) ++ { ++ ++ _mdioWaitForAccessComplete(PhyDev); /* Wait until UserAccess ready */ ++ _mdioUserAccess(PhyDev, MDIO_USERACCESS_READ, regadr, phyadr, 0); ++ _mdioWaitForAccessComplete(PhyDev); /* Wait for Read to complete */ ++ ++ return(myMDIO_USERACCESS & MDIO_USERACCESS_DATA); ++ } ++ ++ ++/************************************ ++*** ++*** Waits for MDIO_USERACCESS to be ready and writes data ++*** ++**************************************/ ++void _mdioUserAccessWrite(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr, bit32u data) ++ { ++ _mdioWaitForAccessComplete(PhyDev); /* Wait until UserAccess ready */ ++ _mdioUserAccess(PhyDev, MDIO_USERACCESS_WRITE, regadr, phyadr, data); ++ } ++ ++void _mdioDumpPhyDetailed(PHY_DEVICE *PhyDev) ++{ ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u PhyNum; ++ int RegData; ++ ++ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ ++ RegData = _mdioUserAccessRead(PhyDev, 0, PhyNum); ++ mdioPrintf("PhyControl: %04X, Lookback=%s, Speed=%s, Duplex=%s\n", ++ RegData, ++ RegData&PHY_LOOP?"On":"Off", ++ RegData&PHY_100?"100":"10", ++ RegData&PHY_FD?"Full":"Half"); ++ RegData = _mdioUserAccessRead(PhyDev, 1, PhyNum); ++ mdioPrintf("PhyStatus: %04X, AutoNeg=%s, Link=%s\n", ++ RegData, ++ RegData&NWAY_COMPLETE?"Complete":"NotComplete", ++ RegData&PHY_LINKED?"Up":"Down"); ++ RegData = _mdioUserAccessRead(PhyDev, 4, PhyNum); ++ mdioPrintf("PhyMyCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n", ++ RegData, ++ RegData&NWAY_FD100?"Yes":"No", ++ RegData&NWAY_HD100?"Yes":"No", ++ RegData&NWAY_FD10?"Yes":"No", ++ RegData&NWAY_HD10?"Yes":"No"); ++ ++ RegData = _mdioUserAccessRead(PhyDev, 5, PhyNum); ++ mdioPrintf("PhyPartnerCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n", ++ RegData, ++ RegData&NWAY_FD100?"Yes":"No", ++ RegData&NWAY_HD100?"Yes":"No", ++ RegData&NWAY_FD10?"Yes":"No", ++ RegData&NWAY_HD10?"Yes":"No"); ++} ++void _mdioDumpPhy(PHY_DEVICE *PhyDev, bit32u p) ++ { ++ bit32u j,n,PhyAcks; ++ bit32u PhyRegAddr; ++ bit32u phy_num; ++ bit32u PhyMask = PhyDev->PhyMask; ++ ++ PhyAcks=myMDIO_ALIVE; ++ PhyAcks&=PhyMask; /* Only interested in 'our' Phys */ ++ ++ for(phy_num=0,j=1;phy_num<32;phy_num++,j<<=1) ++ { ++ if (PhyAcks&j) ++ { ++ mdioPrintf("%2d%s:",phy_num,(phy_num==p)?">":" "); ++ for(PhyRegAddr=0;PhyRegAddr<6;PhyRegAddr++) ++ { ++ n = _mdioUserAccessRead(PhyDev, PhyRegAddr, phy_num); ++ mdioPrintf(" %04x",n&0x0ffff); ++ } ++ mdioPrintf("\n"); ++ } ++ } ++ _mdioDumpPhyDetailed(PhyDev); ++ } ++ ++void _mdioDumpState(PHY_DEVICE *PhyDev) ++ { ++ bit32u state = PhyDev->PhyState; ++ ++ if (!cpMacDebug) return; ++ ++ mdioPrintf("Phy: %d, ",(state&PHY_DEV_MASK)>>PHY_DEV_OFFSET); ++ mdioPrintf("State: %d/%s, ",(state&PHY_STATE_MASK)>>PHY_STATE_OFFSET,lstate[(state&PHY_STATE_MASK)>>PHY_STATE_OFFSET]); ++ mdioPrintf("Speed: %d, ",(state&PHY_SPEED_MASK)>>PHY_SPEED_OFFSET); ++ mdioPrintf("Dup: %d, ",(state&PHY_DUPLEX_MASK)>>PHY_DUPLEX_OFFSET); ++ mdioPrintf("Tim: %d, ",(state&PHY_TIM_MASK)>>PHY_TIM_OFFSET); ++ mdioPrintf("SMode: %d, ",(state&PHY_SMODE_MASK)>>PHY_SMODE_OFFSET); ++ mdioPrintf("Chng: %d",(state&PHY_CHNG_MASK)>>PHY_CHNG_OFFSET); ++ mdioPrintf("\n"); ++ ++ if (((state&PHY_STATE_MASK)!=FINDING)&&((state&PHY_STATE_MASK)!=INIT)) ++ _mdioDumpPhy(PhyDev, (state&PHY_DEV_MASK)>>PHY_DEV_OFFSET); ++ } ++ ++ ++void _mdioResetPhy(PHY_DEVICE *PhyDev,bit32u PhyNum) ++ { ++ bit16u PhyControlReg; ++ ++ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_RESET); ++ if (cpMacDebug) ++ mdioPrintf("cpMacMdioPhYReset(%d)\n",PhyNum); ++ ++ /* Read control register until Phy Reset is complete */ ++ do ++ { ++ PhyControlReg = _mdioUserAccessRead(PhyDev, PHY_CONTROL_REG, PhyNum); ++ } ++ while (PhyControlReg & PHY_RESET); /* Wait for Reset to clear */ ++ } ++ ++void _mdioDisablePhy(PHY_DEVICE *PhyDev,bit32u PhyNum) ++ { ++ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_ISOLATE|PHY_PDOWN); ++ ++ if (cpMacDebug) ++ mdioPrintf("cpMacMdioDisablePhy(%d)\n",PhyNum); ++ ++ } ++ ++void _MdioInitState(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u CurrentState; ++ ++ CurrentState=*PhyState; ++ CurrentState=(CurrentState&~PHY_TIM_MASK)|(PHY_FIND_TO); ++ CurrentState=(CurrentState&~PHY_STATE_MASK)|(FINDING); ++ CurrentState=(CurrentState&~PHY_SPEED_MASK); ++ CurrentState=(CurrentState&~PHY_DUPLEX_MASK); ++ CurrentState|=PHY_CHANGE; ++ ++ *PhyState=CurrentState; ++ ++ } ++ ++void _MdioFindingState(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u PhyMask = PhyDev->PhyMask; ++ bit32u PhyNum,i,j,PhyAcks; ++ ++ ++ PhyNum=PHY_NOT_FOUND; ++ ++ if (*PhyState&PHY_TIM_MASK) ++ { ++ *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<PhyState; ++ bit32u PhyMask = PhyDev->PhyMask; ++ bit32u MLinkMask = PhyDev->MLinkMask; ++ bit32u PhyNum,PhyStatus,NWAYadvertise,m,phynum,i,j,PhyAcks; ++ bit32u PhySel; ++ ++ if ((*PhyState&PHY_SMODE_MASK)==0) return; ++ ++ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ ++ PhyAcks=myMDIO_ALIVE; ++ PhyAcks&=PhyMask; /* Only interested in 'our' Phys */ ++ ++ /* Will now isolate all our Phys, except the one we have decided to use */ ++ for(phynum=0,j=1;phynum<32;phynum++,j<<=1) ++ { ++ if (PhyAcks&j) ++ { ++ if (phynum!=PhyNum) /* Do not disabled Found Phy */ ++ _mdioDisablePhy(PhyDev,phynum); ++ } ++ } ++ ++ /* Reset the Phy and proceed with auto-negotiation */ ++ _mdioResetPhy(PhyDev,PhyNum); ++ ++ /* Now setup the MDIOUserPhySel register */ ++ ++ PhySel=PhyNum; /* Set the phy address */ ++ ++ /* Set the way Link will be Monitored */ ++ /* Check the Link Selection Method */ ++ if ((1 << PhyNum) & MLinkMask) ++ PhySel |= MDIO_USERPHYSEL_LINKSEL; ++ ++ myMDIO_USERPHYSEL = PhySel; /* update PHYSEL */ ++ ++ /* Get the Phy Status */ ++ PhyStatus = _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); ++ ++ ++#ifdef _CPHAL_CPMAC ++ /* For Phy Internal loopback test, need to wait until Phy ++ found, then set Loopback */ ++ if (PhyDev->HalDev->MdioConnect & _CPMDIO_LOOPBK) ++ { ++ /* Set Phy in Loopback */ ++ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_LOOP|PHY_FD); ++ /* Do a read to ensure PHY_LOOP has completed */ ++ _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); ++ *PhyState=(*PhyState&~PHY_STATE_MASK)|(LOOPBACK); ++ *PhyState|=PHY_CHANGE; ++ return; ++ } ++#endif ++ ++ ++ if (cpMacDebug) ++ mdioPrintf("Enable Phy to negotiate external connection\n"); ++ ++ NWAYadvertise=NWAY_SEL; ++ if (*PhyState&SMODE_FD100) NWAYadvertise|=NWAY_FD100; ++ if (*PhyState&SMODE_HD100) NWAYadvertise|=NWAY_HD100; ++ if (*PhyState&SMODE_FD10) NWAYadvertise|=NWAY_FD10; ++ if (*PhyState&SMODE_HD10) NWAYadvertise|=NWAY_HD10; ++ ++ *PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK); ++ if ((PhyStatus&NWAY_CAPABLE)&&(*PhyState&SMODE_AUTO)) /*NWAY Phy Detected*/ ++ { ++ /*For NWAY compliant Phys */ ++ ++ _mdioUserAccessWrite(PhyDev, NWAY_ADVERTIZE_REG, PhyNum, NWAYadvertise); ++ ++ if (cpMacDebug) ++ { ++ mdioPrintf("NWAY Advertising: "); ++ if (NWAYadvertise&NWAY_FD100) mdioPrintf("FullDuplex-100 "); ++ if (NWAYadvertise&NWAY_HD100) mdioPrintf("HalfDuplex-100 "); ++ if (NWAYadvertise&NWAY_FD10) mdioPrintf("FullDuplex-10 "); ++ if (NWAYadvertise&NWAY_HD10) mdioPrintf("HalfDuplex-10 "); ++ mdioPrintf("\n"); ++ } ++ ++ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN); ++ ++ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN|RENEGOTIATE); ++ ++ *PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START; ++ } ++ else ++ { ++ *PhyState&=~SMODE_AUTO; /*The Phy is not capable of auto negotiation! */ ++ m=NWAYadvertise; ++ for(j=0x8000,i=0;(i<16)&&((j&m)==0);i++,j>>=1); ++ m=j; ++ j=0; ++ if (m&(NWAY_FD100|NWAY_HD100)) ++ { ++ j=PHY_100; ++ m&=(NWAY_FD100|NWAY_HD100); ++ } ++ if (m&(NWAY_FD100|NWAY_FD10)) ++ j |= PHY_FD; ++ if (cpMacDebug) ++ mdioPrintf("Requested PHY mode %s Duplex %s Mbps\n",(j&PHY_FD)?"Full":"Half",(j&PHY_100)?"100":"10"); ++ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, j); ++ *PhyState&=~PHY_SPEED_MASK; ++ if (j&PHY_100) ++ *PhyState|=(1<PhyState; ++ bit32u PhyNum,PhyMode; ++ ++ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ ++ /*Wait for Negotiation to start */ ++ ++ PhyMode=_mdioUserAccessRead(PhyDev, PHY_CONTROL_REG, PhyNum); ++ ++ if((PhyMode&RENEGOTIATE)==0) ++ { ++ _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); /*Flush pending latch bits*/ ++ *PhyState&=~(PHY_STATE_MASK|PHY_TIM_MASK); ++ *PhyState|=PHY_CHANGE|NWAY_WAIT|PHY_NWDN_TO; ++ _mdioMdixDelay(PhyDev); /* If AutoMdix add delay */ ++ } ++ else ++ { ++ if (*PhyState&PHY_TIM_MASK) ++ *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<PhyState; ++ bit32u PhyNum,PhyStatus,NWAYadvertise,NWAYREadvertise,NegMode,i,j; ++ ++ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ ++ PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); ++ ++ if (PhyStatus&NWAY_COMPLETE) ++ { ++ *PhyState|=PHY_CHANGE; ++ *PhyState&=~PHY_SPEED_MASK; ++ *PhyState&=~PHY_DUPLEX_MASK; ++ ++ NWAYadvertise =_mdioUserAccessRead(PhyDev, NWAY_ADVERTIZE_REG, PhyNum); ++ NWAYREadvertise =_mdioUserAccessRead(PhyDev, NWAY_REMADVERTISE_REG, PhyNum); ++ ++ /* Negotiated mode is we and the remote have in common */ ++ NegMode = NWAYadvertise & NWAYREadvertise; ++ ++ if (cpMacDebug) ++ { ++ mdioPrintf("Phy: %d, ",(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET); ++ mdioPrintf("NegMode %04X, NWAYadvertise %04X, NWAYREadvertise %04X\n", ++ NegMode, NWAYadvertise, NWAYREadvertise); ++ } ++ ++ /* Limit negotiation to fields below */ ++ NegMode &= (NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10); ++ ++ if (NegMode==0) ++ { ++ NegMode=(NWAY_HD100|NWAY_HD10)&NWAYadvertise; /*or 10 ?? who knows, Phy is not MII compliant*/ ++ if(cpMacDebug) ++ { ++ mdioPrintf("Mdio:WARNING: Negotiation complete but NO agreement, default is HD\n"); ++ _mdioDumpPhyDetailed(PhyDev); ++ } ++ } ++ for(j=0x8000,i=0;(i<16)&&((j&NegMode)==0);i++,j>>=1); ++ ++ ++ NegMode=j; ++ if (cpMacDebug) ++ { ++ mdioPrintf("Negotiated connection: "); ++ if (NegMode&NWAY_FD100) mdioPrintf("FullDuplex 100 Mbs\n"); ++ if (NegMode&NWAY_HD100) mdioPrintf("HalfDuplex 100 Mbs\n"); ++ if (NegMode&NWAY_FD10) mdioPrintf("FullDuplex 10 Mbs\n"); ++ if (NegMode&NWAY_HD10) mdioPrintf("HalfDuplex 10 Mbs\n"); ++ } ++ if (NegMode!=0) ++ { ++ if (PhyStatus&PHY_LINKED) ++ *PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED; ++ else ++ *PhyState=(*PhyState&~PHY_STATE_MASK)|LINK_WAIT; ++ if (NegMode&(NWAY_FD100|NWAY_HD100)) ++ *PhyState=(*PhyState&~PHY_SPEED_MASK)|(1<PhyState; ++ bit32u PhyStatus; ++ bit32u PhyNum; ++ ++ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ ++ PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); ++ ++ if (PhyStatus&PHY_LINKED) ++ { ++ *PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED; ++ *PhyState|=PHY_CHANGE; ++ } ++ else ++ { ++ if (*PhyState&PHY_TIM_MASK) ++ *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<PhyState; ++ ++ /* Indicate MDI/MDIX mode switch is needed */ ++ *PhyState|=PHY_MDIX_SWITCH; ++ ++ /* Toggle the MDIX mode indicatir */ ++ if(*PhyState & PHY_MDIX) ++ *PhyState &= ~PHY_MDIX_MASK; /* Current State is MDIX, set to MDI */ ++ else ++ *PhyState |= PHY_MDIX_MASK; /* Current State is MDI, set to MDIX */ ++ ++ /* Reset state machine to FOUND */ ++ *PhyState=(*PhyState&~PHY_STATE_MASK)|(FOUND); ++ } ++ ++void _MdioLoopbackState(PHY_DEVICE *PhyDev) ++ { ++ return; ++ } ++ ++void _MdioLinkedState(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u PhyNum = (*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ ++ if (myMDIO_LINK&(1<PhyState; ++ /*Awaiting a cpMacMdioInit call */ ++ *PhyState|=PHY_CHANGE; ++ } ++ ++ ++/*User Calls********************************************************* */ ++ ++void cpMacMdioClose(PHY_DEVICE *PhyDev, int Full) ++ { ++ } ++ ++ ++int cpMacMdioInit(PHY_DEVICE *PhyDev, bit32u miibase, bit32u inst, bit32u PhyMask, bit32u MLinkMask, bit32u MdixMask, bit32u ResetReg, bit32u ResetBit, bit32u MdioBusFreq, bit32u MdioClockFreq, int verbose, void *Info) ++ { ++ bit32u HighestChannel; ++ bit32u ControlState; ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u clkdiv; /*MJH+030328*/ ++ ++ cpMacDebug=verbose; ++ ++ PhyDev->miibase = miibase; ++ PhyDev->inst = inst; ++ PhyDev->PhyMask = PhyMask; ++ PhyDev->MLinkMask = MLinkMask; ++ PhyDev->MdixMask = MdixMask; ++#ifdef _CPHAL_CPMAC ++ PhyDev->HalDev = (HAL_DEVICE*) Info; ++#endif ++ ++ *PhyState &= ~PHY_MDIX_MASK; /* Set initial State to MDI */ ++ ++ /* Check that the channel supplied is within range */ ++ HighestChannel = (myMDIO_CONTROL & MDIO_CONTROL_HIGHEST_USER_CHANNEL) > 8; ++ if(inst > HighestChannel) ++ return(HighestChannel); ++ ++ /*Setup MII MDIO access regs */ ++ ++ /* Calculate the correct value for the mclkdiv */ ++ /* See PITS #14 */ ++ if (MdioClockFreq) /*MJH+030402*/ ++ clkdiv = (MdioBusFreq / MdioClockFreq) - 1; /*MJH+030402*/ ++ else /*MJH+030402*/ ++ clkdiv = 0xFF; /*MJH+030402*/ ++ ++ ControlState = MDIO_CONTROL_ENABLE; ++ ControlState |= (clkdiv & MDIO_CONTROL_CLKDIV); /*MJH+030328*/ ++ ++ /* ++ If mii is not out of reset or if the Control Register is not set correctly ++ then initalize ++ */ ++ if( !(VOLATILE32(ResetReg) & (1 << ResetBit)) || ++ ((myMDIO_CONTROL & (MDIO_CONTROL_CLKDIV | MDIO_CONTROL_ENABLE)) != ControlState) )/*GSG~030404*/ ++ { ++ /* MII not setup, Setup initial condition */ ++ VOLATILE32(ResetReg) &= ~(1 << ResetBit); ++ _mdioDelayEmulate(PhyDev, 64); ++ VOLATILE32(ResetReg) |= (1 << ResetBit); /* take mii out of reset */ ++ _mdioDelayEmulate(PhyDev, 64); ++ myMDIO_CONTROL = ControlState; /* Enable MDIO */ ++ } ++ ++ *PhyState=INIT; ++ ++ if (cpMacDebug) ++ mdioPrintf("cpMacMdioInit\n"); ++ _mdioDumpState(PhyDev); ++ return(0); ++ } ++ ++void cpMacMdioSetPhyMode(PHY_DEVICE *PhyDev,bit32u PhyMode) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u CurrentState; ++ ++ PhyDev->PhyMode = PhyMode; /* used for AUTOMIDX, planned to replace PhyState fields */ ++ ++ *PhyState&=~PHY_SMODE_MASK; ++ ++ if (PhyMode&NWAY_AUTO) *PhyState|=SMODE_AUTO; ++ if (PhyMode&NWAY_FD100) *PhyState|=SMODE_FD100; ++ if (PhyMode&NWAY_HD100) *PhyState|=SMODE_HD100; ++ if (PhyMode&NWAY_FD10) *PhyState|=SMODE_FD10; ++ if (PhyMode&NWAY_HD10) *PhyState|=SMODE_HD10; ++ ++ CurrentState=*PhyState&PHY_STATE_MASK; ++ if ((CurrentState==NWAY_START)|| ++ (CurrentState==NWAY_WAIT) || ++ (CurrentState==LINK_WAIT) || ++ (CurrentState==LINKED) ) ++ *PhyState=(*PhyState&~PHY_STATE_MASK)|FOUND|PHY_CHANGE; ++ if (cpMacDebug) ++ mdioPrintf("cpMacMdioSetPhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode, ++ PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100, ++ PhyMode&NWAY_HD100); ++ _mdioDumpState(PhyDev); ++ } ++ ++/* cpMacMdioTic is called every 10 mili seconds to process Phy states */ ++ ++int cpMacMdioTic(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u CurrentState; ++ ++ /*Act on current state of the Phy */ ++ ++ CurrentState=*PhyState; ++ switch(CurrentState&PHY_STATE_MASK) ++ { ++ case INIT: _MdioInitState(PhyDev); break; ++ case FINDING: _MdioFindingState(PhyDev); break; ++ case FOUND: _MdioFoundState(PhyDev); break; ++ case NWAY_START: _MdioNwayStartState(PhyDev); break; ++ case NWAY_WAIT: _MdioNwayWaitState(PhyDev); break; ++ case LINK_WAIT: _MdioLinkWaitState(PhyDev); break; ++ case LINKED: _MdioLinkedState(PhyDev); break; ++ case LOOPBACK: _MdioLoopbackState(PhyDev); break; ++ default: _MdioDefaultState(PhyDev); break; ++ } ++ ++ /*Dump state info if a change has been detected */ ++ ++ if ((CurrentState&~PHY_TIM_MASK)!=(*PhyState&~PHY_TIM_MASK)) ++ _mdioDumpState(PhyDev); ++ ++ /* Check is MDI/MDIX mode switch is needed */ ++ if(*PhyState & PHY_MDIX_SWITCH) ++ { ++ bit32u Mdix; ++ ++ *PhyState &= ~PHY_MDIX_SWITCH; /* Clear Mdix Flip indicator */ ++ ++ if(*PhyState & PHY_MDIX) ++ Mdix = 1; ++ else ++ Mdix = 0; ++ return(_MIIMDIO_MDIXFLIP|Mdix); ++ } ++ ++ /*Return state change to user */ ++ ++ if (*PhyState&PHY_CHNG_MASK) ++ { ++ *PhyState&=~PHY_CHNG_MASK; ++ return(1); ++ } ++ else ++ return(0); ++ } ++ ++/* cpMacMdioGetDuplex is called to retrieve the Duplex info */ ++ ++int cpMacMdioGetDuplex(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ return((*PhyState&PHY_DUPLEX_MASK)?1:0); /* return 0 or a 1 */ ++ } ++ ++/* cpMacMdioGetSpeed is called to retreive the Speed info */ ++ ++int cpMacMdioGetSpeed(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ return(*PhyState&PHY_SPEED_MASK); ++ } ++ ++/* cpMacMdioGetPhyNum is called to retreive the Phy Device Adr info */ ++ ++int cpMacMdioGetPhyNum(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ return((*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET); ++ } ++ ++/* cpMacMdioGetLoopback is called to Determine if the LOOPBACK state has been reached*/ ++ ++int cpMacMdioGetLoopback(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ return((*PhyState&PHY_STATE_MASK)==LOOPBACK); ++ } ++/* cpMacMdioGetLinked is called to Determine if the LINKED state has been reached*/ ++ ++int cpMacMdioGetLinked(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ return((*PhyState&PHY_STATE_MASK)==LINKED); ++ } ++ ++void cpMacMdioLinkChange(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u PhyNum,PhyStatus; ++ ++ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ ++ if (cpMacMdioGetLinked(PhyDev)) ++ { ++ PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); ++ ++ if ((PhyStatus&PHY_LINKED)==0) ++ { ++ *PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK); ++ if (*PhyState&SMODE_AUTO) ++ { ++ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN|RENEGOTIATE); ++ *PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START; ++ } ++ else ++ { ++ *PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT; ++ } ++ } ++ } ++ } ++ ++void cpMacMdioGetVer(bit32u miibase, bit32u *ModID, bit32u *RevMaj, bit32u *RevMin) ++ { ++ bit32u Ver; ++ ++ Ver = MDIO_VER(miibase); ++ ++ *ModID = (Ver & MDIO_VER_MODID) >> 16; ++ *RevMaj = (Ver & MDIO_VER_REVMAJ) >> 8; ++ *RevMin = (Ver & MDIO_VER_REVMIN); ++ } ++ ++int cpMacMdioGetPhyDevSize(void) ++ { ++ return(sizeof(PHY_DEVICE)); ++ } ++ ++ /* returns 0 if current Phy has AutoMdix support, otherwise 0 */ ++int _mdioMdixSupported(PHY_DEVICE *PhyDev) ++ { ++ bit32u *PhyState = &PhyDev->PhyState; ++ bit32u PhyNum; ++ ++ if((PhyDev->PhyMode & NWAY_AUTOMDIX) == 0) ++ return(0); /* AutoMdix not turned on */ ++ ++ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; ++ if( ((1<MdixMask) == 0) ++ return(0); /* Phy does not support AutoMdix*/ ++ ++ return(1); ++ } ++ ++/* If current Phy has AutoMdix support add Mdix Delay to the Timer State Value */ ++void _mdioMdixDelay(PHY_DEVICE *PhyDev) ++ { ++ int Delay; ++ bit32u *PhyState = &PhyDev->PhyState; ++#ifdef _CPHAL_CPMAC ++ HAL_DEVICE *HalDev = PhyDev->HalDev; ++#endif ++ ++ if(_mdioMdixSupported(PhyDev) == 0) ++ return; /* AutoMdix not supported */ ++/* Currently only supported when used with the CPMAC */ ++#ifdef _CPHAL_CPMAC ++ /* Get the Delay value in milli-seconds and convert to ten-milli second value */ ++ Delay = cpmacRandomRange(HalDev, _AUTOMDIX_DELAY_MIN, _AUTOMDIX_DELAY_MAX); ++ Delay /= 10; ++ ++ /* Add AutoMidx Random Switch Delay to AutoMdix Link Delay */ ++ ++ Delay += (PHY_MDIX_TO>>PHY_TIM_OFFSET); ++ ++ /* Change Timeout value to AutoMdix standard */ ++ *PhyState &= ~(PHY_TIM_MASK); /* Clear current Time out value */ ++ *PhyState |= (Delay<ChData[Ch].RxNumBuffers, i; /*+GSG 030303*/ ++ ++ /* Free Rx data buffers attached to descriptors, if necessary */ ++ if (HalDev->RcbStart[Ch] != 0) /*+GSG 030303*/ ++ { /*+GSG 030303*/ ++ for(i=0;iRcbStart[Ch] + (i*rcbSize)); /*+GSG 030303*/ ++ ++ /* free the data buffer */ ++ if (rcb_ptr->DatPtr != 0) ++ { ++ ++ HalDev->OsFunc->FreeRxBuffer((void *)rcb_ptr->OsInfo, (void *)rcb_ptr->DatPtr); ++ rcb_ptr->OsInfo=0; /*MJH+030522*/ ++ rcb_ptr->DatPtr=0; /*MJH+030522*/ ++ } ++ } /*+GSG 030303*/ ++ } /*+GSG 030303*/ ++ ++ /* free up all desciptors at once */ ++ HalDev->OsFunc->FreeDmaXfer(HalDev->RcbStart[Ch]); ++ ++ /* mark buffers as freed */ ++ HalDev->RcbStart[Ch] = 0; ++ } ++ ++static void FreeTx(HAL_DEVICE *HalDev, int Ch, int Queue) ++ { ++ ++/*+GSG 030303*/ ++ ++ /* free all descriptors at once */ ++ HalDev->OsFunc->FreeDmaXfer(HalDev->TcbStart[Ch][Queue]); ++ ++ HalDev->TcbStart[Ch][Queue] = 0; ++ } ++ ++/* return of 0 means that this code executed, -1 means the interrupt was not ++ a teardown interrupt */ ++static int RxTeardownInt(HAL_DEVICE *HalDev, int Ch) ++ { ++ bit32u base = HalDev->dev_base; ++ ++ /* check to see if the interrupt is a teardown interrupt */ ++ if (((CPMAC_RX_INT_ACK( base , Ch )) & TEARDOWN_VAL) == TEARDOWN_VAL) ++ { ++ /* finish channel teardown */ ++ ++ /* Free channel resources on a FULL teardown */ ++ if (HalDev->RxTeardownPending[Ch] & FULL_TEARDOWN) ++ { ++ FreeRx(HalDev, Ch); ++ } ++ ++ /* bug fix - clear Rx channel pointers on teardown */ ++ HalDev->RcbPool[Ch] = 0; ++ HalDev->RxActQueueHead[Ch] = 0; ++ HalDev->RxActQueueCount[Ch] = 0; ++ HalDev->RxActive[Ch] = FALSE; ++ ++ /* write completion pointer */ ++ (CPMAC_RX_INT_ACK( base , Ch )) = TEARDOWN_VAL; ++ ++ /* use direction bit as a teardown pending bit! May be able to ++ use only one teardown pending integer in HalDev */ ++ ++ HalDev->RxTeardownPending[Ch] &= ~RX_TEARDOWN; ++ ++ HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0; ++ ++ HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0; ++ CPMAC_RX_INTMASK_CLEAR(HalDev->dev_base) = (1<RxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0) ++ { ++ ++ HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_RX); ++ } ++ HalDev->RxTeardownPending[Ch] = 0; ++ ++ return (EC_NO_ERRORS); ++ } ++ return (-1); ++ } ++ ++/* return of 0 means that this code executed, -1 means the interrupt was not ++ a teardown interrupt. Note: this code is always called with Queue == 0 (hi priority). */ ++static int TxTeardownInt(HAL_DEVICE *HalDev, int Ch, int Queue) ++ { ++ bit32u base = HalDev->dev_base; ++ HAL_TCB *Last, *Curr, *First; /*+GSG 030303*/ ++ int i; ++ ++ if (((CPMAC_TX_INT_ACK( base , Ch )) & TEARDOWN_VAL) == TEARDOWN_VAL) ++ { ++ /* perform all actions for both queues (+GSG 040212) */ ++ for (i=0; iChData[Ch].TxNumQueues; i++) ++ { ++ /* return outstanding buffers to OS +RC3.02*/ ++ Curr = HalDev->TxActQueueHead[Ch][i]; /*+GSG 030303*/ ++ First = Curr; /*+GSG 030303*/ ++ while (Curr) /*+GSG 030303*/ ++ { /*+GSG 030303*/ ++ /* Pop TCB(s) for packet from the stack */ /*+GSG 030303*/ ++ Last = Curr->Eop; /*+GSG 030303*/ ++ HalDev->TxActQueueHead[Ch][i] = Last->Next; /*+GSG 030303*/ ++ /*+GSG 030303*/ ++ /* return to OS */ /*+GSG 030303*/ ++ HalDev->OsFunc->SendComplete(Curr->OsInfo); /*+GSG 030303*/ ++ /*+GSG 030303*/ ++ /* Push Tcb(s) back onto the stack */ /*+GSG 030303*/ ++ Curr = Last->Next; /*+GSG 030303*/ ++ Last->Next = HalDev->TcbPool[Ch][i]; /*+GSG 030303*/ ++ HalDev->TcbPool[Ch][i] = First; /*+GSG 030303*/ ++ /*+GSG 030303*/ ++ /* set the first(SOP) pointer for the next packet */ /*+GSG 030303*/ ++ First = Curr; /*+GSG 030303*/ ++ } /*+GSG 030303*/ ++ } ++ ++ /* finish channel teardown */ ++ ++ if (HalDev->TxTeardownPending[Ch] & FULL_TEARDOWN) ++ { ++ FreeTx(HalDev, Ch, 0); ++ ++ if (HalDev->ChData[Ch].TxNumQueues == 2) ++ FreeTx(HalDev, Ch, 1); ++ } /* if FULL teardown */ ++ ++ /* perform all actions for both queues (+GSG 040212) */ ++ for (i=0; iChData[Ch].TxNumQueues; i++) ++ { ++ /* bug fix - clear Tx channel pointers on teardown */ ++ HalDev->TcbPool[Ch][i] = 0; ++ HalDev->TxActQueueHead[Ch][i] = 0; ++ HalDev->TxActQueueCount[Ch][i] = 0; ++ HalDev->TxActive[Ch][i] = FALSE; ++ } ++ ++ /* write completion pointer, only needed for the high priority queue */ ++ (CPMAC_TX_INT_ACK( base , Ch )) = TEARDOWN_VAL; ++ ++ /* no longer pending teardown */ ++ HalDev->TxTeardownPending[Ch] &= ~TX_TEARDOWN; ++ ++ HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0; ++ ++ HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0; ++ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = (1<TxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0) ++ { ++ ++ HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_TX); ++ } ++ HalDev->TxTeardownPending[Ch] = 0; ++ ++ return (EC_NO_ERRORS); ++ } ++ return (-1); ++ } ++ ++/* +GSG 030421 */ ++static void AddToRxQueue(HAL_DEVICE *HalDev, HAL_RCB *FirstRcb, HAL_RCB *LastRcb, int FragCount, int Ch) ++ { ++ if (HalDev->RxActQueueHead[Ch]==0) ++ { ++ ++ HalDev->RxActQueueHead[Ch]=FirstRcb; ++ HalDev->RxActQueueTail[Ch]=LastRcb; ++ if (!HalDev->RxActive[Ch]) ++ { ++ /* write Rx Queue Head Descriptor Pointer */ ++ ((CPMAC_RX_HDP( HalDev->dev_base , Ch )) ) = VirtToPhys(FirstRcb) - HalDev->offset; ++ HalDev->RxActive[Ch]=TRUE; ++ } ++ } ++ else ++ { ++ register HAL_RCB *OldTailRcb; ++ register bit32u rmode; ++ ++ HalDev->OsFunc->CriticalOn(); ++ OldTailRcb=HalDev->RxActQueueTail[Ch]; ++ OldTailRcb->Next=(void *)FirstRcb; ++ OldTailRcb=VirtToVirtNoCache(OldTailRcb); ++ OldTailRcb->HNext=VirtToPhys(FirstRcb) - HalDev->offset; ++ HalDev->RxActQueueTail[Ch]=LastRcb; ++ rmode=OldTailRcb->mode; ++ if (rmode&CB_EOQ_BIT) ++ { ++ rmode&=~CB_EOQ_BIT; ++ ((CPMAC_RX_HDP( HalDev->dev_base , Ch )) ) = VirtToPhys(FirstRcb) - HalDev->offset; ++ OldTailRcb->mode=rmode; ++ } ++ HalDev->OsFunc->CriticalOff(); ++ } ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function is called to indicate to the CPHAL that the upper layer ++ * software has finished processing the receive data (given to it by ++ * osReceive()). The CPHAL will then return the appropriate receive buffers ++ * and buffer descriptors to the available pool. ++ * ++ * @param HalReceiveInfo Start of receive buffer descriptor chain returned to ++ * CPHAL. ++ * @param StripFlag Flag indicating whether the upper layer software has ++ * retained ownership of the receive data buffers. ++ *
++ * 'FALSE' means that the CPHAL can reuse the receive data buffers. ++ *
++ * 'TRUE' : indicates the data buffers were retained by the OS ++ *
++ * NOTE: If StripFlag is TRUE, it is the responsibility of the upper layer software to free the buffers when they are no longer needed. ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_RCB_NEEDS_BUFFER "EC_VAL_RCB_NEEDS_BUFFER"
++ * @ref EC_VAL_RCB_DROPPED "EC_VAL_RCB_DROPPED"
++ */ ++static int halRxReturn(HAL_RECEIVEINFO *HalReceiveInfo, ++ int StripFlag) ++ { ++ int Ch, i; ++ HAL_RCB *LastRcb; ++ HAL_DEVICE *HalDev; ++ int RcbSize; ++ int FragCount; ++ ++ Ch = HalReceiveInfo->mode&0x0ff; ++ HalDev = (HAL_DEVICE *)HalReceiveInfo->Off_BLen; ++ FragCount = HalReceiveInfo->mode>>8; ++ ++ if (HalDev->State != enOpened) ++ return(EC_CPMAC |EC_FUNC_RXRETURN|EC_VAL_INVALID_STATE); ++ ++ LastRcb=(HAL_RCB *)HalReceiveInfo->Eop; ++ LastRcb->HNext=0; ++ LastRcb->Next=0; ++ RcbSize = HalDev->ChData[Ch].RxBufSize; ++ ++ if (FragCount>1) ++ { ++ LastRcb->Off_BLen=RcbSize; ++ LastRcb->mode=CB_OWNERSHIP_BIT; ++ } ++ ++ HalReceiveInfo->Off_BLen=RcbSize; ++ HalReceiveInfo->mode=CB_OWNERSHIP_BIT; ++ ++ /* If OS has kept the buffers for this packet, attempt to alloc new buffers */ ++ if (StripFlag) ++ { ++ int rc=0; /*MJH+030417*/ ++ int GoodCount=0; /*GSG+030421*/ ++ HAL_RCB *TempRcb; ++ char *pBuf; ++ HAL_RCB *CurrHeadRcb = HalReceiveInfo, *LastGoodRcb=0; /* +GSG 030421 */ ++ ++ TempRcb = HalReceiveInfo; ++ for (i=0; iEop = %08x, FragCount = %d:%d\n", ++ (bit32u)HalReceiveInfo, (bit32u)HalReceiveInfo->Eop, FragCount,i); ++ osfuncSioFlush(); ++ ++ return(EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_CORRUPT_RCB_CHAIN); ++ } ++ ++ pBuf= (char *) HalDev->OsFunc->MallocRxBuffer(RcbSize,0, ++ 0xF,HalDev->ChData[Ch].OsSetup, ++ (void *)TempRcb, ++ (void *)&TempRcb->OsInfo, ++ (void *) HalDev->OsDev); ++ if (!pBuf) ++ { ++ /* malloc failed, add this RCB to Needs Buffer List */ ++ (HAL_RCB *)TempRcb->Eop = TempRcb; /* GSG +030430 */ ++ TempRcb->mode=1<<8|Ch; ++ TempRcb->Off_BLen=(bit32u)HalDev; ++ ++ if(HalDev->NeedsCount < MAX_NEEDS) /* +MJH 030410 */ ++ { /* +MJH 030410 */ ++ HalDev->Needs[HalDev->NeedsCount] = (HAL_RECEIVEINFO *) TempRcb; /* +MJH 030410 */ ++ HalDev->NeedsCount++; /* +MJH 030410 */ ++ rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_NEEDS_BUFFER); /* ~MJH 030417 */ ++ } /* +MJH 030410 */ ++ else /* +MJH 030410 */ ++ rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_DROPPED); /* ~MJH 030417 */ ++ ++ /* requeue any previous RCB's that were ready to go before this one */ ++ if (GoodCount > 0) /* +GSG 030421 */ ++ { /* +GSG 030421 */ ++ LastGoodRcb->HNext=0; /* +GSG 030430 */ ++ LastGoodRcb->Next=0; /* +GSG 030430 */ ++ osfuncDataCacheHitWritebackAndInvalidate((void *)LastGoodRcb, 16); /* +GSG 030430 */ ++ ++ AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch); /* +GSG 030421 */ ++ GoodCount = 0; /* +GSG 030421 */ ++ } /* +GSG 030421 */ ++ ++ CurrHeadRcb = TempRcb->Next; /* +GSG 030421 */ ++ } ++ else /* +GSG 030421 */ ++ { /* +GSG 030421 */ ++ /* malloc succeeded, requeue the RCB to the hardware */ ++ TempRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset; ++ TempRcb->DatPtr=pBuf; ++ /* Emerald fix 10/29 */ ++ osfuncDataCacheHitWritebackAndInvalidate((void *)TempRcb, 16); ++ ++ /* i store the last good RCB in case the malloc fails for the ++ next fragment. This ensures that I can go ahead and return ++ a partial chain of RCB's to the hardware */ ++ LastGoodRcb = TempRcb; /* +GSG 030421 */ ++ GoodCount++; /* +GSG 030421 */ ++ } /* +GSG 030421 */ ++ TempRcb = TempRcb->Next; ++ } /* end of Frag loop */ ++ /* if there any good RCB's to requeue, do so here */ ++ if (GoodCount > 0) /* +GSG 030421 */ ++ { ++ AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch); /* +GSG 030421 */ ++ } ++ return(rc); /* ~GSG 030421 */ ++ } ++ else ++ { ++ /* Not Stripping */ ++ /* Emerald */ ++ /* Write Back SOP and last RCB */ ++ osfuncDataCacheHitWritebackAndInvalidate((void *)HalReceiveInfo, 16); ++ ++ if (FragCount > 1) ++ { ++ osfuncDataCacheHitWritebackAndInvalidate((void *)LastRcb, 16); ++ } ++ /* if not stripping buffers, always add to queue */ ++ AddToRxQueue(HalDev, HalReceiveInfo, LastRcb, FragCount, Ch); /*MJH~030520*/ ++ } ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/* +MJH 030410 ++ Trys to liberate an RCB until liberation fails. ++ Note: If liberation fails then RxReturn will re-add the RCB to the ++ Needs list. ++*/ ++static void NeedsCheck(HAL_DEVICE *HalDev) ++{ ++ HAL_RECEIVEINFO* HalRcb; ++ int rc; ++ HalDev->OsFunc->CriticalOn(); ++ while(HalDev->NeedsCount) ++ { ++ HalDev->NeedsCount--; ++ HalRcb = HalDev->Needs[HalDev->NeedsCount]; ++ rc = halRxReturn(HalRcb, 1); ++ /* short circuit if RxReturn starts to fail */ ++ if (rc != 0) ++ break; ++ } ++ HalDev->OsFunc->CriticalOff(); ++} ++ ++/* ++ * This function allocates transmit buffer descriptors (internal CPHAL function). ++ * It creates a high priority transmit queue by default for a single Tx ++ * channel. If QoS is enabled for the given CPHAL device, this function ++ * will also allocate a low priority transmit queue. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Ch Channel number. ++ * ++ * @return 0 OK, Non-Zero Not OK ++ */ ++static int InitTcb(HAL_DEVICE *HalDev, int Ch) ++ { ++ int i, Num = HalDev->ChData[Ch].TxNumBuffers; ++ HAL_TCB *pTcb=0; ++ char *AllTcb; ++ int tcbSize, Queue; ++ int SizeMalloc; ++ ++ tcbSize = (sizeof(HAL_TCB)+0xf)&~0xf; ++ SizeMalloc = (tcbSize*Num)+0xf; ++ ++ for (Queue=0; Queue < HalDev->ChData[Ch].TxNumQueues; Queue++) ++ { ++ if (HalDev->TcbStart[Ch][Queue] == 0) ++ { ++ ++ /* malloc all TCBs at once */ ++ AllTcb = (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff); ++ if (!AllTcb) ++ { ++ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_TCB_MALLOC_FAILED); ++ } ++ ++ HalDev->OsFunc->Memset(AllTcb, 0, SizeMalloc); ++ ++ /* keep this address for freeing later */ ++ HalDev->TcbStart[Ch][Queue] = AllTcb; ++ } ++ else ++ { ++ /* if the memory has already been allocated, simply reuse it! */ ++ AllTcb = HalDev->TcbStart[Ch][Queue]; ++ } ++ ++ /* align to cache line */ ++ AllTcb = (char *)(((bit32u)AllTcb + 0xf) &~ 0xf); /*PITS #143 MJH~030522*/ ++ ++ /* default High priority transmit queue */ ++ HalDev->TcbPool[Ch][Queue]=0; ++ for(i=0;iMallocDmaXfer(sizeof(HAL_TCB),0,0xffffffff); */ ++ pTcb= (HAL_TCB *)(AllTcb + (i*tcbSize)); ++ pTcb->mode=0; ++ pTcb->BufPtr=0; ++ pTcb->Next=HalDev->TcbPool[Ch][Queue]; ++ pTcb->Off_BLen=0; ++ HalDev->TcbPool[Ch][Queue]=pTcb; ++ } ++ /*HalDev->TcbEnd = pTcb;*/ ++ } ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/* ++ * This function allocates receive buffer descriptors (internal CPHAL function). ++ * After allocation, the function 'queues' (gives to the hardware) the newly ++ * created receive buffers to enable packet reception. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Ch Channel number. ++ * ++ * @return 0 OK, Non-Zero Not OK ++ */ ++static int InitRcb(HAL_DEVICE *HalDev, int Ch) ++ { ++ int i, Num = HalDev->ChData[Ch].RxNumBuffers; ++ int Size = HalDev->ChData[Ch].RxBufSize; ++ HAL_RCB *pRcb; ++ char *pBuf; ++ char *AllRcb; ++ int rcbSize; ++ int DoMalloc = 0; ++ int SizeMalloc; ++ int MallocSize; ++ ++ rcbSize = (sizeof(HAL_RCB)+0xf)&~0xf; ++ SizeMalloc = (rcbSize*Num)+0xf; ++ ++ if (HalDev->RcbStart[Ch] == 0) ++ { ++ DoMalloc = 1; ++ ++ /* malloc all RCBs at once */ ++ AllRcb= (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff); ++ if (!AllRcb) ++ { ++ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RCB_MALLOC_FAILED); ++ } ++ ++ HalDev->OsFunc->Memset(AllRcb, 0, SizeMalloc); ++ ++ /* keep this address for freeing later */ ++ HalDev->RcbStart[Ch] = AllRcb; ++ } ++ else ++ { ++ /* if the memory has already been allocated, simply reuse it! */ ++ AllRcb = HalDev->RcbStart[Ch]; ++ } ++ ++ /* align to cache line */ ++ AllRcb = (char *)(((bit32u)AllRcb + 0xf)&~0xf); /*PITS #143 MJH~030522*/ ++ ++ HalDev->RcbPool[Ch]=0; ++ for(i=0;iOsFunc->MallocRxBuffer(MallocSize,0,0xF,HalDev->ChData[Ch].OsSetup, (void *)pRcb, (void *)&pRcb->OsInfo, (void *) HalDev->OsDev); ++ if(!pBuf) ++ { ++ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RX_BUFFER_MALLOC_FAILED); ++ } ++ /* -RC3.01 pBuf = (char *)(((bit32u)pBuf+0xF) & ~0xF); */ ++ pRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset; ++ pRcb->DatPtr=pBuf; ++ } ++ pRcb->mode=(1<<8)|Ch; /* One Frag for Ch */ ++ pRcb->Next=(void *)HalDev->RcbPool[Ch]; ++ pRcb->Off_BLen=(bit32u)HalDev; ++ HalDev->RcbPool[Ch]=pRcb; ++ } ++ ++ /* Give all of the Rx buffers to hardware */ ++ ++ while(HalDev->RcbPool[Ch]) ++ { ++ pRcb=HalDev->RcbPool[Ch]; ++ HalDev->RcbPool[Ch]=pRcb->Next; ++ pRcb->Eop=(void*)pRcb; ++ pRcb->mode=(1<<8)|Ch; ++ halRxReturn((HAL_RECEIVEINFO *)pRcb, 0); ++ } ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function transmits the data in FragList using available transmit ++ * buffer descriptors. More information on the use of the Mode parameter ++ * is available in the module-specific appendices. Note: The OS should ++ * not call Send() for a channel that has been requested to be torndown. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param FragList Fragment List structure. ++ * @param FragCount Number of fragments in FragList. ++ * @param PacketSize Number of bytes to transmit. ++ * @param OsSendInfo OS Send Information structure.
++ * @param Mode 32-bit value with the following bit fields:
++ * 31-16: Mode (used for module specific data).
++ * 15-08: Queue (transmit queue to send on).
++ * 07-00: Channel (channel number to send on). ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_NOT_LINKED "EC_VAL_NOT_LINKED"
++ * @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"
++ * @ref EC_VAL_OUT_OF_TCBS "EC_VAL_OUT_OF_TCBS"
++ * @ref EC_VAL_NO_TCBS "EC_VAL_NO_TCBS"
++ */ ++static int halSend(HAL_DEVICE *HalDev,FRAGLIST *FragList, ++ int FragCount,int PacketSize, OS_SENDINFO *OsSendInfo, ++ bit32u Mode) ++ { ++ HAL_TCB *tcb_ptr, *head; ++ int i; ++ int rc = EC_NO_ERRORS; ++ int Ch = Mode & 0xFF; ++ int Queue = (Mode>>8)&0xFF; ++ /*int DoThresholdCheck=1; */ /* Used when TxIntDisable is set and TxInts are re-enabled */ ++ ++ if (HalDev->State != enOpened) ++ return(EC_CPPI|EC_FUNC_SEND|EC_VAL_INVALID_STATE); ++ ++ if (!HalDev->Linked) ++ { ++ rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_NOT_LINKED; ++ return(rc); ++ } ++ ++ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0) /*MJH~030611*/ /*PITS 148*/ ++ return(EC_CPMAC |EC_FUNC_SEND|EC_VAL_INVALID_CH); /*+GSG 030303*/ ++ ++ HalDev->OsFunc->CriticalOn(); ++ ++ /* Setup Tx mode and size */ ++ if (PacketSize<60) ++ { ++ FragList[FragCount-1].len += (60 - PacketSize); /*MJH~030506*//*PITS 132*/ ++ PacketSize = 60; /*MJH~030506*/ ++ } ++ Mode &= CB_PASSCRC_BIT; ++ ++ tcb_ptr = head = HalDev->TcbPool[Ch][Queue]; ++ ++ if (tcb_ptr) ++ { ++ ++ Mode|=PacketSize|CB_SOF_BIT|CB_OWNERSHIP_BIT; ++ ++ for (i=0; iOff_BLen = FragList[i].len; ++ ++ tcb_ptr->mode = Mode; ++ tcb_ptr->BufPtr = VirtToPhys((bit32 *)FragList[i].data) - HalDev->offset; ++ tcb_ptr->OsInfo = OsSendInfo; ++ ++ if (i == (FragCount - 1)) ++ { ++ /* last fragment */ ++ tcb_ptr->mode |= CB_EOF_BIT; ++ ++ /* since this is the last fragment, set the TcbPool pointer before ++ nulling out the Next pointers */ ++ ++ HalDev->TcbPool[Ch][Queue] = tcb_ptr->Next; ++ ++ tcb_ptr->Next = 0; ++ tcb_ptr->HNext = 0; ++ ++ /* In the Tx Interrupt handler, we will need to know which TCB is EOP, ++ so we can save that information in the SOP */ ++ head->Eop = tcb_ptr; ++ ++ /* Emerald fix 10/29 */ ++ osfuncDataCacheHitWritebackAndInvalidate((void *)tcb_ptr, 16); ++ ++ } ++ else ++ { ++ Mode=CB_OWNERSHIP_BIT; ++ tcb_ptr->HNext = VirtToPhys((bit32 *)tcb_ptr->Next) - HalDev->offset; ++ ++ /* Emerald fix 10/29 */ ++ osfuncDataCacheHitWritebackAndInvalidate((void *)tcb_ptr, 16); ++ ++ tcb_ptr = tcb_ptr->Next; /* what about the end of TCB list?? */ ++ ++ if (tcb_ptr == 0) ++ { ++ rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_OUT_OF_TCBS; ++ goto ExitSend; ++ } ++ } ++ } /* for */ ++ ++ /* put it on the high priority queue */ ++ if (HalDev->TxActQueueHead[Ch][Queue] == 0) ++ { ++ HalDev->TxActQueueHead[Ch][Queue]=head; ++ HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr; ++/*+GSG 030303*//*+GSG 030303*/ ++ if (!HalDev->TxActive[Ch][Queue]) ++ { ++ ++ bit32u base = HalDev->dev_base; ++ ++ /* write CPPI TX HDP */ ++ (CPMAC_TX_HDP( base , Ch )) = VirtToPhys(head) - HalDev->offset; ++ HalDev->TxActive[Ch][Queue]=TRUE; ++ ++ } ++ } ++ else ++ { ++ register volatile HAL_TCB *pTailTcb; ++ register bit32u tmode; ++ register bit32u pCurrentTcb; ++ ++ HalDev->TxActQueueTail[Ch][Queue]->Next=head; ++ /* Emerald fix 10/29 */ ++ ++ pTailTcb=(HAL_TCB *)VirtToVirtNoCache(&HalDev->TxActQueueTail[Ch][Queue]->HNext); ++ pCurrentTcb=VirtToPhys(head) - HalDev->offset; ++ pTailTcb->HNext=pCurrentTcb; ++ HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr; ++/*+GSG 030303*/ ++ tmode=pTailTcb->mode; ++ if (tmode&CB_EOQ_BIT) ++ { ++ bit32u base = HalDev->dev_base; ++ ++ tmode&=~CB_EOQ_BIT; ++ pTailTcb->mode=tmode; ++ ((CPMAC_TX_HDP( base , Ch )) ) = pCurrentTcb; ++ } ++ ++ else ++ { ++ if(HalDev->TxIntDisable) ++ { ++ /* Enable Interrupts, to ensure packet goes out on wire */ ++ CPMAC_TX_INTMASK_SET(HalDev->dev_base) = (1<TxIntDisable /*&& DoThresholdCheck*/) ++ { ++ if(--HalDev->TxIntThreshold[Ch] <= 0) ++ { ++ int MoreWork; ++ TxInt(HalDev, Ch, 0, &MoreWork); ++ HalDev->TxIntThreshold[Ch] = HalDev->TxIntThresholdMaster[Ch]; ++ } ++ } ++ HalDev->OsFunc->CriticalOff(); ++ ++ return(rc); ++ } ++ ++/* ++ * This function processes receive interrupts. It traverses the receive ++ * buffer queue, extracting the data and passing it to the upper layer software via ++ * osReceive(). It handles all error conditions and fragments without valid data by ++ * immediately returning the RCB's to the RCB pool. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Ch Channel Number. ++ * @param MoreWork Flag that indicates that there is more work to do when set to 1. ++ * ++ * @return 0 if OK, non-zero otherwise. ++ */ ++static int RxInt(HAL_DEVICE *HalDev, int Ch, int *MoreWork) ++ { ++ HAL_RCB *CurrentRcb, *SopRcb, *EofRcb, *EopRcb; ++ bit32u RxBufStatus,PacketsServiced, RxPktLen = 0, RxSopStatus, ++ FrmFrags, TotalFrags, FrmLen; ++ int base = HalDev->dev_base, Ret; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ int RxServiceMax = HalDev->ChData[Ch].RxServiceMax; ++ int FragIndex; /* +GSG 030508 */ ++ ++ if(HalDev->NeedsCount) /* +MJH 030410 */ ++ NeedsCheck(HalDev); /* +MJH 030410 */ ++ ++ /* Handle case of teardown interrupt */ ++ if (HalDev->RxTeardownPending[Ch] != 0) ++ { ++ Ret = RxTeardownInt(HalDev, Ch); ++ if (Ret == 0) ++ { /*+GSG 030303*/ ++ *MoreWork = 0; ++ return (EC_NO_ERRORS); ++ } /*+GSG 030303*/ ++ } ++ ++ /* Examine first RCB on the software active queue */ ++ CurrentRcb=HalDev->RxActQueueHead[Ch]; ++ osfuncDataCacheHitInvalidate((void*)CurrentRcb, 16); ++ RxBufStatus=CurrentRcb->mode; ++ PacketsServiced=0; ++ ++ /* Process received packets until we find hardware owned descriptors ++ or until we hit RxServiceMax */ ++ while((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)&& ++ (PacketsServicedOff_BLen; ++ ++ FrmLen+=DmaLen; ++ TotalFrags++; ++ if (!EofRcb) ++ { ++ HalDev->fraglist[FragIndex].data=((char *)CurrentRcb->DatPtr); /* ~GSG 030508 */ ++ ++ HalDev->fraglist[FragIndex].len=DmaLen; /* ~GSG 030508 */ ++ ++ /* GSG 12/9 */ ++ HalDev->fraglist[FragIndex].OsInfo = CurrentRcb->OsInfo; /* ~GSG 030508 */ ++ ++ /* Upper layer must do the data invalidate */ ++ ++ FrmFrags++; ++ FragIndex++; /* ~GSG 030508 */ ++ if (FrmLen>=RxPktLen) ++ EofRcb=CurrentRcb; ++ } ++ EopRcb=CurrentRcb; ++ CurrentRcb=EopRcb->Next; ++ if (CurrentRcb) ++ { ++ osfuncDataCacheHitInvalidate((void*)CurrentRcb,16); ++ } ++ }while(((EopRcb->mode&CB_EOF_BIT)==0)&&(CurrentRcb)); ++ ++ /* Write the completion pointer for interrupt acknowledgement*/ ++ (CPMAC_RX_INT_ACK( base , Ch )) = VirtToPhys(EopRcb) - HalDev->offset; ++ ++ EopRcb->Next=0; ++ ++ if (CurrentRcb == 0) ++ { ++ /* If we are out of RCB's we must not send this packet ++ to the OS. */ ++ int RcbSize = HalDev->ChData[Ch].RxBufSize; ++ ++ if (TotalFrags>1) ++ { ++ EopRcb->Off_BLen=RcbSize; ++ EopRcb->mode=CB_OWNERSHIP_BIT; ++ osfuncDataCacheHitWritebackAndInvalidate((void *)EopRcb, 16); ++ } ++ ++ SopRcb->Off_BLen=RcbSize; ++ SopRcb->mode=CB_OWNERSHIP_BIT; ++ osfuncDataCacheHitWritebackAndInvalidate((void *)SopRcb, 16); ++ ++ ((CPMAC_RX_HDP( base , Ch )) ) = VirtToPhys(SopRcb); ++ } ++ else ++ { ++ /* Dequeue packet and send to OS */ ++ int mode; ++ ++ /* setup SopRcb for the packet */ ++ SopRcb->Eop=(void*)EopRcb; ++ ++ /* dequeue packet */ ++ HalDev->RxActQueueHead[Ch]=CurrentRcb; ++ ++ if (EopRcb->mode&CB_EOQ_BIT) ++ { ++ /* Next pointer is non-null and EOQ bit is set, which ++ indicates misqueue packet in CPPI protocol. */ ++ ++ ((CPMAC_RX_HDP( base , Ch )) ) = EopRcb->HNext; ++ } ++ ++ mode = (SopRcb->mode & 0xFFFF0000) | Ch; ++ ++ SopRcb->mode=(FrmFrags<<8)|Ch; ++ SopRcb->Off_BLen=(bit32u)HalDev; ++ ++ /* send packet up the higher layer driver */ ++ OsFunc->Receive(HalDev->OsDev,HalDev->fraglist,FragIndex,RxPktLen, /* ~GSG 030508 */ ++ (HAL_RECEIVEINFO *)SopRcb,mode); ++ ++ RxBufStatus=CurrentRcb->mode; ++ } ++ } /* while loop */ ++ ++ if ((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)) /*~GSG 030307*/ ++ { ++ *MoreWork = 1; ++ } ++ else ++ { ++ *MoreWork = 0; ++ } ++ ++ return (EC_NO_ERRORS); ++} ++ ++/* ++ * This function processes transmit interrupts. It traverses the ++ * transmit buffer queue, detecting sent data buffers and notifying the upper ++ * layer software via osSendComplete(). (for SAR, i originally had this split ++ * into two functions, one for each queue, but joined them on 8/8/02) ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Queue Queue number to service (always 0 for MAC, Choose 1 for SAR to service low priority queue) ++ * @param MoreWork Flag that indicates that there is more work to do when set to 1. ++ * ++ * @return 0 if OK, non-zero otherwise. ++ */ ++int TxInt(HAL_DEVICE *HalDev, int Ch, int Queue, int *MoreWork) ++ { ++ HAL_TCB *CurrentTcb,*LastTcbProcessed,*FirstTcbProcessed; ++ int PacketsServiced; ++ bit32u TxFrameStatus; ++ int base; ++ int TxServiceMax = HalDev->ChData[Ch].TxServiceMax; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ ++/*+GSG 030303*//*+GSG 030303*/ ++ ++ /* load the module base address */ ++ base = HalDev->dev_base; ++ ++ /* Handle case of teardown interrupt. This must be checked at ++ the top of the function rather than the bottom, because ++ the normal data processing can wipe out the completion ++ pointer which is used to determine teardown complete. */ ++ if (HalDev->TxTeardownPending[Ch] != 0) ++ { ++ int Ret; ++ ++ Ret = TxTeardownInt(HalDev, Ch, Queue); ++ if (Ret == 0) ++ { /*+GSG 030303*/ ++ *MoreWork = 0; /* bug fix 1/6 */ /*+GSG 030303*/ ++ return (EC_NO_ERRORS); ++ } /*+GSG 030303*/ ++ } ++ ++ OsFunc->CriticalOn(); /* 240904 */ ++ ++ CurrentTcb = HalDev->TxActQueueHead[Ch][Queue]; ++ FirstTcbProcessed=CurrentTcb; ++ ++ if (CurrentTcb==0) ++ { ++ /* I saw this error a couple of times when multi-channels were added */ ++ dbgPrintf("[cppi TxInt()]TxH int with no TCB in queue!\n"); ++ dbgPrintf(" Ch=%d, CurrentTcb = 0x%08x\n", Ch, (bit32u)CurrentTcb); ++ dbgPrintf(" HalDev = 0x%08x\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ OsFunc->CriticalOff(); ++ return(EC_CPPI|EC_FUNC_TXINT|EC_VAL_NULL_TCB); ++ } ++ ++ osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16); ++ TxFrameStatus=CurrentTcb->mode; ++ PacketsServiced=0; ++ ++ /* should the ownership bit check be inside of the loop?? could make it a ++ while-do loop and take this check away */ ++ if ((TxFrameStatus&CB_OWNERSHIP_BIT)==0) ++ { ++ do ++ { ++ /* Pop TCB(s) for packet from the stack */ ++ LastTcbProcessed=CurrentTcb->Eop; ++ ++ /* new location for acknowledge */ ++ /* Write the completion pointer */ ++ (CPMAC_TX_INT_ACK( base , Ch )) = VirtToPhys(LastTcbProcessed) - HalDev->offset; ++ ++ HalDev->TxActQueueHead[Ch][Queue] = LastTcbProcessed->Next; ++ ++/*+GSG 030303*//*+GSG 030303*/ ++ ++ osfuncDataCacheHitInvalidate((void *)LastTcbProcessed, 16); ++ ++ if (LastTcbProcessed->mode&CB_EOQ_BIT) ++ { ++ if (LastTcbProcessed->Next) ++ { ++ /* Misqueued packet */ ++ ++ (CPMAC_TX_HDP( base , Ch )) = LastTcbProcessed->HNext; ++ ++ } ++ else ++ { ++ /* Tx End of Queue */ ++ ++ HalDev->TxActive[Ch][Queue]=FALSE; ++ } ++ } ++ ++ OsFunc->SendComplete(CurrentTcb->OsInfo); ++ ++ /* Push Tcb(s) back onto the stack */ ++ CurrentTcb = LastTcbProcessed->Next; ++ ++ LastTcbProcessed->Next=HalDev->TcbPool[Ch][Queue]; ++ ++ HalDev->TcbPool[Ch][Queue]=FirstTcbProcessed; ++ ++ PacketsServiced++; ++ ++ TxFrameStatus=CB_OWNERSHIP_BIT; ++ /* set the first(SOP) pointer for the next packet */ ++ FirstTcbProcessed = CurrentTcb; ++ if (CurrentTcb) ++ { ++ osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16); ++ TxFrameStatus=CurrentTcb->mode; ++ } ++ ++ }while(((TxFrameStatus&CB_OWNERSHIP_BIT)==0) ++ &&(PacketsServicedCriticalOff(); ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function performs a teardown for the given channel. The value of the ++ * Mode parameter controls the operation of the function, as documented below. ++ * ++ * Note: If bit 3 of Mode is set, this call is blocking, and will not return ++ * until the teardown interrupt has occurred and been processed. While waiting ++ * for a blocking teardown to complete, ChannelTeardown() will signal the OS ++ * (via Control(.."Sleep"..)) to allow the OS to perform other tasks if ++ * necessary. If and only if bit 3 of Mode is clear, the CPHAL will call the ++ * OS TeardownComplete() function to indicate that the teardown has completed. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param Ch Channel number. ++ * @param Mode Bit 0 (LSB): Perform Tx teardown (if set).
++ * Bit 1: Perform Rx teardown (if set).
++ * Bit 2: If set, perform full teardown (free buffers/descriptors). ++ * If clear, perform partial teardown (keep buffers).
++ * Bit 3 (MSB): If set, call is blocking. ++ * If clear, call is non-blocking. ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"
++ * @ref EC_VAL_TX_TEARDOWN_ALREADY_PEND "EC_VAL_TX_TEARDOWN_ALREADY_PEND"
++ * @ref EC_VAL_RX_TEARDOWN_ALREADY_PEND "EC_VAL_RX_TEARDOWN_ALREADY_PEND"
++ * @ref EC_VAL_TX_CH_ALREADY_TORNDOWN "EC_VAL_TX_CH_ALREADY_TORNDOWN"
++ * @ref EC_VAL_RX_CH_ALREADY_TORNDOWN "EC_VAL_RX_CH_ALREADY_TORNDOWN"
++ * @ref EC_VAL_TX_TEARDOWN_TIMEOUT "EC_VAL_TX_TEARDOWN_TIMEOUT"
++ * @ref EC_VAL_RX_TEARDOWN_TIMEOUT "EC_VAL_RX_TEARDOWN_TIMEOUT"
++ * @ref EC_VAL_LUT_NOT_READY "EC_VAL_LUT_NOT_READY"
++ */ ++static int halChannelTeardown(HAL_DEVICE *HalDev, int Ch, bit32 Mode) ++ { ++ int DoTx, DoRx, Sleep=2048, timeout=0; /*MJH~030306*/ ++ bit32u base = HalDev->dev_base; ++ ++/* Set the module, used for error returns */ ++ ++ DoTx = (Mode & TX_TEARDOWN); ++ DoRx = (Mode & RX_TEARDOWN); ++ ++ if (HalDev->State < enInitialized) ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_STATE); ++ ++ if ((Ch < 0) || (Ch > (MAX_CHAN-1) )) ++ { ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_CH); ++ } ++ ++ /* set teardown pending bits before performing the teardown, because they ++ will be used in the int handler (this is done for AAL5) */ ++ if (DoTx) ++ { ++ if (HalDev->TxTeardownPending[Ch] != 0) ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_ALREADY_PEND); ++ ++ /* If a full teardown, this also means that the user must ++ setup all channels again to use them */ ++ if (Mode & FULL_TEARDOWN) ++ HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0; ++ ++ if (HalDev->State < enOpened) ++ { ++ /* if the hardware has never been opened, the channel has never actually ++ been setup in the hardware, so I just need to reset the software flag ++ and leave */ ++ HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0; ++ return (EC_NO_ERRORS); ++ } ++ else ++ { ++ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0) ++ { ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_CH_ALREADY_TORNDOWN); ++ } ++ ++ /* set teardown flag */ ++ HalDev->TxTeardownPending[Ch] = Mode; ++ } ++ } ++ ++ if (DoRx) ++ { ++ if (HalDev->RxTeardownPending[Ch] != 0) ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_ALREADY_PEND); ++ ++ if (Mode & FULL_TEARDOWN) ++ HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0; ++ ++ if (HalDev->State < enOpened) ++ { ++ HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0; ++ return (EC_NO_ERRORS); ++ } ++ else ++ { ++ if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == 0) ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_CH_ALREADY_TORNDOWN); ++ ++ HalDev->RxTeardownPending[Ch] = Mode; ++ } ++ } ++ ++ /* Perform Tx Teardown Duties */ ++ if ((DoTx) && (HalDev->State == enOpened)) ++ { ++ /* Request TX channel teardown */ ++ (CPMAC_TX_TEARDOWN( base )) = Ch; ++ ++ /* wait until teardown has completed */ ++ if (Mode & BLOCKING_TEARDOWN) ++ { ++ timeout = 0; ++ while (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) ++ { ++ osfuncSleep(&Sleep); ++ ++ timeout++; ++ if (timeout > 100000) ++ { ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_TIMEOUT); ++ } ++ } ++ } ++ } /* if DoTx */ ++ ++ /* Perform Rx Teardown Duties */ ++ if ((DoRx) && (HalDev->State == enOpened)) ++ { ++ ++ /* perform CPMAC specific RX channel teardown */ ++ CPMAC_RX_TEARDOWN(base) = Ch; ++ ++ if (Mode & BLOCKING_TEARDOWN) ++ { ++ timeout = 0; ++ while (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE) ++ { ++ osfuncSleep(&Sleep); ++ ++ timeout++; ++ if (timeout > 100000) ++ { ++ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_TIMEOUT); ++ } ++ } ++ } ++ } /* if DoRx */ ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function closes the CPHAL module. The module will be reset. ++ * The Mode parameter should be used to determine the actions taken by ++ * Close(). ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param Mode Indicates actions to take on close. The following integer ++ * values are valid:
++ * 1: Does not free buffer resources, init parameters remain ++ * intact. User can then call Open() without calling Init() ++ * to attempt to reset the device and bring it back to the ++ * last known state.
++ * 2: Frees the buffer resources, but keeps init parameters. This ++ * option is a more aggressive means of attempting a device reset. ++ * 3: Frees the buffer resources, and clears all init parameters.
++ * At this point, the caller would have to call to completely ++ * reinitialize the device (Init()) before being able to call ++ * Open(). Use this mode if you are shutting down the module ++ * and do not plan to restart. ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * Any error code from halChannelTeardown().
++ */ ++static int halClose(HAL_DEVICE *HalDev, bit32 Mode) ++ { ++ int Ch, Inst, Ret; ++ OS_DEVICE *TmpOsDev; ++ OS_FUNCTIONS *TmpOsFunc; ++ HAL_FUNCTIONS *TmpHalFunc; ++ char *TmpDeviceInfo; ++ ++ int Ticks; /*MJH~030306*/ ++ ++ /* Verify proper device state */ ++ if (HalDev->State != enOpened) ++ return (EC_CPMAC | EC_FUNC_CLOSE|EC_VAL_INVALID_STATE); ++ ++ /* Teardown all open channels */ ++ for (Ch = 0; Ch <= (MAX_CHAN-1) ; Ch++) ++ { ++ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) ++ { ++ if (Mode == 1) ++ { ++ Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ else ++ { ++ Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ } ++ ++ if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE) ++ { ++ if (Mode == 1) ++ { ++ Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ else ++ { ++ Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ } ++ } ++ ++ /* free fraglist in HalDev */ ++ HalDev->OsFunc->Free(HalDev->fraglist); ++ HalDev->fraglist = 0; ++ ++ /* unregister the interrupt */ ++ HalDev->OsFunc->IsrUnRegister(HalDev->OsDev, HalDev->interrupt); ++ ++ Ticks = 0; /* Disable Tick Timer */ /*MJH+030306*/ ++ HalDev->OsFunc->Control(HalDev->OsDev, hcTick, hcClear, &Ticks); /*MJH+030306*/ ++ ++ /* Free the Phy Information Structure */ ++ if(HalDev->PhyDev) ++ { ++ HalDev->OsFunc->Free(HalDev->PhyDev); /*MJH+030513*/ ++ HalDev->PhyDev = 0; /*MJH+030522*/ ++ } ++ ++ /* Perform CPMAC specific closing functions */ ++ CPMAC_MACCONTROL(HalDev->dev_base) &= ~MII_EN; ++ CPMAC_TX_CONTROL(HalDev->dev_base) &= ~TX_EN; ++ CPMAC_RX_CONTROL(HalDev->dev_base) &= ~RX_EN; ++ ++ /* put device back into reset */ ++ (*(volatile bit32u *)(HalDev->ResetBase)) &=~ (1<ResetBit); ++ Ticks = 64; /*MJH~030306*/ ++ osfuncSleep(&Ticks); ++ ++ /* If mode is 3, than clear the HalDev and set next state to DevFound*/ ++ if (Mode == 3) ++ { ++ /* I need to keep the HalDev parameters that were setup in InitModule */ ++ TmpOsDev = HalDev->OsDev; ++ TmpOsFunc = HalDev->OsFunc; ++ TmpDeviceInfo = HalDev->DeviceInfo; ++ ++ TmpHalFunc = HalDev->HalFuncPtr; ++ Inst = HalDev->Inst; ++ ++ /* Clear HalDev */ ++ ++ HalDev->OsFunc->Memset(HalDev, 0, sizeof(HAL_DEVICE)); ++ ++ /* Restore key parameters */ ++ HalDev->OsDev = TmpOsDev; ++ HalDev->OsFunc = TmpOsFunc; ++ HalDev->DeviceInfo = TmpDeviceInfo; ++ ++ HalDev->HalFuncPtr = TmpHalFunc; ++ HalDev->Inst = Inst; ++ ++ HalDev->State = enDevFound; ++ } ++ else ++ { ++ HalDev->State = enInitialized; ++ } ++ ++ return(EC_NO_ERRORS); ++ } +diff -urN linux.old/drivers/net/avalanche_cpmac/cpremap_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpremap_cpmac.c +--- linux.old/drivers/net/avalanche_cpmac/cpremap_cpmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpremap_cpmac.c 2005-07-12 02:48:42.049593000 +0200 +@@ -0,0 +1,28 @@ ++#ifndef _INC_CPREMAP_C ++#define _INC_CPREMAP_C ++ ++#ifdef __ADAM2 ++static inline void osfuncDataCacheHitInvalidate(void *ptr, int Size) ++ { ++ asm(" cache 17, (%0)" : : "r" (ptr)); ++ } ++ ++static inline void osfuncDataCacheHitWriteback(void *ptr, int Size) ++ { ++ asm(" cache 25, (%0)" : : "r" (ptr)); ++ } ++ ++static inline void osfuncDataCacheHitWritebackAndInvalidate(void *ptr, int Size) ++ { ++ asm(" cache 21, (%0)" : : "r" (ptr)); ++ } ++ ++#else ++ ++#define osfuncDataCacheHitInvalidate(MemPtr, Size) __asm__(" .set mips3; cache 17, (%0); .set mips0" : : "r" (MemPtr)) ++#define osfuncDataCacheHitWritebackAndInvalidate(MemPtr, Size) __asm__(" .set mips3; cache 21, (%0); .set mips0" : : "r" (MemPtr)) ++#define osfuncDataCacheHitWriteback(MemPtr, Size) __asm__(" .set mips3; cache 25, (%0); .set mips0" : : "r" (MemPtr)) ++ ++#endif ++ ++#endif +diff -urN linux.old/drivers/net/avalanche_cpmac/cpswhal_cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpswhal_cpmac.h +--- linux.old/drivers/net/avalanche_cpmac/cpswhal_cpmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/cpswhal_cpmac.h 2005-07-12 02:48:42.050593000 +0200 +@@ -0,0 +1,632 @@ ++/************************************************************************ ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: cphal.h ++ * ++ * DESCRIPTION: ++ * User include file, contains data definitions shared between the CPHAL ++ * and the upper-layer software. ++ * ++ * HISTORY: ++ * Date Modifier Ver Notes ++ * 28Feb02 Greg 1.00 Original ++ * 06Mar02 Greg 1.01 Documentation enhanced ++ * 18Jul02 Greg 1.02 Many updates (OAM additions, general reorg) ++ * 22Nov02 Mick RC2 Additions from Denis' input on Control ++ * ++ * author Greg Guyotte ++ * version 1.02 ++ * date 18-Jul-2002 ++ *****************************************************************************/ ++#ifndef _INC_CPHAL_H ++#define _INC_CPHAL_H ++ ++#ifdef _CPHAL_CPMAC ++#include "ec_errors_cpmac.h" ++#endif ++ ++#ifdef _CPHAL_AAL5 ++#include "ec_errors_cpaal5.h" ++#endif ++ ++#ifdef _CPHAL_CPSAR ++#include "ec_errors_cpsar.h" ++#endif ++ ++#ifdef _CPHAL_AAL2 ++#include "ec_errors_cpaal2.h" ++#endif ++ ++#ifndef __ADAM2 ++typedef char bit8; ++typedef short bit16; ++typedef int bit32; ++ ++typedef unsigned char bit8u; ++typedef unsigned short bit16u; ++typedef unsigned int bit32u; ++ ++/* ++typedef char INT8; ++typedef short INT16; ++typedef int INT32; ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++*/ ++/*typedef unsigned int size_t;*/ ++#endif ++ ++#ifdef _CPHAL ++ ++#ifndef TRUE ++#define TRUE (1==1) ++#endif ++ ++#ifndef FALSE ++#define FALSE (1==2) ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#endif ++ ++#define VirtToPhys(a) (((int)a)&~0xe0000000) ++#define VirtToVirtNoCache(a) ((void*)((VirtToPhys(a))|0xa0000000)) ++#define VirtToVirtCache(a) ((void*)((VirtToPhys(a))|0x80000000)) ++#define PhysToVirtNoCache(a) ((void*)(((int)a)|0xa0000000)) ++#define PhysToVirtCache(a) ((void*)(((int)a)|0x80000000)) ++/* ++#define DataCacheHitInvalidate(a) {__asm__(" cache 17, (%0)" : : "r" (a));} ++#define DataCacheHitWriteback(a) {__asm__(" cache 25, (%0)" : : "r" (a));} ++*/ ++ ++#define PARTIAL 1 /**< Used in @c Close() and @c ChannelTeardown() */ ++#define FULL 2 /**< Used in @c Close() and @c ChannelTeardown() */ ++ ++/* Channel Teardown Defines */ ++#define RX_TEARDOWN 2 ++#define TX_TEARDOWN 1 ++#define BLOCKING_TEARDOWN 8 ++#define FULL_TEARDOWN 4 ++#define PARTIAL_TEARDOWN 0 ++ ++#define MAX_DIR 2 ++#define DIRECTION_TX 0 ++#define DIRECTION_RX 1 ++#define TX_CH 0 ++#define RX_CH 1 ++#define HAL_ERROR_DEVICE_NOT_FOUND 1 ++#define HAL_ERROR_FAILED_MALLOC 2 ++#define HAL_ERROR_OSFUNC_SIZE 3 ++#define HAL_DEFAULT 0xFFFFFFFF ++#define VALID(val) (val!=HAL_DEFAULT) ++ ++/* ++ERROR REPORTING ++ ++HAL Module Codes. Each HAL module reporting an error code ++should OR the error code with the respective Module error code ++from the list below. ++*/ ++#define EC_AAL5 EC_HAL|EC_DEV_AAL5 ++#define EC_AAL2 EC_HAL|EC_DEV_AAL2 ++#define EC_CPSAR EC_HAL|EC_DEV_CPSAR ++#define EC_CPMAC EC_HAL|EC_DEV_CPMAC ++#define EC_VDMA EC_HAL|EC_DEV_VDMA ++#define EC_VLYNQ EC_HAL|EC_DEV_VLYNQ ++#define EC_CPPI EC_HAL|EC_DEV_CPPI ++ ++/* ++HAL Function Codes. Each HAL module reporting an error code ++should OR the error code with one of the function codes from ++the list below. ++*/ ++#define EC_FUNC_HAL_INIT EC_FUNC(1) ++#define EC_FUNC_CHSETUP EC_FUNC(2) ++#define EC_FUNC_CHTEARDOWN EC_FUNC(3) ++#define EC_FUNC_RXRETURN EC_FUNC(4) ++#define EC_FUNC_SEND EC_FUNC(5) ++#define EC_FUNC_RXINT EC_FUNC(6) ++#define EC_FUNC_TXINT EC_FUNC(7) ++#define EC_FUNC_AAL2_VDMA EC_FUNC(8) ++#define EC_FUNC_OPTIONS EC_FUNC(9) ++#define EC_FUNC_PROBE EC_FUNC(10) ++#define EC_FUNC_OPEN EC_FUNC(11) ++#define EC_FUNC_CONTROL EC_FUNC(12) ++#define EC_FUNC_DEVICE_INT EC_FUNC(13) ++#define EC_FUNC_STATUS EC_FUNC(14) ++#define EC_FUNC_TICK EC_FUNC(15) ++#define EC_FUNC_CLOSE EC_FUNC(16) ++#define EC_FUNC_SHUTDOWN EC_FUNC(17) ++#define EC_FUNC_DEVICE_INT_ALT EC_FUNC(18) /* +GSG 030306 */ ++ ++/* ++HAL Error Codes. The list below defines every type of error ++used in all HAL modules. DO NOT CHANGE THESE VALUES! Add new ++values in integer order to the bottom of the list. ++*/ ++#define EC_VAL_PDSP_LOAD_FAIL EC_ERR(0x01)|EC_CRITICAL ++#define EC_VAL_FIRMWARE_TOO_LARGE EC_ERR(0x02)|EC_CRITICAL ++#define EC_VAL_DEVICE_NOT_FOUND EC_ERR(0x03)|EC_CRITICAL ++#define EC_VAL_BASE_ADDR_NOT_FOUND EC_ERR(0x04)|EC_CRITICAL ++#define EC_VAL_RESET_BIT_NOT_FOUND EC_ERR(0x05)|EC_CRITICAL ++#define EC_VAL_CH_INFO_NOT_FOUND EC_ERR(0x06) ++#define EC_VAL_RX_STATE_RAM_NOT_CLEARED EC_ERR(0x07)|EC_CRITICAL ++#define EC_VAL_TX_STATE_RAM_NOT_CLEARED EC_ERR(0x08)|EC_CRITICAL ++#define EC_VAL_MALLOC_DEV_FAILED EC_ERR(0x09) ++#define EC_VAL_OS_VERSION_NOT_SUPPORTED EC_ERR(0x0A)|EC_CRITICAL ++#define EC_VAL_CPSAR_VERSION_NOT_SUPPORTED EC_ERR(0x0B)|EC_CRITICAL ++#define EC_VAL_NULL_CPSAR_DEV EC_ERR(0x0C)|EC_CRITICAL ++ ++#define EC_VAL_LUT_NOT_READY EC_ERR(0x0D) ++#define EC_VAL_INVALID_CH EC_ERR(0x0E) ++#define EC_VAL_NULL_CH_STRUCT EC_ERR(0x0F) ++#define EC_VAL_RX_TEARDOWN_ALREADY_PEND EC_ERR(0x10) ++#define EC_VAL_TX_TEARDOWN_ALREADY_PEND EC_ERR(0x11) ++#define EC_VAL_RX_CH_ALREADY_TORNDOWN EC_ERR(0x12) ++#define EC_VAL_TX_CH_ALREADY_TORNDOWN EC_ERR(0x13) ++#define EC_VAL_TX_TEARDOWN_TIMEOUT EC_ERR(0x14) ++#define EC_VAL_RX_TEARDOWN_TIMEOUT EC_ERR(0x15) ++#define EC_VAL_CH_ALREADY_TORNDOWN EC_ERR(0x16) ++#define EC_VAL_VC_SETUP_NOT_READY EC_ERR(0x17) ++#define EC_VAL_VC_TEARDOWN_NOT_READY EC_ERR(0x18) ++#define EC_VAL_INVALID_VC EC_ERR(0x19) ++#define EC_VAL_INVALID_LC EC_ERR(0x20) ++#define EC_VAL_INVALID_VDMA_CH EC_ERR(0x21) ++#define EC_VAL_INVALID_CID EC_ERR(0x22) ++#define EC_VAL_INVALID_UUI EC_ERR(0x23) ++#define EC_VAL_INVALID_UUI_DISCARD EC_ERR(0x24) ++#define EC_VAL_CH_ALREADY_OPEN EC_ERR(0x25) ++ ++#define EC_VAL_RCB_MALLOC_FAILED EC_ERR(0x26) ++#define EC_VAL_RX_BUFFER_MALLOC_FAILED EC_ERR(0x27) ++#define EC_VAL_OUT_OF_TCBS EC_ERR(0x28) ++#define EC_VAL_NO_TCBS EC_ERR(0x29) ++#define EC_VAL_NULL_RCB EC_ERR(0x30)|EC_CRITICAL ++#define EC_VAL_SOP_ERROR EC_ERR(0x31)|EC_CRITICAL ++#define EC_VAL_EOP_ERROR EC_ERR(0x32)|EC_CRITICAL ++#define EC_VAL_NULL_TCB EC_ERR(0x33)|EC_CRITICAL ++#define EC_VAL_CORRUPT_RCB_CHAIN EC_ERR(0x34)|EC_CRITICAL ++#define EC_VAL_TCB_MALLOC_FAILED EC_ERR(0x35) ++ ++#define EC_VAL_DISABLE_POLLING_FAILED EC_ERR(0x36) ++#define EC_VAL_KEY_NOT_FOUND EC_ERR(0x37) ++#define EC_VAL_MALLOC_FAILED EC_ERR(0x38) ++#define EC_VAL_RESET_BASE_NOT_FOUND EC_ERR(0x39)|EC_CRITICAL ++#define EC_VAL_INVALID_STATE EC_ERR(0x40) ++#define EC_VAL_NO_TXH_WORK_TO_DO EC_ERR(0x41) ++#define EC_VAL_NO_TXL_WORK_TO_DO EC_ERR(0x42) ++#define EC_VAL_NO_RX_WORK_TO_DO EC_ERR(0x43) ++#define EC_VAL_NOT_LINKED EC_ERR(0x44) ++#define EC_VAL_INTERRUPT_NOT_FOUND EC_ERR(0x45) ++#define EC_VAL_OFFSET_NOT_FOUND EC_ERR(0x46) ++#define EC_VAL_MODULE_ALREADY_CLOSED EC_ERR(0x47) ++#define EC_VAL_MODULE_ALREADY_SHUTDOWN EC_ERR(0x48) ++#define EC_VAL_ACTION_NOT_FOUND EC_ERR(0x49) ++#define EC_VAL_RX_CH_ALREADY_SETUP EC_ERR(0x50) ++#define EC_VAL_TX_CH_ALREADY_SETUP EC_ERR(0x51) ++#define EC_VAL_RX_CH_ALREADY_OPEN EC_ERR(0x52) ++#define EC_VAL_TX_CH_ALREADY_OPEN EC_ERR(0x53) ++#define EC_VAL_CH_ALREADY_SETUP EC_ERR(0x54) ++#define EC_VAL_RCB_NEEDS_BUFFER EC_ERR(0x55) /* +GSG 030410 */ ++#define EC_VAL_RCB_DROPPED EC_ERR(0x56) /* +GSG 030410 */ ++#define EC_VAL_INVALID_VALUE EC_ERR(0x57) ++ ++/** ++@defgroup shared_data Shared Data Structures ++ ++The data structures documented here are shared by all modules. ++*/ ++ ++/** ++ * @ingroup shared_data ++ * This is the fragment list structure. Each fragment list entry contains a ++ * length and a data buffer. ++ */ ++typedef struct ++ { ++ bit32u len; /**< Length of the fragment in bytes (lower 16 bits are valid). For SOP, upper 16 bits is the buffer offset. */ ++ void *data; /**< Pointer to fragment data. */ ++ void *OsInfo; /**< Pointer to OS defined data. */ ++ }FRAGLIST; ++ ++#if defined (_CPHAL_CPMAC) ++#define CB_PASSCRC_BIT (1<<26) ++ ++/* CPMAC CPHAL STATUS */ ++#define CPMAC_STATUS_LINK (1 << 0) ++#define CPMAC_STATUS_LINK_DUPLEX (1 << 1) /* 0 - HD, 1 - FD */ ++#define CPMAC_STATUS_LINK_SPEED (1 << 2) /* 0 - 10, 1 - 100 */ ++ ++/* ADAPTER CHECK Codes */ ++ ++#define CPMAC_STATUS_ADAPTER_CHECK (1 << 7) ++#define CPMAC_STATUS_HOST_ERR_DIRECTION (1 << 8) ++#define CPMAC_STATUS_HOST_ERR_CODE (0xF << 9) ++#define CPMAC_STATUS_HOST_ERR_CH (0x7 << 13) ++ ++#define _CPMDIO_DISABLE (1 << 0) ++#define _CPMDIO_HD (1 << 1) ++#define _CPMDIO_FD (1 << 2) ++#define _CPMDIO_10 (1 << 3) ++#define _CPMDIO_100 (1 << 4) ++#define _CPMDIO_NEG_OFF (1 << 5) ++#define _CPMDIO_LOOPBK (1 << 16) ++#define _CPMDIO_AUTOMDIX (1 << 17) /* Bit 16 and above not used by MII register */ ++#define _CPMDIO_NOPHY (1 << 20) ++#endif ++ ++/** ++ * @ingroup shared_data ++ * Channel specific configuration information. This structure should be ++ * populated by upper-layer software prior to calling @c ChannelSetup(). Any ++ * configuration item that can be changed on a per channel basis should ++ * be represented here. Each module may define this structure with additional ++ * module-specific members. ++ */ ++typedef struct ++ { ++ int Channel; /**< Channel number. */ ++ int Direction; /**< DIRECTION_RX(1) or DIRECTION_TX(0). */ ++ OS_SETUP *OsSetup; /**< OS defined information associated with this channel. */ ++ ++#if defined(_CPHAL_AAL5) || defined (_CPHAL_CPSAR) || defined (_CPHAL_CPMAC) ++ int RxBufSize; /**< Size (in bytes) for each Rx buffer.*/ ++ int RxBufferOffset; /**< Number of bytes to offset rx data from start of buffer (must be less than buffer size). */ ++ int RxNumBuffers; /**< The number of Rx buffer descriptors to allocate for Ch. */ ++ int RxServiceMax; /**< Maximum number of packets to service at one time. */ ++ ++ int TxNumBuffers; /**< The number of Tx buffer descriptors to allocate for Ch. */ ++ int TxNumQueues; /**< Number of Tx queues for this channel (1-2). Choosing 2 enables a low priority SAR queue. */ ++ int TxServiceMax; /**< Maximum number of packets to service at one time. */ ++#endif ++ ++#if defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++ int CpcsUU; /**< The 2-byte CPCS UU and CPI information. */ ++ int Gfc; /**< Generic Flow Control. */ ++ int Clp; /**< Cell Loss Priority. */ ++ int Pti; /**< Payload Type Indication. */ ++#endif ++ ++#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++ int DaMask; /**< Specifies whether credit issuance is paused when Tx data not available. */ ++ int Priority; /**< Priority bin this channel will be scheduled within. */ ++ int PktType; /**< 0=AAL5,1=Null AAL,2=OAM,3=Transparent,4=AAL2. */ ++ int Vci; /**< Virtual Channel Identifier. */ ++ int Vpi; /**< Virtual Path Identifier. */ ++ int FwdUnkVc; /**< Enables forwarding of unknown VCI/VPI cells to host. 1=enable, 0=disable. */ ++ ++ /* Tx VC State */ ++ int TxVc_CellRate; /**< Tx rate, set as clock ticks between transmissions (SCR for VBR, CBR for CBR). */ ++ int TxVc_QosType; /**< 0=CBR,1=VBR,2=UBR,3=UBRmcr. */ ++ int TxVc_Mbs; /**< Min Burst Size in cells.*/ ++ int TxVc_Pcr; /**< Peak Cell Rate for VBR in clock ticks between transmissions. */ ++ ++ bit32 TxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Tx Ch (must be big endian with 0 PTI). */ ++ int TxVc_OamTc; /**< TC Path to transmit OAM cells for TX connection (0,1). */ ++ int TxVc_VpOffset; /**< Offset to the OAM VP state table. */ ++ /* Rx VC State */ ++ int RxVc_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ ++ int RxVc_OamToHost; /**< 0=do not pass, 1=pass. */ ++ bit32 RxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx conn (must be big endian with 0 PTI). */ ++ int RxVc_OamTc; /**< TC Path to transmit OAM cells for RX connection (0,1). */ ++ int RxVc_VpOffset; /**< Offset to the OAM VP state table. */ ++ /* Tx VP State */ ++ int TxVp_OamTc; /**< TC Path to transmit OAM cells for TX VP connection (0,1). */ ++ bit32 TxVp_AtmHeader; /**< ATM Header placed on firmware gen'd VP OAM cells for this Tx VP conn (must be big endian with 0 VCI). */ ++ /* Rx VP State */ ++ int RxVp_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ ++ int RxVp_OamToHost; /**< 0=do not pass, 1=pass. */ ++ bit32 RxVp_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx VP conn (must be big endian with 0 VCI). */ ++ int RxVp_OamTc; /**< TC Path to transmit OAM cells for RX VP connection (0,1). */ ++ int RxVp_OamVcList; /**< Indicates all VC channels associated with this VP channel (one-hot encoded). */ ++#endif ++ ++ ++#ifdef _CPHAL_VDMAVT ++ bit32u RemFifoAddr; /* Mirror mode only. */ ++ bit32u FifoAddr; ++ bit32 PollInt; ++ bit32 FifoSize; ++ int Ready; ++#endif ++ ++ }CHANNEL_INFO; ++ ++/* ++ * This structure contains each statistic value gathered by the CPHAL. ++ * Applications may access statistics data by using the @c StatsGet() routine. ++ */ ++/* STATS */ ++#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++typedef struct ++ { ++ bit32u CrcErrors[16]; ++ bit32u LenErrors[16]; ++ bit32u DmaLenErrors[16]; ++ bit32u AbortErrors[16]; ++ bit32u StarvErrors[16]; ++ bit32u TxMisQCnt[16][2]; ++ bit32u RxMisQCnt[16]; ++ bit32u RxEOQCnt[16]; ++ bit32u TxEOQCnt[16][2]; ++ bit32u RxPacketsServiced[16]; ++ bit32u TxPacketsServiced[16][2]; ++ bit32u RxMaxServiced; ++ bit32u TxMaxServiced[16][2]; ++ bit32u RxTotal; ++ bit32u TxTotal; ++ } STAT_INFO; ++#endif ++ ++/* ++ * VDMA Channel specific configuration information ++ */ ++#ifdef _CPHAL_AAL2 ++typedef struct ++ { ++ int Ch; /**< Channel Number */ ++ int RemoteEndian; /**< Endianness of remote VDMA-VT device */ ++ int CpsSwap; /**< When 0, octet 0 in CPS pkt located in LS byte of 16-bit word sent to rem VDMA device. When 1, in MS byte. */ ++ }VdmaChInfo; ++#endif ++ ++#ifndef _CPHAL ++ typedef void HAL_DEVICE; ++ typedef void HAL_PRIVATE; ++ typedef void HAL_RCB; ++ typedef void HAL_RECEIVEINFO; ++#endif ++ ++/** ++ * @ingroup shared_data ++ * The HAL_FUNCTIONS struct defines the function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to xxxInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup) (HAL_DEVICE *HalDev, CHANNEL_INFO *Channel, OS_SETUP *OsSetup); ++ int (*ChannelTeardown) (HAL_DEVICE *HalDev, int Channel, int Mode); ++ int (*Close) (HAL_DEVICE *HalDev, int Mode); ++ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*Init) (HAL_DEVICE *HalDev); ++ int (*Open) (HAL_DEVICE *HalDev); ++ int (*PacketProcessEnd) (HAL_DEVICE *HalDev); ++ int (*Probe) (HAL_DEVICE *HalDev); ++ int (*RxReturn) (HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); ++ int (*Send) (HAL_DEVICE *HalDev, FRAGLIST *FragList, int FragCount, int PacketSize, OS_SENDINFO *OsSendInfo, bit32u Mode); ++ int (*Shutdown) (HAL_DEVICE *HalDev); ++ int (*Tick) (HAL_DEVICE *HalDev); ++ ++#ifdef _CPHAL_AAL5 ++ int (*Kick) (HAL_DEVICE *HalDev, int Queue); ++ void (*OamFuncConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig); ++ void (*OamLoopbackConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig, unsigned int *LLID, unsigned int CorrelationTag); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ STAT_INFO* (*StatsGetOld)(HAL_DEVICE *HalDev); ++#endif ++ } HAL_FUNCTIONS; ++ ++/** ++ * @ingroup shared_data ++ * The OS_FUNCTIONS struct defines the function pointers for all upper layer ++ * functions accessible to the CPHAL. The upper layer software is responsible ++ * for providing the correct OS-specific implementations for the following ++ * functions. It is populated by calling InitModule() (done by the CPHAL in ++ * xxxInitModule(). ++ */ ++typedef struct ++ { ++ int (*Control)(OS_DEVICE *OsDev, const char *Key, const char *Action, void *Value); ++ void (*CriticalOn)(void); ++ void (*CriticalOff)(void); ++ void (*DataCacheHitInvalidate)(void *MemPtr, int Size); ++ void (*DataCacheHitWriteback)(void *MemPtr, int Size); ++ int (*DeviceFindInfo)(int Inst, const char *DeviceName, void *DeviceInfo); ++ int (*DeviceFindParmUint)(void *DeviceInfo, const char *Parm, bit32u *Value); ++ int (*DeviceFindParmValue)(void *DeviceInfo, const char *Parm, void *Value); ++ void (*Free)(void *MemPtr); ++ void (*FreeRxBuffer)(OS_RECEIVEINFO *OsReceiveInfo, void *MemPtr); ++ void (*FreeDev)(void *MemPtr); ++ void (*FreeDmaXfer)(void *MemPtr); ++ void (*IsrRegister)(OS_DEVICE *OsDev, int (*halISR)(HAL_DEVICE*, int*), int InterruptBit); ++ void (*IsrUnRegister)(OS_DEVICE *OsDev, int InterruptBit); ++ void* (*Malloc)(bit32u size); ++ void* (*MallocDev)(bit32u Size); ++ void* (*MallocDmaXfer)(bit32u size, void *MemBase, bit32u MemRange); ++ void* (*MallocRxBuffer)(bit32u size, void *MemBase, bit32u MemRange, ++ OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo, ++ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev); ++ void* (*Memset)(void *Dest, int C, bit32u N); ++ int (*Printf)(const char *Format, ...); ++ int (*Receive)(OS_DEVICE *OsDev,FRAGLIST *FragList,bit32u FragCount, ++ bit32u PacketSize,HAL_RECEIVEINFO *HalReceiveInfo, bit32u Mode); ++ int (*SendComplete)(OS_SENDINFO *OsSendInfo); ++ int (*Sprintf)(char *S, const char *Format, ...); ++ int (*Strcmpi)(const char *Str1, const char *Str2); ++ unsigned int (*Strlen)(const char *S); ++ char* (*Strstr)(const char *S1, const char *S2); ++ unsigned long (*Strtoul)(const char *Str, char **Endptr, int Base); ++ void (*TeardownComplete)(OS_DEVICE *OsDev, int Ch, int Direction); ++ } OS_FUNCTIONS; ++ ++/************** MODULE SPECIFIC STUFF BELOW **************/ ++ ++#ifdef _CPHAL_CPMAC ++ ++/* ++int halCpmacInitModule(HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, int (*osBridgeInitModule)(OS_FUNCTIONS *), void* (*osMallocDev) (bit32u), int *Size, int inst); ++*/ ++ ++int halCpmacInitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_AAL5 ++/* ++ * @ingroup shared_data ++ * The AAL5_FUNCTIONS struct defines the AAL5 function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++/* ++typedef struct ++ { ++ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(HAL_DEVICE *HalDev, int Mode); ++ int (*Init)(HAL_DEVICE *HalDev); ++ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(HAL_DEVICE *HalDev); ++ int (*InfoGet)(HAL_DEVICE *HalDev, int Key, void *Value); ++ int (*Probe)(HAL_DEVICE *HalDev); ++ int (*RxReturn)(HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); ++ int (*Send)(HAL_DEVICE *HalDev,FRAGLIST *FragList,int FragCount, ++ int PacketSize,OS_SENDINFO *OsSendInfo,int Ch, int Queue, ++ bit32u Mode); ++ int (*StatsClear)(HAL_DEVICE *HalDev); ++ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); ++ int (*Status)(HAL_DEVICE *HalDev); ++ void (*Tick)(HAL_DEVICE *HalDev); ++ int (*Kick)(HAL_DEVICE *HalDev, int Queue); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ } AAL5_FUNCTIONS; ++*/ ++ ++int cpaal5InitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_AAL2 ++/** ++ * @ingroup shared_data ++ * The AAL2_FUNCTIONS struct defines the AAL2 function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(HAL_DEVICE *HalDev, int Mode); ++ int (*Init)(HAL_DEVICE *HalDev); ++ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(HAL_DEVICE *HalDev); ++ int (*OptionsGet)(HAL_DEVICE *HalDev, char *Key, bit32u *Value); ++ int (*Probe)(HAL_DEVICE *HalDev); ++ ++ int (*StatsClear)(HAL_DEVICE *HalDev); ++ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); ++ int (*Status)(HAL_DEVICE *HalDev); ++ void (*Tick)(HAL_DEVICE *HalDev); ++ int (*Aal2UuiMappingSetup)(HAL_DEVICE *HalDev, int VC, int UUI, ++ int VdmaCh, int UUIDiscard); ++ int (*Aal2RxMappingSetup)(HAL_DEVICE *HalDev, int VC, int CID, ++ int LC); ++ int (*Aal2TxMappingSetup)(HAL_DEVICE *HalDev, int VC, int LC, int VdmaCh); ++ int (*Aal2VdmaChSetup)(HAL_DEVICE *HalDev, bit32u RemVdmaVtAddr, ++ VdmaChInfo *VdmaCh); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ int (*Aal2ModeChange)(HAL_DEVICE *HalDev, int Vc, int RxCrossMode, ++ int RxMultiMode, int TxMultiMode, int SchedMode, ++ int TcCh); ++ void (*Aal2VdmaEnable)(HAL_DEVICE *HalDev, int Ch); ++ int (*Aal2VdmaDisable)(HAL_DEVICE *HalDev, int Ch); ++ } AAL2_FUNCTIONS; ++ ++int cpaal2InitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ AAL2_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_VDMAVT ++/** ++ * @ingroup shared_data ++ * The VDMA_FUNCTIONS struct defines the HAL function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to InitModule(). ++ * ++ * Note that this list is still under definition. ++ */ ++typedef struct ++ { ++ bit32 (*Init)( HAL_DEVICE *VdmaVtDev); ++ /* bit32 (*SetupTxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, ++ bit32u Addr, bit32u Size, bit32u PollInt); ++ bit32 (*SetupRxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, ++ bit32u Addr, bit32u Size, bit32u PollInt); */ ++ bit32 (*Tx)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Rx)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*SetRemoteChannel)(HAL_DEVICE *VdmaVtDev, bit32u RemAddr, ++ bit32u RemDevID); ++ bit32 (*ClearRxInt)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*ClearTxInt)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Open)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Close)(HAL_DEVICE *VdmaVtDev); ++ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*ChannelSetup)(HAL_DEVICE *VdmaVtDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *VdmaVtDev, int Ch, int Mode); ++ int (*Send)(HAL_DEVICE *VdmaVtDev,FRAGLIST *FragList,int FragCount, ++ int PacketSize,OS_SENDINFO *OsSendInfo,bit32u Mode); ++ } VDMA_FUNCTIONS; ++ ++int VdmaInitModule(HAL_DEVICE **VdmaVt, ++ OS_DEVICE *OsDev, ++ VDMA_FUNCTIONS **VdmaVtFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++/* ++extern int cphalInitModule(MODULE_TYPE ModuleType, HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, ++ int (*osInitModule)(OS_FUNCTIONS *), void* (*osMallocDev)(bit32u), ++ int *Size, int Inst); ++*/ ++ ++ ++#ifdef _CPHAL_AAL5 ++extern const char hcSarFrequency[]; ++#endif ++ ++#ifdef _CPHAL_CPMAC ++/* following will be common, once 'utl' added */ ++extern const char hcClear[]; ++extern const char hcGet[]; ++extern const char hcSet[]; ++extern const char hcTick[]; ++ ++extern const char hcCpuFrequency[]; ++extern const char hcCpmacFrequency[]; ++extern const char hcMdioBusFrequency[]; ++extern const char hcMdioClockFrequency[]; ++extern const char hcCpmacBase[]; ++extern const char hcPhyNum[]; ++extern const char hcSize[]; ++extern const char hcCpmacSize[]; ++extern const char hcPhyAccess[]; ++extern const char hcMdixMask[]; ++extern const char hcMdioMdixSwitch[]; ++#endif ++ ++#endif /* end of _INC_ */ +diff -urN linux.old/drivers/net/avalanche_cpmac/dox_cpmac.h linux.dev/drivers/net/avalanche_cpmac/dox_cpmac.h +--- linux.old/drivers/net/avalanche_cpmac/dox_cpmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/dox_cpmac.h 2005-07-12 02:48:42.050593000 +0200 +@@ -0,0 +1,842 @@ ++/***************************************************************************** ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002,2003 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: ++ * ++ * DESCRIPTION: ++ * This file contains documentation for the CPMAC ++ * ++ * HISTORY: ++ * @author Michael Hanrahan/Greg Guyotte ++ * @version 1.00 ++ * @date 03-Dec-2002 ++ *****************************************************************************/ ++#ifndef _DOX_CPMAC_H ++#define _DOX_CPMAC_H ++/** ++@page CPMAC_Implementation_Details Version ++ ++@copydoc CPMAC_Version ++*/ ++ ++/** ++@page cpmac_intro Introduction ++ ++The CPMAC implementation will support 8 channels for transmit and 8 channel for ++receive. Each of the 8 transmit channels has 1 queue associated with it. It is ++recommended that only 1 channel is used for @c Receive() per processor. ++*/ ++ ++/** ++@page cpmac_details API Implementation Details ++@par osReceive ++@p Mode parameter ++- The Upper 16 bits of Mode match Word 3 of the Rx Buffer Descriptor ++ ++@par halSend ++@p Mode parameter ++- Bits 0-7 contain the Channel Number ++- Bits 8-25 are reserved ++- Bit 26 - if 0, the CRC will be calculated, if 1 the CRC will be Passed ++- Bits 27-31 : reserved ++@section cpmac_keys Control Keys ++ ++@par StateChange ++CPHAL calls the OS when a state change is detected. ++OS should check the CPMAC Status. See the Control Key 'Status' for more details. ++ ++@par Status ++OS calls the CPHAL to obtain Status information. The Returned status is as follows ++ ++@par MaxFrags ++The OS may "Set" or "Get" this value. This defines the maximum ++number of fragments that can be received by the CPMAC Rx port. The default ++value for CPMAC is 2. This provides enough space to receive a maximum ++length packet (1,518 bytes) with the default buffer size of 1518 and any ++amount of RxBufferOffset. If the buffer size is configured to be smaller, ++the OS *MUST* modify this parameter according to the following formula: ++((System Max packet length)/(RxBufSize)) + 1. (The extra 1 fragment is to ++allow for RxBufferOffset) ++ ++@code ++// Following defined in "cpswhal_cpmac.h" ++// CPMAC CPHAL STATUS ++#define CPMAC_STATUS_LINK (1 << 0) ++#define CPMAC_STATUS_LINK_DUPLEX (1 << 1) // 0 - HD, 1 - FD ++#define CPMAC_STATUS_LINK_SPEED (1 << 2) // 0 - 10, 1 - 100 ++ ++// ADAPTER CHECK Codes ++#define CPMAC_STATUS_ADAPTER_CHECK (1 << 7) ++#define CPMAC_STATUS_HOST_ERR_DIRECTION (1 << 8) // 0 - Tx, 1 - Rx ++#define CPMAC_STATUS_HOST_ERR_CODE (0xF << 9) See CPMAC Guide ++#define CPMAC_STATUS_HOST_ERR_CH (0x7 << 13) See CPMAC Guide ++@endcode ++ ++@code ++void osStateChange(OS_DEVICE *OsDev) ++ { ++ int status; ++ OsDev->HalFunc->Control(OsDev->HalDev, "Status", hcGet, &status); ++ if(status & CPMAC_STATUS_ADAPTER_CHECK) ++ { ++ printf("[osStateChange[%d]] HAL notified OS of AdapterCheck (Link Status 0x%08X)\n", OsDev->port, status); ++ adaptercheck(OsDev->port); ++ } ++ else ++ { ++ printf("[osStateChange[%d]] HAL notified OS of State Change (Link Status %s)\n", OsDev->port, (status & CPMAC_STATUS_LINK) ? "Up" : "Down"); ++ if(status & CPMAC_STATUS_LINK) ++ { ++ printf("Speed %s, Duplex %s\n", ++ status & CPMAC_STATUS_LINK_SPEED ? "100" : "10", ++ status & CPMAC_STATUS_LINK_DUPLEX ? "FD" : "HD"); ++ } ++ } ++@endcode ++ ++@par Tick ++ The CPHAL calls the OS to set the interval for calling halTick()
++ Note: Predefined value hcTick now recommended for use. ++@code ++*** Example Code *** ++ ++*** CPHAL code *** ++int Ticks; ++HalDev->OsFunc->Control(HalDev->OsDev, hcTick, hcSet, &Ticks); ++ ++*** OS code *** ++ .. ++ if(osStrcmpi(pszKey, hcTick) == 0) ++ { ++ if(osStrcmpi(pszAction, hcSet) == 0) ++ { ++ // Enable the Tick Interval ++ if(*(unsigned int *) ParmValue) ++ printf("osTickSet: Interval = %d ticks\n", Interval); ++ } ++ else ++ if(osStrcmpi(pszAction, hcClear) == 0) ++ { ++ // Request disabling of the Tick Timer, ParmValue is ignored ++ } ++ } ++@endcode ++ ++@par The following information can be obtained by the OS via 'Get' ++ ++- StatsDump : OS supplies pointer to an 36 element unsigned int array ++CPHAL will populate the array with the current Statistics values.
++Note: all hcXXXX values are predefined and should be used by the OS. ++ ++- hcPhyNum : Returns the PHY number. ++- hcCpmacBase : Returns the base-address of the CPMAC device ++- hcCpmacSize : Returns size of the CPMAC memory map ++ ++ ++@par Phy Register Communication ++ ++halControl() is used to read and write the Phy Registers via the key hcPhyAccess ++ ++Both reading and writing the Phy registers involve setting the Value parameter of halControl() ++
++Value is a 32-bit value with bits partioned as follows ++
++ ++ 0 - 4 Phy Number
++ 5 - 9 Phy Register
++ 10 - 15 reserved
++ 16 - 31 Data (write only) ++
++ ++ ++Reading the Phy register ++ ++@code ++ bit32u Value; ++ bit32u RegAddr; ++ bit32u PhyNum; ++ bit32u PhyRegisterData; ++ ++ // Read Phy 31, register 20 ++ ++ PhyNum = 31; ++ RegAddr = 20; ++ ++ Value = (RegAddr << 5); ++ Value |= (PhyNum & 0x1F); ++ ++ rc = HalFunc->Control(HalDev, hcPhyAccess, hcGet, (bit32u *) &Value) ++ If(rc == 0) ++ { ++ // Value is overwriten with the value in Register 20 of Phy number 31. ++ PhyRegisterData = Value; ++ } ++@endcode ++ ++Writing the Phy register ++@code ++ bit32u Value; ++ bit32u RegAddr; ++ bit32u PhyNum; ++ bit32u PhyRegisterData; ++ ++ // Reset Phy 23 ++ ++ PhyNum = 23; ++ RegAddr = 0; ++ PhyRegisterData = 0x8000; // Reset bit set ++ ++ Value = (RegAddr << 5); ++ Value |= (PhyNum & 0x1F); ++ Value |= (PhyRegisterData << 16); ++ ++ rc = HalFunc->Control(HalDev, hcPhyAccess, hcSet, (bit32u *) &Value) ++ ++ // Check is reset if done ++ ++ PhyNum = 23; ++ RegAddr = 0; ++ ++ Value = (RegAddr << 5); ++ Value |= (PhyNum & 0x1F); ++ ++ rc = HalFunc->Control(HalDev, hcPhyAccess, hcGet, (bit32u *) &Value) ++ ++ If(rc == 0) ++ { ++ // Value is overwriten with the value in Register 0 of Phy number 23. ++ PhyRegisterData = Value; ++ if((PhyRegisterData & 0x8000) == 0) ++ ResetIsComplete; ++ } ++ ++@endcode ++ ++*** Example Showing turning values off/on *** ++
++
++ ++@code ++ ++int On=1; ++int Off=0; ++ # Turn On loopback ++ OsDev->HalFunc->Control(OsDev->HalDev, "CTRL_LOOPBACK", hcSet, (int*) &On); ++ ++ # Turn off RX Flow ++ OsDev->HalFunc->Control(OsDev->HalDev, "RX_FLOW_EN", hcSet, (int*) &Off); ++@endcode ++ ++@par CPMAC Configurable Parameters ++ ++- RX_PASS_CRC : See MBP_Enable description ++- RX_QOS_EN : See MBP_Enable description ++- RX_NO_CHAIN : See MBP_Enable description ++- RX_CMF_EN : See MBP_Enable description ++- RX_CSF_EN : See MBP_Enable description ++- RX_CEF_EN : See MBP_Enable description ++- RX_CAF_EN : See MBP_Enable description ++- RX_PROM_CH : See MBP_Enable description ++- RX_BROAD_EN : See MBP_Enable description ++- RX_BROAD_CH : See MBP_Enable description ++- RX_MULT_EN : See MBP_Enable description ++- RX_MULT_CH : See MBP_Enable description ++ ++- TX_PTYPE : See MacControl description ++- TX_PACE : See MacControl description ++- TX_FLOW_EN : See MacControl description ++- RX_FLOW_EN : See MacControl description ++- CTRL_LOOPBACK : See MacControl description ++ ++- RX_MAXLEN : See CPMAC Guide ++- RX_FILTERLOWTHRESH : See CPMAC Guide ++- RX0_FLOWTHRESH : See CPMAC Guide ++- RX_UNICAST_SET : See CPMAC Guide ++- RX_UNICAST_CLEAR : See CPMAC Guide ++ ++@par Multicast Support ++- RX_MULTI_ALL : When used with hcSet, sets all the Hash Bits. When used ++with hcClear clears all the Hash Bits. ++- RX_MULTI_SINGLE : When used with hcSet, adds the Hashed Mac Address. When used ++with hcClear deletes the Hashed Mac Address. ++Note: Support will be added to keep track of Single additions and deletions. ++ ++@code ++*** Example Code *** ++ ++*** OS code *** ++ bit8u MacAddress[6]; ++ MacAddress[0] = 0x80; ++ MacAddress[1] = 0x12; ++ MacAddress[2] = 0x34; ++ MacAddress[3] = 0x56; ++ MacAddress[4] = 0x78; ++ MacAddress[5] = 0x78; ++ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_SINGLE", hcSet, (bit8u*) &MacAddress); ++ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_SINGLE", hcClear, (bit8u*) &MacAddress); ++ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_ALL", hcSet, NULL); ++ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_ALL", hcClear, NULL); ++@endcode ++@par MdioConnect Fields ++
++- "MdioConnect" : The OS can set the Phy connection using this key. The default connection is Auto-Negotiation ON, All modes possible. ++ ++ ++- _CPMDIO_HD <----- Allow Half Duplex, default is 1 (On) ++- _CPMDIO_FD <----- Allow Full Duplex, default is 1 (On) ++- _CPMDIO_10 <----- Allow 10 Mbs, default is 1 (On) ++- _CPMDIO_100 <----- Allow 100 Mbs, default is 1 (On) ++- _CPMDIO_NEG_OFF <----- Turn off Auto Negotiation, default is 0 (Auto Neg is on) ++- _CPMDIO_NOPHY <----- Set for use with Marvel-type switch, default is 0 (Phy present) ++- _CPMDIO_AUTOMDIX <---- Enables Auto Mdix (in conjunction with MdixMask), default is 1 (On) ++ ++Note: When _CPMDIO_NOPHY is set, CPMAC will report being linked at 100/FD. Reported PhyNum will be 0xFFFFFFFF ++ ++@par Setting CPMAC for use with a Marvel-type Switch ++@code ++ bit32u MdioConnect; ++ ++ MdioConnect = _CPMDIO_NOPHY; ++ OsDev->HalFunc->Control(OsDev->HalDev, "MdioConnect", hcSet, (bit32u*) &MdioConnect); ++@endcode ++ ++@par OS Support for MDIO ++@p The OS will need to supply the following values which the CPHAL will request via halControl() ++
++- MdioBusFrequency : The frequency of the BUS that MDIO is on (requested via hcMdioBusFrequency) ++
++- MdioClockFrequency : The desired Clock Frequency that MDIO qill operate at (requested via hcMdioClockFrequency) ++*/ ++ ++/** ++@page cpmac_conf DeviceFindxxx() Parameters ++ ++These are some of the parameters that the CPMAC will request via the DeviceFindxxx() functions - ++
++- "Mlink" : bit mask indicating what link status method Phy is using. Default is MDIO state machine (0x0) ++- "PhyMask" : bit mask indicating PhyNums used by this CPMAC (e.g 0x8000000, PhyNum is 31) ++- "MdixMask" : bit mask indicating which Phys support AutoMdix. Default is 0x0 (None) ++
++@par Example cpmac definition from the options.conf for the Sangam VDB ++
++- cpmac( id=eth0, base=0xA8610000, size=0x800, reset_bit=17, int_line=19, PhyMask=0x80000000, MLink=0, MdixMask=0 ) ++*/ ++ ++/** ++@page auto_mdix Auto Mdix Support ++ ++Auto Mdix selection is controlled by two elements in the CPMAC. First the OS can turn Auto Midx On or Off by the use of the ++MdioConnect field, _CPMDIO_AUTOMDIX. This is defaulted ON. For actual Auto Mdix operation the Phy must also be Auto Mdix capable. ++This is specified by the DeviceFindxxx() field, "MdixMask" (supplied as the variable hcMdixMask). ++If both these fields are set then the CPMDIO state machine will be enabled for Auto Mdix checking. ++If a switch to MDI or MDIX mode is needed, the CPMAC will signal this to the OS via Control() using ++the hcMdioMdixSwitch key. ++ ++@par OS example for responding to a Mdix Switch Request ++
++@code ++if(osStrcmpi(pszKey, hcMdioMdixSwitch) == 0) // See if key is Mdix Switch Request ++ { ++ if(osStrcmpi(pszAction, hcSet) == 0) // Only respond to Set requests ++ { ++ ++ bit32u Mdix; ++ ++ Mdix = *(bit32u *) ParmValue; // Extract requested Mode ++ // 0 : MDI ++ // 1 : MDIX ++ if(Mdix) ++ osSetPhyIntoMdixMode(); // Device specific logic ++ else ++ osSetPhyIntoMdiMode(); // Device specific logic ++ rc = 0; // Set return code as Successfull ++ } ++@endcode ++*/ ++ ++/** ++@page cpmac_stats CPMAC Specific Statistics ++ ++Statistics level '0' contains all CPMAC specific statistics. ++ ++ ++*/ ++ ++/** ++@page Example_Driver_Code ++ ++@section example_intro Introduction ++This section provides an in-depth code example for driver implementations. The code ++below illustrates the use of the CPMAC HAL, but is equally applicable to any CPHAL ++implementation. Note: the CPHAl constants hcGet, hcSet etc., are currently available for use with teh CPMAC module. ++Other modules should continue to use pszGET, etc. until these are made generally available. ++ ++@par Pull Model Example ++ ++@code ++ ++#define _CPHAL_CPMAC ++ ++typedef struct _os_device_s OS_DEVICE; ++typedef struct _os_receive_s OS_RECEIVEINFO; ++typedef struct _os_send_s OS_SENDINFO; ++typedef struct _os_setup_s OS_SETUP; ++ ++#include "cpswhal_cpmac.h" ++ ++#define dbgPrintf printf ++ ++typedef struct _os_device_s ++{ ++ HAL_DEVICE *HalDev; ++ HAL_FUNCTIONS *HalFunc; ++ OS_FUNCTIONS *OsFunc; ++ OS_SETUP *OsSetup; ++ bit32u Interrupt; ++ int (*halIsr)(HAL_DEVICE *HalDev, int*); ++ int ModulePort; ++ int Protocol; ++ int LinkStatus; // 0-> down, otherwise up ++}os_device_s; ++ ++typedef struct _os_receive_s ++{ ++ HAL_RECEIVEINFO *HalReceiveInfo; ++ char *ReceiveBuffer; ++ OS_DEVICE *OsDev; ++}os_receive_s; ++ ++typedef struct _os_send_s ++{ ++ OS_DEVICE *OsDev; ++}os_send_s; ++ ++typedef struct _os_setup_s ++{ ++ OS_DEVICE *OsDev; ++}os_setup_s; ++ ++ ++ ++void FlowForCphal(OS_DEVICE *OsDev) ++{ ++ CHANNEL_INFO ChannelInfo; ++ int nChannels = 200; ++ int halFuncSize; ++ int rc; ++ ++ // Populate OsFunc structure ++ rc = osInitModule(OsDev); ++ ++ if(rc) ++ { ++ sprintf(bufTmp, "%s: return code from osInitModule:'0x%08X'", __FUNCTION__, rc); ++ errorout(bufTmp); ++ } ++ ++ ++ // OS-Cphal handshake ++ rc = halCpmacInitModule(&OsDev->HalDev, OsDev, &OsDev->HalFunc, OsDev->OsFunc, ++ sizeof(OS_FUNCTIONS), &halFuncSize, OsDev->ModulePort); ++ ++ if(rc) ++ { ++ sprintf(bufTmp, "%s: return code from halCpmacInitModule:'0x%08X'", __FUNCTION__, rc); ++ errorout(bufTmp); ++ } ++ ++ // See if hardware module exists ++ rc = OsDev->HalFunc->Probe(OsDev->HalDev); ++ ++ if(rc) ++ { ++ sprintf(bufTmp, "%s: return code from Probe:'0x%08X'", __FUNCTION__, rc); ++ errorout(bufTmp); ++ } ++ ++ // Initialize hardware module ++ rc = OsDev->HalFunc->Init(OsDev->HalDev); ++ ++ if(rc) ++ { ++ sprintf(bufTmp, "%s: return code from Init:'0x%08X'", __FUNCTION__, rc); ++ errorout(bufTmp); ++ } ++ ++ // Setup Channel Information (Tranmsit, channel 0) ++ ChannelInfo.Channel = 0; ++ ChannelInfo.Direction = DIRECTION_TX; ++ ChannelInfo.TxNumBuffers = nChannels; ++ ChannelInfo.TxNumQueues = 1; ++ ChannelInfo.TxServiceMax = nChannels/3; ++ ++ rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup); ++ ++ // Setup Channel Information (Receive, channel 0) ++ ChannelInfo.Channel = 0; ++ ChannelInfo.Direction = DIRECTION_RX; ++ ChannelInfo.RxBufSize = 1518; ++ ChannelInfo.RxBufferOffset = 0; ++ ChannelInfo.RxNumBuffers = 2*nChannels; ++ ChannelInfo.RxServiceMax = nChannels/3; ++ ++ rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup); ++ ++ // Open the hardware module ++ rc = OsDev->HalFunc->Open(OsDev->HalDev); ++ ++ // Module now ready to Send/Receive data ++} ++ ++ ++int osInitModule(OS_FUNCTIONS **pOsFunc) ++ { ++ OS_FUNCTIONS *OsFunc; ++ ++ OsFunc = (OS_FUNCTIONS *) malloc(sizeof(OS_FUNCTIONS)); ++ if (!OsFunc) ++ return (-1); ++ ++ *pOsFunc = OsFunc; ++ ++ OsFunc->CriticalOff = osCriticalOff; ++ OsFunc->CriticalOn = osCriticalOn; ++ OsFunc->DataCacheHitInvalidate = osDataCacheHitInvalidate; ++ OsFunc->DataCacheHitWriteback = osDataCacheHitWriteback; ++ OsFunc->DeviceFindInfo = osDeviceFindInfo; ++ OsFunc->DeviceFindParmUint = osDeviceFindParmUint; ++ OsFunc->DeviceFindParmValue = osDeviceFindParmValue; ++ OsFunc->Free = osFree; ++ OsFunc->FreeDev = osFreeDev; ++ OsFunc->FreeDmaXfer = osFreeDmaXfer; ++ OsFunc->FreeRxBuffer = osFreeRxBuffer; ++ OsFunc->IsrRegister = osIsrRegister; ++ OsFunc->IsrUnRegister = osIsrUnRegister; ++ OsFunc->Malloc = osMalloc; ++ OsFunc->MallocDev = osMallocDev; ++ OsFunc->MallocDmaXfer = osMallocDmaXfer; ++ OsFunc->MallocRxBuffer = osMallocRxBuffer; ++ ++ ++ OsFunc->Memset = memset; ++ OsFunc->Printf = printf; ++ OsFunc->Sprintf = sprintf; ++ OsFunc->Strcmpi = osStrcmpi; ++ OsFunc->Strlen = strlen; ++ OsFunc->Strstr = strstr; ++ OsFunc->Strtoul = strtoul; ++ ++ OsFunc->Control = osControl; ++ OsFunc->Receive = osReceive; ++ OsFunc->SendComplete = osSendComplete; ++ OsFunc->TeardownComplete = osTearDownComplete; ++ ++ return(0); ++ } ++ ++ ++int osReceive(OS_DEVICE *OsDev,FRAGLIST *Fraglist,bit32u FragCount,bit32u PacketSize,HAL_RECEIVEINFO *halInfo, bit32u mode) ++ { ++ OS_RECEIVEINFO *skb = (OS_RECEIVEINFO *)Fraglist[0].OsInfo; ++ dcache_i((char *)Fraglist->data, Fraglist->len); ++ OsDev->HalFunc->RxReturn(halInfo,0); ++ return(0); ++ } ++ ++int osSendComplete(OS_SENDINFO *skb) ++ { ++ return(0); ++ } ++ ++ ++static void *osMallocRxBuffer(bit32u Size,void *MemBase, bit32u MemRange, ++ OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo, ++ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev ) ++ { ++ void *HalBuffer; ++ OS_RECEIVEINFO *OsPriv; ++ ++ HalBuffer=malloc(Size); ++ if (!HalBuffer) ++ { ++ return(0); ++ } ++ ++ // Malloc the OS block ++ *OsReceiveInfo = malloc(sizeof(OS_RECEIVEINFO)); ++ if (!*OsReceiveInfo) ++ { ++ free(HalBuffer); ++ return(0); ++ } ++ ++ // Initialize the new buffer descriptor ++ OsPriv = *OsReceiveInfo; ++ OsPriv->OsDev = OsDev; ++ OsPriv->ReceiveBuffer = HalBuffer; ++ OsPriv->HalReceiveInfo = HalReceiveInfo; ++ ++ return(HalBuffer); ++ } ++ ++ ++void SendBuffer(OS_DEVICE *OsDev, char *Buffer, int Size) ++{ ++ FRAGLIST Fraglist; ++ bit32u FragCount; ++ ++ tcb_pending++; ++ Fraglist.len = Size; ++ Fraglist.data = (unsigned *) Buffer; ++ FragCount = 1; ++ mode = 0; // Channel 0 ++ ++ dcache_wb(Fraglist.data, Fraglist.len); ++ OsDev->HalFunc->Send(OsDev->HalDev, &Fraglist, FragCount, Size, (OS_SENDINFO *) Buffer, mode); ++} ++ ++ ++void osStateChange(OS_DEVICE *OsDev) ++ { ++ int status; ++ int LinkStatus; ++ OsDev->HalFunc->Control(OsDev->HalDev, "Status", hcGet, &status); ++ if(status & CPMAC_STATUS_ADAPTER_CHECK) ++ { ++ // Adapter Check, take appropiate action ++ } ++ else ++ { ++ LinkStatus = status & CPMAC_STATUS_LINK; ++ if(LinkStatus != OsDev->LinkStatus) ++ { ++ dbgPrintf("\n%s:Link %s for inst %d Speed %s, Duplex %s\n", ++ __FUNCTION__, ++ LinkStatus ? "up" : "down", ++ OsDev->ModulePort, ++ status & CPMAC_STATUS_LINK_SPEED ? "100" : "10", ++ status & CPMAC_STATUS_LINK_DUPLEX ? "FD" : "HD"); ++ OsDev->LinkStatus = LinkStatus; ++ } ++ } ++ } ++ ++ ++int osControl(OS_DEVICE *OsDev, const char *pszKey, const char* pszAction, void *ParmValue) ++ { ++ int rc=-1; ++ ++ if (osStrcmpi(pszKey, hcCpuFrequency) == 0) ++ { ++ if(osStrcmpi(pszAction, hcGet) == 0) ++ { ++ *(bit32u*) ParmValue = cpufreq; ++ rc = 0; ++ } ++ } ++ if (osStrcmpi(pszKey, hcMdioBusFrequency) == 0) ++ { ++ if(osStrcmpi(pszAction, hcGet) == 0) ++ { ++ *(bit32u *)ParmValue = MdioBusFrequency; ++ rc = 0; ++ } ++ } ++if (osStrcmpi(pszKey, hcMdioClockFrequency) == 0) ++ { ++ if(osStrcmpi(pszAction, hcGet) == 0) ++ { ++ *(bit32u *)ParmValue = MdioClockFrequency; ++ rc = 0; ++ } ++ } ++ ++ if (osStrcmpi(pszKey, hcTick) == 0) ++ { ++ if(osStrcmpi(pszAction, hcSet) == 0) ++ { ++ osTickSetInterval(OsDev, *(unsigned int *) ParmValue); ++ rc = 0; ++ } ++ else ++ if(osStrcmpi(pszAction, hcClear) == 0) ++ { ++ osTickDisable(OsDev); ++ rc = 0; ++ } ++ } ++ ++ if (osStrcmpi(pszKey, "SioFlush") == 0) ++ { ++ MySioFlush(); ++ rc = 0; ++ } ++ ++ if (osStrcmpi(pszKey, "StateChange") == 0) ++ { ++ osStateChange(OsDev); ++ rc = 0; ++ } ++ ++ if (osStrcmpi(pszKey, "Sleep") == 0) ++ { ++ osSleep(*(int *)ParmValue); ++ rc = 0; ++ } ++ return(rc); ++ } ++ ++@endcode ++ ++ ++@par Push Model Example (Currently Eswitch ONLY) ++ ++@code ++ ++typedef struct _os_device_s OS_DEVICE; ++typedef struct _os_receive_s OS_RECEIVEINFO; ++typedef struct _os_send_s OS_SENDINFO; ++typedef struct _os_setup_s OS_SETUP; ++ ++#include "cpswhal.h" //Get glogal HAL stuff ++#include "cpswhaleswitch.h" //Get device specific hal stuff ++ ++ ++typedef struct _os_device_s ++{ ++ HAL_DEVICE *HalDev; ++ HAL_FUNCTIONS *HalFunc; ++ OS_FUNCTIONS *OsFunc; ++ OS_SETUP *OsSetup; ++ bit32u Interrupt; ++ int (*halIsr)(HAL_DEVICE *HalDev, int*); ++ int ModulePort; ++ int Protocol; ++ int LinkStatus; // 0-> down, otherwise up ++}os_device_s; ++ ++typedef struct _os_receive_s ++{ ++ HAL_RECEIVEINFO *HalReceiveInfo; ++ char *ReceiveBuffer; ++ OS_DEVICE *OsDev; ++}os_receive_s; ++ ++typedef struct _os_send_s ++{ ++ OS_DEVICE *OsDev; ++}os_send_s; ++ ++typedef struct _os_setup_s ++{ ++ OS_DEVICE *OsDev; ++}os_setup_s; ++ ++ ++ ++void FlowForCphal(OS_DEVICE *OsDev) ++{ ++CHANNEL_INFO ChannelInfo; ++ int nChannels = 200; ++ int halFuncSize; ++ int rc; ++ ++ // Populate OsFunc structure ++ rc = osInitModule(OsDev); ++ ++ if(rc) ++ { ++ sprintf(bufTmp, "%s: return code from osInitModule:'0x%08X'", __FUNCTION__, rc); ++ errorout(bufTmp); ++ } ++ ++ ++ // OS-Cphal handshake ++ rc = cpswHalEswitchInitModule(&OsDev->HalDev, OsDev, &OsDev->HalFunc, OsDev->OsFunc, ++ sizeof(OS_FUNCTIONS), &halFuncSize, OsDev->ModulePort); ++ ++ if(rc) ++ { ++ sprintf(bufTmp, "%s: return code from cpswHalEswitchInitModule:'0x%08X'", __FUNCTION__, rc); ++ errorout(bufTmp); ++ } ++ ++ ++ ChannelInfo.Channel = 7; ++ ChannelInfo.Direction = DIRECTION_RX; ++ ChanInfo.Receive = osReceiveSS; // Specify function to receive data for this channel ++ ++ rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup); ++ ++ MyConfig.debug=0; ++ MyConfig.CpuFrequency = CpuFreq; ++ MyConfig.EswitchFrequency = EswitchFreq; ++ MyConfig.ResetBase = 0xa8611600; ++ MyConfig.MacAddress = MacAddr; ++ ++ MyConfig.EswitchResetBit= 27; ++ MyConfig.Cpmac0ResetBit = 17; ++ MyConfig.Cpmac1ResetBit = 21; ++ MyConfig.MdioResetBit = 22; ++ MyConfig.Phy0ResetBit = 26; ++ MyConfig.Phy1ResetBit = 28; ++ MyConfig.HdmaResetBit = 13; ++ MyConfig.Cpmac0IntBit = 19; ++ MyConfig.Cpmac1IntBit = 33; ++ MyConfig.EswitchIntBit = 27; ++ MyConfig.EswitchBase = 0xa8640000; ++ MyConfig.EswitchBufferSize = 64; ++ MyConfig.EswitchHostBufCount = 0; ++ MyConfig.EswitchDefaultCamSize = 64; ++ MyConfig.EswitchOverFlowCount = 200; ++ MyConfig.EswitchOverFlowSize = 256; ++ ++ ++ ++ ++ rc=EswitchConfig(HalDev,HalFunc,&MyConfig); ++ ++ ++ // Open the hardware module ++ rc = OsDev->HalFunc->Open(OsDev->HalDev); ++ ++ // Module now ready to Send/Receive data ++} ++ ++ ++int EswitchConfig(HAL_DEVICE *HalDev, HAL_FUNCTIONS *HalFunc, ESWITCH_CONFIG *Config) ++{ ++ bit32u sts; ++ sts = 0; ++ ++ sts |= cpswhalPushBin(hcdebug, Config->debug); ++ sts |= cpswhalPushBin(hcCpuFrequency , Config->CpuFrequency ); ++ sts |= cpswhalPushBin(hcEswitchFrequency , Config->EswitchFrequency ); ++ sts |= cpswhalPushBin(hcResetBase , Config->ResetBase ); ++ sts |= cpswhalPushBin(hcMacAddress , Config->MacAddress ); ++ sts |= cpswhalPushBin(hcEswitchResetBit, Config->EswitchResetBit); ++ sts |= cpswhalPushBin(hcCpmac0ResetBit , Config->Cpmac0ResetBit ); ++ sts |= cpswhalPushBin(hcCpmac1ResetBit , Config->Cpmac1ResetBit ); ++ sts |= cpswhalPushBin(hcMdioResetBit , Config->MdioResetBit ); ++ sts |= cpswhalPushBin(hcPhy0ResetBit , Config->Phy0ResetBit ); ++ sts |= cpswhalPushBin(hcPhy1ResetBit , Config->Phy1ResetBit ); ++ sts |= cpswhalPushBin(hcHdmaResetBit , Config->HdmaResetBit ); ++ sts |= cpswhalPushBin(hcCpmac0IntBit , Config->Cpmac0IntBit ); ++ sts |= cpswhalPushBin(hcCpmac1IntBit , Config->Cpmac1IntBit ); ++ sts |= cpswhalPushBin(hcEswitchIntBit , Config->EswitchIntBit ); ++ sts |= cpswhalPushBin(hcEswitchBase , Config->EswitchBase ); ++ sts |= cpswhalPushBin(hcEswitchBufferSize , Config->EswitchBufferSize ); ++ sts |= cpswhalPushBin(hcEswitchHostBufCount , Config->EswitchHostBufCount ); ++ sts |= cpswhalPushBin(hcEswitchDefaultCamSize , Config->EswitchDefaultCamSize ); ++ sts |= cpswhalPushBin(hcEswitchOverFlowCount , Config->EswitchOverFlowCount ); ++ sts |= cpswhalPushBin(hcEswitchOverFlowSize , Config->EswitchOverFlowSize ); ++ return(sts); ++} ++ ++ ++ ++@endcode ++*/ ++ ++#endif +diff -urN linux.old/drivers/net/avalanche_cpmac/ec_errors_cpmac.h linux.dev/drivers/net/avalanche_cpmac/ec_errors_cpmac.h +--- linux.old/drivers/net/avalanche_cpmac/ec_errors_cpmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/ec_errors_cpmac.h 2005-07-12 02:48:42.051592000 +0200 +@@ -0,0 +1,118 @@ ++/*************************************************************************** ++ Copyright(c) 2001, Texas Instruments Incorporated. All Rights Reserved. ++ ++ FILE: ec_errors.h ++ ++ DESCRIPTION: ++ This file contains definitions and function declarations for ++ error code support. ++ ++ HISTORY: ++ 14Dec00 MJH Added masking to EC_CLASS etc macros ++ 17Sep02 GSG Added HAL support (new class&devices) ++ 03Oct02 GSG Removed C++ style comments ++***************************************************************************/ ++#ifndef _INC_EC_ERRORS ++#define _INC_EC_ERRORS ++ ++/* ++ 31 - CRITICAL ++ 30-28 - CLASS (ie. DIAG, KERNEL, FLASH, etc) ++ 27-24 - INSTANCE (ie. 1, 2, 3, etc ) ++ 23-16 - DEVICE (ie. EMAC, IIC, etc) ++ 15-08 - FUNCTION (ie. RX, TX, INIT, etc) ++ 07-00 - ERROR CODE (ie. NO_BASE, FILE_NOT_FOUND, etc ) ++*/ ++ ++/*--------------------------------------------------------------------------- ++ Useful defines for accessing fields within error code ++---------------------------------------------------------------------------*/ ++#define CRITICAL_SHIFT 31 ++#define CLASS_SHIFT 28 ++#define INST_SHIFT 24 ++#define DEVICE_SHIFT 16 ++#define FUNCTION_SHIFT 8 ++#define ERROR_CODE_SHIFT 0 ++ ++#define CRITICAL_MASK 1 ++#define CLASS_MASK 0x07 ++#define DEVICE_MASK 0xFF ++#define INST_MASK 0x0F ++#define FUNCTION_MASK 0xFF ++#define ERROR_CODE_MASK 0xFF ++ ++#define EC_CLASS(val) ((val&CLASS_MASK) << CLASS_SHIFT) ++#define EC_DEVICE(val) ((val&DEVICE_MASK) << DEVICE_SHIFT) ++#define EC_INST(val) ((val&INST_MASK) << INST_SHIFT) ++#define EC_FUNC(val) ((val&FUNCTION_MASK) << FUNCTION_SHIFT) ++#define EC_ERR(val) ((val&ERROR_CODE_MASK) << ERROR_CODE_SHIFT) ++ ++/*--------------------------------------------------------------------------- ++ Operation classes ++---------------------------------------------------------------------------*/ ++#define EC_HAL EC_CLASS(0) ++#define EC_DIAG EC_CLASS(8) ++ ++/*--------------------------------------------------------------------------- ++ Device types ++---------------------------------------------------------------------------*/ ++#define EC_DEV_EMAC EC_DEVICE(1) ++#define EC_DEV_IIC EC_DEVICE(2) ++#define EC_DEV_RESET EC_DEVICE(3) ++#define EC_DEV_ATMSAR EC_DEVICE(4) ++#define EC_DEV_MEM EC_DEVICE(5) ++#define EC_DEV_DES EC_DEVICE(6) ++#define EC_DEV_DMA EC_DEVICE(7) ++#define EC_DEV_DSP EC_DEVICE(8) ++#define EC_DEV_TMR EC_DEVICE(9) ++#define EC_DEV_WDT EC_DEVICE(10) ++#define EC_DEV_DCL EC_DEVICE(11) ++#define EC_DEV_BBIF EC_DEVICE(12) ++#define EC_DEV_PCI EC_DEVICE(13) ++#define EC_DEV_XBUS EC_DEVICE(14) ++#define EC_DEV_DSLIF EC_DEVICE(15) ++#define EC_DEV_USB EC_DEVICE(16) ++#define EC_DEV_CLKC EC_DEVICE(17) ++#define EC_DEV_RAPTOR EC_DEVICE(18) ++#define EC_DEV_DSPC EC_DEVICE(19) ++#define EC_DEV_INTC EC_DEVICE(20) ++#define EC_DEV_GPIO EC_DEVICE(21) ++#define EC_DEV_BIST EC_DEVICE(22) ++#define EC_DEV_HDLC EC_DEVICE(23) ++#define EC_DEV_UART EC_DEVICE(24) ++#define EC_DEV_VOIC EC_DEVICE(25) ++/* 9.17.02 (new HAL modules) */ ++#define EC_DEV_CPSAR EC_DEVICE(0x1A) ++#define EC_DEV_AAL5 EC_DEVICE(0x1B) ++#define EC_DEV_AAL2 EC_DEVICE(0x1C) ++#define EC_DEV_CPMAC EC_DEVICE(0x1D) ++#define EC_DEV_VDMA EC_DEVICE(0x1E) ++#define EC_DEV_VLYNQ EC_DEVICE(0x1F) ++#define EC_DEV_CPPI EC_DEVICE(0x20) ++#define EC_DEV_CPMDIO EC_DEVICE(0x21) ++ ++/*--------------------------------------------------------------------------- ++ Function types ++---------------------------------------------------------------------------*/ ++#define EC_FUNC_READ_CONF EC_FUNC(1) ++#define EC_FUNC_INIT EC_FUNC(2) ++ ++/*--------------------------------------------------------------------------- ++ Error codes ++---------------------------------------------------------------------------*/ ++#define EC_CRITICAL (1<State != enDevFound) return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE) ++#define scInit(Module) if (HalDev->State < enInitialized) return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE) ++#define scOpen(Module) if (HalDev->State < enOpened) return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE) ++ ++ ++ ++/******************************************************************** ++** ++** L O C A L F U N C T I O N S ++** ++********************************************************************/ ++static int halIsr(HAL_DEVICE *HalDev, int *MorePackets); ++static int cpmacRandom(HAL_DEVICE *HalDev); ++static int cpmacRandomRange(HAL_DEVICE *HalDev, int min, int max); ++static int halPacketProcessEnd(HAL_DEVICE *HalDev); ++ ++#include "cpcommon_cpmac.c" /*~RC3.02*/ ++#include "cppi_cpmac.c" ++#include "cpmdio.c" /*~RC3.02*/ ++ ++static int MacAddressSave(HAL_DEVICE *HalDev, unsigned char *MacAddr) ++ { ++ int i; ++ int inst = HalDev->inst; ++ ++ HalDev->MacAddr = MacAddr; ++ ++ if(HalDev->debug) ++ { ++ dbgPrintf("MacAddrSave[%d]: ", inst); ++ for (i=0;i<6;i++) ++ dbgPrintf("%X", HalDev->MacAddr[i]); ++ dbgPrintf("\n"); ++ osfuncSioFlush(); ++ } ++ return(EC_NO_ERRORS); ++ } ++static int MacAddressSet(HAL_DEVICE *HalDev) ++ { ++ unsigned char *macadr = &HalDev->MacAddr[0]; ++ int base = HalDev->dev_base; ++ ++ scOpen(EC_CPMAC); ++ CPMAC_MACADDRLO_0(base) = macadr[5]; ++ CPMAC_MACADDRMID(base) = macadr[4]; ++ CPMAC_MACADDRHI(base) = (macadr[0])|(macadr[1]<<8)|(macadr[2]<<16)|(macadr[3]<<24); ++ if(HalDev->debug) ++ { ++ dbgPrintf("MacAddrSet: MacAddr(%d) %X %X %X\n", HalDev->inst, CPMAC_MACADDRLO_0(base), ++ CPMAC_MACADDRMID(base), ++ CPMAC_MACADDRHI(base)); ++ ++ dbgPrintf("Start MAC: %d\n",HalDev->dev_base); ++ osfuncSioFlush(); ++ } ++ return(EC_NO_ERRORS); ++ } ++ ++ ++/* ++ Updates the MacHash registers ++*/ ++static void MacHashSet(HAL_DEVICE *HalDev) ++ { ++ if(HalDev->State < enOpened) ++ return; ++ ++ CPMAC_MACHASH1(HalDev->dev_base) = HalDev->MacHash1; ++ CPMAC_MACHASH2(HalDev->dev_base) = HalDev->MacHash2; ++ if (DBG(11)) ++ dbgPrintf("CPMAC[%X]: MacHash1 0x%08X, MacHash2 0x%08X\n", HalDev->dev_base, CPMAC_MACHASH1(HalDev->dev_base), CPMAC_MACHASH2(HalDev->dev_base)); ++ } ++ ++/* ++ Reads the MacControl register and updates ++ the changable bits. (See MACCONTROL_MASK) ++*/ ++static void RxMBP_EnableSet(HAL_DEVICE *HalDev) ++ { ++ bit32u RxMbpEnable; ++ if(HalDev->State < enOpened) ++ return; ++ RxMbpEnable = CPMAC_RX_MBP_ENABLE(HalDev->dev_base); ++ RxMbpEnable &= ~RX_MBP_ENABLE_MASK; /* Clear out updatable bits */ ++ RxMbpEnable |= HalDev->RxMbpEnable; ++ CPMAC_RX_MBP_ENABLE(HalDev->dev_base) = RxMbpEnable; ++ } ++/* ++ Reads the MacControl register and updates ++ the changable bits. (See MACCONTROL_MASK) ++*/ ++static void MacControlSet(HAL_DEVICE *HalDev) ++ { ++ bit32u MacControl; ++ if(HalDev->State < enOpened) ++ return; ++ MacControl = CPMAC_MACCONTROL(HalDev->dev_base); ++ MacControl &= ~MACCONTROL_MASK; /* Clear out updatable bits */ ++ MacControl |= HalDev->MacControl; ++ if(!(MacControl & MII_EN)) /* If Enable is not set just update register */ ++ CPMAC_MACCONTROL(HalDev->dev_base) = MacControl; ++ else ++ { ++ if(MacControl & CTRL_LOOPBACK) /* Loopback Set */ ++ { ++ /* mii_en is set and loopback is needed, ++ clear mii_en, set loopback, then set mii_en ++ */ ++ MacControl &= ~MII_EN; /* Clear MII_EN */ ++ CPMAC_MACCONTROL(HalDev->dev_base) = MacControl; ++ CPMAC_MACCONTROL(HalDev->dev_base) |= MII_EN; /* Set MII_EN */ ++ HalDev->Linked = 1; /* if in loopback the logically linked */ ++ } ++ else /* If Loopback not set just update */ ++ { ++ CPMAC_MACCONTROL(HalDev->dev_base) = MacControl; ++ } ++ } ++ if(DBG(0)) ++ dbgPrintf("[halMacControlSet]MacControl:%08X\n", CPMAC_MACCONTROL(HalDev->dev_base)); ++ } ++static int UnicastSet(HAL_DEVICE *HalDev) ++ { ++ CPMAC_RX_UNICAST_SET(HalDev->dev_base) = HalDev->RxUnicastSet; ++ CPMAC_RX_UNICAST_CLEAR(HalDev->dev_base) = HalDev->RxUnicastClear; ++ return(EC_NO_ERRORS); ++ } ++ ++ ++static bit32u HashGet(bit8u *Address) ++ { ++ bit32u hash; ++ bit8u tmpval; ++ int i; ++ ++ hash = 0; ++ for( i=0; i<2; i++ ) ++ { ++ tmpval = *Address++; ++ hash ^= (tmpval>>2)^(tmpval<<4); ++ tmpval = *Address++; ++ hash ^= (tmpval>>4)^(tmpval<<2); ++ tmpval = *Address++; ++ hash ^= (tmpval>>6)^(tmpval); ++ } ++ ++ return( hash & 0x3F ); ++ } ++ ++static void HashAdd(HAL_DEVICE *HalDev, bit8u *MacAddress) ++{ ++ bit32u HashValue; ++ bit32u HashBit; ++ ++ HashValue = HashGet(MacAddress); ++ ++ if(HashValue < 32) ++ { ++ HashBit = (1 << HashValue); ++ HalDev->MacHash1 |= HashBit; ++ } ++ else ++ { ++ HashBit = (1 << (HashValue-32)); ++ HalDev->MacHash2 |= HashBit; ++ } ++} ++ ++static void HashDel(HAL_DEVICE *HalDev, bit8u *MacAddress) ++{ ++ bit32u HashValue; ++ bit32u HashBit; ++ ++ HashValue = HashGet(MacAddress); ++ ++ if(HashValue < 32) ++ { ++ HashBit = (1 << HashValue); ++ HalDev->MacHash1 &= ~HashBit; ++ } ++ else ++ { ++ HashBit = (1 << (HashValue-32)); ++ HalDev->MacHash2 &= ~HashBit; ++ } ++} ++ ++/* Replace with an array based on key, with a ptr to the code to do */ ++/* e.g. [enRX_PASS_CRC] = {Set, MBP_UPDATE() } */ ++static void DuplexUpdate(HAL_DEVICE *HalDev) ++{ ++ int base = HalDev->dev_base; ++ PHY_DEVICE *PhyDev = HalDev->PhyDev; ++ ++ if(HalDev->State < enOpened) ++ return; ++ ++ /* No Phy Condition */ ++ if(HalDev->MdioConnect & _CPMDIO_NOPHY) /*MJH+030805*/ ++ { ++ /* No Phy condition, always linked */ ++ HalDev->Linked = 1; ++ HalDev->EmacSpeed = 1; ++ HalDev->EmacDuplex = 1; ++ HalDev->PhyNum = 0xFFFFFFFF; /* No Phy Num */ ++ CPMAC_MACCONTROL(base) |= FULLDUPLEX; /*MJH+030909*/ ++ osfuncStateChange(); ++ return; ++ } ++ ++ if(HalDev->MacControl & CTRL_LOOPBACK) /* Loopback Set */ ++ { ++ HalDev->Linked = 1; ++ return; ++ } ++ ++ if (HalDev->MdioConnect & _CPMDIO_LOOPBK) ++ { ++ HalDev->Linked = cpMacMdioGetLoopback(HalDev->PhyDev); ++ } ++ else ++ { ++ HalDev->Linked = cpMacMdioGetLinked(HalDev->PhyDev); ++ } ++ if (HalDev->Linked) ++ { ++ /* Retreive Duplex and Speed and the Phy Number */ ++ if(HalDev->MdioConnect & _CPMDIO_LOOPBK) ++ HalDev->EmacDuplex = 1; ++ else ++ HalDev->EmacDuplex = cpMacMdioGetDuplex(PhyDev); ++ HalDev->EmacSpeed = cpMacMdioGetSpeed(PhyDev); ++ HalDev->PhyNum = cpMacMdioGetPhyNum(PhyDev); ++ ++ if(HalDev->EmacDuplex) ++ CPMAC_MACCONTROL(base) |= FULLDUPLEX; ++ else ++ CPMAC_MACCONTROL(base) &= ~FULLDUPLEX; ++ if(HalDev->debug) ++ dbgPrintf("%d: Phy= %d, Speed=%s, Duplex=%s\n",HalDev->inst,HalDev->PhyNum,(HalDev->EmacSpeed)?"100":"10",(HalDev->EmacDuplex)?"Full":"Half"); ++ } ++ if(HalDev->debug) ++ dbgPrintf("DuplexUpdate[%d]: MACCONTROL 0x%08X, %s\n", HalDev->inst, CPMAC_MACCONTROL(base),(HalDev->Linked)?"Linked":"Not Linked"); ++} ++static void MdioSetPhyMode(HAL_DEVICE *HalDev) ++ { ++ unsigned int PhyMode; ++ /* Verify proper device state */ ++ if (HalDev->State < enOpened) ++ return; ++ ++ PhyMode = NWAY_AUTO|NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10; ++ if(DBG(0)) ++ { ++ dbgPrintf("halSetPhyMode1: MdioConnect:%08X ,", HalDev->MdioConnect); ++ dbgPrintf("PhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode, ++ PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100, ++ PhyMode&NWAY_HD100); ++ } ++ ++ ++ if ( HalDev->MdioConnect & _CPMDIO_NEG_OFF) /* ~RC3.01 */ ++ PhyMode &= ~(NWAY_AUTO); /* Disable Auto Neg */ ++ if (!(HalDev->MdioConnect & _CPMDIO_HD)) ++ PhyMode &= ~(NWAY_HD100|NWAY_HD10); /* Cannot support HD */ ++ if (!(HalDev->MdioConnect & _CPMDIO_FD)) ++ PhyMode &= ~(NWAY_FD100|NWAY_FD10); /* Cannot support FD */ ++ if (!(HalDev->MdioConnect & _CPMDIO_10)) ++ PhyMode &= ~(NWAY_HD10|NWAY_FD10); /* Cannot support 10 Mbs */ ++ if (!(HalDev->MdioConnect & _CPMDIO_100)) ++ PhyMode &= ~(NWAY_HD100|NWAY_FD100); /* Cannot support 100 Mbs */ ++ ++ if(HalDev->MdioConnect & _CPMDIO_AUTOMDIX) PhyMode |= NWAY_AUTOMDIX; /* Set AutoMdix */ ++ ++ if (HalDev->CpmacFrequency <= 50000000) ++ PhyMode &= ~(NWAY_FD100|NWAY_HD100); /* Cannot support 100 MBS */ ++ if(DBG(7)) ++ dbgPrintf("halNeg: PhyMode[0x%08X] %d\n", HalDev->dev_base, PhyMode); ++ ++ if(DBG(0)) ++ { ++ dbgPrintf("halSetPhyMode2: MdioConnect:%08X ,", HalDev->MdioConnect); ++ dbgPrintf("PhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode, ++ PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100, ++ PhyMode&NWAY_HD100); ++ } ++ ++ ++ cpMacMdioSetPhyMode(HalDev->PhyDev,PhyMode); ++ DuplexUpdate(HalDev); ++ } ++static int StatsClear(HAL_DEVICE *HalDev) ++{ ++ int i; ++ MEM_PTR pStats; ++ ++ scOpen(EC_CPMAC); ++ ++ pStats = pCPMAC_RXGOODFRAMES(HalDev->dev_base); ++ for (i=0;idev_base); ++ ptrValue = (bit32u*) Value; ++ for (i=0; idev_base) = HalDev->RxMaxLen; ++ CPMAC_RX_FILTERLOWTHRESH(HalDev->dev_base) = HalDev->RxFilterLowThresh; ++ CPMAC_RX0_FLOWTHRESH(HalDev->dev_base) = HalDev->Rx0FlowThresh; ++ UnicastSet(HalDev); ++ MacAddressSet(HalDev); ++ RxMBP_EnableSet(HalDev); ++ MacHashSet(HalDev); ++ MacControlSet(HalDev); ++ if(DBG(0)) ++ dbgPrintf("ValuesUpdate[%d]: MBP_ENABLE 0x%08X\n", HalDev->inst, CPMAC_RX_MBP_ENABLE(HalDev->dev_base)); ++ } ++static int halStatus(HAL_DEVICE *HalDev) ++{ ++ int status; ++ ++ if(HalDev->State < enOpened) ++ return (EC_CPMAC|EC_FUNC_STATUS|EC_VAL_INVALID_STATE); /*MJH+030805*/ ++ ++ /* No Phy Condition */ ++ if(HalDev->MdioConnect & _CPMDIO_NOPHY) /*MJH+030805*/ ++ { ++ /* No Phy condition, always linked */ ++ status = HalDev->Linked; ++ status |= CPMAC_STATUS_LINK_DUPLEX; ++ status |= CPMAC_STATUS_LINK_SPEED; ++ return(status); ++ } ++ ++ ++ if (HalDev->HostErr) /* Adapter Check */ ++ { ++ bit32u tmp; ++ status = CPMAC_STATUS_ADAPTER_CHECK; ++ if(HalDev->MacStatus & RX_HOST_ERR_CODE) ++ { ++ status |= CPMAC_STATUS_HOST_ERR_DIRECTION; ++ tmp = (HalDev->MacStatus & RX_HOST_ERR_CODE) >> 12; /* Code */ ++ status |= (tmp << 9); /* Code */ ++ tmp = (HalDev->MacStatus & RX_ERR_CH) >> 8; /* Channel */ ++ status |= (tmp << 13); ++ } ++ else ++ if(HalDev->MacStatus & TX_HOST_ERR_CODE) ++ { ++ status |= CPMAC_STATUS_HOST_ERR_DIRECTION; ++ tmp = (HalDev->MacStatus & TX_HOST_ERR_CODE) >> 20; /* Code */ ++ status |= (tmp << 9); /* Code */ ++ tmp = (HalDev->MacStatus & TX_ERR_CH) >> 16; /* Channel */ ++ status |= (tmp << 13); ++ } ++ } ++ else ++ { ++ status = HalDev->Linked; ++ if(status) ++ { ++ status = CPMAC_STATUS_LINK; ++ if(cpMacMdioGetDuplex(HalDev->PhyDev)) ++ status |= CPMAC_STATUS_LINK_DUPLEX; ++ if(cpMacMdioGetSpeed(HalDev->PhyDev)) ++ status |= CPMAC_STATUS_LINK_SPEED; ++ } ++ } ++ if(HalDev->debug) ++ dbgPrintf("[halStatus] Link Status is %d for 0x%X\n", status, HalDev->dev_base); ++ return(status); ++} ++static int InfoAccess(HAL_DEVICE *HalDev, int Key, int Action, void *ParmValue) ++ { ++ int rc = 0; ++ int Update=0; ++ ++ switch (Key) ++ { ++ /********************************************************************/ ++ /* */ ++ /* GENERAL */ ++ /* */ ++ /********************************************************************/ ++ ++ case enVersion : ++ if(Action==enGET) ++ { ++ *(const char **)ParmValue = pszVersion_CPMAC; ++ } ++ break; ++ case enDebug : ++ if(Action==enSET) ++ { ++ HalDev->debug = *(unsigned int *)ParmValue; ++ } ++ break; ++ ++ case enStatus : ++ if(Action==enGET) ++ { ++ int status; ++ status = halStatus(HalDev); ++ *(int *)ParmValue = status; ++ } ++ break; ++ /********************************************************************/ ++ /* */ ++ /* RX_MBP_ENABLE */ ++ /* */ ++ /********************************************************************/ ++ ++ case enRX_PASS_CRC : ++ if(Action==enSET) ++ { ++ UPDATE_RX_PASS_CRC(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_QOS_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_QOS_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_NO_CHAIN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_NO_CHAIN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_CMF_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_CMF_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_CSF_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_CSF_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_CEF_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_CEF_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_CAF_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_CAF_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_PROM_CH : ++ if(Action==enSET) ++ { ++ UPDATE_RX_PROM_CH(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_BROAD_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_BROAD_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_BROAD_CH : ++ if(Action==enSET) ++ { ++ UPDATE_RX_BROAD_CH(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_MULT_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_MULT_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_MULT_CH : ++ if(Action==enSET) ++ { ++ UPDATE_RX_MULT_CH(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ ++ /********************************************************************/ ++ /* */ ++ /* MAC_CONTROL */ ++ /* */ ++ /********************************************************************/ ++ ++ case enTX_PTYPE : ++ if(Action==enSET) ++ { ++ UPDATE_TX_PTYPE(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enTX_PACE : ++ if(Action==enSET) ++ { ++ UPDATE_TX_PACE(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enTX_FLOW_EN : ++ if(Action==enSET) ++ { ++ UPDATE_TX_FLOW_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_FLOW_EN : ++ if(Action==enSET) ++ { ++ UPDATE_RX_FLOW_EN(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ ++ case enCTRL_LOOPBACK : ++ if(Action==enSET) ++ { ++ UPDATE_CTRL_LOOPBACK(*(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ /********************************************************************/ ++ /* */ ++ /* RX_UNICAST_SET */ ++ /* */ ++ /********************************************************************/ ++ ++ case enRX_UNICAST_SET : ++ if(Action==enSET) ++ { ++ HalDev->RxUnicastSet |= (1 << *(unsigned int *)ParmValue); ++ HalDev->RxUnicastClear &= ~(1 << *(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_UNICAST_CLEAR : ++ if(Action==enSET) ++ { ++ HalDev->RxUnicastClear |= (1 << *(unsigned int *)ParmValue); ++ HalDev->RxUnicastSet &= ~(1 << *(unsigned int *)ParmValue); ++ Update=1; ++ } ++ break; ++ ++ case enRX_MAXLEN : ++ if(Action==enSET) ++ { ++ HalDev->RxMaxLen = *(unsigned int *)ParmValue; ++ Update=1; ++ } ++ break; ++ ++ case enRX_FILTERLOWTHRESH : ++ if(Action==enSET) ++ { ++ HalDev->RxFilterLowThresh = *(unsigned int *)ParmValue; ++ Update=1; ++ } ++ break; ++ case enRX0_FLOWTHRESH : ++ if(Action==enSET) ++ { ++ HalDev->Rx0FlowThresh = *(unsigned int *)ParmValue; ++ Update=1; ++ } ++ break; ++ /********************************************************************/ ++ /* */ ++ /* RX_MULTICAST */ ++ /* */ ++ /********************************************************************/ ++ ++ case enRX_MULTICAST : ++ break; ++ case enRX_MULTI_SINGLE : ++ if(DBG(11)) ++ { ++ int tmpi; ++ bit8u *MacAddress; ++ MacAddress = (bit8u *) ParmValue; ++ dbgPrintf("CPMAC[%X]: MacAddress '", HalDev->dev_base); ++ for (tmpi=0; tmpi<6; tmpi++) ++ dbgPrintf("%02X:", MacAddress[tmpi]); ++ dbgPrintf("\n"); ++ } ++ if(Action==enCLEAR) ++ { ++ HashDel(HalDev, ParmValue); ++ Update=1; ++ } ++ else ++ if(Action==enSET) ++ { ++ HashAdd(HalDev, ParmValue); ++ Update=1; ++ } ++ break; ++ case enRX_MULTI_ALL : ++ if(Action==enCLEAR) ++ { ++ HalDev->MacHash1 = 0; ++ HalDev->MacHash2 = 0; ++ Update=1; ++ } ++ else ++ if(Action==enSET) ++ { ++ HalDev->MacHash1 = 0xFFFFFFFF; ++ HalDev->MacHash2 = 0xFFFFFFFF; ++ Update=1; ++ } ++ break; ++ ++ /********************************************************************/ ++ /* */ ++ /* MDIO */ ++ /* */ ++ /********************************************************************/ ++ ++ case enMdioConnect : ++ if(Action==enSET) ++ { ++ HalDev->MdioConnect = *(unsigned int *)ParmValue; ++ MdioSetPhyMode(HalDev); ++ } ++ if(Action==enGET) ++ { ++ *(unsigned int *)ParmValue = HalDev->MdioConnect; ++ } ++ break; ++ ++ ++ /********************************************************************/ ++ /* */ ++ /* STATISTICS */ ++ /* */ ++ /********************************************************************/ ++ case enStatsClear : ++ StatsClear(HalDev); ++ break; ++ case enStatsDump : ++ if(Action==enGET) ++ { ++ StatsDump(HalDev, ParmValue); ++ } ++ break; ++ ++/* Not implemented ++ case enStats1 : ++ if(Action==enGET) ++ { ++ StatsGet(HalDev, ParmValue, 1); ++ } ++ break; ++ ++ case enStats2 : ++ if(Action==enGET) ++ { ++ StatsGet(HalDev, ParmValue, 2); ++ } ++ break; ++ case enStats3 : ++ if(Action==enGET) ++ { ++ StatsGet(HalDev, ParmValue, 3); ++ } ++ break; ++ case enStats4 : ++ if(Action==enGET) ++ { ++ StatsGet(HalDev, ParmValue, 4); ++ } ++ break; ++ ++*/ ++ ++ default: ++ rc = EC_CPMAC|EC_FUNC_OPTIONS|EC_VAL_KEY_NOT_FOUND; ++ break; ++ } ++ ++ /* Verify proper device state */ ++ if (HalDev->State == enOpened) ++ switch (Update) ++ { ++ case 1 : ++ ConfigApply(HalDev); ++ break; ++ default: ++ break; ++ } ++ ++ return (rc); ++ } ++static const char pszStats[] = "Stats;"; ++ ++static int halControl(HAL_DEVICE *HalDev, const char *pszKey, const char *pszAction, void *Value) ++ { ++ int i; ++ int rc=0; ++ int Action; ++ int ActionFound; ++ int KeyFound; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(1)) ++ { ++ dbgPrintf("\nhalControl-HalDev:%08X,Action:%s,Key:%s\n", (bit32u)HalDev, pszAction, pszKey); ++ } ++#endif ++ ++ /* 23Aug04 - BCIL needs to set Mac Address */ ++ if(HalDev->OsFunc->Strcmpi(pszKey, pszMacAddr) == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ { ++ unsigned char *MacAddr; ++ MacAddr = (unsigned char *) Value; ++ MacAddressSave(HalDev, MacAddr); ++ MacAddressSet(HalDev); ++ return(0); ++ } ++ else ++ { ++ return(-1); ++ } ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, hcLinked) == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ { ++ HalDev->Linked = *(int *)Value; ++ return(0); ++ } ++ else ++ { ++ return(-1); ++ } ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, "TxIntDisable") == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ { ++ HalDev->TxIntDisable = *(int *)Value; ++ if(HalDev->TxIntDisable && (HalDev->State == enOpened)) ++ { ++ /* if Opened and need TxIntDisabled, clear Ints for Channel 0 */ ++ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = 1; ++ } ++ return(0); ++ } ++ else ++ { ++ return(-1); ++ } ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, hcPhyAccess) == 0) ++ { ++ bit32u RegAddr; ++ bit32u PhyNum; ++ bit32u Data; ++ bit32u ValueIn; ++ ++ ValueIn = *(bit32u*) Value; ++ ++ KeyFound=1; ++ /* Cannot access MII if not opended */ ++ ++ if(HalDev->State < enOpened) ++ return(-1); ++ ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) ++ { ++ ++ PhyNum = (ValueIn & 0x1F); /* Phynum 0-32 */ ++ RegAddr = (ValueIn >> 5) & 0xFF; /* RegAddr in upper 11 bits */ ++ ++ *(bit32u*)Value = _mdioUserAccessRead(HalDev->PhyDev, RegAddr, PhyNum); ++ ++ return(0); ++ } /* end of hcGet */ ++ ++ ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ { ++ PhyNum = (ValueIn & 0x1F); /* Phynum 0-32 */ ++ RegAddr = (ValueIn >> 5) & 0xFF; /* RegAddr in upper 11 bits of lower 16 */ ++ ++ Data = ValueIn >> 16; /* Data store in upper 16 bits */ ++ ++ _mdioUserAccessWrite(HalDev->PhyDev, RegAddr, PhyNum, Data); ++ return(0); ++ } ++ } /* End of hcPhyAccess */ ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, hcPhyNum) == 0) ++ { ++ KeyFound=1; ++ if(!HalDev->Linked) ++ return(-1); /* if not linked the no Phy Connected */ ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) ++ { ++ *(int *)Value = HalDev->PhyNum; ++ return(0); ++ } ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, hcCpmacSize) == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) ++ { ++ *(bit32u *)Value = HalDev->CpmacSize; ++ return(0); ++ } ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, hcCpmacBase) == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) ++ { ++ *(int *)Value = HalDev->dev_base; ++ return(0); ++ } ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, hcFullDuplex) == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ { ++ UPDATE_FULLDUPLEX(*(unsigned int *)Value); ++ if(HalDev->State == enOpened) ++ ConfigApply(HalDev); ++ return(0); ++ } ++ else ++ return(-1); ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, pszDebug) == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ { ++ ActionFound=1; ++ HalDev->debug = *(int *)Value; ++ } ++ } ++ ++ if(HalDev->OsFunc->Strcmpi(pszKey, hcMaxFrags) == 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ { ++ ActionFound=1; ++ ++ if ((*(int *)Value) > 0) ++ HalDev->MaxFrags = *(int *)Value; ++ else ++ rc = (EC_AAL5|EC_FUNC_CONTROL|EC_VAL_INVALID_VALUE); ++ } ++ ++ if (HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) ++ { ++ ActionFound=1; ++ ++ *(int *)Value = HalDev->MaxFrags; ++ } ++ } ++ ++ if(HalDev->OsFunc->Strstr(pszKey, pszStats) != 0) ++ { ++ KeyFound=1; ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) ++ { ++ int Level; ++ int Ch; ++ char *TmpKey = (char *)pszKey; ++ ActionFound=1; ++ TmpKey += HalDev->OsFunc->Strlen(pszStats); ++ Level = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ TmpKey++; ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ TmpKey++; ++ osfuncSioFlush(); ++#ifdef __CPHAL_DEBUG ++ if (DBG(1)) ++ { ++ dbgPrintf("\nhalControl-HalDev:%08X, Level:%d, Ch:%d\n", (bit32u)HalDev, Level, Ch); ++ } ++#endif ++ StatsGet(HalDev, (void **)Value, Level, Ch, 0); ++ osfuncSioFlush(); ++ } ++ } ++ ++ ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) ++ Action = enSET; ++ else ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcClear) == 0) ++ Action = enCLEAR; ++ else ++ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) ++ Action = enGET; ++ else ++ Action = enNULL; ++ ++ ++ ++ for(i=enCommonStart+1;iOsFunc->Strcmpi(KeyCommon[i].strKey, pszKey)==0) ++ { ++ rc = InfoAccess(HalDev, KeyCommon[i].enKey, Action, Value); ++ } ++ } ++ for(i=enCpmacStart+1;iOsFunc->Strcmpi(KeyCpmac[i].strKey, pszKey)==0) ++ { ++ rc = InfoAccess(HalDev, KeyCpmac[i].enKey, Action, Value); ++ } ++ } ++/* ++ if (KeyFound == 0) ++ rc = (EC_MODULE|EC_FUNC_CONTROL|EC_VAL_KEY_NOT_FOUND); ++ ++ if (ActionFound == 0) ++ rc = (EC_MODULE|EC_FUNC_CONTROL|EC_VAL_ACTION_NOT_FOUND); ++*/ ++ ++ return(rc); ++ } ++static bit32u ConfigGet(HAL_DEVICE *HalDev) ++ { ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ char *DeviceInfo = HalDev->DeviceInfo; ++ int i = HalDev->inst; ++ bit32u Value; ++ int Error; ++ ++ /* get the configuration parameters common to all modules */ ++ Error = ConfigGetCommon(HalDev); ++ if (Error) return (EC_CPMAC|Error); ++ ++ if (HalDev->debug) ++ { ++ dbgPrintf("ConfigGet: haldev:0x%08X inst:%d base:0x%08X reset:%d\n", (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit); ++ osfuncSioFlush(); ++ } ++ ++ Error = OsFunc->DeviceFindParmUint(DeviceInfo, pszMdioConnect,&Value); /*MJH+030805*/ ++ if(!Error) HalDev->MdioConnect = Value; ++ ++ Error = OsFunc->DeviceFindParmUint(DeviceInfo, "PhyMask",&Value); ++ if(!Error) HalDev->PhyMask = Value; ++ ++ Error = OsFunc->DeviceFindParmUint(DeviceInfo, "MLink",&Value); ++ if(!Error) HalDev->MLinkMask = Value; ++ ++ Error = OsFunc->DeviceFindParmUint(DeviceInfo, hcMdixMask, &Value); ++ if(!Error) ++ HalDev->MdixMask = Value; ++ else ++ HalDev->MdixMask = 0; ++ ++ Error = OsFunc->DeviceFindParmUint(DeviceInfo, hcSize, &Value); /*MJH+030425*/ ++ if(!Error) HalDev->CpmacSize = Value; ++ ++ for(i=enCommonStart+1;iDeviceFindParmUint(DeviceInfo, KeyCommon[i].strKey, (bit32u*)&Value); ++ if(!Error) ++ { ++ InfoAccess(HalDev, KeyCommon[i].enKey, enSET, (bit32u*)&Value); ++ } ++ } ++ for(i=enCpmacStart+1;iDeviceFindParmUint(DeviceInfo, KeyCpmac[i].strKey, (bit32u*)&Value); ++ if(!Error) ++ { ++ InfoAccess(HalDev, KeyCpmac[i].enKey, enSET, (bit32u*)&Value); ++ } ++ } ++ return (EC_NO_ERRORS); ++ } ++ ++ ++static void ConfigInit(HAL_DEVICE *HalDev) ++ { ++ if(HalDev->inst == 0) ++ { ++ HalDev->dev_base = 0xA8610000; ++ HalDev->ResetBit = 17; ++ HalDev->interrupt = 19; ++ HalDev->MLinkMask = 0; ++ HalDev->PhyMask = 0xAAAAAAAA; ++ } ++ else ++ { ++ HalDev->dev_base = 0xA8612800; ++ HalDev->ResetBit = 21; ++ HalDev->interrupt = 33; /*~RC3.02*/ ++ HalDev->MLinkMask = 0; ++ HalDev->PhyMask = 0x55555555; ++ } ++ HalDev->RxMaxLen = 1518; ++ HalDev->MaxFrags = 2; ++ HalDev->MdioConnect = _CPMDIO_HD|_CPMDIO_FD|_CPMDIO_10|_CPMDIO_100|_CPMDIO_AUTOMDIX; ++ HalDev->debug=0xFFFFFFFF; ++ HalDev->debug=0; ++ } ++/* Shuts down the EMAC device ++ * ++ *@param HalDev EMAC instance. This was returned by halOpen() ++ *@param mode Indicates actions to tak on close. ++
++ *PARTIAL - Disable EMAC ++
++ *FULL - Disable EMAC and call OS to free all allocated memory ++ * ++ *@retval ++ * 0 OK ++
++ * Non-Zero Not OK ++ * ++ */ ++static int halInit( HAL_DEVICE *HalDev) ++ { ++ int rc; ++ ++ /* Verify proper device state */ ++ if (HalDev->State != enDevFound) ++ return(EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_INVALID_STATE); ++ ++ /* Configure HAL defaults */ ++ ConfigInit(HalDev); ++ ++ /* Retrieve HAL configuration parameters from data store */ ++ rc = ConfigGet(HalDev); ++ if (rc) return (rc); ++ ++ /* Updated 030403*/ ++ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcCpuFrequency, hcGet, &HalDev->CpuFrequency); /*MJH+030403*/ ++ if(rc) ++ HalDev->CpuFrequency = 20000000; /*20 Mhz default */ /*MJH+030403*/ ++ ++ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcCpmacFrequency, hcGet, &HalDev->CpmacFrequency); /*MJH+030331*/ ++ if(rc) ++ HalDev->CpmacFrequency = HalDev->CpuFrequency/2; /*MJH~030404*/ ++ ++ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcMdioBusFrequency, hcGet, &HalDev->MdioBusFrequency); /*MJH+030402*/ ++ if(rc) ++ HalDev->MdioBusFrequency = HalDev->CpmacFrequency; ++ ++ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcMdioClockFrequency, hcGet, &HalDev->MdioClockFrequency); /*MJH+030402*/ ++ if(rc) ++ HalDev->MdioClockFrequency = 2200000; /* 2.2 Mhz PITS #14 */ ++ ++ ++ /* update device state */ ++ HalDev->State = enInitialized; ++ ++ /* initialize statistics */ ++ StatsInit(HalDev); /* +RC3.02 */ ++ ++ /* -RC3.02 ++ StatsTable3[0].StatPtr = &HalDev->ChData[0].RxBufSize; ++ StatsTable3[1].StatPtr = &HalDev->ChData[0].RxBufferOffset; ++ StatsTable3[2].StatPtr = &HalDev->ChData[0].RxNumBuffers; ++ StatsTable3[3].StatPtr = &HalDev->ChData[0].RxServiceMax; ++ StatsTable3[4].StatPtr = &HalDev->ChData[0].TxNumBuffers; ++ StatsTable3[5].StatPtr = &HalDev->ChData[0].TxNumQueues; ++ StatsTable3[6].StatPtr = &HalDev->ChData[0].TxServiceMax; ++ */ ++ ++ return(EC_NO_ERRORS); ++ } ++static int halProbe(HAL_DEVICE *HalDev) ++ { ++ int inst = HalDev->inst; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ int error_code; ++ ++ if (HalDev->State != enConnected) ++ return (EC_CPMAC|EC_FUNC_PROBE|EC_VAL_INVALID_STATE); ++ ++ if(HalDev->debug) dbgPrintf("halProbe: %d ",inst); ++ ++ error_code = OsFunc->DeviceFindInfo(inst,"cpmac",&HalDev->DeviceInfo); ++ ++ if(error_code) ++ return (EC_CPMAC|EC_FUNC_PROBE|EC_VAL_DEVICE_NOT_FOUND ); ++ ++ /* Set device state to DevFound */ ++ HalDev->State = enDevFound; ++ return(EC_NO_ERRORS); ++ } ++static void ChannelConfigInit(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ int Ch = HalChn->Channel; ++ int Direction = HalChn->Direction; ++ int nTxBuffers = 256; ++ ++ if (Direction == DIRECTION_TX) ++ { ++ HalDev->ChData[Ch].TxNumBuffers = nTxBuffers; ++ HalDev->ChData[Ch].TxNumQueues = 1; ++ HalDev->ChData[Ch].TxServiceMax = nTxBuffers/3; ++ HalDev->TxIntThreshold[Ch] = HalDev->ChData[Ch].TxServiceMax; ++ HalDev->TxIntThresholdMaster[Ch] = HalDev->TxIntThreshold[Ch]; ++ } ++ ++ if (Direction == DIRECTION_RX) ++ { ++ HalDev->ChData[Ch].RxNumBuffers = nTxBuffers*2; ++ HalDev->ChData[Ch].RxBufferOffset = 0; ++ HalDev->ChData[Ch].RxBufSize = 1518; ++ HalDev->ChData[Ch].RxServiceMax = nTxBuffers/3; /*Not a typo*/ ++ } ++ } ++static int ChannelConfigApply(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ int Ch = HalChn->Channel; ++ int Direction = HalChn->Direction; ++ ++ if (DBG(11)) ++ { ++ dbgPrintf("halChannelConfigApply[%d:%d] haldev:0x%08X inst:%d base:0x%08X reset:%d\n", Ch, Direction, (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit); ++ osfuncSioFlush(); ++ } ++ ++ if (Direction == DIRECTION_TX) ++ { ++ if (HalDev->ChIsOpen[Ch][Direction] == TRUE) ++ { ++ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_TX_CH_ALREADY_OPEN); ++ } ++ ++ /* Initialize Queue Data */ ++ HalDev->TxActQueueHead[Ch][0] = 0; ++ HalDev->TxActQueueCount[Ch][0] = 0; ++ HalDev->TxActive[Ch][0] = FALSE; ++ ++ /* Need to use a macro that takes channel as input */ ++ CPMAC_TX0_HDP(HalDev->dev_base)=0; ++ ++ /* Initialize buffer memory for the channel */ ++ InitTcb(HalDev, Ch); ++ ++ if(!HalDev->TxIntDisable) ++ CPMAC_TX_INTMASK_SET(HalDev->dev_base) = (1<ChIsOpen[Ch][Direction] == TRUE) ++ { ++ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_RX_CH_ALREADY_OPEN); ++ } ++ ++ /* Initialize Queue Data */ ++ HalDev->RxActQueueHead[Ch] = 0; ++ HalDev->RxActQueueCount[Ch] = 0; ++ ++ HalDev->RxActive[Ch] = FALSE; ++ ++ /* Need to use a macro that takes channel as input */ ++ CPMAC_RX0_HDP(HalDev->dev_base)=0; ++ ++ /* Initialize buffer memory for the channel */ ++ InitRcb(HalDev, Ch); ++ ++ CPMAC_RX_INTMASK_SET(HalDev->dev_base) = (1<ChIsOpen[Ch][Direction] = TRUE; /* channel is open */ ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/* GSG 11/22 ++ * Retrieves channel parameters from configuration file. Any parameters ++ * which are not found are ignored, and the HAL default value will apply, ++ * unless a new value is given through the channel structure in the call ++ * to ChannelSetup. ++ */ ++static int ChannelConfigGet(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ int Ch = HalChn->Channel; ++ int Direction = HalChn->Direction; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ unsigned int rc, Value; ++ void *ChInfo; ++ ++ rc=OsFunc->DeviceFindParmValue(HalDev->DeviceInfo, channel_names[Ch], &ChInfo); ++ /* Do not fail if Channel Info not available for RC2 */ ++ if (rc) return(0); ++/* if (rc) return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_CH_INFO_NOT_FOUND);*/ ++ ++ /* i don't care if a value is not found because they are optional */ ++ if(Direction == DIRECTION_TX) ++ { ++ rc=OsFunc->DeviceFindParmUint(ChInfo, "TxNumBuffers", &Value); ++ if (!rc) HalDev->ChData[Ch].TxNumBuffers = Value; ++ ++ /*rc=OsFunc->DeviceFindParmUint(ChInfo, "TxNumQueues", &Value);*/ /*MJH-030329*/ ++ /*if (!rc) HalDev->ChData[Ch].TxNumQueues = Value;*/ /*MJH-030329*/ ++ ++ rc=OsFunc->DeviceFindParmUint(ChInfo, "TxServiceMax", &Value); ++ if (!rc) ++ { ++ HalDev->ChData[Ch].TxServiceMax = Value; ++ HalDev->TxIntThreshold[Ch] = HalDev->ChData[Ch].TxServiceMax; ++ HalDev->TxIntThresholdMaster[Ch] = HalDev->TxIntThreshold[Ch]; ++ } ++ } ++ if(Direction == DIRECTION_RX) ++ { ++ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxNumBuffers", &Value); ++ if (!rc) HalDev->ChData[Ch].RxNumBuffers = Value; ++ ++ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxBufferOffset", &Value); ++ if (!rc) HalDev->ChData[Ch].RxBufferOffset = Value; ++ ++ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxBufSize", &Value); ++ if (!rc) HalDev->ChData[Ch].RxBufSize = Value; ++ ++ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxServiceMax", &Value); ++ if (!rc) HalDev->ChData[Ch].RxServiceMax = Value; ++ } ++ return (EC_NO_ERRORS); ++ } ++#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field ++ ++static void ChannelConfigUpdate(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ int Ch = HalChn->Channel; ++ int Direction = HalChn->Direction; ++#ifdef __CPHAL_DEBUG ++ if (DBG(1)) ++ { ++ dbgPrintf("\nChnUpd-HalDev:%08X,Chn:%d:%d\n", (bit32u)HalDev, Ch, Direction); osfuncSioFlush(); ++ } ++#endif ++ if (Direction == DIRECTION_TX) ++ { ++ ChannelUpdate(TxNumBuffers); ++ /*ChannelUpdate(TxNumQueues);*/ /*MJH~030329*/ ++ ChannelUpdate(TxServiceMax); ++ HalDev->TxIntThreshold[Ch] = HalDev->ChData[Ch].TxServiceMax; ++ HalDev->TxIntThresholdMaster[Ch] = HalDev->TxIntThreshold[Ch]; ++ } ++ else ++ if (Direction == DIRECTION_RX) ++ { ++ ChannelUpdate(RxBufferOffset); ++ ChannelUpdate(RxBufSize); ++ ChannelUpdate(RxNumBuffers); ++ ChannelUpdate(RxServiceMax); ++#ifdef __CPHAL_DEBUG ++ if (DBG(1)) ++ { ++ dbgPrintf("\nRxNumBuffers %d\n",HalChn->RxNumBuffers); osfuncSioFlush(); ++ } ++#endif ++ } ++ } ++static int halChannelSetup(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn, OS_SETUP *OsSetup) ++ { ++ int Direction; ++ int Ch; ++ int rc; ++ ++ /* Verify proper device state */ ++ if (HalDev->State < enInitialized) ++ return (EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE); ++ ++ /* We require the channel structure to be passed, even if it only contains ++ the channel number */ ++ if (HalChn == NULL) ++ { ++ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_NULL_CH_STRUCT); ++ } ++ ++ Ch = HalChn->Channel; ++ Direction = HalChn->Direction; ++ ++ /* This should check on Maximum Channels for RX or TX, ++ they might be different Mick 021124 */ ++ if ((Ch < 0) || (Ch > (MAX_CHAN-1))) ++ { ++ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_INVALID_CH); ++ } ++ ++ /* if channel is already open, this call is invalid */ ++ if (HalDev->ChIsOpen[Ch][Direction] == TRUE) ++ { ++ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_CH_ALREADY_OPEN); ++ } ++ ++ /* channel is closed, but might be setup. If so, reopen the hardware channel. */ ++ if (HalDev->ChIsSetup[Ch][Direction] == FALSE) ++ { ++ /* Setup channel configuration */ ++ HalDev->ChData[Ch].Channel = Ch; ++ ++ /* Store OS_SETUP */ ++ HalDev->ChData[Ch].OsSetup = OsSetup; ++ ++ /* Framework : ++ Set Default Values ++ Update with options.conf ++ Apply driver updates ++ */ ++ ChannelConfigInit(HalDev, HalChn); ++ ChannelConfigGet(HalDev, HalChn); ++ ChannelConfigUpdate(HalDev, HalChn); ++ ++ /* cppi.c needs to use Rx/TxServiceMax */ ++ HalDev->BuffersServicedMax = 169; /* TEMP */ ++ ++ HalDev->ChIsSetup[Ch][Direction] = TRUE; ++ } ++ ++ rc = EC_NO_ERRORS; ++ ++ /* If the hardware has been opened (is out of reset), then configure the channel ++ in the hardware. NOTE: ChannelConfigApply calls the CPSAR ChannelSetup()! */ ++ if (HalDev->State == enOpened) ++ { ++ rc = ChannelConfigApply(HalDev, HalChn); ++ } ++ ++ return (rc); ++ } ++ ++ ++static int miiInfoGet(HAL_DEVICE *HalDev, bit32u *miiBaseAddress, bit32u *miiResetBit) ++ { ++ int rc; ++ void *DeviceInfo; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ ++ /* Only one instance of cpmdio */ ++ rc = OsFunc->DeviceFindInfo(0,"cpmdio",&DeviceInfo); /*~RC3.02*/ ++ ++ if(rc) ++ return (EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_DEVICE_NOT_FOUND ); ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",miiBaseAddress); ++ if(rc) ++ rc=EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_NO_BASE; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",miiResetBit); ++ if(rc) ++ rc=EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_NO_BASE; ++ ++ ++ /* See if need to make mdio functional in GPIO */ ++ gpioCheck(HalDev, DeviceInfo); ++ ++ if(DBG(0)) ++ dbgPrintf("miiBase: 0x%08X %u\n", *miiBaseAddress, *miiResetBit); ++ return(rc); ++ } ++static void ephyCheck(HAL_DEVICE *HalDev) ++ { /*+RC3.02*/ ++ int rc; ++ void *DeviceInfo; ++ int mii_phy; ++ int reset_bit; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ ++ rc = OsFunc->DeviceFindInfo(0,"ephy",&DeviceInfo); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "mii_phy",&mii_phy); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit); ++ if(rc) return; ++ ++ if (HalDev->PhyMask & (1 << mii_phy)) ++ { ++ *(volatile bit32u *)(HalDev->ResetBase) |= (1 << reset_bit); /*+RC3.02*/ ++ resetWait(HalDev); ++ } ++ } /*+RC3.02*/ ++static void AutoNegotiate(HAL_DEVICE *HalDev) ++ { ++ int size; ++ bit32u ModID, RevMaj, RevMin; ++ PHY_DEVICE *PhyDev; ++ bit32u miiBaseAddress; ++ bit32u miiResetBit; ++ ++ /* Verify proper device state */ ++ if (HalDev->State < enOpened) ++ return; ++ ++ miiInfoGet(HalDev, &miiBaseAddress, &miiResetBit); ++ ++ cpMacMdioGetVer(miiBaseAddress, &ModID, &RevMaj, &RevMin); ++ if(HalDev->debug) ++ dbgPrintf("Mdio Module Id %d, Version %d.%d\n", ModID, RevMaj, RevMin); ++ ++ size = cpMacMdioGetPhyDevSize(); ++ PhyDev = (PHY_DEVICE *) HalDev->OsFunc->Malloc( size ); ++ ++ HalDev->PhyDev = PhyDev; ++ ++ ephyCheck(HalDev); ++ ++ cpMacMdioInit( PhyDev, miiBaseAddress, HalDev->inst, HalDev->PhyMask, HalDev->MLinkMask, HalDev->MdixMask, HalDev->ResetBase, miiResetBit, HalDev->MdioBusFrequency, HalDev->MdioClockFrequency, HalDev->debug, HalDev); /*MJH~030402*/ ++ MdioSetPhyMode(HalDev); ++ ++ return; ++ } ++static int halOpen(HAL_DEVICE *HalDev) ++ { ++ unsigned char *MacAddr; ++ int i; ++ int j; ++ int rc, Ticks; ++ ++ if (HalDev->debug) ++ { ++ dbgPrintf("halOpen: haldev:0x%08X inst:%d base:0x%08X reset:%d\n", (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit); ++ osfuncSioFlush(); ++ } ++ ++ /* Verify proper device state */ ++ if (HalDev->State < enInitialized) ++ return (EC_CPMAC|EC_FUNC_OPEN|EC_VAL_INVALID_STATE); ++ ++ ++ /* take CPMAC out of reset - GSG 11/20*/ ++ if ((VOLATILE32(HalDev->ResetBase) & (1 << HalDev->ResetBit)) != 0) ++ { ++ /* perform normal close duties */ ++ CPMAC_MACCONTROL(HalDev->dev_base) &= ~MII_EN; ++ CPMAC_TX_CONTROL(HalDev->dev_base) &= ~TX_EN; ++ CPMAC_RX_CONTROL(HalDev->dev_base) &= ~RX_EN; ++ ++ /* disable interrupt masks */ ++ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = 0xFF; ++ CPMAC_RX_INTMASK_CLEAR(HalDev->dev_base) = 0xFF; ++ } ++ ++ /* take CPMAC out of reset */ ++ *(volatile bit32u *)(HalDev->ResetBase) &= ~(1 << HalDev->ResetBit); ++ resetWait(HalDev); ++ *(volatile bit32u *)(HalDev->ResetBase) |= (1 << HalDev->ResetBit); ++ resetWait(HalDev); ++ ++ /* After Reset clear the Transmit and Receive DMA Head Descriptor Pointers */ ++ ++ CPMAC_TX0_HDP(HalDev->dev_base)=0; ++ CPMAC_TX1_HDP(HalDev->dev_base)=0; ++ CPMAC_TX2_HDP(HalDev->dev_base)=0; ++ CPMAC_TX3_HDP(HalDev->dev_base)=0; ++ CPMAC_TX4_HDP(HalDev->dev_base)=0; ++ CPMAC_TX5_HDP(HalDev->dev_base)=0; ++ CPMAC_TX6_HDP(HalDev->dev_base)=0; ++ CPMAC_TX7_HDP(HalDev->dev_base)=0; ++ ++ /* Rx Init */ ++ ++ CPMAC_RX0_HDP(HalDev->dev_base) = 0; ++ CPMAC_RX1_HDP(HalDev->dev_base) = 0; ++ CPMAC_RX2_HDP(HalDev->dev_base) = 0; ++ CPMAC_RX3_HDP(HalDev->dev_base) = 0; ++ CPMAC_RX4_HDP(HalDev->dev_base) = 0; ++ CPMAC_RX5_HDP(HalDev->dev_base) = 0; ++ CPMAC_RX6_HDP(HalDev->dev_base) = 0; ++ CPMAC_RX7_HDP(HalDev->dev_base) = 0; ++ ++ CPMAC_RX_BUFFER_OFFSET(HalDev->dev_base) = 0; ++ ++ /* Init Tx and Rx DMA */ ++ ++ CPMAC_TX_CONTROL(HalDev->dev_base) |= TX_EN; ++ CPMAC_RX_CONTROL(HalDev->dev_base) |= RX_EN; ++ ++ CPMAC_MAC_INTMASK_SET(HalDev->dev_base) |=2; /* Enable Adaptercheck Ints */ ++ HalDev->OsFunc->Control(HalDev->OsDev, pszMacAddr, hcGet, &MacAddr); /* GSG 11/22 */ ++ MacAddressSave(HalDev, MacAddr); ++ ++ HalDev->HostErr = 0; /* Clear Adapter Check indicator */ ++ HalDev->State = enOpened; /* Change device state */ ++ ++ /* Start MDIO Negotiation */ ++ AutoNegotiate(HalDev); ++ ++ /* Enable the Os Timer */ ++ Ticks = HalDev->CpuFrequency / 100; /* 10 milli-secs */ /*MJH~030402*/ ++ HalDev->OsFunc->Control(HalDev->OsDev, pszTick, hcSet, &Ticks); /* GSG 11/22 */ ++ HalDev->OsFunc->IsrRegister(HalDev->OsDev, halIsr, HalDev->interrupt); ++ ++ /* GSG +030523 Malloc space for the Rx fraglist */ ++ HalDev->fraglist = HalDev->OsFunc->Malloc(HalDev->MaxFrags * sizeof(FRAGLIST)); ++ ++ /* Any pre-open configuration */ ++ ++ /* For any channels that have been pre-initialized, set them up now */ ++ /* Note : This loop should not use MAX_CHN, it should only ++ loop through Channels Setup, memory should not be reserved ++ until Channel is Setup ++ */ ++ for(i=0; iChIsSetup[i][j]==TRUE) /* If the Channel and Direction have been Setup */ ++ if(HalDev->ChIsOpen[i][j]==FALSE) /* but not opened, then Apply Values now */ ++ { ++ CHANNEL_INFO HalChn; ++ HalChn.Channel = i; ++ HalChn.Direction = j; ++ rc = ChannelConfigApply(HalDev, &HalChn); ++ if(rc != EC_NO_ERRORS) ++ return(rc); ++ } ++ } /* End of looping through Channel/Direction */ ++ ++ ConfigApply(HalDev); /* Apply Configuration Values to Device */ ++ CPMAC_MACCONTROL(HalDev->dev_base) |= MII_EN; /* MAC_EN */ ++ if(DBG(0)) ++ dbgPrintf("[halOpen]MacControl:%08X\n", CPMAC_MACCONTROL(HalDev->dev_base)); ++ return(EC_NO_ERRORS); ++ } ++ ++#define INT_PENDING (MAC_IN_VECTOR_TX_INT_OR | MAC_IN_VECTOR_RX_INT_OR | MAC_IN_VECTOR_HOST_INT) ++static int halShutdown(HAL_DEVICE *HalDev) ++ { ++ int Ch, Queue; /*GSG+030514*/ ++ ++ /* Verify proper device state */ ++ if (HalDev->State == enOpened) ++ halClose(HalDev, 3); /* GSG ~030429 */ ++ ++ /* Buffer/descriptor resources may still need to be freed if a Close ++ Mode 1 was performed prior to Shutdown - clean up here */ /*GSG+030514*/ ++ for (Ch=0; ChRcbStart[Ch] != 0) ++ FreeRx(HalDev,Ch); ++ ++ for(Queue=0; QueueTcbStart[Ch][Queue] != 0) ++ FreeTx(HalDev,Ch,Queue); ++ } ++ } ++ ++ /* free the HalFunc */ ++ HalDev->OsFunc->Free(HalDev->HalFuncPtr); ++ ++ /* free the HAL device */ ++ HalDev->OsFunc->Free(HalDev); ++ ++ return(EC_NO_ERRORS); ++ } ++int halIsr(HAL_DEVICE *HalDev, int *MorePackets) ++{ ++ bit32u IntVec; ++ int Serviced; ++ int PacketsServiced=0; ++ int Channel; ++ int TxMorePackets=0; ++ int RxMorePackets=0; ++ ++ /* Verify proper device state - important because a call prior to Open would ++ result in a lockup */ ++ if (HalDev->State != enOpened) ++ return(EC_CPMAC|EC_FUNC_DEVICE_INT|EC_VAL_INVALID_STATE); ++ ++ IntVec = CPMAC_MAC_IN_VECTOR(HalDev->dev_base); ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("\nhalIsr: inst %d, IntVec 0x%X\n", HalDev->inst, IntVec); osfuncSioFlush();/* GSG 11/22 */ ++ } ++#endif ++ ++ HalDev->IntVec = IntVec; ++ if (IntVec & MAC_IN_VECTOR_TX_INT_OR) ++ { ++ int TxServiceMax=0; /* Compiler complains if not initialized */ ++ ++ Channel = (IntVec & 0x7); ++ ++ if(HalDev->TxIntDisable) ++ { ++ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = (1<ChData[Channel].TxServiceMax; ++ HalDev->ChData[Channel].TxServiceMax = 10000; /* Need to service all packets in the Queue */ ++ } ++ ++ PacketsServiced |= TxInt(HalDev, Channel, 0, &TxMorePackets); ++ ++ if(HalDev->TxIntDisable) ++ HalDev->ChData[Channel].TxServiceMax = TxServiceMax; ++ } ++ ++ if (IntVec & MAC_IN_VECTOR_RX_INT_OR) ++ { ++ Channel = (IntVec >> 8) & 0x7; ++ Serviced = RxInt(HalDev, Channel, &RxMorePackets); ++ PacketsServiced |= (Serviced<<16); ++ } ++ ++ if (IntVec & MAC_IN_VECTOR_HOST_INT) ++ { ++ /* Adaptercheck */ ++ HalDev->HostErr = 1; ++ HalDev->MacStatus = CPMAC_MACSTATUS(HalDev->dev_base); ++ osfuncStateChange(); /*MJH+030328*/ ++ if(DBG(0)) ++ { ++ dbgPrintf("Adaptercheck: %08x for base:%X\n",HalDev->MacStatus, (bit32u)HalDev->dev_base); ++ osfuncSioFlush(); ++ } ++ } ++ *MorePackets = (TxMorePackets | RxMorePackets); ++ return (PacketsServiced); ++} ++ ++int halPacketProcessEnd(HAL_DEVICE *HalDev) ++{ ++ int base = HalDev->dev_base; ++ CPMAC_MAC_EOI_VECTOR(base) = 0; ++ return(0); ++} ++ ++ ++ ++static int PhyCheck(HAL_DEVICE *HalDev) ++ { ++ return(cpMacMdioTic(HalDev->PhyDev)); ++ } ++static int halTick(HAL_DEVICE *HalDev) ++{ ++ int TickChange; ++ ++ if(HalDev->State < enOpened) ++ return (EC_CPMAC|EC_FUNC_TICK|EC_VAL_INVALID_STATE); ++ ++ /* if NO Phy no need to check Link */ ++ if(HalDev->MdioConnect & _CPMDIO_NOPHY) ++ return(EC_NO_ERRORS); /* No change in Phy State detected */ ++ ++ TickChange = PhyCheck(HalDev); ++ /* Phy State Change Detected */ ++ if(TickChange == 1) ++ { ++ /* MDIO indicated a change */ ++ DuplexUpdate(HalDev); ++ osfuncStateChange(); ++ return(EC_NO_ERRORS); ++ } ++ ++ /* if in AutoMdix mode, and Flip request received, inform OS */ ++ if( (HalDev->MdioConnect & _CPMDIO_AUTOMDIX) && ++ (TickChange & _MIIMDIO_MDIXFLIP)) ++ { ++ bit32u Mdix; ++ Mdix = TickChange & 0x1; /* Mdix mode stored in bit 0 */ ++ HalDev->OsFunc->Control(HalDev->OsDev, hcMdioMdixSwitch, hcSet, &Mdix); ++ return(EC_NO_ERRORS); ++ } ++ ++ return(EC_NO_ERRORS); ++} ++ ++int halCpmacInitModule(HAL_DEVICE **pHalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS **pHalFunc, ++ OS_FUNCTIONS *OsFunc, int OsFuncSize, int *HalFuncSize, int Inst) ++ { ++ HAL_DEVICE *HalDev; ++ HAL_FUNCTIONS *HalFunc; ++ ++ if (OsFuncSize < sizeof(OS_FUNCTIONS)) ++ return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_OS_VERSION_NOT_SUPPORTED); ++ ++ HalDev = (HAL_DEVICE *) OsFunc->MallocDev(sizeof(HAL_DEVICE)); ++ if (!HalDev) ++ return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_DEV_FAILED); ++ ++ /* clear the HalDev area */ ++ OsFunc->Memset(HalDev, 0, sizeof(HAL_DEVICE)); ++ ++ /* Initialize the size of hal functions */ ++ *HalFuncSize = sizeof (HAL_FUNCTIONS); ++ ++ HalFunc = (HAL_FUNCTIONS *) OsFunc->Malloc(sizeof(HAL_FUNCTIONS)); ++ if (!HalFunc) ++ return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_FAILED); ++ ++ /* clear the function pointers */ ++ OsFunc->Memset(HalFunc, 0, sizeof(HAL_FUNCTIONS)); ++ ++ HalDev->OsDev = OsDev; ++ HalDev->OsOpen = OsDev; ++ HalDev->inst = Inst; ++ HalDev->OsFunc = OsFunc; ++ HalDev->HalFunc = HalFunc; ++ /* Remove the following from cppi, replace with HalFunc */ ++ HalDev->HalFuncPtr = HalFunc; /* GSG 11/20 changed name to match cppi */ ++ ++ /****************************************************************/ ++ /* POPULATE HALFUNC */ ++ /****************************************************************/ ++ HalFunc->ChannelSetup = halChannelSetup; ++ HalFunc->ChannelTeardown = halChannelTeardown; /* GSG 11/20 */ ++ HalFunc->Close = halClose; /* GSG 11/20 */ ++ HalFunc->Control = halControl; /* GSG 11/22 */ ++ HalFunc->Init = halInit; ++ HalFunc->Open = halOpen; ++ HalFunc->PacketProcessEnd = halPacketProcessEnd; ++ HalFunc->Probe = halProbe; ++ HalFunc->RxReturn = halRxReturn; ++ HalFunc->Send = halSend; ++ HalFunc->Shutdown = halShutdown; ++ HalFunc->Tick = halTick; ++ ++ /* HalFunc->Status = halStatus;*/ /* GSG 11/22 */ ++ /* pass the HalDev and HalFunc back to the caller */ ++ ++ *pHalDev = HalDev; ++ *pHalFunc = HalFunc; ++ ++ HalDev->State = enConnected; /* Initialize the hardware state */ ++ ++ if (HalDev->debug) HalDev->OsFunc->Printf("halCpmacInitModule: Leave\n"); ++ return(0); ++ } ++ ++int cpmacRandomRange(HAL_DEVICE *HalDev, int min, int max) ++{ ++ int iTmp; ++ iTmp = cpmacRandom(HalDev); ++ iTmp %= ((max-min)+1); ++ iTmp += min; ++ return(iTmp); ++} ++ ++int cpmacRandom(HAL_DEVICE *HalDev) ++{ ++ int iTmp; ++ iTmp = CPMAC_BOFFTEST(HalDev->dev_base); ++ iTmp >>= 16; /* get rndnum field */ ++ iTmp &= (0x3FF); /* field is 10 bits wide */ ++ return(iTmp); ++} +diff -urN linux.old/drivers/net/avalanche_cpmac/hcpmac.h linux.dev/drivers/net/avalanche_cpmac/hcpmac.h +--- linux.old/drivers/net/avalanche_cpmac/hcpmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/hcpmac.h 2005-07-12 02:48:42.175574000 +0200 +@@ -0,0 +1,383 @@ ++/** @file*********************************************************************** ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: ++ * ++ * DESCRIPTION: ++ * This file contains definitions for the HAL EMAC API ++ * ++ * HISTORY: ++ * xxXxx01 Denis 1.00 Original Version created. ++ * 22Jan02 Denis/Mick 1.01 Modified for HAL EMAC API ++ * 24Jan02 Denis/Mick 1.02 Speed Improvements ++ * 28Jan02 Denis/Mick 1.16 Made function calls pointers ++ * 28Jan02 Mick 1.18 Split into separate modules ++ * @author Michael Hanrahan ++ * @version 1.02 ++ * @date 24-Jan-2002 ++ *****************************************************************************/ ++#ifndef _INC_HCPMAC ++#define _INC_HCPMAC ++ ++/** \namespace CPMAC_Version ++This documents version 01.07.04 of the CPMAC CPHAL. ++*/ ++const char *pszVersion_CPMAC="CPMAC 01.07.08 "__DATE__" "__TIME__; ++ ++/* CHECK THESE LOCATIONS */ ++#define TEARDOWN_VAL 0xfffffffc ++#define CB_OFFSET_MASK 0xFFFF0000 ++ ++ ++#define MAX_CHAN 8 ++#define MAX_QUEUE 1 ++ ++typedef struct ++ { ++ bit32 HNext; /*< Hardware's pointer to next buffer descriptor */ ++ bit32 BufPtr; /*< Pointer to the data buffer */ ++ bit32 Off_BLen; /*< Contains buffer offset and buffer length */ ++ bit32 mode; /*< SOP, EOP, Ownership, EOQ, Teardown, Q Starv, Length */ ++ void *Next; ++ void *OsInfo; ++ void *Eop; ++#ifdef __CPHAL_DEBUG ++ bit32 DbgSop; ++ bit32 DbgData; ++ bit32 DbgFraglist; ++#endif ++ }HAL_TCB; ++ ++typedef volatile struct hal_private ++ { ++ bit32 HNext; /*< Hardware's pointer to next buffer descriptor */ ++ bit32 BufPtr; /*< Pointer to the data buffer */ ++ bit32 Off_BLen; /*< Contains buffer offset and buffer length */ ++ bit32 mode; /*< SOP, EOP, Ownership, EOQ, Teardown Complete bits */ ++ void *DatPtr; ++ void *Next; ++ void *OsInfo; ++ void *Eop; ++ }HAL_RCB; ++ ++#define MAX_NEEDS 512 /*MJH+030409*/ ++/* HAL */ ++ ++typedef struct hal_device ++ { ++ OS_DEVICE *OsDev; ++ OS_FUNCTIONS *OsFunc; ++ /*OS_SETUP *OsSetup;*/ /* -GSG 030508 */ ++ int inst; ++ bit32u rxbufseq; ++ ++ ++ bit32 dev_base; ++ bit32 offset; ++ ++ bit32u ResetBase; /* GSG 10/20 */ ++ int ResetBit; ++ void *OsOpen; ++ bit32u IntVec; ++ PHY_DEVICE *PhyDev; ++ bit32u EmacDuplex; ++ bit32u EmacSpeed; ++ bit32u PhyNum; ++ bit32u MLinkMask; ++ bit32u PhyMask; ++ bit32u MdixMask; ++ ++ bit32u Linked; ++ DEVICE_STATE State; ++ unsigned char *MacAddr; ++ HAL_FUNCTIONS *HalFuncPtr; /* GSG 11/20 changed name to match cppi */ ++ HAL_FUNCTIONS *HalFunc; ++/* unsigned int CpuFreq;*/ /*MJH-030402*/ ++ unsigned int MdioConnect; ++ unsigned int HostErr; ++ ++/************************************************************************/ ++/* */ ++/* R E G I S T E R S */ ++/* */ ++/************************************************************************/ ++ ++ bit32u RxMbpEnable; ++ bit32u RxUnicastSet; ++ bit32u RxUnicastClear; ++ bit32u RxMaxLen; ++ bit32u RxFilterLowThresh; ++ bit32u Rx0FlowThresh; ++ bit32u MacControl; ++ bit32u MacStatus; ++ bit32u MacHash1; ++ bit32u MacHash2; ++ ++/************************************************************************/ ++/* */ ++/* O P T I O N S */ ++/* */ ++/************************************************************************/ ++ ++ char *DeviceInfo; ++ bit32u interrupt; ++ ++ ++ bit32u RxPassCrc; ++ bit32u RxCaf; ++ bit32u RxCef; ++ bit32u RxBcast; ++ bit32u RxBcastCh; ++ HAL_RCB *RcbPool[MAX_CHAN]; ++ bit32 RxActQueueCount[MAX_CHAN]; ++ HAL_RCB *RxActQueueHead[MAX_CHAN]; ++ HAL_RCB *RxActQueueTail[MAX_CHAN]; ++ bit32 RxActive[MAX_CHAN]; ++ HAL_TCB *TcbPool[MAX_CHAN][MAX_QUEUE]; ++ bit32 TxActQueueCount[MAX_CHAN][MAX_QUEUE]; ++ HAL_TCB *TxActQueueHead[MAX_CHAN][MAX_QUEUE]; ++ HAL_TCB *TxActQueueTail[MAX_CHAN][MAX_QUEUE]; ++ bit32 TxActive[MAX_CHAN][MAX_QUEUE]; ++ bit32 TxTeardownPending[MAX_CHAN]; ++ bit32 RxTeardownPending[MAX_CHAN]; ++ bit32 ChIsOpen[MAX_CHAN][2]; ++ bit32 ChIsSetup[MAX_CHAN][2]; ++ FRAGLIST *fraglist; ++ char *TcbStart[MAX_CHAN][MAX_QUEUE]; ++ char *RcbStart[MAX_CHAN]; ++ bit32 RcbSize[MAX_CHAN]; ++/* STAT_INFO Stats; */ ++ bit32 Inst; ++ bit32u BuffersServicedMax; ++ CHANNEL_INFO ChData[MAX_CHAN]; ++ bit32u MdioClockFrequency; /*MJH+030402*/ ++ bit32u MdioBusFrequency; /*MJH+030402*/ ++ bit32u CpuFrequency; /*MJH+030402*/ ++ bit32u CpmacFrequency; /*MJH+030403*/ ++ bit32u CpmacSize; /*MJH+030425*/ ++ int debug; ++ bit32u NeedsCount; /*MJH+030409*/ ++ HAL_RECEIVEINFO *Needs[MAX_NEEDS]; /*MJH+030409*/ ++ int MaxFrags; ++ int TxIntThreshold[MAX_CHAN]; /* MJH 040621 NSP Performance Update */ ++ int TxIntThresholdMaster[MAX_CHAN]; /* MJH 040827 NSP Performance Update */ ++ int TxIntDisable; /* MJH 040621 NSP Performance Update */ ++ }HALDEVICE; ++ ++#define STATS_MAX 36 ++ ++#define MACCONTROL_MASK (TX_PTYPE|TX_PACE|TX_FLOW_EN|RX_FLOW_EN|CTRL_LOOPBACK) ++#define RX_MBP_ENABLE_MASK \ ++ (RX_PASS_CRC|RX_QOS_EN|RX_NO_CHAIN| \ ++ RX_CMF_EN|RX_CSF_EN|RX_CEF_EN|RX_CAF_EN|RX_PROM_CH_MASK| \ ++ RX_BROAD_EN|RX_BROAD_CH_MASK|RX_MULT_EN|RX_MULT_CH_MASK) ++ ++ ++#define MBP_UPDATE(Mask, On) \ ++ if(On) HalDev->RxMbpEnable |= Mask; \ ++ else HalDev->RxMbpEnable &= ~Mask ++ ++#define CONTROL_UPDATE(Mask, On) \ ++ if(On) HalDev->MacControl |= Mask; \ ++ else HalDev->MacControl &= ~Mask ++ ++ ++#define UPDATE_TX_PTYPE(Value) CONTROL_UPDATE(TX_PTYPE,Value) ++#define UPDATE_TX_PACE(Value) CONTROL_UPDATE(TX_PACE,Value) ++#define UPDATE_MII_EN(Value) CONTROL_UPDATE(MII_EN,Value) ++#define UPDATE_TX_FLOW_EN(Value) CONTROL_UPDATE(TX_FLOW_EN,Value) ++#define UPDATE_RX_FLOW_EN(Value) CONTROL_UPDATE(RX_FLOW_EN,Value) ++#define UPDATE_CTRL_LOOPBACK(Value) CONTROL_UPDATE(CTRL_LOOPBACK,Value) ++#define UPDATE_FULLDUPLEX(Value) CONTROL_UPDATE(FULLDUPLEX,(Value)) ++ ++#define UPDATE_RX_PASS_CRC(Value) MBP_UPDATE(RX_PASS_CRC, Value) ++#define UPDATE_RX_QOS_EN(Value) MBP_UPDATE(RX_QOS_EN, Value) ++#define UPDATE_RX_NO_CHAIN(Value) MBP_UPDATE(RX_NO_CHAIN, Value) ++#define UPDATE_RX_CMF_EN(Value) MBP_UPDATE(RX_CMF_EN, Value) ++#define UPDATE_RX_CSF_EN(Value) MBP_UPDATE(RX_CSF_EN, Value) ++#define UPDATE_RX_CEF_EN(Value) MBP_UPDATE(RX_CEF_EN, Value) ++#define UPDATE_RX_CAF_EN(Value) MBP_UPDATE(RX_CAF_EN, Value) ++#define UPDATE_RX_BROAD_EN(Value) MBP_UPDATE(RX_BROAD_EN, Value) ++#define UPDATE_RX_MULT_EN(Value) MBP_UPDATE(RX_MULT_EN, Value) ++ ++#define UPDATE_RX_PROM_CH(Value) \ ++ HalDev->RxMbpEnable &= ~RX_PROM_CH_MASK; \ ++ HalDev->RxMbpEnable |= RX_PROM_CH(Value) ++ ++#define UPDATE_RX_BROAD_CH(Value) \ ++ HalDev->RxMbpEnable &= ~RX_BROAD_CH_MASK; \ ++ HalDev->RxMbpEnable |= RX_BROAD_CH(Value) ++ ++#define UPDATE_RX_MULT_CH(Value) \ ++ HalDev->RxMbpEnable &= ~RX_MULT_CH_MASK; \ ++ HalDev->RxMbpEnable |= RX_MULT_CH(Value) ++ ++ ++ ++typedef enum ++ { ++ /* CPMAC */ ++ enCpmacStart=0, ++ enStats0, ++ enStats1, ++ enStats2, ++ enStats3, ++ enStats4, ++ enStatsDump, ++ enStatsClear, ++ enRX_PASS_CRC, ++ enRX_QOS_EN, ++ enRX_NO_CHAIN, ++ enRX_CMF_EN, ++ enRX_CSF_EN, ++ enRX_CEF_EN, ++ enRX_CAF_EN, ++ enRX_PROM_CH, ++ enRX_BROAD_EN, ++ enRX_BROAD_CH, ++ enRX_MULT_EN, ++ enRX_MULT_CH, ++ ++ enTX_PTYPE, ++ enTX_PACE, ++ enMII_EN, ++ enTX_FLOW_EN, ++ enRX_FLOW_EN, ++ enCTRL_LOOPBACK, ++ ++ enRX_MAXLEN, ++ enRX_FILTERLOWTHRESH, ++ enRX0_FLOWTHRESH, ++ enRX_UNICAST_SET, ++ enRX_UNICAST_CLEAR, ++ enMdioConnect, ++ enMAC_ADDR_GET, ++ enTick, ++ enRX_MULTICAST, ++ enRX_MULTI_ALL, ++ enRX_MULTI_SINGLE, ++ enVersion, ++ enCpmacEnd /* Last entry */ ++ }INFO_KEY_CPMAC; ++ ++static const char pszVersion[] = "Version"; ++static const char pszStats0[] = "Stats0"; ++static const char pszStats1[] = "Stats1"; ++static const char pszStats2[] = "Stats2"; ++static const char pszStats3[] = "Stats3"; ++static const char pszStats4[] = "Stats4"; ++static const char pszStatsDump[] = "StatsDump"; ++static const char pszStatsClear[] = "StatsClear"; ++ ++/******************************************************************** ++** ++** RX MBP ENABLE ++** ++********************************************************************/ ++static const char pszRX_PASS_CRC[] = "RX_PASS_CRC"; ++static const char pszRX_QOS_EN[] = "RX_QOS_EN"; ++static const char pszRX_NO_CHAIN[] = "RX_NO_CHAIN"; ++static const char pszRX_CMF_EN[] = "RX_CMF_EN"; ++static const char pszRX_CSF_EN[] = "RX_CSF_EN"; ++static const char pszRX_CEF_EN[] = "RX_CEF_EN"; ++static const char pszRX_CAF_EN[] = "RX_CAF_EN"; ++static const char pszRX_PROM_CH[] = "RX_PROM_CH"; ++static const char pszRX_BROAD_EN[] = "RX_BROAD_EN"; ++static const char pszRX_BROAD_CH[] = "RX_BROAD_CH"; ++static const char pszRX_MULT_EN[] = "RX_MULT_EN"; ++static const char pszRX_MULT_CH[] = "RX_MULT_CH"; ++ ++ ++/******************************************************************** ++** ++** MAC CONTROL ++** ++********************************************************************/ ++static const char pszTX_PTYPE[] = "TX_PTYPE"; ++static const char pszTX_PACE[] = "TX_PACE"; ++static const char pszMII_EN[] = "MII_EN"; ++static const char pszTX_FLOW_EN[] = "TX_FLOW_EN"; ++static const char pszRX_FLOW_EN[] = "RX_FLOW_EN"; ++static const char pszCTRL_LOOPBACK[] = "CTRL_LOOPBACK"; ++ ++static const char pszRX_MAXLEN[] = "RX_MAXLEN"; ++static const char pszRX_FILTERLOWTHRESH[] = "RX_FILTERLOWTHRESH"; ++static const char pszRX0_FLOWTHRESH[] = "RX0_FLOWTHRESH"; ++static const char pszRX_UNICAST_SET[] = "RX_UNICAST_SET"; ++static const char pszRX_UNICAST_CLEAR[] = "RX_UNICAST_CLEAR"; ++static const char pszMdioConnect[] = "MdioConnect"; ++static const char pszMacAddr[] = "MacAddr"; ++static const char pszTick[] = "Tick"; ++ ++/******************************************************************** ++** ++** MULTICAST ++** ++********************************************************************/ ++ ++static const char pszRX_MULTICAST[] = "RX_MULTICAST"; ++static const char pszRX_MULTI_ALL[] = "RX_MULTI_ALL"; ++static const char pszRX_MULTI_SINGLE[] = "RX_MULTI_SINGLE"; ++ ++/* ++static const char* pszGFHN = "GFHN"; ++*/ ++ ++static const CONTROL_KEY KeyCpmac[] = ++ { ++ {"" , enCpmacStart}, ++ {pszStats0 , enStats0}, ++ {pszStats1 , enStats1}, ++ {pszStats2 , enStats2}, ++ {pszStats3 , enStats3}, ++ {pszStats4 , enStats4}, ++ {pszStatsClear , enStatsClear}, ++ {pszStatsDump , enStatsDump}, ++ {pszRX_PASS_CRC , enRX_PASS_CRC}, ++ {pszRX_QOS_EN , enRX_QOS_EN}, ++ {pszRX_NO_CHAIN , enRX_NO_CHAIN}, ++ {pszRX_CMF_EN , enRX_CMF_EN}, ++ {pszRX_CSF_EN , enRX_CSF_EN}, ++ {pszRX_CEF_EN , enRX_CEF_EN}, ++ {pszRX_CAF_EN , enRX_CAF_EN}, ++ {pszRX_PROM_CH , enRX_PROM_CH}, ++ {pszRX_BROAD_EN , enRX_BROAD_EN}, ++ {pszRX_BROAD_CH , enRX_BROAD_CH}, ++ {pszRX_MULT_EN , enRX_MULT_EN}, ++ {pszRX_MULT_CH , enRX_MULT_CH}, ++ ++ {pszTX_PTYPE , enTX_PTYPE}, ++ {pszTX_PACE , enTX_PACE}, ++ {pszMII_EN , enMII_EN}, ++ {pszTX_FLOW_EN , enTX_FLOW_EN}, ++ {pszRX_FLOW_EN , enRX_FLOW_EN}, ++ {pszCTRL_LOOPBACK , enCTRL_LOOPBACK}, ++ {pszRX_MAXLEN , enRX_MAXLEN}, ++ {pszRX_FILTERLOWTHRESH , enRX_FILTERLOWTHRESH}, ++ {pszRX0_FLOWTHRESH , enRX0_FLOWTHRESH}, ++ {pszRX_UNICAST_SET , enRX_UNICAST_SET}, ++ {pszRX_UNICAST_CLEAR , enRX_UNICAST_CLEAR}, ++ {pszMdioConnect , enMdioConnect}, ++ {pszRX_MULTICAST , enRX_MULTICAST}, ++ {pszRX_MULTI_ALL , enRX_MULTI_ALL}, ++ {pszRX_MULTI_SINGLE , enRX_MULTI_SINGLE}, ++ {pszTick , enTick}, ++ {pszVersion , enVersion}, ++ {"" , enCpmacEnd} ++ }; ++ ++const char hcCpuFrequency[] = "CpuFreq"; ++const char hcCpmacFrequency[] = "CpmacFrequency"; ++const char hcMdioBusFrequency[] = "MdioBusFrequency"; ++const char hcMdioClockFrequency[] = "MdioClockFrequency"; ++const char hcCpmacBase[] = "CpmacBase"; ++const char hcPhyNum[] = "PhyNum"; ++const char hcSize[] = "size"; ++const char hcCpmacSize[] = "CpmacSize"; ++const char hcPhyAccess[] = "PhyAccess"; ++const char hcLinked[] = "Linked"; ++const char hcFullDuplex[] = "FullDuplex"; ++const char hcMdixMask[] = "MdixMask"; ++const char hcMdioMdixSwitch[] = "MdixSet"; ++#endif +diff -urN linux.old/drivers/net/avalanche_cpmac/Makefile linux.dev/drivers/net/avalanche_cpmac/Makefile +--- linux.old/drivers/net/avalanche_cpmac/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/Makefile 2005-07-12 02:48:42.175574000 +0200 +@@ -0,0 +1,26 @@ ++# File: drivers/net/avalanche_cpmac/Makefile ++# ++# Makefile for the Linux network (CPMAC) device drivers. ++# ++ ++O_TARGET := avalanche_cpmac.o ++ ++ ++list-multi := avalanche_cpmac.o ++obj-$(CONFIG_MIPS_AVALANCHE_CPMAC) := avalanche_cpmac.o ++ ++avalanche_cpmac-objs += cpmac.o cpmacHalLx.o hcpmac.o \ ++ psp_config_build.o psp_config_mgr.o \ ++ psp_config_parse.o psp_config_util.o ++ ++ ++include $(TOPDIR)/Rules.make ++ ++ ++avalanche_cpmac.o: $(avalanche_cpmac-objs) ++ $(LD) -r -o $@ $(avalanche_cpmac-objs) ++ ++ ++ ++clean: ++ rm -f core *.o *.a *.s +diff -urN linux.old/drivers/net/avalanche_cpmac/mdio_reg.h linux.dev/drivers/net/avalanche_cpmac/mdio_reg.h +--- linux.old/drivers/net/avalanche_cpmac/mdio_reg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/mdio_reg.h 2005-07-12 02:48:42.176573000 +0200 +@@ -0,0 +1,121 @@ ++/**************************************************************************** ++** TNETD53xx Software Support ++** Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved. ++** ++** FILE: mdio_reg.h Register definitions for the VBUS MII module ++** ++** DESCRIPTION: ++** This include file contains register definitions for the ++** VBUS MII module. ++** ++** HISTORY: ++** 27Mar02 Michael Hanrahan Original (modified from emacmdio.h) ++** 01Apr02 Michael Hanrahan Modified to include all regs. in spec ++** 03Apr02 Michael Hanrahan Updated to Version 0.6 of spec ++** 05Apr02 Michael Hanrahan Moved Phy Mode values into here ++** 30Apr02 Michael Hanrahan Updated to Version 0.8 of spec ++** 30Apr02 Michael Hanrahan Updated to recommended format ++** 10May02 Michael Hanrahan Updated to Version 0.9 of spec ++*****************************************************************************/ ++#ifndef _INC_MDIO_REG ++#define _INC_MDIO_REG ++ ++/*************************************************************************** ++** ++** M D I O M E M O R Y M A P ++** ++***************************************************************************/ ++ ++ ++#define pMDIO_VER(base) ((volatile bit32u *)(base+0x00)) ++#define pMDIO_CONTROL(base) ((volatile bit32u *)(base+0x04)) ++#define pMDIO_ALIVE(base) ((volatile bit32u *)(base+0x08)) ++#define pMDIO_LINK(base) ((volatile bit32u *)(base+0x0C)) ++#define pMDIO_LINKINTRAW(base) ((volatile bit32u *)(base+0x10)) ++#define pMDIO_LINKINTMASKED(base) ((volatile bit32u *)(base+0x14)) ++#define pMDIO_USERINTRAW(base) ((volatile bit32u *)(base+0x20)) ++#define pMDIO_USERINTMASKED(base) ((volatile bit32u *)(base+0x24)) ++#define pMDIO_USERINTMASKED_SET(base) ((volatile bit32u *)(base+0x28)) ++#define pMDIO_USERINTMASKED_CLR(base) ((volatile bit32u *)(base+0x2C)) ++#define pMDIO_USERACCESS(base, channel) ((volatile bit32u *)(base+(0x80+(channel*8)))) ++#define pMDIO_USERPHYSEL(base, channel) ((volatile bit32u *)(base+(0x84+(channel*8)))) ++ ++ ++/*************************************************************************** ++** ++** M D I O R E G I S T E R A C C E S S M A C R O S ++** ++***************************************************************************/ ++ ++ ++#define MDIO_ALIVE(base) (*(pMDIO_ALIVE(base))) ++#define MDIO_CONTROL(base) (*(pMDIO_CONTROL(base))) ++#define MDIO_CONTROL_IDLE (1 << 31) ++#define MDIO_CONTROL_ENABLE (1 << 30) ++#define MDIO_CONTROL_PREAMBLE (1 << 20) ++#define MDIO_CONTROL_FAULT (1 << 19) ++#define MDIO_CONTROL_FAULT_DETECT_ENABLE (1 << 18) ++#define MDIO_CONTROL_INT_TEST_ENABLE (1 << 17) ++#define MDIO_CONTROL_HIGHEST_USER_CHANNEL (0x1F << 8) ++#define MDIO_CONTROL_CLKDIV (0xFF) ++#define MDIO_LINK(base) (*(pMDIO_LINK(base))) ++#define MDIO_LINKINTRAW(base) (*(pMDIO_LINKINTRAW(base))) ++#define MDIO_LINKINTMASKED(base) (*(pMDIO_LINKINTMASKED(base))) ++#define MDIO_USERINTRAW(base) (*(pMDIO_USERINTRAW(base))) ++#define MDIO_USERINTMASKED(base) (*(pMDIO_USERINTMASKED(base))) ++#define MDIO_USERINTMASKED_CLR(base) (*(pMDIO_USERINTMASKED_CLR(base))) ++#define MDIO_USERINTMASKED_SET(base) (*(pMDIO_USERINTMASKED_SET(base))) ++#define MDIO_USERINTRAW(base) (*(pMDIO_USERINTRAW(base))) ++#define MDIO_USERACCESS(base, channel) (*(pMDIO_USERACCESS(base, channel))) ++#define MDIO_USERACCESS_GO (1 << 31) ++#define MDIO_USERACCESS_WRITE (1 << 30) ++#define MDIO_USERACCESS_READ (0 << 30) ++#define MDIO_USERACCESS_ACK (1 << 29) ++#define MDIO_USERACCESS_REGADR (0x1F << 21) ++#define MDIO_USERACCESS_PHYADR (0x1F << 16) ++#define MDIO_USERACCESS_DATA (0xFFFF) ++#define MDIO_USERPHYSEL(base, channel) (*(pMDIO_USERPHYSEL(base, channel))) ++#define MDIO_USERPHYSEL_LINKSEL (1 << 7) ++#define MDIO_USERPHYSEL_LINKINT_ENABLE (1 << 6) ++#define MDIO_USERPHYSEL_PHYADR_MON (0x1F) ++#define MDIO_VER(base) (*(pMDIO_VER(base))) ++#define MDIO_VER_MODID (0xFFFF << 16) ++#define MDIO_VER_REVMAJ (0xFF << 8) ++#define MDIO_VER_REVMIN (0xFF) ++ ++ ++ ++ ++/****************************************************************************/ ++/* */ ++/* P H Y R E G I S T E R D E F I N I T I O N S */ ++/* */ ++/****************************************************************************/ ++ ++ ++#define PHY_CONTROL_REG 0 ++ #define PHY_RESET (1<<15) ++ #define PHY_LOOP (1<<14) ++ #define PHY_100 (1<<13) ++ #define AUTO_NEGOTIATE_EN (1<<12) ++ #define PHY_PDOWN (1<<11) ++ #define PHY_ISOLATE (1<<10) ++ #define RENEGOTIATE (1<<9) ++ #define PHY_FD (1<<8) ++ ++#define PHY_STATUS_REG 1 ++ #define NWAY_COMPLETE (1<<5) ++ #define NWAY_CAPABLE (1<<3) ++ #define PHY_LINKED (1<<2) ++ ++#define NWAY_ADVERTIZE_REG 4 ++#define NWAY_REMADVERTISE_REG 5 ++ #define NWAY_FD100 (1<<8) ++ #define NWAY_HD100 (1<<7) ++ #define NWAY_FD10 (1<<6) ++ #define NWAY_HD10 (1<<5) ++ #define NWAY_SEL (1<<0) ++ #define NWAY_AUTO (1<<0) ++ ++ ++#endif _INC_MDIO_REG +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_build.c linux.dev/drivers/net/avalanche_cpmac/psp_config_build.c +--- linux.old/drivers/net/avalanche_cpmac/psp_config_build.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_build.c 2005-07-12 02:48:42.176573000 +0200 +@@ -0,0 +1,335 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager - Configuration Build Source ++ ****************************************************************************** ++ * FILE NAME: psp_config_build.c ++ * ++ * DESCRIPTION: Configuration Build API Implementation ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifdef INCLUDE_FFS ++#include "ffs.h" ++#endif /* INCLUDE_FFS */ ++ ++#include "psp_config_mgr.h" ++#include "psp_config_build.h" ++#include "psp_config_util.h" ++ ++#define MAX_DEVICE_NAME_LEN 16 ++#define MAX_DEVICE_STR_LEN 512 ++ ++#ifndef NULL ++#define NULL (char *)0 ++#endif ++ ++#include ++#include ++#include ++ ++ ++#define os_malloc(size) kmalloc(size, GFP_KERNEL) ++ ++int psp_run_enumerator(void) ++{ ++ return(0); ++} ++ ++#if defined (CONFIG_AVALANCHE_CPMAC_AUTO) ++ ++static int auto_detect_cpmac_phy(void) ++{ ++ ++#define SELECT_INT_PHY_MAC 0 ++#define SELECT_EXT_PHY_MAC 1 ++ ++ volatile unsigned long *reset_cntl = AVALANCHE_RESET_CONTROL_BASE, *mdio_cntl = ((int)AVALANCHE_MDIO_BASE + 0x4); ++ unsigned int j= 0, detected_phy_map = 0, auto_select = SELECT_INT_PHY_MAC; ++ ++ *reset_cntl |= (1 << AVALANCHE_MDIO_RESET_BIT) | (1 << AVALANCHE_LOW_CPMAC_RESET_BIT) | (1 << AVALANCHE_HIGH_CPMAC_RESET_BIT) | (1 << AVALANCHE_LOW_EPHY_RESET_BIT); ++ *mdio_cntl = (1 << 30) | ((CONFIG_AR7_SYS * 1000)/2200); ++ ++ for(j=0;j < 300000; j++) ++ { ++ if(j%100000) continue; ++ ++ detected_phy_map = *(mdio_cntl + 1); ++ if(detected_phy_map) ++ { ++ detected_phy_map &= ~AVALANCHE_LOW_CPMAC_PHY_MASK; ++ ++ if(detected_phy_map && !(detected_phy_map & (detected_phy_map - 1))) ++ { ++ auto_select = SELECT_EXT_PHY_MAC; ++ break; ++ } ++ } ++ } ++ ++ return(auto_select); ++ ++} ++ ++#endif ++ ++ ++#ifndef AVALANCHE_LOW_CPMAC_MDIX_MASK ++#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0 ++#endif ++ ++void psp_load_default_static_cfg(void) ++{ ++ char s2[100], s3[100]; ++ char s4[2000], s6[2000]; ++ int threshold = 20; ++ char *tx_threshold_ptr = prom_getenv("threshold"); ++ ++ if(tx_threshold_ptr) ++ threshold = simple_strtol(tx_threshold_ptr, (char **)NULL, 10); ++ ++ /* Static configuration if options.conf not present */ ++ sprintf(s3,"cpmdio(id=mii, base=%u, reset_bit=%d)", AVALANCHE_MDIO_BASE, 22); ++ sprintf(s2, "reset( id=[ResetRegister], base=%u)", AVALANCHE_RESET_CONTROL_BASE); ++ ++ sprintf(s4, "cpmac(id=[cpmac], unit=0, base=%u, size=0x800, reset_bit=%d, PhyMask=%u, MdixMask=%u, MLink=0, int_line=%d, memory_offset=0, RX_CAF=1, RX_PASSCRC=0, RX_CEF=1, RX_BCAST=0, RX_BCASTCH=0, Ch0=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch1=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch2=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128])", AVALANCHE_LOW_CPMAC_BASE, AVALANCHE_LOW_CPMAC_RESET_BIT, AVALANCHE_LOW_CPMAC_PHY_MASK, AVALANCHE_LOW_CPMAC_MDIX_MASK, AVALANCHE_LOW_CPMAC_INT,threshold,threshold,threshold); ++ ++ sprintf(s6, "cpmac(id=[cpmac], unit=1, base=%u, size=0x800, reset_bit=%d, PhyMask=%u, MLink=0, int_line=%d, memory_offset=0, RX_CAF=1, RX_PASSCRC=0, RX_CEF=1, RX_BCAST=0, RX_BCASTCH=0, Ch0=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch1=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch2=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128])", AVALANCHE_HIGH_CPMAC_BASE, AVALANCHE_HIGH_CPMAC_RESET_BIT, AVALANCHE_HIGH_CPMAC_PHY_MASK, AVALANCHE_HIGH_CPMAC_INT,threshold,threshold,threshold); ++ ++ psp_config_add("reset", s2, psp_config_strlen(s2), en_compile); ++ ++ ++#if defined (CONFIG_AVALANCHE_LOW_CPMAC) ++ ++ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); ++ psp_config_add("cpmac", s4, psp_config_strlen(s4), en_compile); ++ ++#endif ++ ++ ++#if defined (CONFIG_AVALANCHE_HIGH_CPMAC) ++ ++ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); ++ psp_config_add("cpmac", s6, psp_config_strlen(s6), en_compile); ++ ++#endif ++ ++#if defined (CONFIG_AVALANCHE_CPMAC_AUTO) ++ { ++ char *phy_sel_ptr = prom_getenv("mac_phy_sel"); ++ int phy_sel = SELECT_EXT_PHY_MAC; ++ char *mac_port = prom_getenv("MAC_PORT"); /* Internal: 0, External: 1 */ ++ ++ if(phy_sel_ptr && (0 == strcmp(phy_sel_ptr, "int"))) ++ { ++ phy_sel = SELECT_INT_PHY_MAC; ++ } ++ ++ //if(phy_sel == auto_detect_cpmac_phy()) ++ if(!mac_port || (0 != strcmp(mac_port, "0"))) ++ { ++ printk("Using the MAC with external PHY\n"); ++ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); ++ psp_config_add("cpmac", s6, psp_config_strlen(s6), en_compile); ++ } ++ else ++ { ++ printk("Using the MAC with internal PHY\n"); ++ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); ++ psp_config_add("cpmac", s4, psp_config_strlen(s4), en_compile); ++ } ++ } ++ ++#endif ++ ++} ++ ++char* psp_conf_read_file(char *p_file_name) ++{ ++#ifdef INCLUDE_FFS ++ ++ char *p_file_data = NULL; ++ unsigned int file_size; ++ FFS_FILE *p_file = NULL; ++ ++ if(p_file_name == NULL) ++ { ++ return (NULL); ++ } ++ ++ if(!(p_file = ffs_fopen(p_file_name, "r"))) ++ { ++ return(NULL); ++ } ++ ++ file_size = p_file->_AvailableBytes; ++ ++ p_file_data = os_malloc(file_size + 1); ++ ++ if(ffs_fread(p_file_data, file_size, 1, p_file) == 0) ++ { ++ kfree(p_file_data); ++ return(NULL); ++ } ++ ++ ffs_fclose(p_file); ++ ++ p_file_data[file_size] = '\0'; ++ ++ return(p_file_data); ++ ++#else /* NO FFS */ ++ return(NULL); ++#endif /* INCLUDE_FFS */ ++} ++ ++int psp_conf_get_line(char *p_in_data, char **next_line) ++{ ++ char *p = p_in_data; ++ ++ while(*p && *p++ != '\n') ++ { ++ ++ } ++ ++ *next_line = p; ++ ++ return(p - 1 - p_in_data); ++} ++ ++ ++int psp_conf_is_data_line(char *line) ++{ ++ int ret_val = 1; ++ ++ if(*line == '\0' || *line == '\n' || *line == '#') ++ ret_val = 0; ++ ++ return(ret_val); ++} ++ ++int psp_conf_get_key_size(char *data) ++{ ++ char *p = data; ++ ++ while(*p && *p != '\n' && *p != '(' && *p != ' ') ++ p++; ++ ++ return(p - data); ++} ++ ++char* psp_conf_eat_white_spaces(char *p) ++{ ++ while(*p && *p != '\n' && *p == ' ') ++ p++; ++ ++ return (p); ++} ++ ++int psp_build_from_opt_conf(void) ++{ ++ char *data = NULL; ++ char *data_hold = NULL; ++ char *next_line = NULL; ++ int line_size = 0; ++ ++ if((data = psp_conf_read_file("/etc/options.conf")) == NULL) ++ return(-1); ++ ++ data_hold = data; ++ ++ while((line_size=psp_conf_get_line(data, &next_line)) != -1) ++ { ++ ++ char *name = NULL; ++ int name_size; ++ ++ data = psp_conf_eat_white_spaces(data); ++ ++ if(psp_conf_is_data_line(data)) ++ { ++ data[line_size] = '\0'; ++ ++ name_size = psp_conf_get_key_size(data); ++ ++ if(name_size > 0) ++ { ++ name = (char *) os_malloc(name_size + 1); ++ if(name == NULL) break; ++ ++ psp_config_memcpy(name, data, name_size); ++ name[name_size] = '\0'; ++ ++ psp_config_add(name, data, line_size, en_opt_conf); ++ ++ kfree(name); ++ } ++ ++ data[line_size] = '\n'; ++ } ++ ++ data = next_line; ++ } ++ ++ kfree(data_hold); ++ return (0); ++} ++ ++ ++int psp_write_conf_file(char *p_write_file, char * dev_cfg_string) ++{ ++#ifdef INCLUDE_FFS ++ int bytes_written=0; ++ FFS_FILE *file_ptr=NULL; ++ ++ /* ++ * NOTE: In current implementation of FFS in ADAM2 if the file exists beforehand, it ++ * can't be opened for write. ++ */ ++ if(!(file_ptr=ffs_fopen(p_write_file, "w"))) { ++ return(-1); ++ } ++ ++ /* Write into the file "output.con" the character string */ ++ /* write a \n before a writing a line */ ++ if(!(bytes_written = ffs_fwrite("\n", 1, sizeof(char), file_ptr))) { ++ return (-1); ++ } ++ ++ if(!(bytes_written = ffs_fwrite(dev_cfg_string, psp_config_strlen(dev_cfg_string), sizeof(char), file_ptr))) { ++ return (-1); ++ } ++ ffs_fclose(file_ptr); ++ return (bytes_written+1); ++#else /* NO FFS */ ++ return(-1); ++#endif /* INCLUDE_FFS */ ++} ++ ++void build_psp_config(void) ++{ ++ ++ /* initialize the repository. */ ++ psp_config_init(); ++ ++#ifdef INCLUDE_FFS ++ ffs_init(); ++#endif /* INCLUDE_FFS */ ++ ++ /* read the configuration from the options.conf to override default ones */ ++ psp_build_from_opt_conf(); ++ ++ /* read the configuration which were not over ridden in options.conf */ ++ psp_load_default_static_cfg(); ++ ++ /* let the vlynq be enumerated. Enumerator will add cfg info ++ of the discovered device instances to the repository.*/ ++ psp_run_enumerator(); ++ ++ /* dump the repository*/ ++ dump_device_cfg_pool(); ++ ++} ++ +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_build.h linux.dev/drivers/net/avalanche_cpmac/psp_config_build.h +--- linux.old/drivers/net/avalanche_cpmac/psp_config_build.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_build.h 2005-07-12 02:48:42.176573000 +0200 +@@ -0,0 +1,138 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager - Configuration Build Header ++ ****************************************************************************** ++ * FILE NAME: psp_config_build.h ++ * ++ * DESCRIPTION: Configuration Build API's. ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __PSP_CONF_BUILD_H__ ++#define __PSP_CONF_BUILD_H__ ++ ++/*------------------------------------------------------------------------------ ++ * Name: psp_conf_read_file ++ * ++ * Parameters: ++ * in: p_file_name - the name of the file to read from. ++ * ++ * Description: ++ * Reads the entire file in one shot. This function opens the ++ * file, determines the size of the data to be read, allocates ++ * the required memory, NULL terminates the data and closes the ++ * file. ++ * ++ * It is responsibily of the callee to free the memory after it is ++ * done with that data. ++ * ++ * ++ * Returns: ++ * A NULL pointer, if failed to read the data otherwise, a valid ++ * pointer referring to the data read from the file. ++ * ++ * Example: ++ * ++ * psp_conf_read_file("/etc/options.conf"); ++ *---------------------------------------------------------------------------*/ ++ char *psp_conf_read_file(char *p_file_name); ++ ++ /*---------------------------------------------------------------------------- ++ * Function : psp_conf_write_file ++ * ++ * Parameters: ++ * in: p_file_name - the file to which data is to be written. ++ * in: data - the NULL terminated data string. ++ * ++ * Description: ++ * Write the indicated data into the file. This function opens the file, ++ * appends the data to end of the file, closes the file. ++ * ++ * Returns: ++ * ++ * The number of bytes on success. ++ * 0 on failure. ++ * ++ * Example: ++ * ++ * psp_conf_write_file("/etc/outcon.conf", data); ++ *--------------------------------------------------------------------------*/ ++ int psp_conf_write_file(char *p_file_name, char *data); ++ ++ /*---------------------------------------------------------------------------- ++ * Function: psp_conf_get_line ++ * ++ * Parameters: ++ * in: data - the data from which the line is to identified. ++ * out: next_line - the pointer to start of the next line. ++ * ++ * Description: ++ * Expects the data to be '\n' separated segments and data is NULL ++ * terminated. Parses the given data for '\n' or '\0'. Provides a pointer ++ * to the start of next line in the next_line. ++ * ++ * Returns: ++ * -1 on error. ++ * 0 or more to indicate the number of bytes in the line starting at ++ * data. ++ *--------------------------------------------------------------------------*/ ++ int psp_get_conf_line(char *p_in_data, char **next_line); ++ ++ /*---------------------------------------------------------------------------- ++ * Function: psp_conf_is_data_line ++ * ++ * Parameters: ++ * in: line - the array of bytes. ++ * ++ * Description: ++ * Tests the first byte in the array for '\0' or '\n' or '#'. Lines ++ * starting with these characters are not considered data. ++ * ++ * Returns: ++ * 1 if the line has data. ++ * 0 otherwise. ++ * ++ *--------------------------------------------------------------------------*/ ++ int psp_conf_is_data_line(char *line); ++ ++ /*---------------------------------------------------------------------------- ++ * Function: psp_conf_eat_white_spaces ++ * ++ * Parameters: ++ * in: line - the array of bytes. ++ * ++ * Description: ++ * Eats white spaces at the begining of the line while looking out for ++ * '\0' or '\n' or ' '. ++ * ++ * Returns: ++ * Pointer to the begining of the non white space character. ++ * NULL if '\0' or '\n' is found. ++ * ++ *--------------------------------------------------------------------------*/ ++ char *psp_conf_eat_white_spaces(char *line); ++ ++ /*--------------------------------------------------------------------------- ++ * Function: psp_conf_get_key_size ++ * ++ * Parameters: ++ * in: line - the array of bytes. ++ * ++ * Description: ++ * Identifies the size of the 'key' in array formatted as ++ * key(id=[key1]....). This function also checks out for '\0' and '\n'. ++ * ++ * Returns: ++ * On success, The number of bytes that forms the key. ++ * 0 otherwise. ++ * ++ *-------------------------------------------------------------------------*/ ++ int psp_conf_get_key_size(char *line); ++ ++ ++ ++#endif /* __PSP_CONF_BUILD_H__ */ ++ +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.c linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.c +--- linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.c 2005-07-12 02:48:42.177573000 +0200 +@@ -0,0 +1,464 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager Source ++ ****************************************************************************** ++ * FILE NAME: psp_config_mgr.c ++ * ++ * DESCRIPTION: ++ * ++ * Manages configuration information. The repository is managed on the basis of ++ * pair. It is possible to have multiple occurrence of the same key. ++ * Multiple occurences of the same keys are referred to as 'instances'. ++ * 'instances' are assigned in the order of configuration arrival. The first ++ * config for a 'key' added to the repository would be treated as instance 0 and ++ * next config to arrive for the same key would be treated as instance '1' and ++ * so on. ++ * ++ * Info is retrieved from the repository based on the 'key' and 'instance' value. ++ * ++ * No assumption is made about the format of the information that is put in the ++ * repository. The only requirement is that 'key' should be NULL terminated ++ * string. ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++//#include ++//#include ++#include "psp_config_mgr.h" ++#include "psp_config_util.h" ++ ++#include ++ ++/*----------------------------------------------------------- ++ Implemented elsewhere ++ -----------------------------------------------------------*/ ++extern int sys_read_options_conf(void); ++extern int sys_write_options_conf(char *cfg_info); ++extern int sys_load_default_static_cfg(void); ++extern int sys_run_enumerator(void); ++ ++#define os_malloc(size) kmalloc(size, GFP_KERNEL) ++ ++/*--------------------------------------------------------- ++ * Data structures. ++ *--------------------------------------------------------*/ ++struct device_cfg_data; ++ ++typedef struct device_instance_cfg_data ++{ ++ struct device_instance_cfg_data *next; ++ char locale[100]; ++ unsigned int data_size; ++ char *data; ++ ++} DEV_INSTANCE_CFG_DATA_T; ++ ++struct device_cfg_collection; ++ ++typedef struct device_cfg_collection ++{ ++ struct device_cfg_collection *next; ++ char *device_name; ++ CFG_TYPE_T cfg_type; ++ int count; ++ DEV_INSTANCE_CFG_DATA_T *dev_inst_list_begin; ++ DEV_INSTANCE_CFG_DATA_T *dev_inst_list_end; ++} DEVICE_CFG_T; ++ ++ ++typedef struct device_cfg_list ++{ ++ DEVICE_CFG_T *device_cfg_begin; ++ int count; ++} DEVICE_CFG_LIST_T; ++ ++/*----------------------------------------------------------------------------- ++ * Functions used locally with in the file. ++ *---------------------------------------------------------------------------*/ ++static void p_init_device_cfg_list(void); ++static int p_add_instance_cfg_data(DEVICE_CFG_T *p_dev_cfg, ++ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data); ++static DEVICE_CFG_T* p_create_dev_cfg(char *device_name); ++static DEVICE_CFG_T* p_get_dev_cfg(char *device_name); ++static int p_set_device_cfg_type(DEVICE_CFG_T *p_dev_cfg, ++ CFG_TYPE_T cfg_type); ++ ++/* PSP Config manager debug */ ++#define PSP_CFG_MGR_DEBUG 0 ++ ++#define dbgPrint if (PSP_CFG_MGR_DEBUG) printk ++ ++/*----------------------------------------------------------------------------- ++ * The repository. ++ *---------------------------------------------------------------------------*/ ++static DEVICE_CFG_LIST_T g_device_cfg_list; ++ ++/*--------------------------------------------- ++ * Initialize the device collection pool. ++ *--------------------------------------------*/ ++void p_init_device_cfg_list(void) ++{ ++ g_device_cfg_list.count = 0; ++ g_device_cfg_list.device_cfg_begin = NULL; ++} ++ ++/*---------------------------------------------------------------------- ++ * Add the device cfg into the device linked list. ++ *---------------------------------------------------------------------*/ ++int p_add_dev_cfg_to_list(DEVICE_CFG_LIST_T *p_dev_list, ++ DEVICE_CFG_T *p_dev_cfg) ++{ ++ if(p_dev_list->count != 0) ++ p_dev_cfg->next = p_dev_list->device_cfg_begin; ++ ++ p_dev_list->device_cfg_begin = p_dev_cfg; ++ ++ p_dev_list->count++; ++ ++ return (0); ++} ++ ++/*------------------------------------------------------------------ ++ * Add the cfg data into the cfg data linked list of the collection. ++ *------------------------------------------------------------------*/ ++int p_add_instance_cfg_data(DEVICE_CFG_T *p_dev_cfg, ++ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data) ++{ ++ if(p_dev_cfg->count == 0) ++ p_dev_cfg->dev_inst_list_begin = p_dev_inst_data; ++ else ++ p_dev_cfg->dev_inst_list_end->next = p_dev_inst_data; ++ ++ p_dev_cfg->dev_inst_list_end = p_dev_inst_data; ++ ++ p_dev_cfg->count++; ++ ++ return (0); ++} ++ ++/*----------------------------------------------------------------------------- ++ * Create the device cfg. ++ *---------------------------------------------------------------------------*/ ++DEVICE_CFG_T *p_create_dev_cfg(char *device_name) ++{ ++ DEVICE_CFG_T *p_dev_cfg = NULL; ++ ++ if((p_dev_cfg = os_malloc(sizeof(DEVICE_CFG_T))) == NULL) ++ { ++ dbgPrint("Failed to allocate memory for DEVICE_CFG_T.\n"); ++ } ++ else if((p_dev_cfg->device_name = os_malloc(psp_config_strlen(device_name) + 1))==NULL) ++ { ++ dbgPrint("Failed to allocate memory for device name.\n"); ++ } ++ else ++ { ++ psp_config_strcpy(p_dev_cfg->device_name, device_name); ++ p_dev_cfg->cfg_type = en_raw; ++ p_dev_cfg->count = 0; ++ p_dev_cfg->dev_inst_list_begin = NULL; ++ p_dev_cfg->dev_inst_list_end = NULL; ++ p_dev_cfg->next = NULL; ++ } ++ ++ return(p_dev_cfg); ++} ++ ++/*------------------------------------------------------------------------------ ++ * Get the device cfg collection. ++ *-----------------------------------------------------------------------------*/ ++DEVICE_CFG_T *p_get_dev_cfg(char *device_name) ++{ ++ int count = 0; ++ DEVICE_CFG_T *p_dev_cfg = g_device_cfg_list.device_cfg_begin; ++ ++ for(count=0; count < g_device_cfg_list.count; count++) ++ { ++ if(psp_config_strcmp(device_name, p_dev_cfg->device_name) == 0) ++ { ++ break; ++ } ++ ++ p_dev_cfg = p_dev_cfg->next; ++ } ++ ++ return(p_dev_cfg); ++} ++ ++/*------------------------------------------------------------------------- ++ * Gets the name for the static cfg type. Utility function. Debug purposes. ++ *-------------------------------------------------------------------------*/ ++char *p_get_cfg_type_name_for_en(CFG_TYPE_T cfg_type) ++{ ++ static char raw_str [] = "still raw"; ++ static char compile_str [] = "configured at compile time"; ++ static char optconf_str [] = "configured by options.conf"; ++ static char vlynq_str [] = "configured by VLYNQ"; ++ static char no_static_str[] = "no static configuration"; ++ ++ if(cfg_type == en_raw) ++ return (raw_str); ++ else if(cfg_type == en_compile) ++ return (compile_str); ++ else if(cfg_type == en_opt_conf) ++ return (optconf_str); ++ else if(cfg_type == en_vlynq) ++ return (vlynq_str); ++ else ++ return (no_static_str); ++ ++} ++ ++/*----------------------------------------------------------------------------- ++ * Sets the static cfg status of the device collection. ++ * ++ * If the collection is en_virgin then, the collection is assigned to cfg_type. ++ * If the cfg_type is en_vlynq then, the old cfg_type is retained. ++ * en_compile and en_opt_conf are mutually exclusive. One of these can be ++ * accomodated. ++ * ++ *---------------------------------------------------------------------------*/ ++int p_set_device_cfg_type(DEVICE_CFG_T *p_dev_cfg, ++ CFG_TYPE_T cfg_type) ++{ ++ int ret_val = 0; ++ ++ if(p_dev_cfg->cfg_type == en_raw) ++ p_dev_cfg->cfg_type = cfg_type; ++ else if((cfg_type == en_vlynq) || (p_dev_cfg->cfg_type == cfg_type)) ++ ; ++ else ++ { ++ dbgPrint("Device %s has been %s which overrides %s.\n", ++ p_dev_cfg->device_name, ++ p_get_cfg_type_name_for_en(p_dev_cfg->cfg_type), ++ p_get_cfg_type_name_for_en(cfg_type)); ++ ret_val = -1; ++ } ++ ++ return(ret_val); ++} ++ ++/*------------------------------------------------------------------------ ++ * Add the config str into the repository. The cfg type indicates ++ * whether the device has been configured statically, from options.conf or ++ * by vlynq enumeration. ++ *------------------------------------------------------------------------*/ ++int psp_config_add(char *key, void *p_cfg_str, unsigned int cfg_len, ++ CFG_TYPE_T cfg_type) ++{ ++ int ret_val = -1; ++ DEVICE_CFG_T *p_dev_cfg = NULL; ++ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data = NULL; ++ ++ if(p_cfg_str == NULL || key == NULL) ++ { ++ dbgPrint("Null input pointer(s).\n"); ++ } ++ /* check if there exist a dev_cfg for the given key, if not, ++ then create one and add it to the device list. */ ++ else if(((p_dev_cfg = p_get_dev_cfg(key)) == NULL) && ++ (((p_dev_cfg = p_create_dev_cfg(key)) == NULL) || ++ p_add_dev_cfg_to_list(&g_device_cfg_list, p_dev_cfg) != 0)) ++ { ++ dbgPrint("Failed to allocate mem or add dev cfg for %s.\n", key); ++ } ++ /* make sure that we can add this cfg type to the repository */ ++ else if(p_set_device_cfg_type(p_dev_cfg, cfg_type) == -1) ++ { ++ dbgPrint("Ignoring \"%s\" for device \"%s\".\n", ++ p_get_cfg_type_name_for_en(cfg_type), ++ p_dev_cfg->device_name); ++ } ++ else if((p_dev_inst_data = os_malloc(sizeof(DEV_INSTANCE_CFG_DATA_T)))== NULL) ++ { ++ dbgPrint("Failed to allocate memory for DEV_INSTANCE_CFG_DATA_T.\n"); ++ } ++ else if((p_dev_inst_data->data = os_malloc(cfg_len) + 1) == NULL) ++ { ++ dbgPrint("Failed to allocate memory for the config data.\n"); ++ } ++ else ++ { ++ p_dev_inst_data->next = NULL; ++ ++ if(cfg_type == en_opt_conf || cfg_type == en_compile) ++ psp_config_strcpy(p_dev_inst_data->locale, "dev on chip "); ++ else if(cfg_type == en_vlynq) ++ psp_config_strcpy(p_dev_inst_data->locale, "dev on vlynq"); ++ else ++ psp_config_strcpy(p_dev_inst_data->locale, "dev locale ?"); ++ ++ psp_config_memcpy(p_dev_inst_data->data, p_cfg_str, cfg_len); ++ p_dev_inst_data->data_size = cfg_len; ++ *(p_dev_inst_data->data + cfg_len) = '\0'; ++ ++ ret_val = p_add_instance_cfg_data(p_dev_cfg, p_dev_inst_data); ++ } ++ ++ return(ret_val); ++} ++ ++/*------------------------------------------------------------- ++ * Get the total number of device instances in the repository ++ *------------------------------------------------------------*/ ++int psp_config_get_num_keys(void) ++{ ++ return(g_device_cfg_list.count); ++} ++ ++ ++/*-------------------------------------------------------------------- ++ * Get the device configuration info from the repository. ++ *-------------------------------------------------------------------*/ ++int psp_config_get(char *key, int instance, char **cfg_data_out) ++{ ++ int ret_val = -1; ++ DEVICE_CFG_T *p_dev_cfg = NULL; ++ *cfg_data_out = NULL; ++ ++ if(key == NULL && cfg_data_out == NULL) ++ { ++ dbgPrint("Key has a NULL value.\n"); ++ } ++ else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL) ++ { ++ dbgPrint("cfg information for %s could not be found.\n", key); ++ } ++ else if(p_dev_cfg->count) ++ { ++ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data = ++ p_dev_cfg->dev_inst_list_begin; ++ int index = 0; ++ for(index = 0; ++ index != instance && index < p_dev_cfg->count; ++ index++) ++ { ++ p_dev_inst_data = p_dev_inst_data->next; ++ } ++ ++ if(p_dev_inst_data != NULL && p_dev_inst_data->data != NULL) ++ { ++ *cfg_data_out = p_dev_inst_data->data; ++ ret_val = p_dev_inst_data->data_size; ++ } ++ } ++ ++ return (ret_val); ++} ++ ++/*---------------------------------------------------------------- ++ * Returns the number of instances found in the repository for the ++ * specified key. ++ *---------------------------------------------------------------*/ ++int psp_config_get_num_instances(char *key) ++{ ++ int ret_val = 0; ++ DEVICE_CFG_T *p_dev_cfg = NULL; ++ ++ if(key == NULL) ++ { ++ dbgPrint("Key has a NULL value.\n"); ++ } ++ else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL) ++ { ++ dbgPrint("cfg information for %s could not be found.\n", key); ++ } ++ else ++ { ++ ret_val = p_dev_cfg->count; ++ } ++ ++ return (ret_val); ++} ++ ++/*------------------------------------------------------------------ ++ * Dump the configuration repository. ++ * Caution: DO NOT USE THIS FOR ANY NON NBU specified config format. ++ *-----------------------------------------------------------------*/ ++void psp_config_print(char *key) ++{ ++ DEVICE_CFG_T *p_dev_cfg = NULL; ++ ++ if(key == NULL) ++ { ++ dbgPrint("Key has a NULL value.\n"); ++ } ++ else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL) ++ { ++ dbgPrint("cfg information for %s could not be found.\n", key); ++ } ++ else if(p_dev_cfg && p_dev_cfg->count) ++ { ++ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data; ++ ++ p_dev_inst_data = p_dev_cfg->dev_inst_list_begin; ++ ++ do ++ { ++ dbgPrint("%s : %s\n", p_dev_inst_data->locale, ++ p_dev_inst_data->data); ++ p_dev_inst_data = p_dev_inst_data->next; ++ ++ } while(p_dev_inst_data); ++ } ++ else ++ { ++ dbgPrint("Nothing was found for %s.\n", key); ++ } ++} ++ ++void dump_device_cfg_pool(void) ++{ ++ DEVICE_CFG_T *p_dev_cfg = g_device_cfg_list.device_cfg_begin; ++ ++ if(p_dev_cfg != NULL && g_device_cfg_list.count) ++ { ++ int index=0; ++ ++ for(index=0; index < g_device_cfg_list.count; index++) ++ { ++ psp_config_print(p_dev_cfg->device_name); ++ p_dev_cfg = p_dev_cfg->next; ++ } ++ } ++ else ++ { ++ dbgPrint("repository is empty.\n"); ++ } ++} ++ ++void psp_config_init(void) ++{ ++ p_init_device_cfg_list(); ++} ++ ++void psp_config_cleanup() ++{ ++ int dev_count = 0; ++ int inst_count = 0; ++ DEVICE_CFG_T *p = g_device_cfg_list.device_cfg_begin; ++ DEV_INSTANCE_CFG_DATA_T *q = NULL; ++ ++ for(dev_count = 0; dev_count < g_device_cfg_list.count; dev_count++) ++ { ++ DEVICE_CFG_T *p_temp = NULL; ++ if(p) q = p->dev_inst_list_begin; ++ ++ for(inst_count = 0; inst_count < p->count && q != NULL; inst_count++) ++ { ++ DEV_INSTANCE_CFG_DATA_T *q_temp = q; ++ q_temp = q->next; ++ kfree(q->data); ++ kfree(q); ++ q = q_temp; ++ } ++ ++ p_temp = p->next; ++ kfree(p); ++ p = p_temp; ++ } ++} +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.h linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.h +--- linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.h 2005-07-12 02:48:42.177573000 +0200 +@@ -0,0 +1,110 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager Header ++ ****************************************************************************** ++ * FILE NAME: psp_config_mgr.h ++ * ++ * DESCRIPTION: Storing and retrieving the configuration based on key ++ * A set of APIs to be used by one and sundry (including drivers and enumerator) to build ++ * and read cfg information of the devices for an avalanche SOC. ++ * ++ * This set of APIs isolates the configuration management from the world and provides simple ++ * access convinience. ++ * ++ * Device in this set refers to the peripherals that can be found on the SOC or on VLYNQ. ++ * The configuration is stored in the form of string and drivers can use these APIs to get ++ * a particular parameter value. ++ * ++ * The memory allocation for the pass back parameters is done by the caller. ++ * ++ * 0 is returned for SUCCESS or TRUE. ++ * -1 is returned for FAILURE or FALSE. ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __PSP_CONFIG_MGR_H__ ++#define __PSP_CONFIG_MGR_H__ ++ ++typedef enum cfg_type ++{ ++ en_raw = 0, ++ en_compile, ++ en_opt_conf, ++ en_vlynq ++} CFG_TYPE_T; ++ ++/* Build psp configuration */ ++void build_psp_config(void); ++ ++/******************************************************** ++ * Access Operations. ++ ********************************************************/ ++ ++/*------------------------------------------------------------------------- ++ initializes the configuration repository. ++ -------------------------------------------------------------------------*/ ++void psp_config_init(void); ++ ++/*-------------------------------------------------------------------------- ++ Adds the configuration information into the repository. 'key' is required ++ to be NULL terminated string. 'cfg_ptr' points to the configuration data. ++ 'cfg_len' is the length of the data pointed to by 'cfg_ptr' in bytes. ++ 'cfg_type' indicates the type of config information. ++ ++ psp_config_mgr copies the 'cfg_len' bytes of data pointed to by 'cfg_ptr' ++ into its internal repository. ++ ++ Returns: 0 on success, -1 on failure. ++ -------------------------------------------------------------------------*/ ++int psp_config_add(char *key, void *cfg_ptr, ++ unsigned int cfg_len, CFG_TYPE_T cfg_type); ++ ++ ++/* -------------------------------------------------------------------------- ++ Passes back, in "*cfg_out_val" a pointer to the config data in the repository ++ for the specified 'key' and 'instance'. It returns the size of the config ++ info ++ ++ psp_config_mgr passes back a pointer in '*cfg_out_val' which refers to ++ some location in its internal repository. It is strongly recommended that ++ if the user intends to modify the contents of the config info for reasons ++ whatsoever, then, user should allocate memory of size returned by this ++ routine and copy the contents from '*cfg_out_val'. ++ ++ Any, modification carried out on the repository would lead to un-expected ++ results. ++ ++ Returns: 0 or more for the size of config info, -1 on error. ++ --------------------------------------------------------------------------*/ ++int psp_config_get(char *key, int instance, char **cfg_out_val); ++ ++ ++/*-------------------------------------------------------------------------- ++ Get the number of keys that have been added in the repository so far. ++ ++ Returns: 0 or more for the num of keys, -1 on error. ++ -------------------------------------------------------------------------*/ ++int psp_config_get_num_keys(void); ++ ++ ++/*-------------------------------------------------------------------------- ++ Get the number of instances that are present in the repository for the ++ given 'key'. ++ ++ Returns: 0 or more for the num of instances, -1 on error. ++ -------------------------------------------------------------------------*/ ++int psp_config_get_num_instances(char *key); ++ ++ ++/*-------------------------------------------------------------------------- ++ Prints the config data for all instances associated with the specified ++ 'key'. ++ -------------------------------------------------------------------------*/ ++void psp_config_print(char *key); ++ ++void dump_device_cfg_pool(void); ++ ++#endif /* __PSP_CONFIG_MGR_H__ */ +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_parse.c linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.c +--- linux.old/drivers/net/avalanche_cpmac/psp_config_parse.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.c 2005-07-12 02:48:42.178573000 +0200 +@@ -0,0 +1,362 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager - Parse API Source ++ ****************************************************************************** ++ * FILE NAME: psp_config_parse.c ++ * ++ * DESCRIPTION: These APIs should be used only for scanvenging parameters which ++ * are stored in the following format. ++ * ++ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++//#include ++#include ++ ++/*-------------------------------------------------- ++ * MACROS. ++ *-------------------------------------------------*/ ++#define my_isdigit(c) (c >= '0' && c <= '9') ++#define my_isoct(c) (c >= '0' && c <= '7') ++#define my_xtod(c) ((c) <= '9' ? (c) - '0' : (c) - 'a' + 10) ++#define my_ifupper(c) (c >= 'A' && c <= 'F') ++#define XTOD(c) ((c) - 'A' + 10) ++#define my_ishex(c) ((c >= 'a' && c <='f') || (c >= 'A' && c<='F') || my_isdigit(c) ) ++ ++/*--------------------------------------------------- ++ * Local Functions. ++ *--------------------------------------------------*/ ++static int p_get_substr_from_str(char *p_in_str, char begin_delimiter, ++ char end_delimiter, int pair_flag, ++ char **p_out_str); ++static int p_get_u_int_from_str(char *p_in_str, char begin_delimiter, ++ char end_delimiter, unsigned long *out_val); ++ ++/*--------------------------------------------------- ++ * Return pointer to first instance of the char. ++ *--------------------------------------------------*/ ++static char* psp_config_strchr(char *str, char chr) ++{ ++ while(*str) ++ { ++ if(*str == chr) ++ break; ++ str++; ++ } ++ ++ return((*str) ? str : NULL); ++} ++ ++/*------------------------------------------------------------------------ ++ * Convert the string upto delimiter to unsigned long. ++ *-----------------------------------------------------------------------*/ ++unsigned long my_atoul(char *p, char end_delimiter, unsigned long *out_val) ++{ ++ unsigned long n; ++ int c; ++ ++ /* check the for null input */ ++ if (!p) ++ return -1; ++ ++ c = *p; ++ ++ /* pass through the leading spaces */ ++ if (!my_isdigit(c)) ++ { ++ while ( c == ' ') ++ c = *++p; ++ ++ } ++ ++ if (c == '0') ++ { ++ if(*(p + 1) == 'x' || *(p+1) == 'X' ) ++ { ++ /* string is in hex format */ ++ ++ p += 2; ++ c = *p; ++ ++ if(my_ishex(c)) ++ { ++ if(my_ifupper(c)) ++ n = XTOD(c); ++ else ++ n = my_xtod(c); ++ } ++ else ++ return -1; /* invalid hex string format */ ++ ++ while ((c = *++p) && my_ishex(c)) ++ { ++ n *= 16; ++ if(my_ifupper(c)) ++ n += XTOD(c); ++ else ++ n += my_xtod(c); ++ } ++ } ++ else ++ { ++ /* string is in octal format */ ++ ++ if( my_isoct(c) ) ++ n = c - '0'; ++ else ++ return -1; /* invalid octal string format */ ++ ++ while ((c = *++p) && my_isoct(c)) ++ { ++ n *= 8; ++ n += c - '0'; ++ } ++ } ++ ++ } ++ else ++ { ++ /* string is in decimal format */ ++ ++ if( my_isdigit(c) ) ++ n = c - '0'; ++ else ++ return -1; /* invalid decimal string format */ ++ ++ while ((c = *++p) && my_isdigit(c)) ++ { ++ n *= 10; ++ n += c - '0'; ++ } ++ } ++ ++ /* move through the trailing spaces */ ++ while(*p == ' ') ++ p++; ++ ++ if(*p == end_delimiter) ++ { ++ *out_val = n; ++ return 0; ++ } ++ ++ else ++ return -1; /* invalid string format */ ++} ++ ++/*--------------------------------------------------------------------------------- ++ * Gets the substring de-limited by the 'begin_delimiter' and 'end_delimiter'. ++ * and returns the size of the substring. ++ * ++ * Parses the NULL terminated p_in_str for a character array delimited by ++ * begin_delimiter and end_delimiter, passes back the pointer to the character ++ * array in ' *p_out_str '. The passed pointer ' *p_out_str ' should point to ++ * the location next (byte) to the begin_delimiter. The function routine returns ++ * the number of characters excluding the begin_delimiter and end_delimiter, ++ * found in the array delimited by the said delimiters. ++ * ++ * If the pair_flag is set to 1, then, number of begin_delimiter and end_delimiter ++ * found in the parsing should match (equal) and this routine passes back the ++ * pointer to the character array, starting at a location next (byte) to the ++ * first begin_delimiter, inclusive of all intermediate matching delimiter ++ * characters found between outer delimiters. If the pair flag is set and if ++ * begin_delimiter and end_delimiter happens to be same, then error (-1) is ++ * returned. ++ * ++ * Return: 0 or more to indicate the size of the substring, -1 on error. ++ *-------------------------------------------------------------------------------*/ ++int p_get_substr_from_str(char *p_in_str, char begin_delimiter, ++ char end_delimiter, int pair_flag, ++ char **p_out_str) ++{ ++ int cnt,pos; ++ ++ if(pair_flag && begin_delimiter == end_delimiter) ++ return -1; ++ ++ if((p_in_str = psp_config_strchr(p_in_str, begin_delimiter)) == 0) ++ return -1; /* no start delimiter found */ ++ ++ p_in_str++; ++ *p_out_str = p_in_str; ++ ++ for(pos = 0,cnt =1; cnt && p_in_str[pos] ; pos++) ++ { ++ if(p_in_str[pos] == end_delimiter) ++ { ++ if(pair_flag == 0) ++ return pos; ++ ++ cnt--; ++ } ++ else if(p_in_str[pos] == begin_delimiter) ++ cnt++; ++ else ++ ; /* We do nothing */ ++ ++ } ++ ++ if( cnt == 0) ++ return pos - 1; ++ else ++ return -1; /* no corresponding end delimiter found */ ++} ++ ++/*-------------------------------------------------------------------------- ++ * Parses the NULL terminated p_in_str for unsigned long value delimited by ++ * begin_delimiter and end_delimiter, passes back the found in ' *out_val '. ++ * The function routine returns 0 on success and returns -1 on failure. ++ * The first instance of the de-limiter should be accounted for the parsing. ++ * ++ * The base for unsigned value would 10, octal and hex. The value passed back ++ * would be of the base 10. Spaces at the begining of the byte array are valid ++ * and should be ingnored in the calculation of the value. Space character in ++ * the middle of the byte array or any character other than the valid ones ++ * (based on base type) should return error. The octal value begins with '0', ++ * the hex value begins with "0x" or "0X", the base value can begin with ++ * '1' to '9'. ++ * ++ * Returns: 0 on success, -1 on failure. ++ *-------------------------------------------------------------------------*/ ++int p_get_u_int_from_str(char *p_in_str, char begin_delimiter, ++ char end_delimiter, unsigned long *out_val) ++{ ++ char *start; ++ unsigned long num; ++ ++ num = p_get_substr_from_str(p_in_str, begin_delimiter, end_delimiter, ++ 0, &start); ++ ++ if(num == (unsigned long)-1) ++ return -1; ++ ++ return my_atoul(start,end_delimiter,out_val); ++} ++ ++/*-------------------------------------------------------------------------- ++ * Finds the first occurrence of the substring p_find_str in the string ++ * p_in_str. ++ *-------------------------------------------------------------------------*/ ++char *my_strstr(char *p_in_str, const char *p_find_str) ++{ ++ char *p = (char *)p_find_str; ++ char *ret = NULL; ++ ++ while(*p_in_str) ++ { ++ if(!(*p)) ++ return (ret); ++ else if(*p_in_str == *p) ++ { ++ if(!ret) ret = p_in_str; ++ p++; ++ p_in_str++; ++ } ++ else if(ret) ++ { ++ p = (char *)p_find_str; ++ p_in_str = ret + 1; ++ ret = NULL; ++ } ++ else ++ p_in_str++; ++ } ++ ++ if(*p_in_str != *p) ret = NULL; ++ ++ return (ret); ++ ++} ++ ++/*------------------------------------------------------------------------------ ++ * Gets the value of the config param in the unsigned int format. The value is ++ * stored in the following format in the string. ++ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" ++ *-----------------------------------------------------------------------------*/ ++int psp_config_get_param_uint(char *p_in_str, const char *param, unsigned int *out_val) ++{ ++ int ret_val = -1; ++ char *p_strstr; ++ ++ if(!p_in_str || !param || !out_val) ++ { ++ ; ++ } ++ else if((p_strstr = my_strstr(p_in_str, param)) == NULL) ++ { ++ ; ++ } ++ else if(p_get_u_int_from_str(p_strstr, '=', ',', (unsigned long *)out_val) == 0) ++ { ++ ret_val = 0; ++ } ++ else if(p_get_u_int_from_str(p_strstr, '=', ']', (unsigned long*)out_val) == 0) ++ { ++ ret_val = 0; ++ } ++ else if(p_get_u_int_from_str(p_strstr, '=', ')', (unsigned long*)out_val) == 0) ++ { ++ ret_val = 0; ++ } ++ else ++ { ++ /* we failed */ ++ } ++ ++ return (ret_val); ++} ++ ++/*------------------------------------------------------------------------------ ++ * Gets the value of the config param in the Non NULL terminated format. The value ++ * is stored in the following format in the string. ++ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" ++ *-----------------------------------------------------------------------------*/ ++int psp_config_get_param_string(char *p_in_str, const char *param, char **out_val) ++{ ++ int ret_val = -1; ++ char *p_strstr; ++ ++ if(!p_in_str || !param || !(out_val)) ++ ; ++ else if((p_strstr = my_strstr(p_in_str, param)) == NULL) ++ { ++ ; ++ } ++ else if((ret_val = p_get_substr_from_str(p_strstr, '[', ']', 1, out_val)) == -1) ++ { ++ ; ++ } ++ else ++ { ++ ; /* we got the value */ ++ } ++ ++ return (ret_val); ++} ++ ++#ifdef PSP_CONFIG_MGR_DEBUG_TEST ++main() ++{ ++ unsigned long num =999; ++ int ret = 0; ++ char *val1 = NULL; ++ char val[30]; ++ char str1[] = "cpmac(id=[cpmac], k0=[a1=[a2=[test], a3=2], k1=100, k2=[k3=300, k4=200], k7=722)"; ++ ++ psp_config_get_param_uint(str1, "k7", &num); ++ printf("%u.\n", num); ++ ret = psp_config_get_param_string(str1, "a1", &val1); ++ if(ret >= 0) { printf("%d.\n", ret); strncpy(val, val1, ret); val[ret] = '\0';} ++ ++ printf("val = \"%s\", and size = %d \n", val, ret); ++ ++ if(val[ret]) ; else printf("jeee.\n"); ++} ++#endif /* PSP_CONFIG_MGR_DEBUG_TEST */ ++ ++ ++ +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_parse.h linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.h +--- linux.old/drivers/net/avalanche_cpmac/psp_config_parse.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.h 2005-07-12 02:48:42.178573000 +0200 +@@ -0,0 +1,32 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager - Parse API Header ++ ****************************************************************************** ++ * FILE NAME: psp_config_parse.h ++ * ++ * DESCRIPTION: Parsing for params from string available in the NBU format. ++ * These APIs should be used only for scanvenging parameters which ++ * are stored in the following format. ++ * ++ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __PSP_CONFIG_PARSER_H__ ++#define __PSP_CONFIG_PARSER_H__ ++ ++/*------------------------------------------------------------------ ++ * These APIs should be used only for scanvenging parameters which ++ * are stored in the following format. ++ * ++ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" ++ *-----------------------------------------------------------------*/ ++int psp_config_get_param_uint(char *p_in_str, const char *param, ++ unsigned int *out_val); ++int psp_config_get_param_string(char *p_in_str, const char *param, ++ char **out_val); ++ ++#endif /* __PSP_CONFIG_PARSER_H__ */ +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_util.c linux.dev/drivers/net/avalanche_cpmac/psp_config_util.c +--- linux.old/drivers/net/avalanche_cpmac/psp_config_util.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_util.c 2005-07-12 02:48:42.178573000 +0200 +@@ -0,0 +1,106 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager - Utilities API Source ++ ****************************************************************************** ++ * FILE NAME: psp_config_util.c ++ * ++ * DESCRIPTION: These APIs provide the standard "C" string interfaces. ++ * Provided here to reduce dependencies on the standard libraries ++ * and for cases where psp_config would required to run before ++ * the whole system is loaded or outside the scope of the OS. ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++//#include ++#include "psp_config_util.h" ++#include ++ ++/*--------------------------------------------- ++ * strlen. ++ *-------------------------------------------*/ ++int psp_config_strlen(char *p) ++{ ++ char *p_orig = p; ++ while(*p) ++ p++; ++ return(p - p_orig); ++} ++ ++/*-------------------------------------------- ++ * strcmp. ++ *-------------------------------------------*/ ++int psp_config_strcmp(char *s1, char *s2) ++{ ++ while(*s1 && *s2) ++ { ++ if(*s1 != *s2) ++ break; ++ s1++; ++ s2++; ++ } ++ ++ return(*s1 - *s2); ++} ++ ++/*-------------------------------------------- ++ * strcpy. ++ *------------------------------------------*/ ++char* psp_config_strcpy(char *dest, char *src) ++{ ++ char *dest_orig = dest; ++ ++ while(*src) ++ { ++ *dest++ = *src++; ++ } ++ ++ *dest = '\0'; ++ ++ return(dest_orig); ++} ++ ++/*---------------------------------------------- ++ * psp_config_memcpy. ++ *--------------------------------------------*/ ++void* psp_config_memcpy(void* dest, void* src, unsigned int n) ++{ ++ void *dest_orig = dest; ++ ++ while(n) ++ { ++ *(char *)dest++ = *(char *)src++; ++ n--; ++ } ++ ++ return (dest_orig); ++} ++ ++/*--------------------------------------------------- ++ * Return pointer to first instance of the char. ++ *--------------------------------------------------*/ ++char* psp_config_strchr(char *str, char chr) ++{ ++ while(*str) ++ { ++ if(*str == chr) ++ break; ++ str++; ++ } ++ ++ return((*str) ? str : NULL); ++} ++ ++#ifdef PSP_CONFIG_MGR_DEBUG_TEST ++ ++int main( ) ++{ ++ char s[] = "hello "; ++ printf("%d.\n", psp_config_strlen("hello\n")); ++ printf("%d.\n", psp_config_strcmp("hells", "hellq")); ++ printf("%s %s.\n", psp_config_strcpy(s + 6, "test1"), s); ++} ++ ++#endif /* PSP_CONFIG_MGR_DEBUG_TEST */ +diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_util.h linux.dev/drivers/net/avalanche_cpmac/psp_config_util.h +--- linux.old/drivers/net/avalanche_cpmac/psp_config_util.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/psp_config_util.h 2005-07-12 02:48:42.179573000 +0200 +@@ -0,0 +1,26 @@ ++/****************************************************************************** ++ * FILE PURPOSE: PSP Config Manager - Utilities API Header ++ ****************************************************************************** ++ * FILE NAME: psp_config_util.h ++ * ++ * DESCRIPTION: These APIs provide the standard "C" string interfaces. ++ * Provided here to reduce dependencies on the standard libraries ++ * and for cases where psp_config would required to run before ++ * the whole system is loaded or outside the scope of the OS. ++ * ++ * REVISION HISTORY: ++ * 27 Nov 02 - PSP TII ++ * ++ * (C) Copyright 2002, Texas Instruments, Inc ++ *******************************************************************************/ ++ ++#ifndef __PSP_CONFIG_UTIL_H__ ++#define __PSP_CONFIG_UTIL_H__ ++ ++extern int psp_config_strlen(char*); ++extern int psp_config_strcmp(char*, char*); ++extern char* psp_config_strcpy(char*, char*); ++extern void* psp_config_memcpy(void*, void*, unsigned int n); ++extern char* psp_config_strchr(char*, char); ++ ++#endif /* __PSP_CONFIG_UTIL_H__ */ +diff -urN linux.old/drivers/net/avalanche_cpmac/readme.txt linux.dev/drivers/net/avalanche_cpmac/readme.txt +--- linux.old/drivers/net/avalanche_cpmac/readme.txt 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/avalanche_cpmac/readme.txt 2005-07-12 02:48:42.179573000 +0200 +@@ -0,0 +1,545 @@ ++23 August 2004 CPMAC 1.7.8 (NSP Performance Team Release) ++ ++CC Labels: REL_20040823_HALdallas_cpmac_01.07.08 ++ ++New features: Key "MacAddr" can now be used to set the Mac Address after Open. ++ ++ unsigned char MacAddr[6]; ++ ++ // Set Mac Address to "00.B0.D0.10.80.C1" ++ MacAddr[0] = 0x00; ++ MacAddr[1] = 0xB0; ++ MacAddr[2] = 0xD0; ++ MacAddr[3] = 0x10; ++ MacAddr[4] = 0x80; ++ MacAddr[5] = 0xC1; ++ ++ HalFunc->Control(HalDev, "MacAddr", hcSet, &MacAddr); ++ ++Bug fixes: in Send(), Threshold is not checked if Tx Ints are re-enabled. ++ ++Modules affected: hcpmac.c, hcpmac.h, cppi_cpmac.c ++ ++22 June 2004 CPMAC 1.7.6 (NSP Performance Team Release) ++ ++CC Labels: REL_20040622_HALdallas_cpmac_01.07.06 ++ ++New features: Key "TxIntDisable" used to disable Tx Interrupts. If it is set, then Tx Interrupts will be processed on Send() controlled by Tx ServiceMax Setting. ++ ++ int On = 1; ++ HalFunc->Control(HalDev, "TxIntDisable", "Set", &On); ++ ++Bug fixes: NTR ++ ++10 June 2004 CPMAC 1.7.5 (external release) ++ ++CC Labels: REL_20040610_HALdallas_cpmac_01.07.05 ++ ++New features: NTR ++ ++Bug fixes: Fixed an issue with calculation for the multicast hash. ++ ++27 May 2004 CPSAR 1.7.4, CPMAC 1.7.4 (external release) ++ ++CC Labels: REL_20040527_HALdallas_cpsar_01.07.04 ++ REL_20040527_HALdallas_cpmac_01.07.04 ++ ++New features: NTR ++ ++Bug fixes: A flaw was fixed in the critical sectioning of the CPPI file, affecting both ++ the MAC and the SAR releases. This flaw was detected on Titan PSP 4.7 BFT2. ++ ++05 May 2004 CPSAR 1.7.3, CPMAC 1.7.3 (external release) ++ ++CC Labels: REL_20040505_HALdallas_cpsar_01.07.03 ++ REL_20040505_HALdallas_cpmac_01.07.03 ++ ++New features: NTR ++ ++Bug fixes: 1) Firmware has been updated to fix a problem with Host OAM mode operation. ++ 2) Cache macros have been fixed. ++ ++Notes: This release contains all performance enhancements currently available for CPHAL 1.x. ++ ++19 April 2004 CPSAR 1.7.2, CPMAC 1.7.2 (external release) ++ ++CC Labels: REL_20040419_HALdallas_cpsar_01.07.02 ++ REL_20040419_HALdallas_cpmac_01.07.02 ++ ++New features: NTR ++ ++Bug fixes: Fixes merge problem in 1.7.1. ++ ++Notes: This is a branch release which contains only a subset of the performance improvements. ++ The remaining performance improvements are stiill being qualified at this time. ++ ++1 April 2004 CPSAR 1.7.1, CPMAC 1.7.1 (external release) ++ ++NOTICE: DO NOT USE 1.7.1. It has a known problem (see 1.7.2 notes) ++ ++CC Labels: REL_20040401_HALdallas_cpsar_01.07.01 ++ REL_20040401_HALdallas_cpmac_01.07.01 ++ ++New features: Performance improvement in CPPI layer, affecting both CPSAR and CPMAC. ++ ++Bug fixes: NTR ++ ++17 Februrary 2004 CPSAR 1.7.0 (external release) ++ ++CC Labels: REL_20040217_HALdallas_cpsar_01.07.00 ++ ++New features: Added support for "TxFlush" feature. This allows the upper ++ layer to flush all or part of a given Tx queue for a given ++ channel. This is to be used during call setup for a voice ++ connection. ++ ++30 January 2004 CPMAC 1.7.0 (external release) ++ ++CC Labels: REL_20040130_HALdallas_cpmac_01.07.00 ++ ++Bug fixes: CPMDIO - When in manual negotiate mode and linked, dropping link would move into NWAY state rather than manual state. ++ CPMDIO - Extraneous debug message corrected ++New features: CPMDIO - Support for AutoMdix usage added. ++ ++25 September 2003 CPSAR 1.6.6 (external release) ++ ++CC Labels: REL_20030925_HALdallas_cpsar_01.06.06 ++ ++Bug fixes: PDSP firmware has been updated to fix the OAM padding problem. It previously ++ wrote pad bytes into a reserved field of the OAM cell. There is a small ++ change to the CPSAR configuration code which corresponds to the PDSP spec ++ change. ++ ++New features: NTR ++ ++09 September 2003 CPMAC 1.6.6 (external release) ++ ++CC Labels: REL_20030909_HALdallas_cpmac_01.06.06 ++ ++Bug fixes: CPMAC : When _CPMDIO_NOPHY is set, Cpmac COntrol is set to Full Duplex ++ Bridge loopback test does not show a problem using 1.6.5 if packet rate is ++ below 50,000 pbs. Now testing with a 100% send from Ixia. ++ ++New features: NTR ++ ++05 August 2003 CPHAL 1.6.5 (external release) ++ ++CC Labels: REL_20030805_HALdallas_cpmac_01.06.05 ++ ++Bug fixes: NTR ++ ++New features: CPMAC : Added support for CPMAC modules that do not have a Phy connected. ++ The CPMAC is informed of this by the MdioConnect option ++ _CPMDIO_NOPHY. This is the only driver change needed to ++ receive and transmit packets through the Marvel switch. ++ Note In this mode Link status will reported linked at 100/FD to ++ PhyNum 0xFFFFFFFF. ++ ++ ALL: Cleaned up some Vlynq support logic. ++ ++16 July 2003 CPSAR 1.6.3 (external release), no CPMAC release ++ ++CC Labels: REL_20030716_HALdallas_cpsar_01.06.03 ++ ++Bug fixes: 1) Changed default value of CPCS_UU from 0x5aa5 to 0. The old default value caused ++ problems with Cisco routers. ++ ++New features: NTR ++ ++Known issues not addressed in this release: NTR. ++ ++01 July 2003 CPHAL 1.6.2 (external release) ++ ++CC Labels: REL_20030701_HALdallas_cpmac_01.06.02 ++ REL_20030701_HALdallas_cpsar_01.06.02 ++ ++Bug fixes: 1) A previous firmware upgrade caused firmware OAM loopback cells to only work on every other ++ command. This has been fixed in the new firmware version (0.47). ++ 2) Problem with PTI values changing on transparent mode packets has been resolved. ++ 3) Previously, successful firmware OAM loopback cells waited 5 seconds before notifying the ++ OS of success, rather that notifying immediately. This has been resolved in firmware. ++ 4) PITS #148 (MAC and SAR), #149 (MAC) have been fixed. ++ ++New features: 1) AAL5 HAL now capable of receiving unknown VCI/VPI cells on a single transparent channel. ++ See updated HAL document (AAL5 appendix) for implementation details. ++ 2) AAL5 HAL now allows OS to modify the OAM loopback timeout window. Previously, failed ++ OAM loopback attempts timed out after a nominal 5 seconds (based on the SAR frequency ++ provided by the OS). Now, the default is 5 seconds, but the OS may change the ++ value via halControl() to any integer number of milliseconds. See updated HAL document ++ (AAL5 appendix) for implementation details. ++ 3) MAC (cpmdio): added loopback to Istate. Used for debug. ++ ++Known issues not addressed in this release: NTR. ++ ++09 June 2003 CPSAR 1.6.1 (external release), CPMAC 1.6.1 (internal release - no functional change) ++ ++Note: This is the same set of fixes being applied to 1.6.0 that were applied to 1.5.3. The only difference ++ between 1.6.1 and 1.5.4 is that 1.6.1 has the TurboDSL fix. ++ ++CC Labels: REL_20030609_HALdallas_cpmac_01.06.01 ++ REL_20030609_HALdallas_cpsar_01.06.01 ++ ++Bug fixes: 1) Bug in OamLoopbackConfig fixed. ++ 2) New firmware version (.43) to fix Westell issue of dropped downstream packets in ++ presence of OAM traffic when operating at or near line rate. ++ ++New features: NTR. ++ ++09 June 2003 CPSAR 1.5.4 (external release), CPMAC 1.5.4 (internal release - no functional change) ++ ++Note: This is a branch release from 1.5.3. This does not contain anything from 1.6.0. The CPMAC is ++only being labeled to keep the release flow consistent. ++ ++CC Labels: REL_20030609_HALdallas_cpmac_01.05.04 ++ REL_20030609_HALdallas_cpsar_01.05.04 ++ ++Bug fixes: 1) Bug in OamLoopbackConfig fixed. ++ 2) New firmware version (.43) to fix Westell issue of dropped downstream packets in ++ presence of OAM traffic when operating at or near line rate. ++ ++New features: NTR. ++ ++30 May 2003 CPSAR 1.6.0 (external release), CPMAC 1.6.0 (internal release - no functional change) ++ ++CC Labels: REL_20030530_HALdallas_cpmac_01.06.00 ++ REL_20030530_HALdallas_cpsar_01.06.00 ++ ++Bug fixes: 1) TurboDSL issue has been fixed with a software workaround in TxInt. This workaround ++ has been verified under Adam2 ONLY at this point. Testing remains to be done on ++ Linux and VxWorks. ++ ++New features: NTR. ++ ++Known issues not addressed in this release: NTR. ++ ++30 May 2003 CPSAR 1.5.3 (external release), CPMAC 1.5.3 (internal release - no functional change) ++ ++CC Labels: REL_20030530_HALdallas_cpmac_01.05.03 ++ REL_20030530_HALdallas_cpsar_01.05.03 ++ ++Bug fixes: NTR. ++ ++New features: 1) AAL5 Send() has been modified to accept an ATM Header either in the first ++ fragment by itself, or in the first fragment directly in front of payload data. ++ The API() does not change. ++ 2) Documentation updates throughout, reflected in latest version of CPHAL user's ++ guide. ++ 3) AAL5 MaxFrags default value is now 46. This is based upon the default AAL5 ++ RxBufSize of 1518 (MaxFrags = (65568/1518) + 2). IF THE OS CHOOSES A SMALLER ++ RxBufSize, IT MUST INCREASE THE VALUE OF MaxFrags ACCORDINGLY. This is done ++ via halControl(), prior to Open(). ++ ++Known issues not addressed in this release: ++ 1) The Linux SAR driver is seeing an issue in which it cannot ++ reliably send traffic simultaneously on both the high and ++ low priority queues of a single AAL5 channel. (TurboDSL) ++ ++23 May 2003 CPHAL 1.5.2 (external release) ++ ++CC Labels: REL_20030523_HALdallas_cpmac_01.05.02 ++ REL_20030523_HALdallas_cpsar_01.05.02 ++ ++Bug fixes: 1) PITS #138: CPMAC flooding issue resolved. ++ 2) PITS #142: OS may now set "MaxFrags" via Control(). This controls the ++ maximum number of fragments expected by the CPHAL. The default value is 2 for ++ CPMAC and 1028 for AAL5. If the OS chooses a RxBufSize that will cause more ++ fragments than the defaults, the OS must set "MaxFrags" to a correct value ++ ((maximum packet length / RxBufSize) + 2). ++ 3) PITS #143: Fixed. ++ 4) Firmware OAM bug fixed. (new firmware release in this version) ++ ++New features: NTR. ++ ++Known issues not addressed in this release: ++ 1) The Linux SAR driver is seeing an issue in which it cannot ++ reliably send traffic simultaneously on both the high and ++ low priority queues of a single AAL5 channel. (TurboDSL) ++ ++14 May 2003 CPHAL 1.5.1 (external release) ++ ++CC Labels: REL_20030514_HALdallas_cpmac_01.05.01 ++ REL_20030514_HALdallas_cpsar_01.05.01 ++ ++Bug fixes: 1) PITS 132 - (CPMAC) Frames < 60 bytes and split into ++ multi-fragments. ++ 2) BCIL MR PSP00000353 - (CPMAC) PhyDev not free'd on halClose() ++ 3) PITS 113 - OsSetup bug in ChannelSetup fixed. ++ 4) Fixed AAL5 to check return values of InitTcb/InitRcb. ++ 5) Fixed Shutdown to properly free resources in the case of a Close ++ mode 1 followed by Shutdown. Previously, buffer and descriptor ++ resources were left unfreed in this case. ++ ++New features: 1) AAL5 Send() modified to be capable of accepting ATM header as first four ++ bytes of first fragment. This allows the OS to "override" the ++ default ATM header which is constructed from preconfigured channel ++ parameters. ++ 2) AAL5 Receive() modified to be capable of passing the received ATM header (4 bytes, no HEC) ++ in the first fragment (by itself). It also passes up the OS an indication ++ of what the received packet type was. For Host OAM and transparent mode ++ packets, the ATM header is passed in this manner, and for other types of packets ++ (AAL5, NULL AAL) no ATM header is passed currently. ++ ++Known issues not addressed in this release: ++ 1) The Linux SAR driver is seeing an issue in which it cannot ++ reliably send traffic simultaneously on both the high and ++ low priority queues of a single AAL5 channel. ++ ++30 April 2003 CPHAL 1.5.0 (external release) ++ ++CC Labels: REL_20030430_HALdallas_cpmac_01.05.00 ++ REL_20030430_HALdallas_cpsar_01.05.00 ++ ++Bug fixes: 1) Fixed AAL5 bug that rendered the low priority queue ++ unusable. ++ 2) Fixed a bug in AAL5's Oam Rate calculations. ++ 3) Fixed use of "DeviceCPID" key in AAL5's halControl(). ++ 4) Fixed RxReturn logic in HAL. The HAL now can handle ++ failing MallocRxBuffer calls when multiple fragments ++ are being used. ++ ++New features: 1) AAL5 Stats now available on a per queue basis. ++ 2) AAL5 adds two new keys to halControl() for "Set" actions: ++ RxVc_OamCh and RxVp_OamCh. ++ 3) Shutdown() has been modified for both AAL5 and CPMAC to ++ call Close() if the module is still in the Open state. ++ 4) CPMAC adds the following access keys to halControl(): ++ hcPhyAccess,hcPhyNum,hcCpmacBase,hcSize,and hcCpmacSize. ++ 5) CPHAL no longer requests an extra 15 bytes on data buffer ++ mallocs. ++ ++Known issues not addressed in this release: ++ 1) The Linux SAR driver is seeing an issue in which it cannot ++ reliably send traffic simultaneously on both the high and ++ low priority queues of a single AAL5 channel. ++ ++21 April 2003 CPHAL 1.4.1 (external release) ++ ++CC Labels: REL_20030421_HALdallas_cpmac_01.04.01 ++ REL_20030421_HALdallas_cpsar_01.04.01 ++ ++Bug fixes: 1) Fixed OAM logic in SAR portion of CPHAL. ++ ++New features: 1) OAM loopback counters exposed through halControl. ++ 2) Host OAM Send() can now use a single channel to send ++ OAM cells on unlimited number of VP's/VC's. ++ 3) CPHAL now requests "SarFreq" through osControl. ++ 4) CPHAL now calculates all OAM function rates based on ++ "SarFreq"; function OamRateConfig removed for API. ++ 5) New OAM function OamLoopbackConfig, used for configuring ++ loopback functions in firmware OAM mode. ++ ++Known issues not addressed in this release: Bug fix 1) in release 1.4 ++ (see below) does not work properly for multiple fragments. ++ ++10 April 2003 CPHAL 1.4 (external release) ++ ++CC Labels: REL_20030410_HALdallas_cpmac_01.04.00 ++ REL_20030410_HALdallas_cpsar_01.04.00 ++ ++This release is for SAR and MAC. ++ ++ Bug fixes: 1) Implemented logic in HAL to re-request buffer mallocs ++ in the case of MallocRxBuffer failing. The HAL now maintains ++ a NeedsBuffer queue of all RCB's that are without buffers. ++ On interrupts, or on Send(), the HAL checks to see if any ++ RCB's are on the queue, and if so, calls MallocRxBuffer ++ to attempt to get a new buffer and return the RCB to ++ circulation. ++ 2) SAR now properly returns all error codes from halOpen and ++ halChannelSetup. ++ ++ New features: NTR ++ ++ Known issues not addressed in this release: NTR ++ ++08 April 2003 CPHAL 1.3.1 (internal release - SAR only) ++ ++ CC Labels: REL_20030408_HALdallas_cpsar_01.03.01 ++ ++ This is a SAR only release. The current CPMAC release is still 1.3. ++ ++ Bug fixes: 1) PDSP State RAM / Scratchpad RAM is now completely cleared after reset. ++ This resolves a stability issue. ++ ++ New features: 1) OamMode is now a parameter in halControl(). Both "Set" and "Get" ++ actions are available. The value may be "0" (Host OAM), or "1" ++ (Firmware OAM). ++ ++ Known issues not addressed in this release: ++ 1) Appropriate action for HAL in the case of MallocRxBuffer failing. We ++ are investigating whether the HAL should implement a needs buffer ++ queue. ++ ++04 April 2003 CPHAL 1.3 (external release) ++ ++ CC Labels: REL_20030404_HALdallas_cpmac_01.03.00 ++ REL_20030404_HALdallas_cpsar_01.03.00 ++ REL_20030404_HALdallas_cpaal5_01.03.00 ++ REL_20030404_HALdallas_cpaal2_01.03.00 ++ ++ This release requires no changes for the ethernet end driver. The changes necessary ++ for the sar driver (firmware file name changes) have already been implemented. ++ ++ Bug fixes: 1) RxReturn now returns an error if MallocRxBuffer fails. On RxReturn error, the driver should ++ call RxReturn again at a later time (when the malloc may succeed) in order for the CPHAL ++ to maintain a full complement of Rx buffers. We recommend holding off making this driver ++ change until we verify that this condition occurs. ++ ++ New features: 1) Removed benign compiler warnings. ++ 2) PITS 122: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=122 ++ 3) Cpsar label (above) now is applied to everything ++ beneath /cpsar. ++ 4) PITS 14: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=14 ++ Transferred to MR PSP 00000089. ++ 5) PITS 120: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=120 ++ ++ Known issues not addressed in this release: ++ 1) PITS 102 (as relating to OamMode configuration): ++ http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=102 ++ Future release will make OamMode configurable ++ through halControl(), not on per channel basis. ++ ++20 March 2003 CPHAL 1.2.1 (internal release) ++ ++ CC Labels: REL_20030320_HALdallas_cpmac_01.02.01 ++ REL_20030320_HALdallas_cpsar_01.02.01 ++ REL_20030320_HALdallas_cpaal5_01.02.01 ++ REL_20030320_HALdallas_cpaal2_01.02.01 ++ ++ Bug fixes: 1. Fixed modification of buffer pointer following ++ MallocRxBuffer in cppi.c. ++ 2. Removed extra firmware files from /cpsar. ++ ++ New features: NTR. ++ ++ Known issues not addressed in this release: NTR. ++ ++07 March 2003 CPHAL 1.2 (external release) ++ ++ CPMAC/CPSAR feature complete release. SAR added ++ several features including full OAM support and various ++ other features and bug fixes to address PITS 99-106, and ++ 114. CPMAC cleaned up details raised by India PSP ++ team. ++ ++29 January 2003 CPHAL RC 3.01a (external release) ++ ++ Corrects non-static functions to be static in cppi.c. ++ ++09 Janurary 2003 CPHAL RC 3.01 (external release) ++ ++ PITS 88: Fixed MDIO re-connection problem (hcpmac.c) ++ PITS 90: Corrected Rx Buffer Pointer modification (cppi.c) ++ ++ Corrected error in cpremap.c ++ ++20 December 2002 CPHAL RC 3 (external release) ++ ++ Statistics support via halControl(). See Appendix A of guide. ++ Fixed errors in ChannelTeardown/ChannelSetup CPHAL logic. ++ Added multicast support as requested. ++ Several new OS string functions added to OS_FUNCTIONS. ++ "DebugLevel" configuration parameter changed to "Debug". ++ "Stats0" changed to "StatsDump" for CPMAC. ++ ++13 December 2002 CPHAL RC 2.03 (internal release) ++ ++ Performance improvements. ++ More debug statements implemented (esp AAL5). ++ Updated makefile with "make debug" option. ++ Hbridge performance: [debug library] 15774 tps (53% line rate) ++ [non-debug library] 13700 tps (46%) ++ ++10 December 2002 CPHAL Release Candidate 2.02 (internal release) ++ ++ Much of the configuration code internal to CPMAC and AAL5 has been made common. ++ [os]Receive API had been modified to remove OsReceiveInfo. This information is now ++ available as third member of the FRAGLIST structure, on a per buffer basis. ++ Successfully tested multi-fragment support on CPMAC, using 32 byte buffers. ++ Code is now Emerald compliant - all buffer descriptors now aligned to cache-line ++ boundaries. ++ ++2 December 2002 CPHAL Release Candidate 2.01 ++ ++ Updates to comments in hcpmac.c, cpmdio.c, hcpmac.h ++ Nested comment in hcpmac.c in RC2 can cause compile errors. ++ ++25 November 2002 CPHAL Release Candidate 2 ++ ++Project Items not completed for RC2 ++#6 Ship as Library - Once under CC. Moved to RC3 ++#8 Under Clearcase - Moved to RC3 ++#25 Emerald compliant - Moved to RC3 ++#26 Statistics support - Moved to RC3 (some support in RC2) ++#36 Debug scheme implemented - Moved to RC3 (some support in RC2) ++ ++8 November 2002 CPHAL Release Candidate 1 ++ ++Notes: ++ ++Project Items not completed for RC1 ++ ++#8 Under Clearcase - Clearcase server failure this week. Moved to RC2 ++#6 Ship as Library - Once under CC. Moved to RC2 ++#13 Verify Datatypes. Moved to RC2 ++#14 Review APIs. Moved to RC2 ++ ++APIs under review for RC2 ++ ++halIsr() ++hslRxReturn() ++halSend() ++osSendComplete() ++osReceive() ++ ++ ++CPMAC Build Instructions ++ ++Compile the file 'hcpmac.c'. ++ ++ ++AAL5 Build Instructions ++ ++The AAL5 build is composed of the source files aal5sar.c and cpsar.c. ++Refer to the provided makefile for an example of compiling these files ++into a library. ++ ++Example CPHAL Code ++ ++CPMAC: ++ ++Example CPMAC code is provided in the file hbridge.c. ++This program is provided simply as an example of using the CPHAL API. ++It is not intended to be compiled and executed in your environment. ++ ++AAL5: ++ ++Example AAL5 code is provided in the file loopback.c. This program ++is provided simply as an example of using the CPHAL API. It is not ++intended to be compiled and executed in your environment. ++ ++ ++Performance Baseline ++ ++ ++Cpmac ++ ++RC1: hbridge.bin, running with IXIA cpahl_1.cfg. ++ This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port. ++ MIPS core 4Kc. ++ ++RC2: hbridge.bin, running with IXIA cpahl_1.cfg. ++ This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port. ++ MIPS core 4Ke. ++ CPHAL now includes Emerald support, but this has been disabled by using 'cache -wt' to emulate 4Kc. ++ ++RC3: hbridge.bin, running with IXIA cpahl_1.cfg. ++ This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port. ++ MIPS core 4Ke. ++ Running as Emerald processor. ++ ++Release Total Receive Rate Throughput Setting ++ ++RC1 11300 38% ++RC2 9524 32% ++RC3 15190 51% +diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in +--- linux.old/drivers/net/Config.in 2005-07-12 03:20:45.726149872 +0200 ++++ linux.dev/drivers/net/Config.in 2005-07-12 02:48:42.180573000 +0200 +@@ -25,6 +25,24 @@ + comment 'Ethernet (10 or 100Mbit)' + bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET + if [ "$CONFIG_NET_ETHERNET" = "y" ]; then ++ if [ "$CONFIG_MIPS_TITAN" = "y" -o "$CONFIG_AR7" = "y" ]; then ++ tristate ' Texas Instruments Avalanche CPMAC support' CONFIG_MIPS_AVALANCHE_CPMAC ++ fi ++ if [ "$CONFIG_MIPS_AVALANCHE_CPMAC" != "n" ]; then ++ if [ "$CONFIG_AR7WRD" = "y" -o "$CONFIG_AR7VWI" = "y" -o "$CONFIG_AR7VW" = "y" ]; then ++ define_bool CONFIG_MIPS_CPMAC_INIT_BUF_MALLOC y ++ define_int CONFIG_MIPS_CPMAC_PORTS 1 ++ if [ "$CONFIG_MIPS_AVALANCHE_MARVELL" = "y" ]; then ++ define_bool CONFIG_AVALANCHE_LOW_CPMAC n ++ define_bool CONFIG_AVALANCHE_HIGH_CPMAC y ++ else ++ define_bool CONFIG_AVALANCHE_CPMAC_AUTO y ++ define_bool CONFIG_AVALANCHE_LOW_CPMAC n ++ define_bool CONFIG_AVALANCHE_HIGH_CPMAC n ++ fi ++ fi ++ fi ++ + if [ "$CONFIG_ARM" = "y" ]; then + dep_bool ' ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110 + tristate ' Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS +diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile +--- linux.old/drivers/net/Makefile 2005-07-12 03:20:45.726149872 +0200 ++++ linux.dev/drivers/net/Makefile 2005-07-12 02:48:42.181573000 +0200 +@@ -56,6 +56,16 @@ + subdir-$(CONFIG_BONDING) += bonding + + # ++# Texas Instruments AVALANCHE CPMAC driver ++# ++ ++subdir-$(CONFIG_MIPS_AVALANCHE_CPMAC) += avalanche_cpmac ++#obj-$(CONFIG_MIPS_AVALANCHE_CPMAC) += avalanche_cpmac/avalanche_cpmac.o ++ifeq ($(CONFIG_MIPS_AVALANCHE_CPMAC),y) ++ obj-y += avalanche_cpmac/avalanche_cpmac.o ++endif ++ ++# + # link order important here + # + obj-$(CONFIG_PLIP) += plip.o +--- linux.old/drivers/net/avalanche_cpmac/cpmac.c 2005-08-25 10:56:33.702931008 +0200 ++++ linux.dev/drivers/net/avalanche_cpmac/cpmac.c 2005-08-25 11:08:45.027451520 +0200 +@@ -2158,17 +2158,16 @@ + CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; + CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; + struct sk_buff *p_skb = fragList[0].OsInfo; +- p_skb->len = fragList[0].len; + + /* invalidate the cache. */ + dma_cache_inv((unsigned long)p_skb->data, fragList[0].len); + #ifdef CPMAC_TEST +- xdump(p_skb->data, p_skb->len, "recv"); ++ xdump(p_skb->data, fragList[0].len, "recv"); + #endif + #ifdef CPMAC_8021Q_SUPPORT + /* 802.1q stuff, just does the basic checking here. */ + if(!p_cpmac_priv->enable_802_1q && +- p_skb->len > TCI_END_OFFSET && ++ fragList[0].len > TCI_END_OFFSET && + IS_802_1Q_FRAME(p_skb->data + TPID_START_OFFSET)) + { + goto cpmac_hal_recv_frame_mismatch; diff --git a/openwrt/target/linux/ar7-2.4/patches/004-atm_driver.patch b/openwrt/target/linux/ar7-2.4/patches/004-atm_driver.patch new file mode 100644 index 0000000000..f6a920853a --- /dev/null +++ b/openwrt/target/linux/ar7-2.4/patches/004-atm_driver.patch @@ -0,0 +1,27232 @@ +diff -urN linux.old/drivers/atm/Config.in linux.dev/drivers/atm/Config.in +--- linux.old/drivers/atm/Config.in 2005-08-22 23:18:37.773532032 +0200 ++++ linux.dev/drivers/atm/Config.in 2005-08-23 04:46:50.076846888 +0200 +@@ -99,4 +99,10 @@ + bool 'Use S/UNI PHY driver' CONFIG_ATM_HE_USE_SUNI + fi + fi ++# ++# Texas Instruments SANGAM ADSL/ATM support ++# ++if [ "$CONFIG_AR7" = "y" ]; then ++ tristate 'Texas Instruments SANGAM ATM/ADSL support' CONFIG_MIPS_SANGAM_ATM ++fi + endmenu +diff -urN linux.old/drivers/atm/Makefile linux.dev/drivers/atm/Makefile +--- linux.old/drivers/atm/Makefile 2005-08-22 23:18:37.773532032 +0200 ++++ linux.dev/drivers/atm/Makefile 2005-08-23 04:46:50.077846736 +0200 +@@ -14,6 +14,32 @@ + obj-$(CONFIG_ATM_NICSTAR) += nicstar.o + obj-$(CONFIG_ATM_IDT77252) += idt77252.o + ++ifeq ($(CONFIG_AR7),y) ++ ++subdir-$(CONFIG_MIPS_SANGAM_ATM) += sangam_atm ++ ++EXTRA_CFLAGS += -DEL -I$(TOPDIR)/drivers/atm/sangam_atm -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT ++#EXTRA_CFLAGS += -DEL -I$(TOPDIR)/drivers/atm/sangam_atm -DPOST_SILICON -DCOMMON_NSP ++ ++ifeq ($(ANNEX),B) ++EXTRA_CFLAGS += -DANNEX_B -DB ++else ++ifeq ($(ANNEX),C) ++EXTRA_CFLAGS += -DANNEX_C -DC ++else ++EXTRA_CFLAGS += -DANNEX_A -DP ++endif ++endif ++ ++list-multi := tiatm.o ++tiatm-objs := sangam_atm/tn7atm.o sangam_atm/tn7dsl.o sangam_atm/tn7sar.o \ ++ sangam_atm/dsl_hal_api.o sangam_atm/dsl_hal_support.o sangam_atm/cpsar.o \ ++ sangam_atm/aal5sar.o ++ ++obj-$(CONFIG_MIPS_SANGAM_ATM) += sangam_atm/tiatm.o ++ ++endif ++ + ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y) + obj-$(CONFIG_ATM_NICSTAR) += suni.o + endif +diff -urN linux.old/drivers/atm/sangam_atm/aal5sar.c linux.dev/drivers/atm/sangam_atm/aal5sar.c +--- linux.old/drivers/atm/sangam_atm/aal5sar.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/aal5sar.c 2005-08-23 04:46:50.080846280 +0200 +@@ -0,0 +1,2962 @@ ++ ++/** ++ * ++ * aal5sar.c ++ * ++ * TNETDxxxx Software Support\n ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * version ++ * 28Feb02 Greg 1.00 Original Version created.\n ++ * 06Mar02 Greg 1.01 Documentation (Doxygen-style) enhanced ++ * 06May02 Greg 1.02 AAL2 added ++ * 06Jun02 Greg 1.03 Multiple API and bug fixes from emulation ++ * 12Jul02 Greg 1.04 API Update ++ */ ++ ++/** ++@defgroup CPHAL_Functions CPHAL Functions ++ ++These are the CPHAL Functions. ++*/ ++ ++/** ++@page CPHAL_Implementation_Details ++ ++@section cphal_intro Introduction ++ ++The CPHAL API described above is generally applicable to all modules. Any ++implementation differences will be described in the following module-specific ++appendix sections. ++ ++Included for your reference is a diagram showing the internal architecture ++of the CPHAL: ++ ++@image html SangamSoftware.jpg "HAL Architecture" ++@image latex SangamSoftware.jpg "HAL Architecture" height=2.8in ++ ++*/ ++ ++/** ++@defgroup AAL5_Functions Additional Functions for AAL5 Implementation ++ ++These functions are used only by the AAL5 module. ++*/ ++ ++/* ++@defgroup CPMAC_Functions Additional Functions for CPMAC Implementation ++ ++No additional functions currently defined. ++*/ ++ ++/** ++@page VDMA_Implementation_Details ++ ++@section vdma_intro Introduction ++ ++The VDMA-VT module facilitates efficient transfer of data (especially voice) ++between two devices, as shown in the figure below. ++ ++@image html vdma.jpg "VDMA System Block Diagram" ++@image latex vdma.jpg "VDMA System Block Diagram" height=1in ++ ++The VDMA-VT module supports two modes of operation: mirror mode and credit mode. ++Mirror mode is intended for systems in which the remote device does not have a ++VDMA-based module. Credit mode is intended for highest performance when VDMA-based ++modules exist on both ends of an interface. ++ ++For more detailed information on the operation of the VDMA module, please ++reference the VDMA Module Guide. ++ ++@section vdma_channels VDMA Channels ++ ++The VDMA-VT module is a single channel, single transmit queue device. Therefore, ++when using the CHANNEL_INFO structure, the correct value for @c Ch is always 0. ++Correspondingly, the correct value for the @c Ch parameter in @c ChannelTeardown() is ++always 0. Further, when calling @c Send(), the driver should always supply the value ++of 0 for both the @c Ch and @c Queue parameters. ++ ++For the VDMA-VT, configuring the channel requires the configuration of either 2 FIFO ++elements (in credit mode) or 4 FIFO elements (in mirror mode). For credit mode, the ++driver must configure just the local Tx and Rx FIFOs. For mirror mode, the driver must ++configure the Tx and Rx FIFOs for both the remote and local ends of the interface. ++ ++This channel configuration is accomplished through multiple calls to @c ChannelSetup(). ++Each call configures a single FIFO, according to the parameters in the CHANNEL_INFO ++structure. The members of VDMA-VT's CHANNEL_INFO structure are defined below. ++ ++ ++- int RemFifoAddr; Address of remote FIFO (mirror mode only). Set to 0 for credit mode. ++- int FifoAddr; Address of the local FIFO. If 0, the CPHAL will allocate the FIFO. ++- int FifoSize; Size of the FIFO. ++- int PollInt; Polling interval for the FIFO. ++- int Endianness; Endianness of the FIFO. If 1, big endian. If 0, little endian. ++- int RemAddr; Used only in credit mode. This is the base address of the remote ++ remote VDMA-based device (VDMA-VT or AAL2) ++- int RemDevID; Used only in credit mode. Identifies the type of remote VDMA-based device. ++ 0=VDMAVT, 1=AAL2 Ch0, 2=AAL2 Ch1, 3=AAL2 Ch2, 4= AAL2 Ch3. ++ ++For the VDMA-VT module, the driver must make all calls to @c ChannelSetup() prior to calling ++@c Open(). This is because several of the channel specific parameters may not be changed ++while the VDMA-VT module is operational. ++ ++@section vdma_params VDMA Parameters ++ ++Defined here are the set of parameters for the VDMA-VT module. Default settings for ++each parameter should be represented in the device configuration file (options.conf). ++During @c Init(), the CPHAL will reference the device configuration file and load all ++default settings. The @c Control() interface gives the driver an opportunity to ++modify any default settings before the module becomes operational during the @c Open() ++call. ++ ++@param NoTxIndication If 1, the CPHAL will not call @c SendComplete(). 0 is default. ++@param NoRxIndication If 1, the CPHAL will not call @c Receive(). 0 is default. ++@param RemoteCPU If 1, the CPHAL will not directly manipulate data in FIFO's, leaving ++ that task for a remote CPU. 0 is default. ++@param RxIntEn If 1, enables Rx interrupts. 0 is default. ++@param TxIntEn If 1, enables Tx interrupts. 0 is default. ++@param Mirror If 1, enables mirror mode. 0 selects credit mode (default). ++@param RxIntCtl Valid only in mirror mode. If 1, interrupts will occur when the Rx FIFO ++ RdIndex is updated. If 0, interrupts occur when the Rx FIFO WrIndex ++ is updated. ++@param TxIntCtl Valid only in mirror mode. If 1, interrupts will occur when the Rx FIFO ++ RdIndex is updated. If 0, interrupts occur when the Rx FIFO WrIndex ++ is updated. ++@param RBigEn Remote big endian mode. If 1, remote is big endian. ++@param LBigEn Local big endian mode. If 1, local is big endian. ++ ++@section vdma_polling Using VDMA-VT without interrupts ++ ++If your system configuration does not utilize VDMA interrupts, the ability to process the ++Tx and Rx FIFOs is supported. To process the Tx FIFO, call @c CheckTx(). If the CPHAL is ++able to process any complete data transmissions, it will call @c SendComplete() as usual. ++To process the Rx FIFO, call @c CheckRx(). If the CPHAL has received any data, it will ++call @c Receive() to pass the driver the data. Please reference @ref VDMA_Functions for more ++information on these interfaces. ++ ++@section vdma_details VDMA Implementation Details ++ ++The following functions are not defined for use with VDMA: @c Status(), @c Tick(), @c StatsGet(), ++and @c StatsClear(). ++ ++*/ ++ ++/** ++@page AAL5_Implementation_Details ++ ++@section aal5_ver Version ++ ++@copydoc AAL5_Version ++ ++@section aal5_intro Introduction ++ ++The AAL5 implementation will support 16 channels for transmit and 16 channels for ++receive. Each of the transmit channels may have up to two transmit queues ++associated with it. If two queues are used, Queue 0 is the high priority queue, ++and Queue 1 is the low priority queue. ++ ++@section aal5_params AAL5 Configuration Parameters ++ ++AAL5 requires two device entries to be available in the configuration repository, named ++@p "aal5" and @p "sar". The @p aal5 device entry must contain @p base (base address) ++and @p int_line (interrupt number). The @p sar device entry must have both @p base ++(base address) and @p reset_bit (reset bit). ++ ++@par Device Level Configuration Parameters ++ ++The following parameters are device-level parameters, which apply across all ++channels. The value for these parameters may be modified by changing the value in the ++configuration repository. ++ ++- "UniNni": ++AAL5 network setting. 0 = UNI (default), 1 = NNI. ++ ++@par Channel Configuration Parameters ++ ++All AAL5 channel parameters may also be configured through the @c ChannelSetup() interface. ++Following is the list of @p CHANNEL_INFO members that may be modified by the driver when ++calling @c ChannelSetup(). The driver may provide a value of 0xFFFFFFFF for any channel ++parameter to select a default value for the parameter. The driver should at a minimum ++configure @p Vci and @p Vpi. The usage of all parameters beginning with TxVc_, ++TxVp_, RxVc_, RxVp_ is described in greater detail in the SAR Firmware Spec. ++These parameters are mainly associated with QoS and OAM functionality. ++ ++- "RxNumBuffers": ++The number of Rx buffer descriptors to allocate for Ch. ++- "RxBufSize": ++Size (in bytes) for each Rx buffer. ++- "RxBufferOffset": ++Number of bytes to offset rx data from start of buffer (must be less than buffer size). ++- "RxServiceMax": ++Maximum number of packets to service at one time. ++- "TxNumBuffers": ++The number of Tx buffer descriptors to allocate for Ch. ++- "TxNumQueues": ++Number of Tx queues for this channel (1-2). Choosing 2 enables a low priority SAR queue. ++- "TxServiceMax": ++Maximum number of packets to service at one time. ++- "CpcsUU": ++The 2-byte CPCS UU and CPI information. ++- "Gfc": ++Generic Flow Control. Used in ATM header of Tx packets. ++- "Clp": ++Cell Loss Priority. Used in ATM header of Tx packets. ++- "Pti": ++Payload Type Indication. Used in ATM header of Tx packets. ++- "DaMask": ++Specifies whether credit issuance is paused when Tx data not available. ++- "Priority": ++Priority bin this channel will be scheduled within. ++- "PktType": ++0=AAL5,1=Null AAL,2=OAM,3=Transparent,4=AAL2. ++- "Vci": ++Virtual Channel Identifier. ++- "Vpi": ++Virtual Path Identifier. ++- "TxVc_AtmHeader": ++In firmware OAM mode, this ++is the ATM header to be appended to front of firmware generated VC OAM cells for ++this channel. Note: To generate host OAM cells, call @c Send() with ++the appropriate mode. ++- "TxVc_CellRate": ++Tx rate, set as clock ticks between transmissions (SCR for VBR, CBR for CBR). ++- "TxVc_QosType": ++0=CBR,1=VBR,2=UBR,3=UBRmcr. ++- "TxVc_Mbs": ++Min Burst Size in cells. ++- "TxVc_Pcr": ++Peak Cell Rate for VBR in clock ticks between transmissions. ++- "TxVc_OamTc": ++TC Path to transmit OAM cells for TX connections (0,1). ++- "TxVc_VpOffset": ++Offset to the OAM VP state table for TX connections. Channels with the same ++VPI must have the same VpOffset value. Channels with different VPIs ++must have unique VpOffset values. ++- "RxVc_OamCh": ++Channel to which to terminate received OAM cells to be forwarded to the Host ++for either Host OAM mode, or when RxVc_OamToHost is enabled during Firmware ++OAM mode. ++- "RxVc_OamToHost": ++Indicates whether to pass received unmatched OAM loopback cells to the host; ++0=do not pass, 1=pass. ++- "RxVc_AtmHeader": ++ATM Header placed on firmware gen'd OAM cells for this channel on a Rx ++connection (must be big endian with 0 PTI). ++- "RxVc_OamTc": ++TC Path to transmit OAM cells for RX connections (0,1). ++- "RxVc_VpOffset": ++Offset to the OAM VP state table for RX connections. Channels with the same ++VPI must have the same VpOffset value. Channels with different VPIs ++must have unique VpOffset values. ++- "TxVp_OamTc": ++TC Path to transmit OAM cells for TX VP connections (0,1). ++- "TxVp_AtmHeader": ++ATM Header placed on firmware gen'd VP OAM cells for this channel on a Tx VP ++connection (must be big endian with 0 VCI). ++- "RxVp_OamCh": ++Channel to which to terminate received OAM cells to be forwarded to the Host ++for either Host OAM mode, or when RxVc_OamToHost is enabled during Firmware ++OAM mode. ++- "RxVp_OamToHost": ++Indicates whether to pass received unmatched OAM loopback cells to the host; ++0=do not pass, 1=pass. ++- "RxVp_AtmHeader": ++In firmware OAM mode, this ++is the ATM header to be appended to front of firmware generated VP OAM cells for ++this channel. Note: To generate host OAM cells, call @c Send() with ++the appropriate mode. ++- "RxVp_OamTc": ++TC Path to transmit OAM cells for RX VP connections (0,1). ++- "RxVp_OamVcList": ++This 32-bit field is one-hot encoded to indicate all the VC channels that are ++associated with this VP channel. A value of 21 will indicate that VC ++channels 0, 2, and 4 are associated with this VP channel. ++- "FwdUnkVc": ++Indicates whether or not to forward unknown VCI/VPI cells to the host. This ++parameter only takes effect if the channel's PktType is Transparent(3). ++1=forwarding enabled, 0=forwarding disabled. ++ ++@section aal5_details API Implementation Details ++ ++ATTENTION: Documentation given here supplements the documentation given in the general ++CPHAL API section. The following details are crucial to correct usage of the ++AAL5 CPHAL. ++ ++@par Receive() ++The least significant byte of @p Mode contains the channel number. Bit 31 ++indicates whether or not the ATM header is present in the first fragment of ++the packet. If bit 31 is set, the 4 byte ATM header (minus HEC) will be provided ++in the first fragment, with the payload beginning in the second fragment. Currently, ++this is the default behavior for host OAM and transparent mode packets. ++Bits 17-16 indicate the packet type that is being received. ++Mode Parameter Breakdown:
++- 31 ATM Header In First Fragment (1=true, 0=false)
++- 30-18 Unused.
++- 17-16 Pkt Type.
++ - 0=AAL5
++ - 1=PTI Based Null AAL
++ - 2=OAM
++ - 3=Transparent
++- 15-08 Unused.
++- 07-00 Channel Number. ++ ++@par Send() ++The most significant 16 bits of the first fragment 'len' is used as the Offset ++to be added to the packet. @c Send() will reserve this many bytes at the ++beginning of the transmit buffer prior to the first byte of valid data. ++For the @p Mode parameter, Bit 31 must be set if the user has sent a packet with ++the ATM Header (minus HEC) embedded in the first 4 bytes of the first fragment data buffer. ++The OS has the option of using a 4 byte first fragment containing only ATM header, ++or concatenating the ATM Header in front of the data payload. ++If Bit 31 is set, the ATM Header in the buffer is preserved and sent with ++each cell of the packet. Otherwise, Send() will build the ATM header based on the ++values of the Pti, Gfc, Clp, Vpi, and Vci parameters for the given channel. ++Bits 17-16 are defined as the packet type. Bits 15-08 may be used to specify the ++transmit queue to send the packet on. Only values 0 (high priority) and 1 (low ++priority) are accepted. Bits 07-00 should be used to indicate the channel number ++for the @c Send() operation. Valid channel numbers are 0-15. ++Mode Parameter Breakdown:
++- 31 ATM Header In Packet (1=true, 0=false)
++- 30-18 Unused.
++- 17-16 Pkt Type.
++ - 0=AAL5
++ - 1=PTI Based Null AAL
++ - 2=OAM
++ - 3=Transparent
++- 15-08 Transmit Queue.
++- 07-00 Channel Number. ++ ++@par ChannelSetup() ++The AAL5 @c ChannelSetup() always configures both the Tx and Rx side of the channel ++connection in the same call. ++ ++@par ChannelTeardown() ++Regardless of the channel teardown direction selected, the AAL5 CPHAL will always ++teardown both the Tx and Rx side of the channel connection. ++ ++@par TeardownComplete() ++The value for the @p Direction parameter should be ignored for the AAL5 implementation, ++since both directions (Tx and Rx) are always torndown in response to a @c ChannelTeardown() ++command. ++ ++@par Control() (HAL version) ++Defined keys and actions. Unless otherwise stated, the data type ++for Value is pointer to unsigned integer. The list is broken into ++three groups, one group which can be used anytime, one group that should ++be used before halOpen(), and one group which can only be used after ++halOpen() (but before halClose()). For channelized parameters, replace ++'Ch' with the integer number of a channel (ex. "Gfc.4" can be used to set ++Gfc for channel 4). ++ ++MAY USE ANYTIME AFTER INIT (after halInit() is called): ++ ++- "Gfc.Ch". The OS may "Set" this value. Changing this value causes ++the Gfc in each Tx ATM header for this channel to take on the new Gfc value. ++ ++- "Clp.Ch". The OS may "Set" this value. Changing this value causes ++the Clp in each Tx ATM header for this channel to take on the new Clp value. ++ ++- "Pti.Ch". The OS may "Set" this value. Changing this value causes ++the Pti in each Tx ATM header for this channel to take on the new Pti value. ++ ++- "CpcsUU.Ch". The OS may "Set" this value. Changing this value causes ++the CpcsUU in each Tx ATM header for this channel to take on the new CpcsUU value. ++ ++- "OamMode". Specifies if host or firmware is performing OAM functions; 0 = Host OAM, ++1 = Firmware OAM. When set, all SAR channels will be configured for ++the selection, including AAL2 channels. ++ ++- "OamLbTimeout". Specifies the firmware OAM loopback timeout, in milliseconds. ++ ++- "DeviceCPID". The OS may "Set" this value. This is the OAM connection ++point identifier. The OS should provide a pointer to an array of 4 32-bit ++integers. Each word must be configured in big endian format. ++ ++- "FwdUnkVc.Ch". Indicates whether or not to forward unknown VCI/VPI cells to the host. ++This parameter only takes effect if the channel's PktType is Transparent(3). ++1=forwarding enabled, 0=forwarding disabled. ++ ++MAY USE ONLY BEFORE HAL IS OPEN (before halOpen() call): ++- "StrictPriority". The OS may "Set" this value. Setting to 1 causes ++a different interrupt processing routine to be used, which gives strict ++priority to channels with lower numbers (channel 0 has highest priority). ++The default handler gives equal priority to all channels. ++ ++- "MaxFrags". The OS may "Set" or "Get" this value. This defines the maximum ++number of fragments that can be received by the AAL5 Rx port. The default ++value for AAL5 is 46. This provides enough space to receive a maximum ++length AAL5 packet (65,568 bytes) with the default buffer size of 1518 bytes, and ++any amount of RxBufferOffset. If the buffer size is configured to be smaller, ++the OS *MUST* modify this parameter according to the following formula: ++((System Max AAL5 packet length)/(RxBufSize)) + 2. (The extra two fragments in ++the formula allow for RxBufferOffset and one fragment for the ATM Header, used ++when receiving host OAM or transparent mode packets) ++ ++MAY USE ONLY AFTER HAL IS 'OPEN' (after halOpen() call): ++- "Stats;Level;Ch;Queue". The OS may "Get" Stats groups with this key, where ++'Level' is an integer from 0-4, Ch is an integer from 0-15, and Queue is ++an integer from 0-1. Note that Ch is not required for Level 4 stats, and Queue ++is not required for Level 0, 3, and 4. The statistics functionality and return ++value is described in the appendix entitled "Configuration and Control". ++ ++- "TxVc_CellRate.Ch". The OS may "Set" this value. Can be used to modify ++CellRate for a channel on the fly. ++ ++- "TxVc_Mbs.Ch". The OS may "Set" this value. Can be used to modify ++Mbs for a channel on the fly. ++ ++- "TxVc_Pcr.Ch". The OS may "Set" this value. Can be used to modify ++Pcr for a channel on the fly. ++ ++- "PdspEnable". The OS may "Set" this value. Value 0 disables the PDSP. ++Value 1 enables to PDSP. ++ ++- "DeviceCPID". The OS may "Set" this value. The Value should be an array ++of 4 32-bit integers that comprise the CPID. ++ ++- "RxVc_RDICount.Ch". The OS may "Get" or "Set" this value. Get returns ++the current RDI count for the VC channel. Set clears the counter, and the Value ++is ignored. ++ ++- "RxVp_RDICount.Ch". The OS may "Get" or "Set" this value. Get returns ++the current RDI count for the VP channel. Set clears the counter, and the Value ++is ignored. ++ ++- "RxVc_AISseg.Ch". The OS may "Get" this value. This is an indication of ++AIS segment error for the VC channel. ++ ++- "RxVp_AISseg.Ch". The OS may "Get" this value. This is an indication of ++AIS segment error for the VP channel. ++ ++- "RxVc_AISetoe.Ch". The OS may "Get" this value. This is an indication of ++AIS end-to-end error for the VC channel. ++ ++- "RxVp_AISetoe.Ch". The OS may "Get" this value. This is an indication of ++AIS end-to-end error for the VP channel. ++ ++- "RxVc_OamCh.Ch". The OS may "Set" this value. Channel to which to terminate ++received OAM cells to be forwarded to the Host for either Host OAM mode, or when ++RxVc_OamToHost is enabled during Firmware OAM mode. ++ ++- "RxVp_OamCh.Ch". The OS may "Set" this value. Channel to which to terminate ++received OAM cells to be forwarded to the Host for either Host OAM mode, or when ++RxVp_OamToHost is enabled during Firmware OAM mode. ++ ++- "F4_LB_Counter". The OS may "Get" this value. This is a count of the number ++ of near-end F4 loopbacks performed by the PDSP in firmware OAM mode. ++ ++- "F5_LB_Counter". The OS may "Get" this value. This is a count of the number ++ of near-end F5 loopbacks performed by the PDSP in firmware OAM mode. ++ ++- "TxVc_AtmHeader.Ch". The OS may "Set" this value. In firmware OAM mode, this ++is the ATM header to be appended to front of firmware generated VC OAM cells for ++this channel. In host OAM mode, this is used as the ATM header to be appended ++to front of host generated VC OAM cells for this channel. It must be configured ++as big endian with PTI=0. Note: To generate host OAM cells, call @c Send() with ++the appropriate mode. ++ ++- "TxVp_AtmHeader.Ch". The OS may "Set" this value. In firmware OAM mode, this ++is the ATM header to be appended to front of firmware generated VP OAM cells for ++this channel. In host OAM mode, this is used as the ATM header to be appended ++to front of host generated VP OAM cells for this channel. It must be configured ++as big endian with VCI=0. Note: To generate host OAM cells, call @c Send() with ++the appropriate mode. ++ ++- "PdspEnable". The OS may "Set" this value. Controls whether or not the PDSP is ++allowed to fetch new instructions. The PDSP is enabled by the CPHAL during Open(), ++and disabled during Close(). 0 = disabled, 1 = enabled. ++ ++@par Control() (OS version) ++Defined keys and actions: ++ ++- "Firmware". The CPHAL will perform a "Get" action for the key "Firmware". A pointer ++to a pointer is passed in @p Value. The OS must modify the referenced pointer to point ++to the firmware. ++ ++- "FirmwareSize". The CPHAL will perform a "Get" action for the key "FirmwareSize". ++The OS must place the firmware size in the memory pointed at by @p Value. ++ ++- "OamLbResult". When a channel that is in firmware OAM mode is commanded to perform ++a loopback function, the result of the loopback generates an interrupt that is handled ++by the OS like any other interrupt. The CPHAL, upon servicing the interrupt, will call ++osControl with this key, and an action of "Set". The @p Value parameter will be a ++pointer to the integer result. 1 = pass, 0 = fail. ++ ++- "SarFreq". The CPHAL will perform a "Get" action for this key. The OS should place ++the SAR frequency (in Hz) in the memory pointed at by @p Value. ++ ++@section aal5_stats AAL5 Specific Statistics ++ ++Statistics level '0' contains all AAL5 specific statistics. The following values will ++be obtained when requesting stats level 0: ++ ++- "Crc Errors". Number of CRC errors reported by SAR hardware. Incremented for received ++packets that contain CRC errors. ++ ++- "Len Errors". Number of length errors reported by SAR hardware. Incremented for received ++packets that are in excess of 1366 cells. ++ ++- "Abort Errors". Number of abort errors reported by SAR hardware. ++ ++- "Starv Errors". Number of buffer starvation errors reported by SAR hardware. Incremented ++when a part or all of a buffer cannot be received due to lack of RX buffer resources. The SAR ++drops all cells associated with the packet for each buffer starvation error that occurs. ++ ++*/ ++ ++/* register files */ ++#include "cp_sar_reg.h" ++ ++#define _CPHAL_AAL5 ++#define _CPHAL ++#define _CPPI_TEST /** @todo remove for release */ ++#define __CPHAL_CPPI_OFFSET /* support use of offset */ ++ ++/* OS Data Structure definitions */ ++ ++typedef void OS_PRIVATE; ++typedef void OS_DEVICE; ++typedef void OS_SENDINFO; ++typedef void OS_RECEIVEINFO; ++typedef void OS_SETUP; ++ ++/* CPHAL Data Structure definitions */ ++ ++typedef struct hal_device HAL_DEVICE; ++typedef struct hal_private HAL_PRIVATE; ++typedef struct hal_private HAL_RECEIVEINFO; ++ ++/* include CPHAL header files here */ ++#include "cpcommon_cpaal5.h" ++#include "cpswhal_cpaal5.h" ++#include "aal5sar.h" ++#include "cpcommon_cpaal5.c" ++ ++#define CR_SERVICE (170-1) ++#define UTOPIA_PAUSE_REG (*(volatile bit32u *)0xa4000000) ++ ++/* ++these masks are for the mode parameter used in halSend/OsReceive ++(may move these elsewhere) ++*/ ++#define CH_MASK 0xff ++#define PRI_MASK 0x10000 ++ ++/* Rcb/Tcb Constants */ ++#define CB_SOF_BIT (1<<31) ++#define CB_EOF_BIT (1<<30) ++#define CB_SOF_AND_EOF_BIT (CB_SOF_BIT|CB_EOF_BIT) ++#define CB_OWNERSHIP_BIT (1<<29) ++#define CB_EOQ_BIT (1<<28) ++#define CB_SIZE_MASK 0x0000ffff ++#define CB_OFFSET_MASK 0xffff0000 ++#define RCB_ERRORS_MASK 0x03fe0000 ++#define RX_ERROR_MASK 0x000f0000 ++#define CRC_ERROR_MASK 0x00010000 ++#define LENGTH_ERROR_MASK 0x00020000 ++#define ABORT_ERROR_MASK 0x00040000 ++#define STARV_ERROR_MASK 0x00080000 ++#define TEARDOWN_VAL 0xfffffffc ++ ++/* interrupt vector masks */ ++#define TXH_PEND 0x01000000 ++#define TXL_PEND 0x02000000 ++#define RX_PEND 0x04000000 ++#define STS_PEND 0x08000000 ++#define AAL2_PEND 0x10000000 ++#define INT_PENDING (TXH_PEND | TXL_PEND | RX_PEND | STS_PEND | AAL2_PEND) ++#define STS_PEND_INVEC 0x0001F000 ++#define RX_PEND_INVEC 0x00000F00 ++#define TXL_PEND_INVEC 0x000000F0 ++#define TXH_PEND_INVEC 0x0000000F ++#define AIS_SEG_MASK 0x1 /* +01.02.00 */ ++#define AIS_SEG_SHIFT 0 /* +01.02.00 */ ++#define AIS_ETOE_MASK 0x20000 /* +01.02.00 */ ++#define AIS_ETOE_SHIFT 17 /* +01.02.00 */ ++#define RDI_CNT_MASK 0xffff0000 /* +01.02.00 */ ++#define RDI_CNT_SHIFT 16 /* +01.02.00 */ ++ ++/* ++ * This function takes a vpi/vci pair and computes the 4 byte atm header ++ * (minus the HEC). ++ * ++ * @param vpi Virtual Path Identifier. ++ * @param vci Virtual Channel Identifier. ++ * ++ * @return A properly formatted ATM header, without the HEC. ++ */ ++static int atmheader(int gfc, int vpi, int vci, int pti, int clp) ++ { ++ int itmp; ++ ++ itmp=0; ++ ++ /* UNI Mode uses the GFC field */ ++ itmp |= ((gfc & 0xF) << 28); ++ itmp |= ((vpi & 0xFF) << 20); ++ ++ /* if NNI Mode, no gfc and larger VPI */ ++ /*itmp |= ((vpi & 0xFFF) << 20);*/ ++ ++ itmp|=((vci & 0xFFFF) << 4); ++ itmp|=((pti & 0x7) << 1); ++ itmp|=(clp & 0x1); ++ return(itmp); ++ } ++ ++#include "cppi_cpaal5.c" ++ ++/* ++ * Re-entrancy Issues ++ * In order to ensure successful re-entrancy certain sections of the ++ * CPHAL code will be bracketed as Critical. ++ * The OS will provide the function Os.CriticalSection(BOOL), which ++ * will be passed a TRUE to enter the Critical Section and FALSE to exit. ++ */ ++ ++/* ++ * @ingroup CPHAL_Functions ++ * Clears the statistics information. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return 0 OK, Non-zero not OK ++ */ ++static int StatsClear(HAL_DEVICE *HalDev) ++ { ++ int i; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]StatsClear(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* clear stats */ ++ for (i=0; iStats.CrcErrors[i]=0; ++ HalDev->Stats.LenErrors[i]=0; ++ HalDev->Stats.DmaLenErrors[i]=0; ++ HalDev->Stats.AbortErrors[i]=0; ++ HalDev->Stats.StarvErrors[i]=0; ++ HalDev->Stats.TxMisQCnt[i][0]=0; ++ HalDev->Stats.TxMisQCnt[i][1]=0; ++ HalDev->Stats.RxMisQCnt[i]=0; ++ HalDev->Stats.RxEOQCnt[i]=0; ++ HalDev->Stats.TxEOQCnt[i][0]=0; ++ HalDev->Stats.TxEOQCnt[i][1]=0; ++ HalDev->Stats.RxPacketsServiced[i]=0; ++ HalDev->Stats.TxPacketsServiced[i][0]=0; ++ HalDev->Stats.TxPacketsServiced[i][1]=0; ++ HalDev->Stats.TxMaxServiced[i][0]=0; ++ HalDev->Stats.TxMaxServiced[i][1]=0; ++ } ++ HalDev->Stats.RxTotal=0; ++ HalDev->Stats.TxTotal=0; ++ HalDev->Stats.RxMaxServiced=0; ++ return (EC_NO_ERRORS); ++ } ++ ++/* ++ * Returns statistics information. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return 0 ++ */ ++/* ++static STAT_INFO* StatsGet(HAL_DEVICE *HalDev) ++ { ++ STAT_INFO* MyStats = &HalDev->Stats; ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]StatsGet(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ dbgPrintf("HAL Stats:\n"); ++ DispStat(HalDev, "Rx Total",MyStats->RxTotal); ++ DispStat(HalDev, "Tx Total",MyStats->TxTotal); ++ DispStat(HalDev, "Rx Peak",MyStats->RxMaxServiced); ++ DispStat(HalDev, "TxH Peak",MyStats->TxMaxServiced[0][0]); ++ DispStat(HalDev, "TxL Peak",MyStats->TxMaxServiced[0][1]); ++ DispChStat(HalDev, "CrcErr",&MyStats->CrcErrors[0],1); ++ DispChStat(HalDev, "LenErr",&MyStats->LenErrors[0],1); ++ DispChStat(HalDev, "DmaLenErr",&MyStats->DmaLenErrors[0],1); ++ DispChStat(HalDev, "AbortErr",&MyStats->AbortErrors[0],1); ++ DispChStat(HalDev, "StarvErr",&MyStats->StarvErrors[0],1); ++ DispChStat(HalDev, "TxH MisQ Cnt",&MyStats->TxMisQCnt[0][0],2); ++ DispChStat(HalDev, "TxL MisQ Cnt",&MyStats->TxMisQCnt[0][1],2); ++ DispChStat(HalDev, "Rx MisQ Cnt",&MyStats->RxMisQCnt[0],1); ++ DispChStat(HalDev, "Rx EOQ Cnt",&MyStats->RxEOQCnt[0],1); ++ DispChStat(HalDev, "TxH EOQ Cnt",&MyStats->TxEOQCnt[0][0],2); ++ DispChStat(HalDev, "TxL EOQ Cnt",&MyStats->TxEOQCnt[0][1],2); ++ DispChStat(HalDev, "Rx Pkts",&MyStats->RxPacketsServiced[0],1); ++ DispChStat(HalDev, "TxH Pkts",&MyStats->TxPacketsServiced[0][0],2); ++ DispChStat(HalDev, "TxL Pkts",&MyStats->TxPacketsServiced[0][1],2); ++ ++ return (&HalDev->Stats); ++ } ++*/ ++ ++#ifdef __CPHAL_DEBUG ++void dbgChannelConfigDump(HAL_DEVICE *HalDev, int Ch) ++ { ++ CHANNEL_INFO *HalCh = &HalDev->ChData[Ch]; ++ dbgPrintf(" [aal5 Inst %d, Ch %d] Config Dump:\n", HalDev->Inst, Ch); ++ dbgPrintf(" TxNumBuffers :%08d, TxNumQueues :%08d\n", ++ HalCh->TxNumBuffers, HalCh->TxNumQueues); ++ dbgPrintf(" RxNumBuffers :%08d, RxBufSize :%08d\n", ++ HalCh->RxNumBuffers, HalCh->RxBufSize); ++ dbgPrintf(" TxServiceMax :%08d, RxServiceMax:%08d\n", ++ HalCh->TxServiceMax, HalCh->RxServiceMax); ++ dbgPrintf(" RxBufferOffset:%08d, DaMask :%08d\n", ++ HalCh->RxBufferOffset, HalCh->DaMask); ++ dbgPrintf(" CpcsUU :%08d, Gfc :%08d\n", ++ HalCh->CpcsUU, HalCh->Gfc); ++ dbgPrintf(" Clp :%08d, Pti :%08d\n", ++ HalCh->Clp, HalCh->Pti); ++ dbgPrintf(" Priority :%08d, PktType :%08d\n", ++ HalCh->Priority, HalCh->PktType); ++ dbgPrintf(" Vci :%08d, Vpi :%08d\n", ++ HalCh->Vci, HalCh->Vpi); ++ dbgPrintf(" TxVc_CellRate :%08d, TxVc_QosType:%08d\n", ++ HalCh->TxVc_CellRate, HalCh->TxVc_QosType); ++ dbgPrintf(" TxVc_Mbs :%08d, TxVc_Pcr :%08d\n", ++ HalCh->TxVc_Mbs, HalCh->TxVc_Pcr); ++ dbgPrintf(" TxVc_AtmHeader:%08d\n", ++ HalCh->TxVc_AtmHeader); ++ osfuncSioFlush(); ++ } ++#endif ++ ++/* ++ * Retrieves channel parameters from configuration file. Any parameters ++ * which are not found are ignored, and the HAL default value will apply, ++ * unless a new value is given through the channel structure in the call ++ * to ChannelSetup. ++ */ ++static int ChannelConfigGet(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ unsigned int Ret, Value, Ch = HalChn->Channel; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ void *ChInfo; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]ChannelConfigGet(HalDev:%08x, HalChn:%08x)\n", (bit32u)HalDev, ++ (bit32u)HalChn); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ Ret=OsFunc->DeviceFindParmValue(HalDev->DeviceInfo, channel_names[Ch], &ChInfo); ++ if (Ret) return (EC_AAL5|EC_FUNC_CHSETUP|EC_VAL_CH_INFO_NOT_FOUND); ++ ++ /* i don't care if a value is not found because they are optional */ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxNumBuffers", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxNumBuffers = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxNumQueues", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxNumQueues = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxServiceMax", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxServiceMax = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "RxNumBuffers", &Value); ++ if (!Ret) HalDev->ChData[Ch].RxNumBuffers = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "RxBufferOffset", &Value); ++ if (!Ret) HalDev->ChData[Ch].RxBufferOffset = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "RxBufSize", &Value); ++ if (!Ret) HalDev->ChData[Ch].RxBufSize = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "RxServiceMax", &Value); ++ if (!Ret) HalDev->ChData[Ch].RxServiceMax = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "CpcsUU", &Value); ++ if (!Ret) HalDev->ChData[Ch].CpcsUU = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "Gfc", &Value); ++ if (!Ret) HalDev->ChData[Ch].Gfc = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "Clp", &Value); ++ if (!Ret) HalDev->ChData[Ch].Clp = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "Pti", &Value); ++ if (!Ret) HalDev->ChData[Ch].Pti = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "DaMask", &Value); ++ if (!Ret) HalDev->ChData[Ch].DaMask = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "Priority", &Value); ++ if (!Ret) HalDev->ChData[Ch].Priority = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "PktType", &Value); ++ if (!Ret) HalDev->ChData[Ch].PktType = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "Vci", &Value); ++ if (!Ret) HalDev->ChData[Ch].Vci = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "Vpi", &Value); ++ if (!Ret) HalDev->ChData[Ch].Vpi = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxVc_CellRate", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxVc_CellRate = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxVc_QosType", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxVc_QosType = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxVc_Mbs", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxVc_Mbs = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxVc_Pcr", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxVc_Pcr = Value; ++ ++ Ret=OsFunc->DeviceFindParmUint(ChInfo, "TxVc_AtmHeader", &Value); ++ if (!Ret) HalDev->ChData[Ch].TxVc_AtmHeader = Value; ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/* ++ * Sets up channel parameters in the hardware, and initializes the CPPI ++ * TX and RX buffer descriptors and buffers. ++ */ ++static int ChannelConfigApply(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ int j, Ch = HalChn->Channel; ++ volatile bit32u *pTmp; ++ int Ret; /* +GSG 030410 */ ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]ChannelConfigApply(HalDev:%08x, HalChn:%08x)\n", (bit32u)HalDev, ++ (bit32u)HalChn); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ if ((HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) || (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE)) ++ { ++ return(EC_AAL5|EC_FUNC_CHSETUP|EC_VAL_CH_ALREADY_OPEN); ++ } ++ ++ HalDev->InRxInt[Ch]=FALSE; ++ ++ /* Initialize Queue Data */ ++ HalDev->RxActQueueHead[Ch]=0; ++ HalDev->RxActQueueCount[Ch]=0; ++ HalDev->TxActQueueHead[Ch][0]=0; ++ HalDev->TxActQueueHead[Ch][1]=0; ++ HalDev->TxActQueueCount[Ch][0]=0; ++ HalDev->TxActQueueCount[Ch][1]=0; ++ HalDev->RxActive[Ch] = FALSE; ++ HalDev->TxActive[Ch][0] = FALSE; ++ HalDev->TxActive[Ch][1] = FALSE; ++ ++ /* Clear Rx State RAM */ ++ pTmp = pRX_DMA_STATE_WORD_0(HalDev->dev_base) + (Ch*64); ++ for (j=0; jdev_base) + (Ch*64); ++ for (j=0; jdev_base) + (Ch*64)); ++ *pTmp |= (HalDev->ChData[Ch].RxBufferOffset & 0xFF); ++ ++ /* Initialize buffer memory for the channel */ ++ Ret = InitTcb(HalDev, Ch); ++ if (Ret) return (Ret); ++ ++ Ret = InitRcb(HalDev, Ch); ++ if (Ret) return (Ret); ++ ++ /* setup interrupt mask/enable for the channel */ ++ SAR_TX_MASK_SET(HalDev->dev_base) = (1<ChData[Ch].TxNumQueues == 2) /* +GSG 030421 */ ++ SAR_TX_MASK_SET(HalDev->dev_base) = (1<dev_base) = (1<SarFunc->ChannelSetup(HalDev->SarDev, &HalDev->ChData[Ch]); /* ~GSG 030410 */ ++ if (Ret) /* +GSG 030410 */ ++ return (Ret); /* +GSG 030410 */ ++ ++ /* channel officially open for business */ ++ HalDev->ChIsOpen[Ch][DIRECTION_TX] = TRUE; ++ HalDev->ChIsOpen[Ch][DIRECTION_RX] = TRUE; ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/* ++ * Sets up HAL default channel configuration parameter values. ++ */ ++static void ChannelConfigInit(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ int Ch = HalChn->Channel; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]ChannelConfigInit(HalDev:%08x, HalChn:%08x)\n", (bit32u)HalDev, ++ (bit32u)HalChn); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ HalDev->ChData[Ch].Channel = Ch; ++ HalDev->ChData[Ch].TxNumBuffers = cfg_tx_num_bufs[Ch]; ++ HalDev->ChData[Ch].RxNumBuffers = cfg_rx_num_bufs[Ch]; ++ HalDev->ChData[Ch].RxBufSize = cfg_rx_buf_size[Ch]; ++ HalDev->ChData[Ch].RxBufferOffset = cfg_rx_buf_offset[Ch]; ++ HalDev->ChData[Ch].TxNumQueues = cfg_tx_num_queues[Ch]; ++ HalDev->ChData[Ch].CpcsUU = cfg_cpcs_uu[Ch]; ++ HalDev->ChData[Ch].DaMask = cfg_da_mask[Ch]; ++ HalDev->ChData[Ch].Priority = cfg_priority[Ch]; ++ HalDev->ChData[Ch].PktType = cfg_pkt_type[Ch]; ++ HalDev->ChData[Ch].Vci = cfg_vci[Ch]; ++ HalDev->ChData[Ch].Vpi = cfg_vpi[Ch]; ++ HalDev->ChData[Ch].TxVc_CellRate = cfg_cell_rate[Ch]; ++ HalDev->ChData[Ch].TxVc_QosType = cfg_qos_type[Ch]; ++ HalDev->ChData[Ch].TxVc_Mbs = cfg_mbs[Ch]; ++ HalDev->ChData[Ch].TxVc_Pcr = cfg_pcr[Ch]; ++ HalDev->ChData[Ch].Gfc = cfg_gfc[Ch]; ++ HalDev->ChData[Ch].Clp = cfg_clp[Ch]; ++ HalDev->ChData[Ch].Pti = cfg_pti[Ch]; ++ HalDev->ChData[Ch].RxServiceMax = cfg_rx_max_service[Ch]; ++ HalDev->ChData[Ch].TxServiceMax = cfg_tx_max_service[Ch]; ++ } ++ ++/* ++ * Update per channel data in the HalDev based channel structure. ++ * If a certain channel parameter has been passed with the HAL_DEFAULT ++ * value (0xFFFFFFFF), then do not copy it. ++ */ ++static void ChannelConfigUpdate(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) ++ { ++ int Ch = HalChn->Channel; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]ChannelConfigUpdate(HalDev:%08x, HalChn:%08x)\n", (bit32u)HalDev, ++ (bit32u)HalChn); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ HalDev->ChData[Ch].Channel = Ch; ++ ++ /* ChannelUpdate is a macro defined in cpcommon.h. It requires ++ the presence of the variables named 'Ch' and 'HalChn'.*/ ++ ChannelUpdate(DaMask); ++ ChannelUpdate(Priority); ++ ChannelUpdate(PktType); ++ ChannelUpdate(Vci); ++ ChannelUpdate(Vpi); ++ ChannelUpdate(CpcsUU); ++ ChannelUpdate(Gfc); ++ ChannelUpdate(Clp); ++ ChannelUpdate(Pti); ++ /* AAL5 Stuff */ ++ ChannelUpdate(TxNumBuffers); ++ ChannelUpdate(RxNumBuffers); ++ ChannelUpdate(RxBufSize); ++ ChannelUpdate(RxBufferOffset); ++ ChannelUpdate(TxNumQueues); ++ ChannelUpdate(TxServiceMax); ++ ChannelUpdate(RxServiceMax); ++ /* PDSP STATE RAM */ ++ ChannelUpdate(TxVc_CellRate); ++ ChannelUpdate(TxVc_QosType); ++ ChannelUpdate(TxVc_Mbs); ++ ChannelUpdate(TxVc_Pcr); ++ /* OAM */ ++ ChannelUpdate(TxVc_AtmHeader); ++ ChannelUpdate(TxVc_OamTc); ++ ChannelUpdate(TxVc_VpOffset); ++ ChannelUpdate(RxVc_OamCh); ++ ChannelUpdate(RxVc_OamToHost); ++ ChannelUpdate(RxVc_AtmHeader); ++ ChannelUpdate(RxVc_VpOffset); ++ ChannelUpdate(RxVc_OamTc); ++ ChannelUpdate(TxVp_AtmHeader); ++ ChannelUpdate(TxVp_OamTc); ++ ChannelUpdate(RxVp_AtmHeader); ++ ChannelUpdate(RxVp_OamCh); ++ ChannelUpdate(RxVp_OamTc); ++ ChannelUpdate(RxVp_OamToHost); ++ ChannelUpdate(RxVp_OamVcList); ++ ChannelUpdate(FwdUnkVc); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function opens the specified channel. The caller must populate ++ * the @p HalCh structure. CPHAL default values may be requested for any or all ++ * members of the @p HalCh structure by supplying a value of 0xFFFFFFFF for the ++ * given member. The @p OsSetup parameter is a pointer to an OS defined ++ * data structure. If the CPHAL later calls @c MallocRxBuffer(), this pointer ++ * is returned in that call. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param HalCh Per channel information structure. Implementation specific. ++ * @param OsSetup Pointer to an OS-defined data structure. ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_NULL_CH_STRUCT "EC_VAL_NULL_CH_STRUCT"
++ * @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"
++ * @ref EC_VAL_CH_ALREADY_OPEN "EC_VAL_CH_ALREADY_OPEN"
++ * @ref EC_VAL_RX_STATE_RAM_NOT_CLEARED "EC_VAL_RX_STATE_RAM_NOT_CLEARED"
++ * @ref EC_VAL_TX_STATE_RAM_NOT_CLEARED "EC_VAL_TX_STATE_RAM_NOT_CLEARED"
++ * @ref EC_VAL_TCB_MALLOC_FAILED "EC_VAL_TCB_MALLOC_FAILED"
++ * @ref EC_VAL_RCB_MALLOC_FAILED "EC_VAL_RCB_MALLOC_FAILED"
++ * @ref EC_VAL_RX_BUFFER_MALLOC_FAILED "EC_VAL_RX_BUFFER_MALLOC_FAILED"
++ * @ref EC_VAL_LUT_NOT_READY "EC_VAL_LUT_NOT_READY"
++ */ ++static int halChannelSetup(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup) ++ { ++ int Ch, Ret; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halChannelSetup(HalDev:%08x, HalCh:%08x, OsSetup:%08x)\n", (bit32u)HalDev, ++ (bit32u)HalCh, (bit32u)OsSetup); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify proper device state */ ++ if (HalDev->State < enInitialized) ++ return (EC_AAL5|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE); ++ ++ /* We require the channel structure to be passed, even if it only contains ++ the channel number */ ++ if (HalCh == NULL) ++ { ++ return(EC_AAL5|EC_FUNC_CHSETUP|EC_VAL_NULL_CH_STRUCT); ++ } ++ ++ Ch = HalCh->Channel; ++ ++ if ((Ch < 0) || (Ch > MAX_AAL5_CHAN)) ++ { ++ return(EC_AAL5|EC_FUNC_CHSETUP|EC_VAL_INVALID_CH); ++ } ++ ++ /* if channel is already open, this call is invalid */ ++ if ((HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) || (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE)) ++ { ++ return(EC_AAL5|EC_FUNC_CHSETUP|EC_VAL_CH_ALREADY_OPEN); ++ } ++ ++ /* channel is closed, but might be setup. If so, reopen the hardware channel. */ ++ if ((HalDev->ChIsSetup[Ch][DIRECTION_TX] == FALSE) && (HalDev->ChIsSetup[Ch][DIRECTION_RX] == FALSE)) ++ { ++ /* Setup channel configuration */ ++ /* Store OS_SETUP */ ++ HalDev->ChData[Ch].OsSetup = OsSetup; /* ~GSG 030508 */ ++ ++ /* setup HAL default values for this channel first */ ++ ChannelConfigInit(HalDev, HalCh); ++ ++ /* retrieve options.conf channel parameters */ ++ /* currently ignoring return value, making the choice that it's okay if ++ the user does not supply channel configuration in the data store */ ++ ChannelConfigGet(HalDev, HalCh); ++ ++ /* update HalDev with data given in HalCh */ ++ ChannelConfigUpdate(HalDev, HalCh); ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(8)) ++ { ++ dbgChannelConfigDump(HalDev, Ch); ++ } ++#endif ++ ++ /* HalDev->ChIsSetup[Ch][0] = TRUE; */ ++ HalDev->ChIsSetup[Ch][DIRECTION_TX] = TRUE; ++ HalDev->ChIsSetup[Ch][DIRECTION_RX] = TRUE; ++ ++ /* I don't initialize RcbStart or TcbStart here because their values may be ++ reused across several Setup/Teardown calls */ ++ } ++ ++ /* If the hardware has been opened (is out of reset), then configure the channel ++ in the hardware. NOTE: ChannelConfigApply calls the CPSAR ChannelSetup()! */ ++ if (HalDev->State == enOpened) ++ { ++ Ret = ChannelConfigApply(HalDev, HalCh); ++ if (Ret) return (Ret); ++ } ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/* ++ * This function configures the rate at which the OAM timer scheduler ++ * channels will be scheduled. The value of OamRate is the number of ++ * clock ticks between cell transmissions (if OAM function is sourcing ++ * cells), or the number of clock ticks between events or absence of events ++ * (if OAM function is sinking cells). The value of i indicates ++ * which OAM function to apply the rate to. A list is given below. ++ * ++ * @par Oam Function Values ++ * - 0 : Loopback source ++ * - 1 : F4 CC source ++ * - 2 : F5 CC source ++ * - 3 : F4 CC sink ++ * - 4 : F5 CC sink ++ * - 5 : F4 TX AIS source ++ * - 6 : F5 TX AIS source ++ * - 7 : F4 RX RDI source ++ * - 8 : F5 RX RDI source ++ * - 9 : F4 AIS monitor ++ * - 10 : F5 AIS monitor ++ * ++ * The following is information on how to calculate the OAM rate. There ++ * is only one OAM timer that is shared among all channels. Therefore, if ++ * you wanted an OAM source function (ex. F4 CC source) to generate 1 cell/sec ++ * across 8 channels, you would need to configure the OAM timer to schedule 8 ++ * cells/sec. In addition, the credits are shared between segment and end-to-end ++ * type OAM cells, so if you were sending both types of cells, you would ++ * need to configure the OAM timer for 16 cells/sec. However, the clock ++ * rate must be specified in clock ticks between events. Using an example ++ * clock rate of 125 MHz, the rate in clock ticks can be calculated by ++ * dividing 125 Mhz by 16 cells/sec. The results is 7812500 ticks. Thus, ++ * every 7812500 clock cycles, an OAM cell will be generated for the F4 CC ++ * Source function. ++ */ ++static void OamRateConfig(HAL_DEVICE *HalDev) ++ { ++ int i; ++ bit32u OamRate, Freq = HalDev->SarFrequency; ++ ++ /* Configure OAM Timer State Block */ ++ for (i=0; iOamLbTimeout); ++ break; ++ case 1: ++ case 2: ++ case 5: ++ case 6: ++ case 7: ++ case 8: OamRate = (Freq/38); ++ break; ++ case 3: ++ case 4: OamRate = ((Freq*3) + (Freq/2))/38; ++ break; ++ case 9: ++ case 10: OamRate = ((Freq*2) + (Freq/2))/38; ++ break; ++ default: OamRate = (Freq*5); ++ break; ++ } ++ ++ *(pOAM_TIMER_STATE_WORD_0(HalDev->dev_base) + (i*64) + 1) = OamRate; ++ } ++ } ++ ++/** ++ * @ingroup AAL5_Functions ++ * This function is used to enable OAM functions (other than loopback) for a ++ * particular channel. The channel (embedded within OamConfig - see below) must ++ * have been configured for firmware OAM (not host OAM) for these configurations ++ * to take effect. More than one function may be enabled at one time. ++ * If more than one function is enabled, they must all be of the same level, all ++ * F4(VP) or all F5(VC). ++ * ++ * The usage of the OamConfig parameter is described through the table below. To ++ * initiate firmware OAM, set one or more bits in OamConfig corresponding to the ++ * various OAM functions. To disable firmware OAM functions, set bit 30 along ++ * with any other combination of bits to shutdown various OAM functions at once. ++ * ++ * Acronyms: ++ * e2e - end to end, seg - segment, CC - continuity check, ++ * AIS - Alarm Indication Signal ++ * ++ * @par Bit: Function: Description ++ * - 31: Reserved: ++ * - 30: Setup/Teardown: 0 - enable, 1 - disable (Note 1) ++ * - 29: F4 CC Source seg: 0 - no action, 1 - configure ++ * - 28: F4 CC Source e2e: 0 - no action, 1 - configure ++ * - 27: F4 AIS Source seg: 0 - no action, 1 - configure ++ * - 26: F4 AIS Source e2e: 0 - no action, 1 - configure ++ * - 25: F5 CC Source seg: 0 - no action, 1 - configure ++ * - 24: F5 CC Source e2e: 0 - no action, 1 - configure ++ * - 23: F5 AIS Source seg: 0 - no action, 1 - configure ++ * - 22: F5 AIS Source e2e: 0 - no action, 1 - configure ++ * - 21: F4 CC Sink seg: 0 - no action, 1 - configure ++ * - 20: F4 CC Sink e2e: 0 - no action, 1 - configure ++ * - 19: F5 CC Sink seg: 0 - no action, 1 - configure ++ * - 18: F5 CC Sink e2e: 0 - no action, 1 - configure ++ * - 17:8: Reserved: ++ * - 7:0: Channel: AAL5/AAL2 VC/VP channel (Note 2) ++ * ++ * ++ * Note 1: This bit must be clear to enable the specified OAM function. ++ * Note 2: This must specify the VC channel for F5 functions, and the VP ++ * channel for F4 functions. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param OamConfig A 32-bit integer field defined as follows: ++ */ ++static void halOamFuncConfig(HAL_DEVICE *HalDev, unsigned int OamConfig) ++ { ++ /* GPR 0 */ ++ SAR_PDSP_HOST_OAM_CONFIG_REG(HalDev->dev_base) = OamConfig; ++ } ++ ++/** ++ * @ingroup AAL5_Functions ++ * This function is used to enable OAM loopback functions for a particular ++ * channel. The channel (embedded within OamConfig - see below) must have been ++ * configured for firmware OAM (not host OAM) for these configurations to take ++ * effect. Only one loopback function can be enabled at a time. ++ * ++ * The LLID is inserted into to the OAM cell's LLID field, and it specifies the ++ * LLID of the connection point in the network where the generated loopback cell ++ * should be turned around. The LLID is composed of 4 32-bit words, and this ++ * function expects the caller to pass an array of 4 words in the LLID field. ++ * The CorrelationTag is a 32-bit word that the PDSP uses to correlate loopback ++ * commands with loopback responses. It should simply be changed for each ++ * call, and there is no restriction on the value used for CorrelationTag. ++ * ++ * The usage of the OamConfig parameter is described through the table below. To ++ * initiate firmware OAM, set one of the bits corresponding to the ++ * various loopback OAM functions. Note that only one loopback source may be ++ * commanded at a time. ++ * ++ * Acronyms: ++ * e2e - end to end, seg - segment, LB - loopback ++ * ++ * @par Bit: Function: Description ++ * - 31:16: Reserved: ++ * - 15: F4 LB Source seg: 0 - no action, 1 - configure (Note 1) ++ * - 14: F4 LB Source seg: 0 - no action, 1 - configure (Note 1) ++ * - 13: F4 LB Source e2e: 0 - no action, 1 - configure (Note 1) ++ * - 12: F4 LB Source e2e: 0 - no action, 1 - configure (Note 1) ++ * - 11:8: Reserved: ++ * - 7:0: Channel: AAL5/AAL2 VC/VP channel (Note 2) ++ * ++ * ++ * Note 1: Only one LB function may be enabled at one time. Once enabled, ++ * the PDSP will time out after 5 seconds. The host must wait until it ++ * has received the result of the current LB request before initiating ++ * a new request.
++ * Note 2: This must specify the VC channel for F5 functions, and the VP ++ * channel for F4 functions. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param OamConfig A 32-bit integer field defined as follows: ++ * @param LLID Loopback Location Identifier (passed as 4 word array). ++ * Must be configured in big endian format. ++ * @param CorrelationTag 32-bit tag correlates loopback commands with loopback ++ * responses. Must be configured in big endian format. ++ * ++ */ ++static void halOamLoopbackConfig(HAL_DEVICE *HalDev, unsigned int OamConfig, unsigned int *LLID, unsigned int CorrelationTag) ++ { ++ volatile bit32u *tmp; ++ ++ /* test to see if this is a loopback command */ ++ if (OamConfig & 0xf000) ++ { ++ /* write the OAM correlation tag (GPR 1) */ ++ SAR_PDSP_OAM_CORR_REG(HalDev->dev_base) = CorrelationTag; ++ ++ /* write the LLID */ ++ tmp = pOAM_CONFIG_BLOCK_WORD_0(HalDev->dev_base); ++ ++ /* advance past the CPID */ ++ tmp += 4; ++ ++ *tmp++ = LLID[0]; ++ *tmp++ = LLID[1]; ++ *tmp++ = LLID[2]; ++ *tmp = LLID[3]; ++ ++ /* GPR 0 */ ++ SAR_PDSP_HOST_OAM_CONFIG_REG(HalDev->dev_base) = OamConfig; ++ } ++ } ++ ++/* ++ * This function allows the host software to access any register directly. ++ * Primarily used for debug. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param RegOffset Hexadecimal offset to desired register (from device base addr) ++ * ++ * @return Volatile pointer to desired register. ++ */ ++static volatile bit32u* halRegAccess(HAL_DEVICE *HalDev, bit32u RegOffset) ++ { ++ /* compute the register address */ ++ return ((volatile bit32u *)(HalDev->dev_base + RegOffset)); ++ } ++ ++#ifdef __CPHAL_DEBUG ++static void dbgConfigDump(HAL_DEVICE *HalDev) ++ { ++ dbgPrintf(" AAL5 Inst %d Config Dump:\n", HalDev->Inst); ++ dbgPrintf(" Base :%08x, offset:%08d\n", ++ HalDev->dev_base, HalDev->offset); ++ dbgPrintf(" Interrupt:%08d, debug :%08d\n", ++ HalDev->interrupt, HalDev->debug); ++ osfuncSioFlush(); ++ } ++#endif ++ ++/** ++ * @ingroup CPHAL_Functions ++ * Performs a variety of control functions on the CPHAL module. It is used to ++ * modify/read configuration parameters and to initiate internal functions. ++ * The @p Key indicates the function to perform or the parameter to access (note ++ * that these Keys are identical to those used in accessing the configuration data ++ * store). @p Action is applicable to parameters only, and indicates what the ++ * CPHAL should do with the parameter (i.e. "Set", "Get", etc..). The actions ++ * for each parameter are defined in the module specific documentation. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param Key Key specifying the parameter to change or internal function to initiate. See module specific documentation for available keys. ++ * @param Action Specifies the action to take. See module specific documentation for available actions. ++ * @param Value Pointer to new value for given @p Key parameter ("Set"), or returned value of Key ("Get"). ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_KEY_NOT_FOUND "EC_VAL_KEY_NOT_FOUND"
++ * @ref EC_VAL_ACTION_NOT_FOUND "EC_VAL_ACTION_NOT_FOUND"
++ */ ++static int halControl(HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value) ++ { ++ int Level, Ch, KeyFound=0, ActionFound=0, rc=EC_NO_ERRORS, Queue; ++ char *TmpKey = (char *)Key; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halControl(HalDev:%08x, Key:%s, Action:%s, Value:%08x)\n", (bit32u)HalDev, ++ Key, Action, (bit32u)Value); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify proper device state */ ++ if (HalDev->State < enInitialized) ++ return (EC_AAL5|EC_FUNC_CONTROL|EC_VAL_INVALID_STATE); ++ ++ if (HalDev->OsFunc->Strcmpi(Key, "Debug") == 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ HalDev->debug = *(int *)Value; ++ /* also setup debug variable in CPSAR module */ ++ rc = HalDev->SarFunc->Control(HalDev->SarDev, "Debug", "Set", Value); ++ } ++ } ++ ++ if (HalDev->OsFunc->Strstr(Key, "FwdUnkVc.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("FwdUnkVc."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ HalDev->ChData[Ch].FwdUnkVc = *(int *)Value; ++ ++ if ((HalDev->State == enOpened) && (HalDev->ChData[Ch].PktType == 3)) ++ rc = HalDev->SarFunc->Control(HalDev->SarDev, Key, Action, Value); ++ } ++ } ++ ++ /* +GSG 030407 */ ++ if (HalDev->OsFunc->Strcmpi(Key, "OamMode") == 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ rc = HalDev->SarFunc->Control(HalDev->SarDev, Key, Action, Value); ++ } ++ ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ rc = HalDev->SarFunc->Control(HalDev->SarDev, Key, Action, Value); ++ } ++ } ++ ++ /* +GSG 030307 */ ++ if (HalDev->OsFunc->Strcmpi(Key, "Version") == 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ *(const char **)Value = pszVersion_CPAAL5; ++ } ++ } ++ ++ /* +GSG 030529 */ ++ if (HalDev->OsFunc->Strcmpi(Key, "TurboDslErrors") == 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ *(int *)Value = HalDev->TurboDslErrors; ++ } ++ } ++ ++ /* +GSG 030416 */ ++ if (HalDev->OsFunc->Strcmpi(Key, "F4_LB_Counter") == 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ *(int *)Value = SAR_PDSP_OAM_F4_LB_COUNT_REG(HalDev->dev_base); ++ } ++ } ++ ++ /* +GSG 030416 */ ++ if (HalDev->OsFunc->Strcmpi(Key, "F5_LB_Counter") == 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ *(int *)Value = SAR_PDSP_OAM_F5_LB_COUNT_REG(HalDev->dev_base); ++ } ++ } ++ ++ if (HalDev->OsFunc->Strstr(Key, "Stats;") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ TmpKey += HalDev->OsFunc->Strlen("Stats;"); ++ Level = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ TmpKey++; ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ TmpKey++; ++ Queue = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ TmpKey++; ++ StatsGet(HalDev, (void **)Value, Level, Ch, Queue); ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #100 */ ++ if (HalDev->OsFunc->Strstr(Key, "Gfc.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("Gfc."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].Gfc = *(int *)Value; ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #100 */ ++ if (HalDev->OsFunc->Strstr(Key, "Clp.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("Clp."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].Clp = *(int *)Value; ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #100 */ ++ if (HalDev->OsFunc->Strstr(Key, "Pti.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("Pti."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].Pti = *(int *)Value; ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #100 */ ++ if (HalDev->OsFunc->Strstr(Key, "CpcsUU.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("CpcsUU."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].CpcsUU = *(int *)Value; ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #100 */ ++ if (HalDev->OsFunc->Strstr(Key, "TxVc_CellRate.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("TxVc_CellRate."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].TxVc_CellRate = *(int *)Value; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ *(pPDSP_AAL5_TX_STATE_WORD_0(HalDev->dev_base)+(Ch*64))= HalDev->ChData[Ch].TxVc_CellRate; ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #100 */ ++ if (HalDev->OsFunc->Strstr(Key, "TxVc_Mbs.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("TxVc_Mbs."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].TxVc_Mbs = *(int *)Value; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ *(pPDSP_AAL5_TX_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+2)= HalDev->ChData[Ch].TxVc_Mbs; ++ } ++ } ++ ++ if (HalDev->OsFunc->Strstr(Key, "TxVc_AtmHeader.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("TxVc_AtmHeader."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].TxVc_AtmHeader = *(int *)Value; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ *(pPDSP_AAL5_TX_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+6)= HalDev->ChData[Ch].TxVc_AtmHeader; ++ } ++ } ++ ++ if (HalDev->OsFunc->Strstr(Key, "TxVp_AtmHeader.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("TxVp_AtmHeader."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].TxVp_AtmHeader = *(int *)Value; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ *(pPDSP_AAL5_TX_VP_STATE_WORD_0(HalDev->dev_base)+(Ch*64))= HalDev->ChData[Ch].TxVp_AtmHeader; ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #100 */ ++ if (HalDev->OsFunc->Strstr(Key, "TxVc_Pcr.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("TxVc_Pcr."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].TxVc_Pcr = *(int *)Value; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ *(pPDSP_AAL5_TX_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+4)= HalDev->ChData[Ch].TxVc_Pcr; ++ } ++ } ++ ++ /* +GSG 030428 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVc_OamCh.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVc_OamCh."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].RxVc_OamCh = (*(int *)Value) & 0xff; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ *(pPDSP_AAL5_RX_STATE_WORD_0(HalDev->dev_base)+(Ch*64)) |= HalDev->ChData[Ch].RxVc_OamCh; ++ } ++ } ++ ++ /* +GSG 030428 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVp_OamCh.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVp_OamCh."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* first, store new value in our channel structure */ ++ HalDev->ChData[Ch].RxVp_OamCh = (*(int *)Value) & 0xff; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ *(pPDSP_AAL5_RX_VP_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+1) |= HalDev->ChData[Ch].RxVp_OamCh; ++ } ++ } ++ ++ /* +GSG 030304 */ ++ /* Fixes PITS #98 */ ++ if (HalDev->OsFunc->Strstr(Key, "PdspEnable") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ /* this variable is controlled by the CPSAR module */ ++ if (HalDev->State == enOpened) ++ { ++ rc=HalDev->SarFunc->Control(HalDev->SarDev, "PdspEnable", "Set", Value); ++ } ++ } ++ } ++ ++ if (HalDev->OsFunc->Strstr(Key, "OamLbTimeout") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ HalDev->OamLbTimeout = *(int *)Value; ++ /* this variable is controlled by the CPSAR module */ ++ if (HalDev->State == enOpened) ++ { ++ *(pOAM_TIMER_STATE_WORD_0(HalDev->dev_base) + 1) = ++ ((HalDev->SarFrequency/1000) * HalDev->OamLbTimeout); ++ } ++ } ++ } ++ ++ /* +GSG 030306 (PITS #114) */ ++ if (HalDev->OsFunc->Strstr(Key, "DeviceCPID") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ unsigned int* local = (unsigned int *)Value; ++ ActionFound=1; ++ /* first, store new value in our hal structure */ ++ HalDev->DeviceCPID[0] = local[0]; ++ HalDev->DeviceCPID[1] = local[1]; ++ HalDev->DeviceCPID[2] = local[2]; ++ HalDev->DeviceCPID[3] = local[3]; ++ ++ /* now, apply to PDSP state RAM */ ++ if (HalDev->State == enOpened) ++ { ++ *(bit32u *)(pOAM_CONFIG_BLOCK_WORD_0(HalDev->dev_base) + 0) = HalDev->DeviceCPID[0]; ++ *(bit32u *)(pOAM_CONFIG_BLOCK_WORD_0(HalDev->dev_base) + 1) = HalDev->DeviceCPID[1]; ++ *(bit32u *)(pOAM_CONFIG_BLOCK_WORD_0(HalDev->dev_base) + 2) = HalDev->DeviceCPID[2]; ++ *(bit32u *)(pOAM_CONFIG_BLOCK_WORD_0(HalDev->dev_base) + 3) = HalDev->DeviceCPID[3]; ++ } ++ } ++ } ++ ++ /* +GSG 030304 */ ++ /* Fixes PITS #99 */ ++ if (HalDev->OsFunc->Strstr(Key, "StrictPriority") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ /* used in halOpen to decide which interrupt handler to use */ ++ HalDev->StrictPriority = *(int *)Value; ++ } ++ } ++ ++ if (HalDev->OsFunc->Strstr(Key, hcMaxFrags) != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ if ((*(int *)Value) > 0) ++ HalDev->MaxFrags = *(int *)Value; ++ else ++ rc = (EC_AAL5|EC_FUNC_CONTROL|EC_VAL_INVALID_VALUE); ++ } ++ ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ ++ *(int *)Value = HalDev->MaxFrags; ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #103 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVc_RDICount.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVc_RDICount."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* PDSP's Rx VC State word 3 contains the value */ ++ if (HalDev->State == enOpened) ++ { ++ *(int *)Value = (((*(pPDSP_AAL5_RX_STATE_WORD_0(HalDev->dev_base)+(Ch*64))) & RDI_CNT_MASK)>>RDI_CNT_SHIFT); ++ } ++ } ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVc_RDICount."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* All sets write 0, this action is a clear only */ ++ if (HalDev->State == enOpened) ++ { ++ (*(pPDSP_AAL5_RX_STATE_WORD_0(HalDev->dev_base)+(Ch*64))) &=~ RDI_CNT_MASK; ++ } ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #103 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVc_AISseg.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVc_AISseg."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* PDSP's Rx VC State word 3 contains the value */ ++ if (HalDev->State == enOpened) ++ { ++ *(int *)Value = (((*(pPDSP_AAL5_RX_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+3)) & AIS_SEG_MASK)>>AIS_SEG_SHIFT); ++ } ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #103 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVc_AISetoe.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVc_AISetoe."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* PDSP's Rx VC State word 3 contains the value */ ++ if (HalDev->State == enOpened) ++ { ++ *(int *)Value = (((*(pPDSP_AAL5_RX_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+3)) & AIS_ETOE_MASK)>>AIS_ETOE_SHIFT); ++ } ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #103 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVp_RDICount.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVp_RDICount."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* PDSP's Rx VC State word 3 contains the value */ ++ if (HalDev->State == enOpened) ++ { ++ *(int *)Value = (((*(pPDSP_AAL5_RX_VP_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+1)) & RDI_CNT_MASK)>>RDI_CNT_SHIFT); ++ } ++ } ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVp_RDICount."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* All sets write 0, this action is a clear only */ ++ if (HalDev->State == enOpened) ++ { ++ (*(pPDSP_AAL5_RX_VP_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+1)) &=~ RDI_CNT_MASK; ++ } ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #103 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVp_AISseg.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVp_AISseg."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* PDSP's Rx VC State word 3 contains the value */ ++ if (HalDev->State == enOpened) ++ { ++ *(int *)Value = (((*(pPDSP_AAL5_RX_VP_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+2)) & AIS_SEG_MASK)>>AIS_SEG_SHIFT); ++ } ++ } ++ } ++ ++ /* +GSG 030306 */ ++ /* Fixes PITS #103 */ ++ if (HalDev->OsFunc->Strstr(Key, "RxVp_AISetoe.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("RxVp_AISetoe."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* PDSP's Rx VC State word 3 contains the value */ ++ if (HalDev->State == enOpened) ++ { ++ *(int *)Value = (((*(pPDSP_AAL5_RX_VP_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+2)) & AIS_ETOE_MASK)>>AIS_ETOE_SHIFT); ++ } ++ } ++ } ++ ++ if (KeyFound == 0) ++ rc = (EC_AAL5|EC_FUNC_CONTROL|EC_VAL_KEY_NOT_FOUND); ++ ++ if (ActionFound == 0) ++ rc = (EC_AAL5|EC_FUNC_CONTROL|EC_VAL_ACTION_NOT_FOUND); ++ ++ return(rc); ++ } ++ ++/* ++ * Sets up HAL default configuration parameter values. ++ */ ++static void ConfigInit(HAL_DEVICE *HalDev) ++ { ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]ConfigInit(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* configure some defaults with tnetx7300 values */ ++ HalDev->dev_base = 0xa3000000; ++ HalDev->offset = 0; ++ HalDev->interrupt = 15; ++ HalDev->debug = 0; ++ HalDev->MaxFrags = 46; ++ HalDev->OamLbTimeout = 5000; ++ } ++ ++/* ++ * Retrieve HAL configuration parameter values. ++ */ ++static bit32u ConfigGet(HAL_DEVICE *HalDev) ++ { ++ bit32u Ret; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]ConfigGet(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* get the configuration parameters common to all modules */ ++ Ret = ConfigGetCommon(HalDev); ++ if (Ret) return (EC_AAL5|Ret); ++ ++ /* get AAL5 specific configuration parameters here */ ++ Ret = HalDev->OsFunc->Control(HalDev->OsDev, hcSarFrequency, pszGET, &HalDev->SarFrequency); /* GSG +030416*/ ++ if (Ret) /* GSG +030416*/ ++ HalDev->SarFrequency = 200000000; /* 200 Mhz default */ /* GSG +030416*/ ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function initializes the CPHAL module. It gathers all ++ * necessary global configuration info from the configuration file, and ++ * performs initialization and configuration of the device. Note that ++ * the device operation is not started until the OS calls @c Open(). ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_BASE_ADDR_NOT_FOUND "EC_VAL_BASE_ADDR_NOT_FOUND"
++ * @ref EC_VAL_RESET_BIT_NOT_FOUND "EC_VAL_RESET_BIT_NOT_FOUND"
++ * @ref EC_VAL_INTERRUPT_NOT_FOUND "EC_VAL_INTERRUPT_NOT_FOUND"
++ * @ref EC_VAL_OFFSET_NOT_FOUND "EC_VAL_OFFSET_NOT_FOUND"
++ */ ++static int halInit(HAL_DEVICE *HalDev) ++ { ++ int i; ++ bit32u error_code; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halInit(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify proper device state */ ++ if (HalDev->State != enDevFound) ++ return(EC_AAL5|EC_FUNC_HAL_INIT|EC_VAL_INVALID_STATE); ++ ++ /* Configure HAL defaults */ ++ ConfigInit(HalDev); ++ ++ /* Retrieve HAL configuration parameters from data store */ ++ error_code = ConfigGet(HalDev); ++ if (error_code) return (error_code); ++ ++ /* Other items (OAM related) that need to be passed in somehow */ ++ HalDev->DeviceCPID[0] = 0xffffffff; ++ HalDev->DeviceCPID[1] = 0xffffffff; ++ HalDev->DeviceCPID[2] = 0xffffffff; ++ HalDev->DeviceCPID[3] = 0xffffffff; ++ HalDev->LBSourceLLID[0] = 0xffffffff; ++ HalDev->LBSourceLLID[1] = 0xffffffff; ++ HalDev->LBSourceLLID[2] = 0xffffffff; ++ HalDev->LBSourceLLID[3] = 0xffffffff; ++ ++ /* Initialize SAR layer*/ ++ error_code = HalDev->SarFunc->Init(HalDev->SarDev); ++ if (error_code) return (error_code); ++ ++ /* Initialize various HalDev members. This is probably overkill, since these ++ are initialized in ChannelSetup() and HalDev is cleared in InitModule(). */ ++ for (i=0; iInRxInt[i]=FALSE; ++ HalDev->ChIsOpen[i][DIRECTION_TX] = FALSE; ++ HalDev->ChIsOpen[i][DIRECTION_RX] = FALSE; ++ HalDev->TcbStart[i][0] = 0; ++ HalDev->TcbStart[i][1] = 0; ++ HalDev->RcbStart[i] = 0; ++ } ++ ++ /* initialize SAR stats */ ++ StatsClear(HalDev); ++ ++ /* init Stat pointers */ ++ ++ /* even though these statistics may be for multiple channels/queues, i need ++ only configure the pointer to the beginning of the array, and I can index ++ from there if necessary */ ++ StatsTable0[0].StatPtr = &HalDev->Stats.CrcErrors[0]; ++ StatsTable0[1].StatPtr = &HalDev->Stats.LenErrors[0]; ++ StatsTable0[2].StatPtr = &HalDev->Stats.AbortErrors[0]; ++ StatsTable0[3].StatPtr = &HalDev->Stats.StarvErrors[0]; ++ ++ StatsTable1[0].StatPtr = &HalDev->Stats.DmaLenErrors[0]; ++ StatsTable1[1].StatPtr = &HalDev->Stats.TxMisQCnt[0][0]; ++ StatsTable1[2].StatPtr = &HalDev->Stats.RxMisQCnt[0]; ++ StatsTable1[3].StatPtr = &HalDev->Stats.TxEOQCnt[0][0]; ++ StatsTable1[4].StatPtr = &HalDev->Stats.RxEOQCnt[0]; ++ StatsTable1[5].StatPtr = &HalDev->Stats.RxPacketsServiced[0]; ++ StatsTable1[6].StatPtr = &HalDev->Stats.TxPacketsServiced[0][0]; ++ StatsTable1[7].StatPtr = &HalDev->Stats.RxMaxServiced; ++ StatsTable1[8].StatPtr = &HalDev->Stats.TxMaxServiced[0][0]; ++ StatsTable1[9].StatPtr = &HalDev->Stats.RxTotal; ++ StatsTable1[10].StatPtr = &HalDev->Stats.TxTotal; ++ ++ StatsTable2[0].StatPtr = (bit32u *)&HalDev->RcbPool[0]; ++ StatsTable2[1].StatPtr = &HalDev->RxActQueueCount[0]; ++ StatsTable2[2].StatPtr = (bit32u *)&HalDev->RxActQueueHead[0]; ++ StatsTable2[3].StatPtr = (bit32u *)&HalDev->RxActQueueTail[0]; ++ StatsTable2[4].StatPtr = &HalDev->RxActive[0]; ++ StatsTable2[5].StatPtr = (bit32u *)&HalDev->RcbStart[0]; ++ StatsTable2[6].StatPtr = &HalDev->RxTeardownPending[0]; ++ StatsTable2[7].StatPtr = (bit32u *)&HalDev->TcbPool[0][0]; ++ StatsTable2[8].StatPtr = &HalDev->TxActQueueCount[0][0]; ++ StatsTable2[9].StatPtr = (bit32u *)&HalDev->TxActQueueHead[0][0]; ++ StatsTable2[10].StatPtr = (bit32u *)&HalDev->TxActQueueTail[0][0]; ++ StatsTable2[11].StatPtr = &HalDev->TxActive[0][0]; ++ StatsTable2[12].StatPtr = (bit32u *)&HalDev->TcbStart[0][0]; ++ StatsTable2[13].StatPtr = &HalDev->TxTeardownPending[0]; ++ ++ StatsTable4[0].StatPtr = &HalDev->dev_base; ++ StatsTable4[1].StatPtr = &HalDev->offset; ++ StatsTable4[2].StatPtr = &HalDev->interrupt; ++ StatsTable4[3].StatPtr = &HalDev->debug; ++ StatsTable4[4].StatPtr = &HalDev->Inst; ++ ++ StatsTable3[0].StatPtr = &HalDev->ChData[0].RxBufSize; ++ StatsTable3[1].StatPtr = &HalDev->ChData[0].RxBufferOffset; ++ StatsTable3[2].StatPtr = &HalDev->ChData[0].RxNumBuffers; ++ StatsTable3[3].StatPtr = &HalDev->ChData[0].RxServiceMax; ++ StatsTable3[4].StatPtr = &HalDev->ChData[0].TxNumBuffers; ++ StatsTable3[5].StatPtr = &HalDev->ChData[0].TxNumQueues; ++ StatsTable3[6].StatPtr = &HalDev->ChData[0].TxServiceMax; ++ StatsTable3[7].StatPtr = &HalDev->ChData[0].CpcsUU; ++ StatsTable3[8].StatPtr = &HalDev->ChData[0].Gfc; ++ StatsTable3[9].StatPtr = &HalDev->ChData[0].Clp; ++ StatsTable3[10].StatPtr = &HalDev->ChData[0].Pti; ++ StatsTable3[11].StatPtr = &HalDev->ChData[0].DaMask; ++ StatsTable3[12].StatPtr = &HalDev->ChData[0].Priority; ++ StatsTable3[13].StatPtr = &HalDev->ChData[0].PktType; ++ StatsTable3[14].StatPtr = &HalDev->ChData[0].Vci; ++ StatsTable3[15].StatPtr = &HalDev->ChData[0].Vpi; ++ StatsTable3[16].StatPtr = &HalDev->ChData[0].TxVc_CellRate; ++ StatsTable3[17].StatPtr = &HalDev->ChData[0].TxVc_QosType; ++ StatsTable3[18].StatPtr = &HalDev->ChData[0].TxVc_Mbs; ++ StatsTable3[19].StatPtr = &HalDev->ChData[0].TxVc_Pcr; ++ ++ /* update device state */ ++ HalDev->State = enInitialized; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(9)) ++ dbgConfigDump(HalDev); ++#endif ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/* ++ * Use this function to actually send after queuing multiple packets using ++ * Send(). This is a debug only function that should be removed - it was ++ * necessary to properly implement my loopback tests. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param Queue Queue number to kick. ++ * ++ * @return 0 OK, Non-Zero Not OK ++ */ ++static int halKick(HAL_DEVICE *HalDev, int Queue) ++ { ++ int Ch; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halKick(HalDev:%08x. Queue:%d)\n", (bit32u)HalDev, Queue); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ for (Ch = 0; Ch < 16; Ch ++) ++ { ++ if ((!HalDev->TxActive[Ch][Queue]) && (HalDev->TxActQueueHead[Ch][Queue] != 0)) ++ { ++ *(pTX_DMA_STATE_WORD_0(HalDev->dev_base)+(Ch*64)+Queue)= ++ VirtToPhys(HalDev->TxActQueueHead[Ch][Queue]); ++ HalDev->TxActive[Ch][Queue]=TRUE; ++ } ++ } ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/* +GSG 030305 For PITS #99 ++ * Alternate interrupt handler that uses the INT_VECTOR in order to ++ * provide strict priority handling among channels, beginning with Ch 0. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param MoreWork (Output) When set to 1, indicates that there is more work to do. ++ * Caller should ensure that the value pointed at is set to 0 ++ * prior to the call. ++ * @return 0 OK, non-zero error. ++ */ ++static int DeviceIntAlt(HAL_DEVICE *HalDev, int *MoreWork) ++ { ++ int tmp, Ch, WorkFlag; ++ bit32u rc; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]DeviceIntAlt(HalDev:%08x, MoreWork:%08x)\n", (bit32u)HalDev, (bit32u)MoreWork); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify proper device state - important because a call prior to Open would ++ result in a lockup */ ++ if (HalDev->State != enOpened) ++ return(EC_AAL5|EC_FUNC_DEVICE_INT_ALT|EC_VAL_INVALID_STATE); ++ ++ if ((tmp=SAR_INTR_VECTOR(HalDev->dev_base))&INT_PENDING) ++ { ++ /*printf("\015 %d RxQ",HalDev->RxActQueueCount[0]); ++ HalDev->OsFunc->Control(HalDev->OsDev, enSIO_FLUSH, enNULL, 0); */ ++ ++ if (tmp&TXH_PEND) ++ { ++ /* decide which channel to service */ ++ Ch = (SAR_INTR_VECTOR(HalDev->dev_base) & TXH_PEND_INVEC); ++ ++ rc = TxInt(HalDev,Ch,0,&WorkFlag); ++ if (rc) return (rc); ++ ++ if (WorkFlag == 1) ++ *MoreWork = 1; ++ } ++ ++ if (tmp&TXL_PEND) ++ { ++ /* decide which channel to service */ ++ Ch = ((SAR_INTR_VECTOR(HalDev->dev_base) & TXL_PEND_INVEC) >> 4); ++ ++ rc = TxInt(HalDev,Ch,1,&WorkFlag); ++ if (rc) return (rc); ++ ++ if (WorkFlag == 1) ++ *MoreWork = 1; ++ } ++ ++ if (tmp&RX_PEND) ++ { ++ /* decide which channel to service */ ++ Ch = ((SAR_INTR_VECTOR(HalDev->dev_base) & RX_PEND_INVEC) >> 8); ++ ++ rc = RxInt(HalDev,Ch,&WorkFlag); ++ if (rc) return (rc); ++ ++ if (WorkFlag == 1) ++ *MoreWork = 1; ++ } ++ ++ if (tmp&STS_PEND) ++ { ++ /* GPR 2 code added for PITS 103 */ ++ /* determine interrupt source */ ++ Ch = ((SAR_INTR_VECTOR(HalDev->dev_base) & STS_PEND_INVEC) >> 12); ++ ++ /* only if this is GPR 2 interrupt do we take action */ ++ if (Ch == 26) ++ { ++ /* pass loopback result back to OS */ ++ HalDev->OsFunc->Control(HalDev->OsDev, "OamLbResult", "Set", ++ (bit32u *)pSAR_PDSP_OAM_LB_RESULT_REG(HalDev->dev_base)); ++ } ++ ++ /* clear the interrupt */ ++ SAR_STATUS_CLR_REG(HalDev->dev_base) |= 0x04000000; ++ } ++ ++ if (tmp&AAL2_PEND) ++ { ++ /* no action defined */ ++ } ++ ++ SAR_INTR_VECTOR(HalDev->dev_base) = 0; ++ } ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/* ++ * Called to service a module interrupt. This function determines ++ * what type of interrupt occurred and dispatches the correct handler. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param MoreWork (Output) When set to 1, indicates that there is more work to do. ++ * Caller should ensure that the value pointed at is set to 0 ++ * prior to the call. ++ * @return 0 OK, non-zero error. ++ */ ++static int DeviceInt(HAL_DEVICE *HalDev, int *MoreWork) ++ { ++ /*static int NextRxCh=0; ++ static int NextTxCh[2]={0,0};*/ ++ ++ int tmp, Ch, FirstCh, WorkFlag; ++ int NextTxLCh, NextTxHCh, NextRxCh; ++ bit32u rc; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]DeviceInt(HalDev:%08x, MoreWork:%08x)\n", (bit32u)HalDev, (bit32u)MoreWork); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify proper device state - important because a call prior to Open would ++ result in a lockup */ ++ if (HalDev->State != enOpened) ++ return(EC_AAL5|EC_FUNC_DEVICE_INT|EC_VAL_INVALID_STATE); ++ ++ NextTxHCh = HalDev->NextTxCh[0]; ++ NextTxLCh = HalDev->NextTxCh[1]; ++ NextRxCh = HalDev->NextRxCh; ++ ++ /* service interrupts while there is more work to do */ ++ /*while (((tmp=SAR_INTR_VECTOR(HalDev->dev_base))&INT_PENDING) && (TotalPkts < 500))*/ ++ if ((tmp=SAR_INTR_VECTOR(HalDev->dev_base))&INT_PENDING) ++ { ++ /*printf("\015 %d RxQ",HalDev->RxActQueueCount[0]); ++ HalDev->OsFunc->Control(HalDev->OsDev, enSIO_FLUSH, enNULL, 0); */ ++ ++ if (tmp&TXH_PEND) ++ { ++ /* decide which channel to service */ ++ FirstCh = NextTxHCh; ++ while (1) ++ { ++ Ch = NextTxHCh++; ++ if (NextTxHCh == 16) ++ NextTxHCh = 0; ++ if (SAR_TX_MASKED_STATUS(HalDev->dev_base) & (1<dev_base) & (1<<(Ch+16))) ++ break; ++ if (FirstCh == NextTxLCh) ++ { ++ /* we checked every channel and still haven't found anything to do */ ++ return (EC_AAL5|EC_FUNC_DEVICE_INT|EC_VAL_NO_TXL_WORK_TO_DO); ++ } ++ } ++ ++ rc = TxInt(HalDev,Ch,1,&WorkFlag); ++ if (rc) return (rc); ++ ++ if (WorkFlag == 1) ++ *MoreWork = 1; ++ } ++ ++ if (tmp&RX_PEND) ++ { ++ FirstCh = NextRxCh; ++ while (1) ++ { ++ Ch = NextRxCh++; ++ if (NextRxCh == 16) ++ NextRxCh = 0; ++ if (SAR_RX_MASKED_STATUS(HalDev->dev_base) & (1 << Ch)) ++ break; /* found a channel to service */ ++ if (FirstCh == NextRxCh) ++ { ++ /* we checked every channel and still haven't found anything to do */ ++ return (EC_AAL5|EC_FUNC_DEVICE_INT|EC_VAL_NO_RX_WORK_TO_DO); ++ } ++ } ++ ++ rc = RxInt(HalDev,Ch, &WorkFlag); ++ if (rc) return (rc); ++ ++ if (WorkFlag == 1) ++ *MoreWork = 1; ++ } ++ ++ if (tmp&STS_PEND) ++ { ++ /* +GSG 030305 */ ++ /* GPR 2 code added for PITS 103 */ ++ /* determine interrupt source */ ++ Ch = ((SAR_INTR_VECTOR(HalDev->dev_base) & STS_PEND_INVEC) >> 12); ++ ++ /* only if this is GPR 2 interrupt do we take action */ ++ if (Ch == 26) ++ { ++ /* pass loopback result back to OS */ ++ HalDev->OsFunc->Control(HalDev->OsDev, "OamLbResult", "Set", ++ (bit32u *)pSAR_PDSP_OAM_LB_RESULT_REG(HalDev->dev_base)); ++ } ++ ++ /* clear the interrupt */ ++ SAR_STATUS_CLR_REG(HalDev->dev_base) |= 0x04000000; ++ } ++ ++ if (tmp&AAL2_PEND) ++ { ++ /* no action defined */ ++ } ++ ++ SAR_INTR_VECTOR(HalDev->dev_base) = 0; ++ } ++ ++ HalDev->NextTxCh[0] = NextTxHCh; ++ HalDev->NextTxCh[1] = NextTxLCh; ++ HalDev->NextRxCh = NextRxCh; ++ ++ /* This must be done by the upper layer */ ++ /* SAR_EOI(HalDev->dev_base) = 0; */ ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function starts the operation of the CPHAL device. It takes the device ++ * out of reset, and calls @c IsrRegister(). This function should be called after ++ * calling the @c Init() function. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_KEY_NOT_FOUND "EC_VAL_KEY_NOT_FOUND"
++ * @ref EC_VAL_FIRMWARE_TOO_LARGE "EC_VAL_FIRMWARE_TOO_LARGE"
++ * @ref EC_VAL_PDSP_LOAD_FAIL "EC_VAL_PDSP_LOAD_FAIL"
++ * @ref EC_VAL_RX_STATE_RAM_NOT_CLEARED "EC_VAL_RX_STATE_RAM_NOT_CLEARED"
++ * @ref EC_VAL_TX_STATE_RAM_NOT_CLEARED "EC_VAL_TX_STATE_RAM_NOT_CLEARED"
++ * @ref EC_VAL_TCB_MALLOC_FAILED "EC_VAL_TCB_MALLOC_FAILED"
++ * @ref EC_VAL_RCB_MALLOC_FAILED "EC_VAL_RCB_MALLOC_FAILED"
++ * @ref EC_VAL_RX_BUFFER_MALLOC_FAILED "EC_VAL_RX_BUFFER_MALLOC_FAILED"
++ * @ref EC_VAL_LUT_NOT_READY "EC_VAL_LUT_NOT_READY"
++ */ ++static int halOpen(HAL_DEVICE *HalDev) ++ { ++ int i,Ret; ++ bit32 SarBase = HalDev->dev_base; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halOpen(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify proper device state */ ++ if (HalDev->State < enInitialized) ++ return (EC_AAL5|EC_FUNC_OPEN|EC_VAL_INVALID_STATE); ++ ++ /* Open the SAR (this brings the whole device out of reset */ ++ Ret = HalDev->SarFunc->Open(HalDev->SarDev); /* ~GSG 030410 */ ++ if (Ret) /* +GSG 030410 */ ++ return (Ret); /* +GSG 030410 */ ++ ++ /* Change device state */ ++ HalDev->State = enOpened; ++ ++ ++#ifdef __CPHAL_DEBUG ++ /* print out the version information */ ++ if (DBG(7)) ++ { ++ dbgPrintf("[aal5 halOpen()]Module ID(AAL5-CPSAR):%d, Version:%2d.%02d\n", ++ (SAR_ID_REG(SarBase)&0xffff0000)>>16, ++ (SAR_ID_REG(SarBase)&0xff00)>>8, ++ SAR_ID_REG(SarBase)&0xff); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* GREG 11/1/02: The State RAM clearing code was previously in cpsar.c, ++ directly after device reset. I moved it here because I believe it is ++ AAL5 specific code. Also the MAX_CHAN was set to 19 in cpsar.c, which ++ would have caused this code to clear too much memory! */ ++ ++ /* NOTE: State RAM must be cleared prior to initializing the PDSP!! */ ++ ++ /* GSG 030416: Removed all of this. All PDSP State RAM is cleared ++ in CPSAR Open(). On Close(), all channels are torndown, thus all ++ AAL5 channel state RAM is cleared. */ ++ ++ /* Clear Rx State RAM */ ++ /*for (i=0; ifraglist = HalDev->OsFunc->Malloc(HalDev->MaxFrags * sizeof(FRAGLIST)); ++ ++ /* For any channels that have been pre-initialized, set them up now */ ++ for (i=0; iChIsSetup[i][0]==TRUE) && (HalDev->ChIsOpen[i][0]==FALSE)) ++ { ++ CHANNEL_INFO HalChn; ++ HalChn.Channel = i; ++ Ret = ChannelConfigApply(HalDev, &HalChn); ++ if (Ret) return (Ret); ++ } ++ } ++ ++ /* OAM code would be a candidate to go into ConfigApply */ ++ ++ /* Configure OAM Timer State Block */ ++ OamRateConfig(HalDev); /* +GSG 030416 */ ++ ++ /* Setup OAM Configuration Block */ ++ for (i=0; i<8; i++) /* ~GSG 030603 4->8 */ ++ { ++ if (i < 4) ++ *(pOAM_CONFIG_BLOCK_WORD_0(SarBase) + i) = HalDev->DeviceCPID[i]; ++ else ++ *(pOAM_CONFIG_BLOCK_WORD_0(SarBase) + i) = HalDev->LBSourceLLID[i-4]; ++ } ++ ++ /* Setup OAM Padding Block */ ++ for (i=0; i<12; i++) ++ { ++ *(pOAM_PADDING_BLOCK_WORD_0(SarBase) + i) = ((i==11)?0x6a6a0000:0x6a6a6a6a); ++ } ++ ++ /* Enable Tx CPPI DMA */ ++ TX_CPPI_CTL_REG(HalDev->dev_base) = 1; ++ ++ /* Enable Rx CPPI DMA */ ++ RX_CPPI_CTL_REG(HalDev->dev_base) = 1; ++ ++ /* +GSG 030306 */ ++ /* Fix for PITS 103 */ ++ /* Enable Host Interrupt for GPR 2 (OAM LB result register) */ ++ SAR_HOST_INT_EN_SET_REG(HalDev->dev_base) |= 0x04000000; ++ ++ /* +GSG 030304 to fix PITS 99 (if block is new)*/ ++ if (HalDev->StrictPriority == 1) ++ { ++#ifdef __CPHAL_DEBUG ++ if (DBG(1)) ++ { ++ dbgPrintf("[aal5->os]IsrRegister(OsDev:%08x, halIsr:%08x, Interrupt:%d)\n", ++ (bit32u)HalDev->OsDev, (bit32u)DeviceIntAlt, HalDev->interrupt); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* "register" the interrupt handler */ ++ HalDev->OsFunc->IsrRegister(HalDev->OsDev, DeviceIntAlt, HalDev->interrupt); ++ } ++ else /* +GSG 030306 */ ++ { /* +GSG 030306 */ ++#ifdef __CPHAL_DEBUG ++ if (DBG(1)) ++ { ++ dbgPrintf("[aal5->os]IsrRegister(OsDev:%08x, halIsr:%08x, Interrupt:%d)\n", ++ (bit32u)HalDev->OsDev, (bit32u)DeviceInt, HalDev->interrupt); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* "register" the interrupt handler */ ++ HalDev->OsFunc->IsrRegister(HalDev->OsDev, DeviceInt, HalDev->interrupt); ++ } /* +GSG 030306 */ ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * Called to retrigger the interrupt mechanism after packets have been ++ * processed. Call this function when the HalISR function indicates that ++ * there is no more work to do. Proper use of this function will guarantee ++ * that interrupts are never missed. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return EC_NO_ERRORS (ok).
++ */ ++static int halPacketProcessEnd(HAL_DEVICE *HalDev) ++ { ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halPacketProcessEnd(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ SAR_EOI(HalDev->dev_base) = 0; ++ return (EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function probes for the instance of the CPHAL module. It will call ++ * the OS function @c DeviceFindInfo() to get the information required. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_DEVICE_NOT_FOUND "EC_VAL_DEVICE_NOT_FOUND"
++ */ ++static int halProbe(HAL_DEVICE *HalDev) ++ { ++ int Ret; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halProbe(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify hardware state is "enConnected */ ++ if (HalDev->State != enConnected) ++ return (EC_AAL5|EC_FUNC_PROBE|EC_VAL_INVALID_STATE); ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(1)) ++ { ++ dbgPrintf("[aal5->os]DeviceFindInfo(Inst:%d, DeviceName:%s, DeviceInfo:%08x)\n", ++ HalDev->Inst, "aal5", (bit32u)&HalDev->DeviceInfo); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Attempt to find the device information */ ++ Ret = HalDev->OsFunc->DeviceFindInfo(HalDev->Inst, "aal5", &HalDev->DeviceInfo); ++ if (Ret) ++ return(EC_AAL5|EC_FUNC_PROBE|EC_VAL_DEVICE_NOT_FOUND); ++ ++ /* Call Probe for supporting CPSAR layer */ ++ Ret = HalDev->SarFunc->Probe(HalDev->SarDev); ++ if (Ret) ++ return(Ret); ++ ++ /* Set device state to DevFound */ ++ HalDev->State = enDevFound; ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function shuts down the CPHAL module completely. The caller must call ++ * Close() to put the device in reset prior shutting down. This call will free ++ * the HalDev and the HAL function pointer structure, effectively ending ++ * communications between the driver and the CPHAL. Further use of the module ++ * must be initiated by a call to xxxInitModule(), which starts the entire process ++ * over again. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * Any error code from halClose().
++ */ ++static int halShutdown(HAL_DEVICE *HalDev) ++ { ++ int Ch, Queue; /*GSG+030514*/ ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halShutdown(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Verify proper device state */ ++ if (HalDev->State == enOpened) ++ halClose(HalDev, 3); /*GSG+030429*/ ++ ++ /* Buffer/descriptor resources may still need to be freed if a Close ++ Mode 1 was performed prior to Shutdown - clean up here */ /*GSG+030514*/ ++ for (Ch=0; ChRcbStart[Ch] != 0) ++ FreeRx(HalDev,Ch); ++ ++ for(Queue=0; QueueTcbStart[Ch][Queue] != 0) ++ FreeTx(HalDev,Ch,Queue); ++ } ++ } ++ ++ /* shutdown the CPSAR layer */ ++ HalDev->SarFunc->Shutdown(HalDev->SarDev); ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(6)) ++ { ++ dbgPrintf(" [aal5 halShutdown()]Free AAL5 function pointers\n"); ++ osfuncSioFlush(); ++ } ++ if (DBG(1)||DBG(3)) ++ { ++ dbgPrintf("[aal5->os]Free(MemPtr:%08x)\n", (bit32u)HalDev->HalFuncPtr); ++ osfuncSioFlush(); ++ } ++#endif ++ /* free the HalFunc */ ++ HalDev->OsFunc->Free(HalDev->HalFuncPtr); ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(6)) ++ { ++ dbgPrintf(" [aal5 halShutdown]Free HalDev\n"); ++ osfuncSioFlush(); ++ } ++ if (DBG(1)||DBG(3)) ++ { ++ dbgPrintf("[aal5->os]Free(MemPtr:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ /* free the HAL device */ ++ HalDev->OsFunc->FreeDev(HalDev); ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * Used to perform regular checks on the device. This function should be ++ * called at a regular interval specified by the @c Tick parameter. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ */ ++static int halTick(HAL_DEVICE *HalDev) ++ { ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[aal5]halTick(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ if (HalDev->State != enOpened) ++ return(EC_AAL5|EC_FUNC_TICK|EC_VAL_INVALID_STATE); ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * ++ * This function will: ++ * -# allocate a HalDev that will be used by the OS for future communications with the device ++ * -# save OsDev for use when calling OS functions ++ * -# allocate and populate HalFunc with the addresses of CPHAL functions. ++ * -# check OsFuncSize to see if it meets the minimum requirement. ++ * -# return the size of the HAL_FUNCTIONS structure through the HalFuncSize pointer. The OS ++ * should check this value to ensure that the HAL meets its minimum requirement. ++ * ++ * Version checking between the OS and the CPHAL is done using the OsFuncSize and ++ * HalFuncSize. Future versions of the CPHAL may add new functions to either ++ * HAL_FUNCTIONS or OS_FUNCTIONS, but will never remove functionality. This enables ++ * both the HAL and OS to check the size of the function structure to ensure that ++ * the current OS and CPHAL are compatible. ++ * ++ * Note: This is the only function exported by a CPHAL module. ++ * ++ * Please refer to the section "@ref hal_init" for example code. ++ * ++ * @param HalDev Pointer to pointer to CPHAL module information. This will ++ * be used by the OS when communicating to this module via ++ * CPHAL. Allocated during the call. ++ * @param OsDev Pointer to OS device information. This will be saved by ++ * the CPHAL and returned to the OS when required. ++ * @param HalFunc Pointer to pointer to structure containing function pointers for all CPHAL ++ * interfaces. Allocated during the call. ++ * @param OsFunc Pointer to structure containing function pointers for all OS ++ * provided interfaces. Must be allocated by OS prior to call. ++ * @param OsFuncSize Size of OS_FUNCTIONS structure. ++ * @param HalFuncSize Pointer to the size of the HAL_FUNCTIONS structure. ++ * @param Inst The instance number of the module to initialize. (start at ++ * 0). ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_OS_VERSION_NOT_SUPPORTED "EC_VAL_OS_VERSION_NOT_SUPPORTED"
++ * @ref EC_VAL_MALLOC_DEV_FAILED "EC_VAL_MALLOC_DEV_FAILED"
++ * @ref EC_VAL_MALLOC_FAILED "EC_VAL_MALLOC_FAILED"
++ */ ++int xxxInitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++ ++int cpaal5InitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst) ++ { ++ int rc, SarFuncSize; ++ HAL_DEVICE *HalPtr; ++ HAL_FUNCTIONS *HalFuncPtr; ++ ++ /* NEW CODE */ ++ if (OsFuncSize < sizeof(OS_FUNCTIONS)) ++ return (EC_AAL5|EC_FUNC_HAL_INIT|EC_VAL_OS_VERSION_NOT_SUPPORTED); ++ ++ HalPtr = (HAL_DEVICE *) OsFunc->MallocDev(sizeof(HAL_DEVICE)); ++ if (!HalPtr) ++ return (EC_AAL5|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_DEV_FAILED); ++ ++ HalFuncPtr = (HAL_FUNCTIONS *) OsFunc->Malloc(sizeof(HAL_FUNCTIONS)); ++ if (!HalFuncPtr) ++ return (EC_AAL5|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_FAILED); ++ ++ /* Initialize the size of hal functions */ ++ *HalFuncSize = sizeof (HAL_FUNCTIONS); ++ ++ /* clear the device structure */ ++ OsFunc->Memset(HalPtr, 0, sizeof(HAL_DEVICE)); ++ ++ /* clear the function pointers */ ++ OsFunc->Memset(HalFuncPtr, 0, sizeof(HAL_FUNCTIONS)); ++ ++ /* initialize the HAL_DEVICE structure */ ++ HalPtr->OsDev = OsDev; ++ /*HalPtr->OsOpen = OsDev;*/ ++ HalPtr->Inst = Inst; ++ HalPtr->OsFunc = OsFunc; ++ ++ /* Supply pointers for the CPHAL API functions */ ++ HalFuncPtr->RxReturn = halRxReturn; ++ HalFuncPtr->Init = halInit; ++ HalFuncPtr->Close = halClose; ++ HalFuncPtr->Send = halSend; ++ HalFuncPtr->ChannelSetup = halChannelSetup; ++ HalFuncPtr->ChannelTeardown = halChannelTeardown; ++ HalFuncPtr->Open = halOpen; ++ HalFuncPtr->Kick = halKick; ++ HalFuncPtr->RegAccess = halRegAccess; ++ HalFuncPtr->Probe = halProbe; ++ HalFuncPtr->Control = halControl; ++ HalFuncPtr->Tick = halTick; ++ HalFuncPtr->Shutdown = halShutdown; ++ HalFuncPtr->OamFuncConfig = halOamFuncConfig; /* +GSG 030306 */ ++ HalFuncPtr->OamLoopbackConfig = halOamLoopbackConfig; /* ~GSG 030416 */ ++ ++ /* Temporary */ ++ /*HalFuncPtr->StatsGetOld = StatsGet;*/ ++ HalFuncPtr->PacketProcessEnd = halPacketProcessEnd; ++ ++ /* Now, AAL5 must connect to the CPSAR layer */ ++ ++ /* Attach to SAR HAL Functions */ ++ /* ++ cpsarInitModule(NULL, NULL, 0, NULL, &SarFuncSize, Inst); ++ ++ if (SarFuncSize!=sizeof(CPSAR_FUNCTIONS)) ++ return(EC_AAL5|EC_FUNC_HAL_INIT|EC_VAL_CPSAR_VERSION_NOT_SUPPORTED); ++ ++ HalPtr->SarFunc = (CPSAR_FUNCTIONS *) OsFunc->Malloc(SarFuncSize); ++ */ ++ ++ rc = cpsarInitModule(&HalPtr->SarDev, OsDev, &HalPtr->SarFunc, OsFunc, sizeof(OS_FUNCTIONS), &SarFuncSize, Inst); ++ ++ /* pass back the error value from the CPSAR layer if necessary */ ++ if (rc) ++ return(rc); ++ ++ /* ++ if (!HalPtr->SarDev) ++ return(EC_AAL5|EC_FUNC_HAL_INIT|EC_VAL_NULL_CPSAR_DEV); ++ */ ++ ++ /* Initialize the hardware state */ ++ HalPtr->State = enConnected; ++ ++ /* keep a reference to HalFuncPtr so I can free it later */ ++ HalPtr->HalFuncPtr = HalFuncPtr; ++ ++ /* pass the HalPtr back to the caller */ ++ *HalDev = HalPtr; ++ *HalFunc = HalFuncPtr; ++ ++ return(EC_NO_ERRORS); ++ } +diff -urN linux.old/drivers/atm/sangam_atm/aal5sar.h linux.dev/drivers/atm/sangam_atm/aal5sar.h +--- linux.old/drivers/atm/sangam_atm/aal5sar.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/aal5sar.h 2005-08-23 04:46:50.080846280 +0200 +@@ -0,0 +1,198 @@ ++/**@file************************************************************************ ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: aal5sar.h ++ * ++ * DESCRIPTION: ++ * This file contains data structure definitions for the AAL5 HAL SAR. ++ * ++ * HISTORY: ++ * 28Feb02 Greg 1.00 Original Version created. ++ * 06Mar02 Greg 1.01 Documented structures. ++ * 18Jul02 Greg 1.02 Major reorganization ++ * ++ *****************************************************************************/ ++#ifndef _INC_AAL5SAR ++#define _INC_AAL5SAR ++ ++/** \namespace AAL5_Version ++This documents version 01.06.06 of the AAL5 CPHAL. ++*/ ++const char *pszVersion_CPAAL5="CPAAL5 01.06.06 "__DATE__" "__TIME__; ++ ++#include "cpsar_cpaal5.h" ++ ++#define NUM_AAL5_CHAN 16 ++#define MAX_AAL5_CHAN 15 ++#define MAX_QUEUE 2 ++#define MAX_DIRECTION 2 ++ ++#define PKT_TYPE_AAL5 0 /* +GSG 030508 */ ++#define PKT_TYPE_NULL 1 /* +GSG 030508 */ ++#define PKT_TYPE_OAM 2 /* +GSG 030508 */ ++#define PKT_TYPE_TRANS 3 /* +GSG 030508 */ ++#define ATM_HEADER_SIZE 4 /* +GSG 030508 */ ++ ++/* ++ * HAL Default Parameter Values ++ */ ++#define CFG_TX_NUM_BUFS {256,256,256,256,256,256,256,256, 256,256,256,256,256,256,256,256} ++#define CFG_RX_NUM_BUFS {256,256,256,256,256,256,256,256, 256,256,256,256,256,256,256,256} ++#define CFG_RX_BUF_SIZE {1518,1518,1518,1518,1518,1518,1518,1518, 1518,1518,1518,1518,1518,1518,1518,1518} ++#define CFG_RX_BUF_OFFSET {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_TX_NUM_QUEUES {1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1} ++#define CFG_CPCS_UU {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_DA_MASK {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_PRIORITY {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_PKT_TYPE {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_VCI {100,101,102,103,104,105,106,107, 108,109,110,111,112,113,114,115} ++#define CFG_VPI {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_CELL_RATE {0x30d4,0x30d4,0x30d4,0x30d4,0x30d4,0x30d4,0x30d4,0x30d4, 0x30d4,0x30d4,0x30d4,0x30d4,0x30d4,0x30d4,0x30d4,0x30d4} ++#define CFG_QOS_TYPE {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_MBS {8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8} ++#define CFG_PCR {1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1} ++#define CFG_GFC {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_CLP {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_PTI {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0} ++#define CFG_RX_MAX_SERVICE {170,170,170,170,170,170,170,170, 170,170,170,170,170,170,170,170} ++#define CFG_TX_MAX_SERVICE {170,170,170,170,170,170,170,170, 170,170,170,170,170,170,170,170} ++ ++static int cfg_tx_num_bufs[NUM_AAL5_CHAN] = CFG_TX_NUM_BUFS; ++static int cfg_rx_num_bufs[NUM_AAL5_CHAN] = CFG_RX_NUM_BUFS; ++static int cfg_rx_buf_size[NUM_AAL5_CHAN] = CFG_RX_BUF_SIZE; ++static int cfg_rx_buf_offset[NUM_AAL5_CHAN] = CFG_RX_BUF_OFFSET; ++static int cfg_tx_num_queues[NUM_AAL5_CHAN] = CFG_TX_NUM_QUEUES; ++static bit32u cfg_cpcs_uu[NUM_AAL5_CHAN] = CFG_CPCS_UU; ++static int cfg_da_mask[NUM_AAL5_CHAN] = CFG_DA_MASK; ++static int cfg_priority[NUM_AAL5_CHAN] = CFG_PRIORITY; ++static int cfg_pkt_type[NUM_AAL5_CHAN] = CFG_PKT_TYPE; ++static int cfg_vci[NUM_AAL5_CHAN] = CFG_VCI; ++static int cfg_vpi[NUM_AAL5_CHAN] = CFG_VPI; ++static bit32u cfg_cell_rate[NUM_AAL5_CHAN] = CFG_CELL_RATE; ++static int cfg_qos_type[NUM_AAL5_CHAN] = CFG_QOS_TYPE; ++static int cfg_mbs[NUM_AAL5_CHAN] = CFG_MBS; ++static int cfg_pcr[NUM_AAL5_CHAN] = CFG_PCR; ++static int cfg_gfc[NUM_AAL5_CHAN] = CFG_GFC; ++static int cfg_clp[NUM_AAL5_CHAN] = CFG_CLP; ++static int cfg_pti[NUM_AAL5_CHAN] = CFG_PTI; ++static int cfg_rx_max_service[NUM_AAL5_CHAN]= CFG_RX_MAX_SERVICE; ++static int cfg_tx_max_service[NUM_AAL5_CHAN]= CFG_TX_MAX_SERVICE; ++static char *channel_names[] = CHANNEL_NAMES; ++ ++/* ++ * The HAL_FUNCTIONS struct defines the function pointers for all HAL functions ++ * accessible to upper layer software. It is populated by calling ++ * halInitModules(). ++ * ++ * Note that this list is still under definition. ++ */ ++ ++/* ++ * This is the data structure for a transmit buffer descriptor. The first ++ * four 32-bit words of the BD represent the CPPI 3.0 defined buffer descriptor ++ * words. The other words are SAR/HAL implementation specific. ++ */ ++typedef struct ++ { ++ bit32 HNext; /**< Hardware's pointer to next buffer descriptor */ ++ bit32 BufPtr; /**< Pointer to the data buffer */ ++ bit32 Off_BLen; /**< Contains buffer offset and buffer length */ ++ bit32 mode; /**< SOP, EOP, Ownership, EOQ, Teardown Complete bits */ ++ bit32 AtmHeader; /**< Atm Header to be used for each fragment */ ++ bit32 Word5; /**< General control information for the packet */ ++ bit32 Res6; ++ bit32 Res7; ++ void *Next; ++ void *OsInfo; ++#ifdef __CPHAL_DEBUG ++ bit32 DbgSop; ++ bit32 DbgData; ++ bit32 DbgFraglist; ++#endif ++ void *Eop; ++ }HAL_TCB; ++ ++/* ++ * This is the data structure for a receive buffer descriptor. The first ++ * six 32-bit words of the BD represent the CPPI 3.0 defined buffer descriptor ++ * words. The other words are HAL implementation specific. ++ */ ++typedef volatile struct hal_private ++ { ++ bit32 HNext; /**< Hardware's pointer to next buffer descriptor */ ++ bit32 BufPtr; /**< Pointer to the data buffer */ ++ bit32 Off_BLen; /**< Contains buffer offset and buffer length */ ++ bit32 mode; /**< SOP, EOP, Ownership, EOQ, Teardown, Q Starv, Length */ ++ bit32 AtmHeader; ++ bit32 UuCpi; ++ bit32 Res6; ++ bit32 Res7; ++ void *DatPtr; ++ void *Next; ++ void *OsInfo; ++ void *Eop; ++ bit32 FragCount; ++ bit32 Ch; ++ HAL_DEVICE *HalDev; ++ }HAL_RCB; ++ ++ ++#define MAX_NEEDS 512 /*MJH+030409*/ ++/* ++ * This is the data structure for a generic HAL device. It contains all device ++ * specific data for a single instance of that device. This includes Rx/Tx ++ * buffer queues, device base address, reset bit, and other information. ++ */ ++typedef struct hal_device ++ { ++ HAL_RCB *RcbPool[NUM_AAL5_CHAN]; ++ bit32u rxbufseq; ++ bit32 RxActQueueCount[NUM_AAL5_CHAN]; ++ HAL_RCB *RxActQueueHead[NUM_AAL5_CHAN]; ++ HAL_RCB *RxActQueueTail[NUM_AAL5_CHAN]; ++ bit32 RxActive[NUM_AAL5_CHAN]; ++ bit32 dev_base; ++ HAL_TCB *TcbPool[NUM_AAL5_CHAN][MAX_QUEUE]; ++ bit32 offset; ++ bit32 TxActQueueCount[NUM_AAL5_CHAN][MAX_QUEUE]; ++ HAL_TCB *TxActQueueHead[NUM_AAL5_CHAN][MAX_QUEUE]; ++ HAL_TCB *TxActQueueTail[NUM_AAL5_CHAN][MAX_QUEUE]; ++ bit32 TxActive[NUM_AAL5_CHAN][MAX_QUEUE]; ++ bit32 TxTeardownPending[NUM_AAL5_CHAN]; ++ bit32 RxTeardownPending[NUM_AAL5_CHAN]; ++ bit32 ChIsOpen[NUM_AAL5_CHAN][MAX_DIRECTION]; ++ bit32 ChIsSetup[NUM_AAL5_CHAN][MAX_DIRECTION]; ++ bit32 interrupt; ++ bit32 debug; ++ OS_DEVICE *OsDev; ++ OS_FUNCTIONS *OsFunc; ++ CPSAR_FUNCTIONS *SarFunc; ++ CPSAR_DEVICE *SarDev; ++ /*void *OsOpen;*/ ++ /*FRAGLIST fraglist[MAX_FRAG];*/ ++ FRAGLIST *fraglist; ++ char *TcbStart[NUM_AAL5_CHAN][MAX_QUEUE]; ++ char *RcbStart[NUM_AAL5_CHAN]; ++ /*bit32 RcbSize[NUM_AAL5_CHAN];*/ ++ bit32 InRxInt[NUM_AAL5_CHAN]; ++ STAT_INFO Stats; ++ bit32 Inst; ++ bit32u DeviceCPID[4]; ++ bit32u LBSourceLLID[4]; ++ CHANNEL_INFO ChData[NUM_AAL5_CHAN]; ++ DEVICE_STATE State; ++ char *DeviceInfo; ++ HAL_FUNCTIONS *HalFuncPtr; ++ int NextRxCh; ++ int NextTxCh[2]; ++ int StrictPriority; /* +GSG 030304 */ ++ bit32u NeedsCount; /*MJH+030409*/ ++ HAL_RECEIVEINFO *Needs[MAX_NEEDS]; /*MJH+030409*/ ++ bit32u SarFrequency; /* +GSG 030416 */ ++ int MaxFrags; ++ bit32u TurboDslErrors; ++ bit32u OamLbTimeout; ++ }HALDEVICE; ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/cpcommon_cpaal5.c linux.dev/drivers/atm/sangam_atm/cpcommon_cpaal5.c +--- linux.old/drivers/atm/sangam_atm/cpcommon_cpaal5.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpcommon_cpaal5.c 2005-08-23 04:46:50.081846128 +0200 +@@ -0,0 +1,728 @@ ++#ifndef _INC_CPCOMMON_C ++#define _INC_CPCOMMON_C ++ ++#ifdef _CPHAL_CPMAC ++#include "cpremap_cpmac.c" ++#endif ++ ++#ifdef _CPHAL_AAL5 ++#include "cpremap_cpaal5.c" ++#endif ++ ++#ifdef _CPHAL_CPSAR ++#include "cpremap_cpsar.c" ++#endif ++ ++#ifdef _CPHAL_AAL2 ++#include "cpremap_cpaal2.c" ++#endif ++ ++/** ++@defgroup Common_Config_Params Common Configuration Parameters ++ ++This section documents the configuration parameters that are valid across ++all CPHAL devices. ++@{ ++*/ ++/** This is the debug level. The field is bit defined, such that the user ++should set to 1 all the bits corresponding to desired debug outputs. The following ++are the meanings for each debug bit: ++- bit0 (LSB): CPHAL Function Trace ++- b1 : OS Function call trace ++- b2 : Critical section entry/exit ++- b3 : Memory allocation/destruction ++- b4 : Detailed information in Rx path ++- b5 : Detailed information in Tx path ++- b6 : Extended error information ++- b7 : General info ++*/ ++static const char pszDebug[] = "debug"; ++/** CPU Frequency. */ ++/*static const char pszCpuFreq[] = "CpuFreq";*/ /*MJH-030403*/ ++/** Base address for the module. */ ++static const char pszBase[] = "base"; ++/** Reset bit for the module. */ ++static const char pszResetBit[] = "reset_bit"; ++/** Reset base address for the module. */ ++static const char pszResetBase[] = "ResetBase"; ++/** Interrupt line for the module. */ ++static const char pszIntLine[] = "int_line"; ++/** VLYNQ offset for the module. Disregard if not using VLYNQ. */ ++static const char pszOffset[] = "offset"; ++/** The OS may "Get" this parameter, which is a pointer ++ to a character string that indicates the version of CPHAL. */ ++static const char pszVer[] = "Version"; ++/*@}*/ ++ ++/** ++@defgroup Common_Control_Params Common Keys for [os]Control() ++ ++This section documents the keys used with the OS @c Control() interface that ++are required by CPHAL devices. ++ ++@{ ++*/ ++/** Used to wait for an integer number of clock ticks, given as an integer ++ pointer in the @p Value parameter. No actions are defined. */ ++static const char pszSleep[] = "Sleep"; ++/** Requests the OS to flush it's IO buffers. No actions are defined. */ ++static const char pszSioFlush[] = "SioFlush"; ++/*@}*/ ++ ++static const char pszStateChange[] = "StateChange"; ++static const char pszStatus[] = "Status"; ++ ++static const char pszGET[] = "Get"; ++static const char pszSET[] = "Set"; ++static const char pszCLEAR[] = "Clear"; ++static const char pszNULL[] = ""; ++static const char pszLocator[] = "Locator"; ++static const char pszOff[] = "Off"; ++static const char pszOn[] = "On"; ++static const char hcMaxFrags[] = "MaxFrags"; ++ ++#ifdef _CPHAL_CPMAC ++ ++/* New method for string constants */ ++const char hcClear[] = "Clear"; ++const char hcGet[] = "Get"; ++const char hcSet[] = "Set"; ++ ++const char hcTick[] = "Tick"; ++ ++static const CONTROL_KEY KeyCommon[] = ++ { ++ {"" , enCommonStart}, ++ {pszStatus , enStatus}, ++ {pszOff , enOff}, ++ {pszOn , enOn}, ++ {pszDebug , enDebug}, ++ {hcCpuFrequency , enCpuFreq}, /*MJH~030403*/ ++ {"" , enCommonEnd} ++ }; ++#endif ++ ++/** ++@defgroup Common_Statistics Statistics ++ ++A broad array of module statistics is available. Statistics values are accessed ++through the @c Control() interface of the CPHAL. There are 5 different levels ++of statistics, each of which correspond to a unique set of data. Furthermore, ++certain statistics data is indexed by using a channel number and Tx queue number. ++The following is a brief description of each statistics level, along with the ++indexes used for the level: ++ ++- Level 0: Hardware Statistics (index with channel) ++- Level 1: CPHAL Software Statistics (channel, queue) ++- Level 2: CPHAL Flags (channel, queue) ++- Level 3: CPHAL Channel Configuration (channel) ++- Level 4: CPHAL General Configuration (no index) ++ ++The caller requests statistics information by providing a Key string to the ++@c Control() API in the following format: "Stats;[Level #];[Ch #];[Queue #]". ++The only valid Action parameter for statistics usage is "Get". ++ ++Code Examples: ++@code ++unsigned int *StatsData; ++ ++# Get Level 0 stats for Channel 1 ++HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); ++ ++# Get Level 2 stats for Channel 0, Queue 0 ++HalFunc->Control(OsDev->HalDev, "Stats;2;0;0", "Get", &StatsData); ++ ++# Get Level 4 stats ++HalFunc->Control(OsDev->HalDev, "Stats;4", "Get", &StatsData); ++@endcode ++ ++The information returned in the Value parameter of @c Control() is an ++array of pointers to strings. The pointers are arranged in pairs. ++The first pointer is a pointer to a name string for a particular statistic. ++The next pointer is a pointer to a string containing the representation of ++the integer statistic value corresponding to the first pointer. This is followed ++by another pair of pointers, and so on, until a NULL pointer is encountered. The ++following is example code for processing the statistics data. Note that the OS ++is responsible for freeing the memory passed back through the Value parameter of ++@c Control(). ++ ++@code ++unsigned int *StatsData; ++ ++# Get Level 0 stats for Channel 1 ++HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); ++ ++# output Statistics data ++PrintStats(StatsData); ++ ++# the upper layer is responsible for freeing stats info ++free(&StatsPtr); ++ ++... ++ ++void PrintStats(unsigned int *StatsPtr) ++ { ++ while(*StatsPtr) ++ { ++ printf("%20s:", (char *)*StatsPtr); ++ StatsPtr++; ++ printf("%11s\n", (char *)*StatsPtr); ++ StatsPtr++; ++ } ++ MySioFlush(); ++ } ++@endcode ++ ++Within each statistics level, there are several statistics defined. The statistics that ++are common to every CPPI module are listed below. In addition, each module may define ++extra statistics in each level, which will be documented within the module-specific ++documentation appendices. ++ ++- Level 0 Statistics ++ - All level 0 statistics are module-specific. ++- Level 1 Statistics (CPHAL Software Statistics) ++ - DmaLenErrors: Incremented when the port DMA's more data than expected (per channel). (AAL5 Only) ++ - TxMisQCnt: Incremented when host queues a packet for transmission as the port finishes ++transmitting the previous last packet in the queue (per channel and queue). ++ - RxMisQCnt: Incremented when host queues adds buffers to a queue as the port finished the ++reception of the previous last packet in the queue (per channel). ++ - TxEOQCnt: Number of times the port has reached the end of the transmit queue (per channel and queue). ++ - RxEOQCnt: Number of times the port has reached the end of the receive queue (per channel). ++ - RxPacketsServiced: Number of received packets (per channel). ++ - TxPacketsServiced: Number of transmitted packets (per channel and queue). ++ - RxMaxServiced: Maximum number of packets that the CPHAL receive interrupt has serviced at a time (per channel). ++ - TxMaxServiced: Maximum number of packets that the CPHAL transmit interrupt has serviced at a time (per channel and queue). ++ - RxTotal: Total number of received packets, all channels. ++ - TxTotal: Total number of transmitted packets, all channels and queues. ++- Level 2 Statistics (CPHAL Flags) ++ - RcbPool: Pointer to receive descriptor pool (per channel). ++ - RxActQueueCount: Number of buffers currently available for receive (per channel). ++ - RxActQueueHead: Pointer to first buffer in receive queue (per channel). ++ - RxActQueueTail: Pointer to last buffer in receive queue (per channel). ++ - RxActive: 0 if inactive (no buffers available), or 1 if active (buffers available). ++ - RcbStart: Pointer to block of receive descriptors. ++ - RxTeardownPending: 1 if Rx teardown is pending but incomplete, 0 otherwise. ++ - TcbPool: Pointer to transmit descriptor pool (per channel and queue). ++ - TxActQueueCount: Number of buffers currently queued to be transmitted (per channel and queue). ++ - TxActQueueHead: Pointer to first buffer in transmit queue (per channel and queue). ++ - TxActQueueTail: Pointer to last buffer in transmit queue (per channel and queue). ++ - TxActive: 0 if inactive (no buffers to send), or 1 if active (buffers queued to send). ++ - TcbStart: Pointer to block of transmit descriptors. ++ - TxTeardownPending: 1 if Tx teardown is pending but incomplete, 0 otherwise. ++- Level 3 Statistics (CPHAL Channel Configuration) ++ - RxBufSize: Rx buffer size. ++ - RxBufferOffset: Rx buffer offset. ++ - RxNumBuffers: Number of Rx buffers. ++ - RxServiceMax: Maximum number of receive packets to service at a time. ++ - TxNumBuffers: Number of Tx buffer descriptors. ++ - TxNumQueues: Number of Tx queues to use. ++ - TxServiceMax: Maximum number of transmit packets to service at a time. ++- Level 4 Statistics (CPHAL General Configuration) ++ - Base Address: Base address of the module. ++ - Offset (VLYNQ): VLYNQ relative module offset. ++ - Interrupt Line: Interrupt number. ++ - Debug: Debug flag, 1 to enable debug. ++ - Inst: Instance number. ++*/ ++ ++/* ++ Data Type 0 = int display ++ Data Type 1 = hex display ++ Data Type 2 = channel structure, int display ++ Data Type 3 = queue index and int display ++ Data Type 4 = queue index and hex display ++*/ ++#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) /* +GSG 030307 */ ++static STATS_TABLE StatsTable0[] = ++ { ++#ifdef _CPHAL_AAL5 ++ /* Name , Data Ptr, Data Type */ ++ {"Crc Errors", 0, 0}, ++ {"Len Errors", 0, 0}, ++ {"Abort Errors", 0, 0}, ++ {"Starv Errors", 0, 0} ++#endif ++#ifdef _CPHAL_CPMAC ++ {"Rx Good Frames", 0, 0} ++#endif ++ }; ++ ++static STATS_TABLE StatsTable1[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"DmaLenErrors", 0, 0}, ++ {"TxMisQCnt", 0, 3}, ++ {"RxMisQCnt", 0, 0}, ++ {"TxEOQCnt", 0, 3}, ++ {"RxEOQCnt", 0, 0}, ++ {"RxPacketsServiced", 0, 0}, ++ {"TxPacketsServiced", 0, 3}, ++ {"RxMaxServiced", 0, 0}, ++ {"TxMaxServiced", 0, 3}, ++ {"RxTotal", 0, 0}, ++ {"TxTotal", 0, 0}, ++ }; ++ ++static STATS_TABLE StatsTable2[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"RcbPool", 0, 1}, ++ {"RxActQueueCount", 0, 0}, ++ {"RxActQueueHead", 0, 1}, ++ {"RxActQueueTail", 0, 1}, ++ {"RxActive", 0, 0}, ++ {"RcbStart", 0, 1}, ++ {"RxTeardownPending", 0, 0}, ++ {"TcbPool", 0, 4}, ++ {"TxActQueueCount", 0, 3}, ++ {"TxActQueueHead", 0, 4}, ++ {"TxActQueueTail", 0, 4}, ++ {"TxActive", 0, 3}, ++ {"TcbStart", 0, 4}, ++ {"TxTeardownPending", 0, 0} ++ }; ++ ++static STATS_TABLE StatsTable3[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"RxBufSize", 0, 2}, ++ {"RxBufferOffset", 0, 2}, ++ {"RxNumBuffers", 0, 2}, ++ {"RxServiceMax", 0, 2}, ++ {"TxNumBuffers", 0, 2}, ++ {"TxNumQueues", 0, 2}, ++ {"TxServiceMax", 0, 2}, ++#ifdef _CPHAL_AAL5 ++ {"CpcsUU", 0, 2}, ++ {"Gfc", 0, 2}, ++ {"Clp", 0, 2}, ++ {"Pti", 0, 2}, ++ {"DaMask", 0, 2}, ++ {"Priority", 0, 2}, ++ {"PktType", 0, 2}, ++ {"Vci", 0, 2}, ++ {"Vpi", 0, 2}, ++ {"CellRate", 0, 2}, ++ {"QosType", 0, 2}, ++ {"Mbs", 0, 2}, ++ {"Pcr", 0, 2} ++#endif ++ }; ++ ++static STATS_TABLE StatsTable4[] = ++ { ++ {"Base Address", 0, 1}, ++ {"Offset (VLYNQ)", 0, 0}, ++ {"Interrupt Line", 0, 0}, ++ {"Debug", 0, 0}, ++ {"Instance", 0, 0}, ++#ifdef _CPHAL_AAL5 ++ {"UniNni", 0, 0} ++#endif ++ }; ++ ++static STATS_DB StatsDb[] = ++ { ++ {(sizeof(StatsTable0)/sizeof(STATS_TABLE)), StatsTable0}, ++ {(sizeof(StatsTable1)/sizeof(STATS_TABLE)), StatsTable1}, ++ {(sizeof(StatsTable2)/sizeof(STATS_TABLE)), StatsTable2}, ++ {(sizeof(StatsTable3)/sizeof(STATS_TABLE)), StatsTable3}, ++ {(sizeof(StatsTable4)/sizeof(STATS_TABLE)), StatsTable4} ++ }; ++#endif /* +GSG 030307 */ ++ ++#ifdef _CPHAL_CPMAC /* +RC 3.02 */ ++static void resetWait(HAL_DEVICE *HalDev) ++ { /*+RC3.02*/ ++ const int TickReset=64; ++ osfuncSleep((int*)&TickReset); ++ } /*+RC3.02*/ ++#endif /* +RC 3.02 */ ++ ++/* I only define the reset base function for the modules ++ that can perform a reset. The AAL5 and AAL2 modules ++ do not perform a reset, that is done by the shared module ++ CPSAR */ ++#if defined(_CPHAL_CPSAR) || defined(_CPHAL_CPMAC) || defined(_CPHAL_VDMAVT) ++/* ++ * Determines the reset register address to be used for a particular device. ++ * It will search the current device entry for Locator information. If the ++ * device is a root device, there will be no Locator information, and the ++ * function will find and return the root reset register. If a Locator value ++ * is found, the function will search each VLYNQ device entry in the system ++ * looking for a matching Locator. Once it finds a VLYNQ device entry with ++ * a matching Locator, it will extract the "ResetBase" parameter from that ++ * VLYNQ device entry (thus every VLYNQ entry must have the ResetBase parameter). ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param ResetBase Pointer to integer address of reset register. ++ * ++ * @return 0 OK, Non-zero not OK ++ */ ++static int ResetBaseGet(HAL_DEVICE *HalDev, bit32u *ResetBase) ++ { ++ char *DeviceInfo = HalDev->DeviceInfo; ++ char *MyLocator, *NextLocator; ++ int Inst=1; ++ bit32u error_code; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]ResetBaseGet(HalDev:%08x, ResetBase:%08x)\n", (bit32u)HalDev, ResetBase); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &MyLocator); ++ if (error_code) ++ { ++ /* if no Locator value, device is on the root, so get the "reset" device */ ++ error_code = HalDev->OsFunc->DeviceFindInfo(0, "reset", &DeviceInfo); ++ if (error_code) ++ { ++ return(EC_VAL_DEVICE_NOT_FOUND); ++ } ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "base", ResetBase); ++ if (error_code) ++ { ++ return(EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ ++ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); ++ ++ /* found base address for root device, so we're done */ ++ return (EC_NO_ERRORS); ++ } ++ else ++ { ++ /* we have a Locator value, so the device is remote */ ++ ++ /* Find a vlynq device with a matching locator value */ ++ while ((HalDev->OsFunc->DeviceFindInfo(Inst, "vlynq", &DeviceInfo)) == EC_NO_ERRORS) ++ { ++ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &NextLocator); ++ if (error_code) ++ { ++ /* no Locator value for this VLYNQ, so move on */ ++ continue; ++ } ++ if (HalDev->OsFunc->Strcmpi(MyLocator, NextLocator)==0) ++ { ++ /* we have found a VLYNQ with a matching Locator, so extract the ResetBase */ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "ResetBase", ResetBase); ++ if (error_code) ++ { ++ return(EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); ++ ++ /* found base address for root device, so we're done */ ++ return (EC_NO_ERRORS); ++ } ++ Inst++; ++ } /* while */ ++ } /* else */ ++ ++ return (EC_NO_ERRORS); ++ } ++#endif ++ ++#ifndef _CPHAL_AAL2 /* + RC 3.02 */ ++static bit32u ConfigGetCommon(HAL_DEVICE *HalDev) ++ { ++ bit32u ParmValue; ++ bit32 error_code; ++ char *DeviceInfo = HalDev->DeviceInfo; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]ConfigGetCommon(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszBase, &ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ HalDev->dev_base = ((bit32u)PhysToVirtNoCache(ParmValue)); ++ ++#ifndef _CPHAL_AAL5 ++#ifndef _CPHAL_AAL2 ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszResetBit, &ParmValue); ++ if(error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BIT_NOT_FOUND); ++ } ++ HalDev->ResetBit = ParmValue; ++ ++ /* Get reset base address */ ++ error_code = ResetBaseGet(HalDev, &ParmValue); ++ if (error_code) ++ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BASE_NOT_FOUND); ++ HalDev->ResetBase = ParmValue; ++#endif ++#endif ++ ++#ifndef _CPHAL_CPSAR ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszIntLine,&ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_INTERRUPT_NOT_FOUND); ++ } ++ HalDev->interrupt = ParmValue; ++#endif ++ ++ /* only look for the offset if there is a Locator field, which indicates that ++ the module is a VLYNQ module */ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszLocator,&ParmValue); ++ if (!error_code) ++ { ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszOffset,&ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_OFFSET_NOT_FOUND); ++ } ++ HalDev->offset = ParmValue; ++ } ++ else ++ HalDev->offset = 0; ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszDebug, &ParmValue); ++ if (!error_code) HalDev->debug = ParmValue; ++ ++ return (EC_NO_ERRORS); ++ } ++#endif /* +RC 3.02 */ ++ ++#ifdef _CPHAL_CPMAC /* +RC 3.02 */ ++static void StatsInit(HAL_DEVICE *HalDev) /* +() RC3.02 */ ++ { ++ /* even though these statistics may be for multiple channels and ++ queues, i need only configure the pointer to the beginning ++ of the array, and I can index from there if necessary */ ++ ++#ifdef _CPHAL_AAL5 ++ StatsTable0[0].StatPtr = &HalDev->Stats.CrcErrors[0]; ++ StatsTable0[1].StatPtr = &HalDev->Stats.LenErrors[0]; ++ StatsTable0[2].StatPtr = &HalDev->Stats.AbortErrors[0]; ++ StatsTable0[3].StatPtr = &HalDev->Stats.StarvErrors[0]; ++ ++ StatsTable1[0].StatPtr = &HalDev->Stats.DmaLenErrors[0]; ++ StatsTable1[1].StatPtr = &HalDev->Stats.TxMisQCnt[0][0]; ++ StatsTable1[2].StatPtr = &HalDev->Stats.RxMisQCnt[0]; ++ StatsTable1[3].StatPtr = &HalDev->Stats.TxEOQCnt[0][0]; ++ StatsTable1[4].StatPtr = &HalDev->Stats.RxEOQCnt[0]; ++ StatsTable1[5].StatPtr = &HalDev->Stats.RxPacketsServiced[0]; ++ StatsTable1[6].StatPtr = &HalDev->Stats.TxPacketsServiced[0][0]; ++ StatsTable1[7].StatPtr = &HalDev->Stats.RxMaxServiced; ++ StatsTable1[8].StatPtr = &HalDev->Stats.TxMaxServiced[0][0]; ++ StatsTable1[9].StatPtr = &HalDev->Stats.RxTotal; ++ StatsTable1[10].StatPtr = &HalDev->Stats.TxTotal; ++#endif ++ ++#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) ++ StatsTable2[0].StatPtr = (bit32u *)&HalDev->RcbPool[0]; ++ StatsTable2[1].StatPtr = &HalDev->RxActQueueCount[0]; ++ StatsTable2[2].StatPtr = (bit32u *)&HalDev->RxActQueueHead[0]; ++ StatsTable2[3].StatPtr = (bit32u *)&HalDev->RxActQueueTail[0]; ++ StatsTable2[4].StatPtr = &HalDev->RxActive[0]; ++ StatsTable2[5].StatPtr = (bit32u *)&HalDev->RcbStart[0]; ++ StatsTable2[6].StatPtr = &HalDev->RxTeardownPending[0]; ++ StatsTable2[7].StatPtr = (bit32u *)&HalDev->TcbPool[0][0]; ++ StatsTable2[8].StatPtr = &HalDev->TxActQueueCount[0][0]; ++ StatsTable2[9].StatPtr = (bit32u *)&HalDev->TxActQueueHead[0][0]; ++ StatsTable2[10].StatPtr = (bit32u *)&HalDev->TxActQueueTail[0][0]; ++ StatsTable2[11].StatPtr = &HalDev->TxActive[0][0]; ++ StatsTable2[12].StatPtr = (bit32u *)&HalDev->TcbStart[0][0]; ++ StatsTable2[13].StatPtr = &HalDev->TxTeardownPending[0]; ++ ++ StatsTable3[0].StatPtr = &HalDev->ChData[0].RxBufSize; ++ StatsTable3[1].StatPtr = &HalDev->ChData[0].RxBufferOffset; ++ StatsTable3[2].StatPtr = &HalDev->ChData[0].RxNumBuffers; ++ StatsTable3[3].StatPtr = &HalDev->ChData[0].RxServiceMax; ++ StatsTable3[4].StatPtr = &HalDev->ChData[0].TxNumBuffers; ++ StatsTable3[5].StatPtr = &HalDev->ChData[0].TxNumQueues; ++ StatsTable3[6].StatPtr = &HalDev->ChData[0].TxServiceMax; ++#ifdef _CPHAL_AAL5 ++ StatsTable3[7].StatPtr = &HalDev->ChData[0].CpcsUU; ++ StatsTable3[8].StatPtr = &HalDev->ChData[0].Gfc; ++ StatsTable3[9].StatPtr = &HalDev->ChData[0].Clp; ++ StatsTable3[10].StatPtr = &HalDev->ChData[0].Pti; ++ StatsTable3[11].StatPtr = &HalDev->ChData[0].DaMask; ++ StatsTable3[12].StatPtr = &HalDev->ChData[0].Priority; ++ StatsTable3[13].StatPtr = &HalDev->ChData[0].PktType; ++ StatsTable3[14].StatPtr = &HalDev->ChData[0].Vci; ++ StatsTable3[15].StatPtr = &HalDev->ChData[0].Vpi; ++ StatsTable3[16].StatPtr = &HalDev->ChData[0].TxVc_CellRate; ++ StatsTable3[17].StatPtr = &HalDev->ChData[0].TxVc_QosType; ++ StatsTable3[18].StatPtr = &HalDev->ChData[0].TxVc_Mbs; ++ StatsTable3[19].StatPtr = &HalDev->ChData[0].TxVc_Pcr; ++#endif ++#endif ++ ++ StatsTable4[0].StatPtr = &HalDev->dev_base; ++ StatsTable4[1].StatPtr = &HalDev->offset; ++ StatsTable4[2].StatPtr = &HalDev->interrupt; ++ StatsTable4[3].StatPtr = &HalDev->debug; ++ StatsTable4[4].StatPtr = &HalDev->Inst; ++ } ++#endif /* +RC 3.02 */ ++ ++#ifndef _CPHAL_CPSAR /* +RC 3.02 */ ++#ifndef _CPHAL_AAL2 /* +RC 3.02 */ ++/* ++ * Returns statistics information. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return 0 ++ */ ++static int StatsGet(HAL_DEVICE *HalDev, void **StatPtr, int Index, int Ch, int Queue) ++ { ++ int Size; ++ bit32u *AddrPtr; ++ char *DataPtr; ++ STATS_TABLE *StatsTable; ++ int i, NumberOfStats; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]StatsGet(HalDev:%08x, StatPtr:%08x)\n", ++ (bit32u)HalDev, (bit32u)StatPtr); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ StatsTable = StatsDb[Index].StatTable; ++ NumberOfStats = StatsDb[Index].NumberOfStats; ++ ++ Size = sizeof(bit32u)*((NumberOfStats*2)+1); ++ Size += (NumberOfStats*11); ++ *StatPtr = (bit32u *)HalDev->OsFunc->Malloc(Size); ++ ++ AddrPtr = (bit32u *) *StatPtr; ++ DataPtr = (char *)AddrPtr; ++ DataPtr += sizeof(bit32u)*((NumberOfStats*2)+1); ++ ++ for (i=0; iOsFunc->Sprintf(DataPtr, "%d", (bit32u *)StatsTable[i].StatPtr[Ch]); ++ break; ++ case 1: ++ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", (bit32u *)StatsTable[i].StatPtr[Ch]); ++ break; ++ case 2: ++ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch * (sizeof(CHANNEL_INFO)/4)))); ++ break; ++ case 3: ++ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); ++ break; ++ case 4: ++ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); ++ break; ++ default: ++ /* invalid data type, due to CPHAL programming error */ ++ break; ++ } ++ } ++ else ++ { ++ /* invalid statistics pointer, probably was not initialized */ ++ } ++ DataPtr += HalDev->OsFunc->Strlen(DataPtr) + 1; ++ } ++ ++ *AddrPtr = (bit32u) 0; ++ ++ return (EC_NO_ERRORS); ++ } ++#endif /* +RC 3.02 */ ++#endif /* +RC 3.02 */ ++ ++#ifdef _CPHAL_CPMAC ++static void gpioFunctional(int base, int bit) ++ { /*+RC3.02*/ ++ bit32u GpioEnr = base + 0xC; ++ /* To make functional, set to zero */ ++ *(volatile bit32u *)(GpioEnr) &= ~(1 << bit); /*+RC3.02*/ ++ } /*+RC3.02*/ ++ ++ ++/*+RC3.02*/ ++/* Common function, Checks to see if GPIO should be in functional mode */ ++static void gpioCheck(HAL_DEVICE *HalDev, void *moduleDeviceInfo) ++ { /*+RC3.02*/ ++ int rc; ++ void *DeviceInfo; ++ char *pszMuxBits; ++ char pszMuxBit[20]; ++ char *pszTmp; ++ char szMuxBit[20]; ++ char *ptr; ++ int base; ++ int reset_bit; ++ int bit; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ ++ rc = OsFunc->DeviceFindParmValue(moduleDeviceInfo, "gpio_mux",&pszTmp); ++ if(rc) return; ++ /* gpio entry found, get GPIO register info and make functional */ ++ ++ /* temp copy until FinParmValue fixed */ ++ ptr = &szMuxBit[0]; ++ while ((*ptr++ = *pszTmp++)); ++ ++ pszMuxBits = &szMuxBit[0]; ++ ++ rc = OsFunc->DeviceFindInfo(0,"gpio",&DeviceInfo); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",&base); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit); ++ if(rc) return; ++ ++ /* If GPIO still in reset, then exit */ ++ if((VOLATILE32(HalDev->ResetBase) & (1 << reset_bit)) == 0) ++ return; ++ /* format for gpio_mux is gpio_mux = ;;...*/ ++ while (*pszMuxBits) ++ { ++ pszTmp = &pszMuxBit[0]; ++ if(*pszMuxBits == ';') pszMuxBits++; ++ while ((*pszMuxBits != ';') && (*pszMuxBits != '\0')) ++ { ++ osfuncSioFlush(); ++ /*If value not a number, skip */ ++ if((*pszMuxBits < '0') || (*pszMuxBits > '9')) ++ pszMuxBits++; ++ else ++ *pszTmp++ = *pszMuxBits++; ++ } ++ *pszTmp = '\0'; ++ bit = OsFunc->Strtoul(pszMuxBit, &pszTmp, 10); ++ gpioFunctional(base, bit); ++ resetWait(HalDev); /* not sure if this is needed */ ++ } ++ } /*+RC3.02*/ ++#endif /* CPMAC */ ++ ++#ifdef _CPHAL_AAL5 ++const char hcSarFrequency[] = "SarFreq"; ++#endif ++ ++#endif /* _INC */ +diff -urN linux.old/drivers/atm/sangam_atm/cpcommon_cpaal5.h linux.dev/drivers/atm/sangam_atm/cpcommon_cpaal5.h +--- linux.old/drivers/atm/sangam_atm/cpcommon_cpaal5.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpcommon_cpaal5.h 2005-08-23 04:46:50.082845976 +0200 +@@ -0,0 +1,79 @@ ++#ifndef _INC_CPCOMMON_H ++#define _INC_CPCOMMON_H ++ ++#define VOLATILE32(addr) (*(volatile bit32u *)(addr)) ++#ifndef dbgPrintf ++#define dbgPrintf HalDev->OsFunc->Printf ++#endif ++ ++#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field ++ ++#define DBG(level) (HalDev->debug & (1<<(level))) ++/* ++#define DBG0() DBG(0) ++#define DBG1() DBG(1) ++#define DBG2() DBG(2) ++#define DBG3() DBG(3) ++#define DBG4() DBG(4) ++#define DBG5() DBG(5) ++#define DBG6() DBG(6) ++#define DBG7() DBG(7) ++*/ ++ ++/* ++ * List of defined actions for use with Control(). ++ */ ++typedef enum ++ { ++ enGET=0, /**< Get the value associated with a key */ ++ enSET, /**< Set the value associates with a key */ ++ enCLEAR, /**OsFunc->Control(HalDev->OsDev,"SioFlush",pszNULL,0) ++#define osfuncSleep(Ticks) HalDev->OsFunc->Control(HalDev->OsDev,pszSleep,pszNULL,Ticks) ++#define osfuncStateChange() HalDev->OsFunc->Control(HalDev->OsDev,pszStateChange,pszNULL,0) ++ ++#define CHANNEL_NAMES {"Ch0","Ch1","Ch2","Ch3","Ch4","Ch5","Ch6","Ch7","Ch8","Ch9","Ch10","Ch11","Ch12","Ch13","Ch14","Ch15"} ++ ++#endif ++ +diff -urN linux.old/drivers/atm/sangam_atm/cpcommon_cpsar.c linux.dev/drivers/atm/sangam_atm/cpcommon_cpsar.c +--- linux.old/drivers/atm/sangam_atm/cpcommon_cpsar.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpcommon_cpsar.c 2005-08-23 04:46:50.082845976 +0200 +@@ -0,0 +1,728 @@ ++#ifndef _INC_CPCOMMON_C ++#define _INC_CPCOMMON_C ++ ++#ifdef _CPHAL_CPMAC ++#include "cpremap_cpmac.c" ++#endif ++ ++#ifdef _CPHAL_AAL5 ++#include "cpremap_cpaal5.c" ++#endif ++ ++#ifdef _CPHAL_CPSAR ++#include "cpremap_cpsar.c" ++#endif ++ ++#ifdef _CPHAL_AAL2 ++#include "cpremap_cpaal2.c" ++#endif ++ ++/** ++@defgroup Common_Config_Params Common Configuration Parameters ++ ++This section documents the configuration parameters that are valid across ++all CPHAL devices. ++@{ ++*/ ++/** This is the debug level. The field is bit defined, such that the user ++should set to 1 all the bits corresponding to desired debug outputs. The following ++are the meanings for each debug bit: ++- bit0 (LSB): CPHAL Function Trace ++- b1 : OS Function call trace ++- b2 : Critical section entry/exit ++- b3 : Memory allocation/destruction ++- b4 : Detailed information in Rx path ++- b5 : Detailed information in Tx path ++- b6 : Extended error information ++- b7 : General info ++*/ ++static const char pszDebug[] = "debug"; ++/** CPU Frequency. */ ++/*static const char pszCpuFreq[] = "CpuFreq";*/ /*MJH-030403*/ ++/** Base address for the module. */ ++static const char pszBase[] = "base"; ++/** Reset bit for the module. */ ++static const char pszResetBit[] = "reset_bit"; ++/** Reset base address for the module. */ ++static const char pszResetBase[] = "ResetBase"; ++/** Interrupt line for the module. */ ++static const char pszIntLine[] = "int_line"; ++/** VLYNQ offset for the module. Disregard if not using VLYNQ. */ ++static const char pszOffset[] = "offset"; ++/** The OS may "Get" this parameter, which is a pointer ++ to a character string that indicates the version of CPHAL. */ ++static const char pszVer[] = "Version"; ++/*@}*/ ++ ++/** ++@defgroup Common_Control_Params Common Keys for [os]Control() ++ ++This section documents the keys used with the OS @c Control() interface that ++are required by CPHAL devices. ++ ++@{ ++*/ ++/** Used to wait for an integer number of clock ticks, given as an integer ++ pointer in the @p Value parameter. No actions are defined. */ ++static const char pszSleep[] = "Sleep"; ++/** Requests the OS to flush it's IO buffers. No actions are defined. */ ++static const char pszSioFlush[] = "SioFlush"; ++/*@}*/ ++ ++static const char pszStateChange[] = "StateChange"; ++static const char pszStatus[] = "Status"; ++ ++static const char pszGET[] = "Get"; ++static const char pszSET[] = "Set"; ++static const char pszCLEAR[] = "Clear"; ++static const char pszNULL[] = ""; ++static const char pszLocator[] = "Locator"; ++static const char pszOff[] = "Off"; ++static const char pszOn[] = "On"; ++static const char hcMaxFrags[] = "MaxFrags"; ++ ++#ifdef _CPHAL_CPMAC ++ ++/* New method for string constants */ ++const char hcClear[] = "Clear"; ++const char hcGet[] = "Get"; ++const char hcSet[] = "Set"; ++ ++const char hcTick[] = "Tick"; ++ ++static const CONTROL_KEY KeyCommon[] = ++ { ++ {"" , enCommonStart}, ++ {pszStatus , enStatus}, ++ {pszOff , enOff}, ++ {pszOn , enOn}, ++ {pszDebug , enDebug}, ++ {hcCpuFrequency , enCpuFreq}, /*MJH~030403*/ ++ {"" , enCommonEnd} ++ }; ++#endif ++ ++/** ++@defgroup Common_Statistics Statistics ++ ++A broad array of module statistics is available. Statistics values are accessed ++through the @c Control() interface of the CPHAL. There are 5 different levels ++of statistics, each of which correspond to a unique set of data. Furthermore, ++certain statistics data is indexed by using a channel number and Tx queue number. ++The following is a brief description of each statistics level, along with the ++indexes used for the level: ++ ++- Level 0: Hardware Statistics (index with channel) ++- Level 1: CPHAL Software Statistics (channel, queue) ++- Level 2: CPHAL Flags (channel, queue) ++- Level 3: CPHAL Channel Configuration (channel) ++- Level 4: CPHAL General Configuration (no index) ++ ++The caller requests statistics information by providing a Key string to the ++@c Control() API in the following format: "Stats;[Level #];[Ch #];[Queue #]". ++The only valid Action parameter for statistics usage is "Get". ++ ++Code Examples: ++@code ++unsigned int *StatsData; ++ ++# Get Level 0 stats for Channel 1 ++HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); ++ ++# Get Level 2 stats for Channel 0, Queue 0 ++HalFunc->Control(OsDev->HalDev, "Stats;2;0;0", "Get", &StatsData); ++ ++# Get Level 4 stats ++HalFunc->Control(OsDev->HalDev, "Stats;4", "Get", &StatsData); ++@endcode ++ ++The information returned in the Value parameter of @c Control() is an ++array of pointers to strings. The pointers are arranged in pairs. ++The first pointer is a pointer to a name string for a particular statistic. ++The next pointer is a pointer to a string containing the representation of ++the integer statistic value corresponding to the first pointer. This is followed ++by another pair of pointers, and so on, until a NULL pointer is encountered. The ++following is example code for processing the statistics data. Note that the OS ++is responsible for freeing the memory passed back through the Value parameter of ++@c Control(). ++ ++@code ++unsigned int *StatsData; ++ ++# Get Level 0 stats for Channel 1 ++HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); ++ ++# output Statistics data ++PrintStats(StatsData); ++ ++# the upper layer is responsible for freeing stats info ++free(&StatsPtr); ++ ++... ++ ++void PrintStats(unsigned int *StatsPtr) ++ { ++ while(*StatsPtr) ++ { ++ printf("%20s:", (char *)*StatsPtr); ++ StatsPtr++; ++ printf("%11s\n", (char *)*StatsPtr); ++ StatsPtr++; ++ } ++ MySioFlush(); ++ } ++@endcode ++ ++Within each statistics level, there are several statistics defined. The statistics that ++are common to every CPPI module are listed below. In addition, each module may define ++extra statistics in each level, which will be documented within the module-specific ++documentation appendices. ++ ++- Level 0 Statistics ++ - All level 0 statistics are module-specific. ++- Level 1 Statistics (CPHAL Software Statistics) ++ - DmaLenErrors: Incremented when the port DMA's more data than expected (per channel). (AAL5 Only) ++ - TxMisQCnt: Incremented when host queues a packet for transmission as the port finishes ++transmitting the previous last packet in the queue (per channel and queue). ++ - RxMisQCnt: Incremented when host queues adds buffers to a queue as the port finished the ++reception of the previous last packet in the queue (per channel). ++ - TxEOQCnt: Number of times the port has reached the end of the transmit queue (per channel and queue). ++ - RxEOQCnt: Number of times the port has reached the end of the receive queue (per channel). ++ - RxPacketsServiced: Number of received packets (per channel). ++ - TxPacketsServiced: Number of transmitted packets (per channel and queue). ++ - RxMaxServiced: Maximum number of packets that the CPHAL receive interrupt has serviced at a time (per channel). ++ - TxMaxServiced: Maximum number of packets that the CPHAL transmit interrupt has serviced at a time (per channel and queue). ++ - RxTotal: Total number of received packets, all channels. ++ - TxTotal: Total number of transmitted packets, all channels and queues. ++- Level 2 Statistics (CPHAL Flags) ++ - RcbPool: Pointer to receive descriptor pool (per channel). ++ - RxActQueueCount: Number of buffers currently available for receive (per channel). ++ - RxActQueueHead: Pointer to first buffer in receive queue (per channel). ++ - RxActQueueTail: Pointer to last buffer in receive queue (per channel). ++ - RxActive: 0 if inactive (no buffers available), or 1 if active (buffers available). ++ - RcbStart: Pointer to block of receive descriptors. ++ - RxTeardownPending: 1 if Rx teardown is pending but incomplete, 0 otherwise. ++ - TcbPool: Pointer to transmit descriptor pool (per channel and queue). ++ - TxActQueueCount: Number of buffers currently queued to be transmitted (per channel and queue). ++ - TxActQueueHead: Pointer to first buffer in transmit queue (per channel and queue). ++ - TxActQueueTail: Pointer to last buffer in transmit queue (per channel and queue). ++ - TxActive: 0 if inactive (no buffers to send), or 1 if active (buffers queued to send). ++ - TcbStart: Pointer to block of transmit descriptors. ++ - TxTeardownPending: 1 if Tx teardown is pending but incomplete, 0 otherwise. ++- Level 3 Statistics (CPHAL Channel Configuration) ++ - RxBufSize: Rx buffer size. ++ - RxBufferOffset: Rx buffer offset. ++ - RxNumBuffers: Number of Rx buffers. ++ - RxServiceMax: Maximum number of receive packets to service at a time. ++ - TxNumBuffers: Number of Tx buffer descriptors. ++ - TxNumQueues: Number of Tx queues to use. ++ - TxServiceMax: Maximum number of transmit packets to service at a time. ++- Level 4 Statistics (CPHAL General Configuration) ++ - Base Address: Base address of the module. ++ - Offset (VLYNQ): VLYNQ relative module offset. ++ - Interrupt Line: Interrupt number. ++ - Debug: Debug flag, 1 to enable debug. ++ - Inst: Instance number. ++*/ ++ ++/* ++ Data Type 0 = int display ++ Data Type 1 = hex display ++ Data Type 2 = channel structure, int display ++ Data Type 3 = queue index and int display ++ Data Type 4 = queue index and hex display ++*/ ++#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) /* +GSG 030307 */ ++static STATS_TABLE StatsTable0[] = ++ { ++#ifdef _CPHAL_AAL5 ++ /* Name , Data Ptr, Data Type */ ++ {"Crc Errors", 0, 0}, ++ {"Len Errors", 0, 0}, ++ {"Abort Errors", 0, 0}, ++ {"Starv Errors", 0, 0} ++#endif ++#ifdef _CPHAL_CPMAC ++ {"Rx Good Frames", 0, 0} ++#endif ++ }; ++ ++static STATS_TABLE StatsTable1[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"DmaLenErrors", 0, 0}, ++ {"TxMisQCnt", 0, 3}, ++ {"RxMisQCnt", 0, 0}, ++ {"TxEOQCnt", 0, 3}, ++ {"RxEOQCnt", 0, 0}, ++ {"RxPacketsServiced", 0, 0}, ++ {"TxPacketsServiced", 0, 3}, ++ {"RxMaxServiced", 0, 0}, ++ {"TxMaxServiced", 0, 3}, ++ {"RxTotal", 0, 0}, ++ {"TxTotal", 0, 0}, ++ }; ++ ++static STATS_TABLE StatsTable2[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"RcbPool", 0, 1}, ++ {"RxActQueueCount", 0, 0}, ++ {"RxActQueueHead", 0, 1}, ++ {"RxActQueueTail", 0, 1}, ++ {"RxActive", 0, 0}, ++ {"RcbStart", 0, 1}, ++ {"RxTeardownPending", 0, 0}, ++ {"TcbPool", 0, 4}, ++ {"TxActQueueCount", 0, 3}, ++ {"TxActQueueHead", 0, 4}, ++ {"TxActQueueTail", 0, 4}, ++ {"TxActive", 0, 3}, ++ {"TcbStart", 0, 4}, ++ {"TxTeardownPending", 0, 0} ++ }; ++ ++static STATS_TABLE StatsTable3[] = ++ { ++ /* Name , Data Ptr, Data Type */ ++ {"RxBufSize", 0, 2}, ++ {"RxBufferOffset", 0, 2}, ++ {"RxNumBuffers", 0, 2}, ++ {"RxServiceMax", 0, 2}, ++ {"TxNumBuffers", 0, 2}, ++ {"TxNumQueues", 0, 2}, ++ {"TxServiceMax", 0, 2}, ++#ifdef _CPHAL_AAL5 ++ {"CpcsUU", 0, 2}, ++ {"Gfc", 0, 2}, ++ {"Clp", 0, 2}, ++ {"Pti", 0, 2}, ++ {"DaMask", 0, 2}, ++ {"Priority", 0, 2}, ++ {"PktType", 0, 2}, ++ {"Vci", 0, 2}, ++ {"Vpi", 0, 2}, ++ {"CellRate", 0, 2}, ++ {"QosType", 0, 2}, ++ {"Mbs", 0, 2}, ++ {"Pcr", 0, 2} ++#endif ++ }; ++ ++static STATS_TABLE StatsTable4[] = ++ { ++ {"Base Address", 0, 1}, ++ {"Offset (VLYNQ)", 0, 0}, ++ {"Interrupt Line", 0, 0}, ++ {"Debug", 0, 0}, ++ {"Instance", 0, 0}, ++#ifdef _CPHAL_AAL5 ++ {"UniNni", 0, 0} ++#endif ++ }; ++ ++static STATS_DB StatsDb[] = ++ { ++ {(sizeof(StatsTable0)/sizeof(STATS_TABLE)), StatsTable0}, ++ {(sizeof(StatsTable1)/sizeof(STATS_TABLE)), StatsTable1}, ++ {(sizeof(StatsTable2)/sizeof(STATS_TABLE)), StatsTable2}, ++ {(sizeof(StatsTable3)/sizeof(STATS_TABLE)), StatsTable3}, ++ {(sizeof(StatsTable4)/sizeof(STATS_TABLE)), StatsTable4} ++ }; ++#endif /* +GSG 030307 */ ++ ++#ifdef _CPHAL_CPMAC /* +RC 3.02 */ ++static void resetWait(HAL_DEVICE *HalDev) ++ { /*+RC3.02*/ ++ const int TickReset=64; ++ osfuncSleep((int*)&TickReset); ++ } /*+RC3.02*/ ++#endif /* +RC 3.02 */ ++ ++/* I only define the reset base function for the modules ++ that can perform a reset. The AAL5 and AAL2 modules ++ do not perform a reset, that is done by the shared module ++ CPSAR */ ++#if defined(_CPHAL_CPSAR) || defined(_CPHAL_CPMAC) || defined(_CPHAL_VDMAVT) ++/* ++ * Determines the reset register address to be used for a particular device. ++ * It will search the current device entry for Locator information. If the ++ * device is a root device, there will be no Locator information, and the ++ * function will find and return the root reset register. If a Locator value ++ * is found, the function will search each VLYNQ device entry in the system ++ * looking for a matching Locator. Once it finds a VLYNQ device entry with ++ * a matching Locator, it will extract the "ResetBase" parameter from that ++ * VLYNQ device entry (thus every VLYNQ entry must have the ResetBase parameter). ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param ResetBase Pointer to integer address of reset register. ++ * ++ * @return 0 OK, Non-zero not OK ++ */ ++static int ResetBaseGet(HAL_DEVICE *HalDev, bit32u *ResetBase) ++ { ++ char *DeviceInfo = HalDev->DeviceInfo; ++ char *MyLocator, *NextLocator; ++ int Inst=1; ++ bit32u error_code; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]ResetBaseGet(HalDev:%08x, ResetBase:%08x)\n", (bit32u)HalDev, ResetBase); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &MyLocator); ++ if (error_code) ++ { ++ /* if no Locator value, device is on the root, so get the "reset" device */ ++ error_code = HalDev->OsFunc->DeviceFindInfo(0, "reset", &DeviceInfo); ++ if (error_code) ++ { ++ return(EC_VAL_DEVICE_NOT_FOUND); ++ } ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "base", ResetBase); ++ if (error_code) ++ { ++ return(EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ ++ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); ++ ++ /* found base address for root device, so we're done */ ++ return (EC_NO_ERRORS); ++ } ++ else ++ { ++ /* we have a Locator value, so the device is remote */ ++ ++ /* Find a vlynq device with a matching locator value */ ++ while ((HalDev->OsFunc->DeviceFindInfo(Inst, "vlynq", &DeviceInfo)) == EC_NO_ERRORS) ++ { ++ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &NextLocator); ++ if (error_code) ++ { ++ /* no Locator value for this VLYNQ, so move on */ ++ continue; ++ } ++ if (HalDev->OsFunc->Strcmpi(MyLocator, NextLocator)==0) ++ { ++ /* we have found a VLYNQ with a matching Locator, so extract the ResetBase */ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "ResetBase", ResetBase); ++ if (error_code) ++ { ++ return(EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); ++ ++ /* found base address for root device, so we're done */ ++ return (EC_NO_ERRORS); ++ } ++ Inst++; ++ } /* while */ ++ } /* else */ ++ ++ return (EC_NO_ERRORS); ++ } ++#endif ++ ++#ifndef _CPHAL_AAL2 /* + RC 3.02 */ ++static bit32u ConfigGetCommon(HAL_DEVICE *HalDev) ++ { ++ bit32u ParmValue; ++ bit32 error_code; ++ char *DeviceInfo = HalDev->DeviceInfo; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]ConfigGetCommon(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszBase, &ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_BASE_ADDR_NOT_FOUND); ++ } ++ HalDev->dev_base = ((bit32u)PhysToVirtNoCache(ParmValue)); ++ ++#ifndef _CPHAL_AAL5 ++#ifndef _CPHAL_AAL2 ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszResetBit, &ParmValue); ++ if(error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BIT_NOT_FOUND); ++ } ++ HalDev->ResetBit = ParmValue; ++ ++ /* Get reset base address */ ++ error_code = ResetBaseGet(HalDev, &ParmValue); ++ if (error_code) ++ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BASE_NOT_FOUND); ++ HalDev->ResetBase = ParmValue; ++#endif ++#endif ++ ++#ifndef _CPHAL_CPSAR ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszIntLine,&ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_INTERRUPT_NOT_FOUND); ++ } ++ HalDev->interrupt = ParmValue; ++#endif ++ ++ /* only look for the offset if there is a Locator field, which indicates that ++ the module is a VLYNQ module */ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszLocator,&ParmValue); ++ if (!error_code) ++ { ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszOffset,&ParmValue); ++ if (error_code) ++ { ++ return(EC_FUNC_HAL_INIT|EC_VAL_OFFSET_NOT_FOUND); ++ } ++ HalDev->offset = ParmValue; ++ } ++ else ++ HalDev->offset = 0; ++ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszDebug, &ParmValue); ++ if (!error_code) HalDev->debug = ParmValue; ++ ++ return (EC_NO_ERRORS); ++ } ++#endif /* +RC 3.02 */ ++ ++#ifdef _CPHAL_CPMAC /* +RC 3.02 */ ++static void StatsInit(HAL_DEVICE *HalDev) /* +() RC3.02 */ ++ { ++ /* even though these statistics may be for multiple channels and ++ queues, i need only configure the pointer to the beginning ++ of the array, and I can index from there if necessary */ ++ ++#ifdef _CPHAL_AAL5 ++ StatsTable0[0].StatPtr = &HalDev->Stats.CrcErrors[0]; ++ StatsTable0[1].StatPtr = &HalDev->Stats.LenErrors[0]; ++ StatsTable0[2].StatPtr = &HalDev->Stats.AbortErrors[0]; ++ StatsTable0[3].StatPtr = &HalDev->Stats.StarvErrors[0]; ++ ++ StatsTable1[0].StatPtr = &HalDev->Stats.DmaLenErrors[0]; ++ StatsTable1[1].StatPtr = &HalDev->Stats.TxMisQCnt[0][0]; ++ StatsTable1[2].StatPtr = &HalDev->Stats.RxMisQCnt[0]; ++ StatsTable1[3].StatPtr = &HalDev->Stats.TxEOQCnt[0][0]; ++ StatsTable1[4].StatPtr = &HalDev->Stats.RxEOQCnt[0]; ++ StatsTable1[5].StatPtr = &HalDev->Stats.RxPacketsServiced[0]; ++ StatsTable1[6].StatPtr = &HalDev->Stats.TxPacketsServiced[0][0]; ++ StatsTable1[7].StatPtr = &HalDev->Stats.RxMaxServiced; ++ StatsTable1[8].StatPtr = &HalDev->Stats.TxMaxServiced[0][0]; ++ StatsTable1[9].StatPtr = &HalDev->Stats.RxTotal; ++ StatsTable1[10].StatPtr = &HalDev->Stats.TxTotal; ++#endif ++ ++#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) ++ StatsTable2[0].StatPtr = (bit32u *)&HalDev->RcbPool[0]; ++ StatsTable2[1].StatPtr = &HalDev->RxActQueueCount[0]; ++ StatsTable2[2].StatPtr = (bit32u *)&HalDev->RxActQueueHead[0]; ++ StatsTable2[3].StatPtr = (bit32u *)&HalDev->RxActQueueTail[0]; ++ StatsTable2[4].StatPtr = &HalDev->RxActive[0]; ++ StatsTable2[5].StatPtr = (bit32u *)&HalDev->RcbStart[0]; ++ StatsTable2[6].StatPtr = &HalDev->RxTeardownPending[0]; ++ StatsTable2[7].StatPtr = (bit32u *)&HalDev->TcbPool[0][0]; ++ StatsTable2[8].StatPtr = &HalDev->TxActQueueCount[0][0]; ++ StatsTable2[9].StatPtr = (bit32u *)&HalDev->TxActQueueHead[0][0]; ++ StatsTable2[10].StatPtr = (bit32u *)&HalDev->TxActQueueTail[0][0]; ++ StatsTable2[11].StatPtr = &HalDev->TxActive[0][0]; ++ StatsTable2[12].StatPtr = (bit32u *)&HalDev->TcbStart[0][0]; ++ StatsTable2[13].StatPtr = &HalDev->TxTeardownPending[0]; ++ ++ StatsTable3[0].StatPtr = &HalDev->ChData[0].RxBufSize; ++ StatsTable3[1].StatPtr = &HalDev->ChData[0].RxBufferOffset; ++ StatsTable3[2].StatPtr = &HalDev->ChData[0].RxNumBuffers; ++ StatsTable3[3].StatPtr = &HalDev->ChData[0].RxServiceMax; ++ StatsTable3[4].StatPtr = &HalDev->ChData[0].TxNumBuffers; ++ StatsTable3[5].StatPtr = &HalDev->ChData[0].TxNumQueues; ++ StatsTable3[6].StatPtr = &HalDev->ChData[0].TxServiceMax; ++#ifdef _CPHAL_AAL5 ++ StatsTable3[7].StatPtr = &HalDev->ChData[0].CpcsUU; ++ StatsTable3[8].StatPtr = &HalDev->ChData[0].Gfc; ++ StatsTable3[9].StatPtr = &HalDev->ChData[0].Clp; ++ StatsTable3[10].StatPtr = &HalDev->ChData[0].Pti; ++ StatsTable3[11].StatPtr = &HalDev->ChData[0].DaMask; ++ StatsTable3[12].StatPtr = &HalDev->ChData[0].Priority; ++ StatsTable3[13].StatPtr = &HalDev->ChData[0].PktType; ++ StatsTable3[14].StatPtr = &HalDev->ChData[0].Vci; ++ StatsTable3[15].StatPtr = &HalDev->ChData[0].Vpi; ++ StatsTable3[16].StatPtr = &HalDev->ChData[0].TxVc_CellRate; ++ StatsTable3[17].StatPtr = &HalDev->ChData[0].TxVc_QosType; ++ StatsTable3[18].StatPtr = &HalDev->ChData[0].TxVc_Mbs; ++ StatsTable3[19].StatPtr = &HalDev->ChData[0].TxVc_Pcr; ++#endif ++#endif ++ ++ StatsTable4[0].StatPtr = &HalDev->dev_base; ++ StatsTable4[1].StatPtr = &HalDev->offset; ++ StatsTable4[2].StatPtr = &HalDev->interrupt; ++ StatsTable4[3].StatPtr = &HalDev->debug; ++ StatsTable4[4].StatPtr = &HalDev->Inst; ++ } ++#endif /* +RC 3.02 */ ++ ++#ifndef _CPHAL_CPSAR /* +RC 3.02 */ ++#ifndef _CPHAL_AAL2 /* +RC 3.02 */ ++/* ++ * Returns statistics information. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return 0 ++ */ ++static int StatsGet(HAL_DEVICE *HalDev, void **StatPtr, int Index, int Ch, int Queue) ++ { ++ int Size; ++ bit32u *AddrPtr; ++ char *DataPtr; ++ STATS_TABLE *StatsTable; ++ int i, NumberOfStats; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpcommon]StatsGet(HalDev:%08x, StatPtr:%08x)\n", ++ (bit32u)HalDev, (bit32u)StatPtr); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ StatsTable = StatsDb[Index].StatTable; ++ NumberOfStats = StatsDb[Index].NumberOfStats; ++ ++ Size = sizeof(bit32u)*((NumberOfStats*2)+1); ++ Size += (NumberOfStats*11); ++ *StatPtr = (bit32u *)HalDev->OsFunc->Malloc(Size); ++ ++ AddrPtr = (bit32u *) *StatPtr; ++ DataPtr = (char *)AddrPtr; ++ DataPtr += sizeof(bit32u)*((NumberOfStats*2)+1); ++ ++ for (i=0; iOsFunc->Sprintf(DataPtr, "%d", (bit32u *)StatsTable[i].StatPtr[Ch]); ++ break; ++ case 1: ++ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", (bit32u *)StatsTable[i].StatPtr[Ch]); ++ break; ++ case 2: ++ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch * (sizeof(CHANNEL_INFO)/4)))); ++ break; ++ case 3: ++ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); ++ break; ++ case 4: ++ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); ++ break; ++ default: ++ /* invalid data type, due to CPHAL programming error */ ++ break; ++ } ++ } ++ else ++ { ++ /* invalid statistics pointer, probably was not initialized */ ++ } ++ DataPtr += HalDev->OsFunc->Strlen(DataPtr) + 1; ++ } ++ ++ *AddrPtr = (bit32u) 0; ++ ++ return (EC_NO_ERRORS); ++ } ++#endif /* +RC 3.02 */ ++#endif /* +RC 3.02 */ ++ ++#ifdef _CPHAL_CPMAC ++static void gpioFunctional(int base, int bit) ++ { /*+RC3.02*/ ++ bit32u GpioEnr = base + 0xC; ++ /* To make functional, set to zero */ ++ *(volatile bit32u *)(GpioEnr) &= ~(1 << bit); /*+RC3.02*/ ++ } /*+RC3.02*/ ++ ++ ++/*+RC3.02*/ ++/* Common function, Checks to see if GPIO should be in functional mode */ ++static void gpioCheck(HAL_DEVICE *HalDev, void *moduleDeviceInfo) ++ { /*+RC3.02*/ ++ int rc; ++ void *DeviceInfo; ++ char *pszMuxBits; ++ char pszMuxBit[20]; ++ char *pszTmp; ++ char szMuxBit[20]; ++ char *ptr; ++ int base; ++ int reset_bit; ++ int bit; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ ++ rc = OsFunc->DeviceFindParmValue(moduleDeviceInfo, "gpio_mux",&pszTmp); ++ if(rc) return; ++ /* gpio entry found, get GPIO register info and make functional */ ++ ++ /* temp copy until FinParmValue fixed */ ++ ptr = &szMuxBit[0]; ++ while ((*ptr++ = *pszTmp++)); ++ ++ pszMuxBits = &szMuxBit[0]; ++ ++ rc = OsFunc->DeviceFindInfo(0,"gpio",&DeviceInfo); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",&base); ++ if(rc) return; ++ ++ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit); ++ if(rc) return; ++ ++ /* If GPIO still in reset, then exit */ ++ if((VOLATILE32(HalDev->ResetBase) & (1 << reset_bit)) == 0) ++ return; ++ /* format for gpio_mux is gpio_mux = ;;...*/ ++ while (*pszMuxBits) ++ { ++ pszTmp = &pszMuxBit[0]; ++ if(*pszMuxBits == ';') pszMuxBits++; ++ while ((*pszMuxBits != ';') && (*pszMuxBits != '\0')) ++ { ++ osfuncSioFlush(); ++ /*If value not a number, skip */ ++ if((*pszMuxBits < '0') || (*pszMuxBits > '9')) ++ pszMuxBits++; ++ else ++ *pszTmp++ = *pszMuxBits++; ++ } ++ *pszTmp = '\0'; ++ bit = OsFunc->Strtoul(pszMuxBit, &pszTmp, 10); ++ gpioFunctional(base, bit); ++ resetWait(HalDev); /* not sure if this is needed */ ++ } ++ } /*+RC3.02*/ ++#endif /* CPMAC */ ++ ++#ifdef _CPHAL_AAL5 ++const char hcSarFrequency[] = "SarFreq"; ++#endif ++ ++#endif /* _INC */ +diff -urN linux.old/drivers/atm/sangam_atm/cpcommon_cpsar.h linux.dev/drivers/atm/sangam_atm/cpcommon_cpsar.h +--- linux.old/drivers/atm/sangam_atm/cpcommon_cpsar.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpcommon_cpsar.h 2005-08-23 04:46:50.083845824 +0200 +@@ -0,0 +1,79 @@ ++#ifndef _INC_CPCOMMON_H ++#define _INC_CPCOMMON_H ++ ++#define VOLATILE32(addr) (*(volatile bit32u *)(addr)) ++#ifndef dbgPrintf ++#define dbgPrintf HalDev->OsFunc->Printf ++#endif ++ ++#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field ++ ++#define DBG(level) (HalDev->debug & (1<<(level))) ++/* ++#define DBG0() DBG(0) ++#define DBG1() DBG(1) ++#define DBG2() DBG(2) ++#define DBG3() DBG(3) ++#define DBG4() DBG(4) ++#define DBG5() DBG(5) ++#define DBG6() DBG(6) ++#define DBG7() DBG(7) ++*/ ++ ++/* ++ * List of defined actions for use with Control(). ++ */ ++typedef enum ++ { ++ enGET=0, /**< Get the value associated with a key */ ++ enSET, /**< Set the value associates with a key */ ++ enCLEAR, /**OsFunc->Control(HalDev->OsDev,"SioFlush",pszNULL,0) ++#define osfuncSleep(Ticks) HalDev->OsFunc->Control(HalDev->OsDev,pszSleep,pszNULL,Ticks) ++#define osfuncStateChange() HalDev->OsFunc->Control(HalDev->OsDev,pszStateChange,pszNULL,0) ++ ++#define CHANNEL_NAMES {"Ch0","Ch1","Ch2","Ch3","Ch4","Ch5","Ch6","Ch7","Ch8","Ch9","Ch10","Ch11","Ch12","Ch13","Ch14","Ch15"} ++ ++#endif ++ +diff -urN linux.old/drivers/atm/sangam_atm/cppi_cpaal5.c linux.dev/drivers/atm/sangam_atm/cppi_cpaal5.c +--- linux.old/drivers/atm/sangam_atm/cppi_cpaal5.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cppi_cpaal5.c 2005-08-23 04:46:50.084845672 +0200 +@@ -0,0 +1,1483 @@ ++/************************************************************************* ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002,2003 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: cppi.c ++ * ++ * DESCRIPTION: ++ * This file contains shared code for all CPPI modules. ++ * ++ * HISTORY: ++ * 7Aug02 Greg RC1.00 Original Version created. ++ * 27Sep02 Mick RC1.01 Merged for use by CPMAC/CPSAR ++ * 16Oct02 Mick RC1.02 Performance Tweaks (see cppihist.txt) ++ * 12Nov02 Mick RC1.02 Updated to use cpmac_reg.h ++ * 09Jan03 Mick RC3.01 Removed modification to RxBuffer ptr ++ * 28Mar03 Mick 1.03 RxReturn now returns error if Malloc Fails ++ * 10Apr03 Mick 1.03.02 Added Needs Buffer Support ++ * 11Jun03 Mick 1.06.02 halSend() errors corrected ++ * ++ * @author Greg Guyotte ++ * @version 1.00 ++ * @date 7-Aug-2002 ++ *****************************************************************************/ ++/* each CPPI module must modify this file, the rest of the ++ code in cppi.c should be totally shared *//* Each CPPI module MUST properly define all constants shown below */ ++ ++/* CPPI registers */ ++ ++/* the following defines are not CPPI specific, but still used by cppi.c */ ++ ++static void FreeRx(HAL_DEVICE *HalDev, int Ch) ++ { ++ HAL_RCB *rcb_ptr; /*+GSG 030303*/ ++ int rcbSize = (sizeof(HAL_RCB)+0xf)&~0xf; /*+GSG 030303*/ ++ int Num = HalDev->ChData[Ch].RxNumBuffers, i; /*+GSG 030303*/ ++ ++ /* Free Rx data buffers attached to descriptors, if necessary */ ++ if (HalDev->RcbStart[Ch] != 0) /*+GSG 030303*/ ++ { /*+GSG 030303*/ ++ for(i=0;iRcbStart[Ch] + (i*rcbSize)); /*+GSG 030303*/ ++ ++ /* free the data buffer */ ++ if (rcb_ptr->DatPtr != 0) ++ { ++ ++ HalDev->OsFunc->FreeRxBuffer((void *)rcb_ptr->OsInfo, (void *)rcb_ptr->DatPtr); ++ rcb_ptr->OsInfo=0; /*MJH+030522*/ ++ rcb_ptr->DatPtr=0; /*MJH+030522*/ ++ } ++ } /*+GSG 030303*/ ++ } /*+GSG 030303*/ ++ ++ /* free up all desciptors at once */ ++ HalDev->OsFunc->FreeDmaXfer(HalDev->RcbStart[Ch]); ++ ++ /* mark buffers as freed */ ++ HalDev->RcbStart[Ch] = 0; ++ } ++ ++static void FreeTx(HAL_DEVICE *HalDev, int Ch, int Queue) ++ { ++ ++/*+GSG 030303*/ ++ ++ /* free all descriptors at once */ ++ HalDev->OsFunc->FreeDmaXfer(HalDev->TcbStart[Ch][Queue]); ++ ++ HalDev->TcbStart[Ch][Queue] = 0; ++ } ++ ++/* return of 0 means that this code executed, -1 means the interrupt was not ++ a teardown interrupt */ ++static int RxTeardownInt(HAL_DEVICE *HalDev, int Ch) ++ { ++ bit32u base = HalDev->dev_base; ++ ++ int i; ++ volatile bit32u *pTmp; ++ ++ /* check to see if the interrupt is a teardown interrupt */ ++ if (((*(pRX_CPPI_COMP_PTR( base )+( Ch *64))) & TEARDOWN_VAL) == TEARDOWN_VAL) ++ { ++ /* finish channel teardown */ ++ ++ /* Free channel resources on a FULL teardown */ ++ if (HalDev->RxTeardownPending[Ch] & FULL_TEARDOWN) ++ { ++ FreeRx(HalDev, Ch); ++ } ++ ++ /* bug fix - clear Rx channel pointers on teardown */ ++ HalDev->RcbPool[Ch] = 0; ++ HalDev->RxActQueueHead[Ch] = 0; ++ HalDev->RxActQueueCount[Ch] = 0; ++ HalDev->RxActive[Ch] = FALSE; ++ ++ /* write completion pointer */ ++ (*(pRX_CPPI_COMP_PTR( base )+( Ch *64))) = TEARDOWN_VAL; ++ ++ /* use direction bit as a teardown pending bit! May be able to ++ use only one teardown pending integer in HalDev */ ++ ++ HalDev->RxTeardownPending[Ch] &= ~RX_TEARDOWN; ++ ++ HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0; ++ ++ /* call OS Teardown Complete (if TX is also done) */ ++ if ((HalDev->TxTeardownPending[Ch] & TX_TEARDOWN) == 0) ++ { ++ /* mark channel as closed */ ++ HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0; ++ ++ /* disable channel interrupt */ ++ SAR_TX_MASK_CLR(HalDev->dev_base) = (1<dev_base) = (1<<(Ch+16)); /* +GSG 030307 */ ++ SAR_RX_MASK_CLR(HalDev->dev_base) = (1<dev_base)+(Ch*64)); ++ for (i=0; iRxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0) ++ { ++ ++ HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_TX|DIRECTION_RX); ++ } ++ /* clear all teardown pending information for this channel */ ++ HalDev->RxTeardownPending[Ch] = 0; ++ HalDev->TxTeardownPending[Ch] = 0; ++ } ++ ++ return (EC_NO_ERRORS); ++ } ++ return (-1); ++ } ++ ++/* return of 0 means that this code executed, -1 means the interrupt was not ++ a teardown interrupt */ ++static int TxTeardownInt(HAL_DEVICE *HalDev, int Ch, int Queue) ++ { ++ bit32u base = HalDev->dev_base; ++ HAL_TCB *Last, *Curr, *First; /*+GSG 030303*/ ++ ++ int i; ++ volatile bit32u *pTmp; ++ ++ if (((*(pTXH_CPPI_COMP_PTR( base )+( Ch *64)+( Queue ))) & TEARDOWN_VAL) == TEARDOWN_VAL) ++ { ++ /* return outstanding buffers to OS +RC3.02*/ ++ Curr = HalDev->TxActQueueHead[Ch][Queue]; /*+GSG 030303*/ ++ First = Curr; /*+GSG 030303*/ ++ while (Curr) /*+GSG 030303*/ ++ { /*+GSG 030303*/ ++ /* Pop TCB(s) for packet from the stack */ /*+GSG 030303*/ ++ Last = Curr->Eop; /*+GSG 030303*/ ++ HalDev->TxActQueueHead[Ch][Queue] = Last->Next; /*+GSG 030303*/ ++ /*+GSG 030303*/ ++ /* return to OS */ /*+GSG 030303*/ ++ HalDev->OsFunc->SendComplete(Curr->OsInfo); /*+GSG 030303*/ ++ /*+GSG 030303*/ ++ /* Push Tcb(s) back onto the stack */ /*+GSG 030303*/ ++ Curr = Last->Next; /*+GSG 030303*/ ++ Last->Next = HalDev->TcbPool[Ch][Queue]; /*+GSG 030303*/ ++ HalDev->TcbPool[Ch][Queue] = First; /*+GSG 030303*/ ++ /*+GSG 030303*/ ++ /* set the first(SOP) pointer for the next packet */ /*+GSG 030303*/ ++ First = Curr; /*+GSG 030303*/ ++ } /*+GSG 030303*/ ++ ++ /* finish channel teardown */ ++ ++ /* save the OsInfo to pass to upper layer ++ THIS WAS CRASHING - because it's possible that I get the teardown ++ notification and the TcbHPool is null. In this case, the buffers ++ to free can be found in the TxHActiveQueue. If I need to get OsInfo ++ in the future, I can get it from one of those buffers. ++ OsInfo = HalDev->TcbHPool[Ch]->OsInfo; */ ++ ++ if (HalDev->TxTeardownPending[Ch] & FULL_TEARDOWN) ++ { ++ FreeTx(HalDev, Ch, Queue); ++ } /* if FULL teardown */ ++ ++ /* bug fix - clear Tx channel pointers on teardown */ ++ HalDev->TcbPool[Ch][Queue] = 0; ++ HalDev->TxActQueueHead[Ch][Queue] = 0; ++ HalDev->TxActQueueCount[Ch][Queue] = 0; ++ HalDev->TxActive[Ch][Queue] = FALSE; ++ ++ /* write completion pointer */ ++ (*(pTXH_CPPI_COMP_PTR( base )+( Ch *64)+( Queue ))) = TEARDOWN_VAL; ++ ++ /* no longer pending teardown */ ++ HalDev->TxTeardownPending[Ch] &= ~TX_TEARDOWN; ++ ++ HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0; ++ ++ /* call OS Teardown Complete (if Rx is also done) */ ++ if ((HalDev->RxTeardownPending[Ch] & RX_TEARDOWN) == 0) ++ { ++ /* mark channel as closed */ ++ HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0; ++ ++ /* disable channel interrupt */ ++ SAR_TX_MASK_CLR(HalDev->dev_base) = (1<dev_base) = (1<<(Ch+16)); /* +GSG 030307 */ ++ SAR_RX_MASK_CLR(HalDev->dev_base) = (1<dev_base)+(Ch*64)); ++ for (i=0; iTxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0) ++ { ++ ++ HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_TX|DIRECTION_RX); ++ } ++ ++ /* clear all teardown pending information for this channel */ ++ HalDev->RxTeardownPending[Ch] = 0; ++ HalDev->TxTeardownPending[Ch] = 0; ++ } ++ ++ return (EC_NO_ERRORS); ++ } ++ return (-1); ++ } ++ ++/* +GSG 030421 */ ++static void AddToRxQueue(HAL_DEVICE *HalDev, HAL_RCB *FirstRcb, HAL_RCB *LastRcb, int FragCount, int Ch) ++ { ++ HAL_RCB *OldTailRcb; ++ ++ if (HalDev->RxActQueueCount[Ch]==0) ++ { ++ ++ HalDev->RxActQueueHead[Ch]=FirstRcb; ++ HalDev->RxActQueueTail[Ch]=LastRcb; ++ HalDev->RxActQueueCount[Ch]=FragCount; ++ if ((!HalDev->InRxInt[Ch])&&(!HalDev->RxActive[Ch])) ++ { ++ /* write Rx Queue Head Descriptor Pointer */ ++ (*(pRX_DMA_STATE_WORD_1( HalDev->dev_base )+( Ch *64))) = VirtToPhys(FirstRcb) - HalDev->offset; ++ HalDev->RxActive[Ch]=TRUE; ++ } ++ } ++ else ++ { ++ ++ OldTailRcb=HalDev->RxActQueueTail[Ch]; ++ OldTailRcb->Next=(void *)FirstRcb; ++ ++ /* Emerald fix 10/29 (Denis) */ ++ *((bit32u *) VirtToVirtNoCache(&OldTailRcb->HNext))=VirtToPhys(FirstRcb) - HalDev->offset; ++ ++ HalDev->RxActQueueTail[Ch]=LastRcb; ++ HalDev->RxActQueueCount[Ch]+=FragCount; ++ } ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function is called to indicate to the CPHAL that the upper layer ++ * software has finished processing the receive data (given to it by ++ * osReceive()). The CPHAL will then return the appropriate receive buffers ++ * and buffer descriptors to the available pool. ++ * ++ * @param HalReceiveInfo Start of receive buffer descriptor chain returned to ++ * CPHAL. ++ * @param StripFlag Flag indicating whether the upper layer software has ++ * retained ownership of the receive data buffers. ++ *
++ * 'FALSE' means that the CPHAL can reuse the receive data buffers. ++ *
++ * 'TRUE' : indicates the data buffers were retained by the OS ++ *
++ * NOTE: If StripFlag is TRUE, it is the responsibility of the upper layer software to free the buffers when they are no longer needed. ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_RCB_NEEDS_BUFFER "EC_VAL_RCB_NEEDS_BUFFER"
++ * @ref EC_VAL_RCB_DROPPED "EC_VAL_RCB_DROPPED"
++ */ ++static int halRxReturn(HAL_RECEIVEINFO *HalReceiveInfo, ++ int StripFlag) ++ { ++ int Ch = HalReceiveInfo->Ch, i; ++ HAL_RCB *LastRcb, *TempRcb; ++ char *pBuf; ++ HAL_RCB *CurrHeadRcb = HalReceiveInfo, *LastGoodRcb=0; /* +GSG 030421 */ ++ HAL_DEVICE *HalDev = HalReceiveInfo->HalDev; ++ int RcbSize = HalDev->ChData[Ch].RxBufSize; ++ int FragCount = HalReceiveInfo->FragCount; ++ int rc=0; /*MJH+030417*/ ++ int GoodCount=0; /*GSG+030421*/ ++ ++ if (HalDev->State != enOpened) ++ return(EC_AAL5 |EC_FUNC_RXRETURN|EC_VAL_INVALID_STATE); ++ ++ LastRcb=(HAL_RCB *)HalReceiveInfo->Eop; ++ LastRcb->HNext=0; ++ LastRcb->Next=0; ++ ++ if (FragCount>1) ++ { ++ LastRcb->Off_BLen=RcbSize; ++ LastRcb->mode=CB_OWNERSHIP_BIT; ++ } ++ ++ HalReceiveInfo->Off_BLen=RcbSize; ++ HalReceiveInfo->mode=CB_OWNERSHIP_BIT; ++ ++ /* If OS has kept the buffers for this packet, attempt to alloc new buffers */ ++ if (StripFlag) ++ { ++ TempRcb = HalReceiveInfo; ++ for (i=0; iEop = %08x, FragCount = %d:%d\n", ++ (bit32u)HalReceiveInfo, (bit32u)HalReceiveInfo->Eop, FragCount,i); ++ osfuncSioFlush(); ++ ++ return(EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_CORRUPT_RCB_CHAIN); ++ } ++ ++ /* size = ((RcbSize+15) & ~15) + 15;*/ /*-3.01b*/ ++ /*size = RcbSize + 15;*/ /* -GSG 030421 */ ++ pBuf= (char *) HalDev->OsFunc->MallocRxBuffer(RcbSize,0, ++ 0xF,HalDev->ChData[Ch].OsSetup, ++ (void *)TempRcb, ++ (void *)&TempRcb->OsInfo, ++ (void *) HalDev->OsDev); ++ if (!pBuf) ++ { ++ /* malloc failed, add this RCB to Needs Buffer List */ ++ TempRcb->FragCount = 1; /*MJH+030417*/ ++ (HAL_RCB *)TempRcb->Eop = TempRcb; /* GSG +030430 */ ++ ++ if(HalDev->NeedsCount < MAX_NEEDS) /* +MJH 030410 */ ++ { /* +MJH 030410 */ ++ HalDev->Needs[HalDev->NeedsCount] = (HAL_RECEIVEINFO *) TempRcb; /* +MJH 030410 */ ++ HalDev->NeedsCount++; /* +MJH 030410 */ ++ rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_NEEDS_BUFFER); /* ~MJH 030417 */ ++ } /* +MJH 030410 */ ++ else /* +MJH 030410 */ ++ rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_DROPPED); /* ~MJH 030417 */ ++ ++ /* requeue any previous RCB's that were ready to go before this one */ ++ if (GoodCount > 0) /* +GSG 030421 */ ++ { /* +GSG 030421 */ ++ LastGoodRcb->HNext=0; /* +GSG 030430 */ ++ LastGoodRcb->Next=0; /* +GSG 030430 */ ++ osfuncDataCacheHitWriteback((void *)LastGoodRcb, 16); /* +GSG 030430 */ ++ ++ AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch); /* +GSG 030421 */ ++ GoodCount = 0; /* +GSG 030421 */ ++ } /* +GSG 030421 */ ++ ++ CurrHeadRcb = TempRcb->Next; /* +GSG 030421 */ ++ } ++ else /* +GSG 030421 */ ++ { /* +GSG 030421 */ ++ /* malloc succeeded, requeue the RCB to the hardware */ ++ TempRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset; ++ TempRcb->DatPtr=pBuf; ++ /* Emerald fix 10/29 */ ++ osfuncDataCacheHitWriteback((void *)TempRcb, 16); ++ ++ /* i store the last good RCB in case the malloc fails for the ++ next fragment. This ensures that I can go ahead and return ++ a partial chain of RCB's to the hardware */ ++ LastGoodRcb = TempRcb; /* +GSG 030421 */ ++ GoodCount++; /* +GSG 030421 */ ++ } /* +GSG 030421 */ ++ TempRcb = TempRcb->Next; ++ } /* end of Frag loop */ ++ /* if there any good RCB's to requeue, do so here */ ++ if (GoodCount > 0) /* +GSG 030421 */ ++ { ++ AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch); /* +GSG 030421 */ ++ } ++ return(rc); /* ~GSG 030421 */ ++ } ++ else ++ { ++ /* Not Stripping */ ++ /* Emerald */ ++ /* Write Back SOP and last RCB */ ++ osfuncDataCacheHitWriteback((void *)HalReceiveInfo, 16); ++ ++ if (FragCount > 1) ++ { ++ osfuncDataCacheHitWriteback((void *)LastRcb, 16); ++ } ++ /* if not stripping buffers, always add to queue */ ++ AddToRxQueue(HalDev, HalReceiveInfo, LastRcb, FragCount, Ch); /*MJH~030520*/ ++ } ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/* +MJH 030410 ++ Trys to liberate an RCB until liberation fails. ++ Note: If liberation fails then RxReturn will re-add the RCB to the ++ Needs list. ++*/ ++static void NeedsCheck(HAL_DEVICE *HalDev) ++{ ++ HAL_RECEIVEINFO* HalRcb; ++ int rc; ++ HalDev->OsFunc->CriticalOn(); ++ while(HalDev->NeedsCount) ++ { ++ HalDev->NeedsCount--; ++ HalRcb = HalDev->Needs[HalDev->NeedsCount]; ++ rc = halRxReturn(HalRcb, 1); ++ /* short circuit if RxReturn starts to fail */ ++ if (rc != 0) ++ break; ++ } ++ HalDev->OsFunc->CriticalOff(); ++} ++ ++/* ++ * This function allocates transmit buffer descriptors (internal CPHAL function). ++ * It creates a high priority transmit queue by default for a single Tx ++ * channel. If QoS is enabled for the given CPHAL device, this function ++ * will also allocate a low priority transmit queue. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Ch Channel number. ++ * ++ * @return 0 OK, Non-Zero Not OK ++ */ ++static int InitTcb(HAL_DEVICE *HalDev, int Ch) ++ { ++ int i, Num = HalDev->ChData[Ch].TxNumBuffers; ++ HAL_TCB *pTcb=0; ++ char *AllTcb; ++ int tcbSize, Queue; ++ int SizeMalloc; ++ ++ tcbSize = (sizeof(HAL_TCB)+0xf)&~0xf; ++ SizeMalloc = (tcbSize*Num)+0xf; ++ ++ for (Queue=0; Queue < HalDev->ChData[Ch].TxNumQueues; Queue++) ++ { ++ if (HalDev->TcbStart[Ch][Queue] == 0) ++ { ++ ++ /* malloc all TCBs at once */ ++ AllTcb = (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff); ++ if (!AllTcb) ++ { ++ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_TCB_MALLOC_FAILED); ++ } ++ ++ HalDev->OsFunc->Memset(AllTcb, 0, SizeMalloc); ++ ++ /* keep this address for freeing later */ ++ HalDev->TcbStart[Ch][Queue] = AllTcb; ++ } ++ else ++ { ++ /* if the memory has already been allocated, simply reuse it! */ ++ AllTcb = HalDev->TcbStart[Ch][Queue]; ++ } ++ ++ /* align to cache line */ ++ AllTcb = (char *)(((bit32u)AllTcb + 0xf) &~ 0xf); /*PITS #143 MJH~030522*/ ++ ++ /* default High priority transmit queue */ ++ HalDev->TcbPool[Ch][Queue]=0; ++ for(i=0;iMallocDmaXfer(sizeof(HAL_TCB),0,0xffffffff); */ ++ pTcb= (HAL_TCB *)(AllTcb + (i*tcbSize)); ++ pTcb->mode=0; ++ pTcb->BufPtr=0; ++ pTcb->Next=HalDev->TcbPool[Ch][Queue]; ++ pTcb->Off_BLen=0; ++ HalDev->TcbPool[Ch][Queue]=pTcb; ++ } ++ /*HalDev->TcbEnd = pTcb;*/ ++ } ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/* ++ * This function allocates receive buffer descriptors (internal CPHAL function). ++ * After allocation, the function 'queues' (gives to the hardware) the newly ++ * created receive buffers to enable packet reception. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Ch Channel number. ++ * ++ * @return 0 OK, Non-Zero Not OK ++ */ ++static int InitRcb(HAL_DEVICE *HalDev, int Ch) ++ { ++ int i, Num = HalDev->ChData[Ch].RxNumBuffers; ++ int Size = HalDev->ChData[Ch].RxBufSize; ++ HAL_RCB *pRcb; ++ char *pBuf; ++ char *AllRcb; ++ int rcbSize; ++ int DoMalloc = 0; ++ int SizeMalloc; ++ int MallocSize; ++ ++ rcbSize = (sizeof(HAL_RCB)+0xf)&~0xf; ++ SizeMalloc = (rcbSize*Num)+0xf; ++ ++ if (HalDev->RcbStart[Ch] == 0) ++ { ++ DoMalloc = 1; ++ ++ /* malloc all RCBs at once */ ++ AllRcb= (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff); ++ if (!AllRcb) ++ { ++ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RCB_MALLOC_FAILED); ++ } ++ ++ HalDev->OsFunc->Memset(AllRcb, 0, SizeMalloc); ++ ++ /* keep this address for freeing later */ ++ HalDev->RcbStart[Ch] = AllRcb; ++ } ++ else ++ { ++ /* if the memory has already been allocated, simply reuse it! */ ++ AllRcb = HalDev->RcbStart[Ch]; ++ } ++ ++ /* align to cache line */ ++ AllRcb = (char *)(((bit32u)AllRcb + 0xf)&~0xf); /*PITS #143 MJH~030522*/ ++ ++ HalDev->RcbPool[Ch]=0; ++ for(i=0;iOsFunc->MallocRxBuffer(MallocSize,0,0xF,HalDev->ChData[Ch].OsSetup, (void *)pRcb, (void *)&pRcb->OsInfo, (void *) HalDev->OsDev); ++ if(!pBuf) ++ { ++ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RX_BUFFER_MALLOC_FAILED); ++ } ++ /* -RC3.01 pBuf = (char *)(((bit32u)pBuf+0xF) & ~0xF); */ ++ pRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset; ++ pRcb->DatPtr=pBuf; ++ /*pRcb->BufSize=Size;*/ ++ } ++ pRcb->mode=0; ++ pRcb->Ch=Ch; ++ pRcb->Next=(void *)HalDev->RcbPool[Ch]; ++ pRcb->Off_BLen=0; ++ pRcb->HalDev = HalDev; ++ HalDev->RcbPool[Ch]=pRcb; ++ } ++ ++ /* Give all of the Rx buffers to hardware */ ++ ++ while(HalDev->RcbPool[Ch]) ++ { ++ pRcb=HalDev->RcbPool[Ch]; ++ HalDev->RcbPool[Ch]=pRcb->Next; ++ pRcb->Eop=(void*)pRcb; ++ pRcb->FragCount=1; ++ halRxReturn((HAL_RECEIVEINFO *)pRcb, 0); ++ } ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function transmits the data in FragList using available transmit ++ * buffer descriptors. More information on the use of the Mode parameter ++ * is available in the module-specific appendices. Note: The OS should ++ * not call Send() for a channel that has been requested to be torndown. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param FragList Fragment List structure. ++ * @param FragCount Number of fragments in FragList. ++ * @param PacketSize Number of bytes to transmit. ++ * @param OsSendInfo OS Send Information structure.
++ * @param Mode 32-bit value with the following bit fields:
++ * 31-16: Mode (used for module specific data).
++ * 15-08: Queue (transmit queue to send on).
++ * 07-00: Channel (channel number to send on). ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_NOT_LINKED "EC_VAL_NOT_LINKED"
++ * @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"
++ * @ref EC_VAL_OUT_OF_TCBS "EC_VAL_OUT_OF_TCBS"
++ * @ref EC_VAL_NO_TCBS "EC_VAL_NO_TCBS"
++ */ ++static int halSend(HAL_DEVICE *HalDev,FRAGLIST *FragList, ++ int FragCount,int PacketSize, OS_SENDINFO *OsSendInfo, ++ bit32u Mode) ++ { ++ HAL_TCB *tcb_ptr, *head; ++ int i; ++ bit32u base = HalDev->dev_base; ++ int rc = EC_NO_ERRORS; ++ int Ch = Mode & 0xFF; ++ int Queue = (Mode>>8)&0xFF; ++ ++ int WaitFlag = (Mode>>30)&1; /* This is for AAL5 testing only */ /* ~GSG 030508 */ ++ int Offset = (FragList[0].len >> 16); ++ int PktType = (Mode>>16)&3; /* 0=AAL5, 1=Null AAL, 2=OAM, 3=Transparent */ /* +GSG 030508 */ ++ int AtmHeaderInData = (Mode>>31)&1; /* +GSG 030508 */ ++ int FragIndex = 0; ++ ++ if (HalDev->State != enOpened) ++ return(EC_CPPI|EC_FUNC_SEND|EC_VAL_INVALID_STATE); ++ ++ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0) /*MJH~030611*/ /*PITS 148*/ ++ return(EC_AAL5 |EC_FUNC_SEND|EC_VAL_INVALID_CH); /*+GSG 030303*/ ++ ++ HalDev->OsFunc->CriticalOn(); ++ ++ tcb_ptr = head = HalDev->TcbPool[Ch][Queue]; ++ ++ if (tcb_ptr) ++ { ++ ++ /* these two TCB words are only valid on SOP */ ++ if (AtmHeaderInData == 1) ++ { ++ tcb_ptr->AtmHeader = 0; /* bug fix for transparent mode PTI problem */ ++ /* Expect AtmHeader in the data */ ++ tcb_ptr->AtmHeader |= *((bit8u *)FragList[FragIndex].data++) << 24; ++ tcb_ptr->AtmHeader |= *((bit8u *)FragList[FragIndex].data++) << 16; ++ tcb_ptr->AtmHeader |= *((bit8u *)FragList[FragIndex].data++) << 8; ++ tcb_ptr->AtmHeader |= *((bit8u *)FragList[FragIndex].data++); ++ ++ /* decrement data buffer length accordingly */ ++ FragList[FragIndex].len -= ATM_HEADER_SIZE; ++ ++ /* if the first fragment was ATM Header only, go to next fragment for loop */ ++ if (FragList[FragIndex].len == 0) ++ FragIndex++; ++ ++ /* No CPCS_UU/CPI if not AAL5 */ ++ tcb_ptr->Word5 = ((PktType & 0x3)<<16); ++ } ++ else ++ { ++ /* calculate AtmHeader from fields */ ++ tcb_ptr->AtmHeader = atmheader(HalDev->ChData[Ch].Gfc, /* ~GSG 030306 */ ++ HalDev->ChData[Ch].Vpi, HalDev->ChData[Ch].Vci, ++ HalDev->ChData[Ch].Pti, HalDev->ChData[Ch].Clp); ++ ++ tcb_ptr->Word5 = HalDev->ChData[Ch].CpcsUU | ((HalDev->ChData[Ch].PktType &0x3)<<16); ++ } ++ ++ for (i=FragIndex; iHNext = VirtToPhys((bit32 *)tcb_ptr->Next) - HalDev->offset; ++ tcb_ptr->Off_BLen = FragList[i].len; ++ ++ if (i==0) ++ tcb_ptr->Off_BLen |= (Offset << 16); ++ ++ tcb_ptr->mode = 0; /* MUST clear this for each frag !!! */ ++ tcb_ptr->BufPtr = VirtToPhys((bit32 *)FragList[i].data) - ++ HalDev->offset; ++ ++ /* first fragment */ ++ if (i == 0) ++ { ++ tcb_ptr->mode |= CB_SOF_BIT; ++ ++ } ++ ++ tcb_ptr->mode |= (PacketSize | CB_OWNERSHIP_BIT); ++ tcb_ptr->OsInfo = OsSendInfo; ++ ++ if (i == (FragCount - 1)) ++ { ++ /* last fragment */ ++ tcb_ptr->mode |= CB_EOF_BIT; ++ ++ /* since this is the last fragment, set the TcbPool pointer before ++ nulling out the Next pointers */ ++ ++ HalDev->TcbPool[Ch][Queue] = tcb_ptr->Next; ++ ++ tcb_ptr->Next = 0; ++ tcb_ptr->HNext = 0; ++ ++ /* In the Tx Interrupt handler, we will need to know which TCB is EOP, ++ so we can save that information in the SOP */ ++ head->Eop = tcb_ptr; ++ ++ /* Emerald fix 10/29 */ ++ osfuncDataCacheHitWriteback((void *)tcb_ptr, 16); ++ ++ osfuncDataCacheHitWriteback((void *)((bit32u)tcb_ptr + 16), 16); ++ ++ } ++ else ++ { ++ /* Emerald fix 10/29 */ ++ osfuncDataCacheHitWriteback((void *)tcb_ptr, 16); ++ ++ osfuncDataCacheHitWriteback((void *)((bit32u)tcb_ptr + 16), 16); ++ ++ tcb_ptr = tcb_ptr->Next; /* what about the end of TCB list?? */ ++ ++ if (tcb_ptr == 0) ++ { ++ rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_OUT_OF_TCBS; ++ goto ExitSend; ++ } ++ } ++ } /* for */ ++ ++ /* put it on the high priority queue */ ++ if (HalDev->TxActQueueHead[Ch][Queue] == 0) ++ { ++ HalDev->TxActQueueHead[Ch][Queue]=head; ++ HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr; ++/*+GSG 030303*//*+GSG 030303*/ ++ if (!HalDev->TxActive[Ch][Queue]) ++ { ++ ++ if (!WaitFlag) ++ { ++ ++ /* write CPPI TX HDP */ ++ (*(pTX_DMA_STATE_WORD_0( base )+( Ch *64)+( Queue ))) = VirtToPhys(head) - HalDev->offset; ++ HalDev->TxActive[Ch][Queue]=TRUE; ++ ++ } ++ ++ } ++ } ++ else ++ { ++ HalDev->TxActQueueTail[Ch][Queue]->Next=head; ++ /* Emerald fix 10/29 */ ++ *((bit32u *) VirtToVirtNoCache(&HalDev->TxActQueueTail[Ch][Queue]->HNext))=VirtToPhys(head) - HalDev->offset; ++ HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr; ++/*+GSG 030303*//*+GSG 030303*/ ++ } ++ rc = EC_NO_ERRORS; ++ goto ExitSend; ++ } /* if (tcb_ptr) */ ++ else ++ { ++ rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_NO_TCBS; ++ goto ExitSend; ++ } ++ExitSend: ++ ++ HalDev->OsFunc->CriticalOff(); ++ return(rc); ++ } ++ ++/* ++ * This function processes receive interrupts. It traverses the receive ++ * buffer queue, extracting the data and passing it to the upper layer software via ++ * osReceive(). It handles all error conditions and fragments without valid data by ++ * immediately returning the RCB's to the RCB pool. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Ch Channel Number. ++ * @param MoreWork Flag that indicates that there is more work to do when set to 1. ++ * ++ * @return 0 if OK, non-zero otherwise. ++ */ ++static int RxInt(HAL_DEVICE *HalDev, int Ch, int *MoreWork) ++ { ++ HAL_RCB *CurrentRcb, *LastRcb=0, *SopRcb, *EofRcb, *EopRcb; ++ bit32u RxBufStatus,PacketsServiced, RxPktLen = 0, RxSopStatus, ++ FrmFrags, TotalFrags, CurrDmaLen, DmaLen, FrmLen; ++ int base = HalDev->dev_base, Ret; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ int RxServiceMax = HalDev->ChData[Ch].RxServiceMax; ++ int FragIndex; /* +GSG 030508 */ ++ int EarlyReturn = 0; /* +GSG 030521 */ ++ ++ bit32u PktType, ExpDmaSize, Cells; ++ int PassHeader=0; ++ ++ int mode; ++ ++ bit32u SopOffset; ++ ++ if(HalDev->NeedsCount) /* +MJH 030410 */ ++ NeedsCheck(HalDev); /* +MJH 030410 */ ++ ++ /* Handle case of teardown interrupt */ ++ if (HalDev->RxTeardownPending[Ch] != 0) ++ { ++ Ret = RxTeardownInt(HalDev, Ch); ++ if (Ret == 0) ++ { /*+GSG 030303*/ ++ *MoreWork = 0; /* bug fix 1/6 */ /*+GSG 030303*/ ++ return (EC_NO_ERRORS); ++ } /*+GSG 030303*/ ++ } ++ ++ CurrentRcb=HalDev->RxActQueueHead[Ch]; ++ ++ osfuncDataCacheHitInvalidate((void*)CurrentRcb, 16); ++ ++ RxBufStatus=CurrentRcb->mode; ++ ++ /* I think I need to do this to ensure that i read UuCpi properly, ++ which is on the second cache line of the Rcb */ ++ osfuncDataCacheHitInvalidate((void*)((bit32u)CurrentRcb+16), 16); ++ ++ PacketsServiced=0; ++ HalDev->InRxInt[Ch]=TRUE; ++ ++ while((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)&& ++ (PacketsServicedUuCpi & 0x00030000) >> 16); /* GSG ~030508 */ ++ /* Calculate the expected DMA length */ ++ if (RxPktLen != 0) ++ { ++ Cells=RxPktLen/48; ++ if ((RxPktLen%48) > 40) ++ Cells++; ++ if (PktType == PKT_TYPE_AAL5) /* ~GSG 030508 */ ++ Cells++; ++ ExpDmaSize=Cells*48; ++ } ++ else ++ { ++ ExpDmaSize=0; ++ } ++ ++ SopOffset=(SopRcb->Off_BLen&CB_OFFSET_MASK)>>16; ++ ++ CurrDmaLen=0; ++ FrmFrags=0; ++ TotalFrags=0; ++ FragIndex=0; ++ FrmLen=0; ++ EofRcb=0; ++ ++/* +GSG 030508 */ ++ if ((PktType == PKT_TYPE_OAM) || (PktType == PKT_TYPE_TRANS)) /* +GSG 030508 */ ++ { /* +GSG 030508 */ ++ /* first frag is ATM Header */ /* +GSG 030508 */ ++ PassHeader = 1; /* +GSG 030508 */ ++ HalDev->fraglist[FragIndex].data = (void *)&SopRcb->AtmHeader; /* +GSG 030508 */ ++ HalDev->fraglist[FragIndex].len = 4; /* +GSG 030508 */ ++ HalDev->fraglist[FragIndex].OsInfo = SopRcb->OsInfo; /* +GSG 030701 */ ++ FragIndex++; /* +GSG 030508 */ ++ } /* +GSG 030508 */ ++/* +GSG 030508 */ ++ ++ do ++ { ++ ++ DmaLen=CurrentRcb->Off_BLen&CB_SIZE_MASK; ++ ++ CurrDmaLen+=DmaLen; ++ FrmLen+=DmaLen; ++ TotalFrags++; ++ if (!EofRcb) ++ { ++ HalDev->fraglist[FragIndex].data=((char *)CurrentRcb->DatPtr); /* ~GSG 030508 */ ++ ++ HalDev->fraglist[FragIndex].data+=((FrmFrags==0)?SopOffset:0); /* ~GSG 030508 */ ++ ++ HalDev->fraglist[FragIndex].len=DmaLen; /* ~GSG 030508 */ ++ ++ /* GSG 12/9 */ ++ HalDev->fraglist[FragIndex].OsInfo = CurrentRcb->OsInfo; /* ~GSG 030508 */ ++ ++ /* Upper layer must do the data invalidate */ ++ ++ FrmFrags++; ++ FragIndex++; /* ~GSG 030508 */ ++ if (FrmLen>=RxPktLen) ++ EofRcb=CurrentRcb; ++ } ++ LastRcb=CurrentRcb; ++ CurrentRcb=LastRcb->Next; ++ if (CurrentRcb) ++ { ++ osfuncDataCacheHitInvalidate((void*)CurrentRcb,16); ++ /* RxBufStatus=CurrentRcb->mode; */ /*DRB~030522*/ ++ } ++ }while(((LastRcb->mode&CB_EOF_BIT)==0)&&(CurrentRcb)); ++ ++ /* New location for interrupt acknowledge */ ++ /* Write the completion pointer */ ++ (*(pRX_CPPI_COMP_PTR( base )+( Ch *64))) = VirtToPhys(LastRcb) - HalDev->offset; ++ ++ EopRcb=LastRcb; ++ HalDev->RxActQueueHead[Ch]=CurrentRcb; ++ HalDev->RxActQueueCount[Ch]-=TotalFrags; ++ ++ if (LastRcb->mode&CB_EOQ_BIT) ++ { ++ if (CurrentRcb) ++ { ++ ++ HalDev->Stats.RxMisQCnt[Ch]++; ++ ++ (*(pRX_DMA_STATE_WORD_1( base )+( Ch *64))) = LastRcb->HNext; ++ } ++ else ++ { ++ ++ /* Rx EOQ */ ++ HalDev->Stats.RxMisQCnt[Ch]++; ++ ++ HalDev->RxActive[Ch]=FALSE; ++ } ++ } ++ ++ EopRcb->Next=0; ++ ++ /* setup SopRcb for the packet */ ++ SopRcb->Eop=(void*)EopRcb; ++ SopRcb->FragCount=TotalFrags; ++ ++ if ((ExpDmaSize!=CurrDmaLen)||(RxSopStatus&RX_ERROR_MASK)) ++ { ++ /* check for Rx errors (only valid on SOP) */ ++ if (RxSopStatus & RX_ERROR_MASK) ++ { ++ if (RxSopStatus & CRC_ERROR_MASK) ++ HalDev->Stats.CrcErrors[Ch]++; ++ ++ if (RxSopStatus & LENGTH_ERROR_MASK) ++ HalDev->Stats.LenErrors[Ch]++; ++ ++ if (RxSopStatus & ABORT_ERROR_MASK) ++ HalDev->Stats.AbortErrors[Ch]++; ++ ++ if (RxSopStatus & STARV_ERROR_MASK) ++ HalDev->Stats.StarvErrors[Ch]++; ++ } ++ else ++ { ++ HalDev->Stats.DmaLenErrors[Ch]++; /* different type of length error */ ++ } ++ ++ EarlyReturn = 1; ++ } ++ ++ /* do not pass up the packet if we're out of RCB's (or have an errored packet)*/ ++ if ((CurrentRcb == 0) || (EarlyReturn == 1)) ++ { ++ halRxReturn((HAL_RECEIVEINFO *)SopRcb,0); ++ } ++ else ++ { ++ ++ if (EopRcb!=EofRcb) ++ { ++ HAL_RCB *FirstEmptyRcb; ++ ++ FirstEmptyRcb = EofRcb->Next; ++ FirstEmptyRcb->Eop = (void*)EopRcb; ++ FirstEmptyRcb->FragCount = TotalFrags-FrmFrags; ++ ++ halRxReturn((HAL_RECEIVEINFO *)FirstEmptyRcb,0); ++ SopRcb->Eop=(void*)EofRcb; ++ SopRcb->FragCount=FrmFrags; ++ EofRcb->Next=0; /* Optional */ ++ } ++ ++ mode = Ch | (PktType << 16) | (PassHeader << 31); /* ~GSG 030508 */ ++ ++ OsFunc->Receive(HalDev->OsDev,HalDev->fraglist,FragIndex,RxPktLen, /* ~GSG 030508 */ ++ (HAL_RECEIVEINFO *)SopRcb,mode); ++ } /* else */ ++ ++ if (CurrentRcb) /*MJH+030522*/ ++ { ++ RxBufStatus=CurrentRcb->mode; ++ } ++ } /* while */ ++ ++ if ((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)) /*~GSG 030307*/ ++ { ++ *MoreWork = 1; ++ } ++ else ++ { ++ *MoreWork = 0; ++ } ++ ++ if (PacketsServiced != 0) ++ { ++ /* REMOVED when removing InRxInt */ ++ if ((!HalDev->RxActive[Ch]) && (HalDev->RxActQueueCount[Ch])) ++ { ++ (*(pRX_DMA_STATE_WORD_1( base )+( Ch *64))) = VirtToPhys(HalDev->RxActQueueHead[Ch]); ++ HalDev->RxActive[Ch]=TRUE; ++ } ++ } ++ ++ HalDev->InRxInt[Ch]=FALSE; ++ ++ /* update stats */ ++ HalDev->Stats.RxPacketsServiced[Ch] += PacketsServiced; ++ HalDev->Stats.RxTotal += PacketsServiced; ++ if (HalDev->Stats.RxMaxServiced < PacketsServiced) ++ HalDev->Stats.RxMaxServiced = PacketsServiced; ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/* ++ * This function processes transmit interrupts. It traverses the ++ * transmit buffer queue, detecting sent data buffers and notifying the upper ++ * layer software via osSendComplete(). (for SAR, i originally had this split ++ * into two functions, one for each queue, but joined them on 8/8/02) ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Queue Queue number to service (always 0 for MAC, Choose 1 for SAR to service low priority queue) ++ * @param MoreWork Flag that indicates that there is more work to do when set to 1. ++ * ++ * @return 0 if OK, non-zero otherwise. ++ */ ++static int TxInt(HAL_DEVICE *HalDev, int Ch, int Queue, int *MoreWork) ++ { ++ HAL_TCB *CurrentTcb,*LastTcbProcessed,*FirstTcbProcessed; ++ int PacketsServiced; ++ bit32u TxFrameStatus; ++ int base = HalDev->dev_base, Ret; ++ int TxServiceMax = HalDev->ChData[Ch].TxServiceMax; ++ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; ++ ++ int OtherQueue = Queue^1; ++ ++/*+GSG 030303*//*+GSG 030303*/ ++ ++ /* Handle case of teardown interrupt. This must be checked at ++ the top of the function rather than the bottom, because ++ the normal data processing can wipe out the completion ++ pointer which is used to determine teardown complete. */ ++ if (HalDev->TxTeardownPending[Ch] != 0) ++ { ++ Ret = TxTeardownInt(HalDev, Ch, Queue); ++ if (Ret == 0) ++ { /*+GSG 030303*/ ++ *MoreWork = 0; /* bug fix 1/6 */ /*+GSG 030303*/ ++ return (EC_NO_ERRORS); ++ } /*+GSG 030303*/ ++ } ++ ++ CurrentTcb = HalDev->TxActQueueHead[Ch][Queue]; ++ FirstTcbProcessed=CurrentTcb; ++ ++ if (CurrentTcb==0) ++ { ++ /* I saw this error a couple of times when multi-channels were added */ ++ dbgPrintf("[cppi TxInt()]TxH int with no TCB in queue!\n"); ++ dbgPrintf(" Ch=%d, CurrentTcb = 0x%08x\n", Ch, (bit32u)CurrentTcb); ++ dbgPrintf(" HalDev = 0x%08x\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ return(EC_CPPI|EC_FUNC_TXINT|EC_VAL_NULL_TCB); ++ } ++ ++ osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16); ++ TxFrameStatus=CurrentTcb->mode; ++ PacketsServiced=0; ++ ++ /* should the ownership bit check be inside of the loop?? could make it a ++ while-do loop and take this check away */ ++ if ((TxFrameStatus&CB_OWNERSHIP_BIT)==0) ++ { ++ OsFunc->CriticalOn(); /* +GSG 030307 */ ++ do ++ { ++ /* Pop TCB(s) for packet from the stack */ ++ LastTcbProcessed=CurrentTcb->Eop; ++ ++ /* new location for acknowledge */ ++ /* Write the completion pointer */ ++ (*(pTXH_CPPI_COMP_PTR( base )+( Ch *64)+( Queue ))) = VirtToPhys(LastTcbProcessed); ++ ++ HalDev->TxActQueueHead[Ch][Queue] = LastTcbProcessed->Next; ++ ++/*+GSG 030303*//*+GSG 030303*/ ++ ++ osfuncDataCacheHitInvalidate((void *)LastTcbProcessed, 16); ++ ++ if (LastTcbProcessed->mode&CB_EOQ_BIT) ++ { ++ if (LastTcbProcessed->Next) ++ { ++ /* Misqueued packet */ ++ ++ HalDev->Stats.TxMisQCnt[Ch][Queue]++; ++ ++ (*(pTX_DMA_STATE_WORD_0( base )+( Ch *64)+( Queue ))) = LastTcbProcessed->HNext; ++ } ++ else ++ { ++ /* Tx End of Queue */ ++ ++ HalDev->Stats.TxEOQCnt[Ch][Queue]++; ++ ++ HalDev->TxActive[Ch][Queue]=FALSE; ++ } ++ } ++ ++ OsFunc->SendComplete(CurrentTcb->OsInfo); ++ ++ /* Push Tcb(s) back onto the stack */ ++ CurrentTcb = LastTcbProcessed->Next; ++ ++ LastTcbProcessed->Next=HalDev->TcbPool[Ch][Queue]; ++ ++ HalDev->TcbPool[Ch][Queue]=FirstTcbProcessed; ++ ++ PacketsServiced++; ++ ++ TxFrameStatus=CB_OWNERSHIP_BIT; ++ /* set the first(SOP) pointer for the next packet */ ++ FirstTcbProcessed = CurrentTcb; ++ if (CurrentTcb) ++ { ++ osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16); ++ TxFrameStatus=CurrentTcb->mode; ++ } ++ ++ }while(((TxFrameStatus&CB_OWNERSHIP_BIT)==0) ++ &&(PacketsServicedTxActive[Ch][OtherQueue]) ++ if (HalDev->TxActQueueHead[Ch][OtherQueue]) ++ if ((*(pTX_DMA_STATE_WORD_0( base )+( Ch *64)+( OtherQueue ))) == 0) ++ { ++ osfuncDataCacheHitInvalidate(HalDev->TxActQueueHead[Ch][OtherQueue],16); ++ if ((HalDev->TxActQueueHead[Ch][OtherQueue]->mode) & CB_OWNERSHIP_BIT) ++ { ++ HalDev->TurboDslErrors++; ++ (*(pTX_DMA_STATE_WORD_0( base )+( Ch *64)+( OtherQueue ))) = ++ VirtToPhys(HalDev->TxActQueueHead[Ch][OtherQueue]); ++ } ++ } ++ ++ OsFunc->CriticalOff(); /* +GSG 030307 */ ++ if (((TxFrameStatus&CB_OWNERSHIP_BIT)==0) ++ &&(PacketsServiced==TxServiceMax)) ++ { ++ *MoreWork = 1; ++ } ++ else ++ { ++ *MoreWork = 0; ++ } ++ } ++ ++ /* update stats */ ++ HalDev->Stats.TxPacketsServiced[Ch][Queue] += PacketsServiced; ++ HalDev->Stats.TxTotal += PacketsServiced; ++ if (HalDev->Stats.TxMaxServiced[Ch][Queue] < PacketsServiced) ++ HalDev->Stats.TxMaxServiced[Ch][Queue] = PacketsServiced; ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function performs a teardown for the given channel. The value of the ++ * Mode parameter controls the operation of the function, as documented below. ++ * ++ * Note: If bit 3 of Mode is set, this call is blocking, and will not return ++ * until the teardown interrupt has occurred and been processed. While waiting ++ * for a blocking teardown to complete, ChannelTeardown() will signal the OS ++ * (via Control(.."Sleep"..)) to allow the OS to perform other tasks if ++ * necessary. If and only if bit 3 of Mode is clear, the CPHAL will call the ++ * OS TeardownComplete() function to indicate that the teardown has completed. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param Ch Channel number. ++ * @param Mode Bit 0 (LSB): Perform Tx teardown (if set).
++ * Bit 1: Perform Rx teardown (if set).
++ * Bit 2: If set, perform full teardown (free buffers/descriptors). ++ * If clear, perform partial teardown (keep buffers).
++ * Bit 3 (MSB): If set, call is blocking. ++ * If clear, call is non-blocking. ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"
++ * @ref EC_VAL_TX_TEARDOWN_ALREADY_PEND "EC_VAL_TX_TEARDOWN_ALREADY_PEND"
++ * @ref EC_VAL_RX_TEARDOWN_ALREADY_PEND "EC_VAL_RX_TEARDOWN_ALREADY_PEND"
++ * @ref EC_VAL_TX_CH_ALREADY_TORNDOWN "EC_VAL_TX_CH_ALREADY_TORNDOWN"
++ * @ref EC_VAL_RX_CH_ALREADY_TORNDOWN "EC_VAL_RX_CH_ALREADY_TORNDOWN"
++ * @ref EC_VAL_TX_TEARDOWN_TIMEOUT "EC_VAL_TX_TEARDOWN_TIMEOUT"
++ * @ref EC_VAL_RX_TEARDOWN_TIMEOUT "EC_VAL_RX_TEARDOWN_TIMEOUT"
++ * @ref EC_VAL_LUT_NOT_READY "EC_VAL_LUT_NOT_READY"
++ */ ++static int halChannelTeardown(HAL_DEVICE *HalDev, int Ch, bit32 Mode) ++ { ++ int DoTx, DoRx, Sleep=2048, timeout=0; /*MJH~030306*/ ++ bit32u base = HalDev->dev_base; ++ ++/* Set the module, used for error returns */ ++ ++ int Ret; ++ ++ /* AAL5 only supports tearing down both sides at once (currently)*/ ++ Mode = (Mode | TX_TEARDOWN | RX_TEARDOWN); ++ ++ DoTx = (Mode & TX_TEARDOWN); ++ DoRx = (Mode & RX_TEARDOWN); ++ ++ if (HalDev->State < enInitialized) ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_STATE); ++ ++ if ((Ch < 0) || (Ch > MAX_AAL5_CHAN )) ++ { ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_CH); ++ } ++ ++ /* set teardown pending bits before performing the teardown, because they ++ will be used in the int handler (this is done for AAL5) */ ++ if (DoTx) ++ { ++ if (HalDev->TxTeardownPending[Ch] != 0) ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_ALREADY_PEND); ++ ++ /* If a full teardown, this also means that the user must ++ setup all channels again to use them */ ++ if (Mode & FULL_TEARDOWN) ++ HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0; ++ ++ if (HalDev->State < enOpened) ++ { ++ /* if the hardware has never been opened, the channel has never actually ++ been setup in the hardware, so I just need to reset the software flag ++ and leave */ ++ HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0; ++ return (EC_NO_ERRORS); ++ } ++ else ++ { ++ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0) ++ { ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_TX_CH_ALREADY_TORNDOWN); ++ } ++ ++ /* set teardown flag */ ++ HalDev->TxTeardownPending[Ch] = Mode; ++ } ++ } ++ ++ if (DoRx) ++ { ++ if (HalDev->RxTeardownPending[Ch] != 0) ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_ALREADY_PEND); ++ ++ if (Mode & FULL_TEARDOWN) ++ HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0; ++ ++ if (HalDev->State < enOpened) ++ { ++ HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0; ++ return (EC_NO_ERRORS); ++ } ++ else ++ { ++ if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == 0) ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_RX_CH_ALREADY_TORNDOWN); ++ ++ HalDev->RxTeardownPending[Ch] = Mode; ++ } ++ } ++ ++ /* Perform Tx Teardown Duties */ ++ if ((DoTx) && (HalDev->State == enOpened)) ++ { ++ /* Request TX channel teardown */ ++ (TX_CPPI_TEARDOWN_REG( base )) = Ch; ++ ++ /* wait until teardown has completed */ ++ if (Mode & BLOCKING_TEARDOWN) ++ { ++ timeout = 0; ++ while (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) ++ { ++ osfuncSleep(&Sleep); ++ ++ timeout++; ++ if (timeout > 100000) ++ { ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_TIMEOUT); ++ } ++ } ++ } ++ } /* if DoTx */ ++ ++ /* Perform Rx Teardown Duties */ ++ if ((DoRx) && (HalDev->State == enOpened)) ++ { ++ ++ /* call main teardown routine for Rx */ ++ Ret = HalDev->SarFunc->ChannelTeardown(HalDev->SarDev, Ch, Mode); ++ if (Ret) return (Ret); ++ ++ if (Mode & BLOCKING_TEARDOWN) ++ { ++ timeout = 0; ++ while (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE) ++ { ++ osfuncSleep(&Sleep); ++ ++ timeout++; ++ if (timeout > 100000) ++ { ++ return(EC_AAL5 |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_TIMEOUT); ++ } ++ } ++ } ++ } /* if DoRx */ ++ ++ return (EC_NO_ERRORS); ++ } ++ ++/** ++ * @ingroup CPHAL_Functions ++ * This function closes the CPHAL module. The module will be reset. ++ * The Mode parameter should be used to determine the actions taken by ++ * Close(). ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * @param Mode Indicates actions to take on close. The following integer ++ * values are valid:
++ * 1: Does not free buffer resources, init parameters remain ++ * intact. User can then call Open() without calling Init() ++ * to attempt to reset the device and bring it back to the ++ * last known state.
++ * 2: Frees the buffer resources, but keeps init parameters. This ++ * option is a more aggressive means of attempting a device reset. ++ * 3: Frees the buffer resources, and clears all init parameters.
++ * At this point, the caller would have to call to completely ++ * reinitialize the device (Init()) before being able to call ++ * Open(). Use this mode if you are shutting down the module ++ * and do not plan to restart. ++ * ++ * @return EC_NO_ERRORS (ok).
++ * Possible Error Codes:
++ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"
++ * Any error code from halChannelTeardown().
++ */ ++static int halClose(HAL_DEVICE *HalDev, bit32 Mode) ++ { ++ int Ch, Inst, Ret; ++ OS_DEVICE *TmpOsDev; ++ OS_FUNCTIONS *TmpOsFunc; ++ HAL_FUNCTIONS *TmpHalFunc; ++ char *TmpDeviceInfo; ++ ++ CPSAR_FUNCTIONS *TmpSarFunc; ++ CPSAR_DEVICE *TmpSarDev; ++ ++ /* Verify proper device state */ ++ if (HalDev->State != enOpened) ++ return (EC_AAL5 | EC_FUNC_CLOSE|EC_VAL_INVALID_STATE); ++ ++ /* Teardown all open channels */ ++ for (Ch = 0; Ch <= MAX_AAL5_CHAN ; Ch++) ++ { ++ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) ++ { ++ if (Mode == 1) ++ { ++ Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ else ++ { ++ Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ } ++ ++ if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE) ++ { ++ if (Mode == 1) ++ { ++ Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ else ++ { ++ Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN); ++ if (Ret) return (Ret); ++ } ++ } ++ } ++ ++ /* free fraglist in HalDev */ ++ HalDev->OsFunc->Free(HalDev->fraglist); ++ HalDev->fraglist = 0; ++ ++ /* unregister the interrupt */ ++ HalDev->OsFunc->IsrUnRegister(HalDev->OsDev, HalDev->interrupt); ++ ++ /* Disable the Tx CPPI DMA */ ++ TX_CPPI_CTL_REG(HalDev->dev_base) = 0; ++ ++ /* Disable the Rx CPPI DMA */ ++ RX_CPPI_CTL_REG(HalDev->dev_base) = 0; ++ ++ /* Close the SAR hardware - puts the device in reset if this module is the ++ "last one out" */ ++ HalDev->SarFunc->Close(HalDev->SarDev, Mode); ++ ++ /* If mode is 3, than clear the HalDev and set next state to DevFound*/ ++ if (Mode == 3) ++ { ++ /* I need to keep the HalDev parameters that were setup in InitModule */ ++ TmpOsDev = HalDev->OsDev; ++ TmpOsFunc = HalDev->OsFunc; ++ TmpDeviceInfo = HalDev->DeviceInfo; ++ ++ TmpSarFunc = HalDev->SarFunc; ++ TmpSarDev = HalDev->SarDev; ++ ++ TmpHalFunc = HalDev->HalFuncPtr; ++ Inst = HalDev->Inst; ++ ++ /* Clear HalDev */ ++ ++ HalDev->OsFunc->Memset(HalDev, 0, sizeof(HAL_DEVICE)); ++ ++ /* Restore key parameters */ ++ HalDev->OsDev = TmpOsDev; ++ HalDev->OsFunc = TmpOsFunc; ++ HalDev->DeviceInfo = TmpDeviceInfo; ++ ++ HalDev->SarFunc = TmpSarFunc; ++ HalDev->SarDev = TmpSarDev; ++ ++ HalDev->HalFuncPtr = TmpHalFunc; ++ HalDev->Inst = Inst; ++ ++ HalDev->State = enDevFound; ++ } ++ else ++ { ++ HalDev->State = enInitialized; ++ } ++ ++ return(EC_NO_ERRORS); ++ } +diff -urN linux.old/drivers/atm/sangam_atm/cpremap_cpaal5.c linux.dev/drivers/atm/sangam_atm/cpremap_cpaal5.c +--- linux.old/drivers/atm/sangam_atm/cpremap_cpaal5.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpremap_cpaal5.c 2005-08-23 04:46:50.084845672 +0200 +@@ -0,0 +1,27 @@ ++#ifndef _INC_CPREMAP_C ++#define _INC_CPREMAP_C ++ ++#ifdef __ADAM2 ++static inline void osfuncDataCacheHitInvalidate(void *ptr, int Size) ++ { ++ asm(" cache 17, (%0)" : : "r" (ptr)); ++ } ++ ++static inline void osfuncDataCacheHitWriteback(void *ptr, int Size) ++ { ++ asm(" cache 25, (%0)" : : "r" (ptr)); ++ } ++ ++#else ++ #define osfuncDataCacheHitInvalidate(MemPtr, Size) HalDev->OsFunc->DataCacheHitInvalidate(MemPtr, Size) ++ #define osfuncDataCacheHitWriteback(MemPtr, Size) HalDev->OsFunc->DataCacheHitWriteback(MemPtr, Size) ++#endif ++ ++/* ++#define osfuncDataCacheHitInvalidate(ptr, Size) asm(" cache 17, (%0)" : : "r" (ptr)) ++#define osfuncDataCacheHitWriteback(ptr, Size) asm(" cache 25, (%0)" : : "r" (ptr)) ++*/ ++ ++ ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/cpremap_cpsar.c linux.dev/drivers/atm/sangam_atm/cpremap_cpsar.c +--- linux.old/drivers/atm/sangam_atm/cpremap_cpsar.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpremap_cpsar.c 2005-08-23 04:46:50.084845672 +0200 +@@ -0,0 +1,27 @@ ++#ifndef _INC_CPREMAP_C ++#define _INC_CPREMAP_C ++ ++#ifdef __ADAM2 ++static inline void osfuncDataCacheHitInvalidate(void *ptr, int Size) ++ { ++ asm(" cache 17, (%0)" : : "r" (ptr)); ++ } ++ ++static inline void osfuncDataCacheHitWriteback(void *ptr, int Size) ++ { ++ asm(" cache 25, (%0)" : : "r" (ptr)); ++ } ++ ++#else ++ #define osfuncDataCacheHitInvalidate(MemPtr, Size) HalDev->OsFunc->DataCacheHitInvalidate(MemPtr, Size) ++ #define osfuncDataCacheHitWriteback(MemPtr, Size) HalDev->OsFunc->DataCacheHitWriteback(MemPtr, Size) ++#endif ++ ++/* ++#define osfuncDataCacheHitInvalidate(ptr, Size) asm(" cache 17, (%0)" : : "r" (ptr)) ++#define osfuncDataCacheHitWriteback(ptr, Size) asm(" cache 25, (%0)" : : "r" (ptr)) ++*/ ++ ++ ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/cpsar.c linux.dev/drivers/atm/sangam_atm/cpsar.c +--- linux.old/drivers/atm/sangam_atm/cpsar.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpsar.c 2005-08-23 04:46:50.086845368 +0200 +@@ -0,0 +1,881 @@ ++/** ++ * cpsar.c ++ * ++ * TNETDxxxx Software Support\n ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * This file contains the HAL for the CPSAR module. In the software ++ * architecture, the CPSAR module is used exclusively by the AAL5 and AAL2 ++ * CPHAL modules. AAL5 and AAL2 may utilize the same CPSAR instance ++ * simulataneously. ++ * ++ * version ++ * 5Sep02 Greg 1.00 Original Version created. ++ */ ++ ++/* register files */ ++#include "cp_sar_reg.h" ++ ++#define _CPHAL_CPSAR ++#define _CPHAL ++ ++#define WAIT_THRESH 200000 ++#define IRAM_SIZE 1536 ++#define MAX_INST 2 ++ ++/* OS Data Structure definition */ ++ ++typedef void OS_PRIVATE; ++typedef void OS_DEVICE; ++typedef void OS_SENDINFO; ++typedef void OS_RECEIVEINFO; ++typedef void OS_SETUP; ++ ++/* CPHAL Data Structure definitions */ ++ ++typedef struct cpsar_device CPSAR_DEVICE; ++typedef struct cpsar_device HAL_DEVICE; ++typedef void HAL_RECEIVEINFO; ++ ++#define MAX_QUEUE 2 ++#define MAX_CHAN 19 ++ ++#include "cpcommon_cpsar.h" ++#include "cpswhal_cpsar.h" ++#include "cpsar.h" ++#include "cpcommon_cpsar.c" ++ ++static CPSAR_DEVICE *CpsarDev[MAX_INST]= {0,0}; ++ ++/* ++ * Returns statistics information. ++ * ++ * @param HalDev CPHAL module instance. (set by xxxInitModule()) ++ * ++ * @return 0 ++ */ ++static int StatsGet3(CPSAR_DEVICE *HalDev) ++ { ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]StatsGet3(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ /* ++ dbgPrintf("CPSAR General Stats:\n"); ++ DispHexStat(HalDev, "Base Address",HalDev->dev_base); ++ DispStat(HalDev, "Offset (VLYNQ)",HalDev->offset); ++ DispStat(HalDev, "Debug Level",HalDev->debug); ++ DispStat(HalDev, "Instance",HalDev->Inst); ++ DispHexStat(HalDev, "Reset Address",HalDev->ResetBase); ++ DispStat(HalDev, "Reset Bit",HalDev->ResetBit); ++ */ ++ return (EC_NO_ERRORS); ++ } ++ ++/* +GSG 030407 */ ++static void SetOamMode(HAL_DEVICE *HalDev) ++ { ++ int Ch; ++ volatile bit32u *pTmp; ++ int OamMode = (1<<8); ++ ++ /* any configuration of OamMode affects all VC's, including AAL2 */ ++ for (Ch = 0; Ch < MAX_CHAN; Ch++) ++ { ++ if (Ch < 16) ++ pTmp = (pPDSP_AAL5_RX_STATE_WORD_0(HalDev->dev_base) + (Ch*64)); ++ else ++ pTmp = (pPDSP_AAL2_RX_STATE_WORD_0(HalDev->dev_base) + ((Ch-16)*64)); ++ ++ if (HalDev->OamMode == 0) ++ { ++ *pTmp &=~ OamMode; ++ } ++ else ++ { ++ *pTmp |= OamMode; ++ } ++ } ++ } ++ ++static int halControl(CPSAR_DEVICE *HalDev, const char *Key, const char *Action, void *Value) ++ { ++ int KeyFound=0, ActionFound=0, rc=EC_NO_ERRORS, Ch; /* +RC3.02*/ ++ char *TmpKey = (char *)Key; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halControl(HalDev:%08x, Key:%s, Action:%s, Value:%08x)\n", (bit32u)HalDev, ++ Key, Action, (bit32u)Value); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ if (HalDev->OsFunc->Strcmpi(Key, "Debug") == 0) ++ { ++ KeyFound=1; /* +RC3.02*/ ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; /* +RC3.02*/ ++ HalDev->debug = *(int *)Value; ++ } ++ } ++ ++ /* +GSG 030407 */ ++ if (HalDev->OsFunc->Strcmpi(Key, "OamMode") == 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ HalDev->OamMode = *(int *)Value; ++ ++ /* only do this if we're open */ ++ if (HalDev->OpenCount > 0) ++ SetOamMode(HalDev); ++ } ++ ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ { ++ ActionFound=1; ++ *(int *)Value = HalDev->OamMode; ++ } ++ } ++ ++ if (HalDev->OsFunc->Strcmpi(Key, "Stats3") == 0) ++ { ++ if (HalDev->OsFunc->Strcmpi(Action, "Get") == 0) ++ StatsGet3(HalDev); ++ } ++ ++ /* +RC3.02 (if statement) */ ++ /* Fixes PITS #98 */ ++ if (HalDev->OsFunc->Strstr(Key, "PdspEnable") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ /* Configure PDSP enable bit based on Value*/ ++ if (*(int *)Value & 1) ++ { ++ /* enable PDSP */ ++ PDSP_CTRL_REG(HalDev->dev_base) |= 0x2; ++ } ++ else ++ { ++ /* disable PDSP */ ++ PDSP_CTRL_REG(HalDev->dev_base) &=~ 0x2; ++ } ++ } ++ } ++ ++ if (HalDev->OsFunc->Strstr(Key, "FwdUnkVc.") != 0) ++ { ++ KeyFound=1; ++ if (HalDev->OsFunc->Strcmpi(Action, "Set") == 0) ++ { ++ ActionFound=1; ++ ++ /* extract channel number */ ++ TmpKey += HalDev->OsFunc->Strlen("FwdUnkVc."); ++ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); ++ ++ /* Configure forwarding of unknown VCI/VPI cells */ ++ SAR_PDSP_FWD_UNK_VC_REG(HalDev->dev_base) = (((*(int*)Value)<<31) | Ch); ++ } ++ } ++ ++ if (KeyFound == 0) /* +RC3.02 */ ++ rc = (EC_CPSAR|EC_FUNC_CONTROL|EC_VAL_KEY_NOT_FOUND); /* +RC3.02 */ ++ ++ if (ActionFound == 0) /* +RC3.02 */ ++ rc = (EC_CPSAR|EC_FUNC_CONTROL|EC_VAL_ACTION_NOT_FOUND); /* +RC3.02 */ ++ ++ return(rc); /* ~RC3.02 */ ++ } ++ ++/* ++ * This function opens the specified channel. ++ * ++ * @param HalDev CPHAL module instance. (set by cphalInitModule()) ++ * @param Ch Channel number. ++ * ++ * @return 0 OK, Non-zero Not OK ++ */ ++static int halChannelSetup(CPSAR_DEVICE *HalDev, CHANNEL_INFO *HalCh) ++ { ++ int i; ++ int Ch = HalCh->Channel; ++ int PdspChBlock = Ch; ++ int PdspBlockOffset = 0; ++ volatile bit32u *pTmp; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halChannelSetup(HalDev:%08x, HalCh:%08x)\n", (bit32u)HalDev, ++ (bit32u)HalCh); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Figure out the correct offset from the start of the PDSP ++ Scratchpad RAM (starting at 0x8050 in the SAR) */ ++ if (Ch > 15) ++ { ++ /* this is an AAL2 channel, which are channels 16-18 */ ++ PdspChBlock = Ch - 16; ++ /* Get the offset to the AAL2 portion of the block (in words) */ ++ PdspBlockOffset = NUM_PDSP_AAL5_STATE_WORDS + (PdspChBlock*64); ++ /* Clear PDSP State RAM */ ++ /*pTmp = (pPDSP_BLOCK_0(HalDev->dev_base)+PdspBlockOffset); ++ for (i=0; idev_base)+PdspBlockOffset); ++ for (i=0; idev_base)+PdspBlockOffset); ++ *pTmp++ = HalCh->TxVc_CellRate; /* Set the cell rate in cells/sec */ ++ *pTmp++ = HalCh->TxVc_QosType; /* Configure the QoS Type */ ++ *pTmp++ = HalCh->TxVc_Mbs; /* Set minimum burst size */ ++ *pTmp++ = 0; /* (skip a register) */ ++ *pTmp++ = HalCh->TxVc_Pcr; /* set the peak cell rate */ ++ *pTmp++ = 0; /* new addition 4.9.02 */ ++ *pTmp++ = HalCh->TxVc_AtmHeader; /* give the ATM header */ ++ *pTmp++ = (HalCh->TxVc_OamTc << 8) ++ |(HalCh->TxVc_VpOffset); /* Set the OAM TC Path and VP Offset */ ++ ++ /* Setup RX PDSP State RAM */ ++ *pTmp++ = (HalCh->RxVc_OamCh)| ++ (HalDev->OamMode << 8) | ++ (HalCh->RxVc_OamToHost<<9); /* Set OAM Channel, Mode, and ToHost options */ ++ *pTmp++ = HalCh->RxVc_AtmHeader; /* ATM hdr put on firmware generated OAM */ ++ *pTmp++ = (HalCh->RxVc_VpOffset)| /* Set Rx OAM TC Path and VP Offset */ ++ (HalCh->RxVc_OamTc<<8); ++ ++ /* Setup TX VP PDSP State RAM */ ++ pTmp = (pPDSP_BLOCK_0(HalDev->dev_base)+PdspBlockOffset+16); /*GSG~030703 12->16 */ ++ *pTmp++ = HalCh->TxVp_AtmHeader; ++ *pTmp++ = (HalCh->TxVp_OamTc << 8); ++ ++ /* Setup RX VP PDSP State RAM */ ++ pTmp = (pPDSP_BLOCK_0(HalDev->dev_base)+PdspBlockOffset+20); /*GSG~030703 16->20 */ ++ *pTmp++ = HalCh->RxVp_AtmHeader; ++ *pTmp++ = (HalCh->RxVp_OamCh)| ++ (HalCh->RxVp_OamTc<<8)| ++ (HalCh->RxVp_OamToHost<<9); /* Set OAM Channel, Mode, and ToHost options */ ++ *pTmp++ = 0; ++ *pTmp++ = HalCh->RxVp_OamVcList; ++ ++ /* Configure forwarding of unknown VCI/VPI cells */ ++ if (HalCh->PktType == 3) ++ SAR_PDSP_FWD_UNK_VC_REG(HalDev->dev_base) = ((HalCh->FwdUnkVc<<31)|Ch); ++ ++ /* Configure Tx Channel Mapping Register (turn channel "ON") */ ++ TX_CH_MAPPING_REG(HalDev->dev_base) = 0x80000000 | ++ (HalCh->DaMask << 30) ++ | (HalCh->Priority << 24) | Ch; ++ ++ /* Setup Rx Channel in the LUT */ ++ i=0; ++ while (!(RX_LUT_CH_SETUP_REQ_REG(HalDev->dev_base) & 0x80000000)) ++ { ++ if (i > WAIT_THRESH) ++ { ++ return(EC_CPSAR|EC_FUNC_CHSETUP|EC_VAL_LUT_NOT_READY); ++ } ++ else ++ i++; ++ } ++ ++ /* RX LUT is ready */ ++ RX_LUT_CH_SETUP_REQ_REG(HalDev->dev_base) = (HalCh->PktType << 24) | Ch; ++ RX_LUT_CH_SETUP_REQ_VC_REG(HalDev->dev_base) = ((HalCh->Vpi << 20) | ++ (HalCh->Vci << 4)); ++ ++ return (EC_NO_ERRORS); ++ } ++ ++static int halChannelTeardown(CPSAR_DEVICE *HalDev, int Ch, bit32 Mode) ++ { ++ int waitcnt = 0; ++ int PdspBlockOffset = 0, i; ++ volatile bit32u *pTmp; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halChannelTeardown(HalDev:%08x, Ch:%d, Mode:%d\n", ++ (bit32u)HalDev, Ch, Mode); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ if ((Ch < 0) || (Ch > MAX_CHAN)) ++ return(EC_CPSAR|EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_CH); ++ ++ /* Request RX channel teardown through LUT */ ++ while ((RX_LUT_CH_TEARDOWN_REQ_REG(HalDev->dev_base) & 0x80000000) == 0) ++ { ++ waitcnt++; ++ if (waitcnt == WAIT_THRESH) ++ { ++ return(EC_CPSAR|EC_FUNC_CHTEARDOWN|EC_VAL_LUT_NOT_READY); ++ } ++ } ++ ++ RX_LUT_CH_TEARDOWN_REQ_REG(HalDev->dev_base) = (Ch & 0xffff); ++ ++ /* for AAL2, clear channel PDSP RAM here. AAL5 does it when the teardown ++ has completed (which is asynchronous)*/ ++ if (Ch > 15) ++ { ++ /* Get the offset to the AAL2 portion of the block (in words) */ ++ PdspBlockOffset = NUM_PDSP_AAL5_STATE_WORDS + ((Ch-16)*64); ++ /* Clear PDSP State RAM */ ++ pTmp = (pPDSP_BLOCK_0(HalDev->dev_base)+PdspBlockOffset); ++ for (i=0; iOsFunc->Control(HalDev->OsDev, "Firmware", "Get", &SarPdspFirmware); /* ~GSG 030403 */ ++ if (rc) /* +GSG 030403 */ ++ return (EC_CPSAR|EC_FUNC_OPEN|EC_VAL_KEY_NOT_FOUND); /* +GSG 030403 */ ++ ++ /* Get firmware size */ ++ rc = HalDev->OsFunc->Control(HalDev->OsDev, "FirmwareSize", "Get", &FirmwareSize); /* ~GSG 030403 */ ++ if (rc) /* +GSG 030403 */ ++ return (EC_CPSAR|EC_FUNC_OPEN|EC_VAL_KEY_NOT_FOUND); /* +GSG 030403 */ ++ ++ IRamAddress = (bit32u) pPDSP_CTRL_REG(HalDev->dev_base); ++ ++ NumOfEntries = (FirmwareSize)/4; /* ~GSG 030403 */ ++ if (NumOfEntries > IRAM_SIZE) ++ { ++ /* Note: On Avalanche, they truncated the PDSP firmware and warned */ ++ /* NumOfEntries = IRAM_SIZE; */ ++ return(EC_CPSAR|EC_FUNC_INIT|EC_VAL_FIRMWARE_TOO_LARGE); ++ } ++ for(i=8;iInst, "sar", (bit32u)&HalDev->DeviceInfo); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Attempt to find the device information */ ++ Ret = HalDev->OsFunc->DeviceFindInfo(HalDev->Inst, "sar", &HalDev->DeviceInfo); ++ if (Ret) ++ return(EC_CPSAR|EC_FUNC_PROBE|EC_VAL_DEVICE_NOT_FOUND); ++ ++ return(EC_NO_ERRORS); ++ } ++ ++#ifdef __CPHAL_DEBUG ++static void dbgConfigDump(HAL_DEVICE *HalDev) ++ { ++ dbgPrintf(" [cpsar Inst %d] Config Dump:\n", HalDev->Inst); ++ dbgPrintf(" Base :%08x, offset :%08d\n", ++ HalDev->dev_base, HalDev->offset); ++ dbgPrintf(" ResetBit:%08d, ResetBase:%08x\n", ++ HalDev->ResetBit, HalDev->ResetBase); ++ dbgPrintf(" UniNni :%08d, debug :%08d\n", ++ HalDev->ResetBit, HalDev->debug); ++ osfuncSioFlush(); ++ } ++#endif ++ ++/* ++ * Sets up HAL default configuration parameter values. ++ */ ++static void ConfigInit(CPSAR_DEVICE *HalDev) ++ { ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]ConfigInit(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ /* configure some defaults with tnetd7300 values */ ++ HalDev->dev_base = 0xa3000000; ++ HalDev->offset = 0; ++ HalDev->UniNni = CFG_UNI_NNI; ++ HalDev->ResetBit = 9; ++ HalDev->debug = 0; ++ HalDev->ResetBase = 0xa8611600; ++ } ++ ++/* ++ * Retrieve HAL configuration parameter values. ++ */ ++static bit32u ConfigGet(HAL_DEVICE *HalDev) ++ { ++ bit32u ParmValue, error_code; ++ char *DeviceInfo = HalDev->DeviceInfo; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]ConfigGet(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* get the configuration parameters common to all modules */ ++ error_code = ConfigGetCommon(HalDev); ++ if (error_code) return (EC_CPSAR|error_code); ++ ++ /* get SAR specific configuration parameters */ ++ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo,"UniNni",&ParmValue); ++ if (!error_code) HalDev->UniNni = ParmValue; ++ ++ return (EC_NO_ERRORS); ++ } ++ ++static int halInit(CPSAR_DEVICE *HalDev) ++ { ++ bit32u Ret; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halInit(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(7)) ++ { ++ dbgPrintf("[cpsar halInit()]InitCount = %d\n", HalDev->InitCount); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Only run the init code for the first calling module per instance */ ++ if (HalDev->InitCount > 1) ++ { ++ return (EC_NO_ERRORS); ++ } ++ ++ /* Configure HAL defaults */ ++ ConfigInit(HalDev); ++ ++ /* Retrieve HAL configuration parameters from data store */ ++ Ret = ConfigGet(HalDev); ++ if (Ret) return (Ret); ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(9)) ++ dbgConfigDump(HalDev); ++#endif ++ ++ return(EC_NO_ERRORS); ++ } ++ ++static int halOpen(CPSAR_DEVICE *HalDev) ++ { ++ int Ret, Ticks=64; ++ int i; /*+GSG 030407*/ ++ volatile int *pTmp; /*+GSG 030407*/ ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halOpen(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(7)) ++ { ++ dbgPrintf("[cpsar halOpen()]OpenCount = %d\n", HalDev->OpenCount); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Only run the open code for the first calling module per instance */ ++ if (HalDev->OpenCount++ > 0) ++ { ++ return (EC_NO_ERRORS); ++ } ++ ++ /* Take SAR out of reset */ ++ if (((*(volatile bit32u *)(HalDev->ResetBase)) & (1<ResetBit)) != 0) ++ { ++ /** @todo Should I somehow call AAL5/AAL2 Close() here? All I've done ++ here is copy the Close code from each and paste it here. */ ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(7)) ++ { ++ dbgPrintf("[cpsar halOpen()]Module was already out of reset.\n"); ++ dbgPrintf(" Closing module and resetting.\n"); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Disable the Tx CPPI DMA */ ++ TX_CPPI_CTL_REG(HalDev->dev_base) = 0; ++ ++ /* Disable the Rx CPPI DMA */ ++ RX_CPPI_CTL_REG(HalDev->dev_base) = 0; ++ ++ /* Disable the PDSP */ ++ PDSP_CTRL_REG(HalDev->dev_base) &=~ 0x00000002; ++ ++ /* disable interrupt masks */ ++ SAR_TX_MASK_CLR(HalDev->dev_base) = 0xffffffff; ++ SAR_RX_MASK_CLR(HalDev->dev_base) = 0xffffffff; ++ ++#ifndef NO_RESET /* GSG+ 030428 */ ++ /* clear reset bit */ ++ (*(volatile bit32u *)(HalDev->ResetBase)) &=~ (1<ResetBit); /* ~GSG 030307 */ ++ HalDev->OsFunc->Control(HalDev->OsDev, "Sleep", "", &Ticks); ++ ++ /* set reset bit */ ++ (*(volatile bit32u *)(HalDev->ResetBase)) |= (1<ResetBit); /* ~GSG 030307 */ ++ HalDev->OsFunc->Control(HalDev->OsDev, "Sleep", "", &Ticks); ++#endif /* GSG+ 030428 */ ++ } ++ else ++ { ++ (*(volatile bit32u *)(HalDev->ResetBase)) |= (1<ResetBit); /* ~GSG 030307 */ ++ HalDev->OsFunc->Control(HalDev->OsDev, "Sleep", "", &Ticks); ++ } ++ ++ /* Configure UNI/NNI */ ++ RX_LUT_GLOBAL_CFG_REG(HalDev->dev_base) |= (HalDev->UniNni & 0x1); ++ ++ /* Clear entire PDSP state RAM */ /*+GSG 030407*/ ++ pTmp = (pTX_DMA_STATE_WORD_0(HalDev->dev_base)); /*+GSG 030407*/ ++ for (i=0; idev_base) = 0x00080003; ++ ++ return(EC_NO_ERRORS); ++ } ++ ++static int halClose(CPSAR_DEVICE *HalDev, int Mode) ++ { ++ int Ticks = 64; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halClose(HalDev:%08x, Mode:%d)\n", (bit32u)HalDev, Mode); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* handle the error case if there is nothing open */ ++ if (HalDev->OpenCount == 0) ++ { ++ return(EC_CPSAR|EC_FUNC_CLOSE|EC_VAL_MODULE_ALREADY_CLOSED); ++ } ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(7)) ++ { ++ dbgPrintf("[cpsar halClose()]OpenCount = %d\n", HalDev->OpenCount); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Only run the close code for the last calling module per instance */ ++ if (HalDev->OpenCount-- > 1) ++ { ++ return (EC_NO_ERRORS); ++ } ++ ++ /* Disable the PDSP */ ++ PDSP_CTRL_REG(HalDev->dev_base) &=~ 0x00000002; ++ ++#ifndef NO_RESET /* GSG +030428 */ ++ /* put device back into reset */ ++ (*(volatile bit32u *)(HalDev->ResetBase)) &=~ (1<ResetBit); /* ~GSG 030307 */ ++ HalDev->OsFunc->Control(HalDev->OsDev, "Sleep", "", &Ticks); ++#endif /* GSG +030428 */ ++ ++ return(EC_NO_ERRORS); ++ } ++ ++static int halShutdown(CPSAR_DEVICE *HalDev) ++ { ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halShutdown(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* handle the error case */ ++ if (HalDev->InitCount == 0) ++ { ++ return(EC_CPSAR|EC_FUNC_CLOSE|EC_VAL_MODULE_ALREADY_SHUTDOWN); ++ } ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(7)) ++ { ++ dbgPrintf("[cpsar halShutdown()]InitCount = %d\n", HalDev->InitCount); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ /* Only run the shutdown code for the last calling module per instance */ ++ if (HalDev->InitCount-- > 1) ++ { ++ return (EC_NO_ERRORS); ++ } ++ ++ /* free the SAR functions */ ++#ifdef __CPHAL_DEBUG ++ if (DBG(6)) ++ { ++ dbgPrintf(" [cpsar halShutdown()]: Free CPSAR function pointers\n"); ++ osfuncSioFlush(); ++ } ++ if (DBG(1)||DBG(3)) ++ { ++ dbgPrintf("[os]Free(MemPtr:%08x)\n", (bit32u)HalDev->HalFuncPtr); ++ osfuncSioFlush(); ++ } ++#endif ++ /* free the HalFunc */ ++ HalDev->OsFunc->Free(HalDev->HalFuncPtr); ++ ++ /* we have a static global, so I should clear it's value as well */ ++ CpsarDev[HalDev->Inst] = 0; ++ ++#ifdef __CPHAL_DEBUG ++ if (DBG(6)) ++ { ++ dbgPrintf(" [cpsar halShutdown()]Free HalDev\n"); ++ osfuncSioFlush(); ++ } ++ if (DBG(1)||DBG(3)) ++ { ++ dbgPrintf("[os]Free(MemPtr:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ /* free the CPSAR device */ ++ HalDev->OsFunc->Free(HalDev); ++ ++ return(EC_NO_ERRORS); ++ } ++ ++static int halTick(CPSAR_DEVICE *HalDev) ++ { ++#ifdef __CPHAL_DEBUG ++ if (DBG(0)) ++ { ++ dbgPrintf("[cpsar]halTick(HalDev:%08x)\n", (bit32u)HalDev); ++ osfuncSioFlush(); ++ } ++#endif ++ ++ return(EC_NO_ERRORS); ++ } ++ ++/* ++ * The CPSAR version of InitModule() should be passed the OS_FUNCTIONS pointer, ++ * and will return the HalDev pointer. ++ * ++ * @param HalDev Pointer to CPSAR module information. This will ++ * be used by the OS when communicating to this module via ++ * CPSAR. ++ * @param OsDev Pointer to OS device information. This will be saved by ++ * the CPSAR and returned to the OS when required. ++ * @param HalFunc HAL_FUNCTIONS pointer. ++ * @param Size Pointer to the size of the HAL_FUNCTIONS structure. (If ++ * HalFunc is 0, the value will be set by CPSAR, otherwise ++ * ignored) ++ * @param Inst The instance number of the module to initialize. (start at ++ * 0). ++ * ++ * @return 0 OK, Nonzero - error. ++ */ ++/* ++int cpsarInitModule(CPSAR_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ CPSAR_FUNCTIONS *HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int *Size, ++ int Inst) ++*/ ++int cpsarInitModule(CPSAR_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ CPSAR_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst) ++ { ++ CPSAR_DEVICE *HalPtr; ++ CPSAR_FUNCTIONS *HalFuncPtr; ++ ++ /* ++ if ( HalFunc == 0 ) ++ { ++ *Size = sizeof(CPSAR_FUNCTIONS); ++ return(EC_NO_ERRORS); ++ } ++ */ ++ ++ if (CpsarDev[Inst] != 0) ++ { ++ /* this SAR module has been connected to before, so do not ++ allocate another CPSAR_DEVICE */ ++ HalPtr = CpsarDev[Inst]; ++ ++ /* increase count of attached modules */ ++ HalPtr->InitCount++; ++ } ++ else ++ { ++ /* allocate the CPSAR_DEVICE structure */ ++ HalPtr = (CPSAR_DEVICE *) OsFunc->MallocDev(sizeof(CPSAR_DEVICE)); ++ if(!HalPtr) ++ return(EC_CPSAR|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_DEV_FAILED); ++ ++ HalFuncPtr = (CPSAR_FUNCTIONS *) OsFunc->Malloc(sizeof(CPSAR_FUNCTIONS)); ++ if (!HalFuncPtr) ++ return (EC_CPSAR|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_FAILED); ++ ++ /* Initialize the size of hal functions */ ++ *HalFuncSize = sizeof (CPSAR_FUNCTIONS); ++ ++ /* ensure the device structure is cleared */ ++ OsFunc->Memset(HalPtr, 0, sizeof(CPSAR_DEVICE)); ++ ++ /* clear the function pointers */ ++ OsFunc->Memset(HalFuncPtr, 0, sizeof(CPSAR_FUNCTIONS)); ++ ++ /* Supply pointers for the CPSAR API functions */ ++ HalFuncPtr->ChannelSetup = halChannelSetup; ++ HalFuncPtr->ChannelTeardown = halChannelTeardown; ++ HalFuncPtr->Close = halClose; ++ HalFuncPtr->Control = halControl; ++ HalFuncPtr->Init = halInit; ++ HalFuncPtr->Open = halOpen; ++ HalFuncPtr->Probe = halProbe; ++ HalFuncPtr->Shutdown = halShutdown; ++ HalFuncPtr->Tick = halTick; ++ ++ /* keep a reference to HalFuncPtr so I can free it later */ ++ HalPtr->HalFuncPtr = HalFuncPtr; ++ ++ /* store the CPSAR_DEVICE, so the CPSAR module will know whether ++ it is in use for the given instance */ ++ CpsarDev[Inst] = HalPtr; ++ ++ /* increase count of attached modules */ ++ HalPtr->InitCount++; ++ } ++ ++ /* @todo Does this need modification to deal with multiple callers/ ++ drivers? If different callers will use different OsDev/OsFunc, ++ then the current code will not work. ++ */ ++ ++ /* initialize the CPSAR_DEVICE structure */ ++ HalPtr->OsDev = OsDev; ++ /*HalPtr->OsOpen = OsDev;*/ ++ HalPtr->Inst = Inst; ++ HalPtr->OsFunc = OsFunc; ++ ++ /* pass the HalPtr back to the caller */ ++ *HalDev = HalPtr; ++ *HalFunc = HalPtr->HalFuncPtr; ++ ++ return (EC_NO_ERRORS); ++ } +diff -urN linux.old/drivers/atm/sangam_atm/cpsar_cpaal5.h linux.dev/drivers/atm/sangam_atm/cpsar_cpaal5.h +--- linux.old/drivers/atm/sangam_atm/cpsar_cpaal5.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpsar_cpaal5.h 2005-08-23 04:46:50.087845216 +0200 +@@ -0,0 +1,103 @@ ++/******************************************************************************* ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: cpsar.h ++ * ++ * DESCRIPTION: ++ * This file contains data structure definitions for the CPSAR HAL. ++ * ++ * HISTORY: ++ * 6Sep02 Greg 1.00 Original Version created. ++ * ++ *****************************************************************************/ ++#ifndef _INC_CPSAR ++#define _INC_CPSAR ++ ++#define NUM_RX_STATE_WORDS 7 ++#define NUM_TX_STATE_WORDS 9 ++#define MAX_CHAN 19 ++ ++ ++#ifndef _CPHAL_CPSAR ++typedef void CPSAR_DEVICE; ++#endif ++ ++/* ++ * HAL Default Parameter Values ++ */ ++#define CFG_UNI_NNI 0 ++ ++/** ++ * @ingroup shared_data ++ * ++ * List of defined keys for use with Control(). ++ */ ++typedef enum ++ { ++ /* SAR */ ++ enGET_FIRMWARE, /**< Used by the SAR to request a pointer to firmware */ ++ enGET_FIRMWARE_SIZE, /**< Used by the SAR to request the size of the firmware */ ++ enEND=9999 /* Last entry */ ++ }INFO_KEY; ++ ++/* ++ * The CPHAL_FUNCTIONS struct defines the CPHAL function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup)(CPSAR_DEVICE *HalDev, CHANNEL_INFO *HalCh); ++ int (*ChannelTeardown)(CPSAR_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(CPSAR_DEVICE *HalDev, int Mode); ++ int (*Control)(CPSAR_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*Init)(CPSAR_DEVICE *HalDev); ++ int (*ModeChange)(CPSAR_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(CPSAR_DEVICE *HalDev); ++ int (*Probe)(CPSAR_DEVICE *HalDev); ++ int (*Shutdown)(CPSAR_DEVICE *HalDev); ++ int (*Tick)(CPSAR_DEVICE *HalDev); ++ } CPSAR_FUNCTIONS; ++ ++/* ++ * This is the data structure for a generic HAL device. It contains all device ++ * specific data for a single instance of that device. This includes Rx/Tx ++ * buffer queues, device base address, reset bit, and other information. ++ */ ++typedef struct cpsar_device ++ { ++ bit32 dev_base; ++ bit32 offset; ++ bit32 TxTeardownPending[MAX_CHAN]; ++ bit32 RxTeardownPending[MAX_CHAN]; ++ bit32 ChIsOpen[MAX_CHAN]; ++ bit32 ResetBit; ++ bit32 debug; ++ OS_DEVICE *OsDev; ++ OS_FUNCTIONS *OsFunc; ++ /*void *OsOpen;*/ ++ bit32 UniNni; ++ bit32 Inst; ++ bit32u DeviceCPID[4]; ++ bit32u LBSourceLLID[4]; ++ bit32u OamRate[11]; ++ CHANNEL_INFO ChData[MAX_CHAN]; ++ int InitCount; ++ int OpenCount; ++ char *DeviceInfo; ++ bit32u ResetBase; ++ DEVICE_STATE State; ++ CPSAR_FUNCTIONS *HalFuncPtr; ++ int OamMode; /* +GSG 030407 */ ++ }CPSARDEVICE; ++ ++extern int cpsarInitModule(CPSAR_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ CPSAR_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/cpsar.h linux.dev/drivers/atm/sangam_atm/cpsar.h +--- linux.old/drivers/atm/sangam_atm/cpsar.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpsar.h 2005-08-23 04:46:50.087845216 +0200 +@@ -0,0 +1,103 @@ ++/******************************************************************************* ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: cpsar.h ++ * ++ * DESCRIPTION: ++ * This file contains data structure definitions for the CPSAR HAL. ++ * ++ * HISTORY: ++ * 6Sep02 Greg 1.00 Original Version created. ++ * ++ *****************************************************************************/ ++#ifndef _INC_CPSAR ++#define _INC_CPSAR ++ ++#define NUM_RX_STATE_WORDS 7 ++#define NUM_TX_STATE_WORDS 9 ++#define MAX_CHAN 19 ++ ++ ++#ifndef _CPHAL_CPSAR ++typedef void CPSAR_DEVICE; ++#endif ++ ++/* ++ * HAL Default Parameter Values ++ */ ++#define CFG_UNI_NNI 0 ++ ++/** ++ * @ingroup shared_data ++ * ++ * List of defined keys for use with Control(). ++ */ ++typedef enum ++ { ++ /* SAR */ ++ enGET_FIRMWARE, /**< Used by the SAR to request a pointer to firmware */ ++ enGET_FIRMWARE_SIZE, /**< Used by the SAR to request the size of the firmware */ ++ enEND=9999 /* Last entry */ ++ }INFO_KEY; ++ ++/* ++ * The CPHAL_FUNCTIONS struct defines the CPHAL function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup)(CPSAR_DEVICE *HalDev, CHANNEL_INFO *HalCh); ++ int (*ChannelTeardown)(CPSAR_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(CPSAR_DEVICE *HalDev, int Mode); ++ int (*Control)(CPSAR_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*Init)(CPSAR_DEVICE *HalDev); ++ int (*ModeChange)(CPSAR_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(CPSAR_DEVICE *HalDev); ++ int (*Probe)(CPSAR_DEVICE *HalDev); ++ int (*Shutdown)(CPSAR_DEVICE *HalDev); ++ int (*Tick)(CPSAR_DEVICE *HalDev); ++ } CPSAR_FUNCTIONS; ++ ++/* ++ * This is the data structure for a generic HAL device. It contains all device ++ * specific data for a single instance of that device. This includes Rx/Tx ++ * buffer queues, device base address, reset bit, and other information. ++ */ ++typedef struct cpsar_device ++ { ++ bit32 dev_base; ++ bit32 offset; ++ bit32 TxTeardownPending[MAX_CHAN]; ++ bit32 RxTeardownPending[MAX_CHAN]; ++ bit32 ChIsOpen[MAX_CHAN]; ++ bit32 ResetBit; ++ bit32 debug; ++ OS_DEVICE *OsDev; ++ OS_FUNCTIONS *OsFunc; ++ /*void *OsOpen;*/ ++ bit32 UniNni; ++ bit32 Inst; ++ bit32u DeviceCPID[4]; ++ bit32u LBSourceLLID[4]; ++ bit32u OamRate[11]; ++ CHANNEL_INFO ChData[MAX_CHAN]; ++ int InitCount; ++ int OpenCount; ++ char *DeviceInfo; ++ bit32u ResetBase; ++ DEVICE_STATE State; ++ CPSAR_FUNCTIONS *HalFuncPtr; ++ int OamMode; /* +GSG 030407 */ ++ }CPSARDEVICE; ++ ++extern int cpsarInitModule(CPSAR_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ CPSAR_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/cp_sar_reg.h linux.dev/drivers/atm/sangam_atm/cp_sar_reg.h +--- linux.old/drivers/atm/sangam_atm/cp_sar_reg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cp_sar_reg.h 2005-08-23 04:46:50.087845216 +0200 +@@ -0,0 +1,217 @@ ++/*************************************************************************** ++ TNETD73xx Software Support ++ Copyright(c) 2000, Texas Instruments Incorporated. All Rights Reserved. ++ ++ FILE: cp_sar_reg.h Register definitions for the SAR module ++ ++ DESCRIPTION: ++ This include file contains register definitions for the ++ SAR module. ++ ++ HISTORY: ++ 15 Jan 02 G. Guyotte Original version written ++ 03 Oct 02 G. Guyotte C++ style comments removed ++****************************************************************************/ ++#ifndef _INC_SAR_REG ++#define _INC_SAR_REG ++ ++/* Global Registers */ ++#define pSAR_ID_REG(base) ((volatile bit32u *)(base+0x0000)) ++#define SAR_ID_REG(base) (*pSAR_ID_REG(base)) ++#define pSAR_STATUS_SET_REG(base) ((volatile bit32u *)(base+0x0008)) ++#define SAR_STATUS_SET_REG(base) (*pSAR_STATUS_SET_REG(base)) ++#define pSAR_STATUS_CLR_REG(base) ((volatile bit32u *)(base+0x000C)) ++#define SAR_STATUS_CLR_REG(base) (*pSAR_STATUS_CLR_REG(base)) ++#define pSAR_HOST_INT_EN_SET_REG(base) ((volatile bit32u *)(base+0x0010)) ++#define SAR_HOST_INT_EN_SET_REG(base) (*pSAR_HOST_INT_EN_SET_REG(base)) ++#define pSAR_HOST_INT_EN_CLR_REG(base) ((volatile bit32u *)(base+0x0014)) ++#define SAR_HOST_INT_EN_CLR_REG(base) (*pSAR_HOST_INT_EN_CLR_REG(base)) ++#define pSAR_PDSP_INT_EN_SET_REG(base) ((volatile bit32u *)(base+0x0018)) ++#define SAR_PDSP_INT_EN_SET_REG(base) (*pSAR_PDSP_INT_EN_SET_REG(base)) ++#define pSAR_PDSP_INT_EN_CLR_REG(base) ((volatile bit32u *)(base+0x001C)) ++#define SAR_PDSP_INT_EN_CLR_REG(base) (*pSAR_PDSP_INT_EN_CLR_REG(base)) ++ ++/* PDSP OAM General Purpose Registers */ ++#define pSAR_PDSP_HOST_OAM_CONFIG_REG(base) ((volatile bit32u *)(base+0x0020)) ++#define SAR_PDSP_HOST_OAM_CONFIG_REG(base) (*pSAR_PDSP_HOST_OAM_CONFIG_REG(base)) ++#define pSAR_PDSP_OAM_CORR_REG(base) ((volatile bit32u *)(base+0x0024)) ++#define SAR_PDSP_OAM_CORR_REG(base) (*pSAR_PDSP_OAM_CORR_REG(base)) ++#define pSAR_PDSP_OAM_LB_RESULT_REG(base) ((volatile bit32u *)(base+0x0028)) ++#define SAR_PDSP_OAM_LB_RESULT_REG(base) (*pSAR_PDSP_OAM_LB_RESULT_REG(base)) ++#define pSAR_PDSP_OAM_F5_LB_COUNT_REG(base) ((volatile bit32u *)(base+0x002c)) /* +GSG 030416 */ ++#define SAR_PDSP_OAM_F5_LB_COUNT_REG(base) (*pSAR_PDSP_OAM_F5_LB_COUNT_REG(base)) /* +GSG 030416 */ ++#define pSAR_PDSP_OAM_F4_LB_COUNT_REG(base) ((volatile bit32u *)(base+0x0030)) /* +GSG 030416 */ ++#define SAR_PDSP_OAM_F4_LB_COUNT_REG(base) (*pSAR_PDSP_OAM_F4_LB_COUNT_REG(base)) /* +GSG 030416 */ ++#define pSAR_PDSP_FWD_UNK_VC_REG(base) ((volatile bit32u *)(base+0x0034)) /* +GSG 030701 */ ++#define SAR_PDSP_FWD_UNK_VC_REG(base) (*pSAR_PDSP_FWD_UNK_VC_REG(base)) /* +GSG 030701 */ ++ ++ ++/* Rx Lookup Table Registers */ ++#define pRX_LUT_GLOBAL_CFG_REG(base) ((volatile bit32u *)(base+0x0080)) ++#define RX_LUT_GLOBAL_CFG_REG(base) (*pRX_LUT_GLOBAL_CFG_REG(base)) ++#define pRX_LUT_CH_SETUP_REQ_REG(base) ((volatile bit32u *)(base+0x0090)) ++#define RX_LUT_CH_SETUP_REQ_REG(base) (*pRX_LUT_CH_SETUP_REQ_REG(base)) ++#define pRX_LUT_CH_SETUP_REQ_VC_REG(base) ((volatile bit32u *)(base+0x0094)) ++#define RX_LUT_CH_SETUP_REQ_VC_REG(base) (*pRX_LUT_CH_SETUP_REQ_VC_REG(base)) ++#define pRX_LUT_CH_TEARDOWN_REQ_REG(base) ((volatile bit32u *)(base+0x009C)) ++#define RX_LUT_CH_TEARDOWN_REQ_REG(base) (*pRX_LUT_CH_TEARDOWN_REQ_REG(base)) ++ ++/* Tx Scheduler Registers */ ++#define pTX_CH_MAPPING_REG(base) ((volatile bit32u *)(base+0x0170)) ++#define TX_CH_MAPPING_REG(base) (*pTX_CH_MAPPING_REG(base)) ++ ++/* Tx CPPI DMA Controller Registers */ ++#define pTX_CPPI_CTL_REG(base) ((volatile bit32u *)(base+0x0700)) ++#define TX_CPPI_CTL_REG(base) (*pTX_CPPI_CTL_REG(base)) ++#define pTX_CPPI_TEARDOWN_REG(base) ((volatile bit32u *)(base+0x0704)) ++#define TX_CPPI_TEARDOWN_REG(base) (*pTX_CPPI_TEARDOWN_REG(base)) ++ ++/* EOI Interrupt Additions */ ++#define pSAR_EOI(base) ((volatile bit32u *)(base+0x0708)) ++#define SAR_EOI(base) (*pSAR_EOI(base)) ++#define pSAR_INTR_VECTOR(base) ((volatile bit32u *)(base+0x070c)) ++#define SAR_INTR_VECTOR(base) (*pSAR_INTR_VECTOR(base)) ++#define pSAR_TX_MASKED_STATUS(base) ((volatile bit32u *)(base+0x0710)) ++#define SAR_TX_MASKED_STATUS(base) (*pSAR_TX_MASKED_STATUS(base)) ++#define pSAR_TX_RAW_STATUS(base) ((volatile bit32u *)(base+0x0714)) ++#define SAR_TX_RAW_STATUS(base) (*pSAR_TX_RAW_STATUS(base)) ++#define pSAR_TX_MASK_SET(base) ((volatile bit32u *)(base+0x0718)) ++#define SAR_TX_MASK_SET(base) (*pSAR_TX_MASK_SET(base)) ++#define pSAR_TX_MASK_CLR(base) ((volatile bit32u *)(base+0x071c)) ++#define SAR_TX_MASK_CLR(base) (*pSAR_TX_MASK_CLR(base)) ++ ++/* Rx CPPI DMA Controller Registers */ ++#define pRX_CPPI_CTL_REG(base) ((volatile bit32u *)(base+0x0780)) ++#define RX_CPPI_CTL_REG(base) (*pRX_CPPI_CTL_REG(base)) ++#define pSAR_RX_MASKED_STATUS(base) ((volatile bit32u *)(base+0x0790)) ++#define SAR_RX_MASKED_STATUS(base) (*pSAR_RX_MASKED_STATUS(base)) ++#define pSAR_RX_RAW_STATUS(base) ((volatile bit32u *)(base+0x0794)) ++#define SAR_RX_RAW_STATUS(base) (*pSAR_RX_RAW_STATUS(base)) ++#define pSAR_RX_MASK_SET(base) ((volatile bit32u *)(base+0x0798)) ++#define SAR_RX_MASK_SET(base) (*pSAR_RX_MASK_SET(base)) ++#define pSAR_RX_MASK_CLR(base) ((volatile bit32u *)(base+0x079c)) ++#define SAR_RX_MASK_CLR(base) (*pSAR_RX_MASK_CLR(base)) ++ ++/* PDSP Control/Status Registers */ ++#define pPDSP_CTRL_REG(base) ((volatile bit32u *)(base+0x4000)) ++#define PDSP_CTRL_REG(base) (*pPDSP_CTRL_REG(base)) ++ ++/* PDSP Instruction RAM */ ++#define pPDSP_IRAM(base) ((volatile bit32u *)(base+0x4020)) ++#define PDSP_IRAM(base) (*pPDSP_IRAM(base)) ++ ++/* ++ * Channel 0 State/Scratchpad RAM Block ++ * ++ * The following registers (Tx DMA State, Rx DMA State, CPPI Completion PTR, ++ * and PDSP Data) have been given the correct address for channel 0. To ++ * reach the registers for channel X, add (X * 0x100) to the pointer address. ++ * ++ */ ++ ++#define PDSP_STATE_RAM_SIZE 1024 ++ ++/* Tx DMA State RAM */ ++#define pTX_DMA_STATE_WORD_0(base) ((volatile bit32u *)(base+0x8000)) ++#define TX_DMA_STATE_WORD_0(base) (*pTX_DMA_STATE_WORD_0(base)) ++#define pTX_DMA_STATE_WORD_1(base) ((volatile bit32u *)(base+0x8004)) ++#define TX_DMA_STATE_WORD_1(base) (*pTX_DMA_STATE_WORD_1(base)) ++#define pTX_DMA_STATE_WORD_2(base) ((volatile bit32u *)(base+0x8008)) ++#define TX_DMA_STATE_WORD_2(base) (*pTX_DMA_STATE_WORD_2(base)) ++#define pTX_DMA_STATE_WORD_3(base) ((volatile bit32u *)(base+0x800C)) ++#define TX_DMA_STATE_WORD_3(base) (*pTX_DMA_STATE_WORD_3(base)) ++#define pTX_DMA_STATE_WORD_4(base) ((volatile bit32u *)(base+0x8010)) ++#define TX_DMA_STATE_WORD_4(base) (*pTX_DMA_STATE_WORD_4(base)) ++#define pTX_DMA_STATE_WORD_5(base) ((volatile bit32u *)(base+0x8014)) ++#define TX_DMA_STATE_WORD_5(base) (*pTX_DMA_STATE_WORD_5(base)) ++#define pTX_DMA_STATE_WORD_6(base) ((volatile bit32u *)(base+0x8018)) ++#define TX_DMA_STATE_WORD_6(base) (*pTX_DMA_STATE_WORD_6(base)) ++#define pTX_DMA_STATE_WORD_7(base) ((volatile bit32u *)(base+0x801C)) ++#define TX_DMA_STATE_WORD_7(base) (*pTX_DMA_STATE_WORD_7(base)) ++#define pTX_DMA_STATE_WORD_8(base) ((volatile bit32u *)(base+0x8020)) ++#define TX_DMA_STATE_WORD_8(base) (*pTX_DMA_STATE_WORD_8(base)) ++ ++/* Rx DMA State RAM */ ++#define pRX_DMA_STATE_WORD_0(base) ((volatile bit32u *)(base+0x8024)) ++#define RX_DMA_STATE_WORD_0(base) (*pRX_DMA_STATE_WORD_0(base)) ++#define pRX_DMA_STATE_WORD_1(base) ((volatile bit32u *)(base+0x8028)) ++#define RX_DMA_STATE_WORD_1(base) (*pRX_DMA_STATE_WORD_1(base)) ++#define pRX_DMA_STATE_WORD_2(base) ((volatile bit32u *)(base+0x802C)) ++#define RX_DMA_STATE_WORD_2(base) (*pRX_DMA_STATE_WORD_2(base)) ++#define pRX_DMA_STATE_WORD_3(base) ((volatile bit32u *)(base+0x8030)) ++#define RX_DMA_STATE_WORD_3(base) (*pRX_DMA_STATE_WORD_3(base)) ++#define pRX_DMA_STATE_WORD_4(base) ((volatile bit32u *)(base+0x8034)) ++#define RX_DMA_STATE_WORD_4(base) (*pRX_DMA_STATE_WORD_4(base)) ++#define pRX_DMA_STATE_WORD_5(base) ((volatile bit32u *)(base+0x8038)) ++#define RX_DMA_STATE_WORD_5(base) (*pRX_DMA_STATE_WORD_5(base)) ++#define pRX_DMA_STATE_WORD_6(base) ((volatile bit32u *)(base+0x803C)) ++#define RX_DMA_STATE_WORD_6(base) (*pRX_DMA_STATE_WORD_6(base)) ++ ++/* Tx CPPI Completion Pointers */ ++#define pTXH_CPPI_COMP_PTR(base) ((volatile bit32u *)(base+0x8040)) ++#define TXH_CPPI_COMP_PTR(base) (*pTXH_CPPI_COMP_PTR(base)) ++#define pTXL_CPPI_COMP_PTR(base) ((volatile bit32u *)(base+0x8044)) ++#define TXL_CPPI_COMP_PTR(base) (*pTXL_CPPI_COMP_PTR(base)) ++ ++/* Rx CPPI Completion Pointer */ ++#define pRX_CPPI_COMP_PTR(base) ((volatile bit32u *)(base+0x8048)) ++#define RX_CPPI_COMP_PTR(base) (*pRX_CPPI_COMP_PTR(base)) ++ ++/* Tx PDSP Defines */ ++#define NUM_PDSP_AAL5_STATE_WORDS 24 ++#define NUM_PDSP_AAL2_STATE_WORDS 20 ++ ++/* PDSP State RAM Block 0 */ ++#define pPDSP_BLOCK_0(base) ((volatile bit32u *)(base+0x8050)) ++#define PDSP_BLOCK_0(base) (*pPDSP_BLOCK_0(base)) ++ ++/* AAL5 Tx PDSP State RAM */ ++#define pPDSP_AAL5_TX_STATE_WORD_0(base) ((volatile bit32u *)(base+0x8050)) ++#define PDSP_AAL5_TX_STATE_WORD_0(base) (*pPDSP_AAL5_TX_STATE_WORD_0(base)) ++ ++/* AAL5 Rx PDSP State RAM */ ++#define pPDSP_AAL5_RX_STATE_WORD_0(base) ((volatile bit32u *)(base+0x8070)) ++#define PDSP_AAL5_RX_STATE_WORD_0(base) (*pPDSP_AAL5_RX_STATE_WORD_0(base)) ++ ++/* AAL5 Tx VP PDSP State RAM */ ++#define pPDSP_AAL5_TX_VP_STATE_WORD_0(base) ((volatile bit32u *)(base+0x8090)) ++#define PDSP_AAL5_TX_VP_STATE_WORD_0(base) (*pPDSP_AAL5_TX_VP_STATE_WORD_0(base)) ++ ++/* AAL5 Rx VP PDSP State RAM */ ++#define pPDSP_AAL5_RX_VP_STATE_WORD_0(base) ((volatile bit32u *)(base+0x80A0)) ++#define PDSP_AAL5_RX_VP_STATE_WORD_0(base) (*pPDSP_AAL5_RX_VP_STATE_WORD_0(base)) ++ ++/* AAL2 Tx PDSP State RAM */ ++#define pPDSP_AAL2_TX_STATE_WORD_0(base) ((volatile bit32u *)(base+0x80B0)) ++#define PDSP_AAL2_TX_STATE_WORD_0(base) (*pPDSP_AAL2_TX_STATE_WORD_0(base)) ++ ++/* AAL2 Rx PDSP State RAM */ ++#define pPDSP_AAL2_RX_STATE_WORD_0(base) ((volatile bit32u *)(base+0x80D0)) ++#define PDSP_AAL2_RX_STATE_WORD_0(base) (*pPDSP_AAL2_RX_STATE_WORD_0(base)) ++ ++/* AAL2 Tx VP PDSP State RAM */ ++#define pPDSP_AAL2_TX_VP_STATE_WORD_0(base) ((volatile bit32u *)(base+0x80E0)) ++#define PDSP_AAL2_TX_VP_STATE_WORD_0(base) (*pPDSP_AAL2_TX_VP_STATE_WORD_0(base)) ++ ++/* AAL2 Rx VP PDSP State RAM */ ++#define pPDSP_AAL2_RX_VP_STATE_WORD_0(base) ((volatile bit32u *)(base+0x80F0)) ++#define PDSP_AAL2_RX_VP_STATE_WORD_0(base) (*pPDSP_AAL2_RX_VP_STATE_WORD_0(base)) ++ ++/* PDSP OAM Configuration Block */ ++#define pOAM_CONFIG_BLOCK_WORD_0(base) ((volatile bit32u *)(base+0x83C0)) ++#define OAM_CONFIG_BLOCK_WORD_0(base) (*pOAM_CONFIG_BLOCK_WORD_0(base)) ++ ++/* PDSP OAM Padding Block */ ++#define pOAM_PADDING_BLOCK_WORD_0(base) ((volatile bit32u *)(base+0x84C0)) ++#define OAM_PADDING_BLOCK_WORD_0(base) (*pOAM_PADDING_BLOCK_WORD_0(base)) ++ ++#define NUM_OAM_RATES 11 ++ ++/* PDSP OAM Timer State RAM */ ++#define pOAM_TIMER_STATE_WORD_0(base) ((volatile bit32u *)(base+0x85B0)) ++#define OAM_TIMER_STATE_WORD_0(base) (*pOAM_TIMER_STATE_WORD_0(base)) ++ ++ ++/* END OF FILE */ ++ ++#endif _INC_SAR_REG +diff -urN linux.old/drivers/atm/sangam_atm/cpswhal_cpaal5.h linux.dev/drivers/atm/sangam_atm/cpswhal_cpaal5.h +--- linux.old/drivers/atm/sangam_atm/cpswhal_cpaal5.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpswhal_cpaal5.h 2005-08-23 04:46:50.088845064 +0200 +@@ -0,0 +1,629 @@ ++/************************************************************************ ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: cphal.h ++ * ++ * DESCRIPTION: ++ * User include file, contains data definitions shared between the CPHAL ++ * and the upper-layer software. ++ * ++ * HISTORY: ++ * Date Modifier Ver Notes ++ * 28Feb02 Greg 1.00 Original ++ * 06Mar02 Greg 1.01 Documentation enhanced ++ * 18Jul02 Greg 1.02 Many updates (OAM additions, general reorg) ++ * 22Nov02 Mick RC2 Additions from Denis' input on Control ++ * ++ * author Greg Guyotte ++ * version 1.02 ++ * date 18-Jul-2002 ++ *****************************************************************************/ ++#ifndef _INC_CPHAL_H ++#define _INC_CPHAL_H ++ ++#ifdef _CPHAL_CPMAC ++#include "ec_errors_cpmac.h" ++#endif ++ ++#ifdef _CPHAL_AAL5 ++#include "ec_errors_cpaal5.h" ++#endif ++ ++#ifdef _CPHAL_CPSAR ++#include "ec_errors_cpsar.h" ++#endif ++ ++#ifdef _CPHAL_AAL2 ++#include "ec_errors_cpaal2.h" ++#endif ++ ++#ifndef __ADAM2 ++typedef char bit8; ++typedef short bit16; ++typedef int bit32; ++ ++typedef unsigned char bit8u; ++typedef unsigned short bit16u; ++typedef unsigned int bit32u; ++ ++/* ++typedef char INT8; ++typedef short INT16; ++typedef int INT32; ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++*/ ++/*typedef unsigned int size_t;*/ ++#endif ++ ++#ifdef _CPHAL ++ ++#ifndef TRUE ++#define TRUE (1==1) ++#endif ++ ++#ifndef FALSE ++#define FALSE (1==2) ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#endif ++ ++#define VirtToPhys(a) (((int)a)&~0xe0000000) ++#define VirtToVirtNoCache(a) ((void*)((VirtToPhys(a))|0xa0000000)) ++#define VirtToVirtCache(a) ((void*)((VirtToPhys(a))|0x80000000)) ++#define PhysToVirtNoCache(a) ((void*)(((int)a)|0xa0000000)) ++#define PhysToVirtCache(a) ((void*)(((int)a)|0x80000000)) ++/* ++#define DataCacheHitInvalidate(a) {__asm__(" cache 17, (%0)" : : "r" (a));} ++#define DataCacheHitWriteback(a) {__asm__(" cache 25, (%0)" : : "r" (a));} ++*/ ++ ++#define PARTIAL 1 /**< Used in @c Close() and @c ChannelTeardown() */ ++#define FULL 2 /**< Used in @c Close() and @c ChannelTeardown() */ ++ ++/* Channel Teardown Defines */ ++#define RX_TEARDOWN 2 ++#define TX_TEARDOWN 1 ++#define BLOCKING_TEARDOWN 8 ++#define FULL_TEARDOWN 4 ++#define PARTIAL_TEARDOWN 0 ++ ++#define MAX_DIR 2 ++#define DIRECTION_TX 0 ++#define DIRECTION_RX 1 ++#define TX_CH 0 ++#define RX_CH 1 ++#define HAL_ERROR_DEVICE_NOT_FOUND 1 ++#define HAL_ERROR_FAILED_MALLOC 2 ++#define HAL_ERROR_OSFUNC_SIZE 3 ++#define HAL_DEFAULT 0xFFFFFFFF ++#define VALID(val) (val!=HAL_DEFAULT) ++ ++/* ++ERROR REPORTING ++ ++HAL Module Codes. Each HAL module reporting an error code ++should OR the error code with the respective Module error code ++from the list below. ++*/ ++#define EC_AAL5 EC_HAL|EC_DEV_AAL5 ++#define EC_AAL2 EC_HAL|EC_DEV_AAL2 ++#define EC_CPSAR EC_HAL|EC_DEV_CPSAR ++#define EC_CPMAC EC_HAL|EC_DEV_CPMAC ++#define EC_VDMA EC_HAL|EC_DEV_VDMA ++#define EC_VLYNQ EC_HAL|EC_DEV_VLYNQ ++#define EC_CPPI EC_HAL|EC_DEV_CPPI ++ ++/* ++HAL Function Codes. Each HAL module reporting an error code ++should OR the error code with one of the function codes from ++the list below. ++*/ ++#define EC_FUNC_HAL_INIT EC_FUNC(1) ++#define EC_FUNC_CHSETUP EC_FUNC(2) ++#define EC_FUNC_CHTEARDOWN EC_FUNC(3) ++#define EC_FUNC_RXRETURN EC_FUNC(4) ++#define EC_FUNC_SEND EC_FUNC(5) ++#define EC_FUNC_RXINT EC_FUNC(6) ++#define EC_FUNC_TXINT EC_FUNC(7) ++#define EC_FUNC_AAL2_VDMA EC_FUNC(8) ++#define EC_FUNC_OPTIONS EC_FUNC(9) ++#define EC_FUNC_PROBE EC_FUNC(10) ++#define EC_FUNC_OPEN EC_FUNC(11) ++#define EC_FUNC_CONTROL EC_FUNC(12) ++#define EC_FUNC_DEVICE_INT EC_FUNC(13) ++#define EC_FUNC_STATUS EC_FUNC(14) ++#define EC_FUNC_TICK EC_FUNC(15) ++#define EC_FUNC_CLOSE EC_FUNC(16) ++#define EC_FUNC_SHUTDOWN EC_FUNC(17) ++#define EC_FUNC_DEVICE_INT_ALT EC_FUNC(18) /* +GSG 030306 */ ++ ++/* ++HAL Error Codes. The list below defines every type of error ++used in all HAL modules. DO NOT CHANGE THESE VALUES! Add new ++values in integer order to the bottom of the list. ++*/ ++#define EC_VAL_PDSP_LOAD_FAIL EC_ERR(0x01)|EC_CRITICAL ++#define EC_VAL_FIRMWARE_TOO_LARGE EC_ERR(0x02)|EC_CRITICAL ++#define EC_VAL_DEVICE_NOT_FOUND EC_ERR(0x03)|EC_CRITICAL ++#define EC_VAL_BASE_ADDR_NOT_FOUND EC_ERR(0x04)|EC_CRITICAL ++#define EC_VAL_RESET_BIT_NOT_FOUND EC_ERR(0x05)|EC_CRITICAL ++#define EC_VAL_CH_INFO_NOT_FOUND EC_ERR(0x06) ++#define EC_VAL_RX_STATE_RAM_NOT_CLEARED EC_ERR(0x07)|EC_CRITICAL ++#define EC_VAL_TX_STATE_RAM_NOT_CLEARED EC_ERR(0x08)|EC_CRITICAL ++#define EC_VAL_MALLOC_DEV_FAILED EC_ERR(0x09) ++#define EC_VAL_OS_VERSION_NOT_SUPPORTED EC_ERR(0x0A)|EC_CRITICAL ++#define EC_VAL_CPSAR_VERSION_NOT_SUPPORTED EC_ERR(0x0B)|EC_CRITICAL ++#define EC_VAL_NULL_CPSAR_DEV EC_ERR(0x0C)|EC_CRITICAL ++ ++#define EC_VAL_LUT_NOT_READY EC_ERR(0x0D) ++#define EC_VAL_INVALID_CH EC_ERR(0x0E) ++#define EC_VAL_NULL_CH_STRUCT EC_ERR(0x0F) ++#define EC_VAL_RX_TEARDOWN_ALREADY_PEND EC_ERR(0x10) ++#define EC_VAL_TX_TEARDOWN_ALREADY_PEND EC_ERR(0x11) ++#define EC_VAL_RX_CH_ALREADY_TORNDOWN EC_ERR(0x12) ++#define EC_VAL_TX_CH_ALREADY_TORNDOWN EC_ERR(0x13) ++#define EC_VAL_TX_TEARDOWN_TIMEOUT EC_ERR(0x14) ++#define EC_VAL_RX_TEARDOWN_TIMEOUT EC_ERR(0x15) ++#define EC_VAL_CH_ALREADY_TORNDOWN EC_ERR(0x16) ++#define EC_VAL_VC_SETUP_NOT_READY EC_ERR(0x17) ++#define EC_VAL_VC_TEARDOWN_NOT_READY EC_ERR(0x18) ++#define EC_VAL_INVALID_VC EC_ERR(0x19) ++#define EC_VAL_INVALID_LC EC_ERR(0x20) ++#define EC_VAL_INVALID_VDMA_CH EC_ERR(0x21) ++#define EC_VAL_INVALID_CID EC_ERR(0x22) ++#define EC_VAL_INVALID_UUI EC_ERR(0x23) ++#define EC_VAL_INVALID_UUI_DISCARD EC_ERR(0x24) ++#define EC_VAL_CH_ALREADY_OPEN EC_ERR(0x25) ++ ++#define EC_VAL_RCB_MALLOC_FAILED EC_ERR(0x26) ++#define EC_VAL_RX_BUFFER_MALLOC_FAILED EC_ERR(0x27) ++#define EC_VAL_OUT_OF_TCBS EC_ERR(0x28) ++#define EC_VAL_NO_TCBS EC_ERR(0x29) ++#define EC_VAL_NULL_RCB EC_ERR(0x30)|EC_CRITICAL ++#define EC_VAL_SOP_ERROR EC_ERR(0x31)|EC_CRITICAL ++#define EC_VAL_EOP_ERROR EC_ERR(0x32)|EC_CRITICAL ++#define EC_VAL_NULL_TCB EC_ERR(0x33)|EC_CRITICAL ++#define EC_VAL_CORRUPT_RCB_CHAIN EC_ERR(0x34)|EC_CRITICAL ++#define EC_VAL_TCB_MALLOC_FAILED EC_ERR(0x35) ++ ++#define EC_VAL_DISABLE_POLLING_FAILED EC_ERR(0x36) ++#define EC_VAL_KEY_NOT_FOUND EC_ERR(0x37) ++#define EC_VAL_MALLOC_FAILED EC_ERR(0x38) ++#define EC_VAL_RESET_BASE_NOT_FOUND EC_ERR(0x39)|EC_CRITICAL ++#define EC_VAL_INVALID_STATE EC_ERR(0x40) ++#define EC_VAL_NO_TXH_WORK_TO_DO EC_ERR(0x41) ++#define EC_VAL_NO_TXL_WORK_TO_DO EC_ERR(0x42) ++#define EC_VAL_NO_RX_WORK_TO_DO EC_ERR(0x43) ++#define EC_VAL_NOT_LINKED EC_ERR(0x44) ++#define EC_VAL_INTERRUPT_NOT_FOUND EC_ERR(0x45) ++#define EC_VAL_OFFSET_NOT_FOUND EC_ERR(0x46) ++#define EC_VAL_MODULE_ALREADY_CLOSED EC_ERR(0x47) ++#define EC_VAL_MODULE_ALREADY_SHUTDOWN EC_ERR(0x48) ++#define EC_VAL_ACTION_NOT_FOUND EC_ERR(0x49) ++#define EC_VAL_RX_CH_ALREADY_SETUP EC_ERR(0x50) ++#define EC_VAL_TX_CH_ALREADY_SETUP EC_ERR(0x51) ++#define EC_VAL_RX_CH_ALREADY_OPEN EC_ERR(0x52) ++#define EC_VAL_TX_CH_ALREADY_OPEN EC_ERR(0x53) ++#define EC_VAL_CH_ALREADY_SETUP EC_ERR(0x54) ++#define EC_VAL_RCB_NEEDS_BUFFER EC_ERR(0x55) /* +GSG 030410 */ ++#define EC_VAL_RCB_DROPPED EC_ERR(0x56) /* +GSG 030410 */ ++#define EC_VAL_INVALID_VALUE EC_ERR(0x57) ++ ++/** ++@defgroup shared_data Shared Data Structures ++ ++The data structures documented here are shared by all modules. ++*/ ++ ++/** ++ * @ingroup shared_data ++ * This is the fragment list structure. Each fragment list entry contains a ++ * length and a data buffer. ++ */ ++typedef struct ++ { ++ bit32u len; /**< Length of the fragment in bytes (lower 16 bits are valid). For SOP, upper 16 bits is the buffer offset. */ ++ void *data; /**< Pointer to fragment data. */ ++ void *OsInfo; /**< Pointer to OS defined data. */ ++ }FRAGLIST; ++ ++#if defined (_CPHAL_CPMAC) ++#define CB_PASSCRC_BIT (1<<26) ++ ++/* CPMAC CPHAL STATUS */ ++#define CPMAC_STATUS_LINK (1 << 0) ++#define CPMAC_STATUS_LINK_DUPLEX (1 << 1) /* 0 - HD, 1 - FD */ ++#define CPMAC_STATUS_LINK_SPEED (1 << 2) /* 0 - 10, 1 - 100 */ ++ ++/* ADAPTER CHECK Codes */ ++ ++#define CPMAC_STATUS_ADAPTER_CHECK (1 << 7) ++#define CPMAC_STATUS_HOST_ERR_DIRECTION (1 << 8) ++#define CPMAC_STATUS_HOST_ERR_CODE (0xF << 9) ++#define CPMAC_STATUS_HOST_ERR_CH (0x7 << 13) ++ ++#define _CPMDIO_DISABLE (1 << 0) ++#define _CPMDIO_HD (1 << 1) ++#define _CPMDIO_FD (1 << 2) ++#define _CPMDIO_10 (1 << 3) ++#define _CPMDIO_100 (1 << 4) ++#define _CPMDIO_NEG_OFF (1 << 5) ++#define _CPMDIO_LOOPBK (1 << 16) ++#define _CPMDIO_NOPHY (1 << 20) ++#endif ++ ++/** ++ * @ingroup shared_data ++ * Channel specific configuration information. This structure should be ++ * populated by upper-layer software prior to calling @c ChannelSetup(). Any ++ * configuration item that can be changed on a per channel basis should ++ * be represented here. Each module may define this structure with additional ++ * module-specific members. ++ */ ++typedef struct ++ { ++ int Channel; /**< Channel number. */ ++ int Direction; /**< DIRECTION_RX(1) or DIRECTION_TX(0). */ ++ OS_SETUP *OsSetup; /**< OS defined information associated with this channel. */ ++ ++#if defined(_CPHAL_AAL5) || defined (_CPHAL_CPSAR) || defined (_CPHAL_CPMAC) ++ int RxBufSize; /**< Size (in bytes) for each Rx buffer.*/ ++ int RxBufferOffset; /**< Number of bytes to offset rx data from start of buffer (must be less than buffer size). */ ++ int RxNumBuffers; /**< The number of Rx buffer descriptors to allocate for Ch. */ ++ int RxServiceMax; /**< Maximum number of packets to service at one time. */ ++ ++ int TxNumBuffers; /**< The number of Tx buffer descriptors to allocate for Ch. */ ++ int TxNumQueues; /**< Number of Tx queues for this channel (1-2). Choosing 2 enables a low priority SAR queue. */ ++ int TxServiceMax; /**< Maximum number of packets to service at one time. */ ++#endif ++ ++#if defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++ int CpcsUU; /**< The 2-byte CPCS UU and CPI information. */ ++ int Gfc; /**< Generic Flow Control. */ ++ int Clp; /**< Cell Loss Priority. */ ++ int Pti; /**< Payload Type Indication. */ ++#endif ++ ++#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++ int DaMask; /**< Specifies whether credit issuance is paused when Tx data not available. */ ++ int Priority; /**< Priority bin this channel will be scheduled within. */ ++ int PktType; /**< 0=AAL5,1=Null AAL,2=OAM,3=Transparent,4=AAL2. */ ++ int Vci; /**< Virtual Channel Identifier. */ ++ int Vpi; /**< Virtual Path Identifier. */ ++ int FwdUnkVc; /**< Enables forwarding of unknown VCI/VPI cells to host. 1=enable, 0=disable. */ ++ ++ /* Tx VC State */ ++ int TxVc_CellRate; /**< Tx rate, set as clock ticks between transmissions (SCR for VBR, CBR for CBR). */ ++ int TxVc_QosType; /**< 0=CBR,1=VBR,2=UBR,3=UBRmcr. */ ++ int TxVc_Mbs; /**< Min Burst Size in cells.*/ ++ int TxVc_Pcr; /**< Peak Cell Rate for VBR in clock ticks between transmissions. */ ++ ++ bit32 TxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Tx Ch (must be big endian with 0 PTI). */ ++ int TxVc_OamTc; /**< TC Path to transmit OAM cells for TX connection (0,1). */ ++ int TxVc_VpOffset; /**< Offset to the OAM VP state table. */ ++ /* Rx VC State */ ++ int RxVc_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ ++ int RxVc_OamToHost; /**< 0=do not pass, 1=pass. */ ++ bit32 RxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx conn (must be big endian with 0 PTI). */ ++ int RxVc_OamTc; /**< TC Path to transmit OAM cells for RX connection (0,1). */ ++ int RxVc_VpOffset; /**< Offset to the OAM VP state table. */ ++ /* Tx VP State */ ++ int TxVp_OamTc; /**< TC Path to transmit OAM cells for TX VP connection (0,1). */ ++ bit32 TxVp_AtmHeader; /**< ATM Header placed on firmware gen'd VP OAM cells for this Tx VP conn (must be big endian with 0 VCI). */ ++ /* Rx VP State */ ++ int RxVp_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ ++ int RxVp_OamToHost; /**< 0=do not pass, 1=pass. */ ++ bit32 RxVp_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx VP conn (must be big endian with 0 VCI). */ ++ int RxVp_OamTc; /**< TC Path to transmit OAM cells for RX VP connection (0,1). */ ++ int RxVp_OamVcList; /**< Indicates all VC channels associated with this VP channel (one-hot encoded). */ ++#endif ++ ++ ++#ifdef _CPHAL_VDMAVT ++ bit32u RemFifoAddr; /* Mirror mode only. */ ++ bit32u FifoAddr; ++ bit32 PollInt; ++ bit32 FifoSize; ++ int Ready; ++#endif ++ ++ }CHANNEL_INFO; ++ ++/* ++ * This structure contains each statistic value gathered by the CPHAL. ++ * Applications may access statistics data by using the @c StatsGet() routine. ++ */ ++/* STATS */ ++#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++typedef struct ++ { ++ bit32u CrcErrors[16]; ++ bit32u LenErrors[16]; ++ bit32u DmaLenErrors[16]; ++ bit32u AbortErrors[16]; ++ bit32u StarvErrors[16]; ++ bit32u TxMisQCnt[16][2]; ++ bit32u RxMisQCnt[16]; ++ bit32u RxEOQCnt[16]; ++ bit32u TxEOQCnt[16][2]; ++ bit32u RxPacketsServiced[16]; ++ bit32u TxPacketsServiced[16][2]; ++ bit32u RxMaxServiced; ++ bit32u TxMaxServiced[16][2]; ++ bit32u RxTotal; ++ bit32u TxTotal; ++ } STAT_INFO; ++#endif ++ ++/* ++ * VDMA Channel specific configuration information ++ */ ++#ifdef _CPHAL_AAL2 ++typedef struct ++ { ++ int Ch; /**< Channel Number */ ++ int RemoteEndian; /**< Endianness of remote VDMA-VT device */ ++ int CpsSwap; /**< When 0, octet 0 in CPS pkt located in LS byte of 16-bit word sent to rem VDMA device. When 1, in MS byte. */ ++ }VdmaChInfo; ++#endif ++ ++#ifndef _CPHAL ++ typedef void HAL_DEVICE; ++ typedef void HAL_PRIVATE; ++ typedef void HAL_RCB; ++ typedef void HAL_RECEIVEINFO; ++#endif ++ ++/** ++ * @ingroup shared_data ++ * The HAL_FUNCTIONS struct defines the function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to xxxInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup) (HAL_DEVICE *HalDev, CHANNEL_INFO *Channel, OS_SETUP *OsSetup); ++ int (*ChannelTeardown) (HAL_DEVICE *HalDev, int Channel, int Mode); ++ int (*Close) (HAL_DEVICE *HalDev, int Mode); ++ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*Init) (HAL_DEVICE *HalDev); ++ int (*Open) (HAL_DEVICE *HalDev); ++ int (*PacketProcessEnd) (HAL_DEVICE *HalDev); ++ int (*Probe) (HAL_DEVICE *HalDev); ++ int (*RxReturn) (HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); ++ int (*Send) (HAL_DEVICE *HalDev, FRAGLIST *FragList, int FragCount, int PacketSize, OS_SENDINFO *OsSendInfo, bit32u Mode); ++ int (*Shutdown) (HAL_DEVICE *HalDev); ++ int (*Tick) (HAL_DEVICE *HalDev); ++ ++#ifdef _CPHAL_AAL5 ++ int (*Kick) (HAL_DEVICE *HalDev, int Queue); ++ void (*OamFuncConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig); ++ void (*OamLoopbackConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig, unsigned int *LLID, unsigned int CorrelationTag); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ STAT_INFO* (*StatsGetOld)(HAL_DEVICE *HalDev); ++#endif ++ } HAL_FUNCTIONS; ++ ++/** ++ * @ingroup shared_data ++ * The OS_FUNCTIONS struct defines the function pointers for all upper layer ++ * functions accessible to the CPHAL. The upper layer software is responsible ++ * for providing the correct OS-specific implementations for the following ++ * functions. It is populated by calling InitModule() (done by the CPHAL in ++ * xxxInitModule(). ++ */ ++typedef struct ++ { ++ int (*Control)(OS_DEVICE *OsDev, const char *Key, const char *Action, void *Value); ++ void (*CriticalOn)(void); ++ void (*CriticalOff)(void); ++ void (*DataCacheHitInvalidate)(void *MemPtr, int Size); ++ void (*DataCacheHitWriteback)(void *MemPtr, int Size); ++ int (*DeviceFindInfo)(int Inst, const char *DeviceName, void *DeviceInfo); ++ int (*DeviceFindParmUint)(void *DeviceInfo, const char *Parm, bit32u *Value); ++ int (*DeviceFindParmValue)(void *DeviceInfo, const char *Parm, void *Value); ++ void (*Free)(void *MemPtr); ++ void (*FreeRxBuffer)(OS_RECEIVEINFO *OsReceiveInfo, void *MemPtr); ++ void (*FreeDev)(void *MemPtr); ++ void (*FreeDmaXfer)(void *MemPtr); ++ void (*IsrRegister)(OS_DEVICE *OsDev, int (*halISR)(HAL_DEVICE*, int*), int InterruptBit); ++ void (*IsrUnRegister)(OS_DEVICE *OsDev, int InterruptBit); ++ void* (*Malloc)(bit32u size); ++ void* (*MallocDev)(bit32u Size); ++ void* (*MallocDmaXfer)(bit32u size, void *MemBase, bit32u MemRange); ++ void* (*MallocRxBuffer)(bit32u size, void *MemBase, bit32u MemRange, ++ OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo, ++ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev); ++ void* (*Memset)(void *Dest, int C, bit32u N); ++ int (*Printf)(const char *Format, ...); ++ int (*Receive)(OS_DEVICE *OsDev,FRAGLIST *FragList,bit32u FragCount, ++ bit32u PacketSize,HAL_RECEIVEINFO *HalReceiveInfo, bit32u Mode); ++ int (*SendComplete)(OS_SENDINFO *OsSendInfo); ++ int (*Sprintf)(char *S, const char *Format, ...); ++ int (*Strcmpi)(const char *Str1, const char *Str2); ++ unsigned int (*Strlen)(const char *S); ++ char* (*Strstr)(const char *S1, const char *S2); ++ unsigned long (*Strtoul)(const char *Str, char **Endptr, int Base); ++ void (*TeardownComplete)(OS_DEVICE *OsDev, int Ch, int Direction); ++ } OS_FUNCTIONS; ++ ++/************** MODULE SPECIFIC STUFF BELOW **************/ ++ ++#ifdef _CPHAL_CPMAC ++ ++/* ++int halCpmacInitModule(HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, int (*osBridgeInitModule)(OS_FUNCTIONS *), void* (*osMallocDev) (bit32u), int *Size, int inst); ++*/ ++ ++int halCpmacInitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_AAL5 ++/* ++ * @ingroup shared_data ++ * The AAL5_FUNCTIONS struct defines the AAL5 function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++/* ++typedef struct ++ { ++ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(HAL_DEVICE *HalDev, int Mode); ++ int (*Init)(HAL_DEVICE *HalDev); ++ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(HAL_DEVICE *HalDev); ++ int (*InfoGet)(HAL_DEVICE *HalDev, int Key, void *Value); ++ int (*Probe)(HAL_DEVICE *HalDev); ++ int (*RxReturn)(HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); ++ int (*Send)(HAL_DEVICE *HalDev,FRAGLIST *FragList,int FragCount, ++ int PacketSize,OS_SENDINFO *OsSendInfo,int Ch, int Queue, ++ bit32u Mode); ++ int (*StatsClear)(HAL_DEVICE *HalDev); ++ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); ++ int (*Status)(HAL_DEVICE *HalDev); ++ void (*Tick)(HAL_DEVICE *HalDev); ++ int (*Kick)(HAL_DEVICE *HalDev, int Queue); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ } AAL5_FUNCTIONS; ++*/ ++ ++int cpaal5InitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_AAL2 ++/** ++ * @ingroup shared_data ++ * The AAL2_FUNCTIONS struct defines the AAL2 function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(HAL_DEVICE *HalDev, int Mode); ++ int (*Init)(HAL_DEVICE *HalDev); ++ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(HAL_DEVICE *HalDev); ++ int (*OptionsGet)(HAL_DEVICE *HalDev, char *Key, bit32u *Value); ++ int (*Probe)(HAL_DEVICE *HalDev); ++ ++ int (*StatsClear)(HAL_DEVICE *HalDev); ++ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); ++ int (*Status)(HAL_DEVICE *HalDev); ++ void (*Tick)(HAL_DEVICE *HalDev); ++ int (*Aal2UuiMappingSetup)(HAL_DEVICE *HalDev, int VC, int UUI, ++ int VdmaCh, int UUIDiscard); ++ int (*Aal2RxMappingSetup)(HAL_DEVICE *HalDev, int VC, int CID, ++ int LC); ++ int (*Aal2TxMappingSetup)(HAL_DEVICE *HalDev, int VC, int LC, int VdmaCh); ++ int (*Aal2VdmaChSetup)(HAL_DEVICE *HalDev, bit32u RemVdmaVtAddr, ++ VdmaChInfo *VdmaCh); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ int (*Aal2ModeChange)(HAL_DEVICE *HalDev, int Vc, int RxCrossMode, ++ int RxMultiMode, int TxMultiMode, int SchedMode, ++ int TcCh); ++ void (*Aal2VdmaEnable)(HAL_DEVICE *HalDev, int Ch); ++ int (*Aal2VdmaDisable)(HAL_DEVICE *HalDev, int Ch); ++ } AAL2_FUNCTIONS; ++ ++int cpaal2InitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ AAL2_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_VDMAVT ++/** ++ * @ingroup shared_data ++ * The VDMA_FUNCTIONS struct defines the HAL function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to InitModule(). ++ * ++ * Note that this list is still under definition. ++ */ ++typedef struct ++ { ++ bit32 (*Init)( HAL_DEVICE *VdmaVtDev); ++ /* bit32 (*SetupTxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, ++ bit32u Addr, bit32u Size, bit32u PollInt); ++ bit32 (*SetupRxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, ++ bit32u Addr, bit32u Size, bit32u PollInt); */ ++ bit32 (*Tx)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Rx)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*SetRemoteChannel)(HAL_DEVICE *VdmaVtDev, bit32u RemAddr, ++ bit32u RemDevID); ++ bit32 (*ClearRxInt)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*ClearTxInt)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Open)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Close)(HAL_DEVICE *VdmaVtDev); ++ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*ChannelSetup)(HAL_DEVICE *VdmaVtDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *VdmaVtDev, int Ch, int Mode); ++ int (*Send)(HAL_DEVICE *VdmaVtDev,FRAGLIST *FragList,int FragCount, ++ int PacketSize,OS_SENDINFO *OsSendInfo,bit32u Mode); ++ } VDMA_FUNCTIONS; ++ ++int VdmaInitModule(HAL_DEVICE **VdmaVt, ++ OS_DEVICE *OsDev, ++ VDMA_FUNCTIONS **VdmaVtFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++/* ++extern int cphalInitModule(MODULE_TYPE ModuleType, HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, ++ int (*osInitModule)(OS_FUNCTIONS *), void* (*osMallocDev)(bit32u), ++ int *Size, int Inst); ++*/ ++ ++ ++#ifdef _CPHAL_AAL5 ++extern const char hcSarFrequency[]; ++#endif ++ ++#ifdef _CPHAL_CPMAC ++/* following will be common, once 'utl' added */ ++extern const char hcClear[]; ++extern const char hcGet[]; ++extern const char hcSet[]; ++extern const char hcTick[]; ++ ++extern const char hcCpuFrequency[]; ++extern const char hcCpmacFrequency[]; ++extern const char hcMdioBusFrequency[]; ++extern const char hcMdioClockFrequency[]; ++extern const char hcCpmacBase[]; ++extern const char hcPhyNum[]; ++extern const char hcSize[]; ++extern const char hcCpmacSize[]; ++extern const char hcPhyAccess[]; ++#endif ++ ++#endif /* end of _INC_ */ +diff -urN linux.old/drivers/atm/sangam_atm/cpswhal_cpsar.h linux.dev/drivers/atm/sangam_atm/cpswhal_cpsar.h +--- linux.old/drivers/atm/sangam_atm/cpswhal_cpsar.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/cpswhal_cpsar.h 2005-08-23 04:46:50.089844912 +0200 +@@ -0,0 +1,629 @@ ++/************************************************************************ ++ * TNETDxxxx Software Support ++ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. ++ * ++ * FILE: cphal.h ++ * ++ * DESCRIPTION: ++ * User include file, contains data definitions shared between the CPHAL ++ * and the upper-layer software. ++ * ++ * HISTORY: ++ * Date Modifier Ver Notes ++ * 28Feb02 Greg 1.00 Original ++ * 06Mar02 Greg 1.01 Documentation enhanced ++ * 18Jul02 Greg 1.02 Many updates (OAM additions, general reorg) ++ * 22Nov02 Mick RC2 Additions from Denis' input on Control ++ * ++ * author Greg Guyotte ++ * version 1.02 ++ * date 18-Jul-2002 ++ *****************************************************************************/ ++#ifndef _INC_CPHAL_H ++#define _INC_CPHAL_H ++ ++#ifdef _CPHAL_CPMAC ++#include "ec_errors_cpmac.h" ++#endif ++ ++#ifdef _CPHAL_AAL5 ++#include "ec_errors_cpaal5.h" ++#endif ++ ++#ifdef _CPHAL_CPSAR ++#include "ec_errors_cpsar.h" ++#endif ++ ++#ifdef _CPHAL_AAL2 ++#include "ec_errors_cpaal2.h" ++#endif ++ ++#ifndef __ADAM2 ++typedef char bit8; ++typedef short bit16; ++typedef int bit32; ++ ++typedef unsigned char bit8u; ++typedef unsigned short bit16u; ++typedef unsigned int bit32u; ++ ++/* ++typedef char INT8; ++typedef short INT16; ++typedef int INT32; ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++*/ ++/*typedef unsigned int size_t;*/ ++#endif ++ ++#ifdef _CPHAL ++ ++#ifndef TRUE ++#define TRUE (1==1) ++#endif ++ ++#ifndef FALSE ++#define FALSE (1==2) ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#endif ++ ++#define VirtToPhys(a) (((int)a)&~0xe0000000) ++#define VirtToVirtNoCache(a) ((void*)((VirtToPhys(a))|0xa0000000)) ++#define VirtToVirtCache(a) ((void*)((VirtToPhys(a))|0x80000000)) ++#define PhysToVirtNoCache(a) ((void*)(((int)a)|0xa0000000)) ++#define PhysToVirtCache(a) ((void*)(((int)a)|0x80000000)) ++/* ++#define DataCacheHitInvalidate(a) {__asm__(" cache 17, (%0)" : : "r" (a));} ++#define DataCacheHitWriteback(a) {__asm__(" cache 25, (%0)" : : "r" (a));} ++*/ ++ ++#define PARTIAL 1 /**< Used in @c Close() and @c ChannelTeardown() */ ++#define FULL 2 /**< Used in @c Close() and @c ChannelTeardown() */ ++ ++/* Channel Teardown Defines */ ++#define RX_TEARDOWN 2 ++#define TX_TEARDOWN 1 ++#define BLOCKING_TEARDOWN 8 ++#define FULL_TEARDOWN 4 ++#define PARTIAL_TEARDOWN 0 ++ ++#define MAX_DIR 2 ++#define DIRECTION_TX 0 ++#define DIRECTION_RX 1 ++#define TX_CH 0 ++#define RX_CH 1 ++#define HAL_ERROR_DEVICE_NOT_FOUND 1 ++#define HAL_ERROR_FAILED_MALLOC 2 ++#define HAL_ERROR_OSFUNC_SIZE 3 ++#define HAL_DEFAULT 0xFFFFFFFF ++#define VALID(val) (val!=HAL_DEFAULT) ++ ++/* ++ERROR REPORTING ++ ++HAL Module Codes. Each HAL module reporting an error code ++should OR the error code with the respective Module error code ++from the list below. ++*/ ++#define EC_AAL5 EC_HAL|EC_DEV_AAL5 ++#define EC_AAL2 EC_HAL|EC_DEV_AAL2 ++#define EC_CPSAR EC_HAL|EC_DEV_CPSAR ++#define EC_CPMAC EC_HAL|EC_DEV_CPMAC ++#define EC_VDMA EC_HAL|EC_DEV_VDMA ++#define EC_VLYNQ EC_HAL|EC_DEV_VLYNQ ++#define EC_CPPI EC_HAL|EC_DEV_CPPI ++ ++/* ++HAL Function Codes. Each HAL module reporting an error code ++should OR the error code with one of the function codes from ++the list below. ++*/ ++#define EC_FUNC_HAL_INIT EC_FUNC(1) ++#define EC_FUNC_CHSETUP EC_FUNC(2) ++#define EC_FUNC_CHTEARDOWN EC_FUNC(3) ++#define EC_FUNC_RXRETURN EC_FUNC(4) ++#define EC_FUNC_SEND EC_FUNC(5) ++#define EC_FUNC_RXINT EC_FUNC(6) ++#define EC_FUNC_TXINT EC_FUNC(7) ++#define EC_FUNC_AAL2_VDMA EC_FUNC(8) ++#define EC_FUNC_OPTIONS EC_FUNC(9) ++#define EC_FUNC_PROBE EC_FUNC(10) ++#define EC_FUNC_OPEN EC_FUNC(11) ++#define EC_FUNC_CONTROL EC_FUNC(12) ++#define EC_FUNC_DEVICE_INT EC_FUNC(13) ++#define EC_FUNC_STATUS EC_FUNC(14) ++#define EC_FUNC_TICK EC_FUNC(15) ++#define EC_FUNC_CLOSE EC_FUNC(16) ++#define EC_FUNC_SHUTDOWN EC_FUNC(17) ++#define EC_FUNC_DEVICE_INT_ALT EC_FUNC(18) /* +GSG 030306 */ ++ ++/* ++HAL Error Codes. The list below defines every type of error ++used in all HAL modules. DO NOT CHANGE THESE VALUES! Add new ++values in integer order to the bottom of the list. ++*/ ++#define EC_VAL_PDSP_LOAD_FAIL EC_ERR(0x01)|EC_CRITICAL ++#define EC_VAL_FIRMWARE_TOO_LARGE EC_ERR(0x02)|EC_CRITICAL ++#define EC_VAL_DEVICE_NOT_FOUND EC_ERR(0x03)|EC_CRITICAL ++#define EC_VAL_BASE_ADDR_NOT_FOUND EC_ERR(0x04)|EC_CRITICAL ++#define EC_VAL_RESET_BIT_NOT_FOUND EC_ERR(0x05)|EC_CRITICAL ++#define EC_VAL_CH_INFO_NOT_FOUND EC_ERR(0x06) ++#define EC_VAL_RX_STATE_RAM_NOT_CLEARED EC_ERR(0x07)|EC_CRITICAL ++#define EC_VAL_TX_STATE_RAM_NOT_CLEARED EC_ERR(0x08)|EC_CRITICAL ++#define EC_VAL_MALLOC_DEV_FAILED EC_ERR(0x09) ++#define EC_VAL_OS_VERSION_NOT_SUPPORTED EC_ERR(0x0A)|EC_CRITICAL ++#define EC_VAL_CPSAR_VERSION_NOT_SUPPORTED EC_ERR(0x0B)|EC_CRITICAL ++#define EC_VAL_NULL_CPSAR_DEV EC_ERR(0x0C)|EC_CRITICAL ++ ++#define EC_VAL_LUT_NOT_READY EC_ERR(0x0D) ++#define EC_VAL_INVALID_CH EC_ERR(0x0E) ++#define EC_VAL_NULL_CH_STRUCT EC_ERR(0x0F) ++#define EC_VAL_RX_TEARDOWN_ALREADY_PEND EC_ERR(0x10) ++#define EC_VAL_TX_TEARDOWN_ALREADY_PEND EC_ERR(0x11) ++#define EC_VAL_RX_CH_ALREADY_TORNDOWN EC_ERR(0x12) ++#define EC_VAL_TX_CH_ALREADY_TORNDOWN EC_ERR(0x13) ++#define EC_VAL_TX_TEARDOWN_TIMEOUT EC_ERR(0x14) ++#define EC_VAL_RX_TEARDOWN_TIMEOUT EC_ERR(0x15) ++#define EC_VAL_CH_ALREADY_TORNDOWN EC_ERR(0x16) ++#define EC_VAL_VC_SETUP_NOT_READY EC_ERR(0x17) ++#define EC_VAL_VC_TEARDOWN_NOT_READY EC_ERR(0x18) ++#define EC_VAL_INVALID_VC EC_ERR(0x19) ++#define EC_VAL_INVALID_LC EC_ERR(0x20) ++#define EC_VAL_INVALID_VDMA_CH EC_ERR(0x21) ++#define EC_VAL_INVALID_CID EC_ERR(0x22) ++#define EC_VAL_INVALID_UUI EC_ERR(0x23) ++#define EC_VAL_INVALID_UUI_DISCARD EC_ERR(0x24) ++#define EC_VAL_CH_ALREADY_OPEN EC_ERR(0x25) ++ ++#define EC_VAL_RCB_MALLOC_FAILED EC_ERR(0x26) ++#define EC_VAL_RX_BUFFER_MALLOC_FAILED EC_ERR(0x27) ++#define EC_VAL_OUT_OF_TCBS EC_ERR(0x28) ++#define EC_VAL_NO_TCBS EC_ERR(0x29) ++#define EC_VAL_NULL_RCB EC_ERR(0x30)|EC_CRITICAL ++#define EC_VAL_SOP_ERROR EC_ERR(0x31)|EC_CRITICAL ++#define EC_VAL_EOP_ERROR EC_ERR(0x32)|EC_CRITICAL ++#define EC_VAL_NULL_TCB EC_ERR(0x33)|EC_CRITICAL ++#define EC_VAL_CORRUPT_RCB_CHAIN EC_ERR(0x34)|EC_CRITICAL ++#define EC_VAL_TCB_MALLOC_FAILED EC_ERR(0x35) ++ ++#define EC_VAL_DISABLE_POLLING_FAILED EC_ERR(0x36) ++#define EC_VAL_KEY_NOT_FOUND EC_ERR(0x37) ++#define EC_VAL_MALLOC_FAILED EC_ERR(0x38) ++#define EC_VAL_RESET_BASE_NOT_FOUND EC_ERR(0x39)|EC_CRITICAL ++#define EC_VAL_INVALID_STATE EC_ERR(0x40) ++#define EC_VAL_NO_TXH_WORK_TO_DO EC_ERR(0x41) ++#define EC_VAL_NO_TXL_WORK_TO_DO EC_ERR(0x42) ++#define EC_VAL_NO_RX_WORK_TO_DO EC_ERR(0x43) ++#define EC_VAL_NOT_LINKED EC_ERR(0x44) ++#define EC_VAL_INTERRUPT_NOT_FOUND EC_ERR(0x45) ++#define EC_VAL_OFFSET_NOT_FOUND EC_ERR(0x46) ++#define EC_VAL_MODULE_ALREADY_CLOSED EC_ERR(0x47) ++#define EC_VAL_MODULE_ALREADY_SHUTDOWN EC_ERR(0x48) ++#define EC_VAL_ACTION_NOT_FOUND EC_ERR(0x49) ++#define EC_VAL_RX_CH_ALREADY_SETUP EC_ERR(0x50) ++#define EC_VAL_TX_CH_ALREADY_SETUP EC_ERR(0x51) ++#define EC_VAL_RX_CH_ALREADY_OPEN EC_ERR(0x52) ++#define EC_VAL_TX_CH_ALREADY_OPEN EC_ERR(0x53) ++#define EC_VAL_CH_ALREADY_SETUP EC_ERR(0x54) ++#define EC_VAL_RCB_NEEDS_BUFFER EC_ERR(0x55) /* +GSG 030410 */ ++#define EC_VAL_RCB_DROPPED EC_ERR(0x56) /* +GSG 030410 */ ++#define EC_VAL_INVALID_VALUE EC_ERR(0x57) ++ ++/** ++@defgroup shared_data Shared Data Structures ++ ++The data structures documented here are shared by all modules. ++*/ ++ ++/** ++ * @ingroup shared_data ++ * This is the fragment list structure. Each fragment list entry contains a ++ * length and a data buffer. ++ */ ++typedef struct ++ { ++ bit32u len; /**< Length of the fragment in bytes (lower 16 bits are valid). For SOP, upper 16 bits is the buffer offset. */ ++ void *data; /**< Pointer to fragment data. */ ++ void *OsInfo; /**< Pointer to OS defined data. */ ++ }FRAGLIST; ++ ++#if defined (_CPHAL_CPMAC) ++#define CB_PASSCRC_BIT (1<<26) ++ ++/* CPMAC CPHAL STATUS */ ++#define CPMAC_STATUS_LINK (1 << 0) ++#define CPMAC_STATUS_LINK_DUPLEX (1 << 1) /* 0 - HD, 1 - FD */ ++#define CPMAC_STATUS_LINK_SPEED (1 << 2) /* 0 - 10, 1 - 100 */ ++ ++/* ADAPTER CHECK Codes */ ++ ++#define CPMAC_STATUS_ADAPTER_CHECK (1 << 7) ++#define CPMAC_STATUS_HOST_ERR_DIRECTION (1 << 8) ++#define CPMAC_STATUS_HOST_ERR_CODE (0xF << 9) ++#define CPMAC_STATUS_HOST_ERR_CH (0x7 << 13) ++ ++#define _CPMDIO_DISABLE (1 << 0) ++#define _CPMDIO_HD (1 << 1) ++#define _CPMDIO_FD (1 << 2) ++#define _CPMDIO_10 (1 << 3) ++#define _CPMDIO_100 (1 << 4) ++#define _CPMDIO_NEG_OFF (1 << 5) ++#define _CPMDIO_LOOPBK (1 << 16) ++#define _CPMDIO_NOPHY (1 << 20) ++#endif ++ ++/** ++ * @ingroup shared_data ++ * Channel specific configuration information. This structure should be ++ * populated by upper-layer software prior to calling @c ChannelSetup(). Any ++ * configuration item that can be changed on a per channel basis should ++ * be represented here. Each module may define this structure with additional ++ * module-specific members. ++ */ ++typedef struct ++ { ++ int Channel; /**< Channel number. */ ++ int Direction; /**< DIRECTION_RX(1) or DIRECTION_TX(0). */ ++ OS_SETUP *OsSetup; /**< OS defined information associated with this channel. */ ++ ++#if defined(_CPHAL_AAL5) || defined (_CPHAL_CPSAR) || defined (_CPHAL_CPMAC) ++ int RxBufSize; /**< Size (in bytes) for each Rx buffer.*/ ++ int RxBufferOffset; /**< Number of bytes to offset rx data from start of buffer (must be less than buffer size). */ ++ int RxNumBuffers; /**< The number of Rx buffer descriptors to allocate for Ch. */ ++ int RxServiceMax; /**< Maximum number of packets to service at one time. */ ++ ++ int TxNumBuffers; /**< The number of Tx buffer descriptors to allocate for Ch. */ ++ int TxNumQueues; /**< Number of Tx queues for this channel (1-2). Choosing 2 enables a low priority SAR queue. */ ++ int TxServiceMax; /**< Maximum number of packets to service at one time. */ ++#endif ++ ++#if defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++ int CpcsUU; /**< The 2-byte CPCS UU and CPI information. */ ++ int Gfc; /**< Generic Flow Control. */ ++ int Clp; /**< Cell Loss Priority. */ ++ int Pti; /**< Payload Type Indication. */ ++#endif ++ ++#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++ int DaMask; /**< Specifies whether credit issuance is paused when Tx data not available. */ ++ int Priority; /**< Priority bin this channel will be scheduled within. */ ++ int PktType; /**< 0=AAL5,1=Null AAL,2=OAM,3=Transparent,4=AAL2. */ ++ int Vci; /**< Virtual Channel Identifier. */ ++ int Vpi; /**< Virtual Path Identifier. */ ++ int FwdUnkVc; /**< Enables forwarding of unknown VCI/VPI cells to host. 1=enable, 0=disable. */ ++ ++ /* Tx VC State */ ++ int TxVc_CellRate; /**< Tx rate, set as clock ticks between transmissions (SCR for VBR, CBR for CBR). */ ++ int TxVc_QosType; /**< 0=CBR,1=VBR,2=UBR,3=UBRmcr. */ ++ int TxVc_Mbs; /**< Min Burst Size in cells.*/ ++ int TxVc_Pcr; /**< Peak Cell Rate for VBR in clock ticks between transmissions. */ ++ ++ bit32 TxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Tx Ch (must be big endian with 0 PTI). */ ++ int TxVc_OamTc; /**< TC Path to transmit OAM cells for TX connection (0,1). */ ++ int TxVc_VpOffset; /**< Offset to the OAM VP state table. */ ++ /* Rx VC State */ ++ int RxVc_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ ++ int RxVc_OamToHost; /**< 0=do not pass, 1=pass. */ ++ bit32 RxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx conn (must be big endian with 0 PTI). */ ++ int RxVc_OamTc; /**< TC Path to transmit OAM cells for RX connection (0,1). */ ++ int RxVc_VpOffset; /**< Offset to the OAM VP state table. */ ++ /* Tx VP State */ ++ int TxVp_OamTc; /**< TC Path to transmit OAM cells for TX VP connection (0,1). */ ++ bit32 TxVp_AtmHeader; /**< ATM Header placed on firmware gen'd VP OAM cells for this Tx VP conn (must be big endian with 0 VCI). */ ++ /* Rx VP State */ ++ int RxVp_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ ++ int RxVp_OamToHost; /**< 0=do not pass, 1=pass. */ ++ bit32 RxVp_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx VP conn (must be big endian with 0 VCI). */ ++ int RxVp_OamTc; /**< TC Path to transmit OAM cells for RX VP connection (0,1). */ ++ int RxVp_OamVcList; /**< Indicates all VC channels associated with this VP channel (one-hot encoded). */ ++#endif ++ ++ ++#ifdef _CPHAL_VDMAVT ++ bit32u RemFifoAddr; /* Mirror mode only. */ ++ bit32u FifoAddr; ++ bit32 PollInt; ++ bit32 FifoSize; ++ int Ready; ++#endif ++ ++ }CHANNEL_INFO; ++ ++/* ++ * This structure contains each statistic value gathered by the CPHAL. ++ * Applications may access statistics data by using the @c StatsGet() routine. ++ */ ++/* STATS */ ++#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) ++typedef struct ++ { ++ bit32u CrcErrors[16]; ++ bit32u LenErrors[16]; ++ bit32u DmaLenErrors[16]; ++ bit32u AbortErrors[16]; ++ bit32u StarvErrors[16]; ++ bit32u TxMisQCnt[16][2]; ++ bit32u RxMisQCnt[16]; ++ bit32u RxEOQCnt[16]; ++ bit32u TxEOQCnt[16][2]; ++ bit32u RxPacketsServiced[16]; ++ bit32u TxPacketsServiced[16][2]; ++ bit32u RxMaxServiced; ++ bit32u TxMaxServiced[16][2]; ++ bit32u RxTotal; ++ bit32u TxTotal; ++ } STAT_INFO; ++#endif ++ ++/* ++ * VDMA Channel specific configuration information ++ */ ++#ifdef _CPHAL_AAL2 ++typedef struct ++ { ++ int Ch; /**< Channel Number */ ++ int RemoteEndian; /**< Endianness of remote VDMA-VT device */ ++ int CpsSwap; /**< When 0, octet 0 in CPS pkt located in LS byte of 16-bit word sent to rem VDMA device. When 1, in MS byte. */ ++ }VdmaChInfo; ++#endif ++ ++#ifndef _CPHAL ++ typedef void HAL_DEVICE; ++ typedef void HAL_PRIVATE; ++ typedef void HAL_RCB; ++ typedef void HAL_RECEIVEINFO; ++#endif ++ ++/** ++ * @ingroup shared_data ++ * The HAL_FUNCTIONS struct defines the function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to xxxInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup) (HAL_DEVICE *HalDev, CHANNEL_INFO *Channel, OS_SETUP *OsSetup); ++ int (*ChannelTeardown) (HAL_DEVICE *HalDev, int Channel, int Mode); ++ int (*Close) (HAL_DEVICE *HalDev, int Mode); ++ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*Init) (HAL_DEVICE *HalDev); ++ int (*Open) (HAL_DEVICE *HalDev); ++ int (*PacketProcessEnd) (HAL_DEVICE *HalDev); ++ int (*Probe) (HAL_DEVICE *HalDev); ++ int (*RxReturn) (HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); ++ int (*Send) (HAL_DEVICE *HalDev, FRAGLIST *FragList, int FragCount, int PacketSize, OS_SENDINFO *OsSendInfo, bit32u Mode); ++ int (*Shutdown) (HAL_DEVICE *HalDev); ++ int (*Tick) (HAL_DEVICE *HalDev); ++ ++#ifdef _CPHAL_AAL5 ++ int (*Kick) (HAL_DEVICE *HalDev, int Queue); ++ void (*OamFuncConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig); ++ void (*OamLoopbackConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig, unsigned int *LLID, unsigned int CorrelationTag); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ STAT_INFO* (*StatsGetOld)(HAL_DEVICE *HalDev); ++#endif ++ } HAL_FUNCTIONS; ++ ++/** ++ * @ingroup shared_data ++ * The OS_FUNCTIONS struct defines the function pointers for all upper layer ++ * functions accessible to the CPHAL. The upper layer software is responsible ++ * for providing the correct OS-specific implementations for the following ++ * functions. It is populated by calling InitModule() (done by the CPHAL in ++ * xxxInitModule(). ++ */ ++typedef struct ++ { ++ int (*Control)(OS_DEVICE *OsDev, const char *Key, const char *Action, void *Value); ++ void (*CriticalOn)(void); ++ void (*CriticalOff)(void); ++ void (*DataCacheHitInvalidate)(void *MemPtr, int Size); ++ void (*DataCacheHitWriteback)(void *MemPtr, int Size); ++ int (*DeviceFindInfo)(int Inst, const char *DeviceName, void *DeviceInfo); ++ int (*DeviceFindParmUint)(void *DeviceInfo, const char *Parm, bit32u *Value); ++ int (*DeviceFindParmValue)(void *DeviceInfo, const char *Parm, void *Value); ++ void (*Free)(void *MemPtr); ++ void (*FreeRxBuffer)(OS_RECEIVEINFO *OsReceiveInfo, void *MemPtr); ++ void (*FreeDev)(void *MemPtr); ++ void (*FreeDmaXfer)(void *MemPtr); ++ void (*IsrRegister)(OS_DEVICE *OsDev, int (*halISR)(HAL_DEVICE*, int*), int InterruptBit); ++ void (*IsrUnRegister)(OS_DEVICE *OsDev, int InterruptBit); ++ void* (*Malloc)(bit32u size); ++ void* (*MallocDev)(bit32u Size); ++ void* (*MallocDmaXfer)(bit32u size, void *MemBase, bit32u MemRange); ++ void* (*MallocRxBuffer)(bit32u size, void *MemBase, bit32u MemRange, ++ OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo, ++ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev); ++ void* (*Memset)(void *Dest, int C, bit32u N); ++ int (*Printf)(const char *Format, ...); ++ int (*Receive)(OS_DEVICE *OsDev,FRAGLIST *FragList,bit32u FragCount, ++ bit32u PacketSize,HAL_RECEIVEINFO *HalReceiveInfo, bit32u Mode); ++ int (*SendComplete)(OS_SENDINFO *OsSendInfo); ++ int (*Sprintf)(char *S, const char *Format, ...); ++ int (*Strcmpi)(const char *Str1, const char *Str2); ++ unsigned int (*Strlen)(const char *S); ++ char* (*Strstr)(const char *S1, const char *S2); ++ unsigned long (*Strtoul)(const char *Str, char **Endptr, int Base); ++ void (*TeardownComplete)(OS_DEVICE *OsDev, int Ch, int Direction); ++ } OS_FUNCTIONS; ++ ++/************** MODULE SPECIFIC STUFF BELOW **************/ ++ ++#ifdef _CPHAL_CPMAC ++ ++/* ++int halCpmacInitModule(HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, int (*osBridgeInitModule)(OS_FUNCTIONS *), void* (*osMallocDev) (bit32u), int *Size, int inst); ++*/ ++ ++int halCpmacInitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_AAL5 ++/* ++ * @ingroup shared_data ++ * The AAL5_FUNCTIONS struct defines the AAL5 function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++/* ++typedef struct ++ { ++ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(HAL_DEVICE *HalDev, int Mode); ++ int (*Init)(HAL_DEVICE *HalDev); ++ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(HAL_DEVICE *HalDev); ++ int (*InfoGet)(HAL_DEVICE *HalDev, int Key, void *Value); ++ int (*Probe)(HAL_DEVICE *HalDev); ++ int (*RxReturn)(HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); ++ int (*Send)(HAL_DEVICE *HalDev,FRAGLIST *FragList,int FragCount, ++ int PacketSize,OS_SENDINFO *OsSendInfo,int Ch, int Queue, ++ bit32u Mode); ++ int (*StatsClear)(HAL_DEVICE *HalDev); ++ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); ++ int (*Status)(HAL_DEVICE *HalDev); ++ void (*Tick)(HAL_DEVICE *HalDev); ++ int (*Kick)(HAL_DEVICE *HalDev, int Queue); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ } AAL5_FUNCTIONS; ++*/ ++ ++int cpaal5InitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ HAL_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_AAL2 ++/** ++ * @ingroup shared_data ++ * The AAL2_FUNCTIONS struct defines the AAL2 function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to cphalInitModule(). ++ */ ++typedef struct ++ { ++ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); ++ int (*Close)(HAL_DEVICE *HalDev, int Mode); ++ int (*Init)(HAL_DEVICE *HalDev); ++ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); ++ int (*Open)(HAL_DEVICE *HalDev); ++ int (*OptionsGet)(HAL_DEVICE *HalDev, char *Key, bit32u *Value); ++ int (*Probe)(HAL_DEVICE *HalDev); ++ ++ int (*StatsClear)(HAL_DEVICE *HalDev); ++ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); ++ int (*Status)(HAL_DEVICE *HalDev); ++ void (*Tick)(HAL_DEVICE *HalDev); ++ int (*Aal2UuiMappingSetup)(HAL_DEVICE *HalDev, int VC, int UUI, ++ int VdmaCh, int UUIDiscard); ++ int (*Aal2RxMappingSetup)(HAL_DEVICE *HalDev, int VC, int CID, ++ int LC); ++ int (*Aal2TxMappingSetup)(HAL_DEVICE *HalDev, int VC, int LC, int VdmaCh); ++ int (*Aal2VdmaChSetup)(HAL_DEVICE *HalDev, bit32u RemVdmaVtAddr, ++ VdmaChInfo *VdmaCh); ++ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); ++ int (*Aal2ModeChange)(HAL_DEVICE *HalDev, int Vc, int RxCrossMode, ++ int RxMultiMode, int TxMultiMode, int SchedMode, ++ int TcCh); ++ void (*Aal2VdmaEnable)(HAL_DEVICE *HalDev, int Ch); ++ int (*Aal2VdmaDisable)(HAL_DEVICE *HalDev, int Ch); ++ } AAL2_FUNCTIONS; ++ ++int cpaal2InitModule(HAL_DEVICE **HalDev, ++ OS_DEVICE *OsDev, ++ AAL2_FUNCTIONS **HalFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++#ifdef _CPHAL_VDMAVT ++/** ++ * @ingroup shared_data ++ * The VDMA_FUNCTIONS struct defines the HAL function pointers used by upper layer ++ * software. The upper layer software receives these pointers through the ++ * call to InitModule(). ++ * ++ * Note that this list is still under definition. ++ */ ++typedef struct ++ { ++ bit32 (*Init)( HAL_DEVICE *VdmaVtDev); ++ /* bit32 (*SetupTxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, ++ bit32u Addr, bit32u Size, bit32u PollInt); ++ bit32 (*SetupRxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, ++ bit32u Addr, bit32u Size, bit32u PollInt); */ ++ bit32 (*Tx)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Rx)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*SetRemoteChannel)(HAL_DEVICE *VdmaVtDev, bit32u RemAddr, ++ bit32u RemDevID); ++ bit32 (*ClearRxInt)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*ClearTxInt)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Open)(HAL_DEVICE *VdmaVtDev); ++ bit32 (*Close)(HAL_DEVICE *VdmaVtDev); ++ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); ++ int (*ChannelSetup)(HAL_DEVICE *VdmaVtDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); ++ int (*ChannelTeardown)(HAL_DEVICE *VdmaVtDev, int Ch, int Mode); ++ int (*Send)(HAL_DEVICE *VdmaVtDev,FRAGLIST *FragList,int FragCount, ++ int PacketSize,OS_SENDINFO *OsSendInfo,bit32u Mode); ++ } VDMA_FUNCTIONS; ++ ++int VdmaInitModule(HAL_DEVICE **VdmaVt, ++ OS_DEVICE *OsDev, ++ VDMA_FUNCTIONS **VdmaVtFunc, ++ OS_FUNCTIONS *OsFunc, ++ int OsFuncSize, ++ int *HalFuncSize, ++ int Inst); ++#endif ++ ++/* ++extern int cphalInitModule(MODULE_TYPE ModuleType, HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, ++ int (*osInitModule)(OS_FUNCTIONS *), void* (*osMallocDev)(bit32u), ++ int *Size, int Inst); ++*/ ++ ++ ++#ifdef _CPHAL_AAL5 ++extern const char hcSarFrequency[]; ++#endif ++ ++#ifdef _CPHAL_CPMAC ++/* following will be common, once 'utl' added */ ++extern const char hcClear[]; ++extern const char hcGet[]; ++extern const char hcSet[]; ++extern const char hcTick[]; ++ ++extern const char hcCpuFrequency[]; ++extern const char hcCpmacFrequency[]; ++extern const char hcMdioBusFrequency[]; ++extern const char hcMdioClockFrequency[]; ++extern const char hcCpmacBase[]; ++extern const char hcPhyNum[]; ++extern const char hcSize[]; ++extern const char hcCpmacSize[]; ++extern const char hcPhyAccess[]; ++#endif ++ ++#endif /* end of _INC_ */ +diff -urN linux.old/drivers/atm/sangam_atm/dev_host_interface.h linux.dev/drivers/atm/sangam_atm/dev_host_interface.h +--- linux.old/drivers/atm/sangam_atm/dev_host_interface.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dev_host_interface.h 2005-08-23 04:46:50.091844608 +0200 +@@ -0,0 +1,1162 @@ ++#ifndef __DEV_HOST_INTERFACE_H__ ++#define __DEV_HOST_INTERFACE_H__ 1 ++ ++/******************************************************************************* ++* FILE PURPOSE: Public header file for the Host-to-DSP interface ++******************************************************************************** ++* ++* TEXAS INSTRUMENTS PROPRIETARTY INFORMATION ++* ++* (C) Copyright Texas Instruments Inc. 2002. All rights reserved. ++* ++* Property of Texas Instruments Incorporated ++* ++* Restricted Rights - Use, duplication, or disclosure is subject to ++* restrictions set forth in TI's program license agreement and ++* associated documentation ++* ++* ++* FILE NAME: dev_host_interface.h ++* ++* DESCRIPTION: ++* This header file defines the variables and parameters used between the ++* host processor and the DSP. This file is included in both the DSP ++* software and the host software. ++* ++* RULES FOR MODIFICATION AND USE OF THIS FILE: ++* ++* --The main pointer to the struct of pointers will always be at the same fixed ++* location (0x80000000). ++* ++* --Each pointer element in the struct of pointers (indicated by the main pointer) ++* will always point to a struct only. ++* ++* --Any new structures added to the host interface in subsequent versions must ++* each have a corresponding new pointer element added to the END of the struct ++* of pointers. Other than this, there will never be any moving or rearranging ++* of the pointer elements in the struct of pointers. ++* ++* --Any new elements added to existing structures will be added at the END of the ++* structure. Other than this, there will never be any moving or rearranging ++* of structure elements. ++* ++* --A new structure will never be added as a new element in an old structure. ++* New structures must be added separately with a new entry in the struct of ++* pointers, as noted above. ++* ++* --Also, the sizes of existing arrays within old structures will never be changed. ++* ++* --The modem code in the DSP will never reference the struct of pointers in order ++* to avoid aliasing issues in the DSP code. The modem code will only use the ++* specific structures directly. ++* ++* --The host processor never accesses the DSP side of the ATM-TC hardware directly. ++* The DSP interfaces directly to the ATM-TC hardware and relays information to ++* the host processor through the host interface. ++* ++* --The host processor can track the modem's transition through important states ++* by accessing the Modem State Bit Field in the host interface. Each bit in ++* the bit field represents an important state to track in the modem. As the ++* modem transitions through each important state, the corresponding bit will ++* change from a zero to a one. Each bit in the bit field will only be reset to ++* zero if the modem retrains. If new states need to be tracked and are added ++* in subsequent versions of the host interface, a corresponding bit will be ++* added at the END of the bit field to ensure backwards compatibility. The ++* Modem State Bit Field is reset if the modem retrains or falls out of Showtime. ++* ++* --An interrupt will be sent to the host processor when a change occurs in the ++* Modem State Bit Field. There is an interrupt masking register which can mask ++* specific interrupts corresponding to the bits of the Modem State Bit Field. ++* This allows the host to keep an interrupt from being generated for those ++* states that are masked. ++* ++* HISTORY: ++* ++* 11/20/02 J. Bergsagel Written from the previous host interface file ++* 11/27/02 J. Bergsagel Added comments for mailbox control struct and ++* fixed a couple items for overlay page stuff. ++* Also, added temporary elements for SWTC code. ++* 12/04/02 J. Bergsagel Added extra dummy byte to DEV_HOST_eocVarDef_t ++* for proper word alignment. ++* 12/12/02 J. Bergsagel Changed initial states in the modem state bit field ++* and added more instructions for adding more states. ++* 12/16/02 J. Bergsagel Changed name "hostVersion_p" to "hostIntfcVersion_p". ++* Removed dspAturState from DEV_HOST_modemStateBitField_t. ++* Reorganized several struct elements to clean up the ++* host interface. ++* 12/27/02 Sameer V Added missing channel 0 statistics for TC. Added ++* ocd error information. ++* 12/27/02 Sameer V Added overlayState to OlayDP_Parms to indicate whether ++* overlays are being executed in current state. ++* 01/06/03 J. Bergsagel Added maxAllowedMargin and minRequiredMargin to ++* DEV_HOST_msg_t. ++* Renamed TC chan 1 items to be chan 0 items to start out. ++* 01/17/03 Sameer V Moved delineationState to atmStats structure. ++* 01/21/03 Barnett Implemented Ax7 UNIT-MODULE modular software framework. ++* 01/22/03 J. Bergsagel Added warning comments for certain struct typedefs. ++* 01/23/03 C. Perez-N. Removed old AX5-only diags. command/response entries in the ++* HOST and DSP ennumerations, and added the AX7 new ones ++* Added pointer entries in the DEV_HOST_dspOamSharedInterface_t ++* structure pointing to the analog diags. input/output/options ++* structures. ++* 01/29/03 Sameer V Removed TC_IDLE in enum for delineation state. Hardware ++* only reports TC_HUNT, TC_PRESYNC and TC_SYNC. ++* 03/07/03 Sameer/Jonathan Put SWTC token around structs and elements only used by SWTC ++* 03/12/03 Mannering Add CO profile data structures ++* 03/18/03 J. Bergsagel Removed the obsolete DSP_CHECK_TC response message. ++* 03/24/03 J. Bergsagel Added DEV_HOST_hostInterruptMask_t for masking DSP interrupt sources ++* 03/28/03 C. Perez-N Changed the C-style comments and made them C++ sytle instead. ++* Replaced the occurrences of "SINT32 *" pointer declarations with ++* "PSINT32" ++* 03/28/03 Mannering Update CO profile data structures ++* 04/04/03 S. Yim Add host I/F hooks for switchable hybrid and RJ11 ++* inner/outer pair selection ++* 04/11/03 J. Bergsagel Changed modem state bit field struct types to enums instead and used ++* a single integer variable for each "bitfield". ++* Changed bit field for host interrupt masks to an integer value also. ++* 04/14/03 J. Bergsagel Changed name of table pointer "meanSquareTblDstrm_p" to "marginTblDstrm_p". ++* 04/03/03 Umesh Iyer CMsg1 and RMsg1 use the same storage as CMSGPCB and RMSGPCB. ++* The string lengths for these have been adjusted to hold the longest ++* message in each case. The PCB messages from ADSL2 are longer. ++* 04/21/03 Sameeer V Added new host mailbox message for shutting down the DSLSS peripherals. ++* 04/23/03 J. Bergsagel Fixed comments for overlay mailbox messages and for losErrors. ++* 04/28/03 Mannering Added skip phase op flag to CO profile data structure ++* 05/05/03 Mannering Review Comments - Removed "#if CO_PROFILE" from around structure ++* definitions and define the number of profiles (DEV_HOST_LIST_ENTRIES) ++* 05/13/03 J. Bergsagel Added new elements to DEV_HOST_phyPerf_t for host control of hybrid. ++* 05/15/03 J. Bergsagel Added "farEndLosErrors" and "farEndRdiErrors" to DEV_HOST_modemStatsDef_t. ++* 05/16/03 Mannering Updated CO profile structure to support updated bit allocation and ++* interopability. ++* 05/20/03 Sameer V Added DSP message to inicate DYING GASP. ++* 05/22/03 J. Bergsagel Added a new struct typedef "DEV_HOST_hostInterruptSource_t". ++* Added "atucGhsRevisionNum" to "DEV_HOST_dspWrNegoParaDef_t". ++* Moved the following struct typedef's here to the public host interface: ++* DEV_HOST_dspBitSwapDef_t ++* DEV_HOST_atmDsBert_t ++* 05/28/03 A. Redfern Changed pointer type and location for margin reporting. ++* 05/28/03 Mannering Moved CO profile defines to dev_host_interface_pvt.h ++* 05/28/03 J. Bergsagel Moved subStateIndex and STM BERT controls into new struct "DEV_HOST_modemEnvPublic_t" ++* 05/29/03 J. Bergsagel Added elements to "DEV_HOST_modemEnvPublic_t" for host control of DSLSS LED's. ++* 06/10/03 Umesh Iyer Modified trainMode check to be compliant with the new host i/f mods. ++* 06/05/03 J. Bergsagel Added enum that will eventually replace the bitfield: DEV_HOST_diagAnlgOptionsVar_t. ++* Added new element "currentHybridNumUsed" in the DEV_HOST_phyPerf_t typedef ++* Added new host control flags for LPR signal detection on GPIO[0]. ++* 06/06/03 A. Redfern Removed fine gain scale from the CO profile and added max downstream power cutback. ++* Changed "test1" in CO profile struct to "phyEcDelayAdjustment". ++* 06/26/03 J. Bergsagel Added genericStructure typedef and two pointer elements of this type in the big table. ++* 07/03/03 Jack Huang Renamed test2 to bSwapThresholdUpdate ++* 07/07/03 Mallesh Changed phySigTxPowerCutback_f flag to a variable phySigTxGainReductionAt0kft which indicates the ++* amount of gain reduction in linear scale. ++* 07/15/03 Sameer V Changed DEV_HOST_diagAnlgOptionsVar_t to be an enum instead of a bit field. Host code ++* does not support setting bit fields. ++* 07/22/03 Jack Huang Added bitswap control flag in host i/f for API calls ++* 08/06/03 Sameer V Added missingToneDs_p to the DEV_HOST_oamWrNegoParaDef_t to enable host to switch off ++* DS tones on specified bins ++* 08/21/03 Jack Huang Added pcbEnabled flag in the DEV_HOST_modemEnvPublic_t structure ++* Added g.hs buffer definitions to DEV_HOST_dspOamSharedInterface_t ++* Added DEV_HOST_consBufDef_t to the DEV_HOST_dspOamSharedInterface_t structure ++* 08/26/03 J. Bergsagel Fixed name of "missingToneDs_p" to be "missingToneDsAddr" instead (since it is ++* not really used as a pointer). ++* 09/11/03 Mallesh Added a flag "usPilotInT1413ModeInMedley" to determine the need to send Upstream Pilot ++* in medley in T1.413 mode. ++* 09/12/03 J. Bergsagel Changed "test3" to "phyBitaFastPathExcessFineGainBump" in CO profile struct. ++* Changed "test4" to "phyBitaSkipGapAdjustment" in CO profile struct. ++* 09/23/03 J. Bergsagel Changed "T1413vendorRevisionNumber" to "vendorRevisionNumber" in DEV_HOST_msg_t. ++* Added ADSL2 and ADSL2 diag. states to the modem state bit field. ++* 10/01/03 J. Bergsagel Changed define of "MULTI_MODE" to be 255 to indicate that all possible bits ++* in the 8-bit bit field are turned on for any current and future training modes. ++* 10/09/03 M. Turkboylari Added DSP_TRAINING_MSGS and adsl2DeltMsgs_p, which is a pointer to a pointer, ++* in order to pass the ADSL2 training and DELT messages to the host side. This is for ACT. ++* 10/20/03 Mallesh Added a GHS state enumerator for cleardown ++* 10/20/03 Xiaohui Li Add definition for READSL2_MODE and READSL2_DELT ++* 11/07/03 J. Bergsagel Removed all code for when SWTC==1, which therefore allows removal of include of ++* "env_def_defines.h". We shouldn't have any compile tokens used in this file. ++* (the SWTC token is always off in any Ax7 code). ++* 11/14/03 J. Bergsagel Also removed READSL2_ENABLE token (no more compile tokens to be used in this .h file). ++* 12/12/03 Sameer/Ram Added DEV_HOST_EOCAOC_INTERRUPT_MASK to enable host to disable response code for AOC/EOC ++* mailbox messages ++* 12/09/03 Jack Huang Changed G.hs txbuf size from 60 to 64 to fit the max segment size ++* 12/15/03 Mallesh Changed vendor ID type defenition from SINT16 to UINT16 ++* 12/23/03 Sameer V Added ability to turn off constellation display reporting to host using oamFeature bit field. ++* 12/24/03 Sameer V Changed comment for Constellation Display Current Address to Host Write instead of DSP Write. ++* 12/26/03 Sameer/Ram Added DEV_HOST_GHSMSG_INTERRUPT_MASK to enable host to disable response code for GHS Messages ++* (C) Copyright Texas Instruments Inc. 2002. All rights reserved. ++*******************************************************************************/ ++ ++#include "dev_host_verdef.h" ++ ++// --------------------------------------------------------------------------------- ++// Address of the pointer to the DEV_HOST_dspOamSharedInterface_s struct of pointers ++// This is where it all starts. ++// --------------------------------------------------------------------------------- ++#define DEV_HOST_DSP_OAM_POINTER_LOCATION 0x80000000 ++ ++// The define "MAX_NUM_UPBINS" is used in "DEV_HOST_diagAnlgInputVar_t" below. ++// This value can never be changed (for host intf. backwards compatibility) ++#define MAX_NUM_UPBINS 64 ++ ++// ----------------------------------------------- ++// Begin common enumerations between DSP and host. ++// ----------------------------------------------- ++ ++// These Host-to-DSP commands are organized into two groups: ++// immediate state change commands and status affecting commands. ++// Do not add or remove commands except at the bottom since the DSP assumes this sequence. ++ ++enum ++{ ++ HOST_ACTREQ, // Send R-ACKREQ and monitor for C-ACKx ++ HOST_QUIET, // Sit quietly doing nothing for about 60 seconds, DEFAULT STATE; R_IDLE ++ HOST_XMITBITSWAP, // Perform upstream bitswap - FOR INTERNAL USE ONLY ++ HOST_RCVBITSWAP, // Perform downstream bitswap - FOR INTERNAL USE ONLY ++ HOST_RTDLPKT, // Send a remote download packet - FOR INTERNAL USE ONLY ++ HOST_CHANGELED, // Read the LED settings and change accordingly ++ HOST_IDLE, // Sit quiet ++ HOST_REVERBTEST, // Generate REVERB for manufacturing test ++ HOST_CAGCTEST, // Set coarse receive gain for manufacturing test ++ HOST_DGASP, // send Dying Gasp messages through EOC channel ++ HOST_GHSREQ, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHSMSG, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHS_SENDGALF, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHSEXIT, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHSMSG1, // G.hs - FOR INTERNAL USE ONLY ++ HOST_HYBRID, // Enable/Disable automatic hybrid switch ++ HOST_RJ11SELECT, // RJ11 inner/outer pair select ++ HOST_DIGITAL_MEM, // Digital Diags: run external memory tests ++ HOST_TXREVERB, // AFE Diags: TX path Reverb ++ HOST_TXMEDLEY, // AFE Diags: TX path Medley ++ HOST_RXNOISEPOWER, // AFE Diags: RX noise power ++ HOST_ECPOWER, // AFE Diags: RX eco power ++ HOST_ALL_ADIAG, // AFE Diags: all major analog diagnostic modes. Host is responsible to initiate each diagnostic sessions ++ HOST_USER_ADIAG, // AFE Diags: Host fills in analog diagnostic input data structure as specified and requests DSP to perform measurements as specified ++ HOST_QUIT_ADIAG, // AFE Diags: Host requests DSP to quit current diagnostic session. This is used for stopping the transmit REVERB/MEDLEY ++ HOST_NO_CMD, // All others - G.hs - FOR INTERNAL USE ONLY ++ HOST_DSLSS_SHUTDOWN, // Host initiated DSLSS shutdown message ++ HOST_SET_GENERIC, // Set generic CO profile ++ HOST_UNDO_GENERIC, // Set profile previous to Generic ++ HOST_GHS_CLEARDOWN // G.hs - FOR INTERNAL USE ONLY to start cleardown ++}; ++ ++// These DSP-to-Host responses are organized into two groups: ++// responses to commands and requests for OAM services. ++ ++enum ++{ ++ DSP_IDLE, // R_IDLE state entered ++ DSP_ACTMON, // R_ACTMON state entered ++ DSP_TRAIN, // R_TRAIN state entered ++ DSP_ACTIVE, // R_ACTIVE state entered ++ DSP_XMITBITSWAP, // Upstream bitswap complete - FOR INTERNAL USE ONLY ++ DSP_RCVBITSWAP, // Downstream bitswap complete - FOR INTERNAL USE ONLY ++ DSP_RTDL, // R_RTDL state entered - FOR INTERNAL USE ONLY ++ DSP_RRTDLPKT, // RTDL packet received - FOR INTERNAL USE ONLY ++ DSP_XRTDLPKT, // RTDL packet transmitted - FOR INTERNAL USE ONLY ++ DSP_ERROR, // Command rejected, wrong state for this command ++ DSP_REVERBTEST, // Manufacturing REVERB test mode entered ++ DSP_CAGCTEST, // Manufacturing receive gain test done ++ DSP_OVERLAY_START, // Notify host that page overlay has started - overlay number indicated by "tag" ++ DSP_OVERLAY_END, // Notify host that page overlay has ended - overlay number indicated by "tag" ++ DSP_CRATES1, // CRATES1 message is valid and should be copied to host memory now ++ DSP_SNR, // SNR calculations are ready and should be copied to host memory now ++ DSP_GHSMSG, // G.hs - FOR INTERNAL USE ONLY ++ DSP_RCVBITSWAP_TIMEOUT, // Acknowledge Message was not received within ~500 msec (26 Superframes). ++ DSP_ATM_TC_SYNC, // Indicates true TC sync on both the upstream and downstream. Phy layer ready for data xfer. ++ DSP_ATM_NO_TC_SYNC, // Indicates loss of sync on phy layer on either US or DS. ++ DSP_HYBRID, // DSP completed hybrid switch ++ DSP_RJ11SELECT, // DSP completed RJ11 inner/outer pair select ++ DSP_INVALID_CMD, // Manufacturing (Digital and AFE) diags: CMD received not recognized ++ DSP_TEST_PASSED, // Manufacturing diags: test passed ++ DSP_TEST_FAILED, // Manufacturing diags: test failed ++ DSP_TXREVERB, // Manufacturing AFE diags: Response to HOST_TXREVERB ++ DSP_TXMEDLEY, // Manufacturing AFE diags: Response to HOST_TXMEDLEY ++ DSP_RXNOISEPOWER, // Manufacturing AFE diags: Response to HOST_RXNOISEPOWER ++ DSP_ECPOWER, // Manufacturing AFE diags: Response to HOST_ECPOWER ++ DSP_ALL_ADIAG, // Manufacturing AFE diags: Response to HOST_ALL_ADIAG ++ DSP_USER_ADIAG, // Manufacturing AFE diags: Response to HOST_USER_ADIAG ++ DSP_QUIT_ADIAG, // Manufacturing AFE diags: Response to HOST_QUIT_ADIAG ++ DSP_DGASP, // DSP Message to indicate dying gasp ++ DSP_EOC, // DSP Message to indicate that DSP sent an EOC message to CO ++ DSP_TRAINING_MSGS // DSP Message to indicate that host has to copy the training message specified in the tag field. ++}; ++ ++// Define different ADSL training modes. ++//Defintions as per new host interface. ++#define NO_MODE 0 ++#define GDMT_MODE 2 ++#define GLITE_MODE 4 ++#define ADSL2_MODE 8 ++#define ADSL2_DELT (ADSL2_MODE+1) ++#define ADSL2PLUS_MODE 16 ++#define ADSL2PLUS_DELT (ADSL2PLUS_MODE+1) ++#define READSL2_MODE 32 ++#define READSL2_DELT (READSL2_MODE+1) ++#define T1413_MODE 128 ++#define MULTI_MODE 255 // all possible bits are set in the bit field ++ ++// Define the reason for dropping the connection ++ ++enum ++{ ++ REASON_LOS = 0x01, ++ REASON_DYING_GASP = 0x02, ++ REASON_USCRCERR = 0x04, ++ REASON_MARGIN_DROP = 0x08 ++}; ++ ++ ++// ---------------------------------------------------- ++// Begin modem state bit field definitions - DSP write. ++// ---------------------------------------------------- ++ ++// BitField1 for initial states and G.hs states. ++// If more values need to be added, they will be added at the end (up to 32 total entries). However, if this causes ++// the state transitions to tick off out of normal bit order, then the C code will have to be re-written ++// that causes the proper values to be entered into the modem state bit fields. ++typedef enum ++{ ++ ZERO_STATE1 = 0, ++ RTEST = 0x1, ++ RIDLE = 0x2, ++ RINIT = 0x4, ++ RRESET = 0x8, ++ GNSFLR = 0x10, ++ GTONE = 0x20, ++ GSILENT = 0x40, ++ GNEGO = 0x80, ++ GFAIL = 0x100, ++ GACKX = 0x200, ++ GQUIET2 = 0x400 ++} DEV_HOST_stateBitField1_t; // this enum should only have 32 bit entries in it. Add another enum if you need more. ++ ++// BitField2 for T1.413 states and for the rest of the modem states (so far) ++// If more values need to be added, they will be added at the end (up to 32 total entries). However, if this causes ++// the state transitions to tick off out of normal bit order, then the C code will have to be re-written ++// that causes the proper values to be entered into the modem state bit fields. ++typedef enum ++{ ++ ZERO_STATE2 = 0, ++ TNSFLR = 0x1, ++ TACTREQ = 0x2, ++ TACTMON = 0x4, ++ TFAIL = 0x8, ++ TACKX = 0x10, ++ TQUIET2 = 0x20, ++ RQUIET2 = 0x40, ++ RREVERB1 = 0x80, ++ RQUIET3 = 0x100, ++ RECT = 0x200, ++ RREVERB2 = 0x400, ++ RSEGUE1 = 0x800, ++ RREVERB3 = 0x1000, ++ RSEGUE2 = 0x2000, ++ RRATES1 = 0x4000, ++ RMSGS1 = 0x8000, ++ RMEDLEY = 0x10000, ++ RREVERB4 = 0x20000, ++ RSEGUE3 = 0x40000, ++ RMSGSRA = 0x80000, ++ RRATESRA = 0x100000, ++ RREVERBRA = 0x200000, ++ RSEGUERA = 0x400000, ++ RMSGS2 = 0x800000, ++ RRATES2 = 0x1000000, ++ RREVERB5 = 0x2000000, ++ RSEGUE4 = 0x4000000, ++ RBNG = 0x8000000, ++ RREVERB6 = 0x10000000, ++ RSHOWTIME = 0x20000000 ++} DEV_HOST_stateBitField2_t; // this enum should only have 32 bit entries in it. Add another enum if you need more. ++ ++// BitField3 for ADSL2 states ++// If more values need to be added, they will be added at the end (up to 32 total entries). However, if this causes ++// the state transitions to tick off out of normal bit order, then the C code will have to be re-written ++// that causes the proper values to be entered into the modem state bit fields. ++typedef enum ++{ ++ ZERO_STATE3 = 0, ++ G2QUIET1 = 0x1, ++ G2COMB1 = 0x2, ++ G2QUIET2 = 0x4, ++ G2COMB2 = 0x8, ++ G2ICOMB1 = 0x10, ++ G2LINEPROBE = 0x20, ++ G2QUIET3 = 0x40, ++ G2COMB3 = 0x80, ++ G2ICOMB2 = 0x100, ++ G2RMSGFMT = 0x200, ++ G2RMSGPCB = 0x400, ++ G2REVERB1 = 0x800, ++ G2QUIET4 = 0x1000, ++ G2REVERB2 = 0x2000, ++ G2QUIET5 = 0x4000, ++ G2REVERB3 = 0x8000, ++ G2ECT = 0x10000, ++ G2REVERB4 = 0x20000, ++ G2SEGUE1 = 0x40000, ++ G2REVERB5 = 0x80000, ++ G2SEGUE2 = 0x100000, ++ G2RMSG1 = 0x200000, ++ G2MEDLEY = 0x400000, ++ G2EXCHANGE = 0x800000, ++ G2RMSG2 = 0x1000000, ++ G2REVERB6 = 0x2000000, ++ G2SEGUE3 = 0x4000000, ++ G2RPARAMS = 0x8000000, ++ G2REVERB7 = 0x10000000, ++ G2SEGUE4 = 0x20000000 ++} DEV_HOST_stateBitField3_t; // this enum should only have 32 bit entries in it. Add another enum if you need more. ++ ++// BitField4 for ADSL2 diag. states ++// If more values need to be added, they will be added at the end (up to 32 total entries). However, if this causes ++// the state transitions to tick off out of normal bit order, then the C code will have to be re-written ++// that causes the proper values to be entered into the modem state bit fields. ++typedef enum ++{ ++ ZERO_STATE4 = 0, ++ GDSEGUE1 = 0x1, ++ GDREVERB5 = 0x2, ++ GDSEGUE2 = 0x4, ++ GDEXCHANGE = 0x8, ++ GDSEGUELD = 0x10, ++ GDRMSGLD = 0x20, ++ GDQUIET1LD = 0x40, ++ GDQUIET2LD = 0x80, ++ GDRACK1 = 0x100, ++ GDRNACK1 = 0x200, ++ GDQUIETLAST = 0x400 ++} DEV_HOST_stateBitField4_t; // this enum should only have 32 bit entries in it. Add another enum if you need more. ++ ++// This struct collects all of the bitfield types listed above for the modem state bit field(s) ++typedef struct ++{ ++ DEV_HOST_stateBitField1_t bitField1; // this is the first modem state bit field (mostly init. and G.hs) ++ DEV_HOST_stateBitField2_t bitField2; // this is the second modem state bit field (T1.413 and G.dmt) ++ DEV_HOST_stateBitField3_t bitField3; // this is the third modem state bit field (ADSL2) ++ DEV_HOST_stateBitField4_t bitField4; // this is the fourth modem state bit field (ADSL2 diag.) ++} DEV_HOST_modemStateBitField_t; ++ ++ ++// ----------------------------------------------- ++// Begin NegoPara message definitions - DSP write. ++// ----------------------------------------------- ++ ++typedef struct ++{ ++ UINT8 trainMode; // Train mode selected. See training modes defined above. ++ UINT8 bDummy1; // dummy byte for explicit 32-bit alignment ++ UINT16 lineLength; // Contains loop length estimate. Accuracy w/i 500 ft. LSbit = 1 for straight loop, = 0 for bridge tap ++ UINT32 atucVendorId; // Pass the vendor id of the CO to the host ++ UINT8 cMsgs1[8]; // CMsgs1 and CMSGPCB ++ UINT16 adsl2DSRate; // ++ UINT8 cRates2; // ++ UINT8 rRates2; // ++ UINT8 rRates1[4][11]; // ++ UINT8 cMsgs2[4]; // ++ UINT8 cRates1[4][30]; // ++ UINT8 rMsgs2[4]; // ++ UINT16 adsl2USRate; // ++ UINT8 atucGhsRevisionNum; // Pass the G.hs Revision number of the CO to the host ++ UINT8 reserved1; // ++ PUINT8 *adsl2DeltMsgs_p; // This pointer to a pointer passes the address of the globalvar.pString, which is also ++ // a pointer list of pointers. It will be used to pass all the new ADSL2 DELT messages to ++ // host side. This is for ACT. ++} DEV_HOST_dspWrNegoParaDef_t; ++ ++ ++// ---------------------------------------------------- ++// Begin OAM NegoPara message definitions - Host write. ++// ---------------------------------------------------- ++ ++// OAM Feature bit fields. ++// ++// Bit 0 - Enable auto retrain of modem ++// Bit 1 - Detect and report TC sync to host ++// Bit 2-31 - Reserved ++ ++#define DEV_HOST_AUTORETRAIN_ON 0x00000001 ++#define DEV_HOST_TC_SYNC_DETECT_ON 0x00000002 ++ ++#define DEV_HOST_AUTORETRAIN_MASK 0x00000001 ++#define DEV_HOST_TC_SYNC_DETECT_MASK 0x00000002 ++#define DEV_HOST_EOCAOC_INTERRUPT_MASK 0x00000004 ++#define DEV_HOST_CONS_DISP_DISABLE_MASK 0x00000008 ++#define DEV_HOST_GHSMSG_INTERRUPT_MASK 0x00000010 ++ ++typedef struct ++{ ++ UINT8 stdMode; // Desired train mode. See training modes defined above. ++ UINT8 ghsSequence; // Selected G.hs session as shown in Appendix 1 ++ UINT8 usPilotFlag; // Value of 1 indicates transmit an upstream pilot on bin 16 ++ UINT8 bDummy1; // dummy byte for 32-bit alignment ++ UINT8 rMsgs1[38]; // RMSG-1(6) and RMSG_PCB (38) ++ UINT8 bDummy2[2]; // dummy bytes for 32-bit alignment ++ UINT32 oamFeature; // 32 bit wide bit field to set OAM-specific features. ++ SINT8 marginThreshold; // Threshold for margin reporting ++ UINT8 hostFixAgc; // flag to force datapump to bypass AGC training and use the following values ++ UINT8 hostFixEqualizer; // forced analog equalizer value used during AGC training when hostfix_agc is on ++ UINT8 hostFixPga1; // forced pga1 value used during AGC training when hostFixAgc is on ++ UINT8 hostFixPga2; // forced pga2 value used during AGC training when hostFixAgc is on ++ UINT8 hostFixPga3; // forced pga3 value used during AGC training when hostFixAgc is on ++ UINT8 marginMonitorShwtme; // margin monitoring flag (during showtime) ++ UINT8 marginMonitorTrning; // margin monitoring flag (during training) ++ UINT8 disableLosAlarm; // flag to disable training based on los ++ UINT8 usCrcRetrain; // flag to disable retrain due to excessive USCRC ++ UINT8 t1413VendorId[2]; // Vendor ID used for T1.413 trainings ++ UINT8 gdmtVendorId[8]; // Vendor ID used for G.dmt trainings (ITU VendorID) ++ UINT8 missingTones[64]; // 64 element array to define missing tones for TX_MEDLEY and TX REVERB tests ++ UINT32 missingToneDsAddr; // Address given to DSP for tones to be switched off in DS direction ++ UINT8 dsToneTurnoff_f; // This flag controls the DS tone turn off logic ++ UINT8 reserved1; // Dummy bytes ++ UINT8 reserved2; // Dummy bytes ++ UINT8 reserved3; // Dummy bytes ++} DEV_HOST_oamWrNegoParaDef_t; ++ ++ ++// ---------------------------------------- ++// Begin Rate-adaptive message definitions. ++// ---------------------------------------- ++ ++// The four values below can never be changed (for host intf. backwards compatibility) ++#define DEV_HOST_RMSGSRA_LENGTH 10 ++#define DEV_HOST_RRATESRA_LENGTH 1 ++#define DEV_HOST_CRATESRA_LENGTH 120 ++#define DEV_HOST_CMSGSRA_LENGTH 6 ++ ++typedef struct ++{ ++ UINT8 rRatesRaString[DEV_HOST_RRATESRA_LENGTH+3]; ++ UINT8 rMsgsRaString[DEV_HOST_RMSGSRA_LENGTH+2]; ++ UINT8 cMsgsRaString[DEV_HOST_CMSGSRA_LENGTH+2]; ++} DEV_HOST_raMsgsDef_t; ++ ++ ++// ---------------------------------------------- ++// Begin superframe cnts definitions - DSP write. ++// ---------------------------------------------- ++ ++#define DEV_HOST_FRAMES_PER_SUPER 68 ++#define DEV_HOST_SUPERFRAMECNTDSTRM 0 ++#define DEV_HOST_SUPERFRAMECNTUSTRM 4 ++ ++// Although only the least significant 8 bits should be used as an ++// unsigned char for computing the bitswap superframe number, a ++// full 32 bit counter is provided here in order to have an ++// accurate indicator of the length of time that the modem has ++// been connected. This counter will overflow after 2.35 years ++// of connect time. ++ ++typedef struct ++{ ++ UINT32 wSuperFrameCntDstrm; ++ UINT32 wSuperFrameCntUstrm; ++} DEV_HOST_dspWrSuperFrameCntDef_t; ++ ++ ++// -------------------------------- ++// Begin ATUR/ATUC msg definitions. ++// -------------------------------- ++ ++// Grouping used by the DSP to simplify parameter passing. ++// All of these are written by the DSP. ++ ++typedef struct ++{ ++ UINT16 vendorId; // TI's vendor ID = 0x0004; Amati's vendor ID = 0x0006 ++ UINT8 versionNum; // T1.413 issue number ++ UINT8 rateAdapt; // 0 = fix rate (Default); 1= adaptive rate ++ UINT8 trellis; // 0 = disable trellis(default); 1 = enable trellis ++ UINT8 echoCancelling; // 0 = disable echo cancelling; 1 = enable echo cancelling(default) ++ UINT8 maxBits; // value range: 0-15; default = 15 ++ UINT8 maxPsd; // ++ UINT8 actualPsd; // ++ UINT8 maxIntlvDepth; // 0, 1, 2, or 3 for 64, 128, 256, or 512 max depth ++ UINT8 framingMode; // 0 for asynchronous, 1 for synchronous full overhead ++ // 2 for reduced overhead, 3 for merged reduced overhead DSP write. ++ UINT8 maxFrameMode; // maximum framing mode desired. Nor 0 or 3. ++ SINT16 targetMargin; // ++ SINT16 maxAllowedMargin; // ++ SINT16 minRequiredMargin; // ++ SINT16 maxTotBits; // ++ UINT8 grossGain; // ++ UINT8 ntr; // Enable/disable NTR support ++ SINT16 loopAttn; // Loop Attenuation ++ UINT8 vendorRevisionNumber; // Reported Vendor Revision Number ++ UINT8 reserved1; // for 32-bit alignment ++ UINT8 reserved2; // for 32-bit alignment ++ UINT8 reserved3; // for 32-bit alignment ++} DEV_HOST_msg_t; ++ ++ ++// -------------------------------------- ++// Begin bits and gains table definitions ++// -------------------------------------- ++ ++typedef struct ++{ ++ PUINT8 aturBng_p; // pointer to ATU-R bits and gains table ++ PUINT8 atucBng_p; // pointer to ATU-C bits and gains table ++ PUINT8 bitAllocTblDstrm_p; // pointer to Downstream Bit Allocation table ++ PUINT8 bitAllocTblUstrm_p; // pointer to Upstream Bit Allocation table ++ PSINT8 marginTblDstrm_p; // pointer to Downstream Margin table ++} DEV_HOST_dspWrSharedTables_t; ++ ++ ++// ---------------------------------------- ++// Begin datapump code overlay definitions. ++// ---------------------------------------- ++ ++#define DEV_HOST_PAGE_NUM 4 // number of overlay pages ++ ++// Never access a struct of this typedef directly. Always go through the DEV_HOST_olayDpDef_t struct ++typedef struct ++{ ++ UINT32 overlayHostAddr; // source address in host memory ++ UINT32 overlayXferCount; // number of 32bit words to be transfered ++ UINT32 overlayDspAddr; // destination address in DSP's PMEM ++} DEV_HOST_olayDpPageDef_t; ++ ++ ++typedef struct ++{ ++ UINT32 overlayStatus; // Status of current overlay to DSP PMEM ++ UINT32 overlayNumber; // DSP PMEM overlay page number ++ UINT32 overlayState; // Indicates whether current state is an overlay state ++ DEV_HOST_olayDpPageDef_t *olayDpPage_p[DEV_HOST_PAGE_NUM]; // Def's for the Pages ++} DEV_HOST_olayDpDef_t; ++ ++ ++// ------------------------- ++// Begin ATM-TC definitions. ++// ------------------------- ++ ++// TC cell states. ++typedef enum ++{ ++ TC_HUNT, ++ TC_PRESYNC, ++ TC_SYNC ++} DEV_HOST_cellDelinState_t; ++ ++ ++// -------------------------------------------- ++// Begin datapump error/statistics definitions. ++// -------------------------------------------- ++ ++// Never access a struct of this typedef directly. Always go through the DEV_HOST_modemStatsDef_t struct. ++typedef struct ++{ ++ UINT32 crcErrors; // Num of CRC errored ADSL frames ++ UINT32 fecErrors; // Num of FEC errored (corrected) ADSL frames ++ UINT32 ocdErrors; // Out of Cell Delineation ++ UINT32 ncdError; // No Cell Delineation ++ UINT32 lcdErrors; // Loss of Cell Delineation (within the same connection) ++ UINT32 hecErrors; // Num of HEC errored ADSL frames ++} DEV_HOST_errorStats_t; ++ ++ ++typedef struct ++{ ++ DEV_HOST_errorStats_t *usErrorStatsIntlv_p; // us error stats - interleave path ++ DEV_HOST_errorStats_t *dsErrorStatsIntlv_p; // ds error stats - interleave path ++ DEV_HOST_errorStats_t *usErrorStatsFast_p; // us error stats - fast path ++ DEV_HOST_errorStats_t *dsErrorStatsFast_p; // ds error stats - fast path ++ UINT32 losErrors; // Num of ADSL frames where loss-of-signal ++ UINT32 sefErrors; // Num of severly errored ADSL frames - LOS > MAXBADSYNC ADSL frames ++ UINT32 farEndLosErrors; // Number of reported LOS defects by the CO. ++ UINT32 farEndRdiErrors; // Number of reported RDI defects by the CO. ++} DEV_HOST_modemStatsDef_t; ++ ++// Never access a struct of this typedef directly. Always go through the DEV_HOST_atmStats_t struct. ++typedef struct ++{ ++ UINT32 goodCount; // Upstream Good Cell Count ++ UINT32 idleCount; // Upstream Idle Cell Count ++} DEV_HOST_usAtmStats_t; ++ ++// Never access a struct of this typedef directly. Always go through the DEV_HOST_atmStats_t struct. ++typedef struct ++{ ++ UINT32 goodCount; // Downstream Good Cell Count ++ UINT32 idleCount; // Downstream Idle Cell Count ++ UINT32 badHecCount; // Downstream Bad Hec Cell Count ++ UINT32 ovflwDropCount; // Downstream Overflow Dropped Cell Count ++ DEV_HOST_cellDelinState_t delineationState; // Indicates current delineation state ++} DEV_HOST_dsAtmStats_t; ++ ++ ++typedef struct ++{ ++ DEV_HOST_usAtmStats_t *us0_p; // US ATM stats for TC channel 0 ++ DEV_HOST_dsAtmStats_t *ds0_p; // DS ATM stats for TC channel 0 ++ DEV_HOST_usAtmStats_t *us1_p; // US ATM stats for TC channel 1 ++ DEV_HOST_dsAtmStats_t *ds1_p; // DS ATM stats for TC channel 1 ++} DEV_HOST_atmStats_t; ++ ++ ++// ---------------------- ++// Begin EOC definitions. ++// ---------------------- ++ ++// The two values below can never change (for backwards compatibility of host intf.) ++#define DEV_HOST_EOCREG4LENGTH 32 ++#define DEV_HOST_EOCREG5LENGTH 32 ++ ++typedef struct ++{ ++ UINT8 eocReg4[DEV_HOST_EOCREG4LENGTH]; // Host/Dsp Write, vendor specific EOC Register 4 ++ UINT8 eocReg5[DEV_HOST_EOCREG5LENGTH]; // Host/Dsp Write, vendor specific EOC Register 5 ++ UINT8 vendorId[8]; // Host write ++ UINT8 revNumber[4]; // Host, ATU-R Revision Number ++ UINT8 serialNumber[32]; // Host write ++ UINT8 eocReg4Length; // Host Write, valid length for EOC register 4 ++ UINT8 eocReg5Length; // Host Write, valid length for EOC register 5 ++ UINT8 dummy[2]; // dummy bytes for 32-bit alignment ++ UINT32 eocModemStatusReg; // Dsp Write, status bits to host ++ UINT8 lineAtten; // Dsp Write, line attenuation in 0.5 db step ++ SINT8 dsMargin; // DSP Write, measured DS margin ++ UINT8 aturConfig[30]; // Dsp Write, also used by EOC for ATUR Configuration ++} DEV_HOST_eocVarDef_t; ++ ++typedef struct ++{ ++ UINT16 endEocThresh; // Host Write, end of Clear EOC stream threshold ++ UINT16 dummy; // dummy value to fill gap ++ UINT32 dropEocCount; // Dsp Write, counter of dropped Clear EOC bytes ++ UINT16 eocRxLength; // Host/DSP write, number of valid Rx Clear EOC bytes ++ UINT16 eocTxLength; // Host/DSP write, number of valid Tx Clear EOC bytes ++ UINT8 eocRxBuf[64]; // Dsp Write, Buffer for receiving Rx Clear EOC bytes ++ UINT8 eocTxBuf[64]; // Host Write, Buffer for writing Tx Clear EOC bytes ++} DEV_HOST_clearEocVarDef_t; ++ ++ ++// ----------------------------------- ++// Begin CO profile Definitions. ++// ----------------------------------- ++ ++/* struct size must be a word size */ ++typedef struct ++{ ++ ++ SINT16 devCodecRxdf4Coeff[12] ; // (BOTH) IIR Coefficients ++ SINT16 devCodecTxdf2aCoeff[64] ; // (BOTH) FIR filter coefficients ++ SINT16 devCodecTxdf2bCoeff[64] ; // (BOTH) FIR filter coefficients ++ SINT16 devCodecTxdf1Coeff[12] ; // (BOTH) IIR filter coefficients ++ UINT16 devCodecTxDf2aDen; // (BOTH) denominator for IIR filter ++ UINT16 devCodecTxDf2bDen; // (BOTH) denominator for IIR filter ++ SINT16 ctrlMsmSpecGain[32]; // (BOTH) ++ ++ SINT16 phyBitaRateNegIntNoTrellis ; // (BOTH) value to set ++ SINT16 phyBitaRateNegIntTrellis ; // (BOTH) value to set ++ SINT16 phyBitaRateNegFastNoTrellis ; // (BOTH) value to set ++ SINT16 phyBitaRateNegFastTrellis ; // (BOTH) value to set ++ SINT16 phyBitaRsFlag ; // (BOTH) ++ SINT16 phyBitaFirstSubChannel ; // (BOTH) ++ SINT16 phyBitaMaxFineGainBump; // max fine gain bump ++ SINT16 phyBitaFineGainReduction; // fine gain reduction ++ SINT16 phyBitaMaxDownstreamPowerCutback; // max downstream power cutback ++ ++ SINT16 phySigTxGainReductionAt0kft; // upstream power reduction at 0 kft. ++ ++ SINT16 phyAgcPgaTarget ; // (BOTH) compare value ++ ++ UINT16 imsg413TxRate ; // (BOTH) Tx rate ++ SINT16 imsg413RsBytesAdjust ; // (BOTH) subtract value ++ UINT16 imsg413PstringMask ; // (POTS) Or'ed into pString[RMSGS1_INDEX][1] ++ SINT16 imsg413UsPilot ; // (BOTH)?? ++ UINT16 imsg413SkipPhaseOp ; // (POTS) ++ ++ UINT16 ctrlMsmSensitivity1 ; // (BOTH) value to set ++ UINT16 ctrlMsmTxPsdShape_f; // (BOTH) upstream spectral shaping flag ++ ++ UINT16 ovhdAocUsBswapReq_f ; // (BOTH)value to set ++ UINT16 ovhdAocScanMse_f ; // (BOTH)value to set ++ ++ SINT16 phyRevFullFirstBin ; // ++ SINT16 phyRevFullLastBin ; // ++ SINT16 phyRevFirstBin ; // ++ SINT16 phyRevLastBin ; // ++ SINT16 phyMedFirstBin ; // ++ SINT16 phyMedLastBin ; // ++ SINT16 phyMedOptionalLastBin; // Medley last bin - optional ++ ++ SINT16 phyEcDelayAdjustment; // Echo delay adjustment ++ SINT16 bSwapThresholdUpdate; // bSwapThresholdUpdate ++ SINT16 phyBitaFastPathExcessFineGainBump; // Used in phy_bita.c ++ SINT16 phyBitaSkipGapAdjustment; // Used in phy_bita.c ++ SINT16 usPilotInT1413ModeInMedley; // To send Upstream Pilot in medley in T1.413 mode. ++ ++ UINT32 profileVendorId ; // vendor id ++ ++} DEV_HOST_coData_t ; ++ ++typedef struct ++{ ++ DEV_HOST_coData_t * hostProfileBase_p; // base address of profile list ++} DEV_HOST_profileBase_t ; ++ ++ ++ ++// ----------------------------------- ++// Begin DSP/Host Mailbox Definitions. ++// ----------------------------------- ++ ++// The 3 values below can never be decreased, only increased. ++// If you increase one of the values, you must add more to the ++// initializers in "dev_host_interface.c". ++#define DEV_HOST_HOSTQUEUE_LENGTH 8 ++#define DEV_HOST_DSPQUEUE_LENGTH 8 ++#define DEV_HOST_TEXTQUEUE_LENGTH 8 ++ ++// Never access a struct of this typedef directly. Always go through the DEV_HOST_mailboxControl_t struct. ++typedef struct ++{ ++ UINT8 cmd; ++ UINT8 tag; ++ UINT8 param1; ++ UINT8 param2; ++} DEV_HOST_dspHostMsg_t; ++ ++// Never access a struct of this typedef directly. Always go through the DEV_HOST_mailboxControl_t struct. ++typedef struct ++{ ++ UINT32 msgPart1; ++ UINT32 msgPart2; ++} DEV_HOST_textMsg_t; ++ ++// The structure below has been ordered so that the Host need only write to ++// even byte locations to update the indices. ++ ++// The Buffer pointers in the struct below each point to a different ++// struct array that has an array size of one of the matching Queue Length ++// values defined above (DEV_HOST_HOSTQUEUE_LENGTH, DEV_HOST_DSPQUEUE_LENGTH, ++// and DEV_HOST_TEXTQUEUE_LENGTH). ++ ++typedef struct ++{ ++ UINT8 hostInInx; // Host write, DSP must never write except for init ++ UINT8 bDummy0[3]; // dummy bytes for explicit 32-bit alignment ++ UINT8 hostOutInx; // DSP write, Host must never write ++ UINT8 bDummy1[3]; // dummy bytes for explicit 32-bit alignment ++ UINT8 dspOutInx; // Host write, DSP must never write except for init ++ UINT8 bDummy2[3]; // dummy bytes for explicit 32-bit alignment ++ UINT8 dspInInx; // DSP write, Host must never write ++ UINT8 bDummy3[3]; // dummy bytes for explicit 32-bit alignment ++ UINT8 textInInx; // DSP write, Host must never write ++ UINT8 bDummy4[3]; // dummy bytes for explicit 32-bit alignment ++ UINT8 textOutInx; // Host write, DSP must never write except for init ++ UINT8 bDummy5[3]; // dummy bytes for explicit 32-bit alignment ++ DEV_HOST_dspHostMsg_t *hostMsgBuf_p; // pointer to Host Mailbox Buffer (Host writes the buffer) ++ DEV_HOST_dspHostMsg_t *dspMsgBuf_p; // pointer to DSP Mailbox Buffer (DSP writes the buffer) ++ DEV_HOST_textMsg_t *textMsgBuf_p; // pointer to Text Mailbox Buffer (DSP writes the buffer) ++} DEV_HOST_mailboxControl_t; ++ ++ ++//----------------------------------------- ++// Physical layer performance parameter ++//----------------------------------------- ++typedef struct ++{ ++ SINT32 hybridCost[5]; // Cost functions for hybrids (0: none, 1-4 hybrid options) ++ SINT32 usAvgGain; // upstream average gain in 20log10 (Q8) ++ SINT32 dsAvgGain; // downstream average gain in 20log10 (Q8) ++ UINT8 disableDspHybridSelect_f; // Allows host to disable the automatic hybrid selection by the DSP ++ UINT8 hostSelectHybridNum; // DSP will use this hybrid number only if DSP Select is disabled (values: 1-4) ++ UINT8 currentHybridNumUsed; // DSP indicates to the host the current hybrid number in use ++ UINT8 reserved1; // reserved for future use ++} DEV_HOST_phyPerf_t; ++ ++ ++/*********************************************************** ++ * The 3 structures below are used only for analog ++ * diagnostic functions originally defined in diag.h ++ * Moved here by Carlos A. Perez under J. Bergsagel request ++ ***********************************************************/ ++ ++/****************************************************************************/ ++/* Options for the Analog Diagnostic user input data structure */ ++/* (MUST be word aligned) */ ++/****************************************************************************/ ++typedef enum ++{ ++ ZERO_DIAG_OPT = 0, // dummy value for zero place-holder ++ NOISE_ONLY = 0x1, // diagnostic in noise only mode (on=1, off=0), disregard diagMode 0-4 ++ EXTERNAL_CO = 0x2, // operates against external CO (external=1, internal=0) ++ DIAG_AGC = 0x4, // agc selects gains control (agc=1, manual=0) ++ CROSSTALK_TEQ = 0x8, // crosstalk selects teq (crosstalk=1, manual=0) ++ LEAKY_TEQ = 0x10, // use leaky teq (on=1, off=0) ++ AUX_AMPS = 0x20, // auxamps (on=1, off=0) ++ BW_SELECT = 0x40, // change rxhpf/txlpf fc (modify=1, default=0) ++ DIAG_HYB_SELECT = 0x80, // change hybrid (modify=1, default=0) ++ POWER_DOWN_CDC = 0x100, // power down codec (power down=1, no power down=0) ++ ISDN_OP_MODE = 0x200, // operation mode (pots=0, isdn=1) ++ BYPASS_RXAF2 = 0x400, // Bypass except RXAF2 (on=1, off = 0) ++ TX_TEST_CONT = 0x800, // Continuous tx test (on=1, off=0) ++ TX_SCALE_MTT = 0x1000 // Scale tx signal for Mtt test (on=1, off=0) ++} DEV_HOST_diagAnlgOptionsVar_t; ++ ++/****************************************************************************/ ++/* Analog Diagnostic user input data structure (MUST be word align) */ ++/****************************************************************************/ ++ ++typedef struct ++{ ++ DEV_HOST_diagAnlgOptionsVar_t diagOption; // Other diagnostic optional settings ++ ++ UINT8 diagMode; // Performance diagnostic mode ++ UINT8 txMode; // transmit mode ++ UINT8 rxMode; // receive mode ++ UINT8 teqSp; // Select teq starting pt ++ UINT8 txDf1; // see dev_codec_filters.c and ++ UINT8 txDf2a; // dev_codec.h for filter coefficients ++ UINT8 txDf2b; ++ UINT8 rxDf4; ++ ++ UINT16 codingGain256Log2; // 256*Log2(coding gain) ++ UINT16 noiseMargin256Log2; // 256*Log2(noise margin) ++ ++ UINT16 rxPga1; // PGA1 ++ UINT16 rxPga2; // PGA2 ++ UINT16 rxPga3; // PGA3 ++ UINT16 anlgEq; // AEQ settings (dB/MHz) ++ ++ SINT8 pilotBin; // Select pilot subchannel ++ SINT8 txSwGain; // manual set for bridge tap loop ++ SINT8 tdw1Len; // TDW1 length - 0,2,4,8,16 ++ SINT8 tdw2Len; // TDW2 length - 0,2,4,8,16 ++ ++ UINT8 teqEcMode; // TEQ/EC mode ++ UINT8 hybrid; ++ UINT8 txAttn; // Codec Tx attenuation ++ UINT8 txGain; // Codec Tx gain (Sangam only) ++ ++ SINT16 txPda; //Codec Tx Digital gain/attn ++ UINT8 txTone[MAX_NUM_UPBINS]; // Turning tones on/off ++ // Still govern by lastbin ++ UINT16 rsvd; //for 32 bits alignment ++}DEV_HOST_diagAnlgInputVar_t; ++ ++/****************************************************************************/ ++/* Analog diagnostic output data structure */ ++/****************************************************************************/ ++typedef struct ++{ ++ PSINT32 rxSnr_p[2]; // Pointer to estimated snr ++ PSINT32 rxSubChannelCapacity_p[2]; // Pointer to estimated subchan capacity ++ PSINT32 rxSignalPower_p[2]; // Pointer to estimated signal power ++ PSINT32 rxNoisePower_p[2]; // Pointer to estimated noise power ++ PSINT32 rxAvg_p; // Pointer to average of rcvd signal ++ SINT32 chanCapacity[2] ; // Channel total capacity ++ SINT32 dataRate[2]; // Modem data rate (SNR) ++ SINT32 avgNoiseFloor; // Average noise floor ++ SINT16 snrGap256Log2; // 256*Log2(snr gap) ++ SINT16 rxPga1; // PGA1 ++ SINT16 rxPga2; // PGA2 ++ SINT16 rxPga3; // PGA3 ++ SINT16 anlgEq; // AEQ settings (dB/MHz) ++ SINT16 rsvd; ++}DEV_HOST_diagAnlgOutputVar_t; ++ ++ ++// Bit field structure that allows the host to mask off interrupt sources for possible DSP-to-Host interrupts. ++// Each bit represents a possible source of interrupts in the DSP code that might cause a DSP-to-Host ++// interrupt to occur. ++// This mask structure is not intended to show how interrupt sources in the DSP code correspond to the actual ++// DSP-to-Host interrupts. There could be multiple ways to cause an interrupt in the DSP code, but they all ++// eventually tie into one of the three possible DSP-to-Host interrupts. ++// The host should write a "1" to an individual bit when it wants to mask possible interrupts from that source. ++ ++// enum that represents individual bits in maskBitField1 ++typedef enum ++{ ++ ZERO_MASK1 = 0, // dummy value for zero place-holder ++ DSP_MSG_BUF = 0x1, // mask interrupts due to DSP-to-Host message mailbox updates ++ STATE_BIT_FIELD = 0x2, // mask interrupts due to changes in the modem state bit fields ++ DSP_HEARTBEAT = 0x4 // mask interrupts for the DSP hearbeat ++} DEV_HOST_intMask1_t; // this enum should only have 32 values in it (maximum). ++ ++// Add more "mask bit fields" at the end of this struct if you need more mask values ++typedef struct ++{ ++ DEV_HOST_intMask1_t maskBitField1; ++} DEV_HOST_hostInterruptMask_t; // this struct should only have 32 bits in it. ++ ++// Bit field structure that allows the host to determine the source(s) of DSP-to-Host interrupts in case ++// several of the interrupt sources get combined onto a single DSP-to-Host interrupt. ++// DSP will set each bit to a "1"as an interrupt occurs. ++// Host has the reponsibility to clear each bit to a "0" after it has determined the source(s) of interrupts. ++// Each source bit field in this struct will use the same enum typedef that matches the corresponding mask ++// bit field in "DEV_HOST_hostInterruptMask_t" ++typedef struct ++{ ++ DEV_HOST_intMask1_t sourceBitField1; ++} DEV_HOST_hostInterruptSource_t; ++ ++ ++// -------------------------- ++// Begin bitswap definitions. ++// -------------------------- ++ ++// bitSwapSCnt contains the superframe to perform bit swap ++// The entries must be ordered so that the first group only contains bit change commands ++// The other entries may contain power adjustment instructions and must be ++// written with something. NOP (0) is an available instruction. ++typedef struct ++{ ++ PUINT8 fineGains_p; // pointer to bng string, needed to check fine gains for powerswap ++ UINT8 bitSwapNewIndices[6]; // Bin before bitSwapBin to process ++ UINT8 bitSwapCmd[6]; // Bitswap command for bitSwapBin ++ UINT8 bitSwapBin[6]; // bin to modify ++ UINT8 bitSwapSCnt; // Superframe count on which to perform bitswap ++ UINT8 bitSwapEnabled; // bitSwapEnabled ++} DEV_HOST_dspBitSwapDef_t; ++ ++ ++// --------------------------- ++// Begin ATM BERT definitions. ++// --------------------------- ++ ++// Structure used for ATM Idle Cells based bit error rate computation. ++typedef struct ++{ ++ UINT8 atmBertFlag; // Feature enable/disable flag (Host write) ++ UINT8 dummy1; ++ UINT8 dummy[2]; // Dummy bytes for 32-bit alignment ++ UINT32 bitCountLow; // Low part of 64-bit BERT bit count (DSP write) ++ UINT32 bitCountHigh; // High part of 64-bit BERT bit count (DSP write) ++ UINT32 bitErrorCountLow; // Low part of 64-bit BERT bit count (DSP write) ++ UINT32 bitErrorCountHigh;// High part of 64-bit BERT bit count (DSP write) ++} DEV_HOST_atmDsBert_t; ++ ++ ++// ------------------------------------ ++// Misc. modem environment definitions. ++// ------------------------------------ ++ ++ ++typedef struct ++{ ++ SINT16 subStateIndex; // Index that signifies datapump substate. (DSP write) ++ UINT8 externalBert; // Turn on/off external BERT interface. 0 = OFF; 1 = ON. (Host write) ++ UINT8 usBertPattern; // BERT pattern for US TX data. 0 = 2^15-1; 1 = 2^23-1. (Host write) ++ UINT8 overrideDslLinkLed_f; // Overrides DSP operation of the DSL_LINK LED. (Host write) ++ // 0 = DSP is in control; 1 = Host is in control. ++ UINT8 dslLinkLedState_f; // DSL_LINK LED state when override flag has been set. (Host write) ++ // DSL_LINK LED will be updated with this value once per frame. ++ // LED is active-low: 0 = ON, 1 = OFF. ++ UINT8 overrideDslActLed_f; // Overrides DSP operation of the DSL_ACT LED. (Host write) ++ // 0 = DSP is in control; 1 = Host is in control. ++ UINT8 dslActLedState_f; // DSL_ACT LED state when override flag has been set. (Host write) ++ // DSL_ACT LED will be updated with this value once per frame. ++ // LED is active-low: 0 = ON, 1 = OFF. ++ UINT8 dGaspLprIndicator_f; // How LPR signal (GPIO[0]) is to be interpreted. (Host write) ++ // 0 = LPR is active-low; 1 = LPR is active-high. ++ UINT8 overrideDspLprGasp_f; // Overrides DSP detection of LPR signal to send out DGASP. (Host write) ++ // 0 = DSP detects LPR; 1 = Host detects LPR and sends "HOST_DGASP" to DSP. ++ UINT8 pcbEnabled; // DS power cut back ++ UINT8 maxAvgFineGainCtrl_f; // If maxAvgFineGainCtrl_f == 0, then the datapump controls the maximum average fine gain value. ++ // If maxAvgFineGainCtrl_f == 1, then the host controls the maximum average fine gain value. ++ UINT32 reasonForDrop; // This field will tell the host what might be the reason for a dropped connection. ++ SINT16 maxAverageFineGain; // When maxAvgFineGainCtrl_f == 1, the value in maxAverageFineGain is the maximum average fine gain level in 256log2 units. ++ UINT8 reserved1; // These are for 32-bit alignment. ++ UINT8 reserved2; // These are for 32-bit alignment. ++} DEV_HOST_modemEnvPublic_t; ++ ++ ++// ----------------------------- ++// Generic structure definition. ++// ----------------------------- ++ ++typedef struct ++{ ++ PSINT8 parameter1_p; ++ PSINT16 parameter2_p; ++ PSINT32 parameter3_p; ++ PUINT8 parameter4_p; ++ PUINT16 parameter5_p; ++ PUINT32 parameter6_p; ++} DEV_HOST_genericStructure_t; ++ ++ ++// ------------------------------ ++// Begin G.hs buffer definitions. ++// ------------------------------ ++ ++typedef struct ++{ ++ UINT8 txBuf[64]; // G.hs xmt buffer ++} DEV_HOST_ghsDspTxBufDef_t; ++ ++ ++typedef struct ++{ ++ UINT8 rxBuf[80]; // G.hs rcv buffer ++} DEV_HOST_ghsDspRxBufDef_t; ++ ++// ----------------------------------------- ++// Begin Constellation Display definitions. ++// ----------------------------------------- ++ ++typedef struct ++{ ++ UINT32 consDispStartAddr; // Host write ++ UINT32 consDispCurrentAddr; // Host write ++ UINT32 consDispBufLen; // Constellation Buffer Length ++ UINT32 consDispBin; // Host write, DS band only ++} DEV_HOST_consBufDef_t; ++ ++typedef struct ++{ ++ PSINT16 buffer1_p; //DSP write ++ PSINT16 buffer2_p; //DSP write ++} DEV_HOST_snrBuffer_t; ++ ++// -------------------------------------------------------------------------------------- ++// Typedef to be used for the DEV_HOST_dspOamSharedInterface_s struct of pointers ++// (this is used in dev_host_interface.c). ++// NOTE: This struct of pointers is NEVER to be referenced anywhere else in the DSP code. ++// IMPORTANT: Only pointers to other structs go into this struct !! ++// -------------------------------------------------------------------------------------- ++typedef struct ++{ ++ DEV_HOST_hostIntfcVersionDef_t *hostIntfcVersion_p; ++ DEV_HOST_dspVersionDef_t *datapumpVersion_p; ++ DEV_HOST_modemStateBitField_t *modemStateBitField_p; ++ DEV_HOST_dspWrNegoParaDef_t *dspWriteNegoParams_p; ++ DEV_HOST_oamWrNegoParaDef_t *oamWriteNegoParams_p; ++ DEV_HOST_raMsgsDef_t *raMsgs_p; ++ DEV_HOST_dspWrSuperFrameCntDef_t *dspWriteSuperFrameCnt_p; ++ DEV_HOST_msg_t *atucMsg_p; ++ DEV_HOST_msg_t *aturMsg_p; ++ DEV_HOST_dspWrSharedTables_t *dspWrSharedTables_p; ++ DEV_HOST_olayDpDef_t *olayDpParms_p; ++ DEV_HOST_eocVarDef_t *eocVar_p; ++ DEV_HOST_clearEocVarDef_t *clearEocVar_p; ++ DEV_HOST_modemStatsDef_t *modemStats_p; ++ DEV_HOST_atmStats_t *atmStats_p; ++ DEV_HOST_mailboxControl_t *dspHostMailboxControl_p; ++ DEV_HOST_phyPerf_t *phyPerf_p; ++ DEV_HOST_diagAnlgInputVar_t *analogInputVar_p; ++ DEV_HOST_diagAnlgOutputVar_t *analogOutputVar_p; ++ DEV_HOST_hostInterruptMask_t *hostInterruptMask_p; ++ DEV_HOST_profileBase_t *profileList_p; ++ DEV_HOST_hostInterruptSource_t *hostInterruptSource_p; ++ DEV_HOST_dspBitSwapDef_t *dspBitSwapDstrm_p; ++ DEV_HOST_dspBitSwapDef_t *dspBitSwapUstrm_p; ++ DEV_HOST_atmDsBert_t *atmDsBert_p; ++ DEV_HOST_modemEnvPublic_t *modemEnvPublic_p; ++ DEV_HOST_genericStructure_t *genericStructure1_p; ++ DEV_HOST_genericStructure_t *genericStructure2_p; ++ DEV_HOST_ghsDspTxBufDef_t *ghsDspTxBuf_p; ++ DEV_HOST_ghsDspRxBufDef_t *ghsDspRxBuf_p; ++ DEV_HOST_consBufDef_t *consDispVar_p; ++ DEV_HOST_snrBuffer_t *snrBuffer_p; ++} DEV_HOST_dspOamSharedInterface_t; ++ ++ ++// --------------------------------------------------------------------------------- ++// Typedef to be used for the pointer to the DEV_HOST_dspOamSharedInterface_s struct ++// of pointers (this is used in dev_host_interface.c). ++// --------------------------------------------------------------------------------- ++typedef DEV_HOST_dspOamSharedInterface_t *DEV_HOST_dspOamSharedInterfacePtr_t; ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/dev_host_verdef.h linux.dev/drivers/atm/sangam_atm/dev_host_verdef.h +--- linux.old/drivers/atm/sangam_atm/dev_host_verdef.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dev_host_verdef.h 2005-08-23 04:46:50.091844608 +0200 +@@ -0,0 +1,102 @@ ++#ifndef __DEV_HOST_VERDEF_H__ ++#define __DEV_HOST_VERDEF_H__ 1 ++ ++//******************************************************************** ++//* ++//* DMT-BASE ADSL MODEM PROGRAM ++//* TEXAS INSTRUMENTS PROPRIETARTY INFORMATION ++//* AMATI CONFIDENTIAL PROPRIETARY ++//* ++//* (c) Copyright April 1999, Texas Instruments Incorporated. ++//* All Rights Reserved. ++//* ++//* Property of Texas Instruments Incorporated and Amati Communications Corp. ++//* ++//* Restricted Rights - Use, duplication, or disclosure is subject to ++//* restrictions set forth in TI's and Amati program license agreement and ++//* associated documentation ++//* ++//********************************************************************* ++//* ++//* FILENAME: dev_host_verdef.h ++//* ++//* ABSTRACT: This file defines the version structure ++//* ++//* TARGET: Non specific. ++//* ++//* TOOLSET: Non specific. ++//* ++//* ACTIVATION: ++//* ++//* HISTORY: DATE AUTHOR DESCRIPTION ++//* 04/29/99 FLW Created ++//* 01/17/00 Barnett Mod's in support of merging NIC ++//* hardware rev 6/7 T1.413 codebases. ++//* 01/21/00 Wagner derfmake mods ++//* 05/11/00 Barnett hardware_rev is a 2 char string. ++//* 07/24/00 Barnett Rework as part of host interface redesign. ++//* 11/29/00 Hunt added chipset_id2 ++//* 03/30/01 Barnett Prefixed all public elements with DSPDP_. ++//* This insures uniqueness of names that might ++//* match host names by coincidence. ++//* 03/30/01 Barnett Added DSPDP_Host_VersionDef to facilitate ++//* representing a version id for the host i/f ++//* separate from the firmware version id as ++//* a courtesy to the host. ++//* 07/23/01 JEB Changed name from verdef_u.h to dpsys_verdef.h ++//* 04/12/02 Barnett Make timestamp unsigned 32-bit field. ++//* Generalizes for all kinds of hosts. ++//* 11/15/02 JEB Changed name from dpsys_verdef.h to dev_host_verdef.h ++//* Updated structs according to coding guidelines ++//* 12/16/02 JEB Renamed some struct elements for new usage in Ax7 ++//* 01/21/03 MCB Implemented Ax7 UNIT-MODULE modular software framework. ++//* 03/19/03 JEB Added back in "bugFix" elements into each struct type. ++//* Rearranged elements. ++//* ++//******************************************************************** ++ ++#include "env_def_typedefs.h" ++ ++#define DSPDP_FLAVOR_NEWCODES 0xFF // Other values are valid old-style flavors ++ ++// ------------------------------ ++// ------------------------------ ++// Begin DSP version definitions. ++// ------------------------------ ++// ------------------------------ ++ ++typedef struct ++{ ++ UINT32 timestamp; // Number of seconds since 01/01/1970 ++ UINT8 major; // Major "00".00.00.00 revision nomenclature ++ UINT8 minor; // Minor 00."00".00.00 revision nomenclature ++ UINT8 bugFix; // Bug Fix 00.00."00".00 revision nomenclature ++ UINT8 buildNum; // Build Number 00.00.00."00" revision nomenclature ++ UINT8 netService; // Network service identifier ++ UINT8 chipsetGen; // chipset generation ++ UINT8 chipsetId; // chipset identifier ++ UINT8 chipsetId2; // second byte for "RV" chipset et al. ++ UINT8 hardwareRev1; // hardware revision, 1st char ++ UINT8 hardwareRev2; // hardware revision, 2nd char ++ UINT8 featureCode; // feature code ++ UINT8 dummy1; // dummy byte for explicit 32-bit alignment ++} DEV_HOST_dspVersionDef_t; ++ ++// ------------------------------- ++// ------------------------------- ++// Begin host version definitions. ++// ------------------------------- ++// ------------------------------- ++ ++typedef struct ++{ ++ UINT8 major; // Major "00".00.00.00 revision nomenclature ++ UINT8 minor; // Minor 00."00".00.00 revision nomenclature ++ UINT8 bugFix; // Bug Fix 00.00."00".00 revision nomenclature ++ UINT8 buildNum; // Build Number 00.00.00."00" revision nomenclature ++ UINT8 netService; // Network service identifier ++ UINT8 dummy[3]; // dummy bytes for explicit 32-bit alignment ++} DEV_HOST_hostIntfcVersionDef_t; ++ ++ ++#endif // __DEV_HOST_VERDEF_H__ +diff -urN linux.old/drivers/atm/sangam_atm/dsl_hal_api.c linux.dev/drivers/atm/sangam_atm/dsl_hal_api.c +--- linux.old/drivers/atm/sangam_atm/dsl_hal_api.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dsl_hal_api.c 2005-08-23 04:46:50.095844000 +0200 +@@ -0,0 +1,3339 @@ ++/******************************************************************************* ++* FILE PURPOSE: DSL Driver API functions for Sangam ++* ++******************************************************************************** ++* FILE NAME: dsl_hal_basicapi.c ++* ++* DESCRIPTION: ++* Contains basic DSL HAL APIs for Sangam ++* ++* ++* (C) Copyright 2001-02, Texas Instruments, Inc. ++* History ++* Date Version Notes ++* 06Feb03 0.00.00 RamP Original Version Created ++* 10Mar03 0.00.01 RamP Initial Revision for Modular Code Branch ++* 19Mar03 0.00.02 RamP Fixed DSL and DSP Version API Structures ++* 20Mar03 0.00.03 RamP Changed byteswap function names ++* 21Mar03 0.00.03 RamP/ZT Malloc for DSP f/w done in dslStartup ++* 25Mar03 0.00.04 RamP Removed statistics used only by SWTC ++* Created Checkpoint 3 ++* 26Mar03 0.00.05 RamP Added Memory allocation for fwimage in ++* dslStartup function. ++* 07Apr03 0.00.06 RamP Implemented new error reporting scheme ++* Changed Commenting to C style only ++* 09Apr03 0.00.07 RamP Reorganized code to delete POST_SILICON ++* 10Apr03 0.00.08 RamP Removed ptidsl from loadFWImage function ++* moved size and fwimage initialization to ++* dslStartup function ++* 14Apr03 0.00.09 RamP Moved modemStateBitField processing to a ++* support function; deleted stateHistory ++* renamed the REG32 macro ++* 15Apr03 0.00.10 RamP Changed firmware allocate to shim_ ++* osAllocateVMemory function ++* 15Apr03 0.00.11 RamP Changed host version number to 07.00.00.01 ++* 16Apr03 0.00.12 RamP Modified return condition on dslShutdown ++* 16Apr03 0.00.13 RamP Changed host version number to 07.00.00.02 ++* 21Apr03 0.01.00 RamP Cleaned up dslShutdown function ++* Added new function calls to allocate ++* (Alpha) /free overlay pages for different OS ++* Fixed typecasting for allocate/free fxns ++* Added Interrupt Acknowledge logic ++* 22Apr03 0.01.01 RamP Moved acknowledgeInterrupt into api ++* Added static global for intr source ++* 24Apr03 0.01.02 RamP Added processing for OVERLAY_END in ++* DSP message handlers, verified crc32 ++* recovery for overlays ++* 28Apr03 0.01.03 RamP Removed global variable intrSource ++* Added parameter to handleInterrupt fxn ++* (Alpha Plus) to indicate interrupt source ++* Changed version number to 01.00.01.00 ++* Fixed setTrainingMode function problem ++* 07May03 0.01.04 RamP Removed delineation state check in ++* message handling functions, added more ++* safety for setting lConnected in TC_SYNC ++* Changed version number to 01.00.01.01 ++* 14May03 0.01.05 RamP Added 3 Switchable Hybrid APIs ++* Added additional statistics us/ds TxPower, ++* us margin,attenuation, us/ds bitallocation ++* moved versioning to dsl_hal_version.h ++* 14May03 0.01.06 RamP Fixed problem with CMsgs2 parsing ++* 20May03 0.01.07 RamP Added Inner/Outer pair API support. Added ++* dying gasp message. ++* 29May03 0.01.08 ZT/RamP Added memory optimizations for overlay pages ++* and coProfiles; added functions to free, ++* reload overlays and profiles ++* 04Jun03 0.01.09 RamP Added tick counters, fail states reporting ++* Made statistics fixes for higher data rates ++* Added Margin per tone to statistics ++* Added configuration checks for trellis/FEC ++* 06Jun03 0.01.10 RamP Added LED, STM Bert, dGasp LPR Config APIs ++* Modified interrupt acknowledge logic ++* Added current hybrid flag as statistic ++* 09Jun03 0.01.11 RamP Added function to send dying Gasp to Modem ++* fixed problem with reading OamNegoPara var ++* (Beta) fixed problem with reading current config ++* Added function to configure ATM Bert ++* fixed memory leak due to coProfiles ++* Added us/ds R/S FEC statistics ++* Added additional config capability for LED ++* fixed problem in free memory for CO profiles ++* 18Jul03 0.01.12 RamP Fixed problem with reading modemEnv structure ++* affects LED, DGaspLpr APIs ++* Sending Dying Gasp from shutdown function ++* 01Aug03 0.01.13 RamP Added preferred training mode to statistics ++* 13Aug03 0.01.14 MCB Set rev id for D3/R1.1 (ADSL2). ++* 21Aug03 0.01.15 RamP Added g.hs and aoc bitswap message gathering ++* Added new references to bits n gains table ++* Decoupled modem idle/retrain from pair select ++* Added line length and gross gain to statistics ++* 29Sep03 0.01.16 RamP Replaced advcfg function calls with support ++* module function switches ++* 01Oct03 0.01.17 RamP Added enum translation to set training mode ++* & to read statistics ++* 08Oct03 0.01.18 RamP Fixed problems with usTxPower statistic in ++* Annex B target, fixed problem with Trellis ++* 12Oct03 0.01.19 RamP Added API calls to gather ADSL2 Messages ++* 29Oct03 0.01.20 RamP Restored TC_SYNC detect logic ++* 30Oct03 0.01.21 RamP Removed Scaling factor for adsl2DSConRate ++* Setting Showtime state upon DSP_ACTIVE ++* 14Nov03 0.01.22 RamP Fixed scaling for usTxPower & dsTxPower ++* 14Nov03 0.01.23 RamP Added logic to gather CRates1/RRates1 ++* by parsing DSP_CRATES1 ++* 20Nov03 0.01.24 RamP Added generic & interface Read ++* and Write functions to read from ++* DSP - Host Interface ++* 24Nov03 0.01.25 RamP Modified interface Read/Write functions ++* to seperate element offsets from pointers ++* 19Dec03 0.01.26 RamP Modified pointer accessing problems with ++* block read functions ++* 26Dec03 0.01.27 RamP Made ghsIndex a local variable & added ++* check to avoid buffer overflow ++* 30Dec03 0.01.28 RamP Added generic mailbox command function ++*******************************************************************************/ ++#include "dsl_hal_register.h" ++#include "dsl_hal_support.h" ++#include "dsl_hal_logtable.h" ++#include "dsl_hal_version.h" ++ ++static unsigned int hybrid_selected; ++static unsigned int showtimeFlag = FALSE; ++ ++#ifdef PRE_SILICON ++/*********************************************/ ++/* Base Addresses */ ++/*********************************************/ ++#define DEV_MDMA_BASE 0x02000500 ++ ++/*********************************************/ ++/* MC DMA Control Registers in DSL */ ++/*********************************************/ ++ ++#define DEV_MDMA0_SRC_ADDR (DEV_MDMA_BASE + 0x00000000) ++#define DEV_MDMA0_DST_ADDR (DEV_MDMA_BASE + 0x00000004) ++#define DEV_MDMA0_CTL_ADDR (DEV_MDMA_BASE + 0x00000008) ++#define DEV_MDMA1_SRC_ADDR (DEV_MDMA_BASE + 0x00000040) ++#define DEV_MDMA1_DST_ADDR (DEV_MDMA_BASE + 0x00000044) ++#define DEV_MDMA1_CTL_ADDR (DEV_MDMA_BASE + 0x00000048) ++#define DEV_MDMA2_SRC_ADDR (DEV_MDMA_BASE + 0x00000080) ++#define DEV_MDMA2_DST_ADDR (DEV_MDMA_BASE + 0x00000084) ++#define DEV_MDMA2_CTL_ADDR (DEV_MDMA_BASE + 0x00000088) ++#define DEV_MDMA3_SRC_ADDR (DEV_MDMA_BASE + 0x000000C0) ++#define DEV_MDMA3_DST_ADDR (DEV_MDMA_BASE + 0x000000C4) ++#define DEV_MDMA3_CTL_ADDR (DEV_MDMA_BASE + 0x000000C8) ++ ++#define DEV_MDMA0_SRC (*((volatile UINT32 *) DEV_MDMA0_SRC_ADDR)) ++#define DEV_MDMA0_DST (*((volatile UINT32 *) DEV_MDMA0_DST_ADDR)) ++#define DEV_MDMA0_CTL (*((volatile UINT32 *) DEV_MDMA0_CTL_ADDR)) ++#define DEV_MDMA1_SRC (*((volatile UINT32 *) DEV_MDMA1_SRC_ADDR)) ++#define DEV_MDMA1_DST (*((volatile UINT32 *) DEV_MDMA1_DST_ADDR)) ++#define DEV_MDMA1_CTL (*((volatile UINT32 *) DEV_MDMA1_CTL_ADDR)) ++#define DEV_MDMA2_SRC (*((volatile UINT32 *) DEV_MDMA2_SRC_ADDR)) ++#define DEV_MDMA2_DST (*((volatile UINT32 *) DEV_MDMA2_DST_ADDR)) ++#define DEV_MDMA2_CTL (*((volatile UINT32 *) DEV_MDMA2_CTL_ADDR)) ++#define DEV_MDMA3_SRC (*((volatile UINT32 *) DEV_MDMA3_SRC_ADDR)) ++#define DEV_MDMA3_DST (*((volatile UINT32 *) DEV_MDMA3_DST_ADDR)) ++#define DEV_MDMA3_CTL (*((volatile UINT32 *) DEV_MDMA3_CTL_ADDR)) ++ ++/* MDMA control bits */ ++ ++#define DEV_MDMA_START 0x80000000 ++#define DEV_MDMA_STOP 0x00000000 ++#define DEV_MDMA_STATUS 0x40000000 ++#define DEV_MDMA_DST_INC 0x00000000 ++#define DEV_MDMA_DST_FIX 0x02000000 ++#define DEV_MDMA_SRC_INC 0x00000000 ++#define DEV_MDMA_SRC_FIX 0x00800000 ++#define DEV_MDMA_BURST1 0x00000000 ++#define DEV_MDMA_BURST2 0x00100000 ++#define DEV_MDMA_BURST4 0x00200000 ++ ++#define DEV_MDMA_LEN_SHF 2 ++#define DEV_MDMA_LEN_MASK 0x0000FFFF ++ ++#define DMA0 0 ++#define DMA1 1 ++#define DMA2 2 ++#define DMA3 3 ++#endif ++#ifdef DMA ++SINT32 getDmaStatus(UINT32 mask) ++{ ++ if(!(IFR & mask)) ++ { ++ return DSLHAL_ERROR_NO_ERRORS; ++ } ++ else ++ { ++ ICR = mask ; ++ return 1 ; ++ } ++} ++ ++void programMdma(UINT32 dma, UINT32 source, UINT32 destination, UINT32 length, UINT32 wait) ++{ ++ volatile UINT32 statusMask ; ++ ++ switch(dma) ++ { ++ case DMA0: ++ { ++ DEV_MDMA0_SRC = source ; ++ DEV_MDMA0_DST = destination ; ++ DEV_MDMA0_CTL = (DEV_MDMA_START | DEV_MDMA_DST_INC | DEV_MDMA_SRC_INC | ++ DEV_MDMA_BURST1 | (length << DEV_MDMA_LEN_SHF)) ; ++ statusMask = 0x00000010 ; ++ } ++ break ; ++ case DMA1: ++ { ++ DEV_MDMA1_SRC = source ; ++ DEV_MDMA1_DST = destination ; ++ DEV_MDMA1_CTL = (DEV_MDMA_START | DEV_MDMA_DST_INC | DEV_MDMA_SRC_INC | ++ DEV_MDMA_BURST1 | (length << DEV_MDMA_LEN_SHF)) ; ++ statusMask = 0x00000020 ; ++ } ++ break ; ++ case DMA2: ++ { ++ DEV_MDMA2_SRC = source ; ++ DEV_MDMA2_DST = destination ; ++ DEV_MDMA2_CTL = (DEV_MDMA_START | DEV_MDMA_DST_INC | DEV_MDMA_SRC_INC | ++ DEV_MDMA_BURST1 | (length << DEV_MDMA_LEN_SHF)) ; ++ statusMask = 0x00000040 ; ++ } ++ break ; ++ case DMA3: ++ { ++ DEV_MDMA3_SRC = source ; ++ DEV_MDMA3_DST = destination ; ++ DEV_MDMA3_CTL = (DEV_MDMA_START | DEV_MDMA_DST_INC | DEV_MDMA_SRC_INC | ++ DEV_MDMA_BURST1 | (length << DEV_MDMA_LEN_SHF)) ; ++ statusMask = 0x00000080 ; ++ } ++ break ; ++ ++ } ++ ++ if(wait) ++ { ++ while(!(getDmaStatus(statusMask))) ; ++ } ++ ++} ++#endif ++ ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_dslStartup ++* ++******************************************************************************************* ++* DESCRIPTION: Entry point to initialize and load ax5 daughter board ++* ++* INPUT: PITIDSLHW_T *ppIHw ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* ++*****************************************************************************************/ ++ ++int dslhal_api_dslStartup(PITIDSLHW_T *ppIHw) ++{ ++ ++ ITIDSLHW_T *ptidsl; ++ int i; ++ int rc; ++ dprintf(4,"dslhal_api_dslStartup() NEW 1\n"); ++ ++ ptidsl=(ITIDSLHW_T *)shim_osAllocateMemory(sizeof(ITIDSLHW_T)); ++ if(ptidsl==NULL) ++ { ++ dprintf(1, "unable to allocate memory for ptidsl\n"); ++ return 1; ++ } ++ *ppIHw=ptidsl; ++ shim_osZeroMemory((char *) ptidsl, sizeof(ITIDSLHW_T)); ++ ++ /* Unreset the ADSL Subsystem */ ++ rc=dslhal_support_unresetDslSubsystem(); ++ if(rc) ++ { ++ dprintf(1, "unable to reset ADSL Subsystem \n"); ++ shim_osFreeMemory((void *) ptidsl, sizeof(ITIDSLHW_T)); ++ return DSLHAL_ERROR_UNRESET_ADSLSS; ++ } ++ ptidsl->fwimage = shim_osAllocateVMemory(DSP_FIRMWARE_MALLOC_SIZE); ++ if(!ptidsl->fwimage) ++ { ++ dprintf(1,"Failed to Allocate Memory for DSP firmware binary \n"); ++ return DSLHAL_ERROR_FIRMWARE_MALLOC; ++ } ++ /* read firmware file from flash */ ++ rc=shim_osLoadFWImage(ptidsl->fwimage); ++ if(rc<0) ++ { ++ dprintf(1, "unable to get fw image\n"); ++ shim_osFreeVMemory((void *)ptidsl->fwimage,DSP_FIRMWARE_MALLOC_SIZE); ++ shim_osFreeMemory((void *) ptidsl, sizeof(ITIDSLHW_T)); ++ return DSLHAL_ERROR_NO_FIRMWARE_IMAGE; ++ } ++ else ++ { ++ ptidsl->imagesize = rc; ++ } ++ /* Compute the CRC checksum on the image and validate the image */ ++ ++ /* Validate the image in the RAM */ ++ ++ /* load fw to DSP */ ++ ++ if(dslhal_support_hostDspCodeDownload(ptidsl)) ++ { ++ dprintf(0,"dsp load error\n"); ++ for(i=0; iolayDpPage[i].PmemStartWtAddr !=NULL) ++ { ++ shim_osFreeDmaMemory((void *) ptidsl->olayDpPage[i].PmemStartWtAddr, ++ ptidsl->olayDpPage[i].OverlayXferCount); ++ } ++ } ++ if(ptidsl->coProfiles.PmemStartWtAddr != NULL) ++ shim_osFreeDmaMemory((void *)ptidsl->coProfiles.PmemStartWtAddr, ptidsl->coProfiles.OverlayXferCount); ++ if(ptidsl->constDisplay.PmemStartWtAddr != NULL) ++ shim_osFreeDmaMemory((void *)ptidsl->constDisplay.PmemStartWtAddr, ptidsl->constDisplay.OverlayXferCount); ++ shim_osFreeVMemory((void *)ptidsl->fwimage,DSP_FIRMWARE_MALLOC_SIZE); ++ shim_osFreeMemory((void *) ptidsl, sizeof(ITIDSLHW_T)); ++ return DSLHAL_ERROR_CODE_DOWNLOAD; ++ } ++ ++ /* set flag to indicated overlay pages are loaded */ ++ ptidsl->bOverlayPageLoaded = 1; ++ /* set auto retrain to 1 to disble the overlay page reload */ ++ ptidsl->bAutoRetrain = 1; ++ ++ /* unreset Raptor */ ++ /* change this to new function */ ++ /* This function should basically bring DSP out of reset bit 23 of PRCR */ ++ /* Function is ready but bypassed for Pre-Silicon */ ++ ++ rc=dslhal_support_unresetDsp(); ++ if (rc) ++ { ++ dprintf(0,"unable to bring DSP out of Reset\n"); ++ for(i=0; iolayDpPage[i].PmemStartWtAddr !=NULL) ++ { ++ shim_osFreeDmaMemory((void *) ptidsl->olayDpPage[i].PmemStartWtAddr, ++ ptidsl->olayDpPage[i].OverlayXferCount); ++ } ++ } ++ if(ptidsl->coProfiles.PmemStartWtAddr != NULL) ++ shim_osFreeDmaMemory((void *)ptidsl->coProfiles.PmemStartWtAddr, ptidsl->coProfiles.OverlayXferCount); ++ if(ptidsl->constDisplay.PmemStartWtAddr != NULL) ++ shim_osFreeDmaMemory((void *)ptidsl->constDisplay.PmemStartWtAddr, ptidsl->constDisplay.OverlayXferCount); ++ shim_osFreeVMemory((void *)ptidsl->fwimage,DSP_FIRMWARE_MALLOC_SIZE); ++ shim_osFreeMemory((void *) ptidsl, sizeof(ITIDSLHW_T)); ++ return DSLHAL_ERROR_UNRESET_DSP; ++ } ++ shim_osFreeVMemory((void *)ptidsl->fwimage,DSP_FIRMWARE_MALLOC_SIZE); ++ dprintf(4,"dslhal_api_dslStartup() done\n"); ++ ++ /* Add the code to initialize the host interface variables */ ++ /* Add code to tickle the host interface */ ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_dslShutdown ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: routine to shutdown ax5 modem and free the resource ++ * ++ * INPUT: tidsl_t *ptidsl ++ * ++ * RETURN: NULL ++ * ++ * ++ *****************************************************************************************/ ++ ++int dslhal_api_dslShutdown(tidsl_t *ptidsl) ++{ ++ int rc= DSLHAL_ERROR_NO_ERRORS; ++ int i; ++ ++ dprintf(5, "dslhal_api_dslShutdown\n"); ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_DSLSS_SHUTDOWN, 0, 0, 0); ++ if(rc) ++ { ++ dprintf(1, " unable to reset DSP \n"); ++ rc = DSLHAL_ERROR_RESET_DSP; ++ } ++ /* DSP need 50 ms to send out the message*/ ++ ++ shim_osClockWait(60 * 1000); ++ ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_DGASP, 0, 0, 0); ++ ++ /* free memory allocated*/ ++ ++ for(i=0; iolayDpPage[i].PmemStartWtAddr !=NULL) ++ { ++ shim_osFreeDmaMemory((void *) ptidsl->olayDpPage[i].PmemStartWtAddr, ++ ptidsl->olayDpPage[i].OverlayXferCount); ++ } ++ } ++ if(ptidsl->coProfiles.PmemStartWtAddr != NULL) ++ shim_osFreeDmaMemory((void *)ptidsl->coProfiles.PmemStartWtAddr, ptidsl->coProfiles.OverlayXferCount); ++ if(ptidsl->constDisplay.PmemStartWtAddr != NULL) ++ shim_osFreeDmaMemory((void *)ptidsl->constDisplay.PmemStartWtAddr, ptidsl->constDisplay.OverlayXferCount); ++ shim_osFreeMemory((void *)ptidsl, sizeof(tidsl_t)); ++ rc = dslhal_support_resetDsp(); ++ if(rc) ++ { ++ dprintf(1, " unable to reset ADSL subsystem \n"); ++ rc = DSLHAL_ERROR_RESET_DSP; ++ } ++ rc = dslhal_support_resetDslSubsystem(); ++ if(rc) ++ { ++ dprintf(1, " unable to reset ADSL subsystem \n"); ++ rc = DSLHAL_ERROR_RESET_ADSLSS; ++ } ++return rc; ++} ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_getDslHalVersion ++* ++******************************************************************************************* ++* DESCRIPTION: This routine supply DSL Driver version. ++* ++* INPUT: tidsl_t * ptidsl ++* void *pVer, DSP Driver Version Pointer ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* Note: See verdef_u.h for version structure definition. ++*****************************************************************************************/ ++ ++void dslhal_api_getDslHalVersion(void *pVer) ++{ ++ dslVer *pVersion; ++ pVersion = (dslVer *)pVer; ++ pVersion->major = (unsigned char) DSLHAL_VERSION_MAJOR; ++ pVersion->minor = (unsigned char) DSLHAL_VERSION_MINOR; ++ pVersion->bugfix = (unsigned char) DSLHAL_VERSION_BUGFIX; ++ pVersion->buildNum = (unsigned char) DSLHAL_VERSION_BUILDNUM; ++ pVersion->timeStamp = (unsigned char) DSLHAL_VERSION_TIMESTAMP; ++} ++ ++/******************************************************************************************** ++ * FUNCTION NAME: dslhal_api_pollTrainingStatus() ++ * ++ ********************************************************************************************* ++ * DESCRIPTION: code to decode modem status and to start modem training ++ * Input: tidsl_t *ptidsl ++ * ++ * Return: modem status ++ * -1 failed ++ * ++ ********************************************************************************************/ ++ ++int dslhal_api_pollTrainingStatus(tidsl_t *ptidsl) ++{ ++ int cmd; ++ int tag; ++ int parm1,parm2; ++ int rc; ++ unsigned int failState; ++ static unsigned int pollGhsIndex=0; ++ ++ /*char *tmp;*/ ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++#if SWTC ++ DEV_HOST_tcHostCommDef_t TCHostCommDef; ++#endif ++ ++ dprintf(5,"dslhal_api_pollTrainingStatus\n"); ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterface_t *) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++#if SWTC ++ dspOamSharedInterface.tcHostComm_p =(DEV_HOST_tcHostCommDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.tcHostComm_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.tcHostComm_p, ++ &TCHostCommDef, sizeof(DEV_HOST_tcHostCommDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++#endif ++ ++ rc = dslhal_support_processTrainingState(ptidsl); ++ if(rc) ++ { ++ dprintf(0,"Error Reading Modem Training State \n"); ++ return DSLHAL_ERROR_MODEMSTATE; ++ } ++ rc = dslhal_support_processModemStateBitField(ptidsl); ++ if(rc) ++ { ++ dprintf(0,"Error Reading Modem Training State \n"); ++ return DSLHAL_ERROR_MODEMSTATE; ++ } ++ /* ++ rc = dslhal_support_readDelineationState(ptidsl); ++ if(rc) ++ { ++ dprintf(0,"Error Reading Delineation State \n"); ++ return DSLHAL_ERROR_MODEMSTATE; ++ } ++ */ ++ while (dslhal_support_readDspMailbox(ptidsl,&cmd, &tag, &parm1, &parm2) == DSLHAL_ERROR_NO_ERRORS ) ++ { ++ dprintf(4,"mailbox message: 0x%x\n", cmd); ++ /* ++ for(rc=0;rc<8;rc++) ++ { ++ dslhal_support_readTextMailbox(ptidsl,&msg1, &msg2); ++ } ++ */ ++ ++ if (cmd == DSP_IDLE) ++ { ++ dprintf(4,"DSP_IDLE\n"); ++ ptidsl->lConnected=0; ++ hybrid_selected=888; ++ /* add code for reload overlay pages */ ++ if(ptidsl->bAutoRetrain == 0) ++ { ++ while(ptidsl->bOverlayPageLoaded == 0) ++ { ++ shim_osClockWait(6400); ++ } ++ //dslhal_support_restoreTrainingInfo(ptidsl); ++ //ptidsl->bOverlayPageLoaded = 1; ++ } ++ /* command DSP to ACTREQ */ ++ if(showtimeFlag == TRUE) ++ { ++ dslhal_api_resetTrainFailureLog(ptidsl); ++ dslhal_support_advancedIdleProcessing(ptidsl); ++ showtimeFlag = FALSE; ++ } ++ failState = (unsigned int)parm1; ++ if(failState!=0) ++ { ++ ptidsl->AppData.trainFailStates[ptidsl->AppData.trainFails]=failState; ++ ptidsl->AppData.trainFails++; ++ if(ptidsl->AppData.trainFails > 30) ++ ptidsl->AppData.trainFails=0; ++ } ++ for(pollGhsIndex=0;pollGhsIndex<10;pollGhsIndex++) ++ { ++ for(rc=0;rc<62;rc++) ++ ptidsl->AppData.dsl_ghsRxBuf[pollGhsIndex][rc]=0; ++ } ++ pollGhsIndex=0; ++ rc = dslhal_support_writeHostMailbox(ptidsl,HOST_ACTREQ, 0, 0, 0); ++ if (rc) ++ return DSLHAL_ERROR_MAILBOX_WRITE; ++ } ++ ++ if(cmd == DSP_ATM_TC_SYNC) ++ { ++ dprintf(4,"\nTC_SYNC\n"); ++ showtimeFlag = TRUE; ++ ptidsl->lConnected=1; ++ if(ptidsl->bAutoRetrain == 0 && ptidsl->bOverlayPageLoaded == 1) ++ { ++ dslhal_support_clearTrainingInfo(ptidsl); ++ ptidsl->bOverlayPageLoaded = 0; ++ } ++ } ++ if(cmd == DSP_ACTIVE) ++ { ++ dprintf(4,"DSP_ACTIVE"); ++ ptidsl->lConnected=0; ++ ptidsl->AppData.bState = RSTATE_SHOWTIME; ++ dprintf(4,"US Connect Rate: %u \n",ptidsl->AppData.USConRate); ++ dprintf(4,"DS Connect Rate: %u \n",ptidsl->AppData.DSConRate); ++ } ++ if(cmd == DSP_ATM_NO_TC_SYNC) ++ { ++ dprintf(4,"\nTC_NOSYNC\n"); ++ ptidsl->lConnected=0; ++ } ++ if(cmd == DSP_DGASP) ++ { ++ dprintf(0,"\n GASP!!! \n"); ++ } ++ if(cmd == DSP_OVERLAY_END) ++ { ++ dprintf(4,"Overlay Page Done %d \n",tag); ++ rc = dslhal_support_checkOverlayPage(ptidsl,tag); ++ if(rc == DSLHAL_ERROR_OVERLAY_CORRUPTED) ++ { ++ dprintf(0,"Overlay Page: %d CORRUPTED \n",tag); ++ return (0-DSLHAL_ERROR_OVERLAY_CORRUPTED); ++ } ++ } ++ if(cmd == DSP_HYBRID) ++ { ++ dprintf(2,"Hybrid Metrics Available: %d\n",tag); ++ hybrid_selected = tag; ++ } ++ if(cmd == DSP_DGASP) ++ { ++ dprintf(0,"\n GASP!!! \n"); ++ } ++ if(cmd == DSP_XMITBITSWAP) ++ { ++ dslhal_support_aocBitSwapProcessing(ptidsl,0); ++ } ++ if(cmd == DSP_RCVBITSWAP) ++ { ++ dslhal_support_aocBitSwapProcessing(ptidsl,1); ++ } ++ if(cmd == DSP_GHSMSG) ++ { ++ dprintf(3,"Ghs Message Received, bytes: %d \n",tag); ++ dprintf(3,"Addr: 0x%x\n",dspOamSharedInterface.ghsDspRxBuf_p); ++ if(pollGhsIndex > 9) ++ pollGhsIndex=0; ++ rc = dslhal_support_blockRead((void *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.ghsDspRxBuf_p), &ptidsl->AppData.dsl_ghsRxBuf[pollGhsIndex++][0], tag); ++ } ++ if(cmd == DSP_CRATES1) ++ { ++ dprintf(3,"DSP C-Rates1 Data Ready \n"); ++ rc = dslhal_support_gatherRateMessages(ptidsl); ++ } ++ if(cmd == DSP_SNR) ++ { ++ dprintf(3,"DSP SNR Data Ready \n"); ++ rc = dslhal_support_gatherSnrPerBin(ptidsl,tag); ++ } ++ if(cmd == DSP_EOC) ++ { ++ dprintf(3,"DSP_EOC message \n"); ++ rc = dslhal_support_gatherEocMessages(ptidsl,tag,parm1,parm2); ++ } ++ ++ if(cmd == DSP_TRAINING_MSGS) ++ { ++ dprintf(3,"DSP_TRAINING_MSGS \n"); ++ rc = dslhal_support_gatherAdsl2Messages(ptidsl,tag,parm1,parm2); ++ } ++ } ++ dprintf(6,"dslhal_api_pollTrainingStatus done\n"); ++ return(ptidsl->AppData.bState); ++ ++} /* end of dslhal_api_pollTrainingStatus() */ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_handleTrainingInterrupt() ++* ++********************************************************************************************* ++* DESCRIPTION: Code to handle ax5 hardware interrupts ++* ++* Input: tidsl_t *ptidsl ++* int *pMsg, pointer to returned hardware messages. Each byte represent a messge ++* int *pTag, pointer to returned hardware message tags. Each byte represent a tag. ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++int dslhal_api_handleTrainingInterrupt(tidsl_t *ptidsl, int intrSource) ++{ ++ int cmd; ++ int tag; ++ int parm1,parm2; ++ unsigned int msg1; ++ unsigned int msg2; ++ int rc; ++ unsigned int failState; ++ static unsigned int interruptGhsIndex=0; ++ /*char *tmp;*/ ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++#if SWTC ++ DEV_HOST_tcHostCommDef_t TCHostCommDef; ++#endif ++ dprintf(6,"dslhal_api_handleTrainingInterrupt\n"); ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterface_t *) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++#if SWTC ++ dspOamSharedInterface.tcHostComm_p =(DEV_HOST_tcHostCommDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.tcHostComm_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.tcHostComm_p, ++ &TCHostCommDef, sizeof(DEV_HOST_tcHostCommDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++#endif ++ ++ if(intrSource & MASK_BITFIELD_INTERRUPTS) ++ { ++ dspOamSharedInterface.modemStateBitField_p =(DEV_HOST_modemStateBitField_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.modemStateBitField_p); ++ rc = dslhal_support_processTrainingState(ptidsl); ++ if(rc) ++ { ++ dprintf(0,"Error Reading Modem Training State \n"); ++ return DSLHAL_ERROR_MODEMSTATE; ++ } ++ rc = dslhal_support_processModemStateBitField(ptidsl); ++ if(rc) ++ { ++ dprintf(0,"Error Reading Modem Training State \n"); ++ return DSLHAL_ERROR_MODEMSTATE; ++ } ++ } ++ if(intrSource & MASK_MAILBOX_INTERRUPTS) ++ { ++ /* ++ rc = dslhal_support_readDelineationState(ptidsl); ++ if(rc) ++ { ++ dprintf(0,"Error Reading Delineation State \n"); ++ return DSLHAL_ERROR_MODEMSTATE; ++ } ++ */ ++ while (dslhal_support_readDspMailbox(ptidsl,&cmd, &tag, &parm1, &parm2) == DSLHAL_ERROR_NO_ERRORS ) ++ { ++ dprintf(4,"mailbox message: 0x%x\n", cmd); ++ /* ++ for(rc=0;rc<8;rc++) ++ { ++ dslhal_support_readTextMailbox(ptidsl,&msg1, &msg2); ++ } ++ */ ++ if (cmd == DSP_IDLE) ++ { ++ dprintf(4,"DSP_IDLE\n"); ++ ptidsl->lConnected=0; ++ hybrid_selected=888; ++ if(showtimeFlag == TRUE) ++ { ++ dslhal_api_resetTrainFailureLog(ptidsl); ++ dslhal_support_advancedIdleProcessing(ptidsl); ++ showtimeFlag = FALSE; ++ } ++ failState = (unsigned int)parm1; ++ if(failState!=0) ++ { ++ ptidsl->AppData.trainFailStates[ptidsl->AppData.trainFails]=failState; ++ ptidsl->AppData.trainFails++; ++ if(ptidsl->AppData.trainFails > 30) ++ ptidsl->AppData.trainFails=0; ++ } ++ for(interruptGhsIndex=0;interruptGhsIndex<10;interruptGhsIndex++) ++ { ++ for(rc=0;rc<62;rc++) ++ ptidsl->AppData.dsl_ghsRxBuf[interruptGhsIndex][rc]=0; ++ } ++ interruptGhsIndex=0; ++ ++ /* add code for reload overlay pages */ ++ if(ptidsl->bAutoRetrain == 0 && ptidsl->bOverlayPageLoaded == 0) ++ { ++ dslhal_support_restoreTrainingInfo(ptidsl); ++ ptidsl->bOverlayPageLoaded = 1; ++ } ++ /* command DSP to ACTREQ */ ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_ACTREQ, 0, 0, 0); ++ if (rc) ++ return DSLHAL_ERROR_MAILBOX_WRITE; ++ } ++ if(cmd == DSP_ATM_TC_SYNC) ++ { ++ dprintf(4,"\nTC_SYNC\n"); ++ showtimeFlag = TRUE; ++ ptidsl->lConnected=1; ++ if(ptidsl->bAutoRetrain == 0 && ptidsl->bOverlayPageLoaded == 1) ++ { ++ dslhal_support_clearTrainingInfo(ptidsl); ++ ptidsl->bOverlayPageLoaded = 0; ++ } ++ } ++ if(cmd == DSP_ACTIVE) ++ { ++ ptidsl->lConnected=0; ++ ptidsl->AppData.bState = RSTATE_SHOWTIME; ++ dprintf(4,"DSP_ACTIVE"); ++ dprintf(4,"US Connect Rate: %u \n",ptidsl->AppData.USConRate); ++ dprintf(4,"DS Connect Rate: %u \n",ptidsl->AppData.DSConRate); ++ } ++ if(cmd == DSP_ATM_NO_TC_SYNC) ++ { ++ dprintf(4,"\nTC_NOSYNC\n"); ++ ptidsl->lConnected=0; ++ /* add code for reload overlay pages */ ++ } ++ if(cmd == DSP_OVERLAY_END) ++ { ++ dprintf(4,"Overlay Page Done %d \n",tag); ++ rc = dslhal_support_checkOverlayPage(ptidsl,tag); ++ if(rc == DSLHAL_ERROR_OVERLAY_CORRUPTED) ++ { ++ dprintf(4,"Overlay Page: %d CORRUPTED \n",tag); ++ return(0-DSLHAL_ERROR_OVERLAY_CORRUPTED); ++ } ++ } ++ if(cmd == DSP_HYBRID) ++ { ++ dprintf(2,"Hybrid Metrics Available\n"); ++ hybrid_selected = tag; ++ } ++ if(cmd == DSP_XMITBITSWAP) ++ { ++ rc = dslhal_support_aocBitSwapProcessing(ptidsl,0); ++ } ++ if(cmd == DSP_RCVBITSWAP) ++ { ++ rc = dslhal_support_aocBitSwapProcessing(ptidsl,1); ++ } ++ if(cmd == DSP_GHSMSG) ++ { ++ dprintf(3,"Ghs Message Received, bytes: %d \n",tag); ++ dprintf(3,"Addr: 0x%x\n",dspOamSharedInterface.ghsDspRxBuf_p); ++ if(interruptGhsIndex > 9) ++ interruptGhsIndex=0; ++ rc = dslhal_support_blockRead((void *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.ghsDspRxBuf_p), &ptidsl->AppData.dsl_ghsRxBuf[interruptGhsIndex++][0], tag); ++ } ++ if(cmd == DSP_CRATES1) ++ { ++ dprintf(3,"DSP C-Rates1 Data Ready \n"); ++ rc = dslhal_support_gatherRateMessages(ptidsl); ++ } ++ if(cmd == DSP_SNR) ++ { ++ dprintf(3,"DSP SNR Data Ready \n"); ++ rc = dslhal_support_gatherSnrPerBin(ptidsl,tag); ++ } ++ if(cmd == DSP_EOC) ++ { ++ dprintf(3,"DSP_EOC message \n"); ++ rc = dslhal_support_gatherEocMessages(ptidsl,tag,parm1,parm2); ++ } ++ if(cmd == DSP_TRAINING_MSGS) ++ { ++ dprintf(3,"DSP_TRAINING_MSGS \n"); ++ rc = dslhal_support_gatherAdsl2Messages(ptidsl,tag,parm1,parm2); ++ } ++ } ++ ++ dslhal_support_readTextMailbox(ptidsl,&msg1, &msg2); ++ dprintf(5,"Text Message Part1: 0x%x \t Text Message Part2: 0x%x \n",msg1,msg2); ++ } ++ dprintf(6,"dslhal_api_handleTrainingInterrupt done\n"); ++ return(ptidsl->AppData.bState); ++} /* end of dslhal_api_handleTrainingInterrupt() */ ++ ++ ++ ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_dslRetrain(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends CMD_ACTREQ to the DSP to issue a retrain ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_dslRetrain(tidsl_t *ptidsl) ++{ ++ int rc; ++ ++ dprintf(5, "dslhal_cfg_dslRetrain \n"); ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_QUIET, 0, 0, 0); ++ if(rc) ++ { ++ dprintf(1,"dslhal_cfg_dslRetrain failed\n"); ++ return DSLHAL_ERROR_CTRL_API_FAILURE; ++ } ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_sendQuiet(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the CMD_QUIET message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_sendQuiet(tidsl_t *ptidsl) ++{ ++ int rc; ++ ++ dprintf(5, "dslhal_api_sendQuiet\n"); ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_QUIET, 0, 0, 0); ++ if(rc) ++ { ++ dprintf(1,"dslhal_api_sendQuiet failed\n"); ++ return DSLHAL_ERROR_CTRL_API_FAILURE; ++ } ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_sendIdle(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the CMD_IDLE message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_sendIdle(tidsl_t *ptidsl) ++{ ++ int rc; ++ ++ dprintf(5, "dslhal_api_sendIdle\n"); ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_IDLE, 0, 0, 0); ++ if(rc) ++ { ++ dprintf(1,"dslhal_api_sendIdle failed\n"); ++ return DSLHAL_ERROR_CTRL_API_FAILURE; ++ } ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_sendDgasp(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the HOST_DGASP message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_sendDgasp(tidsl_t *ptidsl) ++{ ++ int rc; ++ ++ dprintf(5, "dslhal_api_sendDgasp\n"); ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_DGASP, 0, 0, 0); ++ if(rc) ++ { ++ dprintf(1,"dslhal_api_sendDgasp failed\n"); ++ return DSLHAL_ERROR_CTRL_API_FAILURE; ++ } ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setTrainingMode(tidsl_t *ptidsl,unsigned int trainmode) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Desired Training Mode {None/Multimode/G.dmt/lite ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int trainmode :Should be between 0 and 4; 0:No Mode 1:Multimode ++* 2: T1.413, 3:G.dmt, 4: G.lite ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setTrainingMode(tidsl_t *ptidsl,unsigned int trainmode) ++{ ++ DEV_HOST_oamWrNegoParaDef_t NegoPara; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5," dslhal_api_setTrainingMode()\n"); ++ if(trainmode>255) ++ { ++ dprintf(3,"Invalid Value for Desired Training Mode (must be <255)\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ ++ rc = dslhal_support_blockRead((PVOID) dspOamSharedInterface.oamWriteNegoParams_p,&NegoPara, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ /* Enum Translation to maintain backwards compatibility for train modes */ ++ if(trainmode == DSLTRAIN_MULTI_MODE) ++ trainmode = MULTI_MODE; ++ if(trainmode == DSLTRAIN_T1413_MODE) ++ trainmode = T1413_MODE; ++ if(trainmode == DSLTRAIN_GDMT_MODE) ++ trainmode = GDMT_MODE; ++ ++ NegoPara.stdMode = trainmode; ++ dprintf(5,"Train Mode: 0x%x\n",trainmode); ++ rc = dslhal_support_blockWrite(&NegoPara,(PVOID)dspOamSharedInterface.oamWriteNegoParams_p, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ ++ dprintf(5," dslhal_api_setTrainingMode() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_getDspVersion ++* ++******************************************************************************************* ++* DESCRIPTION: This routine supply AX5 daugther card DSP version. ++* ++* INPUT: tidsl_t * ptidsl ++* void *pVer, DSP version struct is returned starting at this pointer ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* Note: See verdef_u.h for version structure definition. ++*****************************************************************************************/ ++int dslhal_api_getDspVersion(tidsl_t *ptidsl, void *pVer) ++{ ++ /* DEV_HOST_dspVersionDef_t dspVersion; */ ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5, "dslhal_api_getDspVersion\n"); ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ if(!pVer) ++ return DSLHAL_ERROR_INVALID_PARAM; ++ ++ *(unsigned int *) pVer = 0; ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.datapumpVersion_p = (DEV_HOST_dspVersionDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.datapumpVersion_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.datapumpVersion_p, ++ pVer, sizeof(dspVer)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ pVer = (DEV_HOST_dspVersionDef_t *)(dslhal_support_byteSwap32((unsigned int)pVer)); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_gatherStatistics() ++* ++********************************************************************************************* ++* DESCRIPTION: Read statistical infromation from ax5 modem daugter card. ++* Input: tidsl_t *ptidsl ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++void dslhal_api_gatherStatistics(tidsl_t * ptidsl) ++{ ++ int rc,optIdxU,optIdxD,i; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_dspWrNegoParaDef_t rateparms; ++ DEV_HOST_oamWrNegoParaDef_t configParms; ++ DEV_HOST_modemStatsDef_t StatisticsDef; ++ DEV_HOST_errorStats_t usIntlvError, usFastError, dsIntlvError, dsFastError; ++ DEV_HOST_atmStats_t atmStats; ++ DEV_HOST_usAtmStats_t usAtmStats0, usAtmStats1; ++ DEV_HOST_dsAtmStats_t dsAtmStats0,dsAtmStats1; ++ DEV_HOST_dspWrSuperFrameCntDef_t SuperFrameCnt; ++ DEV_HOST_msg_t atuc_msg, aturMsg; ++ DEV_HOST_eocVarDef_t eocVar; ++ DEV_HOST_dspWrSharedTables_t sharedTables; ++ DEV_HOST_phyPerf_t phyPerf; ++ unsigned char usBits[64],dsBits[256]; ++ unsigned char dsPowerCutBack; ++ int usNumLoadedTones=0, dsNumLoadedTones=0; ++ ++ dprintf(5, "dslhal_api_gatherStatistics\n"); ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ if(!ptidsl->bStatisticsInitialized && ptidsl->lConnected == LINE_CONNECTED) ++ { ++ dslhal_api_initStatistics(ptidsl); ++ ptidsl->bStatisticsInitialized = TRUE; ++ } ++ ++ dspOamSharedInterface.dspWriteNegoParams_p = (DEV_HOST_dspWrNegoParaDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspWriteNegoParams_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspWriteNegoParams_p, ++ &rateparms, sizeof(DEV_HOST_dspWrNegoParaDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ if(!rc) ++ { ++ /* trained mode */ ++ ptidsl->AppData.dsl_modulation = (unsigned int)rateparms.trainMode; ++ if(rateparms.trainMode == T1413_MODE) ++ ptidsl->AppData.dsl_modulation = DSLTRAIN_T1413_MODE; ++ if(rateparms.trainMode == GDMT_MODE) ++ ptidsl->AppData.dsl_modulation = DSLTRAIN_GDMT_MODE; ++ /* rate */ ++ /* shim_osMoveMemory((void *)ptidsl->AppData.bCRates1, (void *)rateparms.cRates1, 120); */ ++ ptidsl->AppData.bCRates2 = rateparms.cRates2; ++ /* shim_osMoveMemory((void *)ptidsl->AppData.bRRates1, (void *)rateparms.rRates1, 44); */ ++ ptidsl->AppData.bRRates2 = rateparms.rRates2; ++ shim_osMoveMemory((void *)ptidsl->AppData.bCMsgs1, (void *)rateparms.cMsgs1, 6); ++ shim_osMoveMemory((void *)ptidsl->AppData.bCMsgs2, (void *)rateparms.cMsgs2, 4); ++ shim_osMoveMemory((void *)ptidsl->AppData.bRMsgs2, (void *)rateparms.rMsgs2, 4); ++ ptidsl->AppData.atucVendorId = (unsigned int)rateparms.atucVendorId; ++ ptidsl->AppData.lineLength = (unsigned int)dslhal_support_byteSwap16((unsigned short)rateparms.lineLength); ++ ptidsl->AppData.atucRevisionNum = (unsigned int)rateparms.atucGhsRevisionNum; ++ ptidsl->AppData.usLineAttn = (ptidsl->AppData.bCMsgs2[3] >>2)&0x003f; ++ ptidsl->AppData.usMargin = (ptidsl->AppData.bCMsgs2[2])&0x001f; ++ ++ if((rateparms.cRates2 & 0x0f) == 0x01) ++ optIdxU = 0; ++ else if((rateparms.cRates2 & 0x0f) == 0x02) ++ optIdxU = 1; ++ else if((rateparms.cRates2 & 0x0f) == 0x04) ++ optIdxU = 2; ++ else if((rateparms.cRates2 & 0x0f) == 0x08) ++ optIdxU = 3; ++ else ++ optIdxU = -1; ++ ++ dprintf(5, "optIdxU=%d\n", optIdxU); ++ ++ /* Obtain the US Rates using Opt# and CRates1 Table */ ++ /* Rate(US) = [Bf(LS0) + Bi(LS0)]*32 */ ++ if(ptidsl->AppData.dsl_modulation <= DSLTRAIN_GLITE_MODE) ++ ptidsl->AppData.USConRate = ((rateparms.cRates1[optIdxU][CRATES1_BF_LS0] + rateparms.cRates1[optIdxU][CRATES1_BI_LS0]) * 32); ++ else ++ ptidsl->AppData.USConRate = 32 * dslhal_support_byteSwap16((unsigned short)rateparms.adsl2USRate); ++ ++ ptidsl->AppData.USPeakCellRate = ptidsl->AppData.USConRate; ++ ++ if(((rateparms.cRates2 >> 4) & 0x0f) == 0x01) ++ optIdxD = 0; ++ else if(((rateparms.cRates2 >> 4) & 0x0f) == 0x02) ++ optIdxD = 1; ++ else if(((rateparms.cRates2 >> 4) & 0x0f) == 0x04) ++ optIdxD = 2; ++ else if(((rateparms.cRates2 >> 4) & 0x0f) == 0x08) ++ optIdxD = 3; ++ else ++ optIdxD = -1; ++ /* Obtain the DS Rates using Opt# and CRates1 Table */ ++ /* Rate(DS) = [Bf(AS0) + Bi(AS0)]*32 */ ++ if(ptidsl->AppData.dsl_modulation <= DSLTRAIN_GLITE_MODE) ++ ptidsl->AppData.DSConRate = (((rateparms.cRates1[optIdxD][CRATES1_BF_AS0]|((rateparms.cRates1[optIdxD][CRATES1_BF_DSRS]&0x80)<<1))+ (rateparms.cRates1[optIdxD][CRATES1_BI_AS0]|((rateparms.cRates1[optIdxD][CRATES1_BI_DSRS]&0x80)<<1)))* 32); ++ else ++ ptidsl->AppData.DSConRate = dslhal_support_byteSwap16((unsigned short)rateparms.adsl2DSRate); ++ ++ dprintf(5, "ptidsl->AppData.wDSConRate=%d\n", ptidsl->AppData.DSConRate); ++ /* Determine which Path has Modem Trained with */ ++ if((rateparms.cRates1[optIdxU][CRATES1_BF_LS0]) && (rateparms.cRates1[optIdxD][CRATES1_BF_AS0])) ++ ptidsl->AppData.TrainedPath = FAST_PATH; ++ else ++ ptidsl->AppData.TrainedPath = INTERLEAVED_PATH; ++ ++ /* Set the mode in which the modem is trained */ ++ ptidsl->AppData.TrainedMode = (unsigned int)rateparms.trainMode; ++ if(rateparms.trainMode == T1413_MODE) ++ ptidsl->AppData.TrainedMode = DSLTRAIN_T1413_MODE; ++ if(rateparms.trainMode == GDMT_MODE) ++ ptidsl->AppData.TrainedMode = DSLTRAIN_GDMT_MODE; ++ ++ if(ptidsl->AppData.TrainedPath == FAST_PATH) ++ ptidsl->AppData.dsFastParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BF_DSRS]&0x1f); ++ else ++ ptidsl->AppData.dsIntlvParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BI_DSRS]&0x1f); ++ ptidsl->AppData.dsSymbolsPerCodeWord = (rateparms.cRates1[optIdxU][CRATES1_BFI_DSS]&0x1f); ++ ptidsl->AppData.dsInterleaverDepth = ((rateparms.cRates1[optIdxU][CRATES1_BFI_DSI])|((rateparms.cRates1[optIdxU][CRATES1_BFI_DSS]&0xc0)<<2)); ++ ++ if(ptidsl->AppData.TrainedPath == FAST_PATH) ++ ptidsl->AppData.usFastParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BF_USRS]&0x1f); ++ else ++ ptidsl->AppData.usIntlvParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BI_USRS]&0x1f); ++ ptidsl->AppData.usSymbolsPerCodeWord = (rateparms.cRates1[optIdxU][CRATES1_BFI_USS]&0x1f); ++ ptidsl->AppData.usInterleaverDepth = ((rateparms.cRates1[optIdxU][CRATES1_BFI_USI])|((rateparms.cRates1[optIdxU][CRATES1_BFI_USS]&0xc0)<<2)); ++ } ++ ++ dspOamSharedInterface.modemStats_p = (DEV_HOST_modemStatsDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.modemStats_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.modemStats_p,&StatisticsDef, sizeof(DEV_HOST_modemStatsDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ /* Populate the Error Structure Variables */ ++ ++ /* US Interleave Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.usErrorStatsIntlv_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.usErrorStatsIntlv_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.usErrorStatsIntlv_p,&usIntlvError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* DS Interleave Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.dsErrorStatsIntlv_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.dsErrorStatsIntlv_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.dsErrorStatsIntlv_p,&dsIntlvError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* US Fast Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.usErrorStatsFast_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.usErrorStatsFast_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.usErrorStatsFast_p,&usFastError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* DS Fast Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.dsErrorStatsFast_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.dsErrorStatsFast_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.dsErrorStatsFast_p,&dsFastError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ if(!rc) ++ { ++ if(ptidsl->AppData.bState > 2) ++ { ++ /* Get CRC Errors Stats for both US and DS */ ++ ptidsl->AppData.dsICRC_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.crcErrors); ++ ptidsl->AppData.dsFCRC_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.crcErrors); ++ ptidsl->AppData.usICRC_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.crcErrors); ++ ptidsl->AppData.usFCRC_errors = dslhal_support_byteSwap32((unsigned int)usFastError.crcErrors); ++ /* Get FEC Errors Stats for both US and DS */ ++ ptidsl->AppData.dsIFEC_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.fecErrors); ++ ptidsl->AppData.dsFFEC_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.fecErrors); ++ ptidsl->AppData.usIFEC_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.fecErrors); ++ ptidsl->AppData.usFFEC_errors = dslhal_support_byteSwap32((unsigned int)usFastError.fecErrors); ++ /* Get NCD Errors Stats for both US and DS */ ++ ptidsl->AppData.dsINCD_error = dslhal_support_byteSwap32((unsigned int)dsIntlvError.ncdError); ++ ptidsl->AppData.dsFNCD_error = dslhal_support_byteSwap32((unsigned int)dsFastError.ncdError); ++ ptidsl->AppData.usINCD_error = dslhal_support_byteSwap32((unsigned int)usIntlvError.ncdError); ++ ptidsl->AppData.usFNCD_error = dslhal_support_byteSwap32((unsigned int)usFastError.ncdError); ++ /* Get LCD Errors Stats for both US and DS */ ++ ptidsl->AppData.dsILCD_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.lcdErrors); ++ ptidsl->AppData.dsFLCD_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.lcdErrors); ++ ptidsl->AppData.usILCD_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.lcdErrors); ++ ptidsl->AppData.usFLCD_errors = dslhal_support_byteSwap32((unsigned int)usFastError.lcdErrors); ++ /*Get HEC Errors Stats for both US and DS */ ++ ptidsl->AppData.dsIHEC_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.hecErrors); ++ ptidsl->AppData.dsFHEC_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.hecErrors); ++ ptidsl->AppData.usIHEC_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.hecErrors); ++ ptidsl->AppData.usFHEC_errors = dslhal_support_byteSwap32((unsigned int)usFastError.hecErrors); ++ ++ /* Get LOS and SEF error Stats */ ++ ptidsl->AppData.LOS_errors = dslhal_support_byteSwap32(StatisticsDef.losErrors); ++ ptidsl->AppData.SEF_errors = dslhal_support_byteSwap32(StatisticsDef.sefErrors); ++ ptidsl->AppData.coLosErrors = dslhal_support_byteSwap32(StatisticsDef.farEndLosErrors); ++ ptidsl->AppData.coRdiErrors = dslhal_support_byteSwap32(StatisticsDef.farEndRdiErrors); ++ ++ dspOamSharedInterface.atmStats_p = (DEV_HOST_atmStats_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.atmStats_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.atmStats_p,&atmStats, sizeof(DEV_HOST_atmStats_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ /* Populate the US/DS ATM Stats Variables */ ++ ++ /* US ATM Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ atmStats.us0_p = (DEV_HOST_usAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.us0_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.us0_p,&usAtmStats0, (sizeof(DEV_HOST_usAtmStats_t))); ++ ++ if (rc) ++ return; ++ ++ atmStats.us1_p = (DEV_HOST_usAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.us1_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.us1_p,&usAtmStats1, (sizeof(DEV_HOST_usAtmStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* DS ATM Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ atmStats.ds0_p = (DEV_HOST_dsAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.ds0_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.ds0_p,&dsAtmStats0, (sizeof(DEV_HOST_dsAtmStats_t))); ++ ++ if (rc) ++ return; ++ atmStats.ds1_p = (DEV_HOST_dsAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.ds1_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.ds1_p,&dsAtmStats1, (sizeof(DEV_HOST_dsAtmStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* Get ATM Stats for both US and DS for Channel 0*/ ++ ptidsl->AppData.usAtm_count[0] = dslhal_support_byteSwap32(usAtmStats0.goodCount); ++ ptidsl->AppData.usIdle_count[0] = dslhal_support_byteSwap32(usAtmStats0.idleCount); ++#if SWTC ++ ptidsl->AppData.usPdu_count[0] = dslhal_support_byteSwap32(usAtmStats0.pduCount); ++#endif ++ ptidsl->AppData.dsGood_count[0] = dslhal_support_byteSwap32(dsAtmStats0.goodCount); ++ ptidsl->AppData.dsIdle_count[0] = dslhal_support_byteSwap32(dsAtmStats0.idleCount); ++#if SWTC ++ ptidsl->AppData.dsPdu_count[0] = dslhal_support_byteSwap32(dsAtmStats0.pduCount); ++#endif ++ ptidsl->AppData.dsBadHec_count[0] = dslhal_support_byteSwap32((dsAtmStats0.badHecCount)); ++ ptidsl->AppData.dsOVFDrop_count[0] = dslhal_support_byteSwap32((dsAtmStats0.ovflwDropCount)); ++ /* Get ATM Stats for both US and DS for Channel 1*/ ++ ptidsl->AppData.usAtm_count[1] = dslhal_support_byteSwap32(usAtmStats1.goodCount); ++ ptidsl->AppData.usIdle_count[1] = dslhal_support_byteSwap32(usAtmStats1.idleCount); ++#if SWTC ++ ptidsl->AppData.usPdu_count[1] = dslhal_support_byteSwap32(usAtmStats1.pduCount); ++#endif ++ ptidsl->AppData.dsGood_count[1] = dslhal_support_byteSwap32(dsAtmStats1.goodCount); ++ ptidsl->AppData.dsIdle_count[1] = dslhal_support_byteSwap32(dsAtmStats1.idleCount); ++#if SWTC ++ ptidsl->AppData.dsPdu_count[1] = dslhal_support_byteSwap32(dsAtmStats1.pduCount); ++#endif ++ ptidsl->AppData.dsBadHec_count[1] = dslhal_support_byteSwap32((dsAtmStats1.badHecCount)); ++ ptidsl->AppData.dsOVFDrop_count[1] = dslhal_support_byteSwap32((dsAtmStats1.ovflwDropCount)); ++ ++ /* Determine the US and DS Superframe Count */ ++ ++ dspOamSharedInterface.dspWriteSuperFrameCnt_p = (DEV_HOST_dspWrSuperFrameCntDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspWriteSuperFrameCnt_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspWriteSuperFrameCnt_p,&SuperFrameCnt, sizeof(DEV_HOST_dspWrSuperFrameCntDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ptidsl->AppData.usSuperFrmCnt = dslhal_support_byteSwap32(SuperFrameCnt.wSuperFrameCntUstrm); ++ ptidsl->AppData.dsSuperFrmCnt = dslhal_support_byteSwap32(SuperFrameCnt.wSuperFrameCntDstrm); ++ ++ /* Determine Frame Mode and Max Frame Mode */ ++ ++ dspOamSharedInterface.atucMsg_p = (DEV_HOST_msg_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.atucMsg_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.atucMsg_p,&atuc_msg, sizeof(DEV_HOST_msg_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ ptidsl->AppData.FrmMode = (unsigned int)atuc_msg.framingMode; ++ ptidsl->AppData.MaxFrmMode = (unsigned int)atuc_msg.maxFrameMode; ++ ++ /* Determine Gross Gain */ ++ ++ dspOamSharedInterface.aturMsg_p = (DEV_HOST_msg_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.aturMsg_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.aturMsg_p,&aturMsg, sizeof(DEV_HOST_msg_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ptidsl->AppData.grossGain = (unsigned int)aturMsg.grossGain; ++ ++ /* Determine DS Line Attenuation & Margin */ ++ dspOamSharedInterface.eocVar_p = (DEV_HOST_eocVarDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.eocVar_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.eocVar_p,&eocVar, sizeof(DEV_HOST_eocVarDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ptidsl->AppData.dsLineAttn = (unsigned int)eocVar.lineAtten; ++ ptidsl->AppData.dsMargin = (unsigned int)eocVar.dsMargin; ++ } ++ } ++ ++ /* Read in the Shared Tables structure */ ++ dspOamSharedInterface.dspWrSharedTables_p = (DEV_HOST_dspWrSharedTables_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspWrSharedTables_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspWrSharedTables_p,&sharedTables, sizeof(DEV_HOST_dspWrSharedTables_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ /* Read the ATU-R Bits and Gains Table */ ++ sharedTables.aturBng_p = (unsigned char *)dslhal_support_byteSwap32((unsigned int)sharedTables.aturBng_p); ++ rc = dslhal_support_blockRead((PVOID)sharedTables.aturBng_p,ptidsl->AppData.rBng,255*2*sizeof(unsigned char)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ /* Read the ATU-C Bits and Gains Table */ ++ sharedTables.atucBng_p = (unsigned char *)dslhal_support_byteSwap32((unsigned int)sharedTables.atucBng_p); ++ if(ptidsl->netService == 2) /* for Annex_B */ ++ { ++ rc = dslhal_support_blockRead((PVOID)sharedTables.atucBng_p,ptidsl->AppData.cBng,126*sizeof(unsigned char)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ for(i=0;iAppData.cBng[(i-1)*2])&0xf); ++ dprintf(5,"Bit #%d : 0x%x\n",i,usBits[i]); ++ } ++ for(i=1;iAppData.cBng,62*sizeof(unsigned char)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ for(i=0;iAppData.cBng[(i-1)*2])&0xf); ++ dprintf(5,"Bit #%d : 0x%x\n",i,usBits[i]); ++ } ++ for(i=1;iAppData.currentHybridNum = phyPerf.currentHybridNumUsed; ++ phyPerf.usAvgGain = dslhal_support_byteSwap32(phyPerf.usAvgGain); ++ ptidsl->AppData.usTxPower = LOG43125 + phyPerf.usAvgGain + (256*US_NOMINAL_POWER)+log10[usNumLoadedTones-1]; ++ dprintf(7,"Avg Gain: 0x%x usNumLoadedTones: 0x%x log: 0x%x\n",phyPerf.usAvgGain, usNumLoadedTones, log10[usNumLoadedTones-1]); ++ ++ /* Determine Number D/S of Loaded Tones */ ++ dsBits[0]=0; ++ for(i=0;iAppData.rBng[i-1]=dslhal_support_byteSwap32((unsigned int)ptidsl->AppData.rBng[i-1]);*/ ++ } ++ for(i=1;iAppData.rBng[(i-1)*2])&0xf); ++ dprintf(5,"Bit #%d : 0x%x\n",i,dsBits[i]); ++ } ++ for(i=1;iAppData.bCMsgs1[0]) >>6) &0x3)+(((ptidsl->AppData.bCMsgs1[1]) &0x1) <<2)); ++ phyPerf.dsAvgGain = dslhal_support_byteSwap32(phyPerf.dsAvgGain); ++ ptidsl->AppData.dsTxPower = LOG43125 + phyPerf.dsAvgGain + (256*((2*(dsPowerCutBack-1))-52)) + log10[dsNumLoadedTones-1]; ++ dprintf(7,"Avg Gain: %d dsNumLoadedTones: %d log: %d pcb: %d \n",phyPerf.dsAvgGain, dsNumLoadedTones, log10[dsNumLoadedTones-1], dsPowerCutBack); ++ /* ds bit allocation */ ++ sharedTables.bitAllocTblDstrm_p = (unsigned char *)dslhal_support_byteSwap32((unsigned int)sharedTables.bitAllocTblDstrm_p); ++ rc = dslhal_support_blockRead((PVOID)sharedTables.bitAllocTblDstrm_p,ptidsl->AppData.BitAllocTblDstrm, 256*sizeof(unsigned char)); ++ if(rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed \n"); ++ return; ++ } ++ ++ /* us bit allocation */ ++ sharedTables.bitAllocTblUstrm_p = (unsigned char *)dslhal_support_byteSwap32((unsigned int)sharedTables.bitAllocTblUstrm_p); ++ rc = dslhal_support_blockRead((PVOID)sharedTables.bitAllocTblUstrm_p,ptidsl->AppData.BitAllocTblUstrm, 32*sizeof(unsigned char)); ++ if(rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed \n"); ++ return; ++ } ++ /* margin per tone */ ++ sharedTables.marginTblDstrm_p = (signed char *)dslhal_support_byteSwap32((unsigned int)sharedTables.marginTblDstrm_p); ++ rc = dslhal_support_blockRead((PVOID)sharedTables.marginTblDstrm_p,ptidsl->AppData.marginTblDstrm, 256*sizeof(signed char)); ++ if(rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed \n"); ++ return; ++ } ++ /* Read Configured Options */ ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.oamWriteNegoParams_p, ++ &configParms, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ else ++ { ++ /* r-Msg1 */ ++ ptidsl->AppData.StdMode = (unsigned int)configParms.stdMode; ++ if(configParms.stdMode == T1413_MODE) ++ ptidsl->AppData.StdMode = DSLTRAIN_T1413_MODE; ++ if(configParms.stdMode == GDMT_MODE) ++ ptidsl->AppData.StdMode = DSLTRAIN_GDMT_MODE; ++ if(configParms.stdMode == MULTI_MODE) ++ ptidsl->AppData.StdMode = DSLTRAIN_MULTI_MODE; ++ ++ shim_osMoveMemory((void *)ptidsl->AppData.bRMsgs1, (void *)configParms.rMsgs1, 6*sizeof(char)); ++ if((ptidsl->AppData.bRMsgs1[2] & 0x02) == 0x02) ++ { ++ dprintf(7,"Trellis!\n"); ++ ptidsl->configFlag |= CONFIG_FLAG_TRELLIS; ++ } ++ else ++ ptidsl->configFlag &= ~CONFIG_FLAG_TRELLIS; ++ if(ptidsl->AppData.bRMsgs1[2]&0x01) ++ ptidsl->configFlag |= CONFIG_FLAG_EC; ++ else ++ ptidsl->configFlag &= ~CONFIG_FLAG_EC; ++ } ++ return; ++} ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_initStatistics() ++* ++********************************************************************************************* ++* DESCRIPTION: init statistical information of ax5 modem daugter card. ++* ++* Input: tidsl_t *ptidsl ++* ++* Return: NULL ++* ++********************************************************************************************/ ++void dslhal_api_initStatistics(tidsl_t * ptidsl) ++{ ++ int rc; ++ /*TCHostCommDef TCHostCommParms; */ ++ int optIdxU, optIdxD; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_dspWrNegoParaDef_t rateparms; ++ DEV_HOST_modemStatsDef_t StatisticsDef; ++ DEV_HOST_errorStats_t usIntlvError, usFastError, dsIntlvError, dsFastError; ++ DEV_HOST_atmStats_t atmStats; ++ DEV_HOST_usAtmStats_t usAtmStats0, usAtmStats1; ++ DEV_HOST_dsAtmStats_t dsAtmStats0,dsAtmStats1; ++ DEV_HOST_dspWrSuperFrameCntDef_t SuperFrameCnt; ++ DEV_HOST_msg_t atuc_msg, aturMsg; ++ DEV_HOST_eocVarDef_t eocVar; ++ ++ dprintf(5, "dslhal_api_initStatistics\n"); ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterface_t *) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ dspOamSharedInterface.dspWriteNegoParams_p = (DEV_HOST_dspWrNegoParaDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspWriteNegoParams_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspWriteNegoParams_p,&rateparms, sizeof(DEV_HOST_dspWrNegoParaDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ if(!rc) ++ { ++ /* shim_osMoveMemory((void *)ptidsl->AppData.bCRates1, (void *)rateparms.cRates1, SIZE_OF_CRATES1_TABLE); */ ++ ptidsl->AppData.bCRates2 = rateparms.cRates2; ++ /* shim_osMoveMemory((void *)ptidsl->AppData.bRRates1, (void *)rateparms.rRates1, 44); */ ++ ptidsl->AppData.bRRates2 = rateparms.rRates2; ++ shim_osMoveMemory((void *)ptidsl->AppData.bCMsgs1, (void *)rateparms.cMsgs1, 6); ++ shim_osMoveMemory((void *)ptidsl->AppData.bCMsgs2, (void *)rateparms.cMsgs2, 4); ++ shim_osMoveMemory((void *)ptidsl->AppData.bRMsgs2, (void *)rateparms.rMsgs2, 4); ++ ++ ptidsl->AppData.atucVendorId = dslhal_support_byteSwap32((unsigned int)rateparms.atucVendorId); ++ ptidsl->AppData.lineLength = (unsigned int)dslhal_support_byteSwap16((unsigned short)rateparms.lineLength); ++ ptidsl->AppData.atucRevisionNum = rateparms.atucGhsRevisionNum; ++ ptidsl->AppData.usLineAttn = (ptidsl->AppData.bCMsgs2[3] >>2)&0x003f; ++ ptidsl->AppData.usMargin = (ptidsl->AppData.bCMsgs2[2])&0x001f; ++ ++ /* Get the UpStream Connection Rate */ ++ /* Based on the Bit Pattern Get the Opt# */ ++ if((rateparms.cRates2 & 0x0f) == 0x01) ++ optIdxU = 0; ++ else if((rateparms.cRates2 & 0x0f) == 0x02) ++ optIdxU = 1; ++ else if((rateparms.cRates2 & 0x0f) == 0x04) ++ optIdxU = 2; ++ else if((rateparms.cRates2 & 0x0f) == 0x08) ++ optIdxU = 3; ++ else ++ optIdxU = -1; ++ dprintf(5, "optIdxU=%d\n", optIdxU); ++ /* Obtain the US Rates using Opt# and CRates1 Table */ ++ /* Rate(US) = [Bf(LS0) + Bi(LS0)]*32 */ ++ if(ptidsl->AppData.dsl_modulation <= DSLTRAIN_GLITE_MODE) ++ ptidsl->AppData.USConRate = ((rateparms.cRates1[optIdxU][CRATES1_BF_LS0] + rateparms.cRates1[optIdxU][CRATES1_BI_LS0]) * 32); ++ else ++ ptidsl->AppData.USConRate = dslhal_support_byteSwap16((unsigned short)rateparms.adsl2USRate); ++ ptidsl->AppData.USPeakCellRate = ptidsl->AppData.USConRate; ++ ++ /* Get the DownStream Connection Rate */ ++ /* Based on the Bit Pattern Get the Opt# */ ++ if(((rateparms.cRates2 >> 4) & 0x0f) == 0x01) ++ optIdxD = 0; ++ else if(((rateparms.cRates2 >> 4) & 0x0f) == 0x02) ++ optIdxD = 1; ++ else if(((rateparms.cRates2 >> 4) & 0x0f) == 0x04) ++ optIdxD = 2; ++ else if(((rateparms.cRates2 >> 4) & 0x0f) == 0x08) ++ optIdxD = 3; ++ else ++ optIdxD = -1; ++ /* Obtain the DS Rates using Opt# and CRates1 Table */ ++ /* Rate(DS) = [Bf(AS0) + Bi(AS0)]*32 */ ++ if(ptidsl->AppData.dsl_modulation <= DSLTRAIN_GLITE_MODE) ++ ptidsl->AppData.DSConRate = (((rateparms.cRates1[optIdxD][CRATES1_BF_AS0]|((rateparms.cRates1[optIdxD][CRATES1_BF_DSRS]&0x80)<<1))+ (rateparms.cRates1[optIdxD][CRATES1_BI_AS0]|((rateparms.cRates1[optIdxD][CRATES1_BI_DSRS]&0x80)<<1)))* 32); ++ else ++ ptidsl->AppData.DSConRate = dslhal_support_byteSwap16((unsigned short)rateparms.adsl2DSRate); ++ dprintf(5, "ptidsl->AppData.wDSConRate=%d\n", ptidsl->AppData.DSConRate); ++ /* Determine which Path has Modem Trained with */ ++ if((rateparms.cRates1[optIdxU][CRATES1_BF_LS0]) && (rateparms.cRates1[optIdxD][CRATES1_BF_AS0])) ++ ptidsl->AppData.TrainedPath = FAST_PATH; ++ else ++ ptidsl->AppData.TrainedPath = INTERLEAVED_PATH; ++ ++ /* Set the mode in which the modem is trained */ ++ ptidsl->AppData.TrainedMode = (unsigned int)rateparms.trainMode; ++ if(rateparms.trainMode == T1413_MODE) ++ ptidsl->AppData.TrainedMode = DSLTRAIN_T1413_MODE; ++ if(rateparms.trainMode == GDMT_MODE) ++ ptidsl->AppData.TrainedMode = DSLTRAIN_GDMT_MODE; ++ ++ if(ptidsl->AppData.TrainedPath == FAST_PATH) ++ ptidsl->AppData.dsFastParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BF_DSRS]&0x1f); ++ else ++ ptidsl->AppData.dsIntlvParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BI_DSRS]&0x1f); ++ ptidsl->AppData.dsSymbolsPerCodeWord = (rateparms.cRates1[optIdxU][CRATES1_BFI_DSS]&0x1f); ++ ptidsl->AppData.dsInterleaverDepth = ((rateparms.cRates1[optIdxU][CRATES1_BFI_DSI])|((rateparms.cRates1[optIdxU][CRATES1_BFI_DSS]&0xc0)<<2)); ++ ++ if(ptidsl->AppData.TrainedPath == FAST_PATH) ++ ptidsl->AppData.usFastParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BF_USRS]&0x1f); ++ else ++ ptidsl->AppData.usIntlvParityBytesPerSymbol = (rateparms.cRates1[optIdxU][CRATES1_BI_USRS]&0x1f); ++ ptidsl->AppData.usSymbolsPerCodeWord = (rateparms.cRates1[optIdxU][CRATES1_BFI_USS]&0x1f); ++ ptidsl->AppData.usInterleaverDepth = ((rateparms.cRates1[optIdxU][CRATES1_BFI_USI])|((rateparms.cRates1[optIdxU][CRATES1_BFI_USS]&0xc0)<<2)); ++ } ++ ++ /* get the Statistics itself */ ++ ++ dspOamSharedInterface.modemStats_p = (DEV_HOST_modemStatsDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.modemStats_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.modemStats_p,&StatisticsDef, sizeof(DEV_HOST_modemStatsDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ /* Populate the Error Structure Variables */ ++ ++ /* US Interleave Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.usErrorStatsIntlv_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.usErrorStatsIntlv_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.usErrorStatsIntlv_p,&usIntlvError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* DS Interleave Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.dsErrorStatsIntlv_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.dsErrorStatsIntlv_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.dsErrorStatsIntlv_p,&dsIntlvError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* US Fast Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.usErrorStatsFast_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.usErrorStatsFast_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.usErrorStatsFast_p,&usFastError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ ++ ++ /* DS Fast Path Error Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ StatisticsDef.dsErrorStatsFast_p = (DEV_HOST_errorStats_t *) dslhal_support_byteSwap32((unsigned int)StatisticsDef.dsErrorStatsFast_p); ++ ++ rc = dslhal_support_blockRead((PVOID)StatisticsDef.dsErrorStatsFast_p,&dsFastError, (sizeof(DEV_HOST_errorStats_t))); ++ ++ if (rc) ++ return; ++ ++ if(ptidsl->AppData.bState > 2) ++ { ++ /* Get CRC Errors Stats for both US and DS */ ++ ptidsl->AppData.dsICRC_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.crcErrors); ++ ptidsl->AppData.dsFCRC_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.crcErrors); ++ ptidsl->AppData.usICRC_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.crcErrors); ++ ptidsl->AppData.usFCRC_errors = dslhal_support_byteSwap32((unsigned int)usFastError.crcErrors); ++ /* Get FEC Errors Stats for both US and DS */ ++ ptidsl->AppData.dsIFEC_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.fecErrors); ++ ptidsl->AppData.dsFFEC_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.fecErrors); ++ ptidsl->AppData.usIFEC_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.fecErrors); ++ ptidsl->AppData.usFFEC_errors = dslhal_support_byteSwap32((unsigned int)usFastError.fecErrors); ++ /* Get NCD Errors Stats for both US and DS */ ++ ptidsl->AppData.dsINCD_error = dslhal_support_byteSwap32((unsigned int)dsIntlvError.ncdError); ++ ptidsl->AppData.dsFNCD_error = dslhal_support_byteSwap32((unsigned int)dsFastError.ncdError); ++ ptidsl->AppData.usINCD_error = dslhal_support_byteSwap32((unsigned int)usIntlvError.ncdError); ++ ptidsl->AppData.usFNCD_error = dslhal_support_byteSwap32((unsigned int)usFastError.ncdError); ++ /* Get LCD Errors Stats for both US and DS */ ++ ptidsl->AppData.dsILCD_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.lcdErrors); ++ ptidsl->AppData.dsFLCD_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.lcdErrors); ++ ptidsl->AppData.usILCD_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.lcdErrors); ++ ptidsl->AppData.usFLCD_errors = dslhal_support_byteSwap32((unsigned int)usFastError.lcdErrors); ++ /*Get HEC Errors Stats for both US and DS */ ++ ptidsl->AppData.dsIHEC_errors = dslhal_support_byteSwap32((unsigned int)dsIntlvError.hecErrors); ++ ptidsl->AppData.dsFHEC_errors = dslhal_support_byteSwap32((unsigned int)dsFastError.hecErrors); ++ ptidsl->AppData.usIHEC_errors = dslhal_support_byteSwap32((unsigned int)usIntlvError.hecErrors); ++ ptidsl->AppData.usFHEC_errors = dslhal_support_byteSwap32((unsigned int)usFastError.hecErrors); ++ ++ /* Get LOS and SEF error Stats */ ++ ptidsl->AppData.LOS_errors = dslhal_support_byteSwap32(StatisticsDef.losErrors); ++ ptidsl->AppData.SEF_errors = dslhal_support_byteSwap32(StatisticsDef.sefErrors); ++ ptidsl->AppData.coLosErrors = dslhal_support_byteSwap32(StatisticsDef.farEndLosErrors); ++ ptidsl->AppData.coRdiErrors = dslhal_support_byteSwap32(StatisticsDef.farEndRdiErrors); ++ ++ dspOamSharedInterface.atmStats_p = (DEV_HOST_atmStats_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.atmStats_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.atmStats_p,&atmStats, sizeof(DEV_HOST_atmStats_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ /* Populate the US/DS ATM Stats Variables */ ++ ++ /* US ATM Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ atmStats.us0_p = (DEV_HOST_usAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.us0_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.us0_p,&usAtmStats0, (sizeof(DEV_HOST_usAtmStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* Change the endianness of the Pointer */ ++ atmStats.us1_p = (DEV_HOST_usAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.us1_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.us1_p,&usAtmStats1, (sizeof(DEV_HOST_usAtmStats_t))); ++ ++ if (rc) ++ return; ++ ++ ++ /* DS ATM Statistics */ ++ ++ /* Change the endianness of the Pointer */ ++ atmStats.ds0_p = (DEV_HOST_dsAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.ds0_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.ds0_p,&dsAtmStats0, (sizeof(DEV_HOST_dsAtmStats_t))); ++ ++ if (rc) ++ return; ++ ++ /* Change the endianness of the Pointer */ ++ atmStats.ds1_p = (DEV_HOST_dsAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.ds1_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.ds1_p,&dsAtmStats1, (sizeof(DEV_HOST_dsAtmStats_t))); ++ ++ if (rc) ++ return; ++ /* Get ATM Stats for both US and DS Channel 0*/ ++ ptidsl->AppData.usAtm_count[0] = dslhal_support_byteSwap32(usAtmStats0.goodCount); ++ ptidsl->AppData.usIdle_count[0] = dslhal_support_byteSwap32(usAtmStats0.idleCount); ++#if SWTC ++ ptidsl->AppData.usPdu_count[0] = dslhal_support_byteSwap32(usAtmStats0.pduCount); ++#endif ++ ptidsl->AppData.dsGood_count[0] = dslhal_support_byteSwap32(dsAtmStats0.goodCount); ++ ptidsl->AppData.dsIdle_count[0] = dslhal_support_byteSwap32(dsAtmStats0.idleCount); ++#if SWTC ++ ptidsl->AppData.dsPdu_count[0] = dslhal_support_byteSwap32(dsAtmStats0.pduCount); ++#endif ++ ptidsl->AppData.dsBadHec_count[0] = dslhal_support_byteSwap32((dsAtmStats0.badHecCount)); ++ ptidsl->AppData.dsOVFDrop_count[0] = dslhal_support_byteSwap32((dsAtmStats0.ovflwDropCount)); ++ ++ /* Get ATM Stats for both US and DS Channel 1*/ ++ ptidsl->AppData.usAtm_count[1] = dslhal_support_byteSwap32(usAtmStats1.goodCount); ++ ptidsl->AppData.usIdle_count[1] = dslhal_support_byteSwap32(usAtmStats1.idleCount); ++#if SWTC ++ ptidsl->AppData.usPdu_count[1] = dslhal_support_byteSwap32(usAtmStats1.pduCount); ++#endif ++ ptidsl->AppData.dsGood_count[1] = dslhal_support_byteSwap32(dsAtmStats1.goodCount); ++ ptidsl->AppData.dsIdle_count[1] = dslhal_support_byteSwap32(dsAtmStats1.idleCount); ++#if SWTC ++ ptidsl->AppData.dsPdu_count[1] = dslhal_support_byteSwap32(dsAtmStats1.pduCount); ++#endif ++ ptidsl->AppData.dsBadHec_count[1] = dslhal_support_byteSwap32((dsAtmStats1.badHecCount)); ++ ptidsl->AppData.dsOVFDrop_count[1] = dslhal_support_byteSwap32((dsAtmStats1.ovflwDropCount)); ++ ++ ++ /* Determine the US and DS Superframe Count */ ++ ++ dspOamSharedInterface.dspWriteSuperFrameCnt_p = (DEV_HOST_dspWrSuperFrameCntDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspWriteSuperFrameCnt_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspWriteSuperFrameCnt_p,&SuperFrameCnt, sizeof(DEV_HOST_dspWrSuperFrameCntDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ ptidsl->AppData.usSuperFrmCnt = dslhal_support_byteSwap32(SuperFrameCnt.wSuperFrameCntUstrm); ++ ptidsl->AppData.dsSuperFrmCnt = dslhal_support_byteSwap32(SuperFrameCnt.wSuperFrameCntDstrm); ++ ++ /* Determine Frame Mode and Max Frame Mode */ ++ ++ dspOamSharedInterface.atucMsg_p = (DEV_HOST_msg_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.atucMsg_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.atucMsg_p,&atuc_msg, sizeof(DEV_HOST_msg_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ ptidsl->AppData.FrmMode = (unsigned int)atuc_msg.framingMode; ++ ptidsl->AppData.MaxFrmMode = (unsigned int)atuc_msg.maxFrameMode; ++ ++ /* Determine Gross Gain */ ++ ++ dspOamSharedInterface.aturMsg_p = (DEV_HOST_msg_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.aturMsg_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.aturMsg_p,&aturMsg, sizeof(DEV_HOST_msg_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ptidsl->AppData.grossGain = (unsigned int)aturMsg.grossGain; ++ /* Determine DS Line Attenuation & Margin */ ++ dspOamSharedInterface.eocVar_p = (DEV_HOST_eocVarDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.eocVar_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.eocVar_p,&eocVar, sizeof(DEV_HOST_eocVarDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return; ++ } ++ ++ ptidsl->AppData.dsLineAttn = (unsigned int)eocVar.lineAtten; ++ ptidsl->AppData.dsMargin = (unsigned int)eocVar.dsMargin; ++ } ++ ++#if __HOST_FORINTERNALUSEONLY_R_H__ ++ ptidsl->AppData.BER = dslhal_INTERNAL_computeAtmBitErrorRate(ptidsl); ++#endif ++ dprintf(5, "initstatistics done\n"); ++ return; ++ } ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_disableLosAlarm(tidsl_t *ptidsl,unsigned int set) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction enables/disables all the LOS alarms ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * unsigned int set; //if set is TRUE: LOS Alarms are disabled else enabled ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * NOTES: Currently not supported in any version other than MR4 Patch release.. ++ *****************************************************************************************/ ++unsigned int dslhal_api_disableLosAlarm(tidsl_t *ptidsl,unsigned int set) ++{ ++ DEV_HOST_oamWrNegoParaDef_t NegoPara; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5," dslhal_api_setTrainingMode()\n"); ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ ++ rc = dslhal_support_blockRead((PVOID) dspOamSharedInterface.oamWriteNegoParams_p,&NegoPara, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ if(set) ++ { ++ NegoPara.disableLosAlarm = TRUE; ++ /* NegoPara.marginMonitorTrning = TRUE; ++ NegoPara.marginMonitorShwtme = TRUE;*/ ++ } ++ else ++ { ++ NegoPara.disableLosAlarm = FALSE; ++ /* NegoPara.marginMonitorTrning = FALSE; ++ NegoPara.marginMonitorShwtme = FALSE;*/ ++ } ++ ++ rc = dslhal_support_blockWrite(&NegoPara,(PVOID)dspOamSharedInterface.oamWriteNegoParams_p, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ dprintf(5," dslhal_api_disableLosAlarm() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setMarginThreshold(tidsl_t *ptidsl,int threshold) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction does sets the Margin threshold ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * int threshold ++ * ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setMarginThreshold(tidsl_t *ptidsl, int threshold) ++{ ++ DEV_HOST_oamWrNegoParaDef_t NegoPara; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ ++ dprintf(5," dslhal_ctrl_setThreshold()\n"); ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ ++ ++ rc = dslhal_support_blockRead((PVOID) dspOamSharedInterface.oamWriteNegoParams_p,&NegoPara, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ NegoPara.marginThreshold = threshold; ++ ++ rc = dslhal_support_blockWrite(&NegoPara,dspOamSharedInterface.oamWriteNegoParams_p, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ ++ if(rc) ++ return DSLHAL_ERROR_MARGIN_API_FAILURE; ++ ++ dprintf(5," dslhal_api_setThreshold() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setMonitorFlags(tidsl_t *ptidsl, unsigned int trainflag,unsigned int shwtflag) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction does sets the Margin monitoring flag ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * unsigned int trainflag ++ * unsigned int shwtflag ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setMarginMonitorFlags(tidsl_t *ptidsl,unsigned int trainflag,unsigned int shwtflag) ++{ ++ DEV_HOST_oamWrNegoParaDef_t NegoPara; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ ++ dprintf(5," dslhal_ctrl_setMonitorFlags()\n"); ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ ++ ++ rc = dslhal_support_blockRead((PVOID) dspOamSharedInterface.oamWriteNegoParams_p,&NegoPara, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ if (trainflag) ++ { ++ NegoPara.marginMonitorTrning = TRUE; ++ } ++ else ++ { ++ NegoPara.marginMonitorTrning = FALSE; ++ } ++ if (shwtflag) ++ { ++ NegoPara.marginMonitorShwtme = TRUE; ++ } ++ else ++ { ++ NegoPara.marginMonitorShwtme = FALSE; ++ } ++ ++ rc = dslhal_support_blockWrite(&NegoPara,dspOamSharedInterface.oamWriteNegoParams_p, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_MARGIN_API_FAILURE; ++ dprintf(5," dslhal_api_setMonitorFlags() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setEocSerialNumber(tidsl_t *ptidsl,char *SerialNum) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the eoc Serial Number ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *SerialNum : Input eoc Serial Number ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setEocSerialNumber(tidsl_t *ptidsl,char *SerialNumber) ++{ ++ DEV_HOST_eocVarDef_t eocVar; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5," dslhal_api_setEocSerialNumber()\n"); ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.eocVar_p = (DEV_HOST_eocVarDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.eocVar_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.eocVar_p, ++ &eocVar, sizeof(DEV_HOST_eocVarDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ shim_osMoveMemory(eocVar.serialNumber,SerialNumber,32); ++ ++ rc= dslhal_support_blockWrite(&eocVar,dspOamSharedInterface.eocVar_p,sizeof(DEV_HOST_eocVarDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_EOCREG_API_FAILURE; ++ dprintf(5," dslhal_api_setEocSerialNumber() Done\n"); ++ ++ return DSLHAL_ERROR_NO_ERRORS; ++ ++} ++ ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setEocVendorId(tidsl_t *ptidsl,char *VendorID) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the eoc Vendor ID ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *VendorID : Input eoc Vendor ID ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setEocVendorId(tidsl_t *ptidsl,char *VendorID) ++{ ++ DEV_HOST_oamWrNegoParaDef_t NegoPara; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5," dslhal_api_setEocVendorId()\n"); ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ ++ ++ rc = dslhal_support_blockRead((PVOID) dspOamSharedInterface.oamWriteNegoParams_p,&NegoPara, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ shim_osMoveMemory(NegoPara.gdmtVendorId,VendorID,8); ++ rc= dslhal_support_blockWrite(&NegoPara,dspOamSharedInterface.oamWriteNegoParams_p, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_EOCREG_API_FAILURE; ++ ++ dprintf(5," dslhal_api_setEocVendorId() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setEocRevisionNumber(tidsl_t *ptidsl,char *RevNum) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the eoc Revision Number ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *RevNum : Input eoc Revision Number ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setEocRevisionNumber(tidsl_t *ptidsl,char *RevNumber) ++{ ++ ++ DEV_HOST_eocVarDef_t eocVar; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ /*add for UR2 test */ ++ UINT8 selfTestResults[2]; ++ memset(selfTestResults,0x00,sizeof(selfTestResults)); ++ /* add for UR2 test */ ++ dprintf(5," dslhal_api_setEocRevisionNumber()\n"); ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.eocVar_p = (DEV_HOST_eocVarDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.eocVar_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.eocVar_p, ++ &eocVar, sizeof(DEV_HOST_eocVarDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ shim_osMoveMemory(eocVar.revNumber,RevNumber,4); ++ /* add for UR2 test */ ++ shim_osMoveMemory(eocVar.dummy,selfTestResults,2); ++ /* add for UR2 test */ ++ rc=dslhal_support_blockWrite(&eocVar,dspOamSharedInterface.eocVar_p,sizeof(DEV_HOST_eocVarDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_EOCREG_API_FAILURE; ++ dprintf(5," dslhal_api_setEocRevisionNumber Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setAturConfig(tidsl_t *ptidsl,char *ATURConfig) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the eoc ATUR Config Register ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *ATURConfig : Input eoc ATUR Config Register ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setAturConfig(tidsl_t *ptidsl,char *ATURConfig) ++{ ++ ++ DEV_HOST_eocVarDef_t eocVar; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5," dslhal_api_setAturConfig()\n"); ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.eocVar_p = (DEV_HOST_eocVarDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.eocVar_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.eocVar_p, ++ &eocVar, sizeof(DEV_HOST_eocVarDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ shim_osMoveMemory(eocVar.aturConfig,ATURConfig,30); ++ rc= dslhal_support_blockWrite(&eocVar,dspOamSharedInterface.eocVar_p,sizeof(DEV_HOST_eocVarDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_EOCREG_API_FAILURE; ++ dprintf(5," dslhal_api_setAturConfig() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setRateAdaptFlag(tidsl_t *ptidsl,unsigned int flag) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Rate Adapt Enable Flag ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int flag; //if flag = TRUE set rateadapt flag else reset it ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setRateAdaptFlag(tidsl_t *ptidsl,unsigned int flag) ++{ ++ DEV_HOST_msg_t aturMsg; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5," dslhal_api_setRateAdaptFlag()\n"); ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.aturMsg_p = (DEV_HOST_msg_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.aturMsg_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.aturMsg_p, ++ &aturMsg, sizeof(DEV_HOST_msg_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ if(flag) ++ aturMsg.rateAdapt = TRUE; ++ else ++ aturMsg.rateAdapt = FALSE; ++ ++ rc= dslhal_support_blockWrite(&aturMsg,dspOamSharedInterface.aturMsg_p,sizeof(DEV_HOST_msg_t)); ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ dprintf(5," dslhal_api_setRateAdaptFlag() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setTrellisFlag(tidsl_t *ptidsl,unsigned int flag) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Trellis Coding Enable Flag ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int flag; // if flag = TRUE, set trellis flag else reset ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setTrellisFlag(tidsl_t *ptidsl,unsigned int flag) ++{ ++ ++ DEV_HOST_msg_t aturMsg; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_oamWrNegoParaDef_t negoPara; ++ int rc; ++ dprintf(5," dslhal_api_setTrellisFlag()\n"); ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.aturMsg_p = (DEV_HOST_msg_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.aturMsg_p); ++ rc += dslhal_support_blockRead((PVOID)dspOamSharedInterface.aturMsg_p,&aturMsg, sizeof(DEV_HOST_msg_t)); ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ rc += dslhal_support_blockRead((PVOID) dspOamSharedInterface.oamWriteNegoParams_p,&negoPara, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ if(flag) ++ { ++ aturMsg.trellis = TRUE; ++ negoPara.rMsgs1[2] |= 0x02; ++ } ++ else ++ { ++ aturMsg.trellis = FALSE; ++ negoPara.rMsgs1[2] &= 0xFD; ++ } ++ rc=0; ++ rc+=dslhal_support_blockWrite(&aturMsg,dspOamSharedInterface.aturMsg_p,sizeof(DEV_HOST_msg_t)); ++ rc+= dslhal_support_blockWrite(&negoPara,dspOamSharedInterface.oamWriteNegoParams_p, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ ++ dprintf(5," dslhal_api_setTrellisFlag() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setMaxBitsPerCarrier(tidsl_t *ptidsl,unsigned int maxbits) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Maximum bits per carrier value ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int maxbits : should be a value between 0-15 ++* ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setMaxBitsPerCarrier(tidsl_t *ptidsl,unsigned int maxbits) ++{ ++ ++ DEV_HOST_msg_t aturMsg; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ ++ dprintf(5," dslhal_api_setMaxBitsPerCarrier()\n"); ++ if(maxbits>15) ++ { ++ dprintf(3,"Maximum Number of Bits per carrier cannot exceed 15!\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.aturMsg_p = (DEV_HOST_msg_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.aturMsg_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.aturMsg_p, ++ &aturMsg, sizeof(DEV_HOST_msg_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ aturMsg.maxBits = maxbits; ++ ++ rc=dslhal_support_blockWrite(&aturMsg,dspOamSharedInterface.aturMsg_p,sizeof(DEV_HOST_msg_t)); ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ dprintf(5," dslhal_api_setMaxBitsPerCarrier() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setMaxInterleaverDepth(tidsl_t *ptidsl,unsigned int maxdepth) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Maximum Interleave Depth Supported ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int maxdepth : Should be between 0 and 3 depending on intlv buffer ++* size 64-512 ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setMaxInterleaverDepth(tidsl_t *ptidsl,unsigned int maxdepth) ++{ ++ DEV_HOST_msg_t aturMsg; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ int rc; ++ dprintf(5," dslhal_api_setMaxInterleaverDepth()\n"); ++ if(maxdepth>3) ++ { ++ dprintf(3,"Invalid Value for maximum interleave depth (must be <3)\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.aturMsg_p = (DEV_HOST_msg_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.aturMsg_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.aturMsg_p, ++ &aturMsg, sizeof(DEV_HOST_msg_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ aturMsg.maxIntlvDepth = maxdepth; ++ ++ rc=dslhal_support_blockWrite(&aturMsg,dspOamSharedInterface.aturMsg_p,sizeof(DEV_HOST_msg_t)); ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ dprintf(5," dslhal_api_setMaxInterleaverDepth() Done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_acknowledgeInterrupt() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_acknowledgeInterrupt(tidsl_t * ptidsl) ++{ ++ unsigned int interruptSources=0; ++ /* Clear out the DSLSS Interrupt Registers to acknowledge Interrupt */ ++ if(DSLHAL_REG32(dslhal_support_hostDspAddressTranslate(DSP_INTERRUPT_SOURCE_REGISTER))&MASK_MAILBOX_INTERRUPTS) ++ { ++ DSLHAL_REG32(dslhal_support_hostDspAddressTranslate(DSP_INTERRUPT_CLEAR_REGISTER))|=MASK_MAILBOX_INTERRUPTS; ++ dprintf(5,"Mailbox Interrupt \n"); ++ } ++ if(DSLHAL_REG32(dslhal_support_hostDspAddressTranslate(DSP_INTERRUPT_SOURCE_REGISTER))&MASK_BITFIELD_INTERRUPTS) ++ { ++ DSLHAL_REG32(dslhal_support_hostDspAddressTranslate(DSP_INTERRUPT_CLEAR_REGISTER))|=MASK_BITFIELD_INTERRUPTS; ++ dprintf(5,"Bitfield Interrupt \n"); ++ } ++ if(DSLHAL_REG32(dslhal_support_hostDspAddressTranslate(DSP_INTERRUPT_SOURCE_REGISTER))&MASK_HEARTBEAT_INTERRUPTS) ++ { ++ DSLHAL_REG32(dslhal_support_hostDspAddressTranslate(DSP_INTERRUPT_CLEAR_REGISTER))|=MASK_HEARTBEAT_INTERRUPTS; ++ dprintf(5,"HeartBeat Interrupt \n"); ++ } ++ interruptSources = dslhal_support_parseInterruptSource(ptidsl); ++ if(interruptSources < 0) ++ return DSLHAL_ERROR_INTERRUPT_FAILURE; ++ else ++ return interruptSources; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_disableDspHybridSelect() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_disableDspHybridSelect(tidsl_t * ptidsl,unsigned int disable) ++{ ++ int rc; ++ DEV_HOST_phyPerf_t phyPerf; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.phyPerf_p = (DEV_HOST_phyPerf_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.phyPerf_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.phyPerf_p, ++ &phyPerf, sizeof(DEV_HOST_phyPerf_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ if(disable==1) ++ { ++ phyPerf.disableDspHybridSelect_f = TRUE; ++ // hybrid_selected = 888; ++ } ++ else ++ { ++ phyPerf.disableDspHybridSelect_f = FALSE; ++ // hybrid_selected = 888; ++ } ++ rc=dslhal_support_blockWrite(&phyPerf,dspOamSharedInterface.phyPerf_p,sizeof(DEV_HOST_phyPerf_t)); ++ if(rc) ++ return DSLHAL_ERROR_HYBRID_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_selectHybrid() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_selectHybrid(tidsl_t * ptidsl,unsigned int hybridNum) ++{ ++ int rc; ++ DEV_HOST_phyPerf_t phyPerf; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ if(hybridNum<1||hybridNum>4) ++ { ++ dprintf(3,"Invalid Value for Hybrid Number \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.phyPerf_p = (DEV_HOST_phyPerf_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.phyPerf_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.phyPerf_p, ++ &phyPerf, sizeof(DEV_HOST_phyPerf_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ phyPerf.hostSelectHybridNum = hybridNum; ++ rc=dslhal_support_blockWrite(&phyPerf,dspOamSharedInterface.phyPerf_p,sizeof(DEV_HOST_phyPerf_t)); ++ if(rc) ++ return DSLHAL_ERROR_HYBRID_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_reportHybridMetrics() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_reportHybridMetrics(tidsl_t * ptidsl,int *metric) ++{ ++ int rc,i; ++ DEV_HOST_phyPerf_t phyPerf; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ if(hybrid_selected>5) ++ { ++ dprintf(4,"Hybrid Metrics Not Yet Available \n"); ++ } ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return (0-DSLHAL_ERROR_INVALID_PARAM); ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return (0-DSLHAL_ERROR_BLOCK_READ); ++ } ++ ++ dspOamSharedInterface.phyPerf_p = (DEV_HOST_phyPerf_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.phyPerf_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.phyPerf_p, ++ &phyPerf, sizeof(DEV_HOST_phyPerf_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return (0-DSLHAL_ERROR_BLOCK_READ); ++ } ++ rc = sizeof(phyPerf.hybridCost); ++ for(i=0;i<(rc/4);i++) ++ { ++ metric[i] = dslhal_support_byteSwap32(phyPerf.hybridCost[i]); ++ } ++ return hybrid_selected; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_selectInnerOuterPair(tidsl_t *ptidsl,unsigned int pairSelect) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction selects inner/outer pair on RJ11. ++ * ++ * INPUT: PITIDSLHW_T *ptidsl , unsigned int pairSelect ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_selectInnerOuterPair(tidsl_t *ptidsl,unsigned int pairSelect) ++{ ++ int rc; ++ ++ dprintf(5, "dslhal_api_sendQuiet\n"); ++ rc = dslhal_support_writeHostMailbox(ptidsl, HOST_RJ11SELECT, (unsigned int)pairSelect, 0, 0); ++ if(rc) ++ { ++ dprintf(1,"dslhal_api_sendQuiet failed\n"); ++ return DSLHAL_ERROR_CTRL_API_FAILURE; ++ } ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_resetTrainFailureLog(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction resets the failed state log stored ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_resetTrainFailureLog(tidsl_t *ptidsl) ++{ ++ ++ int rc; ++ dprintf(5, "dslhal_api_resetTrainFailureLog \n"); ++ for(rc=0;rcAppData.trainFails;rc++) ++ { ++ ptidsl->AppData.trainFailStates[rc]=0; ++ } ++ ptidsl->AppData.trainFails = 0; ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_configureLed() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureLed(tidsl_t * ptidsl,unsigned int idLed, unsigned int onOff) ++{ ++ int rc; ++ DEV_HOST_modemEnvPublic_t modemEnv; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ if(idLed>2 || onOff>2) ++ { ++ dprintf(3,"Invalid input parameter \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.modemEnvPublic_p = (DEV_HOST_modemEnvPublic_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.modemEnvPublic_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.modemEnvPublic_p, ++ &modemEnv, sizeof(DEV_HOST_modemEnvPublic_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ if(idLed==ID_DSL_LINK_LED) ++ { ++ modemEnv.overrideDslLinkLed_f = TRUE; ++ if(onOff!=2) ++ modemEnv.dslLinkLedState_f = onOff; ++ } ++ if(idLed==ID_DSL_ACT_LED) ++ { ++ modemEnv.overrideDslLinkLed_f = TRUE; ++ if(onOff!=2) ++ modemEnv.dslLinkLedState_f = onOff; ++ } ++ if(idLed==ID_RESTORE_DEFAULT_LED) ++ { ++ modemEnv.overrideDslLinkLed_f = FALSE; ++ modemEnv.overrideDslActLed_f = FALSE; ++ } ++ rc=dslhal_support_blockWrite(&modemEnv,dspOamSharedInterface.modemEnvPublic_p,sizeof(DEV_HOST_modemEnvPublic_t)); ++ if(rc) ++ return DSLHAL_ERROR_MODEMENV_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_configureExternBert() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureExternBert(tidsl_t * ptidsl,unsigned int configParm, unsigned int parmVal) ++{ ++ int rc; ++ DEV_HOST_modemEnvPublic_t modemEnv; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ if(configParm>1 || parmVal>1) ++ { ++ dprintf(3,"Invalid input parameter \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.modemEnvPublic_p = (DEV_HOST_modemEnvPublic_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.modemEnvPublic_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.modemEnvPublic_p, ++ &modemEnv, sizeof(DEV_HOST_modemEnvPublic_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ if(configParm==0) ++ { ++ modemEnv.externalBert = parmVal; ++ } ++ if(configParm==1) ++ { ++ modemEnv.usBertPattern = parmVal; ++ } ++ rc=dslhal_support_blockWrite(&modemEnv,dspOamSharedInterface.modemEnvPublic_p,sizeof(DEV_HOST_modemEnvPublic_t)); ++ if(rc) ++ return DSLHAL_ERROR_MODEMENV_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_configureAtmBert() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureAtmBert(tidsl_t * ptidsl,unsigned int configParm, unsigned int parmVal) ++{ ++ int rc; ++ DEV_HOST_atmDsBert_t atmDsBert; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ if(configParm>1 || parmVal>1) ++ { ++ dprintf(3,"Invalid input parameter \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.atmDsBert_p = (DEV_HOST_atmDsBert_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.atmDsBert_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.atmDsBert_p, ++ &atmDsBert, sizeof(DEV_HOST_atmDsBert_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ if(configParm==0) ++ { ++ atmDsBert.atmBertFlag = parmVal; ++ rc=dslhal_support_blockWrite(&atmDsBert,dspOamSharedInterface.atmDsBert_p,sizeof(DEV_HOST_atmDsBert_t)); ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ } ++ if(configParm==1) ++ { ++ ptidsl->AppData.atmBertBitCountLow = atmDsBert.bitCountLow; ++ ptidsl->AppData.atmBertBitCountHigh = atmDsBert.bitCountHigh; ++ ptidsl->AppData.atmBertBitErrorCountLow = atmDsBert.bitErrorCountLow; ++ ptidsl->AppData.atmBertBitErrorCountHigh = atmDsBert.bitErrorCountHigh; ++ } ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_configureDgaspLpr() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Configures dying gasp LPR signal ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureDgaspLpr(tidsl_t * ptidsl,unsigned int configParm, unsigned int parmVal) ++{ ++ int rc; ++ DEV_HOST_modemEnvPublic_t modemEnv; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ if(configParm>1 || parmVal>1) ++ { ++ dprintf(3,"Invalid input parameter \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ ++ if(!ptidsl) ++ { ++ dprintf(3, "Error: PTIDSL pointer invalid\n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.modemEnvPublic_p = (DEV_HOST_modemEnvPublic_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.modemEnvPublic_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.modemEnvPublic_p, ++ &modemEnv, sizeof(DEV_HOST_modemEnvPublic_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ if(configParm==0) ++ { ++ modemEnv.dGaspLprIndicator_f = parmVal; ++ } ++ if(configParm==1) ++ { ++ modemEnv.overrideDspLprGasp_f = parmVal; ++ } ++ rc=dslhal_support_blockWrite(&modemEnv,dspOamSharedInterface.modemEnvPublic_p,sizeof(DEV_HOST_modemEnvPublic_t)); ++ if(rc) ++ return DSLHAL_ERROR_MODEMENV_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_genericDspRead() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads from a Generic Location in the DSP Host Interface ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_genericDspRead(tidsl_t * ptidsl,unsigned int offset1, unsigned int offset2, ++ unsigned int offset3, unsigned char *localBuffer, unsigned int numBytes) ++{ ++ int rc=0; ++ unsigned int hostIfLoc,structLoc,elementLoc; ++ hostIfLoc = (unsigned int)ptidsl->pmainAddr; ++ if(numBytes<=0 || !localBuffer || !ptidsl) ++ { ++ dprintf(3,"Invalid input parameter \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ rc += dslhal_support_blockRead((PVOID)(hostIfLoc+sizeof(int)*offset1), &structLoc,sizeof(int)); ++ structLoc = dslhal_support_byteSwap32(structLoc); ++ rc += dslhal_support_blockRead((PVOID)(structLoc+sizeof(int)*offset2), &elementLoc,sizeof(int)); ++ elementLoc = dslhal_support_byteSwap32(elementLoc); ++ dprintf(3,"Host IF Location: 0x%x Struct1 Location: 0x%x Element Location: 0x%x \n",hostIfLoc, structLoc, elementLoc); ++ rc += dslhal_support_blockRead((PVOID)(elementLoc+(offset3*4)), localBuffer,numBytes); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_genericDspWrite() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Writes to a Generic Location in the DSP Host Interface ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_genericDspWrite(tidsl_t * ptidsl,unsigned int offset1, unsigned int offset2, ++ unsigned int offset3, unsigned char *localBuffer, unsigned int numBytes) ++{ ++ ++ int rc=0; ++ unsigned int hostIfLoc,structLoc,elementLoc; ++ hostIfLoc = (unsigned int)ptidsl->pmainAddr; ++ if(numBytes<=0 || !localBuffer || !ptidsl) ++ { ++ dprintf(3,"Invalid input parameter \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ rc += dslhal_support_blockRead((PVOID)(hostIfLoc+(offset1*4)), &structLoc,4); ++ structLoc = dslhal_support_byteSwap32(structLoc); ++ rc += dslhal_support_blockRead((PVOID)(structLoc+(offset2*4)), &elementLoc,4); ++ elementLoc = dslhal_support_byteSwap32(elementLoc); ++ dprintf(3,"Host IF Location: 0x%x Struct1 Location: 0x%x Element Location: 0x%x \n",hostIfLoc, structLoc, elementLoc); ++ rc += dslhal_support_blockWrite(localBuffer,(PVOID)(elementLoc+(offset3*4)),numBytes); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_dspInterfaceRead() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads from a Generic Location in the DSP Host Interface ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_dspInterfaceRead(tidsl_t * ptidsl,unsigned int baseAddr, unsigned int numOffsets, ++ unsigned int *offsets, unsigned char *localBuffer, unsigned int numBytes) ++{ ++ int rc=0, off=0; ++ unsigned int prevAddr,currAddr; ++ prevAddr = baseAddr; ++ if(numBytes<=0 || !localBuffer || !ptidsl || !offsets) ++ { ++ dprintf(3,"Invalid input parameter \n"); ++ return DSLHAL_ERROR_INVALID_PARAM; ++ } ++ for(off=0;off ++#endif ++ ++#define NUM_PAGES 4 ++#define OAMFEATURE_AUTORETRAIN_MASK 0x00000001 ++#define OAMFEATURE_TC_SYNC_DETECT_MASK 0x00000002 ++#define OAMFEATURE_EOCAOC_INTERRUPT_MASK 0x00000004 ++#define OAMFEATURE_CONS_DISP_DISABLE_MASK 0x00000008 ++#define OAMFEATURE_GHSMSG_INTERRUPT_MASK 0x00000010 ++ ++typedef struct tagTIOIDINFO ++{ ++ unsigned int bState; /* addr->bDSPATURState */ ++ unsigned int USConRate; /* US Conection Rates */ ++ unsigned int DSConRate; /* DS Connection Rates */ ++ unsigned int USPayload; /* ennic_tx_pullup*/ ++ unsigned int DSPayload; /* ennic_indicate_receive_packet*/ ++ unsigned int FrmMode; /* addr->atur_msg.framing_mode*/ ++ unsigned int MaxFrmMode; ++ unsigned int TrainedPath; /* Status of the Modem in which trained (Fast or Interleaved Path) */ ++ unsigned int TrainedMode; /* Status of the mode in which the modem is trained (G.dmt, T1.413, etc) */ ++ ++ /* Superframe Count */ ++ unsigned int usSuperFrmCnt; /* Num of US Superframes */ ++ unsigned int dsSuperFrmCnt; /* Num of DS Superframes */ ++ ++ /* LOS & SEF Stats */ ++ unsigned int LOS_errors; /* Num of ADSL frames where loss-of-sync */ ++ unsigned int SEF_errors; /* Num of severly errored ADSL frames - LOS > MAXBADSYNC ADSL frames */ ++ unsigned int coLosErrors; /* CO LOS Defects */ ++ unsigned int coRdiErrors; /* CO RDI defects */ ++ /* CRC Stats */ ++ unsigned int usICRC_errors; /* Num of Upstream CRC errored ADSL frames on Interleaved Path */ ++ unsigned int usFCRC_errors; /* Num of Upstream CRC errored ADSL frames on Fast Path */ ++ unsigned int dsICRC_errors; /* Num of Downstream CRC errored ADSL frames on Interleaved Path */ ++ unsigned int dsFCRC_errors; /* Num of Downstream CRC errored ADSL frames on Fast Path */ ++ ++ /* FEC Stats */ ++ unsigned int usIFEC_errors; /* Num of Upstream FEC errored (corrected) ADSL frames on Interleaved Path */ ++ unsigned int usFFEC_errors; /* Num of Upstream FEC errored (corrected) ADSL frames on Fast Path */ ++ unsigned int dsIFEC_errors; /* Num of Downstream FEC errored (corrected) ADSL frames on Interleaved Path */ ++ unsigned int dsFFEC_errors; /* Num of Downstream FEC errored (corrected) ADSL frames on Fast Path */ ++ ++ /* NCD Stats */ ++ unsigned int usINCD_error; /* UpStream No Cell Delineation on Interleaved Path */ ++ unsigned int usFNCD_error; /* UpStream No Cell Delineation on Fast Path */ ++ unsigned int dsINCD_error; /* Downstream No Cell Delineation on Interleaved Path */ ++ unsigned int dsFNCD_error; /* Downstream No Cell Delineation on Fast Path */ ++ ++ /* LCD Stats */ ++ unsigned int usILCD_errors; /* UpStream Loss of Cell Delineation (within the same connection) on Interleaved Path */ ++ unsigned int usFLCD_errors; /* UpStream Loss of Cell Delineation (within the same connection) on Fast Path */ ++ unsigned int dsILCD_errors; /* Downstream Loss of Cell Delineation (within the same connection) on Interleaved Path */ ++ unsigned int dsFLCD_errors; /* Downstream Loss of Cell Delineation (within the same connection) on Fast Path */ ++ ++ /* HEC Stats */ ++ unsigned int usIHEC_errors; /* Num of Upstream HEC errored ADSL frames on Interleaved Path */ ++ unsigned int usFHEC_errors; /* Num of Upstream HEC errored ADSL frames on Fast Path */ ++ unsigned int dsIHEC_errors; /* Num of Downstream HEC errored ADSL frames on Interleaved Path */ ++ unsigned int dsFHEC_errors; /* Num of Downstream HEC errored ADSL frames on Fast Path */ ++ ++ /* Upstream ATM Stats */ ++ unsigned int usAtm_count[2]; /* Upstream Good Cell Count */ ++ unsigned int usIdle_count[2]; /* Upstream Idle Cell Count */ ++ unsigned int usPdu_count[2]; /* UpStream PDU Count */ ++ ++ /* Downstream ATM Stats */ ++ unsigned int dsGood_count[2]; /* Downstream Good Cell Count */ ++ unsigned int dsIdle_count[2]; /* Downstream Idle Cell Count */ ++ unsigned int dsBadHec_count[2]; /* Downstream Bad Hec Cell Count */ ++ unsigned int dsOVFDrop_count[2]; /* Downstream Overflow Dropped Cell Count */ ++ unsigned int dsPdu_count[2]; /* Downstream PDU Count */ ++ /* (only looks for end of pdu on good atm cells received, */ ++ /* not on Bad_Hec or Overflow cell) */ ++ ++ unsigned int dsLineAttn; /* DS Line Attenuation */ ++ unsigned int dsMargin; /* Measured DS MArgin */ ++ ++ unsigned int usLineAttn; ++ unsigned int usMargin; ++ ++ unsigned char bCMsgs1[6]; ++ unsigned char bRMsgs1[6]; ++ unsigned char bCRates2; ++ unsigned char bRRates2; ++ unsigned char bRRates1[4][11]; ++ unsigned char bCMsgs2[4]; ++ unsigned char bCRates1[4][30]; ++ unsigned char bRMsgs2[4]; ++ ++ unsigned int USPeakCellRate; ++ ++ unsigned int dsl_status; ++ unsigned int dsl_modulation; ++ unsigned char dsl_ghsRxBuf[10][64]; ++ unsigned char dsl_GHS_msg_type[2]; ++ ++ int TxVCs[12]; ++ int RxVCs[12]; ++ ++ unsigned int vci_vpi_val; ++ ++ unsigned char BitAllocTblDstrm[256]; ++ unsigned char BitAllocTblUstrm[32]; ++ signed char marginTblDstrm[256]; ++ unsigned char rBng[512]; ++ unsigned char cBng[126]; ++ int usTxPower; ++ int dsTxPower; ++ short rxSnrPerBin0[256]; ++ short rxSnrPerBin1[256]; ++ short rxSnrPerBin2[256]; ++ ++ unsigned int StdMode; ++ unsigned int atucVendorId; ++ unsigned char currentHybridNum; ++ unsigned char atucRevisionNum; ++ unsigned int trainFails; ++ unsigned int trainFailStates[30]; ++ unsigned int idleTick; ++ unsigned int initTick; ++ unsigned int showtimeTick; ++ unsigned char dsFastParityBytesPerSymbol; ++ unsigned char dsIntlvParityBytesPerSymbol; ++ unsigned char dsSymbolsPerCodeWord; ++ unsigned int dsInterleaverDepth; ++ unsigned char usFastParityBytesPerSymbol; ++ unsigned char usIntlvParityBytesPerSymbol; ++ unsigned char usSymbolsPerCodeWord; ++ unsigned int usInterleaverDepth; ++ unsigned int atmBertBitCountLow; ++ unsigned int atmBertBitCountHigh; ++ unsigned int atmBertBitErrorCountLow; ++ unsigned int atmBertBitErrorCountHigh; ++ unsigned int lineLength; ++ unsigned int grossGain; ++ int rxNoisePower0[256]; ++ int rxNoisePower1[256]; ++}TIOIDINFO,*PTIOIDINFO; ++ ++typedef struct{ ++ unsigned char bCMsgs1[6]; ++ unsigned char bCRates2; ++ unsigned char bRRates2; ++ unsigned char bRRates1[4][11]; ++ unsigned char bCMsgs2[4]; ++ unsigned char bCRates1[4][30]; ++ unsigned char bCRatesRA[4][30]; ++ unsigned char bRMsgs2[4]; ++ unsigned char bRRatesRA[4]; ++ unsigned char bRMsgsRA[12]; ++ unsigned char bCMsgsRA[6]; ++}negoMsgs; ++ ++typedef struct{ ++ unsigned char cMsgFmt[2]; ++ unsigned char rMsgFmt[2]; ++ unsigned char cMsgPcb[12]; ++ unsigned char rMsgPcb[70]; ++ unsigned char dummy1[2]; ++ unsigned char cMsg1[40]; ++ unsigned char rMsg1[4]; ++ unsigned char cMsg2[8]; ++ unsigned char rMsg2[64]; ++ unsigned char cParams[264]; ++ unsigned char rParams[2088]; ++ unsigned short cMsgPcbLen; ++ unsigned short rMsgPcbLen; ++ unsigned short cMsg1Len; ++ unsigned short rMsg1Len; ++ unsigned short cMsg2Len; ++ unsigned short rMsg2Len; ++ unsigned short cParamsLen; ++ unsigned short rParamsLen; ++}adsl2Msgs; ++ ++typedef struct{ ++ unsigned char rMsg1Ld[16]; ++ unsigned char rMsg2Ld[260]; ++ unsigned char rMsg3Ld[260]; ++ unsigned char rMsg4Ld[260]; ++ unsigned char rMsg5Ld[260]; ++ unsigned char rMsg6Ld[260]; ++ unsigned char rMsg7Ld[260]; ++ unsigned char rMsg8Ld[260]; ++ unsigned char rMsg9Ld[260]; ++ unsigned char cMsg1Ld[16]; ++ unsigned char cMsg2Ld[260]; ++ unsigned char cMsg3Ld[132]; ++ unsigned char cMsg4Ld[68]; ++ unsigned char cMsg5Ld[68]; ++ unsigned short rMsg1LdLen; ++ unsigned short rMsgxLdLen; ++ unsigned short cMsg1LdLen; ++ unsigned short cMsg2LdLen; ++ unsigned short cMsg3LdLen; ++ unsigned short cMsg4LdLen; ++ unsigned short cMsg5LdLen; ++ unsigned short dummy8; ++}adsl2DeltMsgs; ++ ++typedef struct{ ++ unsigned char trellisFlag; ++ unsigned char rateAdaptFlag; ++ unsigned char marginMonitorTraining; ++ unsigned char marginMonitorShowtime; ++ signed char marginThreshold; ++ unsigned char disableLosFlag; ++ unsigned char aturConfig[30]; ++ unsigned char eocVendorId[8]; ++ unsigned char eocSerialNumber[32]; ++ unsigned char eocRevisionNumber[4]; ++}currentPhySettings; ++ ++ ++typedef struct ++{ ++ unsigned int PmemStartWtAddr; /* source address in host memory */ ++ unsigned int OverlayXferCount; /* number of 32bit words to be transfered */ ++ unsigned int BinAddr; /* destination address in dsp's pmem */ ++ unsigned int overlayHostAddr; ++ unsigned int olayPageCrc32; ++ unsigned int SecOffset; ++} OlayDP_Def; ++ ++typedef struct ++{ ++ unsigned int timeStamp; /* TimeStp revision */ ++ unsigned char major; /* Major revision */ ++ unsigned char minor; /* Minor revision */ ++ unsigned char bugFix; /* BugFix revision */ ++ unsigned char buildNum; /* BuildNum revision */ ++ unsigned char reserved; /* for future use */ ++}dspVer; ++ ++typedef struct{ ++ unsigned char major; ++ unsigned char minor; ++ unsigned char bugfix; ++ unsigned char buildNum; ++ unsigned int timeStamp; ++}dslVer; ++ ++typedef struct{ ++ unsigned char bitSwapCommand[6]; ++ unsigned char bitSwapBinNum[6]; ++ unsigned char bitSwapSFrmCnt; ++}dslBitSwapDef; ++ ++typedef struct{ ++ unsigned int aturState; ++ unsigned int subStateIndex; ++ unsigned int timeStamp; ++}trainStateInfo; ++ ++typedef struct{ ++ unsigned char ctrlBits; ++ unsigned char infoBits; ++}eocMessageDef; ++ ++enum ++{ ++ RSTATE_TEST, ++ RSTATE_IDLE, ++ RSTATE_INIT, ++ RSTATE_HS, ++ RSTATE_RTDL, ++ RSTATE_SHOWTIME, ++}; ++ ++typedef enum ++{ ++ ATU_RZERO1 = 100, ++ ATU_RTEST = 101, ++ ATU_RIDLE = 102, ++ ATU_RINIT = 103, ++ ATU_RRESET = 104, ++ GDMT_NSFLR = 105, ++ GDMT_TONE = 106, ++ GDMT_SILENT = 107, ++ GDMT_NEGO = 108, ++ GDMT_FAIL = 109, ++ GDMT_ACKX = 110, ++ GDMT_QUIET2 = 111, ++ ATU_RZERO2 = 200, ++ T1413_NSFLR = 201, ++ T1413_ACTREQ = 202, ++ T1413_ACTMON = 203, ++ T1413_FAIL = 204, ++ T1413_ACKX = 205, ++ T1413_QUIET2 = 206, ++ ATU_RQUIET2 = 207, ++ ATU_RREVERB1 = 208, ++ ATU_RQUIET3 = 209, ++ ATU_RECT = 210, ++ ATU_RREVERB2 = 211, ++ ATU_RSEGUE1 = 212, ++ ATU_RREVERB3 = 213, ++ ATU_RSEGUE2 = 214, ++ ATU_RRATES1 = 215, ++ ATU_RMSGS1 = 216, ++ ATU_RMEDLEY = 217, ++ ATU_RREVERB4 = 218, ++ ATU_RSEGUE3 = 219, ++ ATU_RMSGSRA = 220, ++ ATU_RRATESRA = 221, ++ ATU_RREVERBRA = 222, ++ ATU_RSEGUERA = 223, ++ ATU_RMSGS2 = 224, ++ ATU_RRATES2 = 225, ++ ATU_RREVERB5 = 226, ++ ATU_RSEGUE4 = 227, ++ ATU_RBNG = 228, ++ ATU_RREVERB6 = 229, ++ ATU_RSHOWTIME = 230, ++ ATU_RZERO3 = 300, ++ ADSL2_QUIET1 = 301, ++ ADSL2_COMB1 = 302, ++ ADSL2_QUIET2 = 303, ++ ADSL2_COMB2 = 304, ++ ADSL2_ICOMB1 = 305, ++ ADSL2_LINEPROBE = 306, ++ ADSL2_QUIET3 = 307, ++ ADSL2_COMB3 = 308, ++ ADSL2_ICOMB2 = 309, ++ ADSL2_RMSGFMT = 310, ++ ADSL2_RMSGPCB = 311, ++ ADSL2_REVERB1 = 312, ++ ADSL2_QUIET4 = 313, ++ ADSL2_REVERB2 = 314, ++ ADSL2_QUIET5 = 315, ++ ADSL2_REVERB3 = 316, ++ ADSL2_ECT = 317, ++ ADSL2_REVERB4 = 318, ++ ADSL2_SEGUE1 = 319, ++ ADSL2_REVERB5 = 320, ++ ADSL2_SEGUE2 = 321, ++ ADSL2_RMSG1 = 322, ++ ADSL2_MEDLEY = 323, ++ ADSL2_EXCHANGE = 324, ++ ADSL2_RMSG2 = 325, ++ ADSL2_REVERB6 = 326, ++ ADSL2_SEGUE3 = 327, ++ ADSL2_RPARAMS = 328, ++ ADSL2_REVERB7 = 329, ++ ADSL2_SEGUE4 = 330, ++ ATU_RZERO4 = 400, ++ DELT_SEGUE1 = 401, ++ DELT_REVERB5 = 402, ++ DELT_SEGUE2 = 403, ++ DELT_EXCHANGE = 404, ++ DELT_SEGUELD = 405, ++ DELT_RMSGLD = 406, ++ DELT_QUIET1LD = 407, ++ DELT_QUIET2LD = 408, ++ DELT_RACK1 = 409, ++ DELT_RNACK1 = 410, ++ DELT_QUIETLAST = 411 ++} modemStates_t; ++ ++enum ++{ ++ DSLTRAIN_NO_MODE, ++ DSLTRAIN_MULTI_MODE, ++ DSLTRAIN_T1413_MODE, ++ DSLTRAIN_GDMT_MODE, ++ DSLTRAIN_GLITE_MODE ++}; ++ ++enum ++{ ++ ID_RESTORE_DEFAULT_LED, ++ ID_DSL_LINK_LED, ++ ID_DSL_ACT_LED ++}; ++ ++typedef struct _ITIDSLHW ++{ ++ /* struct _TIDSL_IHwVtbl * pVtbl; */ ++ unsigned char* fwimage; ++ void* pmainAddr; ++ void* pOsContext; ++ unsigned int ReferenceCount; ++ unsigned int netService; ++ ++ int InitFlag; ++ ++ int imagesize; ++ ++ unsigned int lConnected; ++ unsigned int bStatisticsInitialized; ++ unsigned int rState; ++ unsigned int bShutdown; ++ unsigned int blackOutValid_f; ++ unsigned char blackOutBits[64]; ++ unsigned int bAutoRetrain; ++ volatile unsigned int bOverlayPageLoaded; ++ unsigned int stateTransition; ++ unsigned int configFlag; ++ unsigned int dsBitSwapInx; ++ unsigned int usBitSwapInx; ++ unsigned int trainStateInx; ++ unsigned int usEocMsgInx; ++ unsigned int dsEocMsgInx; ++ unsigned int reasonForDrop; ++ TIOIDINFO AppData; ++ dspVer dspVer; ++ ++ OlayDP_Def olayDpPage[NUM_PAGES]; ++ OlayDP_Def coProfiles; ++ OlayDP_Def constDisplay; ++ dslBitSwapDef dsBitSwap[30]; ++ dslBitSwapDef usBitSwap[30]; ++ trainStateInfo trainHistory[120]; ++ eocMessageDef usEocMsgBuf[30]; ++ eocMessageDef dsEocMsgBuf[30]; ++ adsl2Msgs adsl2TrainingMessages; ++ adsl2DeltMsgs adsl2DiagnosticMessages; ++ unsigned int modemStateBitField[4]; ++#ifdef INTERNAL_BUILD ++ internalParameters internalVars; ++#endif ++} ITIDSLHW_T, *PITIDSLHW_T, tidsl_t; ++ ++ ++/********************************************************************************** ++* API proto type defines ++**********************************************************************************/ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_dslStartup ++* ++******************************************************************************************* ++* DESCRIPTION: Entry point to initialize and load ax5 daughter board ++* ++* INPUT: PITIDSLHW_T *ppIHw ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* ++* Notes: external function osAllocateMemory(), osZeroMemory(), osLoadFWImage() are required ++*****************************************************************************************/ ++int dslhal_api_dslStartup ++( ++ PITIDSLHW_T *ppIHw ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_gatherStatistics ++* ++********************************************************************************************* ++* DESCRIPTION: Read statistical infromation from ax5 modem daugter card. ++* Input: tidsl_t *ptidsl ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++ ++void dslhal_api_gatherStatistics ++( ++ tidsl_t * ptidsl ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_initStatistics ++* ++********************************************************************************************* ++* DESCRIPTION: init statistical infromation of ax5 modem daugter card. ++* ++* Input: tidsl_t *ptidsl ++* ++* Return: NULL ++* ++********************************************************************************************/ ++ ++void dslhal_api_initStatistics ++( ++ tidsl_t * ptidsl ++); ++ ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_getDslDriverVersion ++* ++******************************************************************************************* ++* DESCRIPTION: This routine supply DSL Driver version. ++* ++* INPUT: tidsl_t * ptidsl ++* void *pVer, DSP Driver Version Pointer ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* Note: See verdef_u.h for version structure definition. ++*****************************************************************************************/ ++ ++void dslhal_api_getDslHalVersion ++( ++ void *pVer ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_dslShutdown ++* ++******************************************************************************************* ++* DESCRIPTION: routine to shutdown ax5 modem and free the resource ++* ++* INPUT: tidsl_t *ptidsl ++* ++* RETURN: NULL ++* ++* Notes: external function osFreeMemory() is required. ++*****************************************************************************************/ ++ ++int dslhal_api_dslShutdown ++( ++ tidsl_t *ptidsl ++); ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_getDspVersion ++* ++******************************************************************************************* ++* DESCRIPTION: This routine supply AX5 daugther card DSP version. ++* ++* INPUT: tidsl_t * ptidsl ++* void *pVer, DSP version struct is returned starting at this pointer ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* ++*****************************************************************************************/ ++ ++int dslhal_api_getDspVersion ++( ++ tidsl_t *ptidsl, ++ void *pVer ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_digi_memTestA() ++* ++********************************************************************************************* ++* DESCRIPTION: This function does the digital tests on the DSP. It does the DSP ID test, ++* memory tests on the external and internal memories of DSP, Codec Interconnect ++* test and Interrupt Test. ++* ++* Input: Test selects the test to be performed based on the elements set of 9 element ++* array passed the the parameter. ++* ++* Return: Status of the Tests Failed ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_digi_memTestA ++( ++unsigned int* Test ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_digi_memTestB() ++* ++********************************************************************************************* ++* DESCRIPTION: This function does the digital tests on the DSP. It does the DSP ID test, ++* memory tests on the external and internal memories of DSP, Codec Interconnect ++* test and Interrupt Test. ++* ++* Input: Test selects the digital test to be performed. ++* ++* Return: Status of the Tests Failed ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_digi_memTestB ++( ++unsigned int Test, ++unsigned int *Status ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_anlg_tonesTestA() ++* ++********************************************************************************************* ++* DESCRIPTION: This function instructs the Transciever to transmit the Reverb with missing ++* tones and Medley's with missing tones. These signals are defined in ITU ++* G.992.1 ADSL Standards. ++* ++* Input: Test selects between the Reverb or Medley tests. 0 - Reverb, 1 - Medley ++* Array is a 64 element unsigned integer type array. The element of this array ++* describe which tones are to be generated by selecting the element of ++* the array to be non zero. ++* Return: NULL ++* ++********************************************************************************************/ ++ ++void dslhal_diags_anlg_tonesTestA ++( ++unsigned int Test, ++unsigned int* Array ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_anlg_tonesTestB() ++* ++********************************************************************************************* ++* DESCRIPTION: This function instructs the Transciever to transmit the Reverb with missing ++* tones and Medley's with missing tones. These signals are defined in ITU ++* G.992.1 ADSL Standards. ++* ++* Input: Test selects between the Reverb or Medley tests. 0 - Reverb, 1 - Medley ++* Array is a 64 element unsigned integer type array. The element of this array ++* describe which tones are to be generated by selecting the element of ++* the array to be non zero. ++* Return: NULL ++* ++********************************************************************************************/ ++ ++void dslhal_diags_anlg_tonesTestB ++( ++unsigned int Test, ++unsigned int Tones ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_anlg_rxNoiseTest() ++* ++********************************************************************************************* ++* DESCRIPTION: This function instructs the Transciever to transmit the Reverb with missing ++* tones and Medley's with missing tones. These signals are defined in ITU ++* G.992.1 ADSL Standards. ++* ++* Input: Test selects between the Reverb or Medley tests. 0 - Reverb, 1 - Medley ++* Tones selects the . ++* Return: NULL ++* ++********************************************************************************************/ ++ ++void dslhal_diags_anlg_rxNoiseTest ++(int agcFlag, ++short pga1, ++short pga2, ++short pga3, ++short aeq ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_anlg_ecNoiseTest() ++* ++********************************************************************************************* ++* DESCRIPTION: This function instructs the Transciever to transmit the Reverb with missing ++* tones and Medley's with missing tones. These signals are defined in ITU ++* G.992.1 ADSL Standards. ++* ++* Input: Test selects between the Reverb or Medley tests. 0 - Reverb, 1 - Medley ++* Tones selects the . ++* Return: NULL ++* ++********************************************************************************************/ ++ ++void dslhal_diags_anlg_ecNoiseTest ++(int agcFlag, ++short pga1, ++short pga2, ++short pga3, ++short aeq ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_pollTrainingStatus() ++* ++********************************************************************************************* ++* DESCRIPTION: code to decode modem status and to start modem training ++* ++* Input: tidsl_t *ptidsl ++* ++* Return: 0-? status mode training ++* -1 failed ++* ++********************************************************************************************/ ++int dslhal_api_pollTrainingStatus ++( ++ tidsl_t *ptidsl ++); ++ ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_handleTrainingInterrupt() ++* ++********************************************************************************************* ++* DESCRIPTION: Code to handle ax5 hardware interrupts ++* ++* Input: tidsl_t *ptidsl ++* int *pMsg, pointer to returned hardware messages. Each byte represent a messge ++* int *pTag, pointer to returned hardware message tags. Each byte represent a tag. ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++int dslhal_api_handleTrainingInterrupt ++( ++ tidsl_t *ptidsl, ++ int intrSource ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setEocSerialNumber(tidsl_t *ptidsl,char *SerialNumber) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the EOC Serial Number ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *SerialNumber : Input EOC Serial Number ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setEocSerialNumber ++( ++tidsl_t *ptidsl, ++char *SerialNumber ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setEocVendorId(tidsl_t *ptidsl,char *VendorID) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the EOC Serial Number ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *VendorID : EOC Vendor ID ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setEocVendorId ++( ++tidsl_t *ptidsl, ++char *VendorID ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setEocRevisionNumber(tidsl_t *ptidsl,char *RevNum) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the EOC Revision Number ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *RevNum : Input EOC Revision Number ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setEocRevisionNumber ++( ++tidsl_t *ptidsl, ++char *RevNumber ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setAturConfig(tidsl_t *ptidsl,char *ATURConfig) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction Sets the EOC ATUR Config Register ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * char *RevNum : Input EOC ATUR Config Register ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setAturConfig ++( ++tidsl_t *ptidsl, ++char *ATURConfig ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_disableLosAlarm(tidsl_t *ptidsl, unsigned int set) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction disables all the LOS alarms ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * unsigned int set // if set == TRUE : Disable LOS alarms, else enable ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * NOTES: Currently not supported in any version other than MR4 Patch release.. ++ *****************************************************************************************/ ++unsigned int dslhal_api_disableLosAlarm ++( ++tidsl_t *ptidsl, ++unsigned int ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_sendIdle(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the CMD_IDLE message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_sendIdle ++( ++tidsl_t *ptidsl ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_sendQuiet(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the CMD_QUIET message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_sendQuiet ++( ++tidsl_t *ptidsl ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_sendDgasp(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the HOST_DGASP message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_sendDgasp ++( ++tidsl_t *ptidsl ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setMarginThreshold(tidsl_t *ptidsl, int threshold) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction does sets the Margin threshold ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * int threshold ++ * ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setMarginThreshold ++( ++tidsl_t *ptidsl, ++int threshold ++); ++ ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_setMarginMonitorFlags(tidsl_t *ptidsl, unsigned int trainflag,unsigned int shwtflag) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction does sets the Margin monitoring flag ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * unsigned int trainflag ++ * unsigned int shwtflag ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_setMarginMonitorFlags ++( ++tidsl_t *ptidsl, ++unsigned int trainflag, ++unsigned int shwtflag ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setRateAdaptFlag(tidsl_t *ptidsl) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Rate Adapt Enable Flag ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int flag //if flag = TRUE set flag else reset ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setRateAdaptFlag ++( ++tidsl_t *ptidsl, ++unsigned int flag ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setTrellisFlag(tidsl_t *ptidsl, unsigned int flag) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Trellis Coding Enable Flag ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int flag //if flag = TRUE set flag else reset ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setTrellisFlag ++( ++tidsl_t *ptidsl, ++unsigned int flag ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setMaxBitsPerCarrier(tidsl_t *ptidsl,unsigned int maxbits) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Maximum bits per carrier value ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int maxbits : should be a value between 0-15 ++* ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setMaxBitsPerCarrier ++( ++tidsl_t *ptidsl, ++unsigned int maxbits ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setMaxInterleaverDepth(tidsl_t *ptidsl,unsigned int maxdepth) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the Maximum Interleave Depth Supported ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int maxdepth : Should be between 0 and 3 depending on intlv buffer ++* size 64-512 ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++unsigned int dslhal_api_setMaxInterleaverDepth ++( ++tidsl_t *ptidsl, ++unsigned int maxdepth ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_api_setTrainingMode(tidsl_t *ptidsl,unsigned int trainmode) ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction Sets the desired training mode(none/T1.413/G.dmt/G.lite) ++* ++* INPUT: PITIDSLHW_T *ptidsl ++* unsigned int trainmode :Should be between 0 and 4; 0:No Mode 1:Multimode ++* 2: T1.413, 3:G.dmt, 4: G.lite ++* RETURN: 0 SUCCESS ++* 1 FAILED ++* ++*****************************************************************************************/ ++ ++unsigned int dslhal_api_setTrainingMode ++( ++tidsl_t *ptidsl, ++unsigned int trainmode ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_dslRetrain(tidsl_t *ptidsl) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the CMD_QUIET message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_dslRetrain ++( ++tidsl_t *ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_acknowledgeInterrupt() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_acknowledgeInterrupt ++(tidsl_t * ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_disableDspHybridSelect() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_disableDspHybridSelect ++(tidsl_t * ptidsl, ++ unsigned int disable ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_disableDspHybridSelect() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_selectHybrid ++(tidsl_t * ptidsl, ++ unsigned int hybridNum ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_reportHybridMetrics() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_reportHybridMetrics ++(tidsl_t * ptidsl, ++ int *metric ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_selectInnerOuterPair(tidsl_t *ptidsl, unsigned int pairSelect) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the CMD_QUIET message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++ ++unsigned int dslhal_api_selectInnerOuterPair ++(tidsl_t *ptidsl, ++unsigned int pairSelect ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_resetTrainFailureLog(tidsl_t *ptidsl, unsigned int pairSelect) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the CMD_QUIET message to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++ ++unsigned int dslhal_api_resetTrainFailureLog ++(tidsl_t *ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_controlLed() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureLed ++(tidsl_t * ptidsl, ++unsigned int idLed, ++unsigned int onOff ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_configureExternBert() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureExternBert ++(tidsl_t * ptidsl, ++unsigned int configParm, ++unsigned int parmVal ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_configureAtmBert() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureAtmBert ++(tidsl_t * ptidsl, ++unsigned int configParm, ++unsigned int parmVal ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_configureDgaspLpr() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_configureDgaspLpr ++(tidsl_t * ptidsl, ++unsigned int configParm, ++unsigned int parmVal ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_onOffPcb() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_onOffPcb ++(tidsl_t * ptidsl, ++unsigned int onOff ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_onOffBitSwap() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Turns on / off the power cutback feature; ++* Input ++* usDs; 0 = us and 1 = ds; ++* onOff; 0 = OFF and 1 = ON ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_onOffBitSwap ++(tidsl_t * ptidsl, ++ unsigned int usDs, ++ unsigned int onOff ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_configDsTones() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Turns on / off specific tones in the downstream direction; ++* Input ++* pointer to the array specifying the tones to be turned on/off ++* ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_configDsTones ++(tidsl_t * ptidsl, ++ unsigned int *dsTones ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_getAocBitSwapBuffer() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Fetches the Tx/Rx AOC bitswap Buffer; ++* Input ++* Transmit / Receive buffer to be fetched ++* ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_getAocBitswapBuffer ++(tidsl_t * ptidsl, ++unsigned int usDs ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_readTrainingMessages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads all the training messages on demand; ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* void *msgStruct : Pointer to Message Structure ++* ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_readTrainingMessages ++(tidsl_t * ptidsl, ++void *msgPtr ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_getTrainingState() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads all the training messages on demand; ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* void *msgStruct : Pointer to training state structure ++* ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_getTrainingState ++(tidsl_t * ptidsl, ++void *statePtr ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_resetBitSwapMessageLog() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Clears the Aoc Bitswap Message Log ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* unsigned int usDs ; Upstream=0, Downstream=1 ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_resetBitSwapMessageLog ++(tidsl_t * ptidsl, ++ unsigned int usDs ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_setConstellationBinNumber() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Specifies the bin number for which constellation data should be fetched ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* unsigned int binNum : constellation bin number whose data is required ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_setConstellationBinNumber ++(tidsl_t * ptidsl, ++ unsigned int binNum ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_resetTrainStateHistory() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Clears the Training State History Log ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_resetTrainStateHistory ++(tidsl_t * ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_getSnrPerBin() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Get SNR data per bin ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_getSnrPerBin ++(tidsl_t * ptidsl, ++ unsigned int snrBufferOpt ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_logEocMessages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Logs EOC messages sent by the Modem to the CO ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* unsigned int eocLowerBytes : Lower [1-5] bits of EOC Message ++* unsigned int eocUpperBytes : Upper [6-13] bits of EOC Message ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_logEocMessages ++(tidsl_t * ptidsl, ++ unsigned int usDs, ++ unsigned int eocLowerBytes, ++ unsigned int eocUpperBytes ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_getReasonForDrop() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads the reason for dropping DSL connection; ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++ ++* ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_getReasonForDrop ++(tidsl_t * ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_ctrlMaxAvgFineGains() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Turns on / off the host control for Max Avg Fine Gains; 0 = OFF and 1 = ON ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_ctrlMaxAvgFineGains ++(tidsl_t * ptidsl, ++unsigned int onOff ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_setMaxAvgFineGain() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Set the Maximum Average Fine Gain Value ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_setMaxAvgFineGain ++(tidsl_t * ptidsl, ++ short fineGain ++); ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_readPhySettings() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads the advanced Phy layer settings on demand; ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* void *cfgStruct : Pointer to Phy Config Structure ++* ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_readPhySettings ++(tidsl_t * ptidsl, ++void *cfgPtr ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_advcfg_setBlackOutBits() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the Blackout Bits in the RMSGPCB message ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_advcfg_setBlackOutBits ++(tidsl_t * ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_genericDspRead() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads from a generic location in the host interface ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_genericDspRead ++(tidsl_t * ptidsl, ++ unsigned int offset1, ++ unsigned int offset2, ++ unsigned int offset3, ++ unsigned char* localBuffer, ++ unsigned int numBytes ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_genericDspWrite() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Writes to a generic location in the host interface ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_genericDspWrite ++(tidsl_t * ptidsl, ++ unsigned int offset1, ++ unsigned int offset2, ++ unsigned int offset3, ++ unsigned char* localBuffer, ++ unsigned int numBytes ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_dspInterfaceRead() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reads from a generic location in the host interface ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_dspInterfaceRead ++(tidsl_t * ptidsl, ++ unsigned int baseAddr, ++ unsigned int numOffsets, ++ unsigned int *offsets, ++ unsigned char* localBuffer, ++ unsigned int numBytes ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_api_dspInterfaceWrite() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Writes to a generic location in the host interface ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_api_dspInterfaceWrite ++(tidsl_t * ptidsl, ++ unsigned int baseAddr, ++ unsigned int numOffsets, ++ unsigned int *offsets, ++ unsigned char* localBuffer, ++ unsigned int numBytes ++); ++ ++/****************************************************************************************** ++ * FUNCTION NAME: dslhal_api_sendMailboxCommand(tidsl_t *ptidsl, unsigned int cmd) ++ * ++ ******************************************************************************************* ++ * DESCRIPTION: This fuction sends the passed mailbox command to the DSP ++ * ++ * INPUT: PITIDSLHW_T *ptidsl ++ * unsigned int cmd ++ * ++ * RETURN: 0 SUCCESS ++ * 1 FAILED ++ * ++ *****************************************************************************************/ ++unsigned int dslhal_api_sendMailboxCommand ++(tidsl_t *ptidsl, ++unsigned int cmd ++); ++ ++#ifdef INTERNAL_BUILD ++#include ++#endif ++ ++ ++#endif /* pairs #ifndef __DSL_APPLICATION_INTERFACE_H__ */ +diff -urN linux.old/drivers/atm/sangam_atm/dsl_hal_logtable.h linux.dev/drivers/atm/sangam_atm/dsl_hal_logtable.h +--- linux.old/drivers/atm/sangam_atm/dsl_hal_logtable.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dsl_hal_logtable.h 2005-08-23 04:46:50.097843696 +0200 +@@ -0,0 +1,259 @@ ++unsigned int log10[]= ++{ ++ 0, ++ 771, ++ 1221, ++ 1541, ++ 1789, ++ 1992, ++ 2163, ++ 2312, ++ 2443, ++ 2560, ++ 2666, ++ 2763, ++ 2852, ++ 2934, ++ 3011, ++ 3083, ++ 3150, ++ 3213, ++ 3274, ++ 3331, ++ 3385, ++ 3437, ++ 3486, ++ 3533, ++ 3579, ++ 3622, ++ 3664, ++ 3705, ++ 3744, ++ 3781, ++ 3818, ++ 3853, ++ 3887, ++ 3921, ++ 3953, ++ 3984, ++ 4015, ++ 4044, ++ 4073, ++ 4101, ++ 4129, ++ 4156, ++ 4182, ++ 4207, ++ 4232, ++ 4257, ++ 4281, ++ 4304, ++ 4327, ++ 4349, ++ 4371, ++ 4393, ++ 4414, ++ 4435, ++ 4455, ++ 4475, ++ 4495, ++ 4514, ++ 4533, ++ 4552, ++ 4570, ++ 4589, ++ 4606, ++ 4624, ++ 4641, ++ 4658, ++ 4675, ++ 4691, ++ 4707, ++ 4723, ++ 4739, ++ 4755, ++ 4770, ++ 4785, ++ 4800, ++ 4815, ++ 4829, ++ 4844, ++ 4858, ++ 4872, ++ 4886, ++ 4899, ++ 4913, ++ 4926, ++ 4939, ++ 4952, ++ 4965, ++ 4978, ++ 4990, ++ 5003, ++ 5015, ++ 5027, ++ 5039, ++ 5051, ++ 5063, ++ 5075, ++ 5086, ++ 5098, ++ 5109, ++ 5120, ++ 5131, ++ 5142, ++ 5153, ++ 5164, ++ 5174, ++ 5185, ++ 5195, ++ 5206, ++ 5216, ++ 5226, ++ 5236, ++ 5246, ++ 5256, ++ 5266, ++ 5275, ++ 5285, ++ 5295, ++ 5304, ++ 5313, ++ 5323, ++ 5332, ++ 5341, ++ 5350, ++ 5359, ++ 5368, ++ 5377, ++ 5386, ++ 5394, ++ 5403, ++ 5412, ++ 5420, ++ 5429, ++ 5437, ++ 5445, ++ 5454, ++ 5462, ++ 5470, ++ 5478, ++ 5486, ++ 5494, ++ 5502, ++ 5510, ++ 5518, ++ 5525, ++ 5533, ++ 5541, ++ 5548, ++ 5556, ++ 5563, ++ 5571, ++ 5578, ++ 5586, ++ 5593, ++ 5600, ++ 5607, ++ 5614, ++ 5622, ++ 5629, ++ 5636, ++ 5643, ++ 5649, ++ 5656, ++ 5663, ++ 5670, ++ 5677, ++ 5683, ++ 5690, ++ 5697, ++ 5703, ++ 5710, ++ 5716, ++ 5723, ++ 5729, ++ 5736, ++ 5742, ++ 5749, ++ 5755, ++ 5761, ++ 5767, ++ 5773, ++ 5780, ++ 5786, ++ 5792, ++ 5798, ++ 5804, ++ 5810, ++ 5816, ++ 5822, ++ 5828, ++ 5834, ++ 5839, ++ 5845, ++ 5851, ++ 5857, ++ 5862, ++ 5868, ++ 5874, ++ 5879, ++ 5885, ++ 5891, ++ 5896, ++ 5902, ++ 5907, ++ 5913, ++ 5918, ++ 5924, ++ 5929, ++ 5934, ++ 5940, ++ 5945, ++ 5950, ++ 5955, ++ 5961, ++ 5966, ++ 5971, ++ 5976, ++ 5981, ++ 5986, ++ 5992, ++ 5997, ++ 6002, ++ 6007, ++ 6012, ++ 6017, ++ 6022, ++ 6027, ++ 6031, ++ 6036, ++ 6041, ++ 6046, ++ 6051, ++ 6056, ++ 6060, ++ 6065, ++ 6070, ++ 6075, ++ 6079, ++ 6084, ++ 6089, ++ 6093, ++ 6098, ++ 6103, ++ 6107, ++ 6112, ++ 6116, ++ 6121, ++ 6125, ++ 6130, ++ 6134, ++ 6139, ++ 6143, ++ 6148, ++ 6152, ++ 6156, ++ 6161, ++ 6165 ++ }; +diff -urN linux.old/drivers/atm/sangam_atm/dsl_hal_register.h linux.dev/drivers/atm/sangam_atm/dsl_hal_register.h +--- linux.old/drivers/atm/sangam_atm/dsl_hal_register.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dsl_hal_register.h 2005-08-23 04:46:50.097843696 +0200 +@@ -0,0 +1,337 @@ ++#ifndef ___DSL_REGISTER_DEFINES_H___ ++#define ___DSL_REGISTER_DEFINES_H___ 1 ++ ++/******************************************************************************* ++* FILE PURPOSE: DSL HAL H/W Registers and Constant Declarations for Sangam ++* ++******************************************************************************** ++* FILE NAME: dsl_hal_register.h ++* ++* DESCRIPTION: ++* Contains DSL HAL APIs for Adam2 OS functions ++* ++* ++* (C) Copyright 2001-02, Texas Instruments, Inc. ++* History ++* Date Version Notes ++* 06Feb03 0.00.00 RamP Created ++* 21Mar03 0.00.01 RamP Changed header files for Modular ++* build framework ++* 21Mar03 0.00.02 RamP Introduced malloc size for DSP f/w ++* 07Apr03 0.00.03 RamP Implemented new error reporting scheme ++* Changed Commenting to C style only ++* 12Apr03 0.00.04 RamP Added Interrupt Mask defines ++* 14Apr03 0.00.05 RamP Renamed macros for REG8, REG16 & REG32 ++* 21Apr03 0.01.00 RamP Added Interrupt source/clear registers ++* Changed enum RSTATE_SHOWTIME to 5 ++* 24Apr03 0.01.01 RamP Moved the RSTATE enum to api.h ++* Added olay recovery error condition ++* 14May03 0.01.02 RamP Added defines for power computation ++* Added error condition for hybrids ++* 04Jun03 0.01.03 RamP Added enum for config flags, ++* Cleaned up AR5 register defines ++* Added defines for higher data rate ++* 06Jun03 0.01.04 RamP Added error & interrupt defines ++* 09Jun03 0.01.05 RamP Modified enum for current config ++* Added additional C-Rates defines ++* 18Jul03 0.01.06 RamP Modified internal build flow ++* 21Aug03 0.01.07 RamP Added constellation buffer size ++* 08Oct03 0.01.08 RamP Added us/ds Bits n gains size ++* 12Oct03 0.01.08 RamP Added ADSL2 Message sizes, lengths ++* and offsets for various formats ++* 29Oct03 0.01.09 RamP Added ADSL2 Delt offsets & sizes ++* 24Nov03 0.01.10 RamP Added bit field number, scan vector ++* 26Dec03 0.01.11 RamP Removed the oamFeature masks to api.h ++*******************************************************************************/ ++ ++#include "env_def_typedefs.h" ++#ifdef INTERNAL_BUILD ++#include "dev_host_internalinterface.h" ++#endif ++#include "dev_host_interface.h" ++#include "dsl_hal_api.h" ++ ++#define ADSLSS_BASE 0x01000000 ++#define BBIF_BASE 0x02000000 ++ ++#define ADSLSSADR (BBIF_BASE+0x0000) ++#define ADSLSSADRMASK 0xff000000 ++#define WAKEUP_DSP 0x00000001 ++ ++/* Ax7 Reset Control */ ++ ++#define RST_CNTRL_BASE 0x8611600 ++#define RST_CNTRL_PRCR (RST_CNTRL_BASE + 0x00 ) ++ ++#define RST_CNTRL_PRCR_GPIO 0x00000040 ++#define RST_CNTRL_PRCR_ADSLSS 0x00000080 ++#define RST_CNTRL_PRCR_USB 0x00000100 ++#define RST_CNTRL_PRCR_SAR 0x00000200 ++#define RST_CNTRL_PRCR_DSP 0x00800000 ++#define RST_CNTRL_PRCR_EMAC1 0x00200000 /* EMAC1 reset */ ++ ++#define RST_CNTRL_SWRCR (RST_CNTRL_BASE + 0x04 ) ++#define RST_SWRCR_SWR0 0x00000001 ++#define RST_SWRCR_SWR1 0x00000002 ++ ++#define RST_CNTRL_RSR (TNETD53XX_RST_CNTRL_BASE + 0x08 ) ++#define RST_RSR_RSCAUSE 0x00000003 /* Software Reset Caused by writing to SWR1 bit */ ++ ++ ++/* ****************************************************** ++Interrupt sources on Ax7 interrupt controller. ++The reserved sources are noted. ++********************************************************* */ ++ ++#define INTR_CNTRL_SRC_SECOND 0 ++#define INTR_CNTRL_SRC_EXTERNAL0 1 ++#define INTR_CNTRL_SRC_EXTERNAL1 2 ++/* reserved sources ... */ ++#define INTR_CNTRL_SRC_TIMER0 5 ++#define INTR_CNTRL_SRC_TIMER1 6 ++#define INTR_CNTRL_SRC_UART0 7 ++#define INTR_CNTRL_SRC_UART1 8 ++#define INTR_CNTRL_SRC_DMA0 9 ++#define INTR_CNTRL_SRC_DMA1 10 ++/* reserved sources ... */ ++#define INTR_CNTRL_SRC_SAR 15 ++/* reserved sources ... */ ++#define INTR_CNTRL_SRC_EMAC0 19 ++/* reserved sources ... */ ++#define INTR_CNTRL_SRC_VLYNQ0 21 ++#define INTR_CNTRL_SRC_CODEC_WAKE 22 ++/* reserved sources ... */ ++#define INTR_CNTRL_SRC_USB 24 ++#define INTR_CNTRL_SRC_VLYNQ1 25 ++/* reserved sources ... */ ++#define INTR_CNTRL_SRC_EMAC1 28 ++#define INTR_CNTRL_SRC_I2C 29 ++#define INTR_CNTRL_SRC_DMA2 30 ++#define INTR_CNTRL_SRC_DMA3 31 ++/* reserved sources ... */ ++#define INTR_CNTRL_SRC_VDMA_RX 37 ++#define INTR_CNTRL_SRC_VDMA_TX 38 ++#define INTR_CNTRL_SRC_ADSLSS 39 ++ ++#ifndef K0BASE ++#define K0BASE 0x80000000 ++#endif ++ ++#ifndef K1BASE ++#define K1BASE 0xA0000000 ++#endif ++ ++#ifndef PHYS_ADDR ++#define PHYS_ADDR(X) ((X) & 0X1FFFFFFF) ++#endif ++ ++#ifndef PHYS_TO_K0 ++#define PHYS_TO_K0(X) (PHYS_ADDR(X)|K0BASE) ++#endif ++ ++#ifndef PHYS_TO_K1 ++#define PHYS_TO_K1(X) (PHYS_ADDR(X)|K1BASE) ++#endif ++ ++#ifndef DSLHAL_REG8 ++#define DSLHAL_REG8( addr ) (*(volatile unsigned short *) PHYS_TO_K1(addr)) ++#endif ++ ++#ifndef DSLHAL_REG16 ++#define DSLHAL_REG16( addr ) (*(volatile unsigned short *)PHYS_TO_K1(addr)) ++#endif ++ ++#ifndef DSLHAL_REG32 ++#define DSLHAL_REG32( addr ) (*(volatile unsigned int *)PHYS_TO_K1(addr)) ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE (1==1) ++#endif ++ ++#ifndef FALSE ++#define FALSE (1==2) ++#endif ++ ++/******************************************************************************* ++* Type Defines for Library ++********************************************************************************/ ++typedef unsigned int size_t; ++ ++#define TIDSL_HW_CREATED 0x00000001 ++#define TIDSL_HW_OPENED 0x00000002 ++#define TIDSL_HW_STARTED 0x00000004 ++#define TIDSL_OS_INITIALIZED 0x00000008 ++ ++/* Data Pump CRATES Table Defines */ ++#define SIZE_OF_CRATES1_TABLE 120 ++#define CRATES1_BF_LS0 7 ++#define CRATES1_BI_LS0 17 ++#define CRATES1_BF_AS0 0 ++#define CRATES1_BI_AS0 10 ++#define CRATES1_BF_DSRS 20 ++#define CRATES1_BI_DSRS 21 ++#define CRATES1_BFI_DSS 22 ++#define CRATES1_BFI_DSI 23 ++#define CRATES1_BF_USRS 25 ++#define CRATES1_BI_USRS 26 ++#define CRATES1_BFI_USS 27 ++#define CRATES1_BFI_USI 28 ++ ++#define FAST_PATH 0 ++#define INTERLEAVED_PATH 1 ++ ++#define LINE_NOT_CONNECTED 0 ++#define LINE_CONNECTED 1 ++#define LINE_DISCONNECTED 2 ++#define LINE_NOT_TO_CONNECT 3 ++ ++#define MAXSECTIONS 125 ++ ++/***************************************************************************************** ++ * Localstructure declarations ++ * ++ ****************************************************************************************/ ++enum ++{ ++ DSLHAL_ERROR_NO_ERRORS, /* 00 */ ++ DSLHAL_ERROR_UNRESET_ADSLSS, /* 01 */ ++ DSLHAL_ERROR_RESET_ADSLSS, /* 02 */ ++ DSLHAL_ERROR_UNRESET_DSP, /* 03 */ ++ DSLHAL_ERROR_RESET_DSP, /* 04 */ ++ DSLHAL_ERROR_NO_FIRMWARE_IMAGE, /* 05 */ ++ DSLHAL_ERROR_MALLOC, /* 06 */ ++ DSLHAL_ERROR_FIRMWARE_MALLOC, /* 07 */ ++ DSLHAL_ERROR_DIAG_MALLOC, /* 08 */ ++ DSLHAL_ERROR_OVERLAY_MALLOC, /* 09 */ ++ DSLHAL_ERROR_CODE_DOWNLOAD, /* 10 */ ++ DSLHAL_ERROR_DIAGCODE_DOWNLOAD, /* 11 */ ++ DSLHAL_ERROR_BLOCK_READ, /* 12 */ ++ DSLHAL_ERROR_BLOCK_WRITE, /* 13 */ ++ DSLHAL_ERROR_MAILBOX_READ, /* 14 */ ++ DSLHAL_ERROR_MAILBOX_WRITE, /* 15 */ ++ DSLHAL_ERROR_MAILBOX_NOMAIL, /* 16 */ ++ DSLHAL_ERROR_MAILBOX_OVERFLOW, /* 17 */ ++ DSLHAL_ERROR_INVALID_PARAM, /* 18 */ ++ DSLHAL_ERROR_ADDRESS_TRANSLATE, /* 19 */ ++ DSLHAL_ERROR_FIRMWARE_CRC, /* 20 */ ++ DSLHAL_ERROR_FIRMWARE_OFFSET, /* 21 */ ++ DSLHAL_ERROR_CONFIG_API_FAILURE, /* 22 */ ++ DSLHAL_ERROR_EOCREG_API_FAILURE, /* 23 */ ++ DSLHAL_ERROR_VERSION_API_FAILURE, /* 24 */ ++ DSLHAL_ERROR_STATS_API_FAILURE, /* 25 */ ++ DSLHAL_ERROR_MARGIN_API_FAILURE, /* 26 */ ++ DSLHAL_ERROR_CTRL_API_FAILURE, /* 27 */ ++ DSLHAL_ERROR_HYBRID_API_FAILURE, /* 28 */ ++ DSLHAL_ERROR_MODEMENV_API_FAILURE, /* 29 */ ++ DSLHAL_ERROR_INTERRUPT_FAILURE, /* 30 */ ++ DSLHAL_ERROR_INTERNAL_API_FAILURE, /* 31 */ ++ DSLHAL_ERROR_DIGIDIAG_FAILURE, /* 32 */ ++ DSLHAL_ERROR_TONETEST_FAILURE, /* 33 */ ++ DSLHAL_ERROR_NOISETEST_FAILURE, /* 34 */ ++ DSLHAL_ERROR_MODEMSTATE, /* 35 */ ++ DSLHAL_ERROR_OVERLAY_CORRUPTED /* 36 */ ++}; ++ ++enum ++{ ++ CONFIG_FLAG_NOFLAG, /* 00 */ ++ CONFIG_FLAG_TRELLIS, /* 01 */ ++ CONFIG_FLAG_EC, /* 02 */ ++ CONFIG_FLAG_RS /* 03 */ ++}; ++ ++#define USE_EMIF_REV 0 ++#define USE_CVR_REV 1 ++#define TNETD53XX_MAXLOOP 10000 ++#define REVERB 0 ++#define MEDLEY 1 ++#define NONINTENSE 0 ++#define slavespace0 0xa1000000 ++ ++#define MASK_MAILBOX_INTERRUPTS 0x00000001 ++#define MASK_BITFIELD_INTERRUPTS 0x00000002 ++#define MASK_HEARTBEAT_INTERRUPTS 0x00000004 ++#define DSP_INTERRUPT_SOURCE_REGISTER 0x020007A0 ++#define DSP_INTERRUPT_CLEAR_REGISTER 0x020007A4 ++ ++#define DIGITAL_DIAG_MEMSIZE 1048576 ++#define CRC32_QUOTIENT 0x04c11db7 ++#define DSP_FIRMWARE_MALLOC_SIZE 0x7ffff ++#define DSP_CONSTELLATION_BUFFER_SIZE 1024*4 ++#define LOG43125 9303 ++#define US_NOMINAL_POWER (-38) ++#define US_BNG_LENGTH 32 ++#define DS_BNG_LENGTH 256 ++#define NUMBER_OF_BITFIELDS 4 ++#define BITFIELD_SCAN 0x80000000 ++ ++/* ADSL Message offsets from Host Interface Pointer */ ++ ++/* ADSL2 Messages Index and Length defines */ ++ ++#define CMSGFMT_INDEX 0 ++#define CMSGPCB_INDEX 1 ++#define RMSGFMT_INDEX 2 ++#define RMSGPCB_INDEX 3 ++#define RMSG1LD_INDEX 13 ++#define RMSG2LD_INDEX 14 ++#define RMSG3LD_INDEX 15 ++#define RMSG4LD_INDEX 16 ++#define RMSG5LD_INDEX 17 ++#define RMSG6LD_INDEX 18 ++#define RMSG7LD_INDEX 19 ++#define RMSG8LD_INDEX 20 ++#define RMSG9LD_INDEX 21 ++#define CMSG1LD_INDEX 22 ++#define CMSG2LD_INDEX 23 ++#define CMSG3LD_INDEX 24 ++#define CMSG4LD_INDEX 25 ++#define CMSG5LD_INDEX 26 ++#define CMSGPCB2_INDEX 28 ++#define CMSGPCB2L_INDEX 29 ++#define RMSGFMT2_INDEX 30 ++#define RMSGPCB2L_INDEX 31 ++#define CMSG1ADSL2_INDEX 32 ++#define RMSG1ADSL2_INDEX 33 ++#define CMSG2ADSL2_INDEX 34 ++#define RMSG2ADSL2_INDEX 35 ++#define CPARAMS_INDEX 36 ++#define RPARAMS_INDEX 37 ++ ++/* ADSL2 Message Sizes */ ++ ++#define CMSGFMT_SIZE 2 ++#define RMSGFMT_SIZE 2 ++#define CMSGPCB_SIZE 2 ++#define CMSGPCB2_SIZE 6 /* Annex A with Blackout */ ++#define CMSGPCB2L_SIZE 10 /* Annex B with Blackout */ ++#define RMSGPCB_SIZE 36 ++#define RMSG1LD_SIZE 16 ++#define RMSGxLD_SIZE 258 ++#define CMSG1LD_SIZE 16 ++#define CMSG2LD_SIZE 130 ++#define CMSG3LD_SIZE 66 ++#define CMSG4LD_SIZE 34 ++#define CMSG5LD_SIZE 34 ++#define CMSG1ADSL2_SIZE 24 ++#define RMSG1ADSL2_SIZE 4 ++#define CMSG2ADSL2_SIZE 4 ++#define RMSG2ADSL2_SIZE 32 ++#define CPARAMS_SIZE 136 ++#define RPARAMS_SIZE 808 ++ ++/* ADSL2 Plus Message Sizes (if Different from ADSL2) */ ++ ++#define RMSGPCB_P_SIZE 68 ++#define CMSG1ADSL2P_SIZE 40 /* With Blackout */ ++#define CPARAMS_PA_SIZE 168 ++#define RPARAMS_PA_SIZE 2088 ++#define CPARAMS_PB_SIZE 296 ++#define RPARAMS_PB_SIZE 2088 ++ ++#endif /* pairs #ifndef ___DSL_REGISTER_DEFINES_H___ */ +diff -urN linux.old/drivers/atm/sangam_atm/dsl_hal_support.c linux.dev/drivers/atm/sangam_atm/dsl_hal_support.c +--- linux.old/drivers/atm/sangam_atm/dsl_hal_support.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dsl_hal_support.c 2005-08-23 04:46:50.100843240 +0200 +@@ -0,0 +1,2788 @@ ++/******************************************************************************* ++* FILE PURPOSE: DSL Driver API functions for Sangam ++********************************************************************************* ++* FILE NAME: dsl_hal_support.c ++* ++* DESCRIPTION: ++* Contains DSL HAL APIs for Modem Control ++* ++* ++* (C) Copyright 2001-02, Texas Instruments, Inc. ++* History ++* Date Version Notes ++* 06Feb03 0.00.00 RamP Created ++* 21Mar03 0.00.01 RamP Inserted byteswap functions ++* 07Apr03 0.00.02 RamP Implemented new error reporting scheme ++* Changed Commenting to C style only ++* 12Apr03 0.00.03 RamP Added function to set Interrupt Bit ++* Masks for bitfield & Mailboxes ++* 14Apr03 0.00.04 RamP Added function to process modem state ++* bit fields; renamed REG32 macros ++* Changed interrupt bit field settings ++* 15Apr03 0.00.05 RamP Fixed exit condition on dslShutdown ++* 21Apr03 0.01.00 RamP Fixed dslShutdown function & changed ++* loop counter for overlay byteswaps ++* (Alpha) Added cache writeback for overlays ++* Added function acknowledgeInterrupt ++* 22Apr03 0.01.01 RamP Moved acknowledgeInterrupt into api ++* 24Apr03 0.01.02 RamP Added function to compare crc32 with ++* pre-computed value as a recovery ++* scheme for corrupt overlay pages ++* 28Apr03 0.01.03 RamP Fixed a parameter in crc32 fxn call ++* 05May03 0.01.04 RamP Fixed Message structure access in ++* writeHostMailbox function ++* 14May03 0.01.05 RamP Lookup to netService of dsp version ++* (alpha ++) to determine pots/isdn service ++* 21May03 0.01.06 RamP Added support for CO profiles ++* 29May03 0.01.07 RamP Added critical section tabs for block ++* read/write operations ++* Added functions to reload overlay pages ++* and CO Profiles ++* 04Jun03 0.01.08 RamP Added state transition timing counters ++* 06Jun03 0.01.09 RamP Added Interrupt source parsing function ++* Interrupt masking for heartbeat added ++* 09Jun03 0.01.10 RamP Modified modem state bit field processing ++* for structure changes in ITIDSLHW ++* fixed problem in free memory for CO prof ++* 18Jul03 0.01.11 RamP Optimized free memory for CO profiles & ++* overlay pages in the supporting APIs ++* 28Jul03 0.02.00 RamP Modified the process bitfield functn ++* for LED & Application State report ++* 21Aug03 0.03.00 RamP Added logic to allocate & communicate ++* memory for constellation buffer display ++* 29Sep03 0.03.01 RamP Added API switch calls to advcfg module ++* to abstract them from the API module ++* 12Oct03 0.03.02 RamP Added API to gather ADSL2 Messages ++* 14Oct03 0.03.03 RamP Added function to read CMsgsRA ++* 23Oct03 0.03.04 RamP Changed train history index to circular ++* buffer upon rollover ++* 29Oct03 0.03.05 RamP Added Adsl2 Delt Message Parsing ++* 12Nov03 0.03.06 RamP Fixed endianness issues with ++* Constellation Display ++* 14Nov03 0.03.07 RamP Added function to gather CRates1/RRates1 ++* before they get overwritten by CRatesRA ++* 19Nov03 0.03.08 JohnP Revised dslhal_support_aocBitSwapProcessing to ++* prevent duplicate ATU-R bitswaps going to ACT ++* 24Nov03 0.03.09 RamP Implemented detailed State Tracking through ++* Modem State bit fields for ADSL/2 ++* 12Dec03 0.03.10 RamP Tokenized advanced configuration code ++* 12Dec03 0.03.11 RamP Added state reset upon IDLE ++* 19Dec03 0.03.12 RamP Added static adsl2 byteswap function for ++* handling pointer to pointer cases ++* Changed adsl2 messages to correct pointer to ++* pointer dereferencing problems in some OS ++* 26Dec03 0.03.13 RamP Setting Current Address for Constellation ++* buffer in addition to start address ++* Added additional check to overlay page malloc ++*******************************************************************************/ ++#include "dsl_hal_register.h" ++#include "dsl_hal_support.h" ++ ++static unsigned int dslhal_support_adsl2ByteSwap32(unsigned int in32Bits); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_unresetDslSubsystem ++* ++******************************************************************************************* ++* DESCRIPTION: This function unreset Dsl Subsystem ++* ++* INPUT: None ++* ++* RETURN: 0 if Pass; 1 if Fail ++* ++*****************************************************************************************/ ++int dslhal_support_unresetDslSubsystem(void) ++{ ++ dprintf(4," dslhal_support_unresetDslSubsystem()\n"); ++ /* Put ADSLSS in to reset */ ++ DSLHAL_REG32(0xa8611a10) = 0x1; ++ shim_osClockWait(64); ++ dprintf(5,"Selected APLL Reg \n"); ++ ++ DSLHAL_REG32(0xa8610a90) = 0x4; ++ shim_osClockWait(64); ++ dprintf(5,"Enable Analog PLL \n"); ++ ++ DSLHAL_REG32(0xa8610a90) = 0x77fe; ++ shim_osClockWait(64); ++ dprintf(5,"Set PLL for DSP\n"); ++ ++ /* DSLHAL_REG32(0xa8611600) = 0x007f1bdf;*/ ++ DSLHAL_REG32(0xa8611600) |= RST_CNTRL_PRCR_ADSLSS; ++ shim_osClockWait(64); ++ dprintf(5,"Brought ADSLSS out of Reset \n"); ++ ++ DSLHAL_REG32(0xa861090c) &= ~((1<<20)|(1<<21)|(1<<22)|(1<<23)|(1<<24)|(1<<25)); ++ shim_osClockWait(64); ++ dprintf(5,"Configured GPIO 20-25 for McBSP \n"); ++ ++ /*DSLHAL_REG32(0xa8611600) |= RST_CNTRL_PRCR_ADSLSS;*/ ++ ++ ++ /* DSLHAL_REG32(0xa8611a04) = 0x00000001; ++ shim_osClockWait(64); */ ++ ++ dprintf(4," dslhal_support_unresetDslSubsystem done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_resetDslSubsystem ++* ++******************************************************************************************* ++* DESCRIPTION: This function unreset Dsl Subsystem ++* ++* INPUT: None ++* ++* RETURN: 0 if Pass; 1 if Fail ++* ++*****************************************************************************************/ ++int dslhal_support_resetDslSubsystem(void) ++{ ++ dprintf(4, "dslhal_support_resetDslSubsystem \n"); ++ /* Put ADSLSS into reset */ ++ DSLHAL_REG32(0xa8611600) &= ~RST_CNTRL_PRCR_ADSLSS; ++ shim_osClockWait(64); ++ /* DSLHAL_REG32(0xa8611a04) = 0x00000000; ++ shim_osClockWait(64); */ ++ dprintf(4, "dslhal_support_resetDslSubsystem Done \n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_unresetDsp() ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction takes ax5 daugter board out of reset. ++* ++* INPUT: None ++* ++* RETURN: 0 --successful. ++* 1 --failed ++* ++*****************************************************************************************/ ++int dslhal_support_unresetDsp(void) ++{ ++#ifdef PRE_SILICON ++ /* unsigned char value; */ ++ int rc; ++ ++ rc=dslhal_support_hostDspAddressTranslate((unsigned int)DEV_MDMA0_SRC_ADDR); ++ if(rc==DSLHAL_ERROR_ADDRESS_TRANSLATE) ++ { ++ dprintf(1, "dslhal_support_hostDspAddressTranslate failed\n"); ++ return DSLHAL_ERROR_ADDRESS_TRANSLATE; ++ } ++ dprintf(5,"MDMA SRC: %08x\n", rc); ++ DSLHAL_REG32(rc) = 0x80000001; ++ rc=dslhal_support_hostDspAddressTranslate((unsigned int)DEV_MDMA0_DST_ADDR); ++ if(rc==DSLHAL_ERROR_ADDRESS_TRANSLATE) ++ { ++ dprintf(1, "dslhal_support_hostDspAddressTranslate failed\n"); ++ return DSLHAL_ERROR_ADDRESS_TRANSLATE; ++ } ++ dprintf(5,"MDMA DST: %08x\n", rc); ++ DSLHAL_REG32(rc) = 0x02090001; ++ rc=dslhal_support_hostDspAddressTranslate((unsigned int)DEV_MDMA0_CTL_ADDR); ++ if(rc== DSLHAL_ERROR_ADDRESS_TRANSLATE) ++ { ++ dprintf(1, "dslhal_support_hostDspAddressTranslate failed\n"); ++ return DSLHAL_ERROR_ADDRESS_TRANSLATE; ++ } ++ dprintf(5,"MDMA CTL: %08x\n", rc); ++ DSLHAL_REG32(rc) = (DEV_MDMA_START | DEV_MDMA_DST_INC | DEV_MDMA_SRC_INC | ++ DEV_MDMA_BURST1 | (1 << DEV_MDMA_LEN_SHF)); ++ /* statusMask = 0x00000010;*/ ++#else ++ dprintf(4, "dslhal_support_unresetDsp()\n"); ++ ++ /* Bring the DSP core out of reset */ ++ /* DSLHAL_REG32(0xa8611600) = 0x00ff1bdf; */ ++ DSLHAL_REG32(0xa8611600) |= RST_CNTRL_PRCR_DSP; ++ shim_osClockWait(64); ++ dprintf(5,"Brought DSP out of Reset \n"); ++ dprintf(6,"Current Contents of PRCR: 0x%x\n",(unsigned int)DSLHAL_REG32(0xa8611600)); ++ /* DSLHAL_REG32(0xa8611a0c) = 0x00000007; ++ shim_osClockWait(64); */ ++#endif ++ ++ dprintf(4, "dslhal_support_unresetDsp() done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_resetDsp() ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction takes ax5 daugter board into reset. ++* ++* INPUT: None ++* ++* RETURN: 0 --successful. ++* 1 --failed ++* ++*****************************************************************************************/ ++int dslhal_support_resetDsp(void) ++{ ++ dprintf(4, "dslhal_support_resetDsp \n"); ++ /* Put ADSLSS into reset */ ++ DSLHAL_REG32(0xa8611600) &= ~RST_CNTRL_PRCR_DSP; ++ shim_osClockWait(64); ++ dprintf(4, "dslhal_support_resetDsp Done \n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_hostDspAddressTranslate() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Maps ax5 daugter card dsp memory address to avalanche memory space ++* ++* Input: unsigned int addr, dsp memory address. ++* ++* Return: >=0, unsigned int, mapped Avalanche address(VBUS address). ++* -1, mapping failed ++* ++* ++********************************************************************************************/ ++/* static unsigned int bbifmap0,bbifmap1; */ ++ ++unsigned int dslhal_support_hostDspAddressTranslate( unsigned int addr ) ++{ ++ unsigned int addrMap; ++ /* This function should just be used to move the memory window of the ADSLSS */ ++ dprintf(5, "dslhal_support_hostDspAddressTranslate()\n"); ++ ++ /* select vbus to xbus memory */ ++ /* addrMap = addr & 0xff000000; */ ++ addrMap = addr & ADSLSSADRMASK; ++ ++ DSLHAL_REG32(ADSLSSADR) = addrMap; ++ ++ dprintf(6, "dslhal_support_hostDspAddressTranslate() done\n"); ++#ifdef PRE_SILICON ++ return ((ADSLSS_BASE | (~ADSLSSADRMASK & addr))+ 0x00000100); ++ /* Added 0x100 for Pre-Silicon VLNQ offset.. to be removed for Silicon */ ++#else ++ return ((ADSLSS_BASE | (~ADSLSSADRMASK & addr))); ++ /* Added 0x100 for Pre-Silicon VLNQ offset.. to be removed for Silicon */ ++#endif ++ ++} ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_blockWrite ++* ++******************************************************************************************* ++* DESCRIPTION: This rouin simulates DSP memory write as done in ax5 pci nic card ++* ++* INPUT: void *buffer, data need to written ++* void *adde, memory address to be written ++* size_t count, number of bytes to be written ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* ++*****************************************************************************************/ ++ ++int dslhal_support_blockWrite(void *buffer, void *addr, size_t count) ++{ ++ int rc, byteCnt=0; ++ unsigned char* ptr; ++ union ++ { ++ unsigned char *cptr; ++ short *sptr; ++ int *iptr; ++ } src; ++ union ++ { ++ int anint; /* DSP location */ ++ unsigned char *cptr; /* to avoid casts */ ++ } dst; ++ union ++ { ++ unsigned int anint; ++ unsigned char byte[4]; ++ }data,dword,sword; ++ ++ /* Enter Critical Section */ ++ shim_osCriticalEnter(); ++ ++ dprintf(6, "dslhal_support_blockWrite\n"); ++ ++ dprintf(6,"addr=0x%X, length=0x%X, buffer=0x%X\n", (unsigned int) addr, (unsigned int) count, (unsigned int)buffer); ++ ++ src.cptr = (unsigned char*) buffer; /* local buffer */ ++ dst.cptr = addr; /* DSP memory location */ ++ ++ /*Maps address first*/ ++ rc=dslhal_support_hostDspAddressTranslate((unsigned int)addr); ++ dprintf(5, "NewAddr: %08x\n", rc); ++ if(rc== DSLHAL_ERROR_ADDRESS_TRANSLATE) ++ { ++ dprintf(1, "dslhal_support_hostDspAddressTranslate failed\n"); ++ return DSLHAL_ERROR_ADDRESS_TRANSLATE; ++ } ++ ++ dst.cptr=(unsigned char *)rc; ++ ++ /* check wether address is at 32bits boundary */ ++ ++ if ((dst.anint & 0x3) && count) ++ { ++ sword.anint = *(unsigned int*)((unsigned int)src.cptr & 0xfffffffc); ++ dword.anint = DSLHAL_REG32((unsigned int)dst.cptr & 0xfffffffc); ++ sword.anint = (unsigned int) dslhal_support_byteSwap32(sword.anint); ++ dword.anint = (unsigned int) dslhal_support_byteSwap32(dword.anint); ++ ptr = (unsigned char *)((unsigned int)dst.cptr & 0xfffffffc); ++ ++ if((dst.anint & 3) ==3) /* last byte of a dword */ ++ { ++ dword.byte[3] = sword.byte[3]; ++ dst.anint++; /* bump the address by one */ ++ byteCnt++; ++ count--; ++ } ++ ++ if((dst.anint & 3) ==1) /* second byte */ ++ { ++ if(count>3) ++ { ++ dword.byte[3] = sword.byte[3]; ++ dst.anint++; ++ count--; ++ byteCnt++; ++ } ++ if(count>2) ++ { ++ dword.byte[2] = sword.byte[2]; ++ dst.anint++; ++ count--; ++ byteCnt++; ++ } ++ if(count) ++ { ++ dword.byte[1] = sword.byte[1]; ++ dst.anint++; ++ count--; ++ byteCnt++; ++ } ++ } ++ ++ if((dst.anint & 3) && (count >1)) ++ { ++ dword.byte[2] = sword.byte[2]; ++ dword.byte[3] = sword.byte[3]; ++ byteCnt+=2; ++ dst.anint += 2; /* bump the address by two */ ++ count -= 2; /* decrement the byte count by two */ ++ } ++ ++ if((dst.anint & 3) && (count==1)) ++ { ++ dword.byte[2] = sword.byte[2]; ++ dst.anint++; ++ byteCnt++; ++ count--; ++ } ++ src.cptr = (char *)((unsigned int)src.cptr & 0xfffffffc); /* fix 032802 */ ++ dword.anint = dslhal_support_byteSwap32(dword.anint); ++ DSLHAL_REG32((unsigned int)ptr) = dword.anint; ++ ptr = src.cptr; ++ for(rc=0;rc 3) ++ { ++ DSLHAL_REG32((unsigned int)dst.cptr) = dslhal_support_byteSwap32(*src.iptr); ++ src.iptr++; /* bump the data pointer by four */ ++ dst.anint += 4; /* bump the address by four */ ++ count -= 4; /* decrement the byte count by four */ ++ } ++ ++ /* write remaining bytes */ ++ if(count) ++ { ++ int i; ++ ++ data.anint= DSLHAL_REG32((unsigned int)dst.cptr); ++ data.anint=dslhal_support_byteSwap32(data.anint); ++ for (i=0; i< count; i++) ++ { ++ data.byte[i]=*(src.cptr+i); ++ } ++ data.anint=dslhal_support_byteSwap32(data.anint); ++ DSLHAL_REG32((unsigned int)dst.cptr) = data.anint; ++ src.cptr +=count; ++ dst.anint +=count; ++ count=0; ++ } ++ dprintf(6, "dslhal_support_blockWrite done\n"); ++ /* Exit Critical Section */ ++ shim_osCriticalExit(); ++ return DSLHAL_ERROR_NO_ERRORS; ++} /* end of dslhal_support_blockWrite() */ ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_blockRead ++* ++********************************************************************************************* ++* DESCRIPTION: This rouin simulates DSP memory read as done in ax5 pci nic card ++* ++* INPUT: void *addr, memory address to be read ++* void *buffer, dat buffer to be filled with from memmory ++* size_t count, number of bytes to be written ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* ++*****************************************************************************************/ ++ ++int dslhal_support_blockRead(void *addr, void *buffer, size_t count) ++{ ++ int rc; ++ union ++ { ++ int anint; /* DSP location */ ++ char *cptr; /* to avoid casts */ ++ } src; ++ union ++ { ++ char byte[4]; ++ int anint; /* DSP data */ ++ } data; ++ union ++ { ++ char *cptr; ++ int *iptr; ++ } dst; ++ ++ /* Enter Critical Section */ ++ shim_osCriticalEnter(); ++ ++ dprintf(6,"dslhal_support_blockRead\n"); ++ ++ ++ src.cptr = addr; /* DSP memory location */ ++ dst.cptr = buffer; /* local buffer */ ++ ++ dprintf(6, "Read addr=0x%X, size=0x%X\n", (unsigned int)addr, count); ++ ++ ++ /*Maps address first*/ ++ rc=dslhal_support_hostDspAddressTranslate((unsigned int)addr); ++ if(rc== DSLHAL_ERROR_ADDRESS_TRANSLATE) ++ { ++ dprintf(1, "dslhal_support_hostDspAddressTranslate failed\n"); ++ return DSLHAL_ERROR_ADDRESS_TRANSLATE; ++ } ++ ++ src.cptr=(unsigned char *)rc; ++ ++ /********************************************** ++ * if the source is NOT on a 32-bit boundary * ++ * then we read the full word * ++ * and ignore the first part of it * ++ **********************************************/ ++ ++ if ((src.anint & 3) && count) ++ { ++ unsigned int anword; ++ ++ anword = DSLHAL_REG32((unsigned int)src.cptr & 0xfffffffc); ++ data.anint = dslhal_support_byteSwap32(anword); ++ ++ /************************************ ++ * there is no need for case 0 * ++ * notice that there are no breaks * ++ * each falls through to the next * ++ ************************************/ ++ ++ switch (src.anint & 3) ++ { ++ case 1: ++ /* use only byte[1-3] */ ++ *(dst.cptr++) = data.byte[1]; ++ src.anint++; ++ count--; ++ case 2: ++ /* use byte[2-3] */ ++ if (count) ++ { ++ *(dst.cptr++) = data.byte[2]; ++ src.anint++; ++ count--; ++ } ++ case 3: ++ /* use byte[3] */ ++ if (count) ++ { ++ *(dst.cptr++) = data.byte[3]; ++ src.anint++; ++ count--; ++ } ++ } ++ } ++ ++ /* the src pointer should now be on a 32-bit boundary */ ++ while (count > 3) ++ { ++ unsigned int anword; ++ ++ anword=DSLHAL_REG32((unsigned int)src.cptr); ++ ++ *dst.iptr = dslhal_support_byteSwap32(anword); ++ src.anint += 4; /* bump the address by four */ ++ dst.iptr++; /* bump the data pointer by four */ ++ count -= 4; /* decrement the byte count by four */ ++ } ++ ++ /******************************* ++ * if there's any count left * ++ * then we read the next word * ++ * and ignore the end of it * ++ *******************************/ ++ if (count) ++ { ++ unsigned int anword; ++ ++ anword= DSLHAL_REG32((unsigned int)src.cptr); ++ data.anint = dslhal_support_byteSwap32(anword); ++ ++ /************************************ ++ * there is no need for case 0 * ++ * notice that there are no breaks * ++ * each falls through to the next * ++ ************************************/ ++ switch (count) ++ { ++ case 1: ++ /* use byte[0] */ ++ *(dst.cptr++) = data.byte[0]; ++ src.anint++; ++ count--; ++ break; ++ case 2: ++ /* use byte[0-1] */ ++ *(dst.cptr++) = data.byte[0]; ++ *(dst.cptr++) = data.byte[1]; ++ src.anint +=2; ++ count -= 2; ++ break; ++ case 3: ++ /* use only byte[0-2] */ ++ *(dst.cptr++) = data.byte[0]; ++ *(dst.cptr++) = data.byte[1]; ++ *(dst.cptr++) = data.byte[2]; ++ src.anint +=3; ++ count -= 3; ++ break; ++ } ++ } ++ /* Exit Critical Section */ ++ shim_osCriticalExit(); ++ ++ return DSLHAL_ERROR_NO_ERRORS; ++ ++} /* end of dslhal_support_blockRead() */ ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_readDspMailbox ++* ++********************************************************************************************* ++* DESCRIPTION: Reads a message from the mailbox ++* ++* ARGUMENTS: int *pcmd Pointer to command read ++* ++* RETURNS: 0 if successful ++* 1 if no mail ++* NZ otherwise ++* ++*****************************************************************************************/ ++ ++int dslhal_support_readDspMailbox(tidsl_t *ptidsl, int *pcmd, int *ptag, int *pprm1, int *pprm2) ++{ ++ int rc; ++ int cmd; ++ int tag; ++ int prm1; ++ int prm2; ++ unsigned char dspOutInx; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_mailboxControl_t mailboxControl; ++ DEV_HOST_dspHostMsg_t dspMailboxMsg[DEV_HOST_DSPQUEUE_LENGTH]; ++ ++ dprintf(6,"dslhal_support_readDspMailbox\n"); ++ ++ /* get the DSP main pointer */ ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ /* Read in the command/response buffer */ ++ dspOamSharedInterface.dspHostMailboxControl_p = (DEV_HOST_mailboxControl_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspHostMailboxControl_p); ++ ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspHostMailboxControl_p, ++ &mailboxControl, sizeof(DEV_HOST_mailboxControl_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ /* Change the endianness of the Mailbox Pointer */ ++ mailboxControl.dspMsgBuf_p = (DEV_HOST_dspHostMsg_t *) dslhal_support_byteSwap32((unsigned int)mailboxControl.dspMsgBuf_p); ++ ++ rc = dslhal_support_blockRead((PVOID)mailboxControl.dspMsgBuf_p, ++ &dspMailboxMsg, (sizeof(DEV_HOST_dspHostMsg_t)*DEV_HOST_DSPQUEUE_LENGTH)); ++ ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ /* Extract the command/response message index */ ++ mailboxControl.hostInInx &= 7; ++ mailboxControl.hostOutInx &= 7; ++ mailboxControl.dspOutInx &= 7; ++ mailboxControl.dspInInx &= 7; ++ ++ ++ /* check for messages in the mailbox */ ++ ++ if (mailboxControl.dspOutInx == mailboxControl.dspInInx) ++ { ++ return DSLHAL_ERROR_MAILBOX_NOMAIL; ++ /* no messages to read */ ++ } ++ ++ /* use bDRESPOutInx as index to DRESPMsgBuf */ ++ ++ cmd = dspMailboxMsg[mailboxControl.dspOutInx].cmd; ++ tag = dspMailboxMsg[mailboxControl.dspOutInx].tag; ++ prm1= dspMailboxMsg[mailboxControl.dspOutInx].param1; ++ prm2= dspMailboxMsg[mailboxControl.dspOutInx].param2; ++ ++ mailboxControl.dspOutInx++; /* increment count */ ++ mailboxControl.dspOutInx &= 7; /* only two bits */ ++ ++ dspOutInx = mailboxControl.dspOutInx; ++ ++ /* Read in the command response buffer again to take care of changes */ ++ mailboxControl.dspOutInx = dspOutInx; ++ rc = dslhal_support_blockWrite(&mailboxControl.dspOutInx, ++ &dspOamSharedInterface.dspHostMailboxControl_p->dspOutInx, sizeof(BYTE)); ++ ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ ++ /* Is the input parameter address non-zero*/ ++ ++ if (pcmd) ++ { ++ *pcmd = cmd; ++ } ++ if (ptag) ++ { ++ *ptag = tag; ++ } ++ if (pprm1) ++ { ++ *pprm1 = prm1; ++ } ++ if (pprm2) ++ { ++ *pprm2 = prm2; ++ } ++ ++ dprintf(6,"dslhal_support_readDspMailbox done\n"); ++ dprintf(6,"cmd=%d, tag=%d\n", cmd, tag); ++ dprintf(6,"dslhal_support_readDspMailbox:cmd: 0x%x, tag=%d\n", cmd, tag); ++ return DSLHAL_ERROR_NO_ERRORS; ++ ++} /* end of dslhal_support_readDspMailbox() */ ++ ++/******************************************************************************************* ++* FUNCTION NAME: dslhal_support_writeHostMailbox ++* ++******************************************************************************************** ++* DESCRIPTION: Send a message to a mailbox ++* ++* ARGUMENTS: int cmd command to write ++* int tag tag (currently unused) ++* int p1 parameter 1 (currently unused) ++* int p2 parameter 2 (currently unused) ++* ++* RETURNS: 0 if successful ++* NZ otherwise ++* ++*******************************************************************************************/ ++ ++int dslhal_support_writeHostMailbox(tidsl_t *ptidsl, int cmd, int tag, int p1, int p2) ++{ ++ int rc; ++ int index; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_mailboxControl_t mailboxControl; ++ DEV_HOST_dspHostMsg_t hostMailboxMsg[DEV_HOST_HOSTQUEUE_LENGTH]; ++ unsigned char hostInInx; ++ ++ dprintf(6,"dslhal_support_writeHostMailbox:cmd: 0x%x, tag=%d\n", cmd, tag); ++ ++ dprintf(6,"cmd=%d, tag=%d\n", cmd, tag); ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ /* Read in the command/response buffer */ ++ dspOamSharedInterface.dspHostMailboxControl_p = (DEV_HOST_mailboxControl_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspHostMailboxControl_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspHostMailboxControl_p, ++ &mailboxControl, sizeof(DEV_HOST_mailboxControl_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ /* Change the endianness of the Mailbox Control Pointer */ ++ mailboxControl.hostMsgBuf_p = (DEV_HOST_dspHostMsg_t *) dslhal_support_byteSwap32((unsigned int)mailboxControl.hostMsgBuf_p); ++ rc = dslhal_support_blockRead((PVOID)mailboxControl.hostMsgBuf_p, ++ &hostMailboxMsg, (sizeof(DEV_HOST_dspHostMsg_t)*DEV_HOST_HOSTQUEUE_LENGTH)); ++ ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ /* Extract the command/response message index */ ++ mailboxControl.hostInInx &= 7; ++ mailboxControl.hostOutInx &= 7; ++ mailboxControl.dspOutInx &= 7; ++ mailboxControl.dspInInx &= 7; ++ ++ /* make sure there's room in the mailbox */ ++ ++ index = mailboxControl.hostInInx; ++ mailboxControl.hostInInx++; ++ mailboxControl.hostInInx &= 7; ++ hostInInx = mailboxControl.hostInInx; ++ if (mailboxControl.hostInInx == mailboxControl.hostOutInx) ++ { ++ /* mailbox is full */ ++ return DSLHAL_ERROR_MAILBOX_OVERFLOW; ++ } ++ ++ /* use bOCMDInInx as index to OCMDMsgBuf */ ++ hostMailboxMsg[index].cmd = (BYTE) cmd; ++ hostMailboxMsg[index].tag = (BYTE) tag; ++ hostMailboxMsg[index].param1 = (BYTE) p1; ++ hostMailboxMsg[index].param2 = (BYTE) p2; ++ rc = dslhal_support_blockWrite(&hostMailboxMsg, ++ (PVOID)mailboxControl.hostMsgBuf_p, ++ sizeof(DEV_HOST_dspHostMsg_t)*DEV_HOST_HOSTQUEUE_LENGTH); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockWrite failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ rc = dslhal_support_blockWrite(&mailboxControl, ++ &dspOamSharedInterface.dspHostMailboxControl_p, ++ sizeof(DEV_HOST_mailboxControl_t)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ /* update the index */ ++ mailboxControl.hostInInx = hostInInx; ++ rc = dslhal_support_blockWrite(&mailboxControl.hostInInx, ++ &dspOamSharedInterface.dspHostMailboxControl_p->hostInInx, ++ sizeof(BYTE)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ ++ dprintf(6,"dslhal_support_writeHostMailbox done\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++ ++} ++/* end of dslhal_support_writeHostMailbox() */ ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_readTextMailbox ++* ++********************************************************************************************* ++* DESCRIPTION: Reads a message from the mailbox ++* ++* ARGUMENTS: int *pcmd Pointer to command read ++* ++* RETURNS: 0 if successful ++* 1 if no mail ++* NZ otherwise ++* ++*****************************************************************************************/ ++ ++int dslhal_support_readTextMailbox(tidsl_t *ptidsl, int *pmsg1, int *pmsg2) ++{ ++ int rc; ++ unsigned int msg1; ++ unsigned int msg2; ++ unsigned char textOutInx; ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_mailboxControl_t mailboxControl; ++ DEV_HOST_textMsg_t textMailboxMsg[DEV_HOST_TEXTQUEUE_LENGTH]; ++ ++ dprintf(6,"dslhal_support_readTextMailbox\n"); ++ ++ /* get the DSP main pointer */ ++ ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterfacePtr_t) ptidsl->pmainAddr; ++ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ /* Read in the command/response buffer */ ++ dspOamSharedInterface.dspHostMailboxControl_p = (DEV_HOST_mailboxControl_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspHostMailboxControl_p); ++ ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspHostMailboxControl_p, ++ &mailboxControl, sizeof(DEV_HOST_mailboxControl_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ /* Change the endianness of the Mailbox Pointer */ ++ mailboxControl.textMsgBuf_p = (DEV_HOST_textMsg_t *) dslhal_support_byteSwap32((unsigned int)mailboxControl.textMsgBuf_p); ++ ++ rc = dslhal_support_blockRead((PVOID)mailboxControl.textMsgBuf_p, ++ &textMailboxMsg, (sizeof(DEV_HOST_textMsg_t)*DEV_HOST_DSPQUEUE_LENGTH)); ++ ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ /* Extract the command/response message index */ ++ ++ mailboxControl.textInInx &= 7; ++ mailboxControl.textOutInx &= 7; ++ ++ /* check for messages in the mailbox */ ++ ++ if (mailboxControl.textOutInx == mailboxControl.textInInx) ++ { ++ return DSLHAL_ERROR_MAILBOX_NOMAIL; ++ /* no messages to read */ ++ } ++ ++ /* use bDRESPOutInx as index to DRESPMsgBuf */ ++ ++ msg1 = textMailboxMsg[mailboxControl.textOutInx].msgPart1; ++ msg2 = textMailboxMsg[mailboxControl.textOutInx].msgPart2; ++ msg1 = (unsigned int) dslhal_support_byteSwap32((unsigned int)msg1); ++ msg2 = (unsigned int) dslhal_support_byteSwap32((unsigned int)msg2); ++ ++ mailboxControl.textOutInx++; /* increment count */ ++ mailboxControl.textOutInx &= 7; /* only two bits */ ++ ++ textOutInx = mailboxControl.textOutInx; ++ ++ /* Read in the command response buffer again to take care of changes */ ++ ++ mailboxControl.textOutInx = textOutInx; ++ ++ rc = dslhal_support_blockWrite(&mailboxControl.textOutInx, ++ &dspOamSharedInterface.dspHostMailboxControl_p->textOutInx, sizeof(BYTE)); ++ ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ ++ /* Is the input parameter address non-zero*/ ++ ++ if (pmsg1) ++ { ++ *pmsg1 = msg1; ++ } ++ if (pmsg2) ++ { ++ *pmsg2 = msg2; ++ } ++ ++ dprintf(6,"dslhal_support_readTextMailbox done\n"); ++ dprintf(6,"msgPart1=%d, msgPart2=%d\n", msg1, msg2); ++ dprintf(6,"dslhal_support_readTextMailbox:Message Part1: 0x%x, tag=0x%x\n", msg1, msg2); ++ return DSLHAL_ERROR_NO_ERRORS; ++ ++} /* end of dslhal_support_readTextMailbox() */ ++ ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_hostDspCodeDownload() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* download DSP image from host memory to dsp memory ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++int dslhal_support_hostDspCodeDownload(tidsl_t * ptidsl) ++{ ++ ++ unsigned int index; ++ int rc = 0, i; ++ unsigned char *iptr; /* image pointer */ ++ unsigned int numbytes,olayXfer,olayStore; ++ /* unsigned int holdSecPhyAddr=0,holdSecVirtAddr; */ ++ unsigned int *olayStart; ++ size_t len; /* size of the file */ ++ size_t expoffset; /* expected offset for next section header */ ++ unsigned short checksum; ++ unsigned int crc32; ++ unsigned char * image; ++ char *tmp = (char *)DEV_HOST_DSP_OAM_POINTER_LOCATION; ++ DEV_HOST_dspVersionDef_t dspVersion; ++#if SWTC ++ DEV_HOST_tcHostCommDef_t TCHostCommDef; ++#endif ++ DEV_HOST_oamWrNegoParaDef_t OamWrNegoParaDef; ++ DEV_HOST_dspOamSharedInterface_t dspOamSharedInterface, *pdspOamSharedInterface; ++ DEV_HOST_olayDpDef_t olayDpParms; ++ DEV_HOST_profileBase_t profileList; ++#ifndef NO_ACT ++ DEV_HOST_consBufDef_t constDisp; ++#endif ++#if CO_PROFILES ++ DEV_HOST_coData_t coData; ++#endif ++ DEV_HOST_olayDpPageDef_t olayDpPageDef[NUM_PAGES]; ++ union ++ { ++ char byte[4]; ++ unsigned short hword[2]; ++ unsigned int aword; ++ } data; ++ ++ struct _header ++ { ++ char signature[6]; ++ unsigned short sectcount; ++ unsigned int length; ++ } header; ++ ++ struct _section ++ { ++ unsigned int addr; ++ unsigned int length; ++ unsigned int offset; ++ unsigned int page; ++ };/* section[MAXSECTIONS]; */ ++ ++ struct _section *sptr; ++ unsigned int secAddr, secLength, secOffset, secPage; ++ ++ ++ dprintf(5,"dslhal_support_hostDspCodeDownload\n"); ++ image = ptidsl->fwimage; ++ ++ if (!image) ++ { ++ dprintf(1,"no image file\n"); ++ return DSLHAL_ERROR_NO_FIRMWARE_IMAGE; ++ } ++ ++ iptr=image; ++ ++ numbytes = sizeof(header); ++ ++ shim_osMoveMemory((char *) &header, (char *)iptr, numbytes); ++ header.length = dslhal_support_byteSwap32(header.length); ++ header.sectcount = dslhal_support_byteSwap16(header.sectcount); ++#if 0 ++ crc32 = dslhal_support_computeCrc32((unsigned char*)&crcTest[0],20); ++ dprintf(6,"CRC-32 for the crcTest: 0x%x",crc32); ++ dprintf(4,"header.length=%d, header.sectcount=0x%X\n", header.length, header.sectcount); ++#endif ++ /* point to the checksum */ ++ /* compute the checksum on CRC32 here */ ++ iptr = image + header.length-4; ++ numbytes = sizeof(data.aword); ++ ++ dprintf(5,"tiload: check checksum\n"); ++ shim_osMoveMemory((char *)&(data.byte), (char *)iptr, numbytes); ++ ++ crc32 = dslhal_support_computeCrc32(image,ptidsl->imagesize); ++ dprintf(5,"CRC-32 for the Binary: 0x%x",crc32); ++ /* CRC currently not added to the DSP binary, so this code is commented out */ ++ /* ++ data.aword = dslhal_support_byteSwap32(data.aword); ++ if (data.aword != crc32) ++ { ++ dprintf(1,"Checksum error\n"); ++ } ++ */ ++ /* Verify signature - Changed from "320C6x" to "TIDSL" for load 80 */ ++ ++ header.signature[5]='\0'; ++ dprintf(5, "signature=%s\n", header.signature); ++ ++ if (shim_osStringCmp(header.signature, "TIDSL")) ++ { ++ dprintf(1,"Signature not match\n"); ++ return DSLHAL_ERROR_FIRMWARE_OFFSET; ++ } ++ ++ dprintf(5,"tiload: check sect count\n"); ++ /* check section count */ ++ ++ if (header.sectcount > MAXSECTIONS) ++ { ++ dprintf(1,"Section # %d exceeds max %d\n", header.sectcount, MAXSECTIONS); ++ return DSLHAL_ERROR_FIRMWARE_OFFSET; ++ } ++ else ++ { ++ dprintf(5,"found %d sections\n", header.sectcount); ++ } ++ ++ /* Validation of Section offsets */ ++ ++ /* point to the first section */ ++ len = header.length; /* file size in bytes */ ++ expoffset = sizeof(struct _header) + header.sectcount * sizeof(struct _section); ++ ++ dprintf(5,"tiload: check offset\n"); ++ for (index=0; indexaddr); ++ secOffset = dslhal_support_byteSwap32(sptr->offset); ++ secLength = dslhal_support_byteSwap32(sptr->length); ++ secPage = dslhal_support_byteSwap32(sptr->page); ++ ++ /* validate offset */ ++ if ( secOffset== 0xffffffff) ++ { ++ /* special case: zero fill */ ++ /* offset is valid, don't change expoffset */ ++ } ++ else ++ { ++ if (secOffset > len-4) ++ { ++ dprintf(5,"Offset error\n"); ++ return DSLHAL_ERROR_FIRMWARE_OFFSET; ++ } ++ ++ /* determine expected offset of NEXT section */ ++ expoffset = secLength + secOffset; ++ ++ /* all addresses must be on word boundaries */ ++ if (secAddr & 3) ++ { ++ ++ } ++ } ++ } ++ ++ /* check final offset - should just be a checksum left */ ++/* IMPORTANT 11/24/02 --> Got this error... but bypassed for Pf of Concept*/ ++ /* ++ if (expoffset != len-4) ++ { ++ dprintf(5,"Final offset error\n"); ++ return DSLHAL_ERROR_FIRMWARE_OFFSET; ++ } ++ */ ++ ++ /* Actual Code loading to DSP Memory */ ++ ++ /* Initialize DSP Data Memory before code load*/ ++ dprintf(5,"Zero Prefill DSP DMEM\n"); ++ DSLHAL_REG32(ADSLSSADR)=0x80000000; ++ shim_osZeroMemory((char *)0xa1000000, 0x10000); ++ /* Load sections from the image */ ++ for (index=0; indexaddr); ++ secOffset = dslhal_support_byteSwap32(sptr->offset); ++ secLength = dslhal_support_byteSwap32(sptr->length); ++ secPage = dslhal_support_byteSwap32(sptr->page); ++ ++ data.aword = secAddr; ++ checksum += data.byte[0] + data.byte[1] + data.byte[2] + data.byte[3]; ++ ++ data.aword = secLength; ++ checksum += data.byte[0] + data.byte[1] + data.byte[2] + data.byte[3]; ++ ++ data.aword = secOffset; ++ checksum += data.byte[0] + data.byte[1] + data.byte[2] + data.byte[3]; ++ ++ data.aword = secPage; ++ checksum += data.byte[0] + data.byte[1] + data.byte[2] + data.byte[3]; ++ ++ ++ /* validate offset */ ++ if (secOffset == 0xffffffff) ++ { ++ /* special case: zero fill */ ++ /* offset is valid, don't change expoffset */ ++ } ++ else ++ { ++ /* real offset */ ++ if(secOffset > len-4) ++ { ++ dprintf(5,"section[%u] offset too big (%X/%X)\n", index, ++ secOffset, len-4); ++ ++ return DSLHAL_ERROR_FIRMWARE_OFFSET; ++ } ++ ++ /* determine expected offset of NEXT section */ ++ expoffset = secLength + secOffset; ++ ++ } ++ ++ } ++ ++ /* check final offset - should just be a checksum left */ ++ /* ++ if(expoffset != len-4) ++ { ++ dprintf(1,"sections don't span full file (%X/%X)\n",expoffset,len-2); ++ return DSLHAL_ERROR_FIRMWARE_OFFSET; ++ } ++ */ ++ dprintf(5,"tiload: load binary\n"); ++ ++ for (index=0; indexaddr); ++ secOffset = dslhal_support_byteSwap32(sptr->offset); ++ secLength = dslhal_support_byteSwap32(sptr->length); ++ secPage = dslhal_support_byteSwap32(sptr->page); ++ dprintf(5,"loading section %u\n", index); ++ dprintf(5,"section %u: addr: %X\n", index, secAddr); ++ dprintf(5,"section %u: length: %X\n", index, secLength); ++ dprintf(5,"section %u: offset: %X\n", index, secOffset); ++ dprintf(5,"section %u: page: %X\n", index, secPage); ++ ++ /* point to the section's data */ ++ if(secOffset != 0xffffffff) ++ { ++ /* Load this section of data */ ++ iptr = image + secOffset; ++ dprintf(6, "iptr %8x\n", (unsigned int)iptr); ++ } ++ ++ if(secPage) ++ { ++ dprintf(6,"OVERLAY PAGE #%d\n",secPage); ++ /* overlay page, don't write to dsp yet, save into host memory*/ ++ ++ dprintf(6,"Section Length: %d \n",secLength); ++ ptidsl->olayDpPage[secPage].PmemStartWtAddr = (unsigned int) shim_osAllocateDmaMemory(secLength); ++ if(ptidsl->olayDpPage[secPage].PmemStartWtAddr == NULL) ++ { ++ dprintf(1, "overlay page allocate error\n"); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++#ifdef PRE_SILICON ++ ptidsl->olayDpPage[secPage].overlayHostAddr = ((((ptidsl->olayDpPage[secPage].PmemStartWtAddr)-0x84000000)-0x10000000)+0x030b0000); ++#else ++ /* ptidsl->olayDpPage[secPage].overlayHostAddr = ((unsigned int)(ptidsl->olayDpPage[secPage].PmemStartWtAddr)&~0xe0000000); */ ++ ptidsl->olayDpPage[secPage].overlayHostAddr = virtual2Physical((unsigned int)ptidsl->olayDpPage[secPage].PmemStartWtAddr); ++#endif ++ dprintf(6,"Allocated Addr: 0x%x \t Xlated Addr: 0x%x \n",ptidsl->olayDpPage[secPage].PmemStartWtAddr,ptidsl->olayDpPage[secPage].overlayHostAddr); ++ ++ ptidsl->olayDpPage[secPage].overlayHostAddr = (unsigned int)dslhal_support_byteSwap32(ptidsl->olayDpPage[secPage].overlayHostAddr); ++ ptidsl->olayDpPage[secPage].OverlayXferCount = secLength; ++ ptidsl->olayDpPage[secPage].BinAddr = secAddr; ++ ptidsl->olayDpPage[secPage].SecOffset = secOffset; ++ shim_osMoveMemory((char *)ptidsl->olayDpPage[secPage].PmemStartWtAddr, (char *)iptr, secLength); ++ /* RamP Image ByteSwap test */ ++ olayStart = (unsigned int *)ptidsl->olayDpPage[secPage].PmemStartWtAddr; ++ ++ for(olayXfer=0;olayXfer< secLength/4;olayXfer++) ++ { ++ olayStore = *(unsigned int *)olayStart; ++ olayStore = (unsigned int)dslhal_support_byteSwap32(olayStore); ++ *(unsigned int*)olayStart = olayStore; ++ dprintf(5, "Addr:0x%x \t Content: 0x%x \n",olayStart,olayStore); ++ olayStart++; ++ olayStore=0; ++ } ++ /* RamP Image ByteSwap test */ ++ /* compute the CRC of each overlay page and Store the Checksum in a local global variable */ ++ /* This Value of CRC is to be compared with the header where all the CRC bytes are lumped together */ ++ ptidsl->olayDpPage[secPage].olayPageCrc32 = dslhal_support_computeCrc32((char *)ptidsl->olayDpPage[secPage].PmemStartWtAddr, ptidsl->olayDpPage[secPage].OverlayXferCount); ++ ++ shim_osWriteBackCache((void *)ptidsl->olayDpPage[secPage].PmemStartWtAddr, secLength); ++ } ++ else ++ { ++ rc = secAddr&0xff000000; ++ if(rc && rc!=0x80000000) ++ { ++ dprintf(4,"Not DSP PMEM/DMEM\n"); ++ /* don't write to dsp, save into host memory*/ ++ dprintf(4,"Section Addr: %x Section Length: %d \n",secAddr,secLength); ++ ptidsl->coProfiles.PmemStartWtAddr = (unsigned int) shim_osAllocateDmaMemory(secLength); ++ if(ptidsl->coProfiles.PmemStartWtAddr == NULL) ++ { ++ dprintf(1, "memory allocate error\n"); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++ ptidsl->coProfiles.overlayHostAddr = virtual2Physical((unsigned int)ptidsl->coProfiles.PmemStartWtAddr); ++ dprintf(4,"Allocated Addr: 0x%x \t Xlated Addr: 0x%x \n",ptidsl->coProfiles.PmemStartWtAddr, ptidsl->coProfiles.overlayHostAddr); ++ ptidsl->coProfiles.overlayHostAddr = (unsigned int)dslhal_support_byteSwap32(ptidsl->coProfiles.overlayHostAddr); ++ ptidsl->coProfiles.OverlayXferCount = secLength; ++ ptidsl->coProfiles.BinAddr = secAddr; ++ ptidsl->coProfiles.SecOffset = secOffset; ++ ++ shim_osMoveMemory((char *)ptidsl->coProfiles.PmemStartWtAddr, (char *)iptr, secLength); ++ /* RamP Image ByteSwap test */ ++ olayStart = (unsigned int *)ptidsl->coProfiles.PmemStartWtAddr; ++ ++ for(olayXfer=0;olayXfer< secLength/4;olayXfer++) ++ { ++ olayStore = *(unsigned int *)olayStart; ++ olayStore = (unsigned int)dslhal_support_byteSwap32(olayStore); ++ *(unsigned int*)olayStart = olayStore; ++ dprintf(5, "Addr:0x%x \t Content: 0x%x \n",olayStart,olayStore); ++ olayStart++; ++ olayStore=0; ++ } ++ shim_osWriteBackCache((void *)ptidsl->coProfiles.PmemStartWtAddr, secLength); ++ } ++ else ++ { ++ /* IMPORTANT: write image to DSP memory */ ++ rc=dslhal_support_blockWrite((void *)iptr, (void *)secAddr, secLength); ++ if(rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ shim_osClockWait(0x50000); ++ /* ++ rc=dslhal_support_blockRead((void*)secAddr, (void*)tmpBuffer, secLength); ++ if(rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ for(i=0;ipmainAddr=pdspOamSharedInterface; ++ ++ /* read the OamSharedInterfaceStructure */ ++ ++ dprintf(5,"ptidsl->hostIf.mainAddr=0x%X\n", (unsigned int)ptidsl->pmainAddr); ++ ++ /* get the pointer to DSP-OAM Shared Interface */ ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ /* Communicate the Allocated Memory Address to DSP to choose CO Profiles */ ++ ++ /* Change the Endianness of the profileList pointer */ ++ dspOamSharedInterface.profileList_p = (DEV_HOST_profileBase_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.profileList_p); ++ /* Access the profileList Structure */ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.profileList_p,&profileList, sizeof(DEV_HOST_profileBase_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ dprintf(2,"Old Addr:%x New: %x \n",profileList.hostProfileBase_p,ptidsl->coProfiles.overlayHostAddr); ++ profileList.hostProfileBase_p = (DEV_HOST_coData_t *)ptidsl->coProfiles.overlayHostAddr; ++ rc = dslhal_support_blockWrite(&profileList,(PVOID)dspOamSharedInterface.profileList_p,sizeof(DEV_HOST_profileBase_t)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ ++ /* Communicate the Allocated Memory Address to DSP to do overlays */ ++ ++ /* Change the Endianness of the olayDpDef pointer */ ++ dspOamSharedInterface.olayDpParms_p = (DEV_HOST_olayDpDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.olayDpParms_p); ++ /* Access the olayDpDef Structure */ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.olayDpParms_p,&olayDpParms, sizeof(DEV_HOST_olayDpDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ ++ for(i=1;iolayDpPage[i].overlayHostAddr; ++ rc = dslhal_support_blockWrite(&olayDpPageDef[i],(PVOID)olayDpParms.olayDpPage_p[i],sizeof(DEV_HOST_olayDpPageDef_t)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ } ++ ++ /* Change the endianness of the Datapump Version Pointer */ ++ dspOamSharedInterface.datapumpVersion_p = (DEV_HOST_dspVersionDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.datapumpVersion_p); ++ ++ /* get DSPVersion itself */ ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.datapumpVersion_p,&dspVersion, sizeof(DEV_HOST_dspVersionDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ /* table_dsp info */ ++#if SWTC ++ dspOamSharedInterface.tcHostComm_p = (DEV_HOST_tcHostCommDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.tcHostComm_p); ++ rc = dslhal_support_blockRead(&pdspOamSharedInterface->tcHostComm_p, ++ &pTCHostCommDef, 4); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ pTCHostCommDef=(DEV_HOST_tcHostCommDef_t *) dslhal_support_byteSwap32((unsigned int)pTCHostCommDef); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.tcHostComm_p, ++ &TCHostCommDef, sizeof(DEV_HOST_tcHostCommDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++#endif ++ /* Select the Multimode Training */ ++ dspOamSharedInterface.oamWriteNegoParams_p = (DEV_HOST_oamWrNegoParaDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.oamWriteNegoParams_p); ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.oamWriteNegoParams_p, &OamWrNegoParaDef, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++switch(dspVersion.netService) ++ { ++ case 1: OamWrNegoParaDef.stdMode = MULTI_MODE; ++ dprintf(5,"POTS Service \n"); ++ ptidsl->netService = 1; ++ break; ++ case 2: OamWrNegoParaDef.stdMode = GDMT_MODE; ++ dprintf(5,"ISDN Service \n"); ++ ptidsl->netService = 2; ++ break; ++ default: OamWrNegoParaDef.stdMode = T1413_MODE; ++ dprintf(5,"Default Service \n"); ++ break; ++ } ++ ++ ptidsl->AppData.StdMode = (unsigned int)OamWrNegoParaDef.stdMode; ++ ++ OamWrNegoParaDef.oamFeature = dslhal_support_byteSwap32((OAMFEATURE_TC_SYNC_DETECT_MASK)); ++ /* Set the flag to start retraining if the margin of the modem drops below ++ default margin during showtime */ ++ ++ OamWrNegoParaDef.marginMonitorShwtme = FALSE; ++ /* Set the flag to start retraining if the margin of the modem drops below default margin during training */ ++ ++ OamWrNegoParaDef.marginMonitorTrning = FALSE; ++ OamWrNegoParaDef.dsToneTurnoff_f = 0; ++ dslhal_support_blockWrite(&OamWrNegoParaDef, ++ (PVOID)dspOamSharedInterface.oamWriteNegoParams_p, sizeof(DEV_HOST_oamWrNegoParaDef_t)); ++ rc=dslhal_support_setInterruptMask(ptidsl,0); ++ if(rc!=DSLHAL_ERROR_NO_ERRORS) ++ return rc; ++ /* Co Profile Test */ ++#if CO_PROFILES ++ dspOamSharedInterface.profileList_p = (DEV_HOST_profileBase_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.profileList_p); ++ /* Access the profileList Structure */ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.profileList_p,&profileList, sizeof(DEV_HOST_profileBase_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ profileList.hostProfileBase_p = (DEV_HOST_coData_t *)dslhal_support_byteSwap32((unsigned int)profileList.hostProfileBase_p); ++ rc = dslhal_support_blockRead((PVOID)profileList.hostProfileBase_p,&coData, sizeof(DEV_HOST_coData_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ dprintf(2,"Current Profile Vendor Id: %x \n",coData.phyAgcPgaTarget); ++ coData.phyAgcPgaTarget = 0xcaba; ++ rc = dslhal_support_blockWrite(&coData,(PVOID)profileList.hostProfileBase_p,sizeof(DEV_HOST_coData_t)); ++ if(rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++#endif ++ /* End of CO Profile Test */ ++ ++#ifndef NO_ACT ++ /* Constellation Display Buffer Allocate */ ++ ptidsl->constDisplay.PmemStartWtAddr = (unsigned int) shim_osAllocateDmaMemory(DSP_CONSTELLATION_BUFFER_SIZE); ++ if(ptidsl->constDisplay.PmemStartWtAddr == NULL) ++ { ++ dprintf(1, "memory allocate error\n"); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++ shim_osZeroMemory((void*)ptidsl->constDisplay.PmemStartWtAddr,DSP_CONSTELLATION_BUFFER_SIZE); ++ ptidsl->constDisplay.overlayHostAddr = virtual2Physical((unsigned int)ptidsl->constDisplay.PmemStartWtAddr); ++ dprintf(4,"Allocated Addr: 0x%x \t Xlated Addr: 0x%x \n",ptidsl->constDisplay.PmemStartWtAddr, ptidsl->constDisplay.overlayHostAddr); ++ ptidsl->constDisplay.OverlayXferCount = DSP_CONSTELLATION_BUFFER_SIZE; ++ ++ /* Communicate the Allocated Buffer for DSP load Constellation Data */ ++ ++ /* Change the Endianness of the profileList pointer */ ++ dspOamSharedInterface.consDispVar_p = (DEV_HOST_consBufDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.consDispVar_p); ++ /* Access the profileList Structure */ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.consDispVar_p,&constDisp, sizeof(DEV_HOST_consBufDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ dprintf(2,"Constellation Old Addr:%x New: %x \n",constDisp.consDispStartAddr,ptidsl->constDisplay.overlayHostAddr); ++ constDisp.consDispStartAddr = (unsigned int)dslhal_support_byteSwap32(ptidsl->constDisplay.overlayHostAddr); ++ constDisp.consDispCurrentAddr = constDisp.consDispStartAddr; ++ constDisp.consDispBufLen = (unsigned int)dslhal_support_byteSwap32(DSP_CONSTELLATION_BUFFER_SIZE); ++ rc = dslhal_support_blockWrite(&constDisp,(PVOID)dspOamSharedInterface.consDispVar_p,sizeof(DEV_HOST_consBufDef_t)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++#endif ++ dprintf(5,"dslhal_support_hostDspCodeDownload() completed.\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++ ++} /* end of dslhal_support_hostDspCodeDownload() */ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_readDelineationState() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* download DSP image from host memory to dsp memory ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_readDelineationState(tidsl_t * ptidsl) ++{ ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_atmStats_t atmStats; ++ DEV_HOST_dsAtmStats_t dsAtmStats0; ++ unsigned int rc=0, delinState=0; ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterface_t *) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ dspOamSharedInterface.atmStats_p = (DEV_HOST_atmStats_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.atmStats_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.atmStats_p,&atmStats, sizeof(DEV_HOST_atmStats_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ atmStats.ds0_p = (DEV_HOST_dsAtmStats_t *) dslhal_support_byteSwap32((unsigned int)atmStats.ds0_p); ++ ++ rc = dslhal_support_blockRead((PVOID)atmStats.ds0_p,&dsAtmStats0, (sizeof(DEV_HOST_dsAtmStats_t))); ++ ++ if (rc) ++ return rc; ++ delinState = dslhal_support_byteSwap32(dsAtmStats0.delineationState); ++ if(delinState == TC_SYNC) ++ ptidsl->lConnected = 1; ++ else ++ ptidsl->lConnected = 0; ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_processModemStateBitField() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* download DSP image from host memory to dsp memory ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_processModemStateBitField(tidsl_t * ptidsl) ++{ ++ int rc, offset[2]={2,0}; ++ int modemStateBitFields[NUMBER_OF_BITFIELDS],changedField=0; ++ rc = dslhal_api_dspInterfaceRead(ptidsl,(unsigned int)ptidsl->pmainAddr,2,(unsigned int *)&offset, ++ (unsigned char *)&modemStateBitFields,NUMBER_OF_BITFIELDS*sizeof(int)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ for(rc=0;rc0;rc--) ++ { ++ if(ptidsl->modemStateBitField[rc-1]!=modemStateBitFields[rc-1]) ++ { ++ changedField = rc; ++ break; ++ } ++ } ++ if(changedField) ++ { ++ for(rc=0;rc<32;rc++) ++ { ++ if(modemStateBitFields[changedField-1] & dslhal_support_byteSwap32((BITFIELD_SCAN >> rc))) ++ break; ++ } ++ dprintf(5,"Changed Field : %d Changed Bit : %d \n",changedField,(31-rc)); ++ ptidsl->rState = ((changedField*100) + (31-rc)); ++ dprintf(5,"Modem State : %d \n",ptidsl->rState); ++ shim_osMoveMemory((void *)ptidsl->modemStateBitField,(void *)modemStateBitFields, 4*NUMBER_OF_BITFIELDS); ++ } ++ ++ switch(changedField) ++ { ++ case 1: if((ptidsl->rState >= ATU_RIDLE) && (ptidsl->AppData.bState < RSTATE_IDLE)) ++ ptidsl->AppData.bState = RSTATE_IDLE; ++ if((ptidsl->rState >= GDMT_NSFLR) && (ptidsl->AppData.bState < RSTATE_INIT)) ++ ptidsl->AppData.bState = RSTATE_INIT; ++ if((ptidsl->rState >= GDMT_ACKX) && (ptidsl->AppData.bState < RSTATE_HS)) ++ ptidsl->AppData.bState = RSTATE_HS; ++ break; ++ ++ case 2: if((ptidsl->rState >= T1413_NSFLR) && (ptidsl->AppData.bState < RSTATE_INIT)) ++ ptidsl->AppData.bState = RSTATE_INIT; ++ if((ptidsl->rState >= T1413_ACKX) && (ptidsl->AppData.bState < RSTATE_HS)) ++ ptidsl->AppData.bState = RSTATE_HS; ++ if((ptidsl->rState == ATU_RSHOWTIME) && (ptidsl->AppData.bState < RSTATE_SHOWTIME)) ++ ptidsl->AppData.bState = RSTATE_SHOWTIME; ++ break; ++ ++ case 3: if((ptidsl->rState >= ADSL2_COMB3) && (ptidsl->AppData.bState < RSTATE_INIT)) ++ ptidsl->AppData.bState = RSTATE_INIT; ++ if((ptidsl->rState >= ADSL2_RPARAMS) && (ptidsl->AppData.bState < RSTATE_HS)) ++ ptidsl->AppData.bState = RSTATE_HS; ++ break; ++ ++ case 4: break; ++ default: break; ++ } ++ ++ ptidsl->stateTransition = modemStateBitFields[1]; ++ switch(ptidsl->AppData.bState) ++ { ++ case RSTATE_IDLE: ptidsl->AppData.idleTick=shim_osClockTick(); ++ ptidsl->AppData.initTick=0; ++ ptidsl->AppData.showtimeTick=0; ++ break; ++ case RSTATE_HS: if(!ptidsl->AppData.initTick) ++ { ++ ptidsl->AppData.initTick=shim_osClockTick(); ++ } ++ ptidsl->AppData.showtimeTick=0; ++ break; ++ case RSTATE_SHOWTIME: if(!ptidsl->AppData.showtimeTick) ++ ptidsl->AppData.showtimeTick=shim_osClockTick(); ++ break; ++ default: break; ++ } ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_setInterruptMask() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_setInterruptMask(tidsl_t * ptidsl,unsigned int inputMask) ++{ ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_hostInterruptMask_t interruptMask; ++ unsigned int rc=0; ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterface_t *) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ dspOamSharedInterface.hostInterruptMask_p =(DEV_HOST_hostInterruptMask_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.hostInterruptMask_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.hostInterruptMask_p, ++ &interruptMask, sizeof(DEV_HOST_hostInterruptMask_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ if(inputMask & MASK_MAILBOX_INTERRUPTS) ++ { ++ dprintf(7,"Mailbox Interrupts Masked \n"); ++ dprintf(7,"interruptMask.maskBitField1 = %d \n",dslhal_support_byteSwap32(interruptMask.maskBitField1)); ++ interruptMask.maskBitField1 |= dslhal_support_byteSwap32(MASK_MAILBOX_INTERRUPTS); ++ dprintf(7,"interruptMask.maskBitField1 = %d \n",dslhal_support_byteSwap32(interruptMask.maskBitField1)); ++ } ++ if(inputMask & MASK_BITFIELD_INTERRUPTS) ++ { ++ dprintf(7,"Bit field Interrupts Masked \n"); ++ dprintf(7,"interruptMask.maskBitField1 = %d \n",dslhal_support_byteSwap32(interruptMask.maskBitField1)); ++ interruptMask.maskBitField1 |= dslhal_support_byteSwap32(MASK_BITFIELD_INTERRUPTS); ++ dprintf(7,"interruptMask.maskBitField1 = %d \n",dslhal_support_byteSwap32(interruptMask.maskBitField1)); ++ } ++ if(inputMask & MASK_HEARTBEAT_INTERRUPTS) ++ { ++ dprintf(7,"Bit field Interrupts Masked \n"); ++ dprintf(7,"interruptMask.maskBitField1 = %d \n",dslhal_support_byteSwap32(interruptMask.maskBitField1)); ++ interruptMask.maskBitField1 |= dslhal_support_byteSwap32(MASK_HEARTBEAT_INTERRUPTS); ++ dprintf(7,"interruptMask.maskBitField1 = %d \n",dslhal_support_byteSwap32(interruptMask.maskBitField1)); ++ } ++ dslhal_support_blockWrite(&interruptMask, ++ dspOamSharedInterface.hostInterruptMask_p, sizeof(DEV_HOST_hostInterruptMask_t)); ++ dprintf(5,"dslhal_support_setInterruptMask() completed.\n"); ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_parseInterruptSource() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Parses the Interrupt Source Bit Field ++* ++* Return: interrupt Code if successful ++* negative error code if failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_parseInterruptSource(tidsl_t * ptidsl) ++{ ++ DEV_HOST_dspOamSharedInterface_t *pdspOamSharedInterface, dspOamSharedInterface; ++ DEV_HOST_hostInterruptSource_t interruptSource; ++ unsigned int rc=0,intrCode=0; ++ pdspOamSharedInterface = (DEV_HOST_dspOamSharedInterface_t *) ptidsl->pmainAddr; ++ rc = dslhal_support_blockRead(pdspOamSharedInterface, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return (0-DSLHAL_ERROR_BLOCK_READ); ++ } ++ dspOamSharedInterface.hostInterruptSource_p =(DEV_HOST_hostInterruptSource_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.hostInterruptSource_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.hostInterruptSource_p, ++ &interruptSource, sizeof(DEV_HOST_hostInterruptSource_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return (0-DSLHAL_ERROR_BLOCK_READ); ++ } ++ if(interruptSource.sourceBitField1 & dslhal_support_byteSwap32(MASK_MAILBOX_INTERRUPTS)) ++ { ++ dprintf(7,"Mailbox Interrupts Acknowledge \n"); ++ intrCode |= 0x00000011; ++ } ++ if(interruptSource.sourceBitField1 & dslhal_support_byteSwap32(MASK_BITFIELD_INTERRUPTS)) ++ { ++ dprintf(7,"Bit field Interrupt Acknowledge \n"); ++ intrCode |= 0x00001002; ++ } ++ if(interruptSource.sourceBitField1 & dslhal_support_byteSwap32(MASK_HEARTBEAT_INTERRUPTS)) ++ { ++ dprintf(7,"HeartBeat Interrupt Acknowledge \n"); ++ intrCode |= 0x00100004; ++ } ++ ++ interruptSource.sourceBitField1 &=0x0; ++ rc=dslhal_support_blockWrite(&interruptSource, ++ dspOamSharedInterface.hostInterruptSource_p, sizeof(DEV_HOST_hostInterruptSource_t)); ++ if(rc) ++ return (0-DSLHAL_ERROR_BLOCK_WRITE); ++ dprintf(5,"dslhal_support_parseInterruptSource() completed.\n"); ++ return intrCode; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_byteSwap16() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* input 16 bit short, byte swap from little endian to big endian or vise versa ++* ++********************************************************************************************/ ++ ++unsigned short dslhal_support_byteSwap16(unsigned short in16Bits) ++{ ++ unsigned short out16Bits; ++ ++#ifdef EB ++ unsigned char *pchar; ++ unsigned char tmp; ++#endif ++ ++ out16Bits = in16Bits; ++ ++#ifdef EB ++ pchar = (unsigned char *)(&out16Bits); ++ ++ tmp = *pchar; ++ *pchar = *(pchar + 1); ++ *(pchar + 1) = tmp; ++#endif ++ ++ return out16Bits; ++ ++} /* end of dslhal_support_byteSwap16() */ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_byteSwap32() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* input 32 bit int, byte swap from little endian to big endian or vise versa ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_byteSwap32(unsigned int in32Bits) ++{ ++ int out32Bits; ++ ++#ifdef EB ++ unsigned char tmp; ++ unsigned char *pchar; ++#endif ++ ++ out32Bits = in32Bits; ++ ++#ifdef EB ++ pchar = (unsigned char *)(&out32Bits); ++ ++ tmp = *pchar; ++ *pchar = *(pchar + 3); ++ *(pchar + 3) = tmp; ++ ++ tmp = *(pchar + 1); ++ *(pchar + 1) = *(pchar + 2); ++ *(pchar + 2) = tmp; ++#endif ++ ++ return out32Bits; ++ ++} /* end of dslhal_support_byteSwap32() */ ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_computeCrc32() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data ++* ++* Return: 32 bit CRC of the input data ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_computeCrc32(unsigned char *data, int len) ++{ ++ unsigned int result; ++ int i,j; ++ unsigned char octet; ++ ++ if ((len < 4) || (data==NULL)) ++ return(0xdeaddead); ++ result = *data++ << 24; ++ result |= *data++ << 16; ++ result |= *data++ << 8; ++ result |= *data++; ++ result = ~ result; ++ ++ len -=4; ++ ++ for (i=0; i> 7); ++ } ++ else ++ { ++ result = (result << 1) ^ (octet >> 7); ++ } ++ octet <<= 1; ++ } ++ } ++ return ~result; /* The complement of the remainder */ ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_checkOverlayPage() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data and compares it with reference ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_checkOverlayPage(tidsl_t *ptidsl, unsigned int tag) ++{ ++ unsigned int computedCrc; ++ if((unsigned char *)ptidsl->olayDpPage[tag].PmemStartWtAddr == NULL) ++ { ++ dprintf(5,"Null Address for Page: %d\n",tag); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++ computedCrc = dslhal_support_computeCrc32((unsigned char *)ptidsl->olayDpPage[tag].PmemStartWtAddr, ptidsl->olayDpPage[tag].OverlayXferCount); ++ dprintf(6,"\n Pre-Computed CRC32 = 0x%x \t Current CRC32 = 0x%x \n",ptidsl->olayDpPage[tag].olayPageCrc32,computedCrc); ++ if(computedCrc != ptidsl->olayDpPage[tag].olayPageCrc32) ++ return DSLHAL_ERROR_OVERLAY_CORRUPTED; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_clearTrainingInfo() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data and compares it with reference ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++int dslhal_support_clearTrainingInfo(tidsl_t *ptidsl) ++{ ++ int i; ++ ++ for(i=0; iolayDpPage[i].PmemStartWtAddr !=NULL) ++ { ++ shim_osFreeDmaMemory((void *) ptidsl->olayDpPage[i].PmemStartWtAddr, ++ ptidsl->olayDpPage[i].OverlayXferCount); ++ ptidsl->olayDpPage[i].PmemStartWtAddr =NULL; ++ } ++ } ++ if(ptidsl->coProfiles.PmemStartWtAddr != NULL) ++ { ++ shim_osFreeDmaMemory((void *)ptidsl->coProfiles.PmemStartWtAddr, ptidsl->coProfiles.OverlayXferCount); ++ ptidsl->coProfiles.PmemStartWtAddr = NULL; ++ } ++ return 0; ++} ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_reloadTrainingInfo() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Reload overlay pages from flash or memory ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++int dslhal_support_reloadTrainingInfo(tidsl_t * ptidsl) ++{ ++ ++ int rc = 0, i; ++ unsigned int olayXfer,olayStore; ++ unsigned int *olayStart; ++ ++ unsigned int crc32; ++ DEV_HOST_dspOamSharedInterface_t dspOamSharedInterface; ++ DEV_HOST_olayDpDef_t olayDpParms; ++ DEV_HOST_olayDpPageDef_t olayDpPageDef[NUM_PAGES]; ++ DEV_HOST_profileBase_t profileList; ++ ++ unsigned int secLength, secOffset, secPage; ++ ++ /* co profile */ ++ secLength = ptidsl->coProfiles.OverlayXferCount; ++ secOffset = ptidsl->coProfiles.SecOffset; ++ ptidsl->coProfiles.PmemStartWtAddr = (unsigned int) shim_osAllocateDmaMemory(secLength); ++ if(ptidsl->coProfiles.PmemStartWtAddr == NULL) ++ { ++ dprintf(1, "memory allocate error\n"); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++ /* holdSecPhyAddr = virtual2Physical((unsigned int)holdSecVirtAddr); */ ++ ptidsl->coProfiles.overlayHostAddr = virtual2Physical((unsigned int)ptidsl->coProfiles.PmemStartWtAddr); ++ dprintf(4,"Allocated Addr: 0x%x \t Xlated Addr: 0x%x \n",ptidsl->coProfiles.PmemStartWtAddr, ptidsl->coProfiles.overlayHostAddr); ++ ptidsl->coProfiles.overlayHostAddr = (unsigned int)dslhal_support_byteSwap32(ptidsl->coProfiles.overlayHostAddr); ++ ++ rc = shim_read_overlay_page((void *)ptidsl->coProfiles.PmemStartWtAddr, secOffset, secLength); ++ if(rc != secLength) ++ { ++ dprintf(1, "shim_read_overlay_page failed\n"); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++ ++ /*shim_osMoveMemory((char *)ptidsl->coProfiles.PmemStartWtAddr, (char *)iptr, secLength);*/ ++ /* RamP Image ByteSwap test */ ++ olayStart = (unsigned int *)ptidsl->coProfiles.PmemStartWtAddr; ++ ++ for(olayXfer=0;olayXfer< secLength/4;olayXfer++) ++ { ++ olayStore = *(unsigned int *)olayStart; ++ olayStore = (unsigned int)dslhal_support_byteSwap32(olayStore); ++ *(unsigned int*)olayStart = olayStore; ++ dprintf(5, "Addr:0x%x \t Content: 0x%x \n",olayStart,olayStore); ++ olayStart++; ++ olayStore=0; ++ } ++ shim_osWriteBackCache((void *)ptidsl->coProfiles.PmemStartWtAddr, secLength); ++ ++ ++ for (secPage=1;secPageolayDpPage[secPage].OverlayXferCount; ++ ++ dprintf(4,"Section[%d] Length: %d \n",secPage, secLength); ++ ++ secOffset = ptidsl->olayDpPage[secPage].SecOffset; ++ ptidsl->olayDpPage[secPage].PmemStartWtAddr = (unsigned int) shim_osAllocateDmaMemory(secLength); ++ if(ptidsl->olayDpPage[secPage].PmemStartWtAddr == NULL) ++ { ++ dprintf(1, "overlay page allocate error\n"); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++ ++ rc = shim_read_overlay_page((void *)ptidsl->olayDpPage[secPage].PmemStartWtAddr,secOffset, secLength); ++ if(rc != secLength) ++ { ++ dprintf(1, "overlay page read error\n"); ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ } ++ ++ /* ptidsl->olayDpPage[secPage].overlayHostAddr = ((unsigned int)(ptidsl->olayDpPage[secPage].PmemStartWtAddr)&~0xe0000000); */ ++ ptidsl->olayDpPage[secPage].overlayHostAddr = virtual2Physical((unsigned int)ptidsl->olayDpPage[secPage].PmemStartWtAddr); ++ dprintf(6,"Allocated Addr: 0x%x \t Xlated Addr: 0x%x \n",ptidsl->olayDpPage[secPage].PmemStartWtAddr,ptidsl->olayDpPage[secPage].overlayHostAddr); ++ ++ ptidsl->olayDpPage[secPage].overlayHostAddr = (unsigned int)dslhal_support_byteSwap32(ptidsl->olayDpPage[secPage].overlayHostAddr); ++ /*ptidsl->olayDpPage[secPage].OverlayXferCount = secLength; ++ ptidsl->olayDpPage[secPage].BinAddr = secAddr; ++ shim_osMoveMemory((char *)ptidsl->olayDpPage[secPage].PmemStartWtAddr, (char *)iptr, secLength); ++ */ ++ olayStart = (unsigned int *)ptidsl->olayDpPage[secPage].PmemStartWtAddr; ++ ++ for(olayXfer=0;olayXfer< secLength/4;olayXfer++) ++ { ++ olayStore = *(unsigned int *)olayStart; ++ olayStore = (unsigned int)dslhal_support_byteSwap32(olayStore); ++ *(unsigned int*)olayStart = olayStore; ++ dprintf(5, "Addr:0x%x \t Content: 0x%x \n",olayStart,olayStore); ++ olayStart++; ++ olayStore=0; ++ } ++ /* RamP Image ByteSwap test */ ++ /* compute the CRC of each overlay page and Store the Checksum in a local global variable */ ++ /* This Value of CRC is to be compared with the header where all the CRC bytes are lumped together */ ++ crc32 = dslhal_support_computeCrc32((char *)ptidsl->olayDpPage[secPage].PmemStartWtAddr, ptidsl->olayDpPage[secPage].OverlayXferCount); ++ if(crc32 != ptidsl->olayDpPage[secPage].olayPageCrc32) ++ return DSLHAL_ERROR_OVERLAY_MALLOC; ++ ++ shim_osWriteBackCache((void *)ptidsl->olayDpPage[secPage].PmemStartWtAddr, secLength); ++ } ++ ++ ++ dprintf(5,"ptidsl->hostIf.mainAddr=0x%X\n", (unsigned int)ptidsl->pmainAddr); ++ ++ /* get the pointer to DSP-OAM Shared Interface */ ++ rc = dslhal_support_blockRead(ptidsl->pmainAddr, &dspOamSharedInterface, ++ sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ /* Communicate the Allocated Memory Address to DSP to choose CO Profiles */ ++ ++ /* Change the Endianness of the profileList pointer */ ++ dspOamSharedInterface.profileList_p = (DEV_HOST_profileBase_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.profileList_p); ++ /* Access the profileList Structure */ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.profileList_p,&profileList, sizeof(DEV_HOST_profileBase_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ dprintf(2,"Old Addr:%x New: %x \n",profileList.hostProfileBase_p,ptidsl->coProfiles.overlayHostAddr); ++ profileList.hostProfileBase_p = (DEV_HOST_coData_t *)ptidsl->coProfiles.overlayHostAddr; ++ rc = dslhal_support_blockWrite(&profileList,(PVOID)dspOamSharedInterface.profileList_p,sizeof(DEV_HOST_profileBase_t)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ ++ /* Communicate the Allocated Memory Address to DSP to do overlays */ ++ ++ /* Change the Endianness of the olayDpDef pointer */ ++ dspOamSharedInterface.olayDpParms_p = (DEV_HOST_olayDpDef_t *)dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.olayDpParms_p); ++ /* Access the olayDpDef Structure */ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.olayDpParms_p,&olayDpParms, sizeof(DEV_HOST_olayDpDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ ++ for(i=1;iolayDpPage[i].overlayHostAddr; ++ rc = dslhal_support_blockWrite(&olayDpPageDef[i],(PVOID)olayDpParms.olayDpPage_p[i],sizeof(DEV_HOST_olayDpPageDef_t)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_WRITE; ++ } ++ ++ ptidsl->bOverlayPageLoaded = 1; ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ /* end of dslhal_support_reloadTrainingInfo() */ ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_restoreTrainingInfo() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data and compares it with reference ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++ ++int dslhal_support_restoreTrainingInfo(tidsl_t *ptidsl) ++{ ++ int rc; ++ ++ rc=1; ++ while(rc != 0) ++ { ++ dslhal_support_clearTrainingInfo(ptidsl); ++ //shim_osCriticalEnter(); ++ rc = dslhal_support_reloadTrainingInfo(ptidsl); ++ //shim_osCriticalExit(); ++ shim_osClockWait(6400); ++ } ++ return 0; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_advancedIdleProcessing() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Idle State Processing Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_advancedIdleProcessing(tidsl_t *ptidsl) ++{ ++ int rc=0; ++ ptidsl->AppData.bState = RSTATE_IDLE; ++#ifndef NO_ACT ++ rc += dslhal_advcfg_resetBitSwapMessageLog(ptidsl,0); ++ rc += dslhal_advcfg_resetBitSwapMessageLog(ptidsl,1); ++ rc += dslhal_advcfg_resetTrainStateHistory(ptidsl); ++ rc += dslhal_advcfg_getReasonForDrop(ptidsl); ++#endif ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_aocBitSwapProcessing() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Idle State Processing Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_aocBitSwapProcessing(tidsl_t *ptidsl,unsigned int usDs) ++{ ++ int rc=0; ++#ifndef NO_ACT ++ int i; ++ int differentCmd_f; ++ unsigned int dsSwapInx; ++ ++ static UINT8 lastAturBitSwapCommands[6] = {0, 0, 0, 0, 0, 0}; ++ static UINT8 lastAturBitSwapBinNum[6] = {0, 0, 0, 0, 0, 0}; ++ ++ if (usDs == 0) ++ { ++ dprintf(4," DSP_XMITBITSWAP\n"); ++ rc += dslhal_advcfg_getAocBitswapBuffer(ptidsl,0); ++ ptidsl->usBitSwapInx++; ++ if (ptidsl->usBitSwapInx > 29) ++ ptidsl->usBitSwapInx=0; ++ } ++ ++ if (usDs == 1) ++ { ++ dprintf(4," DSP_RCVBITSWAP\n"); ++ rc += dslhal_advcfg_getAocBitswapBuffer(ptidsl,1); ++ differentCmd_f = FALSE; ++ dsSwapInx = ptidsl->dsBitSwapInx; ++ if (! rc) ++ { ++ for (i = 0; i < 6; i++) ++ { ++ if (lastAturBitSwapCommands[i] != ptidsl->dsBitSwap[dsSwapInx].bitSwapCommand[i]) ++ { ++ differentCmd_f = TRUE; ++ break; ++ } ++ } ++ if (! differentCmd_f) ++ { ++ for (i = 0; i < 6; i++) ++ { ++ if (lastAturBitSwapBinNum[i] != ptidsl->dsBitSwap[dsSwapInx].bitSwapBinNum[i]) ++ { ++ differentCmd_f = TRUE; ++ break; ++ } ++ } ++ } ++ //CPE data pump seems to occasionally send us the same bit swap twice in a row with different sframe counter. ++ //Since these are never counted twice by the debug output of AC5, we should not count them twice either. ++ //So, we ignore the sframe_counter in determining whether the most recent bitswap is a duplicate. ++ if (differentCmd_f) ++ { ++ shim_osMoveMemory((void *)lastAturBitSwapCommands, (void *)ptidsl->dsBitSwap[dsSwapInx].bitSwapCommand, 6); ++ shim_osMoveMemory((void *)lastAturBitSwapBinNum, (void *)ptidsl->dsBitSwap[dsSwapInx].bitSwapBinNum, 6); ++ ptidsl->dsBitSwapInx++; ++ if (ptidsl->dsBitSwapInx > 29) ++ ptidsl->dsBitSwapInx = 0; ++ } ++ } ++ } ++#endif ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherEocMessages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced EOC Buffering functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherEocMessages(tidsl_t *ptidsl,int usDs, int msgPart1, int msgPart2) ++{ ++ int rc=0; ++#ifndef NO_ACT ++ rc = dslhal_advcfg_logEocMessages(ptidsl,usDs, msgPart1, msgPart2); ++#endif ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherSnrPerBin() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Snr per bin buffering Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherSnrPerBin(tidsl_t *ptidsl,unsigned int snrParam) ++{ ++ int rc=0; ++#ifndef NO_ACT ++ rc = dslhal_advcfg_getSnrPerBin(ptidsl,snrParam); ++#endif ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_processTrainingState() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Training State Processing Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_processTrainingState(tidsl_t *ptidsl) ++{ ++ int rc=0; ++#ifndef NO_ACT ++ ++ if(ptidsl->trainStateInx<120) ++ { ++ rc = dslhal_advcfg_getTrainingState(ptidsl,(void *)&ptidsl->trainHistory[ptidsl->trainStateInx++]); ++ if(ptidsl->trainHistory[(ptidsl->trainStateInx-1)].subStateIndex == ++ ptidsl->trainHistory[(ptidsl->trainStateInx-2)].subStateIndex) ++ ptidsl->trainStateInx--; ++ } ++ else ++ ptidsl->trainStateInx = 0; ++#endif ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherAdsl2Messages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Gathers ADSL2 Training Messages ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherAdsl2Messages(tidsl_t *ptidsl,int tag, int param1, int param2) ++{ ++ int rc=0; ++ unsigned int adsl2MsgLoc; ++ switch(tag) ++ { ++ case CMSGFMT_INDEX: ++ dprintf(5,"C-Msg-FMT rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSGFMT_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.cMsgFmt,CMSGFMT_SIZE); ++ break; ++ case RMSGFMT_INDEX: ++ case RMSGFMT2_INDEX: ++ dprintf(5,"R-Msg-FMT rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSGFMT_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.rMsgFmt,RMSGFMT_SIZE); ++ break; ++ case CMSGPCB_INDEX: ++ dprintf(5,"C-Msg-PCB rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSGPCB_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.cMsgPcb,CMSGPCB_SIZE); ++ ptidsl->adsl2TrainingMessages.cMsgPcbLen = CMSGPCB_SIZE; ++ break; ++ case CMSGPCB2_INDEX: ++ dprintf(5,"C-Msg-PCB2 rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSGPCB2_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.cMsgPcb,CMSGPCB2_SIZE); ++ ptidsl->adsl2TrainingMessages.cMsgPcbLen = CMSGPCB2_SIZE; ++#ifndef NO_ACT ++ rc += dslhal_advcfg_setBlackOutBits(ptidsl); ++#endif ++ break; ++ case CMSGPCB2L_INDEX: ++ dprintf(5,"C-Msg-PCB2L rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSGPCB2L_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.cMsgPcb,CMSGPCB2L_SIZE); ++ ptidsl->adsl2TrainingMessages.cMsgPcbLen = CMSGPCB2L_SIZE; ++ break; ++ case RMSGPCB_INDEX: ++ case RMSGPCB2L_INDEX: ++ dprintf(5,"R-Msg-PCB rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSGPCB_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.rMsgPcb,RMSGPCB_SIZE); ++ ptidsl->adsl2TrainingMessages.rMsgPcbLen = RMSGPCB_SIZE; ++ break; ++ ++ case CMSG1ADSL2_INDEX: ++ dprintf(5,"C-Msg1 rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSG1ADSL2_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.cMsg1,CMSG1ADSL2_SIZE); ++ ptidsl->adsl2TrainingMessages.cMsg1Len = CMSG1ADSL2_SIZE; ++ break; ++ case CMSG2ADSL2_INDEX: ++ dprintf(5,"C-Msg2 rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSG2ADSL2_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.cMsg2,CMSG2ADSL2_SIZE); ++ ptidsl->adsl2TrainingMessages.cMsg2Len = CMSG2ADSL2_SIZE; ++ break; ++ case RMSG1ADSL2_INDEX: ++ dprintf(5,"R-Msg1 rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG1ADSL2_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.rMsg1,RMSG1ADSL2_SIZE); ++ ptidsl->adsl2TrainingMessages.rMsg1Len = RMSG1ADSL2_SIZE; ++ break; ++ case RMSG2ADSL2_INDEX: ++ dprintf(5,"R-Msg2 rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG2ADSL2_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.rMsg2,RMSG2ADSL2_SIZE); ++ ptidsl->adsl2TrainingMessages.rMsg2Len = RMSG2ADSL2_SIZE; ++ break; ++ case CPARAMS_INDEX: ++ dprintf(5,"C-Params rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CPARAMS_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.cParams,CPARAMS_SIZE); ++ ptidsl->adsl2TrainingMessages.cParamsLen = CPARAMS_SIZE; ++ break; ++ case RPARAMS_INDEX: ++ dprintf(5,"R-Params rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RPARAMS_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2TrainingMessages.rParams,RPARAMS_SIZE); ++ ptidsl->adsl2TrainingMessages.rParamsLen = RPARAMS_SIZE; ++ break; ++ case RMSG1LD_INDEX: ++ dprintf(5,"R-Msg1 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG1LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg1Ld,RMSG1LD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsg1LdLen = RMSG1LD_SIZE; ++ break; ++ case RMSG2LD_INDEX: ++ dprintf(5,"R-Msg2 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG2LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg2Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case RMSG3LD_INDEX: ++ dprintf(5,"R-Msg3 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG3LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg3Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case RMSG4LD_INDEX: ++ dprintf(5,"R-Msg4 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG4LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg4Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case RMSG5LD_INDEX: ++ dprintf(5,"R-Msg5 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG5LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg5Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case RMSG6LD_INDEX: ++ dprintf(5,"R-Msg6 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG6LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg6Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case RMSG7LD_INDEX: ++ dprintf(5,"R-Msg7 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG7LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg7Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case RMSG8LD_INDEX: ++ dprintf(5,"R-Msg8 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG8LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg8Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case RMSG9LD_INDEX: ++ dprintf(5,"R-Msg9 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, RMSG9LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.rMsg9Ld,RMSGxLD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.rMsgxLdLen = RMSGxLD_SIZE; ++ break; ++ case CMSG1LD_INDEX: ++ dprintf(5,"C-Msg1 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSG1LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.cMsg1Ld,CMSG1LD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.cMsg1LdLen = CMSG1LD_SIZE; ++ break; ++ case CMSG2LD_INDEX: ++ dprintf(5,"C-Msg2 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSG2LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.cMsg2Ld,CMSG2LD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.cMsg2LdLen = CMSG2LD_SIZE; ++ break; ++ case CMSG3LD_INDEX: ++ dprintf(5,"C-Msg3 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSG3LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.cMsg3Ld,CMSG3LD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.cMsg3LdLen = CMSG3LD_SIZE; ++ break; ++ case CMSG4LD_INDEX: ++ dprintf(5,"C-Msg4 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSG4LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.cMsg4Ld,CMSG4LD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.cMsg4LdLen = CMSG4LD_SIZE; ++ break; ++ case CMSG5LD_INDEX: ++ dprintf(5,"C-Msg5 LD rec'd\n"); ++ adsl2MsgLoc = dslhal_support_getAdsl2MessageLocation ++ (ptidsl, CMSG5LD_INDEX); ++ rc += dslhal_support_blockRead((PVOID)adsl2MsgLoc, ++ ptidsl->adsl2DiagnosticMessages.cMsg5Ld,CMSG5LD_SIZE); ++ ptidsl->adsl2DiagnosticMessages.cMsg5LdLen = CMSG5LD_SIZE; ++ break; ++ default: ++ dprintf(5,"Unknown ADSL2 Message rec'd\n"); ++ break; ++ } ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_getAdsl2MessageLocation() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Gets the address to the ADSL2 Message being looked up ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_getAdsl2MessageLocation(tidsl_t *ptidsl,int msgOffset) ++{ ++ int rc=0; ++ ++ DEV_HOST_dspOamSharedInterface_t *pSharedInterface, sharedInterface; ++ DEV_HOST_dspWrNegoParaDef_t dspNegoPara; ++ int adsl2MsgString, adsl2MsgAddr; ++ ++ pSharedInterface = (DEV_HOST_dspOamSharedInterface_t *) ptidsl->pmainAddr; ++ rc += dslhal_support_blockRead(pSharedInterface, &sharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ sharedInterface.dspWriteNegoParams_p = (DEV_HOST_dspWrNegoParaDef_t *) dslhal_support_adsl2ByteSwap32((unsigned int)sharedInterface.dspWriteNegoParams_p); ++ rc += dslhal_support_blockRead((PVOID)sharedInterface.dspWriteNegoParams_p,&dspNegoPara, sizeof(DEV_HOST_dspWrNegoParaDef_t)); ++ ++ if (rc) ++ { ++ dprintf(1,"dslhal_support_blockRead failed\n"); ++ return DSLHAL_ERROR_BLOCK_READ; ++ } ++ ++ adsl2MsgString = dslhal_support_adsl2ByteSwap32((unsigned int)dspNegoPara.adsl2DeltMsgs_p); ++ dprintf(5,"ADSL2 Message String Address: 0x%x\n",adsl2MsgString); ++ rc += dslhal_support_blockRead((PVOID)(adsl2MsgString + ++ ((sizeof(unsigned char *)*msgOffset))), ++ &adsl2MsgAddr, sizeof(int)); ++ adsl2MsgAddr = dslhal_support_adsl2ByteSwap32((unsigned int)adsl2MsgAddr); ++ dprintf(5," Message Address: 0x%x\n",adsl2MsgAddr); ++ ++ if(rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ else ++ return adsl2MsgAddr; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_getCMsgsRa() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Training Message functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_getCMsgsRa(tidsl_t *ptidsl,void *cMsg) ++{ ++ int rc=0; ++ DEV_HOST_raMsgsDef_t raMsgParms; ++ DEV_HOST_dspOamSharedInterface_t dspOamSharedInterface; ++ rc += dslhal_support_blockRead(ptidsl->pmainAddr, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ ++ dspOamSharedInterface.raMsgs_p = (DEV_HOST_raMsgsDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.raMsgs_p); ++ ++ rc += dslhal_support_blockRead((PVOID)dspOamSharedInterface.raMsgs_p, ++ &raMsgParms, sizeof(DEV_HOST_raMsgsDef_t)); ++ shim_osMoveMemory((void *)cMsg,(void *)raMsgParms.cMsgsRaString,6); ++ ++ if(rc) ++ return DSLHAL_ERROR_CONFIG_API_FAILURE; ++ else ++ return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherRateMessages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Gathers Rate Training Messages ++* Input ++* tidsl_t *ptidsl : Pointer to application structure ++* ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherRateMessages(tidsl_t * ptidsl) ++{ ++ int rc; ++ DEV_HOST_dspWrNegoParaDef_t negoParms; ++ DEV_HOST_dspOamSharedInterface_t dspOamSharedInterface; ++ ++ dprintf(1, "dslhal_support_gatherRateMessages\n"); ++ ++ rc += dslhal_support_blockRead(ptidsl->pmainAddr, &dspOamSharedInterface,sizeof(DEV_HOST_dspOamSharedInterface_t)); ++ dspOamSharedInterface.dspWriteNegoParams_p = (DEV_HOST_dspWrNegoParaDef_t *) dslhal_support_byteSwap32((unsigned int)dspOamSharedInterface.dspWriteNegoParams_p); ++ ++ rc = dslhal_support_blockRead((PVOID)dspOamSharedInterface.dspWriteNegoParams_p, &negoParms, sizeof(DEV_HOST_dspWrNegoParaDef_t)); ++ if (rc) ++ return DSLHAL_ERROR_BLOCK_READ; ++ else ++ { ++ shim_osMoveMemory((void *)ptidsl->AppData.bCRates1, (void *)negoParms.cRates1, 120); ++ shim_osMoveMemory((void *)ptidsl->AppData.bRRates1, (void *)negoParms.rRates1, 44); ++ } ++return DSLHAL_ERROR_NO_ERRORS; ++} ++ ++static unsigned int dslhal_support_adsl2ByteSwap32(unsigned int in32Bits) ++{ ++ int out32Bits=0; ++ ++#ifdef EB ++ out32Bits = (in32Bits << 24); ++ out32Bits |=((in32Bits & 0x0000ff00) << 8); ++ out32Bits |=((in32Bits & 0xff000000) >> 24); ++ out32Bits |=((in32Bits & 0x00ff0000) >> 8); ++#else ++ out32Bits = in32Bits; ++#endif ++ ++ return out32Bits; ++ ++} /* end of dslhal_support_byteSwap32() */ +diff -urN linux.old/drivers/atm/sangam_atm/dsl_hal_support.h linux.dev/drivers/atm/sangam_atm/dsl_hal_support.h +--- linux.old/drivers/atm/sangam_atm/dsl_hal_support.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dsl_hal_support.h 2005-08-23 04:46:50.101843088 +0200 +@@ -0,0 +1,718 @@ ++#ifndef DSL_HAL_SUPPORT_H__ ++#define DSL_HAL_SUPPORT_H__ 1 ++ ++/******************************************************************************* ++* FILE PURPOSE: DSL Driver API functions for Sangam ++* ++******************************************************************************** ++* FILE NAME: dsl_hal_functiondefines.c ++* ++* DESCRIPTION: ++* Contains basic DSL HAL API declarations for Sangam ++* ++* ++* (C) Copyright 2001-02, Texas Instruments, Inc. ++* History ++* Date Version Notes ++* 06Feb03 0.00.00 RamP Created ++* 21Mar03 0.00.01 RamP Removed byteswap functions ++* 21Mar03 0.00.02 RamP Added extern osFreeVMemory declaration ++* 10Apr03 0.00.03 RamP Changed declaration for loadFWImage & ++* loadDebugFWImage to remove ptidsl param ++* 12Apr03 0.00.04 RamP Added function to set Interrupt Bit ++* Masks for bitfield & Mailboxes ++* 14Apr03 0.00.05 RamP Added modem state bit field processing ++* 15Apr03 0.00.06 RamP Added function osAllocateVMemory ++* 21Apr03 0.01.00 RamP Added function osAllocateDmaMemory ++* Added function osFreeDmaMemory ++* (Alpha) Added macro virtual2Physical, ++* 22Apr03 0.01.01 RamP Moved acknowledgeInterrupt to api.h ++* 24Apr03 0.01.02 RamP Added checkOvelayPage function ++* 29May03 0.01.03 RamP Added critical enter/exit function decl ++* 06Jun03 0.01.04 RamP Added Interrupt source parsing function ++* 06Oct03 0.01.05 RamP Added function abstraction switches ++* 12Oct03 0.01.06 RamP Added ADSL2 Message function prototypes ++* 14Nov03 0.03.07 RamP Added function to gather Rate Messages ++*******************************************************************************/ ++ ++#include "dsl_hal_api.h" ++ ++#define virtual2Physical(a) (((int)a)&~0xe0000000) ++/* External Function Prototype Declarations */ ++ ++extern unsigned int shim_osGetCpuFrequency(void); ++extern void shim_osClockWait(int val); ++extern unsigned int shim_osClockTick(void); ++ ++extern int shim_osStringCmp(const char *s1, const char *s2); ++ ++extern void dprintf( int uDbgLevel, char * szFmt, ...); ++ ++extern int shim_osLoadFWImage(unsigned char *firmwareImage); ++extern int shim_osLoadDebugFWImage(unsigned char *debugFirmwareImage); ++extern unsigned int shim_read_overlay_page(void *ptr, unsigned int secOffset, unsigned int secLength); ++extern void shim_osMoveMemory(char *dst, char *src, unsigned int numBytes); ++extern void shim_osZeroMemory(char *dst, unsigned int numBytes); ++ ++extern void *shim_osAllocateMemory(unsigned int size); ++extern void *shim_osAllocateVMemory(unsigned int size); ++extern void *shim_osAllocateDmaMemory(unsigned int size); ++ ++extern void shim_osFreeMemory(void *ptr, unsigned int size); ++extern void shim_osFreeVMemory(void *ptr, unsigned int size); ++extern void shim_osFreeDmaMemory(void *ptr, unsigned int size); ++ ++extern void shim_osWriteBackCache(void *pMem, unsigned int size); ++extern void shim_osCriticalEnter(void); ++extern void shim_osCriticalExit(void); ++ ++ ++/******************************************************************************************* ++* FUNCTION NAME: dslhal_support_writeHostMailbox ++* ++******************************************************************************************** ++* DESCRIPTION: Send a message to a mailbox ++* ++* ARGUMENTS: int cmd command to write ++* int tag tag (currently unused) ++* int p1 parameter 1 (currently unused) ++* int p2 parameter 2 (currently unused) ++* ++* RETURNS: 0 if successful ++* NZ otherwise ++* ++*******************************************************************************************/ ++ ++int dslhal_support_writeHostMailbox ++(tidsl_t *ptidsl, ++ int cmd, ++ int tag, ++ int p1, ++ int p2); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_readDspMailbox ++* ++********************************************************************************************* ++* DESCRIPTION: Reads a message from the mailbox ++* ++* ARGUMENTS: int *pcmd Pointer to command read ++* ++* RETURNS: 0 if successful ++* 1 if no mail ++* NZ otherwise ++* ++*****************************************************************************************/ ++ ++int dslhal_support_readDspMailbox ++(tidsl_t *ptidsl, ++ int *pcmd, ++ int *ptag, ++ int *pprm1, ++ int *pprm2); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_readTextMailbox ++* ++********************************************************************************************* ++* DESCRIPTION: Reads a message from the mailbox ++* ++* ARGUMENTS: int *pcmd Pointer to command read ++* ++* RETURNS: 0 if successful ++* 1 if no mail ++* NZ otherwise ++* ++*****************************************************************************************/ ++ ++int dslhal_support_readTextMailbox ++(tidsl_t *ptidsl, ++ int *pmsg1, ++ int *pmsg2); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_blockRead ++* ++********************************************************************************************* ++* DESCRIPTION: This rouin simulates DSP memory read as done in ax5 pci nic card ++* ++* INPUT: void *addr, memory address to be read ++* void *buffer, dat buffer to be filled with from memmory ++* size_t count, number of bytes to be written ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* ++*****************************************************************************************/ ++ ++int dslhal_support_blockRead ++(void *addr, ++ void *buffer, ++ size_t count); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_blockWrite ++* ++******************************************************************************************* ++* DESCRIPTION: This rouin simulates DSP memory write as done in ax5 pci nic card ++* ++* INPUT: void *buffer, data need to written ++* void *adde, memory address to be written ++* size_t count, number of bytes to be written ++* ++* RETURN: 0 --succeeded ++* 1 --Failed ++* ++*****************************************************************************************/ ++ ++int dslhal_support_blockWrite ++(void *buffer, ++ void *addr, ++ size_t count); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_hostDspAddressTranslate ++* ++******************************************************************************************* ++* DESCRIPTION: This function moves the address window to translate physical address ++* ++* INPUT: unsigned int addr : address that requires translation ++* ++* RETURN: Translated address or error condition ++* ++* ++*****************************************************************************************/ ++ ++unsigned int dslhal_support_hostDspAddressTranslate ++( unsigned int addr ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_unresetDslSubsystem ++* ++******************************************************************************************* ++* DESCRIPTION: This function unreset Dsl Subsystem ++* ++* INPUT: None ++* ++* RETURN: 0 if Pass; 1 if Fail ++* ++*****************************************************************************************/ ++int dslhal_support_unresetDslSubsystem ++(void ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_unresetDsp() ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction takes ax5 daugter board out of reset. ++* ++* INPUT: None ++* ++* RETURN: 0 --successful. ++* 1 --failed ++* ++*****************************************************************************************/ ++int dslhal_support_unresetDsp ++(void ++); ++ ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_resetDslSubsystem ++* ++******************************************************************************************* ++* DESCRIPTION: This function unreset Dsl Subsystem ++* ++* INPUT: None ++* ++* RETURN: 0 if Pass; 1 if Fail ++* ++*****************************************************************************************/ ++int dslhal_support_resetDslSubsystem ++(void ++); ++ ++/****************************************************************************************** ++* FUNCTION NAME: dslhal_support_resetDsp() ++* ++******************************************************************************************* ++* DESCRIPTION: This fuction takes ax5 daugter board out of reset. ++* ++* INPUT: None ++* ++* RETURN: 0 --successful. ++* 1 --failed ++* ++*****************************************************************************************/ ++int dslhal_support_resetDsp ++(void ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_hostDspCodeDownload() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* download DSP image from host memory to dsp memory ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++int dslhal_support_hostDspCodeDownload ++(tidsl_t * ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_digi_assignMemTestSpace() ++* ++********************************************************************************************* ++* DESCRIPTION: Assigns Memory Space in SDRAM for External Memory Test ++* Input: tidsl_t *ptidsl ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_digi_assignMemTestSpace ++(tidsl_t *ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_digi_readMemTestResult() ++* ++********************************************************************************************* ++* DESCRIPTION: Reads Results of External Memory Test ++* Input: tidsl_t *ptidsl ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_digi_readMemTestResult ++(tidsl_t *ptidsl, ++unsigned int testResult ++); ++ ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_codeDownload() ++* ++********************************************************************************************* ++* DESCRIPTION: Brings DSLSS out of Reset, Downloads Diag Firmware, ++* brings DSP out of Reset ++* Input: tidsl_t *ptidsl ++* ++* Return: 0 success ++* 1 failed ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_codeDownload ++(tidsl_t *ptidsl, ++unsigned char* missingTones ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_anlg_setPgaParams() ++* ++********************************************************************************************* ++* DESCRIPTION: This function instructs the Transciever to transmit the Reverb with missing ++* tones and Medley's with missing tones. These signals are defined in ITU ++* G.992.1 ADSL Standards. ++* ++* Input: Test selects between the Reverb or Medley tests. 0 - Reverb, 1 - Medley ++* Tones selects the . ++* Return: NULL ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_anlg_setPgaParams ++(tidsl_t *ptidsl, ++int agcFlag, ++short pga1, ++short pga2, ++short pga3, ++short aeq ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_anlg_getRxNoisePower() ++* ++********************************************************************************************* ++* DESCRIPTION: This function instructs the Transciever to transmit the Reverb with missing ++* tones and Medley's with missing tones. These signals are defined in ITU ++* G.992.1 ADSL Standards. ++* ++* Input: Test selects between the Reverb or Medley tests. 0 - Reverb, 1 - Medley ++* Tones selects the . ++* Return: NULL ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_anlg_getRxNoisePower ++(tidsl_t *ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_diags_anlg_setMissingTones() ++* ++********************************************************************************************* ++* DESCRIPTION: This function instructs the Transciever to transmit the Reverb with missing ++* tones and Medley's with missing tones. These signals are defined in ITU ++* G.992.1 ADSL Standards. ++* ++* Input: Test selects between the Reverb or Medley tests. 0 - Reverb, 1 - Medley ++* Tones selects the . ++* Return: NULL ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_diags_anlg_setMissingTones ++(tidsl_t *ptidsl, ++unsigned char* missingTones ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_readDelineationState() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* download DSP image from host memory to dsp memory ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_readDelineationState ++(tidsl_t *ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_processModemStateBitField() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* download DSP image from host memory to dsp memory ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_processModemStateBitField ++(tidsl_t *ptidsl ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_setInterruptMask() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_setInterruptMask ++(tidsl_t * ptidsl, ++unsigned int inputMask ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_computeCrc32() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data ++* ++* Return: 32 bit CRC of the input data ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_computeCrc32 ++(unsigned char *data, ++int len ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_checkOverlayPage() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data and compares it with reference ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_checkOverlayPage ++(tidsl_t *ptidsl, ++unsigned int tag ++); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_restoreTrainingInfo() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data and compares it with reference ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++int dslhal_support_restoreTrainingInfo(tidsl_t * ptidsl); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_reloadTrainingInfo() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data and compares it with reference ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++int dslhal_support_reloadTrainingInfo(tidsl_t * ptidsl); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_clearTrainingInfo() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Computes the CRC-32 for the input data and compares it with reference ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++int dslhal_support_clearTrainingInfo(tidsl_t * ptidsl); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_parseInterruptSource() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Sets the host interrupt bit masks ++* ++* Return: 0 success ++* 1 failed ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_parseInterruptSource(tidsl_t * ptidsl); ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_advancedIdleProcessing() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Idle State Processing Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_advancedIdleProcessing(tidsl_t *ptidsl); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_aocBitSwapProcessing() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Bitswap buffer Processing Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_aocBitSwapProcessing(tidsl_t *ptidsl,unsigned int usDs); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherEocMessages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced EOC Buffering functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherEocMessages(tidsl_t *ptidsl,int usDs, int msgPart1, int msgPart2); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherSnrPerBin() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Snr per bin buffering Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherSnrPerBin(tidsl_t *ptidsl,unsigned int snrParm); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_processTrainingState() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Training State Processing Functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_processTrainingState(tidsl_t *ptidsl); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherAdsl2Messages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced EOC Buffering functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherAdsl2Messages(tidsl_t *ptidsl,int msgTag, int param1, int param2); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_getAdsl2MsgLocation() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Gets the address to the ADSL2 Message being looked up ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_getAdsl2MessageLocation(tidsl_t *ptidsl,int msgOffset); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_getCMsgsRa() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Calls Advanced Training Message functions ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_getCMsgsRa(tidsl_t *ptidsl,void *cMsg); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_gatherRateMessages() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* Gathers Advanced Training Messages ++* ++* Return: Error Condition (if any) ++* ++* ++* NOTE: ++* DSP image is based on LITTLE endian ++* ++********************************************************************************************/ ++unsigned int dslhal_support_gatherRateMessages(tidsl_t *ptidsl); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_byteSwap16() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* byteswap a short ++* ++* INPUT: ++* Return: NULL ++* ++********************************************************************************************/ ++ ++unsigned short dslhal_support_byteSwap16(unsigned short in16Bits); ++ ++/******************************************************************************************** ++* FUNCTION NAME: dslhal_support_byteSwap32() ++* ++********************************************************************************************* ++* DESCRIPTION: ++* byteswap a word ++* ++* INPUT: ++* Return: NULL ++* ++********************************************************************************************/ ++ ++unsigned int dslhal_support_byteSwap32(unsigned int in32Bits); ++ ++#endif /* Pairs #ifndef DSL_HAL_FUNCTIONDEFINES_H__ */ +diff -urN linux.old/drivers/atm/sangam_atm/dsl_hal_version.h linux.dev/drivers/atm/sangam_atm/dsl_hal_version.h +--- linux.old/drivers/atm/sangam_atm/dsl_hal_version.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/dsl_hal_version.h 2005-08-23 04:46:50.102842936 +0200 +@@ -0,0 +1,94 @@ ++#ifndef __SYSSW_VERSION_H__ ++#define __SYSSW_VERSION_H__ 1 ++ ++/******************************************************************************* ++* FILE PURPOSE: DSL Driver API functions for Sangam ++* ++******************************************************************************** ++* FILE NAME: dsl_hal_basicapi.c ++* ++* DESCRIPTION: ++* Contains basic DSL HAL APIs for Sangam ++* ++* (C) Copyright 2003-04, Texas Instruments, Inc. ++* History ++* Date Version Notes ++* 14May03 0.00.00 RamP Original Version Created ++* 14May03 0.00.01 RamP Initial Rev numbers inserted ++* 14May03 0.00.02 RamP Bumped version numbers for Dsl Hal ++* & dhalapp for alpha plus ++* 19May03 0.00.03 MCB Bumped dslhal version number ++* because of dependant changes ++* wrt. linux-nsp atm drivers. ++* 22May03 0.00.04 RamP Bumped dslhal & dhalapp buildnum ++* for inner/outer pair & DGASP code ++* 06Jun03 0.00.05 RamP Bumped up buildnum for LED, STM, ++* interrupt processing, statistics ++* and other pre-beta features ++* 09Jun03 0.00.06 JEB Fixed error in DHALAPP bugfix/buildnum ++* 09Jun03 0.00.07 RamP Bumped up buildnum for incremental ++* changes to apis, statistics, memory ++* fixes, parameter configurations ++* 11Jun03 0.00.08 RamP Bumped up buildnum for Co profile ++* free memory fix ++* 12Jun03 0.00.09 JEB Bumped version numbers for AR7 1.00 Beta ++* 02Jul03 0.00.10 ZT Bumped HAL version for overlay page ++* 18Jul03 0.00.11 RamP Bumped HAL version for analog diags ++* 22Jul03 0.00.12 JEB Bumped DHALAPP buildnum for analog diags ++* 31Jul03 0.00.13 RamP Bumped HAL version for engr. drop ++* 04Aug03 0.00.14 JEB Bumped HAL version buildnum for CHECKPOINT65 changes ++* Bumped LINUX version buildnum for CHECKPOINT65 changes ++* 06Aug03 0.00.15 MCB Bumped all version numbers in prep for AR7 1.0 R2 release for POTS. ++* 13Aug03 0.00.16 MCB Set rev id's for D3/R1.1 (ADSL2). ++* 21Aug03 0.00.17 JEB Bumped up build numbers for merge of code additions from D1 ++* 26Sep03 0.00.18 JEB Set rev id's for another D3/R1 (ADSL2). ++* 14Oct03 0.00.19 JEB Bumped Linux minor number and reset bugfix number for release. ++* Bumped build numbers on DSLHAL and DHALAPP for this checkpoint. ++* 14Oct03 0.00.20 JEB Bumped build numbers on DSLHAL and DHALAPP for CHECKPOINT15. ++* 21Oct03 0.00.21 JEB Bumped build number on DSLHAL for CHECKPOINT16. ++* 22Oct03 0.00.22 MCB Bumped all version numbers in support of D3R1 release. ++* 27Oct03 0.00.23 JEB Bumped build numbers on DSLHAL and DHALAPP for CHECKPOINT19. ++* Updated version for DSLAGENT to be 02.01.00.01 for ACT 2.1 R0. ++* 30Oct03 0.00.24 JEB Bumped bugfix number on LINUXATM Version for next release. ++* Bumped build numbers on DSLHAL and DHALAPP ++* 31Oct03 0.00.25 MCB Bumped all version numbers in support of D3R2 release. ++* 14Nov03 0.00.26 JEB Bumped build numbers on DSLHAL and DHALAPP ++* Changed version for DSLAGENT to be 02.00.01.01 for an ACT 2.0 R0 ++* 20Nov03 0.00.27 JEB Bumped build number on DSLHAL. ++* Changed version for DSLAGENT to be 02.00.02.00 for the next ACT 2.0 R2 ++* 21Nov03 0.00.28 MCB Bumped all version numbers in support of D3R2 release. ++* 21Nov03 0.00.29 JEB Bumped build numbers on DSLHAL and DHALAPP for D3-R0 drop on 11/21. ++* 16Dec03 0.00.30 JEB Bumped build numbers on DSLHAL and DHALAPP for CHECKPOINT31. ++* 21Dec03 0.00.31 MCB Bumped all version numbers in support of D3R2 release. ++* 05Jan04 0.00.32 JEB Bumped build numbers on DSLHAL and Linux ATM for CHECKPOINT 34. ++* 15Jan04 0.00.33 JEB Bumped build numbers on DSLHAL and Linux ATM for CHECKPOINT 36. ++* 26Jan04 0.00.34 JEB Changed Linux ATM version number to be 04.02.03.00. ++* 27Jan04 0.00.35 MCB Bumped all version numbers in support of D3R2 release. ++*******************************************************************************/ ++ ++/* Dsl Hal API Version Numbers */ ++#define DSLHAL_VERSION_MAJOR 03 ++#define DSLHAL_VERSION_MINOR 00 ++#define DSLHAL_VERSION_BUGFIX 06 ++#define DSLHAL_VERSION_BUILDNUM 00 ++#define DSLHAL_VERSION_TIMESTAMP 00 ++ ++/* dhalapp Adam2 Application Version Numbers */ ++#define DHALAPP_VERSION_MAJOR 03 ++#define DHALAPP_VERSION_MINOR 00 ++#define DHALAPP_VERSION_BUGFIX 05 ++#define DHALAPP_VERSION_BUILDNUM 00 ++ ++/* Linux ATM Driver Version Numbers */ ++#define LINUXATM_VERSION_MAJOR 04 ++#define LINUXATM_VERSION_MINOR 02 ++#define LINUXATM_VERSION_BUGFIX 04 ++#define LINUXATM_VERSION_BUILDNUM 00 ++ ++/* DSL Agent Version Numbers */ ++#define DSLAGENT_VERSION_MAJOR 02 ++#define DSLAGENT_VERSION_MINOR 00 ++#define DSLAGENT_VERSION_BUGFIX 02 ++#define DSLAGENT_VERSION_BUILDNUM 00 ++ ++#endif /* pairs with #ifndef __SYSSW_VERSION_H__ */ +diff -urN linux.old/drivers/atm/sangam_atm/ec_errors_cpaal5.h linux.dev/drivers/atm/sangam_atm/ec_errors_cpaal5.h +--- linux.old/drivers/atm/sangam_atm/ec_errors_cpaal5.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/ec_errors_cpaal5.h 2005-08-23 04:46:50.102842936 +0200 +@@ -0,0 +1,118 @@ ++/*************************************************************************** ++ Copyright(c) 2001, Texas Instruments Incorporated. All Rights Reserved. ++ ++ FILE: ec_errors.h ++ ++ DESCRIPTION: ++ This file contains definitions and function declarations for ++ error code support. ++ ++ HISTORY: ++ 14Dec00 MJH Added masking to EC_CLASS etc macros ++ 17Sep02 GSG Added HAL support (new class&devices) ++ 03Oct02 GSG Removed C++ style comments ++***************************************************************************/ ++#ifndef _INC_EC_ERRORS ++#define _INC_EC_ERRORS ++ ++/* ++ 31 - CRITICAL ++ 30-28 - CLASS (ie. DIAG, KERNEL, FLASH, etc) ++ 27-24 - INSTANCE (ie. 1, 2, 3, etc ) ++ 23-16 - DEVICE (ie. EMAC, IIC, etc) ++ 15-08 - FUNCTION (ie. RX, TX, INIT, etc) ++ 07-00 - ERROR CODE (ie. NO_BASE, FILE_NOT_FOUND, etc ) ++*/ ++ ++/*--------------------------------------------------------------------------- ++ Useful defines for accessing fields within error code ++---------------------------------------------------------------------------*/ ++#define CRITICAL_SHIFT 31 ++#define CLASS_SHIFT 28 ++#define INST_SHIFT 24 ++#define DEVICE_SHIFT 16 ++#define FUNCTION_SHIFT 8 ++#define ERROR_CODE_SHIFT 0 ++ ++#define CRITICAL_MASK 1 ++#define CLASS_MASK 0x07 ++#define DEVICE_MASK 0xFF ++#define INST_MASK 0x0F ++#define FUNCTION_MASK 0xFF ++#define ERROR_CODE_MASK 0xFF ++ ++#define EC_CLASS(val) ((val&CLASS_MASK) << CLASS_SHIFT) ++#define EC_DEVICE(val) ((val&DEVICE_MASK) << DEVICE_SHIFT) ++#define EC_INST(val) ((val&INST_MASK) << INST_SHIFT) ++#define EC_FUNC(val) ((val&FUNCTION_MASK) << FUNCTION_SHIFT) ++#define EC_ERR(val) ((val&ERROR_CODE_MASK) << ERROR_CODE_SHIFT) ++ ++/*--------------------------------------------------------------------------- ++ Operation classes ++---------------------------------------------------------------------------*/ ++#define EC_HAL EC_CLASS(0) ++#define EC_DIAG EC_CLASS(8) ++ ++/*--------------------------------------------------------------------------- ++ Device types ++---------------------------------------------------------------------------*/ ++#define EC_DEV_EMAC EC_DEVICE(1) ++#define EC_DEV_IIC EC_DEVICE(2) ++#define EC_DEV_RESET EC_DEVICE(3) ++#define EC_DEV_ATMSAR EC_DEVICE(4) ++#define EC_DEV_MEM EC_DEVICE(5) ++#define EC_DEV_DES EC_DEVICE(6) ++#define EC_DEV_DMA EC_DEVICE(7) ++#define EC_DEV_DSP EC_DEVICE(8) ++#define EC_DEV_TMR EC_DEVICE(9) ++#define EC_DEV_WDT EC_DEVICE(10) ++#define EC_DEV_DCL EC_DEVICE(11) ++#define EC_DEV_BBIF EC_DEVICE(12) ++#define EC_DEV_PCI EC_DEVICE(13) ++#define EC_DEV_XBUS EC_DEVICE(14) ++#define EC_DEV_DSLIF EC_DEVICE(15) ++#define EC_DEV_USB EC_DEVICE(16) ++#define EC_DEV_CLKC EC_DEVICE(17) ++#define EC_DEV_RAPTOR EC_DEVICE(18) ++#define EC_DEV_DSPC EC_DEVICE(19) ++#define EC_DEV_INTC EC_DEVICE(20) ++#define EC_DEV_GPIO EC_DEVICE(21) ++#define EC_DEV_BIST EC_DEVICE(22) ++#define EC_DEV_HDLC EC_DEVICE(23) ++#define EC_DEV_UART EC_DEVICE(24) ++#define EC_DEV_VOIC EC_DEVICE(25) ++/* 9.17.02 (new HAL modules) */ ++#define EC_DEV_CPSAR EC_DEVICE(0x1A) ++#define EC_DEV_AAL5 EC_DEVICE(0x1B) ++#define EC_DEV_AAL2 EC_DEVICE(0x1C) ++#define EC_DEV_CPMAC EC_DEVICE(0x1D) ++#define EC_DEV_VDMA EC_DEVICE(0x1E) ++#define EC_DEV_VLYNQ EC_DEVICE(0x1F) ++#define EC_DEV_CPPI EC_DEVICE(0x20) ++#define EC_DEV_CPMDIO EC_DEVICE(0x21) ++ ++/*--------------------------------------------------------------------------- ++ Function types ++---------------------------------------------------------------------------*/ ++#define EC_FUNC_READ_CONF EC_FUNC(1) ++#define EC_FUNC_INIT EC_FUNC(2) ++ ++/*--------------------------------------------------------------------------- ++ Error codes ++---------------------------------------------------------------------------*/ ++#define EC_CRITICAL (1< 03.00.00 datapump. ++//* 03/16/01 Nirmal Warke Added in TOKEN definition for crosstalk performance mods (CROSSTALK): IMP DEPENDENCIES - ++//* TEQ_AVG must be off and LEAKY_LMS must be on when CROSSTALK is on ++//* 03/21/01 Barnett Added support for ar0500lp, ar0500mp, ar0500dp, arv500lp, arv500mp, and arv500dp. ++//* 03/26/01 M. Seidl enabled 64pt IFFT for ap0500mb (Raptor+AD11, FDM) ++//* 03/28/01 J. Bergsagel Removed EXTERNBERT token (now use host intf. var. instead) ++//* 04/03/01 J. Bergsagel Removed condition of DSPDP_CHIPSET_GEN==5 for default defines ++//* Removed LEAKY_LMS token (assumed always 1) ++//* Removed OLAYDP_HOST token (assumed always 0) ++//* Removed RX_HPF token (assumed always 1) ++//* Removed TRIBRID token (not used any more) ++//* Removed FDD token (assumed always 1) ++//* Removed HW_DEC token (assumed always 1) ++//* Removed HW_TEQ token (assumed always 1) ++//* Removed HWRSDEC token (assumed always 1) ++//* Removed ILEC_AD11_ALCATEL337 token (assumed always 0) ++//* Removed ILEC_AD11_HDSLNOISEFIX token (assumed always 0) ++//* Removed ILEC_AD11_MODULATEPILOT token (assumed always 0) ++//* Removed ILEC_AD11_NEWINTERPOLATE token (assumed always 0) ++//* Removed ILEC_AD11_USTXHPF token (assumed always 0) ++//* Removed SWDI token (assumed always 1) ++//* Removed TD_AGC token (assumed always 1) ++//* Removed DSPDP_LEGACY_TARGET token (assumed always 0) ++//* Removed AD11_20, AD11_20NL and AD11_20_NEWPREC token (always 1) ++//* Removed AI token (assumed always 1) ++//* Removed ATUC token (assumed always 0) ++//* Removed EU token (assumed always 0) ++//* Removed EVM2 token (assumed always 0) ++//* Removed INTRPT_RUFUS token (assumed always 0) ++//* Removed MODPILOT token (assumed always 0) ++//* Removed SL and SL_EVM tokens (assumed always 0) ++//* Removed STBIFX token (assumed always 0) ++//* Removed STD token (assumed always 1) ++//* Removed SWDI_LOOPBACK token (assumed always 0) ++//* Removed TID token (assumed always 0) ++//* Removed TII token (assumed always 1) ++//* Removed TIPCI token (assumed always 1) ++//* Removed UDI token (assumed always 1) ++//* Removed DC_BIAS token (assumed always 1) ++//* 04/05/01 Barnett Added DSPDP_ prefix to tokens that originate ++//* in the public interface. ++//* 05/07/01 Jack Huang Removed DOUBLE_XMT_RATE token. ++//* 05/16/01 Barnett Added back in EXTERNBERT token in support ++//* of saving PMEM. ++//* 06/05/01 Jack Huang Fixed the rules for ar0500mp_debug target ++//* 04/23/01 M. Halleck Merge Astro Wu's DDC enhancements ++//* 06/05/01 M. Capps Changed DSP_DEBUG to ENHANCED_SERIAL_DEBUG ++//* 07/03/01 M. Capps Replaced ESD token with !DDC, added DEV_DEBUG ++//* 06/26/01 J. Bergsagel Removed all the old ap03... stuff ++//* Removed OLAYDP_HOST token (again) ++//* Removed CROSSTALK token (assumed always 1) ++//* Removed TEQ_AVG token (assumed always 0) ++//* Removed DE token (assumed always 1) ++//* Removed PVAT token and au0501cp target ++//* Removed FASTRETRAIN token (assumed always 0) ++//* 07/05/01 J. Bergsagel Changed PCIMASTER token to TC_ATM_PCIMASTER ++//* 07/20/01 Umesh Iyer Added ATMBERT token. ATMBERT is conditional on SWTC definition. if SWTC is 0 ++//* ATMBERT should be 0. Else it can be 0/1. Default 0. ++//* 07/23/01 J. Bergsagel Changed name from defines_u.h to dpsys_defines.h ++//* 07/24/01 Barnett Added support for build of $(TARGET)_diag mfgr'ing targets. ++//* 08/02/01 Michael Seidl renamed KAPIL token to !AD1X ++//* 08/02/01 Michael Seidl renamed GHS token to PMEMSAVE_GHS ++//* 08/03/01 S.Yim Added MFGR_DIAG token for afe diagnostic ++//* Added AFEDEV token for afe device driver ++//* Added DSPBIOSII token for dsp bios ++//* 09/21/01 Sameer Enable EXTERNBERT. Disable ATMBERT. ++//* 10/01/01 U.Dasgupta Turned off SMART_MARGIN for ap0500mb because of FECs/CRCs; ++//* 10/09/01 Barnett Added support for ar0500db. ++//* 10/12/01 Barnett Disable EXTERNBERT. ++//* 10/15/01 Barnett Turn off SMART_MARGIN. ++//* 11/07/01 Barnett Def'ed ISDN_DEBUG for all targets to avoid compiler warnings. ++//* Assumed defaul value is zero. ++//* 11/13/01 Barnett Reworked ar0500db_debug to build JTAG-bootable load. ++//* The equivalent production target should only be flash-bootable. ++//* 01/11/02 Yim Added TOKEN JTAG to build JTAG load ar0500db_diag. ++//* 01/23/02 U Iyer Added DEBUG_LOG token. Default value 0 ++//* 01/31/02 Barnett Added support for ar0700mp target. ++//* 02/04/02 S.Yim Added TOKEN JTAG to build JTAG load ar0500mp_diag ++//* 02/11/02 U Iyer Added MARGIN_DELTA_RETRAIN token. Default value 1 ++//* 05/15/02 Sameer V Enabled EXTERNBERT token for AR5 and AU5 platforms. EXTERNBERT is ++//* not supported on AR5H. ++//* 02/14/02 Barnett Don't ref the SWTC feature token if mfgr'ing diag target. ++//* 02/19/02 Yim Added support to build au0502db_diag target. ++//* 03/08/02 Nirmal Warke Added feature token HYBRID_SWITCH ++//* 03/15/02 U G Jani Turned ON Bitswap support for AU5I (au0502db) targets. ++//* 04/08/02 U G Jani Enabled NLNOISEADJSNR token for AU5I targets. ++//* 06/24/02 Seungmok Oh Added PERTONE_EQ token support for those targets: ++//* (ar0500mp_debug, au0502mp_debug, ar0500mp, au0502mp) ++//* 06/26/02 Mallesh Added DS_PWR_CUTBACK token. Default value 1. ++//* 06/27/02 Mallesh Changed default value of DS_PWR_CUTBACK token to 0. ++//* 06/29/02 U.Dasgupta Token cleanup: Removed ISDN_DEBUG token ++//* 04/29/02 Mannering Remove EIGHTBITSRAM, Combined DOUBLEBUFFER with ++//* BITSWAP, added FPGA token ++//* 05/03/02 Mannering cleanup token changed by the new routine names ++//* 05/06/02 Mannering Add tokens OUTBAND and INBAND for codec commands ++//* If both OUTBAND and INBAND are 0 codec register are ++//* memory mapped. ++//* 05/29/2002 S.Yim Removed AD1X, AFEDEV ++//* 08/31/2002 Paul Hunt Added PERTONE_EQ and HYBRID_SWITCH for ar0700mp ++//* 09/12/2002 Paul Hunt Added support for ar0700db target. ++//* 08/07/2002 U.Dasgupta Turned off MARGIN_DELTA_RETRAIN feature for ISDN platforms ++//* 11/14/2002 Paul Hunt Merged AX5 MR6 PC modifications into AR7 codebase, specifically ++//* turned off MARGIN_DELTA_RETRAIN feature for ar0700db target ++//* 08/26/2002 N. Warke Added DUAL_TEQ token. Active only for Ax7 target ++//* 09/26/2002 Mannering Add token CODEC_EMU for codec emulator board ++//* 10/15/2002 Iyer/Molla Added DMT_BIS token for DELT support ++//* 10/21/2002 A. Redfern Added PHY_EC_ENABLE and PHY_PATH_ENABLE tokens ++//* 10/23/2002 A. Redfern Removed LINE_DIAG token ++//* 10/28/2002 J. Bergsagel Cleaned up old targets and cleaned up the token list ++//* 10/30/2002 A. Redfern Added PHY_TDW_ENABLE ++//* 11/01/2002 A. Redfern Removed SMART_MARGIN token ++//* 11/01/2002 Mustafa Turned on SPECTRAL_SHAPING features for Lucent AnyMedia O.69 Interop. ++//* 11/15/2002 Yim/Mannering Added CODEC_EMU token for analog emulation board specifics ++//* 11/15/2002 Iyer/Molla Added DEBUG_DELT and MEM_STR token to support DELT debug ++//* 12/27/2002 Sameer V Added ATM_TC_HW token for Sangam. ++//* 01/06/2003 J. Bergsagel Added default values for NLNOISEADJSNR, ARTT and DS_PWR_CUTBACK ++//* 01/07/2003 S.Yim Modified ar0700db_diag target to turn on ISDN token ++//* 01/22/2003 J. Bergsagel Added back in defines for the debug targets. ++//* 01/21/2003 MCB Implemented Ax7 UNIT-MODULE modular software framework. ++//* 01/31/2003 J. Bergsagel Made debug targets to be for the FPGA platform; non-debug for Sangam. ++//* Turned off DUAL_TEQ, PHY_EC_ENABLE and PHY_PATH_ENABLE by default ++//* for the Sangam (non-debug) targets. ++//* Turned off OLAYDP token by default. ++//* Turned off SWTC and turned on ATM_TC_HW by default for Sangam targets. ++//* 01/29/2003 Sameer V Added ATMBERT_HW token for Sangam. ++//* 02/04/2003 D. Mannering Added CO_PROFILE token ++//* 02/19/2003 Sameer V Added back EXTERNBERT token for ar0700mp_dp and ar0700db_dp targets. ++//* Disabled EXTERNBERT for debug target since it is not supported on the ++//* FPGA platform. ++//* 02/21/2003 A. Redfern Turned off OAM_EOC, AOC and BITSWAP (until memory issues are resolved). ++//* Turned on DUAL_TEQ, PHY_PATH_ENABLE and PHY_EC_ENABLE. ++//* 02/21/2003 D. Mannering Added DEBUG_DUMP. ++//* 03/06/2003 J. Bergsagel Cleaned up tokens for each target and switched diag targets ++//* over to the Sangam platform (instead of the FPGA platform). ++//* 03/07/2003 J. Bergsagel Cleaned up TC and BERT tokens ++//* 03/11/2003 J. Bergsagel Turned on AOC and BITSWAP for Sangam POTS and ISDN targets. ++//* 03/20/2003 Mallesh Added SHALF token. ++//* 03/24/2003 F. Mujica Enable hybrid selection ++//* 03/26/2003 A. Redfern Removed PMEMSAVE_GHS (always = 1). ++//* 04/08/2003 F. Mujica Renamed HYBRID_SWITCH token to PHY_HYB_ENABLE ++//* 04/08/2003 J. Bergsagel Turned off PHY_HYB_ENABLE for _debug targets (FPGA board builds) ++//* 04/09/2003 J. Bergsagel Turned on OLAYDP only for ar0700mp and ar0700db. ++//* Turned on AOC, BITSWAP, and OAM_EOC for ar0700mp and ar0700db. ++//* 04/09/2003 J. Bergsagel Corrected name "PHY_HYB_SELECT" to "PHY_HYB_ENABLE" ++//* 04/15/2003 A. Redfern Turned on ECI_PULSECOM_INTEROP because phase optimization was enabled. ++//* 05/05/2003 D. Mannering Review Comments - turn on AOC, EXTERNBERT, SHALF, for ar0700mp; amd ++//* turn on AOC for ar0700db ++//* 05/11/2003 Prashant S Added DMT_BIS token for AR7 Soft DI work ++//* 05/13/2003 J. Bergsagel Turned on IMPROVED_STAT_SUPPORT_06_03_00 by default for necessary statistics ++//* 05/15/2003 J. Bergsagel Turned off CO_PROFILE for diag targets. ++//* 05/27/2003 U.Dasgupta Added NLNOISEADJSNR_EC token for ISDN - to take care of non-linear noise ++//* (from ISDN splitter) compensation. ++//* 06/02/2003 Z. Yang Added PHY_NDIAG_ENABLE token. ++//* 06/02/2003 Z. Yang Added COMB_LINEDIAG_ENABLE token. ++//* 06/05/2003 P. Hunt Turned on ATUC_CLEARDOWN_CHANGE token for all targets. ++//* 06/05/2003 Mallesh Turned on CENTILLIUM_VENDORID_AND_TXRATE_CHNG to enable logging the vendor ID ++//* for centillium and litespan ++//* 06/05/2003 U.Dasgupta Turned on SHALF token for ISDN. ++//* 06/06/2003 U.Dasgupta Turned on G.hs nonstandard field token for ar0700db target. ++//* 06/12/2003 J. Bergsagel Changed *_debug targets to be for JTAG=1 instead of FPGA targets ++//* IMPORTANT: For non-JTAG cases, "JTAG" should be undefined. ++//* Therefore, "JTAG" should not have a default case at the bottom (JTAG 0) ++//* 06/18/2003 A. Redfern Turned on spectral shaping token for all targets. ++//* 06/23/2003 J. Bergsagel Turned off GHS_NON_STD_FIELD token for ar0700db until bugs are fixed. ++//* 06/23/2003 U G Jani Undid the above change since the bug is fixed. ++//* 06/27/2003 Mallesh Removed all the interop tokens which are no longer required. ++//* 08/20/2003 J. Bergsagel Added default value for OVHD_PMDTEST_PARA and put default section ++//* tokens in alphabetical order. ++//* 10/09/2003 Hanyu Liu Defined token ADSL2_1BIT_TONE to support Rx one bit constellation. ++//* 10/12/2003 Hanyu Liu Defined token ADSL2_BSWP for bitswap. ++//* 10/20/2003 Xiaohui Li Added READSL2_ENABLE token. ++//* 12/01/2003 Seungmok Oh Added TXDF2B_PROFILING token, which is active only for POTS target. ++//* 12/09/2003 Jack Huang Turned on GHS_NON_STD_FIELD support for AR7 POTS targets ++//* 12/16/2003 Mustafa T. Added the necessary definitions for diag target. ++//***************************************************************************************************** ++//* ++//* The default flag settings are: ++//* ++//* -dATUC=1 -dSTD=0 -dISDN=0 -dTIPCI=0 -dTID=0 -dTII=0 -dAI=0 ++//* -dEVM2=0 -dEU=0 -dSL=0 -dSL_EVM=1 -dGLITE=0 ++//* ++//* and are set after all the per-suffix options have had a chance to ++//* set them. Each flag is only set if it has not previously been set, so ++//* per-suffix settings can override defaults, and command-line defines can ++//* override per-suffix settings. ++//* ++//***************************************************************************** ++ ++ ++//* =========================================================================== ++//* Suffix codes ++//* The command-line can include -dOBJSFX_xxx to get a flag set ++//* instead of explicitly setting each flag on each CC/ASM command-line. ++//* and the object suffix will control the settings of "feature" constants. ++//* =========================================================================== ++// ++//* =========================================================================== ++// Flag settings for new suffixes (in alphabetical order of suffix) ++// Each suffix has to specify only those flags which differ from the ++// default settings. ++//* =========================================================================== ++// NOTE: Try to keep feature flags in alphabetical order to ease maintenance. ++//* =========================================================================== ++//* ++ ++#define CHIPSET_ID_UNKN '?' ++#define CHIPSET_ID_AH 'H' ++#define CHIPSET_ID_AP 'P' ++#define CHIPSET_ID_AR 'R' ++#define CHIPSET_ID_ARV 'R' ++#define CHIPSET_ID_AT 'T' ++#define CHIPSET_ID_AU 'U' ++ ++#define CHIPSET_ID2_GENERIC '0' ++#define CHIPSET_ID2_ARV 'R' ++ ++ #define DSPDP_IMAGE_ID_STANDARD(code) ( \ ++ STANDARD_is_MULTIMODE(code) ? "M" : \ ++ STANDARD_is_GDMT(code) ? "D" : \ ++ STANDARD_is_GLITE(code) ? "L" : \ ++ STANDARD_is_T1413(code) ? "T" : "_") ++ ++ #define DSPDP_IMAGE_ID_SERVICE(code) ( \ ++ SERVICE_is_POTS(code) ? "P" : \ ++ SERVICE_is_ISDN_ANNEXB(code) ? "B" : \ ++ SERVICE_is_ISDN_ANNEXC(code) ? "C" : \ ++ SERVICE_is_ISDN_PROP(code) ? "I" : "") ++ ++// Bit-codes for feature byte in new version. ++// ++// 0000 0000 ++// |||| |||| ++// |||| |||+ -- POTS ++// |||| ||+---- ISDN_ANNEXB ++// |||| |+----- ISDN_ANNEXC ++// |||| +------ ISDN_PROP ++// |||+-------- ++// ||+--------- GHS ++// |+---------- GLITE ++// +----------- T1413 ++// ++// ++#define FEATURE_BIT_T1413 0x80 ++#define FEATURE_BIT_GLITE 0x40 ++#define FEATURE_BIT_GHS 0x20 ++#define FEATURE_BIT_ISDN_PROP 0x08 ++#define FEATURE_BIT_ISDN_ANNEXC 0x04 ++#define FEATURE_BIT_ISDN_ANNEXB 0x02 ++#define FEATURE_BIT_POTS 0x01 ++ ++#define STANDARD_BITS_MASK (FEATURE_BIT_T1413 | FEATURE_BIT_GLITE | FEATURE_BIT_GHS) ++#define STANDARD_BITS_T1413 FEATURE_BIT_T1413 ++#define STANDARD_BITS_GHS FEATURE_BIT_GHS ++#define STANDARD_BITS_GLITE (FEATURE_BIT_GLITE | FEATURE_BIT_GHS) ++#define STANDARD_BITS_GDMT (STANDARD_BITS_T1413 | STANDARD_BITS_GHS) ++#define STANDARD_BITS_MULTIMODE (STANDARD_BITS_T1413 | STANDARD_BITS_GLITE | STANDARD_BITS_GDMT) ++ ++#define SERVICE_BIT_ISDN_ANNEXB FEATURE_BIT_ISDN_ANNEXB ++#define SERVICE_BIT_ISDN_ANNEXC FEATURE_BIT_ISDN_ANNEXC ++#define SERVICE_BIT_ISDN_PROP FEATURE_BIT_ISDN_PROP ++#define SERVICE_BIT_POTS FEATURE_BIT_POTS ++ ++// ++// Debug new-style suffixes ++// ++// ++ ++#if defined(OBJSFX_ar0700db_debugobj) ++#ifndef OBJSFX_ar0700dbobj ++#define OBJSFX_ar0700dbobj 1 ++#endif ++// Here, in alphabetic order, are the feature tokens that ++// distinguish this suffix from its non-_debug partner: ++// (All other tokens from the non-_debug partner that are non-conflicting will also be picked up) ++ ++#ifndef JTAG ++#define JTAG 1 ++#endif ++ ++#elif defined(OBJSFX_ar0700mp_debugobj) ++#ifndef OBJSFX_ar0700mpobj ++#define OBJSFX_ar0700mpobj 1 ++#endif ++// Here, in alphabetic order, are the feature tokens that ++// distinguish this suffix from its non-_debug partner: ++// (All other tokens from the non-_debug partner that are non-conflicting will also be picked up) ++ ++#ifndef ADSL2_BSWP ++#define ADSL2_BSWP 1 ++#endif ++#ifndef AOC ++#define AOC 1 ++#endif ++#ifndef BITSWAP ++#define BITSWAP 1 ++#endif ++#ifndef DEBUG_ADSL2 ++#define DEBUG_ADSL2 0 ++#endif ++#ifndef DEBUG_LOG ++#define DEBUG_LOG 0 ++#endif ++#ifndef GHS_NON_STD_FIELD ++#define GHS_NON_STD_FIELD 1 ++#endif ++#ifndef JTAG ++#define JTAG 1 ++#endif ++#endif // end of the series of "#elif defined" for debug targets ++ ++ ++// ++// Standard new-style suffixes for operational and mfgr'ing diag. ++// ++ ++#if defined(OBJSFX_ar0700dbobj) ++#define CHIPSET_AR07 1 ++#define PLATFORM_AR0700 1 ++#define DSPDP_CHIPSET_ID CHIPSET_ID_AR ++#define DSPDP_CHIPSET_ID2 CHIPSET_ID2_GENERIC ++#define DSPDP_CHIPSET_GEN 7 ++#define DSPDP_HARDWARE_REV1 '0' ++#define DSPDP_HARDWARE_REV2 '0' ++#define DSPDP_FEATURE_CODE (STANDARD_BITS_GDMT|SERVICE_BIT_ISDN_ANNEXB) ++#ifndef AOC ++#define AOC 1 ++#endif ++// ATM_TC_HW and SWTC are mutually exclusive ++#ifndef ATM_TC_HW ++#define ATM_TC_HW 1 ++#endif ++#ifndef SWTC ++#define SWTC 0 ++#endif ++#ifndef BITSWAP ++#define BITSWAP 1 ++#endif ++#ifndef EXTERNBERT ++#define EXTERNBERT 0 ++#endif ++#ifndef GHS_NON_STD_FIELD ++#define GHS_NON_STD_FIELD 1 ++#endif ++#ifndef MARGIN_DELTA_RETRAIN ++#define MARGIN_DELTA_RETRAIN 0 ++#endif ++#ifndef NLNOISEADJSNR_EC ++#define NLNOISEADJSNR_EC 1 ++#endif ++#ifndef OLAYDP ++#define OLAYDP 1 ++#endif ++#ifndef SHALF ++#define SHALF 1 ++#endif ++ ++ ++#elif defined(OBJSFX_ar0700db_diagobj) ++#define CHIPSET_AR07 1 ++#define PLATFORM_AR0700 1 ++#define DSPDP_CHIPSET_ID CHIPSET_ID_AR ++#define DSPDP_CHIPSET_ID2 CHIPSET_ID2_GENERIC ++#define DSPDP_CHIPSET_GEN 7 ++#define DSPDP_HARDWARE_REV1 '0' ++#define DSPDP_HARDWARE_REV2 '0' ++#define DSPDP_FEATURE_CODE (STANDARD_BITS_GDMT|SERVICE_BIT_ISDN_ANNEXB) ++#ifndef AOC ++#define AOC 0 ++#endif ++// ATM_TC_HW and SWTC are mutually exclusive (or both must be off) ++#ifndef ATM_TC_HW ++#define ATM_TC_HW 0 ++#endif ++#ifndef SWTC ++#define SWTC 0 ++#endif ++#ifndef BITSWAP ++#define BITSWAP 0 ++#endif ++#ifndef CO_PROFILE ++#define CO_PROFILE 0 ++#endif ++#ifndef MARGIN_DELTA_RETRAIN ++#define MARGIN_DELTA_RETRAIN 0 ++#endif ++#ifndef MFGR_DIAG ++#define MFGR_DIAG 1 ++#endif ++#ifndef OAM_EOC ++#define OAM_EOC 0 ++#endif ++#ifndef OLAYDP ++#define OLAYDP 0 ++#endif ++#ifndef SNR_UPDATE ++#define SNR_UPDATE 0 ++#endif ++ ++#elif defined(OBJSFX_ar0700mpobj) ++#define CHIPSET_AR07 1 ++#define PLATFORM_AR0700 1 ++#define DSPDP_CHIPSET_ID CHIPSET_ID_AR ++#define DSPDP_CHIPSET_ID2 CHIPSET_ID2_GENERIC ++#define DSPDP_CHIPSET_GEN 7 ++#define DSPDP_HARDWARE_REV1 '0' ++#define DSPDP_HARDWARE_REV2 '0' ++#define DSPDP_FEATURE_CODE (STANDARD_BITS_MULTIMODE|SERVICE_BIT_POTS) ++#ifndef AOC ++#define AOC 1 ++#endif ++// ATM_TC_HW and SWTC are mutually exclusive ++#ifndef ADSL2_1BIT_TONE ++#define ADSL2_1BIT_TONE 0 ++#endif ++#ifndef ADSL2_BSWP ++#define ADSL2_BSWP 1 ++#endif ++#ifndef ATM_TC_HW ++#define ATM_TC_HW 1 ++#endif ++#ifndef SWTC ++#define SWTC 0 ++#endif ++#ifndef BITSWAP ++#define BITSWAP 1 ++#endif ++#ifndef EXTERNBERT ++#define EXTERNBERT 0 ++#endif ++#ifndef OLAYDP ++#define OLAYDP 1 ++#endif ++#ifndef DMT_BIS ++#define DMT_BIS 1 ++#endif ++#ifndef SHALF ++#define SHALF 1 ++#endif ++#ifndef MEM_STR ++#define MEM_STR 0 ++#endif ++#ifndef DS_LOOP_BACK ++#define DS_LOOP_BACK 0 ++#endif ++#ifndef LOOP_BACK_DEBUG ++#define LOOP_BACK_DEBUG 0 ++#endif ++#ifndef US_LOOP_BACK ++#define US_LOOP_BACK 0 ++#endif ++#ifndef OVHD_PMDTEST_PARA ++#define OVHD_PMDTEST_PARA 0 ++#endif ++#ifndef DS_RX_CODEWORD ++#define DS_RX_CODEWORD 1 ++#endif ++#ifndef READSL2_ENABLE ++#define READSL2_ENABLE 1 ++#endif ++#ifndef GHS_NON_STD_FIELD ++#define GHS_NON_STD_FIELD 1 ++#endif ++ ++#elif defined(OBJSFX_ar0700mp_diagobj) ++#define CHIPSET_AR07 1 ++#define PLATFORM_AR0700 1 ++#define DSPDP_CHIPSET_ID CHIPSET_ID_AR ++#define DSPDP_CHIPSET_ID2 CHIPSET_ID2_GENERIC ++#define DSPDP_CHIPSET_GEN 7 ++#define DSPDP_HARDWARE_REV1 '0' ++#define DSPDP_HARDWARE_REV2 '0' ++#define DSPDP_FEATURE_CODE (STANDARD_BITS_MULTIMODE|SERVICE_BIT_POTS) ++#ifndef ADSL2_BSWP ++#define ADSL2_BSWP 0 ++#endif ++#ifndef AOC ++#define AOC 0 ++#endif ++// ATM_TC_HW and SWTC are mutually exclusive (or both must be off) ++#ifndef ATM_TC_HW ++#define ATM_TC_HW 0 ++#endif ++#ifndef SWTC ++#define SWTC 0 ++#endif ++#ifndef BITSWAP ++#define BITSWAP 0 ++#endif ++#ifndef CO_PROFILE ++#define CO_PROFILE 0 ++#endif ++#ifndef DMT_BIS ++#define DMT_BIS 0 ++#endif ++#ifndef MARGIN_DELTA_RETRAIN ++#define MARGIN_DELTA_RETRAIN 0 ++#endif ++#ifndef MFGR_DIAG ++#define MFGR_DIAG 1 ++#endif ++#ifndef OAM_EOC ++#define OAM_EOC 0 ++#endif ++#ifndef OLAYDP ++#define OLAYDP 0 ++#endif ++#ifndef SNR_UPDATE ++#define SNR_UPDATE 0 ++#endif ++#ifndef US_CRC_RETRAIN ++#define US_CRC_RETRAIN 0 ++#endif ++#ifndef ADSL2_BSWP ++#define ADSL2_BSWP 0 ++#endif ++#ifndef DMT_BIS ++#define DMT_BIS 0 ++#endif ++#ifndef DS_RX_CODEWORD ++#define DS_RX_CODEWORD 0 ++#endif ++ ++#else ++#define DSPDP_CHIPSET_ID CHIPSET_ID_UNKN ++#define DSPDP_CHIPSET_ID2 CHIPSET_ID2_GENERIC ++#define DSPDP_CHIPSET_GEN 0 ++#define DSPDP_HARDWARE_REV1 '0' ++#define DSPDP_HARDWARE_REV2 '0' ++#define DSPDP_FEATURE_CODE 0 ++#endif ++ ++// For use in checking the code in drivers -- indented to avoid .h->.ah ++ #define STANDARD_is_T1413(code) (!(((code) & STANDARD_BITS_MASK) ^ STANDARD_BITS_T1413)) ++ #define STANDARD_is_GLITE(code) (!(((code) & STANDARD_BITS_MASK) ^ STANDARD_BITS_GLITE)) ++ #define STANDARD_is_GHS(code) (((code) & STANDARD_BITS_MASK) & STANDARD_BITS_GHS) ++ #define STANDARD_is_GDMT(code) (!(((code) & STANDARD_BITS_MASK) ^ (STANDARD_BITS_T1413 | STANDARD_BITS_GHS))) ++ #define STANDARD_is_MULTIMODE(code) (!(((code) & STANDARD_BITS_MASK) ^ (STANDARD_BITS_T1413 | STANDARD_BITS_GLITE | STANDARD_BITS_GDMT))) ++ #define SERVICE_is_POTS(code) ((code) & SERVICE_BIT_POTS) ++ #define SERVICE_is_ISDN_ANNEXB(code) ((code) & SERVICE_BIT_ISDN_ANNEXB) ++ #define SERVICE_is_ISDN_ANNEXC(code) ((code) & SERVICE_BIT_ISDN_ANNEXC) ++ #define SERVICE_is_ISDN_PROP(code) ((code) & SERVICE_BIT_ISDN_PROP) ++ ++#define STANDARD_T1413 (!((DSPDP_FEATURE_CODE & STANDARD_BITS_MASK) ^ STANDARD_BITS_T1413)) ++#define STANDARD_GLITE (!((DSPDP_FEATURE_CODE & STANDARD_BITS_MASK) ^ STANDARD_BITS_GLITE)) ++#define STANDARD_GHS ((DSPDP_FEATURE_CODE & STANDARD_BITS_MASK) & STANDARD_BITS_GHS) ++#define STANDARD_GDMT (!((DSPDP_FEATURE_CODE & STANDARD_BITS_MASK) ^ (STANDARD_BITS_T1413 | STANDARD_BITS_GHS))) ++#define STANDARD_MULTIMODE (!((DSPDP_FEATURE_CODE & STANDARD_BITS_MASK) ^ (STANDARD_BITS_T1413 | STANDARD_BITS_GLITE | STANDARD_BITS_GDMT))) ++ ++#define SERVICE_POTS (DSPDP_FEATURE_CODE & SERVICE_BIT_POTS) ++#define SERVICE_ISDN_ANNEXB (DSPDP_FEATURE_CODE & SERVICE_BIT_ISDN_ANNEXB) ++#define SERVICE_ISDN_ANNEXC (DSPDP_FEATURE_CODE & SERVICE_BIT_ISDN_ANNEXC) ++#define SERVICE_ISDN_PROP (DSPDP_FEATURE_CODE & SERVICE_BIT_ISDN_PROP) ++#define SERVICE_ISDN (SERVICE_ISDN_ANNEXB | SERVICE_ISDN_ANNEXC | SERVICE_ISDN_PROP) ++ ++ ++// ++// Backwards compatibility with old tokens ++// ++ ++#if (SERVICE_POTS) ++#ifndef ISDN ++#define ISDN 0 ++#endif ++#endif ++ ++#if (SERVICE_ISDN_ANNEXB | SERVICE_ISDN_PROP) ++#ifndef ISDN ++#define ISDN 1 ++#endif ++#endif ++ ++ ++// ++//* =========================================================================== ++// More Default settings ++//* =========================================================================== ++// ++ ++// ++// BEGIN Could automatically generate showdefs code ++// ++#ifndef AOC ++#define AOC 1 ++#endif ++#ifndef ARTT ++#define ARTT 0 ++#endif ++#ifndef ATMBERT ++#define ATMBERT 0 ++#endif ++// ATM_TC_HW and SWTC are mutually exclusive ++#ifndef ATM_TC_HW ++#define ATM_TC_HW 1 ++#endif ++#if ATM_TC_HW ++#ifndef ATMBERT_HW ++#define ATMBERT_HW 1 ++#endif ++#ifndef SWTC ++#define SWTC 0 ++#endif ++#else // else case for #if ATM_TC_HW ++#ifndef ATMBERT_HW ++#define ATMBERT_HW 0 ++#endif ++#ifndef SWTC ++#define SWTC 1 ++#endif ++#endif // end of #if ATM_TC_HW ++#ifndef ATM_TC_PATH1_ON ++#define ATM_TC_PATH1_ON 0 ++#endif ++#ifndef BITSWAP ++#define BITSWAP 1 ++#endif ++#ifndef COMB_LINEDIAG_ENABLE ++#define COMB_LINEDIAG_ENABLE 0 ++#endif ++#ifndef CODEC_EMU ++#define CODEC_EMU 0 ++#endif ++#ifndef CO_PROFILE ++#define CO_PROFILE 1 ++#endif ++#ifndef DDC ++#define DDC 0 ++#endif ++#ifndef DEBUG_ADSL2 ++#define DEBUG_ADSL2 0 ++#endif ++#ifndef DEBUG_DUMP ++#define DEBUG_DUMP 0 ++#endif ++#ifndef DEBUG_LOG ++#define DEBUG_LOG 0 ++#endif ++#ifndef DEV_DEBUG ++#define DEV_DEBUG 0 ++#endif ++#ifndef DS_LOOP_BACK ++#define DS_LOOP_BACK 0 ++#endif ++#ifndef DS_RX_CODEWORD ++#define DS_RX_CODEWORD 1 ++#endif ++#ifndef LOOP_BACK_DEBUG ++#define LOOP_BACK_DEBUG 0 ++#endif ++#ifndef US_LOOP_BACK ++#define US_LOOP_BACK 0 ++#endif ++#ifndef DPLL_MODE ++#define DPLL_MODE 0 ++#endif ++#ifndef DSPBIOSII ++#define DSPBIOSII 0 ++#endif ++#ifndef DMT_BIS ++#define DMT_BIS 1 ++#endif ++#ifndef ADSL2_1BIT_TONE ++#define ADSL2_1BIT_TONE 0 ++#endif ++#ifndef ADSL2_BSWP ++#define ADSL2_BSWP 1 ++#endif ++#ifndef MEM_STR ++#define MEM_STR 0 ++#endif ++#ifndef DS_PWR_CUTBACK ++#define DS_PWR_CUTBACK 0 ++#endif ++#ifndef DUAL_TEQ ++#define DUAL_TEQ 1 ++#endif ++#ifndef EXTERNBERT ++#define EXTERNBERT 0 ++#endif ++#ifndef FPGA ++#define FPGA 0 ++#endif ++#ifndef INBAND ++#define INBAND 0 ++#endif ++#ifndef ISDN ++#define ISDN 0 ++#endif ++#ifndef ISDN_DEBUG ++#define ISDN_DEBUG 0 ++#endif ++#ifndef LINE_DIAG ++#define LINE_DIAG 1 ++#endif ++#ifndef LOOP_BACK_DEBUG ++#define LOOP_BACK_DEBUG 0 ++#endif ++#ifndef MANUFACTURING_TESTS ++#define MANUFACTURING_TESTS 0 ++#endif ++#ifndef MARGIN_DELTA_RETRAIN ++#define MARGIN_DELTA_RETRAIN 1 ++#endif ++#ifndef MEM_STR ++#define MEM_STR 0 ++#endif ++#ifndef MFGR_DIAG ++#define MFGR_DIAG 0 ++#endif ++#ifndef NLNOISEADJSNR ++#define NLNOISEADJSNR 0 ++#endif ++#ifndef NLNOISEADJSNR_EC ++#define NLNOISEADJSNR_EC 0 ++#endif ++#ifndef NTR_MODE ++#define NTR_MODE 0 ++#endif ++#ifndef OAM_EOC ++#define OAM_EOC 1 ++#endif ++#ifndef OLAYDP ++#define OLAYDP 0 ++#endif ++#ifndef OLAYDP_EMIF ++#define OLAYDP_EMIF 0 ++#endif ++#ifndef OLAYDP_2STEP ++#define OLAYDP_2STEP 0 ++#endif ++#ifndef OLAYDP_PCI ++#define OLAYDP_PCI 0 ++#endif ++#ifndef OUTBAND ++#define OUTBAND 0 ++#endif ++#ifndef OVHD_PMDTEST_PARA ++#define OVHD_PMDTEST_PARA 0 ++#endif ++#ifndef PERTONE_EQ ++#define PERTONE_EQ 0 ++#endif ++#ifndef PHY_EC_ENABLE ++#define PHY_EC_ENABLE 1 ++#endif ++#ifndef PHY_HYB_ENABLE ++#define PHY_HYB_ENABLE 1 ++#endif ++#ifndef PHY_NDIAG_ENABLE ++#define PHY_NDIAG_ENABLE 0 ++#endif ++#ifndef PHY_PATH_ENABLE ++#define PHY_PATH_ENABLE 1 ++#endif ++#ifndef PHY_TDW_ENABLE ++#define PHY_TDW_ENABLE 0 ++#endif ++#ifndef TC_ATM_PCIMASTER ++#define TC_ATM_PCIMASTER 0 ++#endif ++#ifndef SEPARATE_TX_RX_BUFFERS ++#define SEPARATE_TX_RX_BUFFERS 0 ++#endif ++#ifndef SHALF ++#define SHALF 0 ++#endif ++#ifndef SPECTRAL_SHAPING ++#define SPECTRAL_SHAPING 1 ++#endif ++#ifndef SNR_UPDATE ++#define SNR_UPDATE 1 ++#endif ++#ifndef TC_DEBUG ++#define TC_DEBUG 0 ++#endif ++#ifndef TC_LOOPBACK ++#define TC_LOOPBACK 0 ++#endif ++#ifndef TESTMODE ++#define TESTMODE 0 ++#endif ++#ifndef TRELLIS ++#define TRELLIS 1 ++#endif ++#ifndef TXDF2B_PROFILING ++#if (SERVICE_POTS & (!MFGR_DIAG) & (CO_PROFILE)) ++#define TXDF2B_PROFILING 1 ++#else ++#define TXDF2B_PROFILING 0 ++#endif ++#endif ++#ifndef US_CRC_RETRAIN ++#define US_CRC_RETRAIN 1 ++#endif ++#ifndef US_LOOP_BACK ++#define US_LOOP_BACK 0 ++#endif ++#ifndef USB ++#define USB 0 ++#endif ++#ifndef READSL2_ENABLE ++#define READSL2_ENABLE 1 ++#endif ++ ++// Interop tokens ++#ifndef GHS_NON_STD_FIELD ++#define GHS_NON_STD_FIELD 0 ++#endif ++#ifndef LUCENT_ANYMEDIA_ENIATT_INTEROP ++#define LUCENT_ANYMEDIA_ENIATT_INTEROP 0 ++#endif ++ ++ ++// ++// END Could automatically generate showdefs code ++// ++#if DSPDP_FEATURE_CODE ++#else ++// Unrecognized_suffix____check_spelling ++#endif ++// ++// LNK_CMD is set when running CPP to generate lnk_cpe.cmd file ++// -- the linker is not happy when it sees C code show up in the ++// result! ++// ++#ifndef LNK_CMD ++extern int compile_happy; // Keep the compiler from complaining about an empty file ++#endif ++ ++#endif ++ +diff -urN linux.old/drivers/atm/sangam_atm/env_def_typedefs.h linux.dev/drivers/atm/sangam_atm/env_def_typedefs.h +--- linux.old/drivers/atm/sangam_atm/env_def_typedefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/env_def_typedefs.h 2005-08-23 04:46:50.104842632 +0200 +@@ -0,0 +1,228 @@ ++#ifndef __ENV_DEF_TYPEDEFS_H__ ++#define __ENV_DEF_TYPEDEFS_H__ 1 ++ ++/******************************************************************************* ++* FILE PURPOSE: Define data types for C and TMS320C6x C compilers ++******************************************************************************** ++* ++* FILE NAME: dpsys_typedefs.h ++* ++* DESCRIPTION: ++* This file contains the main typedefs that we need. ++* ++* HISTORY: ++* ++* 03/11/97 Bob Lee Created ++* 03/13/97 Chishtie ++* 03/14/97 Bob Lee Format change to meet "Engineering Model ++* - System Architucture Specification" ++* Rev AP3. Jan. 29, 1997 ++* 07/21/00 Barnett Moved many common typedefs from ++* host i/f header file to here. ++* 03/30/01 Barnett Mod's per driver team feedback. ++* Some tokens cannot be def'ed ++* if _WINDEF_ is def'ed. ++* 04/05/01 Barnett Added DSPDP_ prefix to tokens that originate ++* in the public interface. ++* 06/01/01 J. Bergsagel Modified to add standard typedefs ++* 07/25/01 J. Bergsagel Changed name from typedefs.h to dpsys_typedefs.h ++* 07/30/01 J. Bergsagel Moved typedefs that were conflicting with Windows ++* driver software to the "#ifndef _WINDEF_" section. ++* 08/09/01 S. Yim Moved FALSE/TRUE definitions from ctl_interface_u.h ++* (conflict with BIOS/std.h) ++* 09/03/01 S. Yim Do not include typedef char and float if _STD defined ++* (conflict with BIOS/std.h) ++* 01/21/03 MCB Implemented Ax7 UNIT-MODULE modular software framework. ++* 03/20/03 Mallesh Defined size of basic variables ++* 03/27/03 F. Mujica Added SINT40 and UINT40 definitions. ++* ++* (C) Copyright Texas Instruments Inc. 1997-2001. All rights reserved. ++*******************************************************************************/ ++ ++// Common type definitions ++ ++// Basic constants needed everywhere ++#ifndef STD_ ++#define FALSE 0 ++#define TRUE 1 ++#endif ++ ++// Read-Write Data Types ++typedef signed char SINT8; // Signed 8-bit integer (7-bit magnitude) ++typedef unsigned char UINT8; // Unsigned 8-bit integer ++typedef signed short SINT16; // Signed 16-bit integer (15-bit magnitude) ++typedef unsigned short UINT16; // Unsigned 16-bit integer ++typedef signed int SINT32; // Signed 32-bit integer (31-bit magnitude) ++typedef unsigned int UINT32; // Unsigned 32-bit integer ++typedef long signed int SINT40; // Long signed 40-bit integer ++typedef long unsigned int UINT40; // Long unsigned 40-bit integer ++ ++// All pointers are 32 bits long ++typedef SINT8 *PSINT8; // Pointer to SINT8 ++typedef UINT8 *PUINT8; // Pointer to UINT8 ++typedef SINT16 *PSINT16; // Pointer to SINT16 ++typedef UINT16 *PUINT16; // Pointer to UINT16 ++typedef SINT32 *PSINT32; // Pointer to SINT32 ++typedef UINT32 *PUINT32; // Pointer to UINT32 ++ ++#define SIZEOF_SINT8 1 ++#define SIZEOF_UINT8 1 ++#define SIZEOF_SINT16 2 ++#define SIZEOF_UINT16 2 ++#define SIZEOF_SINT32 4 ++#define SIZEOF_UINT32 4 ++#define SIZEOF_SINT40 8 ++#define SIZEOF_UINT40 8 ++ ++// Size of Read-Write Data Types - in bytes ++#define SIZEOF_char 1 ++#define SIZEOF_Int8 1 ++#define SIZEOF_UChar 1 ++#define SIZEOF_UInt8 1 ++#define SIZEOF_Float 4 ++#define SIZEOF_Double 8 ++#define SIZEOF_byte 1 ++ ++// Read-Only Data Types - should be only used for ROM code ++typedef const char CharRom; // 8 bit signed character ++typedef const signed char Int8Rom; // 8 bit signed integer ++typedef const unsigned char UCharRom; // 8 bit unsigned character ++typedef const unsigned char UInt8Rom; // 8 bit unsigned integer ++typedef const float FloatRom; // IEEE 32-bit ++typedef const double DoubleRom; // IEEE 64-bit ++ ++#ifndef _WINDEF_ ++ ++// Read-Write Data Types ++typedef signed char Int8; // 8 bit signed integer ++typedef unsigned char UChar; // 8 bit unsigned character ++typedef unsigned char UInt8; // 8 bit unsigned integer ++#ifndef STD_ ++typedef char Char; // 8 bit signed character ++typedef float Float; // IEEE 32-bit ++#endif ++typedef double Double; // IEEE 64-bit ++typedef signed char byte; // 8 bit signed integer ++ ++ ++// These typedefs collide with those in Win2k DDK inc\WINDEF.H ++ ++// common type definition ++typedef unsigned char BYTE; // 8-bit ++typedef signed short SHORT; // 16-bit signed ++typedef unsigned short WORD; // 16-bit ++typedef unsigned int DWORD; // 32-bit, TI DSP has 40 bit longs ++ ++// All pointers are 32 bits long ++typedef BYTE *PBYTE; // pointer to 8 bit data ++typedef unsigned char *PCHAR; // pointer to 8 bit data ++typedef SHORT *PSHORT; // pointer to 16 bit data ++typedef WORD *PWORD; // pointer to 16 bit data ++typedef DWORD *PDWORD; // pointer to 32 bit data ++ ++#endif // #ifndef _WINDEF_ ++ ++ ++#define SIZEOF_BYTE 1 ++#define SIZEOF_SHORT 2 ++#define SIZEOF_WORD 2 ++#define SIZEOF_DWORD 4 ++#define SIZEOF_PCHAR 4 ++#define SIZEOF_PWORD 4 ++#define SIZEOF_PDWORD 4 ++ ++// Size of Read-Only Data Types - in bytes ++#define SIZEOF_CharRom 1 ++#define SIZEOF_Int8Rom 1 ++#define SIZEOF_UCharRom 1 ++#define SIZEOF_UInt8Rom 1 ++#define SIZEOF_FloatRom 4 ++#define SIZEOF_DoubleRom 8 ++ ++#define SIZEOF_complex_byte (2*SIZEOF_byte) ++#define SIZEOF_PTR_complex_byte 4 ++typedef struct { ++ byte re; ++ byte im; ++} complex_byte, *PTR_complex_byte; ++ ++#define SIZEOF_complex_short 4 ++#define SIZEOF_PTR_complex_short 4 ++typedef struct { ++ short re; ++ short im; ++} complex_short, *PTR_complex_short; ++ ++#define SIZEOF_complex_int 8 ++#define SIZEOF_PTR_complex_int 4 ++typedef struct { ++ int re; ++ int im; ++} complex_int, *PTR_complex_int; ++ ++typedef struct { ++ int high; ++ unsigned int low; ++} int64; ++ ++typedef struct { ++ int64 real; ++ int64 imag; ++} complex_int64; ++ ++#define SIZEOF_PVOID 4 ++typedef void *PVOID; // pointer to void ++ ++//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ++ ++#if defined(_TMS320C6X) // TMS320C6xx type definitions ++ ++// Read-Write Data Types ++typedef short Int16; // 16 bit signed integer ++typedef unsigned short UInt16; // 16 bit unsigned integer ++typedef int Int32; // 32 bit signed integer ++typedef unsigned int UInt32; // 32 bit unsigned signed integer ++typedef long Long40; // 40 bit signed integer ++typedef unsigned long ULong40; // 40 bit unsigned signed integer ++ ++// Size of Read-Write Data Types - in bytes ++#define SIZEOF_Int16 2 ++#define SIZEOF_UInt16 2 ++#define SIZEOF_Int32 4 ++#define SIZEOF_UInt32 4 ++#define SIZEOF_Long40 5 ++#define SIZEOF_ULong40 5 ++ ++// Read-Only Data Types - should be only used for ROM code ++typedef const short Int16Rom; // 16 bit signed integer ++typedef const unsigned short UInt16Rom; // 16 bit unsigned integer ++typedef const int Int32Rom; // 32 bit signed integer ++typedef const unsigned int UInt32Rom; // 32 bit unsigned signed integer ++typedef const long Long40Rom; // 40 bit signed integer ++typedef const unsigned long ULong40Rom; // 40 bit unsigned signed integer ++ ++// Size of Read-Only Data Types - in bytes ++#define SIZEOF_Int16Rom 2 ++#define SIZEOF_UInt16Rom 2 ++#define SIZEOF_Int32Rom 4 ++#define SIZEOF_UInt32Rom 4 ++#define SIZEOF_Long40Rom 5 ++#define SIZEOF_ULong40Rom 5 ++ ++#else // 32 bits PC Host type definitions ++ ++// Read-Write Data Types ++typedef short Int16; // 16 bit signed integer ++typedef unsigned short UInt16; // 16 bit unsigned integer ++typedef int Int32; // 32 bit signed integer ++typedef unsigned int UInt32; // 32 bit unsigned integer ++ ++// Read-Only Data Types - should be only used for ROM code ++typedef const short Int16Rom; // 16 bit signed integer ++typedef const unsigned short UInt16Rom; // 16 bit unsigned integer ++typedef const int Int32Rom; // 32 bit signed integer ++typedef const unsigned int UInt32Rom; // 32 bit unsigned integer ++ ++#endif ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/Makefile linux.dev/drivers/atm/sangam_atm/Makefile +--- linux.old/drivers/atm/sangam_atm/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/Makefile 2005-08-23 04:46:50.104842632 +0200 +@@ -0,0 +1,35 @@ ++# File: drivers/net/avalanche_cpmac/Makefile ++# ++# Makefile for the Linux network (CPMAC) device drivers. ++# ++ ++ ++O_TARGET := tiatm.o ++obj-$(CONFIG_MIPS_SANGAM_ATM) += tiatm.o ++list-multi := tiatm.o ++ ++tiatm-objs := tn7atm.o tn7dsl.o tn7sar.o dsl_hal_api.o dsl_hal_support.o cpsar.o aal5sar.o ++ ++EXTRA_CFLAGS += -DEL -I$(TOPDIR)/drivers/atm/sangam_atm -DPOST_SILICON -DCOMMON_NSP -DCONFIG_LED_MODULE -DDEREGISTER_LED -DNO_ACT ++ ++ifeq ($(ANNEX),B) ++EXTRA_CFLAGS += -DANNEX_B -DB ++else ++ifeq ($(ANNEX),C) ++EXTRA_CFLAGS += -DANNEX_C -DC ++else ++EXTRA_CFLAGS += -DANNEX_A -DP ++endif ++endif ++ ++ ++include $(TOPDIR)/Rules.make ++ ++tiatm.o: $(tiatm-objs) ++ $(LD) -r -o $@ $(tiatm-objs) ++ ++#avalanche_cpmac.o: $(avalanche_cpmac-objs) ++# $(LD) -r -o $@ $(avalanche_cpmac-objs) ++ ++clean: ++ rm -f core *.o *.a *.s +diff -urN linux.old/drivers/atm/sangam_atm/queue.h linux.dev/drivers/atm/sangam_atm/queue.h +--- linux.old/drivers/atm/sangam_atm/queue.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/queue.h 2005-08-23 04:46:50.104842632 +0200 +@@ -0,0 +1,167 @@ ++ ++#if !defined( __QUEUE_H__ ) ++#define __QUEUE_H__ ++ ++typedef spinlock_t OS_SPIN_LOCK; ++#define osFreeSpinLock(pLock) while(0) ++void osAcquireSpinLock(OS_SPIN_LOCK *pLock); ++void osReleaseSpinLock(OS_SPIN_LOCK *pLock); ++void osAllocateSpinLock(OS_SPIN_LOCK *pLock); ++ ++//#define osAcquireSpinLock(pLock) spin_lock(pLock) ++//#define osReleaseSpinLock(pLock) spin_unlock(pLock) ++//#define osAllocateSpinLock(pLock) spin_lock_init(pLock) ++ ++ ++typedef struct _TI_LIST_ENTRY { ++ struct _TI_LIST_ENTRY *Flink; ++ struct _TI_LIST_ENTRY *Blink; ++} TI_LIST_ENTRY, *PTI_LIST_ENTRY, TQE, *PTQE; ++ ++typedef struct _TIATM_LIST_ENTRY ++{ ++ TI_LIST_ENTRY Link; ++} TIATM_LIST_ENTRY, *PTIATM_LIST_ENTRY; ++ ++//------------------------------------------------------------------------- ++// QueueInitList -- Macro which will initialize a queue to NULL. ++//------------------------------------------------------------------------- ++#define QueueInitList(_L) (_L)->Link.Flink = (_L)->Link.Blink = (PTI_LIST_ENTRY)0; ++ ++//------------------------------------------------------------------------- ++// QueueEmpty -- Macro which checks to see if a queue is empty. ++//------------------------------------------------------------------------- ++#define QueueEmpty(_L) (QueueGetHead((_L)) == (PTIATM_LIST_ENTRY)0) ++ ++//------------------------------------------------------------------------- ++// QueueGetHead -- Macro which returns the head of the queue, but does not ++// remove the head from the queue. ++//------------------------------------------------------------------------- ++#define QueueGetHead(_L) ((PTIATM_LIST_ENTRY)((_L)->Link.Flink)) ++ ++#define QueueGetNext(Elem) ((PTIATM_LIST_ENTRY)((Elem)->Link.Flink)) ++ ++//------------------------------------------------------------------------- ++// QueuePushHead -- Macro which puts an element at the head of the queue. ++//------------------------------------------------------------------------- ++#define QueuePushHead(_L,_E) \ ++ if (!((_E)->Link.Flink = (_L)->Link.Flink)) \ ++ { \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY)(_E); \ ++ } \ ++(_L)->Link.Flink = (PTI_LIST_ENTRY)(_E); ++ ++//------------------------------------------------------------------------- ++// QueueRemoveHead -- Macro which removes the head of the head of queue. ++//------------------------------------------------------------------------- ++#define QueueRemoveHead(_L) \ ++{ \ ++ PTIATM_LIST_ENTRY ListElem; \ ++ if (ListElem = (PTIATM_LIST_ENTRY)(_L)->Link.Flink) \ ++ { \ ++ if(!((_L)->Link.Flink = ListElem->Link.Flink)) \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY) 0; \ ++ } \ ++} ++ ++//------------------------------------------------------------------------- ++// QueuePutTail -- Macro which puts an element at the tail (end) of the queue. ++//------------------------------------------------------------------------- ++#define QueuePutTail(_L,_E) \ ++{ \ ++ if ((_L)->Link.Blink) \ ++ { \ ++ ((PTIATM_LIST_ENTRY)(_L)->Link.Blink)->Link.Flink = (PTI_LIST_ENTRY)(_E); \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY)(_E); \ ++ } \ ++ else \ ++ { \ ++ (_L)->Link.Flink = \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY)(_E); \ ++ } \ ++ (_E)->Link.Flink = (PTI_LIST_ENTRY)0; \ ++} ++ ++//------------------------------------------------------------------------- ++// QueuePutTailWithLock -- Macro which puts an element at the tail (end) of ++// the queue, using spin lock. ++//------------------------------------------------------------------------- ++#define QueuePutTailWithLock(_L,_E, pLock) \ ++{ \ ++ osAcquireSpinLock(pLock); \ ++ if ((_L)->Link.Blink) \ ++ { \ ++ ((PTIATM_LIST_ENTRY)(_L)->Link.Blink)->Link.Flink = (PTI_LIST_ENTRY)(_E); \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY)(_E); \ ++ } \ ++ else \ ++ { \ ++ (_L)->Link.Flink = \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY)(_E); \ ++ } \ ++ (_E)->Link.Flink = (PTI_LIST_ENTRY)0; \ ++ osReleaseSpinLock(pLock); \ ++} ++ ++//------------------------------------------------------------------------- ++// QueueGetTail -- Macro which returns the tail of the queue, but does not ++// remove the tail from the queue. ++//------------------------------------------------------------------------- ++#define QueueGetTail(_L) ((PTIATM_LIST_ENTRY)((_L)->Link.Blink)) ++ ++//------------------------------------------------------------------------- ++// QueuePopHead -- Macro which will pop the head off of a queue (list), and ++// return it (this differs only from queueremovehead only in ++// the 1st line) ++//------------------------------------------------------------------------- ++#define QueuePopHead(_L) \ ++(PTIATM_LIST_ENTRY) (_L)->Link.Flink; QueueRemoveHead(_L); ++ ++#define QueueRemoveTail(_L) \ ++{ \ ++ PTIATM_LIST_ENTRY ListElem; \ ++ ListElem = (PTIATM_LIST_ENTRY)(_L)->Link.Flink; \ ++ if(ListElem == (PTIATM_LIST_ENTRY)(_L)->Link.Blink) \ ++ { \ ++ (_L)->Link.Flink = (_L)->Link.Blink = (PTI_LIST_ENTRY) 0; \ ++ } \ ++ else \ ++ { \ ++ while(ListElem->Link.Flink != (PTI_LIST_ENTRY)(_L)->Link.Blink) \ ++ { \ ++ ListElem = (PTIATM_LIST_ENTRY)ListElem->Link.Flink; \ ++ } \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY) ListElem; \ ++ ListElem->Link.Flink = (PTI_LIST_ENTRY)0; \ ++ } \ ++} ++ ++#define QueueRemoveItem(_L, Elem) \ ++{ \ ++ PTIATM_LIST_ENTRY ListElem; \ ++ ListElem = (PTIATM_LIST_ENTRY)(_L)->Link.Flink; \ ++ if(ListElem == Elem) \ ++ { \ ++ QueueRemoveHead(_L); \ ++ } \ ++ else \ ++ { \ ++ while(ListElem) \ ++ { \ ++ if(Elem == (PTIATM_LIST_ENTRY)ListElem->Link.Flink) \ ++ { \ ++ ListElem->Link.Flink = ((PTIATM_LIST_ENTRY)Elem)->Link.Flink; \ ++ if(Elem == (PTIATM_LIST_ENTRY)(_L)->Link.Blink) \ ++ (_L)->Link.Blink = (PTI_LIST_ENTRY) 0; \ ++ break; \ ++ } \ ++ ListElem = (PTIATM_LIST_ENTRY)ListElem->Link.Flink; \ ++ }\ ++ } \ ++ ((PTIATM_LIST_ENTRY)Elem)->Link.Flink = (PTI_LIST_ENTRY) 0; \ ++} ++ ++#define QueuePopTail(_L) \ ++((PTIATM_LIST_ENTRY)((_L)->Link.Blink)); QueueRemoveTail(_L); ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/release.txt linux.dev/drivers/atm/sangam_atm/release.txt +--- linux.old/drivers/atm/sangam_atm/release.txt 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/release.txt 2005-08-23 04:46:50.104842632 +0200 +@@ -0,0 +1,118 @@ ++This is release notes for AR7 Linux ATM driver. ++ ++version 04.02.04.00 ++------------------- ++ ++1. Corrected the conditional logic from logical AND to logical OR in the case ++ of check for DSL line down condition. This is to fix PPPoA crashing ++ problem when DSL line is unplugged. ++ ++version 04.02.03.00 ++------------------- ++1. Changed overlay page to static allocation. ++2. Added flag to stop TX during channel closing. ++3. Changed DMA memory allocation back to "GFP_ATOMIC" flag. ++ ++version 04.02.02.00 ++------------------- ++1. Changed DMA memory allocation from "GFP_ATOMIC" to "GFP_KERNEL" flag. ++2. Added "DoMask" setting for VBR channel setup. ++ ++version 04.02.01.01 ++------------------- ++1. Modified priority check scheme per SPTC request. ++ ++Version 04.02.01.00 ++------------------- ++1. Add check to skb->priority to place packets to either normal or priority queue. ++2. Add spin lock to increment and decrement of queued buffer number. ++ ++Version 04.02.00.00 ++------------------- ++Features: ++1. Add MBS and CDVT QoS support for ATM driver. ++2. Add "stop/start queue" for ToS application. ++3. Add Showtime margin retrain based on EOC message. ++4. Add EOC vendor ID customalization logic for Annex B. ++5. Supports D3 datapump. ++ ++Version 04.01.00.00 ++------------------- ++Re-release of 04.00.07.00 for D1.1 datapump. ++ ++Version 04.00.07.00 ++------------------- ++Features: ++1. Add marging retrain capability by setting following Adam2 Env. ++ setenv enable_margin_retrain 1 ++ setenv margin_threshold xx, xx is in half db, i.e., 10 means 5db. ++ ++Bugfixs: ++1. New PDSP firmware that fix the F5 OAM cell loopback probelm in Cisco DSLAM. ++ ++Version 04.00.06.00 ++------------------- ++1. ATM interrupt pacing is defauted to 2 interrupts/s. ++2. Rx Service MAX changed ftom 16 to 8. ++ ++Version 04.00.05.00 ++------------------- ++Features: ++1. Add Adam2 env to disable the TurboDSL by entering "setenv TurboDSL 0". ++2. Add ability to set interrupt pacing for ATM driver. ++ ++Bugfixs: ++1. Fixed the RFC2684 and CLIP problems for Cisco router. ++2. Fixed LED blinking problem when DSL cable is unplugged. ++3. Fixed problem that "selected mode" is not updated. ++ ++Version 04.00.04.00 ++------------------- ++Features: ++1. Added feature so OAM F5 ping will not require a corresponding PVC channel to ++ be setup. ++2. Added timeout value for F5 OAM ping. The new command are "exxxpyyycdzzzt" for ++ end-to-end and "sxxxpyyycdzzzt" for segment. "zzz" is timeout value in milli-second. ++3. Added proc entry "avsar_pvc_table" to record received VPIs and VCIs. The format is ++ vpi,vci ++ seperated by new line. To search for PVCs, an application can do the following. ++ i) Send a (or several) F5 OAM cell on a VPI/VPI pairs with command ++ echo exxxpyyycd2t > /proc/sys/dev/dslmod ++ ii) Wait >2ms or poll proc entry /proc/avalanche/avsar_oam_ping until the result ++ indicates a failure. (It will be failed all the time with 2ms timeout.) ++ iii) Repeat above two steps for new VPI/VCI pairs. ++ iv) Check proc entry /proc/avalanche/avsar_pvc_table any time for PVCs that responded. ++ ++Version 04.00.03.00 ++------------------- ++Bug Fixs: ++1. Fixed bug that caused crash when phone cable is unplugged. ++2. Fixed LED operation for "flexible LEDs". ++ ++Features: ++1. Added the proc entry "avsar_oam_ping" to signal oam ping result. ++ 0 - failed; 1 - success; 2 - in progress. ++2. Added oam ping timeout env variable. The timeout can be specified by ++ adding Adam2 env "oam_lb_timeout". The value is in millisecond. ++ ++Version 04.00.02.00 ++------------------- ++1. The driver uses hardware queue for Turbo DSL. ++2. Added new modem statistics listed below: ++ US and DS TX powers, atuc Vendor ID and revision, training mode selected, ++ Hybrid Selected, and etc. ++ ++Version 04.00.01.00 ++------------------- ++ ++1. This driver release contains all the features that exists in AR5 Linux ATM ++ 3.1 driver. ++ ++2. F4 OAM generation is added. ++ ++3. Software queuing is used for TURBO DSL. ++ ++4. Porting guide "is created. Please look into that document for detailed ++ information. ++ ++ +diff -urN linux.old/drivers/atm/sangam_atm/syssw_version.h linux.dev/drivers/atm/sangam_atm/syssw_version.h +--- linux.old/drivers/atm/sangam_atm/syssw_version.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/syssw_version.h 2005-08-23 04:46:50.105842480 +0200 +@@ -0,0 +1,94 @@ ++#ifndef __SYSSW_VERSION_H__ ++#define __SYSSW_VERSION_H__ 1 ++ ++/******************************************************************************* ++* FILE PURPOSE: DSL Driver API functions for Sangam ++* ++******************************************************************************** ++* FILE NAME: dsl_hal_basicapi.c ++* ++* DESCRIPTION: ++* Contains basic DSL HAL APIs for Sangam ++* ++* (C) Copyright 2003-04, Texas Instruments, Inc. ++* History ++* Date Version Notes ++* 14May03 0.00.00 RamP Original Version Created ++* 14May03 0.00.01 RamP Initial Rev numbers inserted ++* 14May03 0.00.02 RamP Bumped version numbers for Dsl Hal ++* & dhalapp for alpha plus ++* 19May03 0.00.03 MCB Bumped dslhal version number ++* because of dependant changes ++* wrt. linux-nsp atm drivers. ++* 22May03 0.00.04 RamP Bumped dslhal & dhalapp buildnum ++* for inner/outer pair & DGASP code ++* 06Jun03 0.00.05 RamP Bumped up buildnum for LED, STM, ++* interrupt processing, statistics ++* and other pre-beta features ++* 09Jun03 0.00.06 JEB Fixed error in DHALAPP bugfix/buildnum ++* 09Jun03 0.00.07 RamP Bumped up buildnum for incremental ++* changes to apis, statistics, memory ++* fixes, parameter configurations ++* 11Jun03 0.00.08 RamP Bumped up buildnum for Co profile ++* free memory fix ++* 12Jun03 0.00.09 JEB Bumped version numbers for AR7 1.00 Beta ++* 02Jul03 0.00.10 ZT Bumped HAL version for overlay page ++* 18Jul03 0.00.11 RamP Bumped HAL version for analog diags ++* 22Jul03 0.00.12 JEB Bumped DHALAPP buildnum for analog diags ++* 31Jul03 0.00.13 RamP Bumped HAL version for engr. drop ++* 04Aug03 0.00.14 JEB Bumped HAL version buildnum for CHECKPOINT65 changes ++* Bumped LINUX version buildnum for CHECKPOINT65 changes ++* 06Aug03 0.00.15 MCB Bumped all version numbers in prep for AR7 1.0 R2 release for POTS. ++* 13Aug03 0.00.16 MCB Set rev id's for D3/R1.1 (ADSL2). ++* 21Aug03 0.00.17 JEB Bumped up build numbers for merge of code additions from D1 ++* 26Sep03 0.00.18 JEB Set rev id's for another D3/R1 (ADSL2). ++* 14Oct03 0.00.19 JEB Bumped Linux minor number and reset bugfix number for release. ++* Bumped build numbers on DSLHAL and DHALAPP for this checkpoint. ++* 14Oct03 0.00.20 JEB Bumped build numbers on DSLHAL and DHALAPP for CHECKPOINT15. ++* 21Oct03 0.00.21 JEB Bumped build number on DSLHAL for CHECKPOINT16. ++* 22Oct03 0.00.22 MCB Bumped all version numbers in support of D3R1 release. ++* 27Oct03 0.00.23 JEB Bumped build numbers on DSLHAL and DHALAPP for CHECKPOINT19. ++* Updated version for DSLAGENT to be 02.01.00.01 for ACT 2.1 R0. ++* 30Oct03 0.00.24 JEB Bumped bugfix number on LINUXATM Version for next release. ++* Bumped build numbers on DSLHAL and DHALAPP ++* 31Oct03 0.00.25 MCB Bumped all version numbers in support of D3R2 release. ++* 14Nov03 0.00.26 JEB Bumped build numbers on DSLHAL and DHALAPP ++* Changed version for DSLAGENT to be 02.00.01.01 for an ACT 2.0 R0 ++* 20Nov03 0.00.27 JEB Bumped build number on DSLHAL. ++* Changed version for DSLAGENT to be 02.00.02.00 for the next ACT 2.0 R2 ++* 21Nov03 0.00.28 MCB Bumped all version numbers in support of D3R2 release. ++* 21Nov03 0.00.29 JEB Bumped build numbers on DSLHAL and DHALAPP for D3-R0 drop on 11/21. ++* 16Dec03 0.00.30 JEB Bumped build numbers on DSLHAL and DHALAPP for CHECKPOINT31. ++* 21Dec03 0.00.31 MCB Bumped all version numbers in support of D3R2 release. ++* 05Jan04 0.00.32 JEB Bumped build numbers on DSLHAL and Linux ATM for CHECKPOINT 34. ++* 15Jan04 0.00.33 JEB Bumped build numbers on DSLHAL and Linux ATM for CHECKPOINT 36. ++* 26Jan04 0.00.34 JEB Changed Linux ATM version number to be 04.02.03.00. ++* 27Jan04 0.00.35 MCB Bumped all version numbers in support of D3R2 release. ++*******************************************************************************/ ++ ++/* Dsl Hal API Version Numbers */ ++#define DSLHAL_VERSION_MAJOR 03 ++#define DSLHAL_VERSION_MINOR 00 ++#define DSLHAL_VERSION_BUGFIX 06 ++#define DSLHAL_VERSION_BUILDNUM 00 ++#define DSLHAL_VERSION_TIMESTAMP 00 ++ ++/* dhalapp Adam2 Application Version Numbers */ ++#define DHALAPP_VERSION_MAJOR 03 ++#define DHALAPP_VERSION_MINOR 00 ++#define DHALAPP_VERSION_BUGFIX 05 ++#define DHALAPP_VERSION_BUILDNUM 00 ++ ++/* Linux ATM Driver Version Numbers */ ++#define LINUXATM_VERSION_MAJOR 04 ++#define LINUXATM_VERSION_MINOR 02 ++#define LINUXATM_VERSION_BUGFIX 04 ++#define LINUXATM_VERSION_BUILDNUM 00 ++ ++/* DSL Agent Version Numbers */ ++#define DSLAGENT_VERSION_MAJOR 02 ++#define DSLAGENT_VERSION_MINOR 00 ++#define DSLAGENT_VERSION_BUGFIX 02 ++#define DSLAGENT_VERSION_BUILDNUM 00 ++ ++#endif /* pairs with #ifndef __SYSSW_VERSION_H__ */ +diff -urN linux.old/drivers/atm/sangam_atm/tn7api.h linux.dev/drivers/atm/sangam_atm/tn7api.h +--- linux.old/drivers/atm/sangam_atm/tn7api.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/tn7api.h 2005-08-23 04:46:50.105842480 +0200 +@@ -0,0 +1,54 @@ ++/* ++ * Tnetd73xx ATM driver. ++ * by Zhicheng Tang, ztang@ti.com ++ * 2000 (c) Texas Instruments Inc. ++ * ++ * ++*/ ++ ++#ifndef __SAPI_H ++#define __SAPI_H ++ ++/* tn7atm.c */ ++void xdump(unsigned char *buff, int len, int debugLev); ++int tn7atm_receive(void *os_dev, int ch, unsigned int packet_size, void *os_receive_info, void *data); ++void *tn7atm_allocate_rx_skb(void *os_dev, void **os_receive_info, unsigned int size); ++void tn7atm_free_rx_skb(void *skb); ++void tn7atm_sarhal_isr_register(void *os_dev, void *hal_isr, int interrupt_num); ++int tn7atm_send_complete(void *osSendInfo); ++int tn7atm_device_connect_status(void *priv, int state); ++int tn7atm_lut_find(short vpi, int vci); ++ ++/* tn7dsl.h */ ++void tn7dsl_exit(void); ++int tn7dsl_init(void *priv); ++int tn7dsl_proc_stats(char* buf, char **start, off_t offset, int count,int *eof, void *data); ++int tn7dsl_proc_modem(char* buf, char **start, off_t offset, int count,int *eof, void *data); ++int tn7dsl_handle_interrupt(void); ++void dprintf( int uDbgLevel, char * szFmt, ...); ++void tn7dsl_dslmod_sysctl_register(void); ++void tn7dsl_dslmod_sysctl_unregister(void); ++int tn7dsl_get_dslhal_version(char *pVer); ++int tn7dsl_get_dsp_version(char *pVer); ++ ++int os_atoi(const char *pStr); ++int os_atoh(const char *pStr); ++unsigned long os_atoul(const char *pStr); ++ ++/* tn7sar.c */ ++int tn7sar_activate_vc(Tn7AtmPrivate *priv, short vpi, int vci, int pcr, int scr, int mbs, int cdvt, int chan, int qos); ++int tn7sar_init(struct atm_dev *dev, Tn7AtmPrivate *priv); ++int tn7sar_register_interrupt_handle(void *os_dev, void *hal_isr, int *interrupt_num); ++void tn7sar_exit(struct atm_dev *dev, Tn7AtmPrivate *priv); ++int tn7sar_deactivate_vc(Tn7AtmPrivate *priv, int chan); ++int tn7sar_handle_interrupt(struct atm_dev *dev, Tn7AtmPrivate *priv); ++int tn7sar_send_packet(Tn7AtmPrivate *priv, int chan, void *new_skb, void *data,unsigned int len, int priority); ++void tn7sar_get_sar_version(Tn7AtmPrivate *priv, char **pVer); ++int tn7sar_get_near_end_loopback_count(unsigned int *pF4count, unsigned int *pF5count); ++int tn7sar_oam_generation(void *privContext, int chan, int type, int vpi, int vci, int timeout); ++int tn7sar_get_stats(void *priv1); ++int tn7sar_proc_sar_stat(char* buf, char **start, off_t offset, int count,int *eof, void *data); ++void tn7sar_get_sar_firmware_version(unsigned int *pdsp_version_ms, unsigned int *pdsp_version_ls); ++int tn7sar_proc_oam_ping(char* buf, char **start, off_t offset, int count,int *eof, void *data); ++int tn7sar_proc_pvc_table(char* buf, char **start, off_t offset, int count,int *eof, void *data); ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/tn7atm.c linux.dev/drivers/atm/sangam_atm/tn7atm.c +--- linux.old/drivers/atm/sangam_atm/tn7atm.c 2005-08-28 01:52:26.000000000 -0600 ++++ linux.dev/drivers/atm/sangam_atm/tn7atm.c 2005-08-28 02:08:07.000000000 -0600 +@@ -0,0 +1,1233 @@ ++/* ++ * tn7.c ++ * Linux atm module implementation. ++ * Zhicheng Tang 01/08/2003 ++ * 2003 (c) Texas Instruments Inc. ++ * ++ * ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "tn7atm.h" ++#include "tn7api.h" ++#include "syssw_version.h" ++ ++#ifdef CONFIG_LED_MODULE ++#include ++#endif ++#include ++ ++#ifdef MODULE ++MODULE_DESCRIPTION ("Tnetd73xx ATM Device Driver"); ++MODULE_AUTHOR ("Zhicheng Tang"); ++#endif ++ ++/* Version Information */ ++//static char atm_version[] ="1.0.0.1"; ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++#define STOP_EMPTY_BUFF 2 ++#define START_EMPTY_BUFF 3 ++/* externs */ ++ ++/*end of externs */ ++ ++#define tn7atm_kfree_skb(x) dev_kfree_skb(x) ++ ++/* prototypes */ ++int tn7atm_open (struct atm_vcc *vcc, short vpi, int vci); ++ ++void tn7atm_close (struct atm_vcc *vcc); ++ ++static int tn7atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg); ++ ++int tn7atm_send (struct atm_vcc *vcc, struct sk_buff *skb); ++ ++static int tn7atm_change_qos (struct atm_vcc *vcc, struct atm_qos *qos,int flags); ++ ++static int tn7atm_detect(void); ++static int tn7atm_init(struct atm_dev* dev); ++//static int tn7atm_reset(void); ++static int tn7atm_irq_request(struct atm_dev* dev); ++static int tn7atm_proc_version(char* buf, char **start, off_t offset, int count,int *eof, void *data); ++static void tn7atm_exit(void); ++static int tn7atm_proc_channels(char* buf, char **start, off_t offset, int count,int *eof, void *data); ++static int tn7atm_proc_private(char* buf, char **start, off_t offset, int count,int *eof,void *data); ++//static void tn7atm_free_packet(void *vcc1, void *priv, void *skb1); ++static int tn7atm_queue_packet_to_sar(void *vcc1, void *skb1); ++ ++#include "turbodsl.c" ++ ++/* ATM device operations */ ++ ++struct atm_dev *mydev; ++ ++static const struct atmdev_ops tn7atm_ops = { ++ open: tn7atm_open, ++ close: tn7atm_close, ++ ioctl: tn7atm_ioctl, ++ getsockopt: NULL, ++ setsockopt: NULL, ++ send: tn7atm_send, ++ sg_send: NULL, ++ phy_put: NULL, ++ phy_get: NULL, ++ change_qos: tn7atm_change_qos, ++}; ++ ++ ++int __guDbgLevel = 1; ++ ++ ++void xdump(unsigned char *buff, int len, int debugLev) ++{ ++#ifdef DEBUG_BUILD ++ int i, j; ++ if( __guDbgLevel < debugLev) ++ return; ++ ++ j=0; ++ for(i=0;idev->vccs; walk; walk = walk->next) { ++ ++ if ((walk->vci == *vci) && (walk->vpi == *vpi)) { ++ (*vpi)++; ++ walk = vcc->dev->vccs; ++ } ++ } ++ } ++ ++ /* find a free VCI */ ++ if (*vci == ATM_VCI_ANY) { ++ ++ for (*vci = ATM_NOT_RSV_VCI, walk = vcc->dev->vccs; walk; walk = walk->next) { ++ ++ if ((walk->vpi = *vpi) && (walk->vci == *vci)) { ++ *vci = walk->vci + 1; ++ walk = vcc->dev->vccs; ++ } ++ } ++ } ++ ++ return 0; ++} ++#endif ++ ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_sar_irq(void) ++ * ++ * Description: tnetd73xx SAR interrupt. ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++static void ++tn7atm_sar_irq(int irq , void *voiddev , struct pt_regs *regs) ++{ ++ struct atm_dev *atmdev; ++ Tn7AtmPrivate *priv; ++ ++ dprintf(6, "tn7atm_sar_irq\n"); ++ atmdev = (struct atm_dev *) voiddev; ++ priv = (Tn7AtmPrivate *)atmdev->dev_data; ++ ++ tn7sar_handle_interrupt(atmdev, priv); ++ ++ dprintf(6, "Leaving tn7atm_sar_irq\n"); ++} ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_dsl_irq(void) ++ * ++ * Description: tnetd73xx DSL interrupt. ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++static void ++tn7atm_dsl_irq(int irq , void *voiddev , struct pt_regs *regs) ++{ ++ struct atm_dev *atmdev; ++ Tn7AtmPrivate *priv; ++ ++ dprintf(4, "tn7atm_dsl_irq\n"); ++ atmdev = (struct atm_dev *) voiddev; ++ priv = (Tn7AtmPrivate *)atmdev->dev_data; ++ ++ tn7dsl_handle_interrupt(); ++ ++ dprintf(4, "Leaving tn7atm_dsl_irq\n"); ++} ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_Inittxcomp(struct tn7* tn7) ++ * ++ * Description: Initialize Interrupt handler ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ++static int __init ++tn7atm_irq_request (struct atm_dev *dev) ++{ ++ Tn7AtmPrivate *priv; ++ char *ptr; ++ int ipace=2; ++ ++ dprintf(4, "tn7atm_irq_request()\n"); ++ priv = (Tn7AtmPrivate *) dev->dev_data; ++ ++ /* Register SAR interrupt */ ++ priv->sar_irq = LNXINTNUM(ATM_SAR_INT); /* Interrupt line # */ ++ if (request_irq(priv->sar_irq, tn7atm_sar_irq, SA_INTERRUPT, "SAR ", dev)) ++ printk ("Could not register tn7atm_sar_irq\n"); ++ ++ /* interrupt pacing */ ++ ptr= prom_getenv("sar_ipacemax"); ++ if(ptr) ++ { ++ ipace=os_atoi(ptr); ++ } ++ avalanche_request_pacing(priv->sar_irq, ATM_SAR_INT_PACING_BLOCK_NUM, ipace); ++ ++ /* Reigster Receive interrupt A */ ++ priv->dsl_irq = LNXINTNUM(ATM_DSL_INT); /* Interrupt line # */ ++ if (request_irq(priv->dsl_irq, tn7atm_dsl_irq, SA_INTERRUPT, "DSL ", dev)) ++ printk ("Could not register tn7atm_dsl_irq\n"); ++ ++ return 0; ++} ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_lut_find(struct atm_vcc *vcc) ++ * ++ * Description: find an TX DMA channel ++ * that matches a vpi/vci pair ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ++int ++tn7atm_lut_find(short vpi, int vci) ++{ ++ int i; ++ Tn7AtmPrivate *priv; ++ ++ priv = (Tn7AtmPrivate *)mydev->dev_data; ++ ++ if(vci==0) // find first vpi channel ++ { ++ for(i=0; i< MAX_DMA_CHAN; i++) ++ { ++ if((priv->lut[i].vpi == vpi)) ++ return i; ++ } ++ } ++ ++ dprintf(4, "vpi=%d, vci=%d\n", vpi, vci); ++ for(i=0; i< MAX_DMA_CHAN; i++) ++ { ++ if((priv->lut[i].vpi == vpi) && (priv->lut[i].vci == vci)) ++ return i; ++ } ++ ++ ++ ++ return ATM_NO_DMA_CHAN; ++} ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_lut_clear(struct atm_vcc *vcc,int chan) ++ * ++ * Description: find an TX DMA channel ++ * that matches a vpi/vci pair ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ++static int ++tn7atm_lut_clear(struct atm_vcc *vcc, int chan) ++{ ++ Tn7AtmPrivate *priv; ++ ++ priv = (Tn7AtmPrivate *)vcc->dev->dev_data; ++ ++ memset(&priv->lut[chan], 0, sizeof(priv->lut[chan])); ++ ++ return 0; ++} ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_walk_lut(void) ++ * ++ * Description: find an available TX DMA channel ++ * and initialize LUT ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ++static int ++tn7atm_walk_lut(Tn7AtmPrivate *priv) ++{ ++ int i; ++ ++ for(i=0; i< MAX_DMA_CHAN; i++){ ++ if(!priv->lut[i].inuse) ++ { ++ return i; /* return available dma channel number */ ++ } ++ } ++ return ATM_NO_DMA_CHAN; /* no tx dma channels available */ ++} ++ ++static int ++tn7atm_set_lut(Tn7AtmPrivate *priv, struct atm_vcc *vcc, int chan) ++{ ++ ++ if(!priv->lut[chan].inuse) ++ { ++ priv->lut[chan].vpi = (int)vcc->vpi; ++ priv->lut[chan].vci = vcc->vci; ++ priv->lut[chan].chanid = chan; ++ priv->lut[chan].inuse = 1; /* claim the channel */ ++ priv->lut[chan].vcc = (void *)vcc; ++ priv->lut[chan].bClosing = 0; ++ priv->lut[chan].ready = 0; ++ priv->lut[chan].tx_total_bufs = TX_BUFFER_NUM; ++ priv->lut[chan].tx_used_bufs[0] = 0; ++ priv->lut[chan].tx_used_bufs[1] = 0; ++ return 0; ++ } ++ return -1; /* no tx dma channels available */ ++} ++ ++#if 0 ++static void tn7atm_free_packet(void *pVc, void *pDev, void *pPacket) ++ { ++ Tn7AtmPrivate *priv; ++ struct atm_vcc *vcc; ++ struct sk_buff *skb; ++ ++ vcc = (struct atm_vcc *)pVc; ++ priv = (Tn7AtmPrivate *)pDev; ++ skb = (struct sk_buff *) pPacket; ++ ++ if(vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ tn7atm_kfree_skb(skb); ++ } ++#endif ++ ++static void str2eaddr(char *pMac, char *pStr) ++{ ++ char tmp[3]; ++ int i; ++ ++ for(i=0;i<6;i++) ++ { ++ tmp[0]=pStr[i*3]; ++ tmp[1]=pStr[i*3+1]; ++ tmp[2]=0; ++ pMac[i]=os_atoh(tmp); ++ } ++} ++ ++static int __init ++tn7atm_get_ESI(struct atm_dev *dev) ++{ ++ int i; ++ char esi_addr[ESI_LEN]={0x00,0x00,0x11,0x22,0x33,0x44}; ++ char *esiaddr_str = NULL; ++ ++ esiaddr_str = prom_getenv("macc"); ++ ++ if (!esiaddr_str) { ++ //printk("macc address not set in adam2 environment space\n"); ++ //printk("Using default macc address = 00:01:02:03:04:05\n"); ++ esiaddr_str = "00:00:02:03:04:05"; ++ } ++ str2eaddr(esi_addr, esiaddr_str); ++ ++ for(i=0; i < ESI_LEN; i++) ++ dev->esi[i] = esi_addr[i]; ++ ++ return 0; ++} ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_open(struct atm_vcc *vcc, short vpi, int vci) ++ * ++ * Description: Device operation: open ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ++//static int ++int tn7atm_open (struct atm_vcc *vcc, short vpi, int vci) ++{ ++ Tn7AtmPrivate *priv; ++ int dmachan; ++ int rc; ++ int traffic_type; ++ int pcr = 0x20000; ++ int scr = 0x20000; ++ int mbs = 0x20000; ++ int cdvt = 10000; ++ int err; ++ ++ dprintf(1, "tn7atm_open()\n"); ++ ++ priv = (Tn7AtmPrivate *)vcc->dev->dev_data; ++ if(priv==NULL) ++ { ++ printk("null priv\n"); ++ return -1; ++ } ++ ++ MOD_INC_USE_COUNT; ++ ++#if 0 /* by nbd */ ++ /* find a free VPI/VCI */ ++ tn7atm_walk_vccs(vcc, &vpi, &vci); ++#else ++ if ((err = atm_find_ci(vcc, &vpi, &vci))) { ++ printk("atm_find_ci err = %d\n", err); ++ return err; ++ } ++ ++#endif ++ ++ vcc->vpi = vpi; ++ vcc->vci = vci; ++ ++ if (vci == ATM_VCI_UNSPEC || vpi == ATM_VCI_UNSPEC) ++ { ++ MOD_DEC_USE_COUNT; ++ return -EBUSY; ++ } ++ ++ /* check to see whether PVC is opened or not */ ++ if((dmachan = tn7atm_lut_find(vcc->vpi, vcc->vci)) != ATM_NO_DMA_CHAN) ++ { ++ MOD_DEC_USE_COUNT; ++ printk("PVC already opened. dmachan = %d\n", dmachan); ++ return -EBUSY; ++ } ++ /*check for available channel */ ++ if((dmachan = tn7atm_walk_lut(priv)) == ATM_NO_DMA_CHAN) ++ { ++ printk("No TX DMA channels available\n"); ++ return -EBUSY; ++ } ++ ++ set_bit(ATM_VF_ADDR, &vcc->flags); /* claim address */ ++ ++ vcc->itf = vcc->dev->number; /* interface number */ ++ ++ switch(vcc->qos.txtp.traffic_class) ++ { ++ case ATM_CBR: /* Constant Bit Rate */ ++ traffic_type = 0; ++ pcr = vcc->qos.txtp.pcr; ++ scr = vcc->qos.txtp.pcr; ++ cdvt = vcc->qos.txtp.max_cdv; ++ printk("cdvt=%d\n", cdvt); ++ break; ++ case ATM_UBR: /* Unspecified Bit Rate */ ++ traffic_type = 2; ++ break; ++ ++ /* Disable ATM_VBR until pppd ppoatm plugin supports it. ++ * NOTE: Support ATM_VBR requires the addition of a scr ++ * field to the atm_trafprm structure which will cause ++ * a change in the SO_ATMQOS ioctl. Make sure that the ++ * revised header file becomes visible to the pppd ++ * pppoatm plugin source, or the SO_ATMQOS ioctl will fail. ++ */ ++#if 0 ++ case ATM_VBR: /* Variable Bit Rate */ ++ traffic_type = 1; ++ pcr = vcc->qos.txtp.pcr; ++ scr = vcc->qos.txtp.scr; ++ if(vcc->qos.txtp.max_pcr >= 0) ++ mbs = vcc->qos.txtp.max_pcr; ++ cdvt = vcc->qos.txtp.max_cdv; ++ printk("cdvt=%d\n", cdvt); ++ printk("mbs=%d\n", mbs); ++ break; ++#endif ++ default: ++ traffic_type = 2; ++ } ++ ++ dprintf(4, "vpi=%d, vci=%d, pcr=%d, dmachan=%d, qos=%d\n", vpi,vci,pcr,dmachan,traffic_type); ++ /* Activate SAR channel */ ++ rc = tn7sar_activate_vc(priv, vpi, vci, pcr, scr, mbs, cdvt, dmachan, traffic_type); ++ if(rc < 0) ++ { ++ ++ MOD_DEC_USE_COUNT; ++ return -EBUSY; ++ } ++ ++ /* insure that the the vcc struct points to the correct entry ++ in the lookup table */ ++ ++ tn7atm_set_lut(priv,vcc, dmachan); ++ vcc->dev_data = (void *)&priv->lut[dmachan]; ++ set_bit(ATM_VF_READY, &vcc->flags); ++ ++ mdelay(100); ++ priv->lut[dmachan].ready = 1; ++ dprintf (1, "Leave tn7atm_open\n"); ++ return 0; ++} ++ ++ ++//static void ++void tn7atm_close (struct atm_vcc *vcc) ++{ ++ Tn7AtmPrivate *priv; ++ int dmachan; ++ ++ priv = (Tn7AtmPrivate *)vcc->dev->dev_data; ++ dprintf(4, "closing %d.%d.%d.%d\n", vcc->itf, vcc->vpi, vcc->vci, vcc->qos.aal); ++ ++ clear_bit(ATM_VF_READY, &vcc->flags); /* ATM_VF_READY: channel is ready to transfer data */ ++ ++ dmachan = tn7atm_lut_find(vcc->vpi, vcc->vci); ++ printk("closing channel: %d\n", dmachan); ++ if(dmachan == ATM_NO_DMA_CHAN) ++ { ++ printk("Closing channel not found.\n"); ++ return; ++ } ++ priv->lut[dmachan].bClosing = 1; ++ priv->lut[dmachan].ready = 0; ++ if(tn7sar_deactivate_vc(priv,dmachan)) /* tear down channel */ ++ { ++ printk("failed to close channel %d.\n", dmachan); ++ } ++ ++ clear_bit(ATM_VF_READY, &vcc->flags); /* ATM_VF_READY: channel is ready to transfer data */ ++ tn7atm_lut_clear(vcc, dmachan); ++ ++ MOD_DEC_USE_COUNT; ++ ++ dprintf (1, "Leave tn7atm_close\n"); ++} ++ ++#define ATM_TXSTOP 0x800c61f4 ++static int ++tn7atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg) ++{ ++ Tn7AtmPrivate *priv; ++ priv = (Tn7AtmPrivate *) dev->dev_data; ++ ++ //printk("tn7atm_ioctl\n"); ++ //printk("arg = %x\n", *(int *)arg); ++ //printk("cmd =%x\n", cmd); ++ switch(cmd) ++ { ++ ++ case ATM_TXSTOP: /*temp fix for SAR tear down problem */ ++// printk("ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg); ++// printk("arg = %d\n", *(int*)arg); ++ priv->xmitStop = *(int *)arg; ++ //printk("Executing ATM_SETLOOP for tn7 \n"); ++ //printk("Stop variable = :%d: \n",priv->xmitStop); ++ return 0; ++ ++ //case SAR_DSL_RESET_SOFTBOOT: ++ // return tn7atm_dsl_clean_reboot(); ++ case 0: ++ return 0; ++ } ++ ++ return -ENOSYS; ++ ++} ++ ++static int ++tn7atm_change_qos (struct atm_vcc *vcc, struct atm_qos *qos,int flags) ++{ ++ dprintf (1, "Enter tn7atm_change_qos\n"); ++ dprintf (1, "Leave tn7atm_change_qos\n"); ++ return 0; ++} ++ ++ ++int tn7atm_send (struct atm_vcc *vcc, struct sk_buff *skb) ++{ ++ ++ Tn7AtmPrivate *priv; ++ int bret; ++ int chan; ++ ++ dprintf(4, "tn7atm_send()\n"); ++ ++ priv = (Tn7AtmPrivate*)vcc->dev->dev_data; ++ ++ //if(skb->len < 64) ++ //xdump((unsigned char *)skb->data, skb->len, 1); ++ //else ++ //xdump((unsigned char *)skb->data, 64, 1); ++ /* check for dsl line connection */ ++ ++ /* add vcc field in skb for clip inATMARP fix */ ++ ATM_SKB(skb)->vcc = vcc; ++ /* Ron change 2.3 -> 2.4 ??*/ ++ //if(priv->lConnected != 1 || priv->xmitStop == 1) ++ if(priv->lConnected != 1 && priv->xmitStop == 1) ++ { ++ dprintf(4,"dsl line down\n"); ++ if(vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ tn7atm_kfree_skb(skb); ++ return 1; ++ } ++ ++ /* check whether PVC is closing */ ++ chan = tn7atm_lut_find(vcc->vpi, vcc->vci); ++ /* set br2684 dev pointer */ ++ priv->lut[chan].net_device = skb->dev; ++ if(chan == ATM_NO_DMA_CHAN || priv->lut[chan].bClosing == 1) ++ { ++ dprintf(4, "can find sar channel\n"); ++ if(vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ tn7atm_kfree_skb(skb); ++ return 1; ++ } ++ ++ bret=tn7atm_queue_packet_to_sar(vcc, skb); ++ ++ return bret; ++} ++ ++ ++static int tn7atm_queue_packet_to_sar(void *vcc1, void *skb1) ++{ ++ struct atm_vcc *vcc; ++ struct sk_buff *skb; ++ int priority = 1; ++ Tn7AtmPrivate *priv; ++ int dmachan; ++ ++ vcc = (struct atm_vcc *)vcc1; ++ skb = (struct sk_buff *)skb1; ++ ++ priv = (Tn7AtmPrivate*)vcc->dev->dev_data; ++ ++ dprintf(4, "vcc->vci=%d\n", vcc->vci); ++ dmachan = tn7atm_lut_find(vcc->vpi, vcc->vci); ++ if(dmachan == ATM_NO_DMA_CHAN) ++ { ++ dprintf(4, "can find sar channel\n"); ++ if(vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ tn7atm_kfree_skb(skb); ++ return 1; ++ } ++ ++ // turbo dsl TCP ack check ++ if(priv->bTurboDsl) ++ priority = turbodsl_check_priority_type(skb->data); ++ ++ //skb priority check ++ if(priority != 0) ++ { ++ if((skb->cb[47])>>1) ++ priority=1; ++ else ++ priority = 0; ++ } ++ ++ /* add queue info here */ ++ skb->cb[47] = (char)priority; ++ spin_lock_irqsave(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ priv->lut[dmachan].tx_used_bufs[priority]++; ++ spin_unlock_irqrestore(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ ++ if(tn7sar_send_packet(priv,dmachan, skb, skb->data, skb->len, priority) != 0) ++ { ++ dprintf(1, "failed to send packet\n"); ++ if(vcc->pop) ++ vcc->pop(vcc, skb); ++ else ++ tn7atm_kfree_skb(skb); ++ ++ spin_lock_irqsave(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ priv->lut[dmachan].tx_used_bufs[priority]--; ++ spin_unlock_irqrestore(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ return 1; ++ } ++ ++ /* check for whether tx queue is full or not */ ++ //printk("bufs used = %d\n", priv->lut[dmachan].tx_used_bufs[1]); ++ spin_lock_irqsave(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ if(priv->lut[dmachan].tx_used_bufs[1] >= (priv->lut[dmachan].tx_total_bufs - STOP_EMPTY_BUFF) || ++ priv->lut[dmachan].tx_used_bufs[0] >= (priv->lut[dmachan].tx_total_bufs - STOP_EMPTY_BUFF)) ++ { ++ //printk("net queue stoped\n"); ++ netif_stop_queue(priv->lut[dmachan].net_device); ++ priv->lut[dmachan].netqueue_stop = 1; ++ } ++ spin_unlock_irqrestore(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ ++ return 0; ++} ++ ++/* functions needed by SAR HAL */ ++ ++int tn7atm_send_complete(void *osSendInfo) ++{ ++ Tn7AtmPrivate *priv; ++ //struct atm_dev *dev; ++ struct sk_buff *skb; ++ struct atm_vcc *vcc; ++ int chan; ++ ++ dprintf(4, "tn7atm_send_complete()\n"); ++ ++ ++ skb = (struct sk_buff *)osSendInfo; ++ //dev = (struct atm_dev *) (skb->dev); ++ priv = (Tn7AtmPrivate *)mydev->dev_data; ++ vcc =ATM_SKB(skb)->vcc; ++ if(vcc) ++ { ++ dprintf(4, "vcc->vci=%d\n",vcc->vci ); ++ chan = tn7atm_lut_find(vcc->vpi, vcc->vci); ++ if(chan==ATM_NO_DMA_CHAN) ++ return 1; ++ ++ /*decreament packet queued number */ ++ spin_lock_irqsave(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ priv->lut[chan].tx_used_bufs[(int)skb->cb[47]] --; ++ if(priv->lut[chan].tx_used_bufs[1] < priv->lut[chan].tx_total_bufs - START_EMPTY_BUFF && ++ priv->lut[chan].tx_used_bufs[0] < priv->lut[chan].tx_total_bufs - START_EMPTY_BUFF) ++ { ++ if(priv->lut[chan].netqueue_stop) ++ { ++ //printk("net queue restarted\n"); ++ netif_wake_queue(priv->lut[chan].net_device); ++ priv->lut[chan].netqueue_stop = 0; ++ } ++ } ++ spin_unlock_irqrestore(&priv->netifqueueLock, priv->netifqueueLockFlag); ++ ++ if(vcc->pop) ++ { ++ dprintf(5, "free packet\n"); ++ vcc->pop(vcc, skb); ++ } ++ ++ ++ } ++ ++ ++ ++ /* Update Stats: There may be a better place to do this, but this is a start */ ++ priv->stats.tx_packets++; ++#ifdef CONFIG_LED_MODULE ++// led_operation(MOD_ADSL, DEF_ADSL_ACTIVITY); ++#endif ++ ++ /* track number of buffer used */ ++ ++ dprintf(4, "tn7atm_send_complete() done\n"); ++ ++ return 0; ++} ++ ++void *tn7atm_allocate_rx_skb(void *os_dev, void **os_receive_info, unsigned int size) ++{ ++ struct sk_buff *skb; ++ dprintf(4, "tn7atm_allocate_rx_skb size=%d\n", size); ++ size = ((size+3)&0xfffffffc); ++ skb = dev_alloc_skb(size); ++ if(skb==NULL) ++ { ++ //printk("rx allocate skb failed\n"); ++ return NULL; ++ } ++ *os_receive_info = (void *)skb; ++ return (skb->data); ++} ++ ++void tn7atm_free_rx_skb(void *skb) ++{ ++ dprintf(4, "tn7atm_free_rx_skb\n"); ++ tn7atm_kfree_skb((struct sk_buff *)skb); ++} ++ ++ ++int tn7atm_receive(void *os_dev, int ch, unsigned int packet_size, void *os_receive_info, void *data) ++{ ++ Tn7AtmPrivate *priv; ++ struct atm_dev *dev; ++ struct sk_buff *skb; ++ struct atm_vcc *vcc; ++ ++ ++ dprintf(4, "tn7atm_receive()\n"); ++ dev = (struct atm_dev *)os_dev; ++ ++ priv = (Tn7AtmPrivate *)dev->dev_data; ++ ++ if(priv->lConnected != 1 || priv->lut[ch].ready == 0) ++ { ++ //printk("channel not ready\n"); ++ return 1; ++ } ++ ++ vcc = (struct atm_vcc *)priv->lut[ch].vcc; ++ if(vcc == NULL) ++ { ++ printk("vcc=Null"); ++ return 1; ++ } ++ ++ ++ /* assume no fragment packet for now */ ++ skb = (struct sk_buff *)os_receive_info; ++ ++ if(skb==NULL) ++ { ++ dprintf(1, "received empty skb.\n"); ++ return 1; ++ } ++ /* see skbuff->cb definition in include/linux/skbuff.h */ ++ ATM_SKB(skb)->vcc = vcc; ++ ++ skb->len = packet_size; ++ dprintf(3, "skb:[0x%p]:0x%x pdu_len: 0x%04x\n",skb,skb->len,packet_size); ++ dprintf(3, "data location: 0x%x, 0x%x\n", (unsigned int)skb->data, (unsigned int)data); ++ ++ /*skb_trim(skb,skb->len); */ /* skb size is incorrect for large packets > 1428 bytes ?? */ ++ __skb_trim(skb,skb->len); /* change to correct > 1500 ping when firewall is on */ ++ ++ dprintf(3, "pushing the skb...\n"); ++ skb->stamp = xtime; ++ ++ xdump((unsigned char *)skb->data, skb->len, 5); ++ ++ if(atm_charge(vcc, skb->truesize) == 0) ++ { ++ dprintf(1,"Receive buffers saturated for %d.%d.%d - PDU dropped\n", vcc->itf, vcc->vci, vcc->vpi); ++ return 1; ++ } ++ ++ /*pass it up to kernel networking layer and update stats*/ ++ vcc->push(vcc,skb); ++ ++ /* Update receive packet stats */ ++ priv->stats.rx_packets++; ++ atomic_inc(&vcc->stats->rx); ++ ++#ifdef CONFIG_LED_MODULE ++// led_operation(MOD_ADSL, DEF_ADSL_ACTIVITY); ++#endif ++ dprintf(3, "(a) Receiving:vpi/vci[%d/%d] chan_id: %d skb len:0x%x skb truesize:0x%x\n", ++ vcc->vpi,vcc->vci,ch,skb->len, skb->truesize); ++ ++ return 0; ++} ++ ++static int ++tn7atm_proc_channels(char* buf, char **start, off_t offset, int count,int *eof, void *data) ++{ ++ int len = 0; ++ int limit = count - 80; ++ int i; ++ ++ struct atm_dev *dev; ++ Tn7AtmPrivate *priv; ++ ++ dev = (struct atm_dev *)data; ++ priv = (Tn7AtmPrivate *)dev->dev_data; ++ ++ if(len<=limit) ++ len += sprintf(buf+len,"Chan Inuse ChanID VPI VCI \n"); ++ if(len<=limit) ++ len += sprintf(buf+len,"------------------------------------------------------------------\n"); ++ ++ for(i=0; i < MAX_DMA_CHAN; i++) ++ { ++ if(len<=limit) ++ { ++ len += sprintf(buf+len, ++ " %02d %05d %05d %05d %05d \n", ++ i,priv->lut[i].inuse,priv->lut[i].chanid, ++ priv->lut[i].vpi,priv->lut[i].vci); ++ } ++ } ++ ++ return len; ++} ++ ++static int ++tn7atm_proc_private(char* buf, char **start, off_t offset, int count,int *eof, void *data) ++{ ++ int len = 0; ++ int limit = count - 80; ++ struct atm_dev *dev; ++ Tn7AtmPrivate *priv; ++ ++ dev = (struct atm_dev *)data; ++ priv = (Tn7AtmPrivate *)dev->dev_data; ++ ++ if(len<=limit) ++ len += sprintf(buf+len, "\nPrivate Data Structure(%s):\n",priv->name); ++ if(len<=limit) ++ len += sprintf(buf+len, "----------------------------------------\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "priv: 0x%p\n",priv); ++ if(len<=limit) ++ len += sprintf(buf+len, "next: 0x%p",priv->next); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tdev: 0x%p\n",priv->dev); ++ ++ if(len<=limit) ++ len += sprintf(buf+len, "tx_irq: %02d",priv->sar_irq); ++ if(len<=limit) ++ len += sprintf(buf+len, "rx_irq: %02d",priv->dsl_irq); ++ ++ ++ return len; ++} ++ ++void tn7atm_sarhal_isr_register(void *os_dev, void *hal_isr, int interrupt_num) ++{ ++ struct atm_dev *dev; ++ Tn7AtmPrivate *priv; ++ ++ dprintf(4, "tn7atm_sarhal_isr_register()\n"); ++ ++ dev = (struct atm_dev *)os_dev; ++ priv = (Tn7AtmPrivate *)dev->dev_data; ++ priv->halIsr = (void *)hal_isr; ++ priv->int_num = interrupt_num; ++} ++ ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_exit(void) ++ * ++ * Description: Avalanche SAR exit function ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++ ++static void ++tn7atm_exit (void) ++{ ++ ++ struct atm_dev *dev; ++ ++ Tn7AtmPrivate *priv; ++ ++ dprintf(4, "tn7atm_exit()\n"); ++ ++ dev=mydev; ++ priv = (Tn7AtmPrivate *)dev->dev_data; ++ priv->lConnected = 0; ++ tn7dsl_exit(); ++ ++ tn7sar_exit(dev, priv); ++ ++ /* freeup irq's */ ++ free_irq(priv->dsl_irq,priv->dev); ++ free_irq(priv->sar_irq,priv->dev); ++ ++ kfree (dev->dev_data); ++ ++ // atm_dev_deregister (dev); ++ shutdown_atm_dev(dev); ++ ++ /* remove proc entries */ ++ remove_proc_entry("tiatm/avsar_ver",NULL); ++ remove_proc_entry("tiatm/avsar_modem_stats",NULL); ++ remove_proc_entry("tiatm/avsar_modem_training",NULL); ++ remove_proc_entry("tiatm/avsar_channels",NULL); ++ remove_proc_entry("tiatm/avsar_private",NULL); ++ remove_proc_entry("tiatm/avsar_sarhal_stats",NULL); ++ remove_proc_entry("tiatm/avsar_oam_ping",NULL); ++ remove_proc_entry("tiatm/avsar_pvc_table",NULL); ++ remove_proc_entry("tiatm",NULL); ++ tn7dsl_dslmod_sysctl_unregister(); ++ ++ printk ("Module Removed\n"); ++ ++} ++ ++ ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_registration(struct tn7* tn7) ++ * ++ * Description: ATM driver registration ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++ ++static int __init ++tn7atm_register (Tn7AtmPrivate * priv) ++{ ++ /* allocate memory for the device */ ++ ++ dprintf(4,"device %s being registered\n", priv->name); ++ ++ mydev = atm_dev_register (priv->proc_name, &tn7atm_ops, -1, NULL); ++ ++ if (mydev == NULL) ++ { ++ printk ("atm_dev_register returning NULL\n"); ++ return ATM_REG_FAILED; ++ } ++ ++ printk ("registered device %s\n", priv->name); ++ ++ mydev->dev_data = priv; /* setup device data in atm_dev struct */ ++ priv->dev = mydev; /* setup atm_device in avalanche sar struct */ ++ ++ mydev->ci_range.vpi_bits = ATM_CI_MAX; /* atm supports 11 bits */ ++ mydev->ci_range.vci_bits = 16; /* atm VCI max = 16 bits */ ++ ++ ++ return ATM_REG_OK; ++} ++ ++static int ++tn7atm_proc_version(char* buf, char **start, off_t offset, int count,int *eof, void *data) ++{ ++ int len = 0; ++ char dslVer[8]; ++ char dspVer[10]; ++ char *pSarVer; ++ Tn7AtmPrivate *priv; ++ int i; ++ unsigned int pdspV1, pdspV2; ++ ++ priv = mydev->dev_data; ++ ++ len += sprintf(buf+len, "ATM Driver version:[%d.%02d.%02d.%02d]\n",LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR, ++ LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM); ++ ++ tn7dsl_get_dslhal_version(dslVer); ++ ++ len += sprintf(buf+len, "DSL HAL version: [%d.%02d.%02d.%02d]\n", dslVer[0], dslVer[1], dslVer[2], ++ dslVer[3]); ++ tn7dsl_get_dsp_version(dspVer); ++ ++ len += sprintf(buf+len, "DSP Datapump version: [%d.%02d.%02d.%02d] ", dspVer[4], dspVer[5], dspVer[6], ++ dspVer[7]); ++ if(dspVer[8]==2) // annex B ++ len += sprintf(buf+len, "Annex B\n"); ++ else if(dspVer[8]==3) //annex c ++ len += sprintf(buf+len, "Annex c\n"); ++ else ++ len += sprintf(buf+len, "Annex A\n"); ++ ++ tn7sar_get_sar_version(priv, &pSarVer); ++ ++ len += sprintf(buf+len, "SAR HAL version: ["); ++ for(i=0;i<8;i++) ++ { ++ len += sprintf(buf+len, "%c", pSarVer[i+7]); ++ } ++ len += sprintf(buf+len, "]\n"); ++ ++ tn7sar_get_sar_firmware_version(&pdspV1, &pdspV2); ++ len += sprintf(buf+len, "PDSP Firmware version:[%01x.%02x]\n", ++ pdspV1,pdspV2); ++ ++ return len; ++} ++ ++/* ++static struct net_device_stats ++*tn7atm_get_stats(struct atm_dev *dev) ++{ ++ Tn7AtmPrivate *priv; ++ //unsigned long flags; ++ ++ //spin_lock_irqsave(&priv->stats_lock,flags); ++ priv= (Tn7AtmPrivate *)dev->dev_data; ++ //spin_unlock_irqrestore(&priv->stats_lock,flags); ++ ++ return &priv->stats; ++ ++} ++*/ ++/* Device detection */ ++ ++static int __init ++tn7atm_detect (void) ++{ ++ Tn7AtmPrivate *priv; ++ //static struct proc_dir_entry *proc_dir; ++ ++ dprintf(4, "tn7atm_detect().\n"); ++ /* Device allocated as a global static structure at top of code "mydev" */ ++ ++ /* Alloc priv struct */ ++ priv=kmalloc(sizeof(Tn7AtmPrivate),GFP_KERNEL); ++ if(!priv) ++ { ++ printk("unable to kmalloc priv structure. Killing autoprobe.\n"); ++ return -ENODEV; ++ } ++ memset(priv, 0, sizeof(Tn7AtmPrivate)); ++#ifdef COMMON_NSP ++ priv->name = "TI Avalanche SAR"; ++ priv->proc_name = "avsar"; ++#else ++ priv->name = "TI tnetd73xx ATM Driver"; ++ priv->proc_name = "tn7"; ++#endif ++ ++ if ((tn7atm_register (priv)) == ATM_REG_FAILED) ++ return -ENODEV; ++ ++ tn7atm_init(mydev); ++ ++ /* Set up proc entry for atm stats */ ++ proc_mkdir("tiatm", NULL); ++ create_proc_read_entry("tiatm/avsar_modem_stats",0,NULL,tn7dsl_proc_stats,NULL); ++ create_proc_read_entry("tiatm/avsar_modem_training",0,NULL,tn7dsl_proc_modem,NULL); ++ create_proc_read_entry("tiatm/avsar_ver",0,NULL,tn7atm_proc_version,NULL); ++ create_proc_read_entry("tiatm/avsar_channels",0,NULL,tn7atm_proc_channels,mydev); ++ create_proc_read_entry("tiatm/avsar_private",0,NULL,tn7atm_proc_private,mydev); ++ create_proc_read_entry("tiatm/avsar_sarhal_stats",0,NULL,tn7sar_proc_sar_stat,mydev); ++ create_proc_read_entry("tiatm/avsar_oam_ping",0,NULL,tn7sar_proc_oam_ping,mydev); ++ create_proc_read_entry("tiatm/avsar_pvc_table",0,NULL,tn7sar_proc_pvc_table,mydev); ++ ++ tn7dsl_dslmod_sysctl_register(); ++ ++ printk("Texas Instruments ATM driver: version:[%d.%02d.%02d.%02d]\n",LINUXATM_VERSION_MAJOR, LINUXATM_VERSION_MINOR, ++ LINUXATM_VERSION_BUGFIX, LINUXATM_VERSION_BUILDNUM); ++ return 0; ++} ++ ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_probe(void) ++ * ++ * Description: Avalanche SAR driver probe (see net/atm/pvc.c) ++ * this is utilized when the SAR driver is built ++ * into the kernel and needs to be configured. ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++int __init tn7atm_probe(void) ++{ ++ tn7atm_detect(); ++ return -ENODEV; ++} ++ ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int tn7atm_init(struct atm_dev *dev) ++ * ++ * Description: Device Initialization ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++static int __init ++tn7atm_init(struct atm_dev *dev) ++{ ++ Tn7AtmPrivate *priv; ++ char *ptr; ++ ++ dprintf(4, "tn7atm_init()\n"); ++ ++ priv = (Tn7AtmPrivate *)dev->dev_data; ++ ++ if(tn7sar_init(dev, priv) != 0) ++ { ++ printk("Failed to init SAR.\n"); ++ return -ENODEV; ++ } ++ ++ if(tn7dsl_init(priv) < 0) ++ { ++ printk("Failed to init DSL.\n"); ++ return -ENODEV; ++ } ++ ++ if(tn7atm_get_ESI(dev) < 0) /* set ESI */ ++ return -ENODEV; ++ ++ if(tn7atm_irq_request(dev) < 0) ++ return -EBUSY; ++ ++ priv->bTurboDsl = 1; ++ // read config for turbo dsl ++ ptr = prom_getenv("TurboDSL"); ++ if(ptr) ++ { ++ priv->bTurboDsl = os_atoi(ptr); ++ } ++ ++ return 0; ++} ++ ++int tn7atm_device_connect_status(void *priv, int state) ++{ ++ Tn7AtmPrivate *priv1; ++ ++ dprintf(5, "tn7atm_device_connect_status()\n"); ++ priv1 = (Tn7AtmPrivate *)priv; ++ ++ priv1->lConnected = state; ++ dprintf(5, "priv1->lConnected=%d\n", priv1->lConnected); ++ return 0; ++} ++ ++ ++#ifdef MODULE ++module_init (tn7atm_detect); ++module_exit (tn7atm_exit); ++#endif /* MODULE */ +diff -urN linux.old/drivers/atm/sangam_atm/tn7atm.h linux.dev/drivers/atm/sangam_atm/tn7atm.h +--- linux.old/drivers/atm/sangam_atm/tn7atm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/tn7atm.h 2005-08-23 04:46:50.107842176 +0200 +@@ -0,0 +1,115 @@ ++/* ++ * Tnetd73xx ATM driver. ++ * by Zhicheng Tang, ztang@ti.com ++ * 2000 (c) Texas Instruments Inc. ++ * ++ * ++*/ ++ ++#ifndef __TN7ATM_H ++#define __TN7ATM_H ++ ++//#include "mips_support.h" ++#include ++ ++#define ATM_REG_OK 1 ++#define ATM_REG_FAILED 0 ++ ++#define TX_SERVICE_MAX 32 ++#define RX_SERVICE_MAX 20 ++#define TX_BUFFER_NUM 64 ++#define RX_BUFFER_NUM 28 ++#define TX_QUEUE_NUM 2 ++#define RX_BUFFER_SIZE 1582 ++ ++#define TX_DMA_CHAN 16 /* number of tx dma channels available */ ++#define MAX_DMA_CHAN 16 ++#define ATM_NO_DMA_CHAN MAX_DMA_CHAN + 1 /* no tx dma channels available */ ++#define ATM_SAR_INT 15 ++#define ATM_SAR_INT_PACING_BLOCK_NUM 2 ++#define ATM_DSL_INT 39 ++ ++#define CONFIG_ATM_TN7ATM_DEBUG 0 /* Debug level (0=no mtn7s 5=verbose) */ ++ ++#define TN7ATM_DEV(d) ((struct tn7atm*)((d)->dev_data)) ++ ++ ++/* Avalanche SAR state information */ ++ ++typedef enum tn7atm_state ++{ ++ TN7ATM_STATE_REGISTER /* device registered */ ++}tn7atm_state; ++ ++typedef struct _sar_stat ++{ ++ unsigned int txErrors; ++ unsigned int rxErrors; ++ unsigned int rxPktCnt; ++ unsigned int txPktCnt; ++ unsigned int rxBytes; ++ unsigned int txBytes; ++}sar_stat_t; ++ ++/* Host based look up table to xref Channel Id's, VPI/VCI, LC, CID, packet type */ ++typedef struct _tn7atm_tx_lut ++{ ++ int inuse; /* is DMA channel available (1=y) */ ++ int chanid; /* DMA channel ID (0-0x1f) This corresponds to the Channel ID ++ that is used in the connection config reg (TN7ATM_CONN_CONFIG) */ ++ int vpi; /* Virtual path identifier */ ++ int vci; /* Virtual channel identifier */ ++ void *vcc; ++ int bClosing; ++ int ready; ++ void *net_device; ++ int tx_total_bufs; ++ int tx_used_bufs[2]; ++ int netqueue_stop; ++}tn7atm_lut_t; ++ ++/* per device data */ ++ ++typedef struct _tn7atm_private ++{ ++ struct _tn7atm_private *next; /* next device */ ++ struct atm_dev *dev; /* ATM device */ ++ struct net_device_stats stats; /* Used to report Tx/Rx frames from ifconfig */ ++ tn7atm_lut_t lut[MAX_DMA_CHAN]; /* Tx DMA look up table (LUT) */ ++ int dsl_irq; /* ATM SAR TransmitA interrupt number */ ++ int sar_irq; /* ATM SAR ReceiveA interrupt number */ ++ char* name; /* device name */ ++ char* proc_name; /* board name under /proc/atm */ ++ unsigned int available_cell_rate; /* cell rate */ ++ unsigned int connection_cell_rate; /* cell rate */ ++ int lConnected; ++ ++ /* Tnetd73xx CPHAL */ ++ void *pSarHalDev; ++ void *pSarHalFunc; ++ void *pSarOsFunc; ++ void *halIsr; ++ int int_num; ++ ++ /* turbo dsl */ ++ int bTurboDsl; ++ ++ /* spin lock for netifqueue */ ++ spinlock_t netifqueueLock; ++ int netifqueueLockFlag; ++ int xmitStop; /* temp fix for SAR problem */ ++}tn7atm_private_t, Tn7AtmPrivate; ++ ++ ++ ++/* ATM adaptation layer id */ ++typedef enum tn7atm_aal { ++ TN7ATM_AAL0 = 0, ++ TN7ATM_AAL2 = 2, ++ TN7ATM_AAL5 = 5, ++} tn7atm_aal_t; ++ ++ ++ ++ ++#endif +diff -urN linux.old/drivers/atm/sangam_atm/tn7dsl.c linux.dev/drivers/atm/sangam_atm/tn7dsl.c +--- linux.old/drivers/atm/sangam_atm/tn7dsl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/tn7dsl.c 2005-08-23 04:46:50.109841872 +0200 +@@ -0,0 +1,1780 @@ ++/* ++ * $Id$ ++ * ++ * Avalanche SAR driver ++ * ++ * Zhicheng Tang, ztang@ti.com ++ * 2000 (c) Texas Instruments Inc. ++ * ++ * ++*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "tn7atm.h" ++#include "tn7api.h" ++#include "dsl_hal_api.h" ++ ++#ifdef CONFIG_LED_MODULE ++#include ++#define MOD_ADSL 1 ++#define DEF_ADSL_IDLE 1 ++#define DEF_ADSL_TRAINING 2 ++#define DEF_ADSL_SYNC 3 ++#define DEF_ADSL_ACTIVITY 4 ++ ++#define LED_NUM_1 3 ++#define LED_NUM_2 4 ++ ++led_reg_t ledreg[2]; ++ ++static int led_on; ++#endif ++ ++extern int __guDbgLevel; ++extern sar_stat_t sarStat; ++static int dslInSync = 0; ++static int bMarginThConfig; ++static int bMarginRetrainEnable; ++static char EOCVendorID[8]= {0xb5, 0x00, 0x54, 0x53, 0x54, 0x43, 0x00, 0x00}; ++ ++#define TC_SYNC 1 ++#define SYNC_TIME_DELAY 500000 ++ ++ ++#define DEV_DSLMOD 1 ++#define MAX_STR_SIZE 256 ++#define DSL_MOD_SIZE 256 ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++ ++enum ++{ ++ NO_MODE, ++ MULTI_MODE, ++ T1413_MODE, ++ GDMT_MODE, ++ GLITE_MODE ++}; ++ ++ ++ ++/* a structure to store all information we need ++ for our thread */ ++typedef struct kthread_struct ++{ ++ /* private data */ ++ ++ /* Linux task structure of thread */ ++ struct task_struct *thread; ++ /* Task queue need to launch thread */ ++ struct tq_struct tq; ++ /* function to be started as thread */ ++ void (*function) (struct kthread_struct *kthread); ++ /* semaphore needed on start and creation of thread. */ ++ struct semaphore startstop_sem; ++ ++ /* public data */ ++ ++ /* queue thread is waiting on. Gets initialized by ++ init_kthread, can be used by thread itself. ++ */ ++ wait_queue_head_t queue; ++ /* flag to tell thread whether to die or not. ++ When the thread receives a signal, it must check ++ the value of terminate and call exit_kthread and terminate ++ if set. ++ */ ++ int terminate; ++ /* additional data to pass to kernel thread */ ++ void *arg; ++} kthread_t; ++ ++#ifndef ADIAG ++#define DSP_FIRMWARE_PATH "/lib/modules/ar0700xx.bin" ++#else ++#define DSP_FIRMWARE_PATH "/var/tmp/ar0700xx_diag.bin" ++#endif ++ ++/* externs */ ++extern struct atm_dev *mydev; ++extern unsigned int oamFarLBCount[4]; ++extern int dslhal_support_restoreTrainingInfo(PITIDSLHW_T pIhw); ++/* gloabal functions */ ++ ++/* end of global functions */ ++ ++/* module wide declars */ ++static PITIDSLHW_T pIhw; ++static char mod_req[16]={'\t'}; ++static volatile int bshutdown; ++static char info[MAX_STR_SIZE]; ++static DECLARE_MUTEX_LOCKED(adsl_sem_overlay); /* Used for DSL Polling enable */ ++kthread_t overlay_thread; ++/* end of module wide declars */ ++ ++/* Internal Functions */ ++static void tn7dsl_chng_modulation(void* data); ++static void tn7dsl_set_modulation(void* data); ++static int tn7dsl_reload_overlay(void); ++static int dslmod_sysctl(ctl_table *ctl, int write, struct file * filp, void *buffer, size_t *lenp); ++static void tn7dsl_register_dslss_led(void); ++void tn7dsl_dslmod_sysctl_register(void); ++void tn7dsl_dslmod_sysctl_unregister(void); ++/* end of internal functions */ ++ ++ ++ ++ ++ ++/* prototypes */ ++ ++/* start new kthread (called by creator) */ ++void start_kthread(void (*func)(kthread_t *), kthread_t *kthread); ++ ++/* stop a running thread (called by "killer") */ ++void stop_kthread(kthread_t *kthread); ++ ++/* setup thread environment (called by new thread) */ ++void init_kthread(kthread_t *kthread, char *name); ++ ++/* cleanup thread environment (called by thread upon receiving termination signal) */ ++void exit_kthread(kthread_t *kthread); ++ ++ ++ ++/* private functions */ ++static void kthread_launcher(void *data) ++{ ++ kthread_t *kthread = data; ++ kernel_thread((int (*)(void *))kthread->function, (void *)kthread, 0); ++ ++} ++ ++/* public functions */ ++ ++/* create a new kernel thread. Called by the creator. */ ++void start_kthread(void (*func)(kthread_t *), kthread_t *kthread) ++{ ++ /* initialize the semaphore: ++ we start with the semaphore locked. The new kernel ++ thread will setup its stuff and unlock it. This ++ control flow (the one that creates the thread) blocks ++ in the down operation below until the thread has reached ++ the up() operation. ++ */ ++ //init_MUTEX_LOCKED(&kthread->startstop_sem); ++ ++ /* store the function to be executed in the data passed to ++ the launcher */ ++ kthread->function=func; ++ ++ /* create the new thread my running a task through keventd */ ++ ++ /* initialize the task queue structure */ ++ kthread->tq.sync = 0; ++ INIT_LIST_HEAD(&kthread->tq.list); ++ kthread->tq.routine = kthread_launcher; ++ kthread->tq.data = kthread; ++ ++ /* and schedule it for execution */ ++ schedule_task(&kthread->tq); ++ ++ /* wait till it has reached the setup_thread routine */ ++ //down(&kthread->startstop_sem); ++ ++} ++ ++/* stop a kernel thread. Called by the removing instance */ ++void stop_kthread(kthread_t *kthread) ++{ ++ if (kthread->thread == NULL) ++ { ++ printk("stop_kthread: killing non existing thread!\n"); ++ return; ++ } ++ ++ /* this function needs to be protected with the big ++ kernel lock (lock_kernel()). The lock must be ++ grabbed before changing the terminate ++ flag and released after the down() call. */ ++ lock_kernel(); ++ ++ /* initialize the semaphore. We lock it here, the ++ leave_thread call of the thread to be terminated ++ will unlock it. As soon as we see the semaphore ++ unlocked, we know that the thread has exited. ++ */ ++ //init_MUTEX_LOCKED(&kthread->startstop_sem); ++ ++ /* We need to do a memory barrier here to be sure that ++ the flags are visible on all CPUs. ++ */ ++ mb(); ++ ++ /* set flag to request thread termination */ ++ kthread->terminate = 1; ++ ++ /* We need to do a memory barrier here to be sure that ++ the flags are visible on all CPUs. ++ */ ++ mb(); ++ kill_proc(kthread->thread->pid, SIGKILL, 1); ++ ++ /* block till thread terminated */ ++ //down(&kthread->startstop_sem); ++ ++ /* release the big kernel lock */ ++ unlock_kernel(); ++ ++ /* now we are sure the thread is in zombie state. We ++ notify keventd to clean the process up. ++ */ ++ kill_proc(2, SIGCHLD, 1); ++ ++} ++ ++/* initialize new created thread. Called by the new thread. */ ++void init_kthread(kthread_t *kthread, char *name) ++{ ++ /* lock the kernel. A new kernel thread starts without ++ the big kernel lock, regardless of the lock state ++ of the creator (the lock level is *not* inheritated) ++ */ ++ lock_kernel(); ++ ++ /* fill in thread structure */ ++ kthread->thread = current; ++ ++ /* set signal mask to what we want to respond */ ++ siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)); ++ ++ /* initialise wait queue */ ++ init_waitqueue_head(&kthread->queue); ++ ++ /* initialise termination flag */ ++ kthread->terminate = 0; ++ ++ /* set name of this process (max 15 chars + 0 !) */ ++ sprintf(current->comm, name); ++ ++ /* let others run */ ++ unlock_kernel(); ++ ++ /* tell the creator that we are ready and let him continue */ ++ //up(&kthread->startstop_sem); ++ ++} ++ ++/* cleanup of thread. Called by the exiting thread. */ ++void exit_kthread(kthread_t *kthread) ++{ ++ /* we are terminating */ ++ ++ /* lock the kernel, the exit will unlock it */ ++ lock_kernel(); ++ kthread->thread = NULL; ++ mb(); ++ ++ /* notify the stop_kthread() routine that we are terminating. */ ++ //up(&kthread->startstop_sem); ++ /* the kernel_thread that called clone() does a do_exit here. */ ++ ++ /* there is no race here between execution of the "killer" and real termination ++ of the thread (race window between up and do_exit), since both the ++ thread and the "killer" function are running with the kernel lock held. ++ The kernel lock will be freed after the thread exited, so the code ++ is really not executed anymore as soon as the unload functions gets ++ the kernel lock back. ++ The init process may not have made the cleanup of the process here, ++ but the cleanup can be done safely with the module unloaded. ++ */ ++ ++} ++ ++ ++ ++int os_atoi(const char *pStr) ++{ ++ int retVal = -1; ++ ++ if(*pStr=='-') ++ retVal = -simple_strtoul(pStr+1, (char **)NULL, 10); ++ else ++ retVal = simple_strtoul(pStr, (char **)NULL, 10); ++ return retVal ; ++} ++ ++ ++int os_atoh(const char *pStr) ++{ ++ int retVal = -1; ++ ++ if(*pStr=='-') ++ retVal = -simple_strtoul(pStr+1, (char **)NULL, 16); ++ else ++ retVal = simple_strtoul(pStr, (char **)NULL, 16); ++ return retVal ; ++} ++ ++unsigned long os_atoul(const char *pStr) ++{ ++ unsigned long retVal = -1; ++ ++ retVal = simple_strtoul(pStr, (char **)NULL, 10); ++ return retVal ; ++} ++ ++void dprintf( int uDbgLevel, char * szFmt, ...) ++{ ++#ifdef DEBUG_BUILD ++ static char buff[256]; ++ va_list ap; ++ ++ if( __guDbgLevel < uDbgLevel) ++ return; ++ ++ va_start( ap, szFmt); ++ vsprintf((char *)buff, szFmt, ap); ++ va_end(ap); ++ printk("%s", buff); ++#endif ++} ++ ++/*int strcmp(const char *s1, const char *s2) ++{ ++ ++ int i=0; ++ ++ while(s1[i] !=0) ++ { ++ if(s2[i]==0) ++ return -1; ++ if(s1[i] != s2[i]) ++ return 1; ++ i++; ++ } ++ if(s2[i] != 0) ++ return 1; ++ return 0; ++} ++*/ ++ ++int shim_osLoadFWImage(unsigned char *ptr) ++{ ++ unsigned int bytesRead; ++ mm_segment_t oldfs; ++ static struct file *filp; ++ unsigned int imageLength=0x4ffff; ++ ++ ++ dprintf(4, "tn7dsl_read_dsp()\n"); ++ ++ dprintf(4,"open file %s\n", DSP_FIRMWARE_PATH); ++ ++ filp=filp_open(DSP_FIRMWARE_PATH ++ ,00,O_RDONLY); ++ ++ if(filp ==NULL) ++ { ++ printk("Failed: Could not open DSP binary file\n"); ++ return -1; ++ } ++ ++ if (filp->f_op->read==NULL) ++ return -1; /* File(system) doesn't allow reads */ ++ ++ /* Now read bytes from postion "StartPos" */ ++ filp->f_pos = 0; ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ bytesRead = filp->f_op->read(filp,ptr,imageLength,&filp->f_pos); ++ ++ dprintf(4,"file length = %d\n", bytesRead); ++ ++ set_fs(oldfs); ++ ++ /* Close the file */ ++ fput(filp); ++ ++ return bytesRead; ++} ++ ++unsigned int shim_read_overlay_page(void *ptr, unsigned int secOffset, unsigned int secLength) ++{ ++ unsigned int bytesRead; ++ mm_segment_t oldfs; ++ struct file *filp; ++ ++ dprintf(4,"shim_read_overlay_page\n"); ++ //dprintf(4,"sec offset=%d, sec length =%d\n", secOffset, secLength); ++ ++ filp=filp_open(DSP_FIRMWARE_PATH,00,O_RDONLY); ++ if(filp ==NULL) ++ { ++ printk("Failed: Could not open DSP binary file\n"); ++ return -1; ++ } ++ ++ if (filp->f_op->read==NULL) ++ return -1; /* File(system) doesn't allow reads */ ++ ++ /* Now read bytes from postion "StartPos" */ ++ ++ if(filp->f_op->llseek) ++ filp->f_op->llseek(filp,secOffset, 0); ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ filp->f_pos = secOffset; ++ bytesRead = filp->f_op->read(filp,ptr,secLength,&filp->f_pos); ++ ++ set_fs(oldfs); ++ /* Close the file */ ++ fput(filp); ++ return bytesRead; ++} ++ ++int shim_osLoadDebugFWImage(unsigned char *ptr) ++{ ++ return 0; ++} ++int shim_osStringCmp(const char *s1, const char *s2) ++{ ++ return strcmp(s1, s2); ++} ++ ++void *shim_osAllocateMemory(unsigned int size) ++{ ++ return ((void *)kmalloc(size, GFP_KERNEL)); ++} ++ ++void *shim_osAllocateDmaMemory(unsigned int size) ++{ ++ /* ++ int order; ++ ++ order=1; ++ size=size/4096; ++ while(size >= 1) ++ { ++ order++; ++ size=size/2; ++ } ++ ++ return ( (void *)__get_free_pages(GFP_ATOMIC, order)); ++ */ ++ //return ((void *)kmalloc(size, GFP_ATOMIC)); ++ //return ((void *)kmalloc(size, GFP_KERNEL)); ++ void *ptr; ++ ++ ptr = kmalloc(size, GFP_ATOMIC); ++ if(ptr==NULL) ++ { ++ printk("failed atomic\n"); ++ ptr = kmalloc(size, GFP_KERNEL); ++ if(ptr==NULL) ++ { ++ printk("failed kernel\n"); ++ ptr = kmalloc(size, GFP_KERNEL|GFP_DMA); ++ } ++ } ++ printk("size=%d\n", size); ++ return ptr; ++ ++} ++ ++ ++void shim_osFreeMemory(void *ptr, unsigned int size) ++{ ++ ++ kfree(ptr); ++} ++ ++void shim_osFreeDmaMemory(void *ptr, unsigned int size) ++{ ++/* ++ int order; ++ ++ order=1; ++ size=size/4096; ++ while(size >=1) ++ { ++ order++; ++ size=size/2; ++ } ++ free_pages(ptr, order); ++*/ ++ kfree(ptr); ++} ++ ++void *shim_osAllocateVMemory(unsigned int size) ++{ ++ ++ return ((void *)vmalloc(size)); ++} ++ ++void shim_osFreeVMemory(void *ptr, unsigned int size) ++{ ++ vfree(ptr); ++} ++ ++void shim_osMoveMemory(char *dst, char *src, unsigned int numBytes) ++{ ++ memcpy(dst, src, numBytes); ++} ++ ++void shim_osZeroMemory(char *dst, unsigned int numBytes) ++{ ++ memset(dst, 0, numBytes); ++} ++ ++void shim_osWriteBackCache(void *addr, unsigned int size) ++{ ++ unsigned int i,Size=(((unsigned int)addr)&0xf)+size; ++ ++ for (i=0;i 1000) ++ { ++ mdelay(chkvalue/1000); ++ return; ++ } ++ else ++ udelay(val/64); ++} /* end of cwait() */ ++ ++unsigned int shim_osClockTick(int val) ++{ ++ return jiffies; ++} ++ ++int flags; ++spinlock_t shimLock; ++ ++void shim_osCriticalEnter(void) ++{ ++ spin_lock_irqsave(&shimLock, flags); ++ ++} ++ ++ ++void shim_osCriticalExit(void) ++{ ++ spin_unlock_irqrestore(&shimLock, flags); ++} ++ ++ ++int tn7dsl_proc_stats(char* buf, char **start, off_t offset, int count, ++ int *eof, void *data) ++{ ++ ++ int len = 0; ++ int limit = count - 80; ++ int F4count, F5count; ++ ++ ++ /* Read Ax5 Stats */ ++ dslhal_api_gatherStatistics(pIhw); ++ ++ if(len<=limit) ++ len += sprintf(buf+len, "\nAR7 DSL Modem Statistics:\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "--------------------------------\n"); ++ /* us and ds Connection Rates */ ++ if(len<=limit) ++ len += sprintf(buf+len, "[DSL Modem Stats]\n"); ++ ++ ++ if(len<=limit) ++ { ++ if(pIhw->lConnected != 1) ++ { ++ pIhw->AppData.USConRate = 0; ++ pIhw->AppData.DSConRate = 0; ++ } ++ len += sprintf(buf+len, "\tUS Connection Rate:\t%u\tDS Connection Rate:\t%u\n", ++ (unsigned int)pIhw->AppData.USConRate, ++ (unsigned int)pIhw->AppData.DSConRate ); ++ } ++ if(len<=limit) ++ len += sprintf(buf+len, "\tDS Line Attenuation:\t%u\tDS Margin:\t\t%u\n", ++ (unsigned int)pIhw->AppData.dsLineAttn/2, ++ (unsigned int)pIhw->AppData.dsMargin/2 ); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tUS Line Attenuation:\t%u\tUS Margin:\t\t%u\n", ++ (unsigned int)pIhw->AppData.usLineAttn, ++ (unsigned int)pIhw->AppData.usMargin ); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tUS Payload :\t\t%u\tDS Payload:\t\t%u\n", ++ ((unsigned int)pIhw->AppData.usAtm_count[0] + (unsigned int)pIhw->AppData.usAtm_count[1])*48, ++ ((unsigned int)pIhw->AppData.dsGood_count[0] + (unsigned int)pIhw->AppData.dsGood_count[1])*48); ++ /* Superframe Count */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\tUS Superframe Cnt :\t%u\tDS Superframe Cnt:\t%u\n", ++ (unsigned int)pIhw->AppData.usSuperFrmCnt, ++ (unsigned int)pIhw->AppData.dsSuperFrmCnt ); ++ ++ /* US and DS power */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\tUS Transmit Power :\t%u\tDS Transmit Power:\t%u\n", ++ (unsigned int)pIhw->AppData.usTxPower/256, ++ (unsigned int)pIhw->AppData.dsTxPower/256 ); ++ /* DSL Stats Errors*/ ++ if(len<=limit) ++ len += sprintf(buf+len, "\tLOS errors:\t\t%u\tSEF errors:\t\t%u\n", ++ (unsigned int)pIhw->AppData.LOS_errors, ++ (unsigned int)pIhw->AppData.SEF_errors ); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tFrame mode:\t\t%u\tMax Frame mode:\t\t%u\n", ++ (unsigned int)pIhw->AppData.FrmMode, ++ (unsigned int)pIhw->AppData.MaxFrmMode ); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tTrained Path:\t\t%u\tUS Peak Cell Rate:\t%u\n", ++ (unsigned int)pIhw->AppData.TrainedPath, ++ (unsigned int)pIhw->AppData.USConRate*1000/8/53 ); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tTrained Mode:\t\t%u\tSelected Mode:\t\t%u\n", ++ (unsigned int)pIhw->AppData.TrainedMode, (unsigned int)pIhw->AppData.StdMode ); ++ ++ if(len<=limit) ++ len += sprintf(buf+len, "\tATUC Vendor ID:\t%u\tATUC Revision:\t\t%u\n", ++ (unsigned int)pIhw->AppData.atucVendorId, pIhw->AppData.atucRevisionNum); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tHybrid Selected:\t%u\n", ++ (unsigned int)pIhw->AppData.currentHybridNum); ++ ++ /* Upstream Interleaved Errors */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\n\t[Upstream (TX) Interleave path]\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n", ++ (unsigned int)pIhw->AppData.usICRC_errors, ++ (unsigned int)pIhw->AppData.usIFEC_errors, ++ (unsigned int)pIhw->AppData.usINCD_error); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n", ++ (unsigned int)pIhw->AppData.usILCD_errors, ++ (unsigned int)pIhw->AppData.usIHEC_errors); ++ /* Downstream Interleaved Errors */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\n\t[Downstream (RX) Interleave path]\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n", ++ (unsigned int)pIhw->AppData.dsICRC_errors, ++ (unsigned int)pIhw->AppData.dsIFEC_errors, ++ (unsigned int)pIhw->AppData.dsINCD_error); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n", ++ (unsigned int)pIhw->AppData.dsILCD_errors, ++ (unsigned int)pIhw->AppData.dsIHEC_errors); ++ /* Upstream Fast Errors */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\n\t[Upstream (TX) Fast path]\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n", ++ (unsigned int)pIhw->AppData.usFCRC_errors, ++ (unsigned int)pIhw->AppData.usFFEC_errors, ++ (unsigned int)pIhw->AppData.usFNCD_error); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n", ++ (unsigned int)pIhw->AppData.usFLCD_errors, ++ (unsigned int)pIhw->AppData.usFHEC_errors); ++ /* Downstream Fast Errors */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\n\t[Downstream (RX) Fast path]\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tCRC: \t%u\tFEC: \t%u\tNCD: \t%u\n", ++ (unsigned int)pIhw->AppData.dsFCRC_errors, ++ (unsigned int)pIhw->AppData.dsFFEC_errors, ++ (unsigned int)pIhw->AppData.dsFNCD_error); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tLCD: \t%u\tHEC: \t%u\n", ++ (unsigned int)pIhw->AppData.dsFLCD_errors, ++ (unsigned int)pIhw->AppData.dsFHEC_errors); ++ /* ATM stats upstream */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\n[ATM Stats]"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\n\t[Upstream/TX]\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\n", ++ (unsigned int)pIhw->AppData.usAtm_count[0] + (unsigned int)pIhw->AppData.usAtm_count[1], ++ (unsigned int)pIhw->AppData.usIdle_count[0] + (unsigned int)pIhw->AppData.usIdle_count[1]); ++ /* ATM stats downstream */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\n\t[Downstream/RX)]\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tGood Cell Cnt:\t%u\n\tIdle Cell Cnt:\t%u\n\tBad Hec Cell Cnt:\t%u\n", ++ (unsigned int)pIhw->AppData.dsGood_count[0] + (unsigned int)pIhw->AppData.dsGood_count[1], ++ (unsigned int)pIhw->AppData.dsIdle_count[0] + (unsigned int)pIhw->AppData.dsIdle_count[1], ++ (unsigned int)pIhw->AppData.dsBadHec_count[0] + (unsigned int)pIhw->AppData.dsBadHec_count[1]); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tOverflow Dropped Cell Cnt:\t%u\n", ++ (unsigned int)pIhw->AppData.dsOVFDrop_count[0] + (unsigned int)pIhw->AppData.dsOVFDrop_count[1]); ++ tn7sar_get_stats(pIhw->pOsContext); ++ if(len<=limit) ++ len += sprintf(buf+len, "\n[SAR AAL5 Stats]\n"); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tTx PDU's:\t%u\n\tRx PDU's:\t%u\n", ++ sarStat.txPktCnt, ++ sarStat.rxPktCnt); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tTx Total Bytes:\t%u\n\tRx Total Bytes:\t%u\n", ++ sarStat.txBytes, ++ sarStat.rxBytes); ++ if(len<=limit) ++ len += sprintf(buf+len, "\tTx Total Error Counts:\t%u\n\tRx Total Error Counts:\t%u\n\n", ++ sarStat.txErrors, ++ sarStat.rxErrors); ++ ++ /* oam loopback info */ ++ if(len<=limit) ++ len += sprintf(buf+len, "\n[OAM Stats]\n"); ++ ++ tn7sar_get_near_end_loopback_count(&F4count, &F5count); ++ ++ if(len<=limit) ++ { ++ len += sprintf(buf+len, "\tNear End F5 Loop Back Count:\t%u\n\tNear End F4 Loop Back Count:\t%u\n\tFar End F5 Loop Back Count:\t%u\n\tFar End F4 Loop Back Count:\t%u\n", ++ F5count, ++ F4count, ++ oamFarLBCount[0] + oamFarLBCount[2], ++ oamFarLBCount[1] + oamFarLBCount[3]); ++ } ++ return len; ++} ++ ++int ++tn7dsl_proc_modem(char* buf, char **start, off_t offset, int count, ++ int *eof, void *data) ++{ ++ ++ int len = 0; ++ int limit = count - 80; ++ ++ char *state; ++ int tag; ++ ++ tag= dslhal_api_pollTrainingStatus(pIhw); ++ tag = pIhw->AppData.bState; ++ ++ switch(tag){ ++ case 0: state = "ACTREQ"; break; ++ case 1: state = "QUIET1"; break; ++ case 2: state = "IDLE"; break; ++ case 3: state = "INIT"; break; ++ case 4: state = "RTDL"; break; ++ case 5: state = "SHOWTIME"; break; ++ default: state = "unknown"; break; ++ } ++ ++ if(pIhw->lConnected == 1) ++ state = "SHOWTIME"; ++ if(len<=limit) ++ len += sprintf(buf+len,"%s\n",state); ++ ++ return len; ++} ++ ++ ++ ++int tn7dsl_handle_interrupt(void) ++{ ++ int intsrc; ++ unsigned char cMsgRa[6]; ++ short margin; ++ ++ dprintf(4, "tn7dsl_handle_dsl_interrupt()\n"); ++ if(pIhw) ++ { ++ intsrc=dslhal_api_acknowledgeInterrupt(pIhw); ++ dslhal_api_handleTrainingInterrupt(pIhw, intsrc); ++ ++ if(pIhw->lConnected == TC_SYNC) ++ { ++ ++ if(dslInSync == 0) ++ { ++ printk("DSL in Sync\n"); ++ tn7atm_device_connect_status(pIhw->pOsContext, 1); ++ dslhal_api_initStatistics(pIhw); ++ dslhal_api_gatherStatistics(pIhw); ++#ifdef CONFIG_LED_MODULE ++// led_operation(MOD_ADSL, DEF_ADSL_SYNC); ++ led_on = DEF_ADSL_SYNC; ++#endif ++ /* add auto margin retrain */ ++ if(pIhw->AppData.TrainedMode < 5) ++ { ++ if(bMarginRetrainEnable && bMarginThConfig == 0) ++ { ++ dslhal_support_getCMsgsRa(pIhw, cMsgRa); ++ margin = *(unsigned short *)&cMsgRa[4]; ++ margin = (margin >> 6) & 0x3f; ++ if(margin & 0x20) // highest bit is 1 ++ { ++ margin = -(margin & 0x1f); ++ } ++ ++ //printk("margin = %d, cmsg-ra = %02x %02x %02x %02x %02x %02x\n", margin, cMsgRa[0],cMsgRa[1],cMsgRa[2],cMsgRa[3],cMsgRa[4],cMsgRa[5]); ++ dslhal_api_setMarginThreshold(pIhw, margin*2); /* DSL margin is in 0.5db */ ++ } ++ } ++ ++ } ++ dslInSync = 1; ++ } ++ else ++ { ++ if(dslInSync == 1) ++ { ++ dslInSync = 0; ++ tn7atm_device_connect_status(pIhw->pOsContext, 0); ++ up(&adsl_sem_overlay); ++ printk("DSL out of syn\n"); ++ } ++#ifdef CONFIG_LED_MODULE ++ if(pIhw->AppData.bState < RSTATE_INIT) ++ { ++ if(led_on != DEF_ADSL_IDLE) ++ { ++// led_operation(MOD_ADSL, DEF_ADSL_IDLE); ++ led_on = DEF_ADSL_IDLE; ++ } ++ } ++ else ++ { ++ if(led_on != DEF_ADSL_TRAINING) ++ { ++// led_operation(MOD_ADSL, DEF_ADSL_TRAINING); ++ led_on = DEF_ADSL_TRAINING; ++ } ++ ++ } ++ ++#endif ++ ++ } ++ } ++ return 0; ++} ++ ++ ++int tn7dsl_get_dslhal_version(char *pVer) ++{ ++ dslVer ver; ++ ++ dslhal_api_getDslHalVersion(&ver); ++ ++ memcpy(pVer,&ver,8); ++ return 0; ++} ++ ++int tn7dsl_get_dsp_version(char *pVer) ++{ ++ dspVer ver; ++ dslhal_api_getDspVersion(pIhw, &ver); ++ memcpy(pVer, &ver, 9); ++ return 0; ++} ++ ++ ++static int ++tn7dsl_get_modulation(void) ++{ ++ char *ptr = NULL; ++ ++ dprintf(4, "tn7dsl_get_modulation\n"); ++ //printk("tn7dsl_get_modulation\n"); ++ ptr = prom_getenv("modulation"); ++ ++ if (!ptr) { ++ //printk("modulation is not set in adam2 env\n"); ++ //printk("Using multimode\n"); ++ return 0; ++ } ++ printk("dsl modulation = %s\n", ptr); ++ ++ tn7dsl_set_modulation(ptr); ++ ++ return 0; ++} ++ ++ ++static int tn7dsl_set_dsl(void) ++{ ++ ++ char *ptr = NULL; ++ int value; ++ int i, offset[2]={4,11},oamFeature=0; ++ char tmp[4]; ++ char dspVer[10]; ++ ++ // OAM Feature Configuration ++ dslhal_api_dspInterfaceRead(pIhw,(unsigned int)pIhw->pmainAddr, 2, (unsigned int *)&offset, (unsigned char *)&oamFeature, 4); ++ oamFeature |= dslhal_support_byteSwap32(0x0000000C); ++ dslhal_api_dspInterfaceWrite(pIhw,(unsigned int)pIhw->pmainAddr, 2, (unsigned int *)&offset, (unsigned char *)&oamFeature, 4); ++ ++ // modulation ++ ptr = prom_getenv("modulation"); ++ if (ptr) ++ { ++ printk("dsl modulation = %s\n", ptr); ++ tn7dsl_set_modulation(ptr); ++ } ++ ++ // margin retrain ++ ptr = NULL; ++ ptr = prom_getenv("enable_margin_retrain"); ++ if(ptr) ++ { ++ value = os_atoi(ptr); ++ if(value == 1) ++ { ++ dslhal_api_setMarginMonitorFlags(pIhw, 0, 1); ++ bMarginRetrainEnable = 1; ++ printk("enable showtime margin monitor.\n"); ++ ptr = NULL; ++ ptr = prom_getenv("margin_threshold"); ++ if(ptr) ++ { ++ value = os_atoi(ptr); ++ printk("Set margin threshold to %d x 0.5 db\n",value); ++ if(value >= 0) ++ { ++ dslhal_api_setMarginThreshold(pIhw, value); ++ bMarginThConfig=1; ++ } ++ } ++ } ++ } ++ ++ // rate adapt ++ ptr = NULL; ++ ptr = prom_getenv("enable_rate_adapt"); ++ if(ptr) ++ { ++ dslhal_api_setRateAdaptFlag(pIhw, os_atoi(ptr)); ++ } ++ ++ // trellis ++ ptr = NULL; ++ ptr = prom_getenv("enable_trellis"); ++ if(ptr) ++ { ++ dslhal_api_setTrellisFlag(pIhw, os_atoi(ptr)); ++ } ++ ++ // maximum bits per carrier ++ ptr = NULL; ++ ptr = prom_getenv("maximum_bits_per_carrier"); ++ if(ptr) ++ { ++ dslhal_api_setMaxBitsPerCarrier(pIhw, os_atoi(ptr)); ++ } ++ ++ // maximum interleave depth ++ ptr = NULL; ++ ptr = prom_getenv("maximum_interleave_depth"); ++ if(ptr) ++ { ++ dslhal_api_setMaxInterleaverDepth(pIhw, os_atoi(ptr)); ++ } ++ ++ // inner and outer pairs ++ ptr = NULL; ++ ptr = prom_getenv("pair_selection"); ++ if(ptr) ++ { ++ dslhal_api_selectInnerOuterPair(pIhw, os_atoi(ptr)); ++ } ++ ++ ptr = NULL; ++ ptr = prom_getenv("dgas_polarity"); ++ if(ptr) ++ { ++ dslhal_api_configureDgaspLpr(pIhw, 1, 1); ++ dslhal_api_configureDgaspLpr(pIhw, 0, os_atoi(ptr)); ++ } ++ ++ ptr = NULL; ++ ptr = prom_getenv("los_alarm"); ++ if(ptr) ++ { ++ dslhal_api_disableLosAlarm(pIhw, os_atoi(ptr)); ++ } ++ ++ ptr = NULL; ++ ptr = prom_getenv("eoc_vendor_id"); ++ if(ptr) ++ { ++ for(i=0;i<8;i++) ++ { ++ tmp[0]=ptr[i*2]; ++ tmp[1]=ptr[i*2+1]; ++ tmp[2]=0; ++ EOCVendorID[i] = os_atoh(tmp); ++ //printk("tmp=%s--", tmp); ++ //printk("ID[%d]=0x%02x ", i, (unsigned char)EOCVendorID[i]); ++ } ++ tn7dsl_get_dsp_version(dspVer); ++ //printk("Annex =%d\n", dspVer[8]); ++ if(dspVer[8]==2) // annex b ++ { ++ //printk("EOCVendorID=%02x %02x %02x %02x %02x %02x %02x %02x\n", EOCVendorID[0], EOCVendorID[1], EOCVendorID[2], EOCVendorID[3], ++ // EOCVendorID[4], EOCVendorID[5], EOCVendorID[6], EOCVendorID[7]); ++ dslhal_api_setEocVendorId(pIhw, EOCVendorID); ++ } ++ ++ } ++ ++ return 0; ++} ++ ++ ++ ++ ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: static void tn7dsl_init(void) ++ * ++ * Description: This function initializes ++ * Ar7 DSL interface ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++ ++int tn7dsl_init(void *priv) ++{ ++ ++ printk("Initializing DSL interface\n"); ++ ++ ++ /* start dsl */ ++ if(dslhal_api_dslStartup(&pIhw) !=0 ) ++ { ++ printk("DSL start failed.\n"); ++ return -1; ++ } ++ ++ // set dsl into overlay page reload mode ++ pIhw->bAutoRetrain = 1; ++ ++ // set default training properties ++ tn7dsl_set_dsl(); ++ ++ pIhw->pOsContext = priv; ++ ++ //start_kthread(tn7dsl_reload_overlay, &overlay_thread); ++ ++ /*register dslss LED with led module */ ++#ifdef CONFIG_LED_MODULE ++ tn7dsl_register_dslss_led(); ++#endif ++ ++ ++ return 0; /* What do we return here? */ ++} ++ ++/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * Function: int avsar_exit(void) ++ * ++ * Description: Avalanche SAR exit function ++ * ++ *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ++ ++void tn7dsl_exit (void) ++{ ++ ++ bshutdown = 1; ++#ifdef CONFIG_LED_MODULE ++#ifdef DEREGISTER_LED ++ //down(&adsl_sem_overlay); ++ deregister_led_drv(LED_NUM_1); ++ deregister_led_drv(LED_NUM_2); ++#else ++// led_operation(MOD_ADSL,DEF_ADSL_IDLE); ++#endif ++#endif ++ stop_kthread(&overlay_thread); ++ dslhal_api_dslShutdown(pIhw); ++ ++} ++ ++ ++static int tn7dsl_process_oam_string(int *type, int *pvpi, int *pvci, int *pdelay) ++{ ++ int i=1; ++ int j=0; ++ int vci, vpi; ++ char tmp[16]; ++ int chan; ++ int tt; ++ ++ while(j<8) ++ { ++ tmp[j] = mod_req[i]; ++ //printk("tmp[%d]=%c, %d\n", j, tmp[j], tmp[j]); ++ if(tmp[j] == 0x50 || tmp[j] == 0x70) ++ break; ++ j++; ++ i++; ++ } ++ ++ tmp[j] = 0; ++ vpi = os_atoi(tmp); ++ ++ i++; ++ j=0; ++ while(j<8) ++ { ++ tmp[j] = mod_req[i]; ++ //printk("tmp[%d]=%c, %d\n", j, tmp[j], tmp[j]); ++ if(tmp[j] == 0x43 || tmp[j] == 0x63) ++ break; ++ ++ j++; ++ i++; ++ } ++ ++ vci = os_atoi(tmp); ++ ++ if(vci==0) // f4 oam ++ *type = 1; ++ else ++ *type = 0; ++ ++ ++ tt=5000; ++ i++; ++ j=0; ++ tmp[j] = mod_req[i]; ++ if(tmp[j]==0x44 || tmp[j]==0x64) ++ { ++ i++; ++ while(j<8) ++ { ++ tmp[j] = mod_req[i]; ++ ++ //printk("tmp[%d]=%c, %d\n", j, tmp[j], tmp[j]); ++ if(tmp[j] == 0x54 || tmp[j] == 0x74) ++ break; ++ ++ j++; ++ i++; ++ } ++ tt = os_atoi(tmp); ++ } ++ ++ chan = tn7atm_lut_find(vpi, vci); ++ ++ *pvci=vci; ++ *pvpi=vpi; ++ *pdelay =tt; ++ dprintf(2, "oam chan=%d, type =%d\n", chan, *type); ++ ++ return chan; ++} ++ ++static void tn7dsl_dump_memory(void) ++{ ++ unsigned int *pUi; ++ int i=1; ++ int j=0; ++ int addr, len; ++ char tmp[16]; ++ ++ ++ while(j<8) ++ { ++ tmp[j] = mod_req[i]; ++ j++; ++ i++; ++ } ++ ++ tmp[j] = 0; ++ ++ addr = os_atoh(tmp); ++ ++ printk("start dump address =0x%x\n", addr); ++ pUi = (unsigned int *)addr; ++ i++; ++ j=0; ++ while(j<8) ++ { ++ tmp[j] = mod_req[i]; ++ //printk("tmp[%d]=%c, %d\n", j, tmp[j], tmp[j]); ++ if(tmp[j] == 0x43 || tmp[j] == 0x63) ++ break; ++ ++ j++; ++ i++; ++ } ++ ++ len = os_atoi(tmp); ++ j=0; ++ for(i=0; if_pos && !write)) { ++ *lenp = 0; ++ return 0; ++ } ++ /* DSL MODULATION is changed */ ++ if(write) ++ { ++ ret = proc_dostring(ctl, write, filp, buffer, lenp); ++ ++ switch (ctl->ctl_name) ++ { ++ case DEV_DSLMOD: ++ ptr = strpbrk(info, " \t"); ++ strcpy(mod_req, info); ++ ++ /* parse the string to determine the action */ ++ if(mod_req[0] == 0x45 || mod_req[0] == 0x65 ) // 'e', or 'E' f5 end to end ++ { ++ chan = tn7dsl_process_oam_string(&type, &vpi, &vci, &timeout); ++ tn7sar_oam_generation(pIhw->pOsContext, chan, type, vpi, vci, timeout); ++ } ++ else if(mod_req[0] == 0x53 || mod_req[0] == 0x73 ) // 's', or 'S' f5 seg to seg ++ { ++ chan=tn7dsl_process_oam_string(&type, &vpi, &vci,&timeout); ++ type = type | (1<<1); ++ tn7sar_oam_generation(pIhw->pOsContext, chan, type, vpi, vci,timeout); ++ } ++ //debug only. Dump memory ++ else if(mod_req[0] == 0x44 || mod_req[0] == 0x64 ) // 'd' or 'D' ++ tn7dsl_dump_memory(); ++ else ++ tn7dsl_chng_modulation(info); ++ break; ++ } ++ } ++ else ++ { ++ len += sprintf(info+len, mod_req); ++ ret = proc_dostring(ctl, write, filp, buffer, lenp); ++ } ++ return ret; ++} ++ ++ ++ctl_table dslmod_table[] = { ++ {DEV_DSLMOD, "dslmod", info, DSL_MOD_SIZE, 0644, NULL, &dslmod_sysctl}, ++ {0} ++ }; ++ ++/* Make sure that /proc/sys/dev is there */ ++ctl_table dslmod_root_table[] = { ++#ifdef CONFIG_PROC_FS ++ {CTL_DEV, "dev", NULL, 0, 0555, dslmod_table}, ++#endif /* CONFIG_PROC_FS */ ++ {0} ++ }; ++ ++static struct ctl_table_header *dslmod_sysctl_header; ++ ++void tn7dsl_dslmod_sysctl_register(void) ++{ ++ static int initialized; ++ ++ if (initialized == 1) ++ return; ++ ++ dslmod_sysctl_header = register_sysctl_table(dslmod_root_table, 1); ++ dslmod_root_table->child->de->owner = THIS_MODULE; ++ ++ /* set the defaults */ ++ info[0] = 0; ++ ++ initialized = 1; ++} ++ ++void tn7dsl_dslmod_sysctl_unregister(void) ++{ ++ unregister_sysctl_table(dslmod_sysctl_header); ++} ++ ++static void ++tn7dsl_set_modulation(void* data) ++{ ++ dprintf(4,"tn7dsl_set_modulation\n"); ++ ++ if(!strcmp(data, "T1413")) ++ { ++ printk("retraining in T1413 mode\n"); ++ dslhal_api_setTrainingMode(pIhw, T1413_MODE); ++ return; ++ } ++ if(!strcmp(data, "GDMT")) ++ { ++ dslhal_api_setTrainingMode(pIhw, GDMT_MODE); ++ return; ++ } ++ if(!strcmp(data, "GLITE")) ++ { ++ dslhal_api_setTrainingMode(pIhw, GLITE_MODE); ++ return; ++ } ++ if(!strcmp(data, "MMODE")) ++ { ++ dslhal_api_setTrainingMode(pIhw, MULTI_MODE); ++ return; ++ } ++ if(!strcmp(data, "NMODE")) ++ { ++ dslhal_api_setTrainingMode(pIhw, NO_MODE); ++ return; ++ } ++ ++ return; ++} ++ ++ ++/* Codes added for compiling tiadiag.o for Analog Diagnostic tests */ ++#ifdef ADIAG ++ ++enum ++{ ++ HOST_ACTREQ, // Send R-ACKREQ and monitor for C-ACKx ++ HOST_QUIET, // Sit quietly doing nothing for about 60 seconds, DEFAULT STATE; R_IDLE ++ HOST_XMITBITSWAP, // Perform upstream bitswap - FOR INTERNAL USE ONLY ++ HOST_RCVBITSWAP, // Perform downstream bitswap - FOR INTERNAL USE ONLY ++ HOST_RTDLPKT, // Send a remote download packet - FOR INTERNAL USE ONLY ++ HOST_CHANGELED, // Read the LED settings and change accordingly ++ HOST_IDLE, // Sit quiet ++ HOST_REVERBTEST, // Generate REVERB for manufacturing test ++ HOST_CAGCTEST, // Set coarse receive gain for manufacturing test ++ HOST_DGASP, // send Dying Gasp messages through EOC channel ++ HOST_GHSREQ, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHSMSG, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHS_SENDGALF, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHSEXIT, // G.hs - FOR INTERNAL USE ONLY ++ HOST_GHSMSG1, // G.hs - FOR INTERNAL USE ONLY ++ HOST_HYBRID, // Enable/Disable automatic hybrid switch ++ HOST_RJ11SELECT, // RJ11 inner/outer pair select ++ HOST_DIGITAL_MEM, // Digital Diags: run external memory tests ++ HOST_TXREVERB, // AFE Diags: TX path Reverb ++ HOST_TXMEDLEY, // AFE Diags: TX path Medley ++ HOST_RXNOISEPOWER, // AFE Diags: RX noise power ++ HOST_ECPOWER, // AFE Diags: RX eco power ++ HOST_ALL_ADIAG, // AFE Diags: all major analog diagnostic modes. Host is responsible to initiate each diagnostic sessions ++ HOST_USER_ADIAG, // AFE Diags: Host fills in analog diagnostic input data structure as specified and requests DSP to perform measurements as specified ++ HOST_QUIT_ADIAG, // AFE Diags: Host requests DSP to quit current diagnostic session. This is used for stopping the transmit REVERB/MEDLEY ++ HOST_NO_CMD, // All others - G.hs - FOR INTERNAL USE ONLY ++ HOST_DSLSS_SHUTDOWN, // Host initiated DSLSS shutdown message ++ HOST_SET_GENERIC, // Set generic CO profile ++ HOST_UNDO_GENERIC // Set profile previous to Generic ++}; ++ ++enum ++{ ++ DSP_IDLE, // R_IDLE state entered ++ DSP_ACTMON, // R_ACTMON state entered ++ DSP_TRAIN, // R_TRAIN state entered ++ DSP_ACTIVE, // R_ACTIVE state entered ++ DSP_XMITBITSWAP, // Upstream bitswap complete - FOR INTERNAL USE ONLY ++ DSP_RCVBITSWAP, // Downstream bitswap complete - FOR INTERNAL USE ONLY ++ DSP_RTDL, // R_RTDL state entered - FOR INTERNAL USE ONLY ++ DSP_RRTDLPKT, // RTDL packet received - FOR INTERNAL USE ONLY ++ DSP_XRTDLPKT, // RTDL packet transmitted - FOR INTERNAL USE ONLY ++ DSP_ERROR, // Command rejected, wrong state for this command ++ DSP_REVERBTEST, // Manufacturing REVERB test mode entered ++ DSP_CAGCTEST, // Manufacturing receive gain test done ++ DSP_OVERLAY_START, // Notify host that page overlay has started - overlay number indicated by "tag" ++ DSP_OVERLAY_END, // Notify host that page overlay has ended - overlay number indicated by "tag" ++ DSP_CRATES1, // CRATES1 message is valid and should be copied to host memory now ++ DSP_SNR, // SNR calculations are ready and should be copied to host memory now ++ DSP_GHSMSG, // G.hs - FOR INTERNAL USE ONLY ++ DSP_RCVBITSWAP_TIMEOUT, // Acknowledge Message was not received within ~500 msec (26 Superframes). ++ DSP_ATM_TC_SYNC, // Indicates true TC sync on both the upstream and downstream. Phy layer ready for data xfer. ++ DSP_ATM_NO_TC_SYNC, // Indicates loss of sync on phy layer on either US or DS. ++ DSP_HYBRID, // DSP completed hybrid switch ++ DSP_RJ11SELECT, // DSP completed RJ11 inner/outer pair select ++ DSP_INVALID_CMD, // Manufacturing (Digital and AFE) diags: CMD received not recognized ++ DSP_TEST_PASSED, // Manufacturing diags: test passed ++ DSP_TEST_FAILED, // Manufacturing diags: test failed ++ DSP_TXREVERB, // Manufacturing AFE diags: Response to HOST_TXREVERB ++ DSP_TXMEDLEY, // Manufacturing AFE diags: Response to HOST_TXMEDLEY ++ DSP_RXNOISEPOWER, // Manufacturing AFE diags: Response to HOST_RXNOISEPOWER ++ DSP_ECPOWER, // Manufacturing AFE diags: Response to HOST_ECPOWER ++ DSP_ALL_ADIAG, // Manufacturing AFE diags: Response to HOST_ALL_ADIAG ++ DSP_USER_ADIAG, // Manufacturing AFE diags: Response to HOST_USER_ADIAG ++ DSP_QUIT_ADIAG, // Manufacturing AFE diags: Response to HOST_QUIT_ADIAG ++ DSP_DGASP // DSP Message to indicate dying gasp ++}; ++ ++static unsigned char analogNoTonesTestArray[64]= ++ { ++ 0,0,0,0,0,0,0,0, // Tones 01-08 ++ 0,0,0,0,0,0,0,0, // Tones 09-16 ++ 0,0,0,0,0,0,0,0, // Tones 17-24 ++ 0,0,0,0,0,0,0,0, // Tones 25-32 ++ 0,0,0,0,0,0,0,0, // Tones 33-40 ++ 0,0,0,0,0,0,0,0, // Tones 41-48 ++ 0,0,0,0,0,0,0,0, // Tones 49-56 ++ 0,0,0,0,0,0,0,0 // Tones 57-64 ++ }; ++ ++static unsigned char analogAllTonesTestArray[64]= ++ { ++ 1,1,1,1,1,1,1,1, // Tones 01-08 ++ 1,1,1,1,1,1,1,1, // Tones 09-16 ++ 1,1,1,1,1,1,1,1, // Tones 17-24 ++ 1,1,1,1,1,1,1,1, // Tones 25-32 ++ 1,1,1,1,1,1,1,1, // Tones 33-40 ++ 1,1,1,1,1,1,1,1, // Tones 41-48 ++ 1,1,1,1,1,1,1,1, // Tones 49-56 ++ 1,1,1,1,1,1,1,1 // Tones 57-64 ++ }; ++ ++static unsigned char analogEvenTonesTestArray[64]= ++ { ++ 0,1,0,1,0,1,0,1, // Tones 01-08 ++ 0,1,0,1,0,1,0,1, // Tones 09-16 ++ 0,1,0,1,0,1,0,1, // Tones 17-24 ++ 0,1,0,1,0,1,0,1, // Tones 25-32 ++ 0,1,0,1,0,1,0,1, // Tones 33-40 ++ 0,1,0,1,0,1,0,1, // Tones 41-48 ++ 0,1,0,1,0,1,0,1, // Tones 49-56 ++ 0,1,0,1,0,1,0,1 // Tones 57-64 ++ }; ++ ++static unsigned char analogOddTonesTestArray[64]= ++ { ++ 1,0,1,0,1,0,1,0, // Tones 01-08 ++ 1,0,1,0,1,0,1,0, // Tones 09-16 ++ 1,0,1,0,1,0,1,0, // Tones 17-24 ++ 1,0,1,0,1,0,1,0, // Tones 25-32 ++ 1,0,1,0,1,0,1,0, // Tones 33-40 ++ 1,0,1,0,1,0,1,0, // Tones 41-48 ++ 1,0,1,0,1,0,1,0, // Tones 49-56 ++ 1,0,1,0,1,0,1,0 // Tones 57-64 ++ }; ++ ++unsigned int shim_osGetCpuFrequency(void) ++{ ++ return 150; ++} ++ ++static void tn7dsl_adiag(int Test, unsigned char *missingTones) ++{ ++ int rc,cmd, tag; ++ ++ rc = dslhal_diags_anlg_setMissingTones(pIhw,missingTones); ++ if(rc) ++ { ++ printk(" failed to set Missing town\n"); ++ return; ++ } ++ ++/*********** Start the actual test **********************/ ++ ++ if(Test==0) ++ { ++ printk("TX REVERB Test\n"); ++ rc = dslhal_support_writeHostMailbox(pIhw, HOST_TXREVERB, 0, 0, 0); ++ if (rc) ++ { ++ printk("HOST_TXREVERB failed\n"); ++ return; ++ } ++ ++ } ++ if(Test==1) ++ { ++ dprintf(0,"TX MEDLEY Test\n"); ++ rc = dslhal_support_writeHostMailbox(pIhw, HOST_TXMEDLEY, 0, 0, 0); ++ if (rc) ++ return; ++ } ++ dprintf(4,"dslhal_diags_anlg_testA() done\n"); ++ return; ++} ++ ++ ++static void tn7dsl_diagnostic_test(char *data) ++{ ++ if(!strcmp(data, "ADIAGRALL")) ++ { ++ printk("TX Reverb All tone\n"); ++ tn7dsl_adiag(0,analogAllTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGRNONE")) ++ { ++ printk("TX Reverb No tone\n"); ++ tn7dsl_adiag(0,analogNoTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGREVEN")) ++ { ++ printk("TX Reverb Even tone\n"); ++ tn7dsl_adiag(0,analogEvenTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGRODD")) ++ { ++ printk("TX Reverb Odd tone\n"); ++ tn7dsl_adiag(0,analogOddTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGMALL")) ++ { ++ printk("TX Mdelay All tone\n"); ++ tn7dsl_adiag(1,analogAllTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGMNONE")) ++ { ++ printk("TX Mdelay No tone\n"); ++ tn7dsl_adiag(1,analogNoTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGMEVEN")) ++ { ++ printk("TX Mdelay Even tone\n"); ++ tn7dsl_adiag(1,analogEvenTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGMODD")) ++ { ++ printk("TX Mdelay Odd tone\n"); ++ tn7dsl_adiag(1,analogOddTonesTestArray); ++ return; ++ } ++ if(!strcmp(data, "ADIAGQUIET")) ++ { ++ dslhal_api_sendIdle(pIhw); ++ return; ++ } ++ if(!strncmp(data, "ADIAGRN", 7)) ++ { ++ char tones[64], tmp[4]; ++ int nth, i; ++ ++ tmp[0]=data[7]; ++ tmp[1]=data[8]; ++ tmp[2]=data[9]; ++ ++ nth = os_atoi(tmp); ++ ++ for(i=0;i<64;i++) ++ { ++ if(((i+1)% nth)==0) ++ { ++ tones[i]=0; ++ } ++ else ++ { ++ tones[i]=1; ++ } ++ } ++ printk("TX Reverb with %dth tones missing.\n", nth); ++ tn7dsl_adiag(0,tones); ++ return; ++ } ++ if(!strncmp(data, "ADIAGMN", 7)) ++ { ++ char tones[64], tmp[4]; ++ int nth, i; ++ ++ tmp[0]=data[7]; ++ tmp[1]=data[8]; ++ tmp[2]=data[9]; ++ nth = os_atoi(tmp); ++ ++ for(i=0;i<64;i++) ++ { ++ if(((i+1)% nth)==0) ++ { ++ tones[i]=0; ++ } ++ else ++ { ++ tones[i]=1; ++ } ++ } ++ printk("TX Mdelay with %dth tones missing.\n", nth); ++ tn7dsl_adiag(1,tones); ++ return; ++ } ++ ++ ++} ++ ++#endif ++ ++static void ++tn7dsl_chng_modulation(void* data) ++{ ++ //printk("DSL Modem Retraining\n"); ++ ++ if(!strcmp(data, "T1413")) ++ { ++ printk("retraining in T1413 mode\n"); ++ dslhal_api_setTrainingMode(pIhw, T1413_MODE); ++ dslhal_api_sendQuiet(pIhw); ++ return; ++ } ++ if(!strcmp(data, "GDMT")) ++ { ++ dslhal_api_setTrainingMode(pIhw, GDMT_MODE); ++ dslhal_api_sendQuiet(pIhw); ++ return; ++ } ++ if(!strcmp(data, "GLITE")) ++ { ++ dslhal_api_setTrainingMode(pIhw, GLITE_MODE); ++ dslhal_api_sendQuiet(pIhw); ++ return; ++ } ++ if(!strcmp(data, "MMODE")) ++ { ++ dslhal_api_setTrainingMode(pIhw, MULTI_MODE); ++ dslhal_api_sendQuiet(pIhw); ++ return; ++ } ++ if(!strcmp(data, "NMODE")) ++ { ++ dslhal_api_setTrainingMode(pIhw, NO_MODE); ++ dslhal_api_sendQuiet(pIhw); ++ return; ++ } ++ ++#ifdef ADIAG ++ tn7dsl_diagnostic_test(data); ++#endif ++ ++ ++ return; ++} ++ ++#ifdef CONFIG_LED_MODULE ++static void tn7dsl_led_on(unsigned long parm) ++{ ++ dslhal_api_configureLed(pIhw,parm, 0); ++} ++ ++ ++static void tn7dsl_led_off(unsigned long parm) ++{ ++ dslhal_api_configureLed(pIhw,parm, 1); ++} ++ ++static void tn7dsl_led_init(unsigned long parm) ++{ ++ dslhal_api_configureLed(pIhw,parm, 2); ++} ++#endif ++ ++static void tn7dsl_register_dslss_led(void) ++{ ++#ifdef CONFIG_LED_MODULE ++ ++ // register led0 with led module ++ ledreg[0].param = 0; ++ ledreg[0].init = (void *)tn7dsl_led_init; ++ ledreg[0].onfunc = (void *)tn7dsl_led_on; ++ ledreg[0].offfunc = (void *)tn7dsl_led_off; ++ register_led_drv(LED_NUM_1, &ledreg[0]); ++ ++ // register led1 output with led module ++ ledreg[1].param = 1; ++ ledreg[1].init = (void *)tn7dsl_led_init; ++ ledreg[1].onfunc = (void *)tn7dsl_led_on; ++ ledreg[1].offfunc = (void *)tn7dsl_led_off; ++ register_led_drv(LED_NUM_2, &ledreg[1]); ++#endif ++} ++ ++static int tn7dsl_reload_overlay(void) ++{ ++ int overlayFlag; ++ spinlock_t overlayLock; ++ ++ init_kthread(&overlay_thread, "adsl"); ++ down(&adsl_sem_overlay); ++ while(1) ++ { ++ mdelay(500); ++ if(pIhw->lConnected == 0) ++ { ++ spin_lock_irqsave(&overlayLock, overlayFlag); ++ dslhal_support_restoreTrainingInfo(pIhw); ++ spin_unlock_irqrestore(&overlayLock, overlayFlag); ++ } ++ down(&adsl_sem_overlay); ++ } ++ return 0; ++} ++ ++ ++ ++ +diff -urN linux.old/drivers/atm/sangam_atm/tn7sar.c linux.dev/drivers/atm/sangam_atm/tn7sar.c +--- linux.old/drivers/atm/sangam_atm/tn7sar.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/tn7sar.c 2005-08-23 04:46:50.110841720 +0200 +@@ -0,0 +1,1376 @@ ++/****************************************************************************** ++ * FILE PURPOSE: OS files for CPSAR ++ ****************************************************************************** ++ * FILE NAME: tn7sar.c ++ * ++ * DESCRIPTION: This file contains source for required os files for CPSAR ++ * ++ * (C) Copyright 2002, Texas Instruments Inc ++ * ++ * ++ * Revision History: ++ * 0/11/02 Zhicheng Tang, created. ++ * ++ *******************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define _CPHAL_AAL5 ++#define _CPHAL_SAR ++#define _CPHAL_HAL ++typedef void OS_PRIVATE; ++typedef void OS_DEVICE; ++typedef void OS_SENDINFO; ++typedef void OS_RECEIVEINFO; ++typedef void OS_SETUP; ++ ++#include "cpswhal_cpsar.h" ++#include "tn7atm.h" ++#include "tn7api.h" ++ ++ ++/* PDSP Firmware files */ ++#include "tnetd7300_sar_firm.h" ++ ++ ++enum ++{ ++ PACKET_TYPE_AAL5, ++ PACKET_TYPE_NULL, ++ PACKET_TYPE_OAM, ++ PACKET_TYPE_TRANS, ++ PACKET_TYPE_AAL2 ++}PACKET_TYPE; ++ ++enum ++{ ++ OAM_PING_FAILED, ++ OAM_PING_SUCCESS, ++ OAM_PING_PENDING, ++ OAM_PING_NOT_STARTED ++}OAM_PING; ++ ++/* PDSP OAM General Purpose Registers (@todo: These need to be used in the HAL!) */ ++ ++#define SAR_PDSP_HOST_OAM_CONFIG_REG_ADDR 0xa3000020 ++#define SAR_PDSP_OAM_CORR_REG_ADDR 0xa3000024 ++#define SAR_PDSP_OAM_LB_RESULT_REG_ADDR 0xa3000028 ++#define SAR_PDSP_OAM_F5LB_COUNT_REG_ADDR 0xa300002c ++#define SAR_PDSP_OAM_F4LB_COUNT_REG_ADDR 0xa3000030 ++ ++#define SAR_FREQUNCY 50000000 ++ ++#define AAL5_PARM "id=aal5, base = 0x03000000, offset = 0, int_line=15, ch0=[RxBufSize=1522; RxNumBuffers = 32; RxServiceMax = 50; TxServiceMax=50; TxNumBuffers=32; CpcsUU=0x5aa5; TxVc_CellRate=0x3000; TxVc_AtmHeader=0x00000640]" ++#define SAR_PARM "id=sar,base = 0x03000000, reset_bit = 9, offset = 0; UniNni = 0, PdspEnable = 1" ++#define RESET_PARM "id=ResetControl, base=0xA8611600" ++#define CH0_PARM "RxBufSize=1522, RxNumBuffers = 32, RxServiceMax = 50, TxServiceMax=50, TxNumBuffers=32, CpcsUU=0x5aa5, TxVc_CellRate=0x3000, TxVc_AtmHeader=0x00000640" ++ ++#define MAX_PVC_TABLE_ENTRY 16 ++ ++sar_stat_t sarStat; ++ ++typedef struct _channel_parm ++{ ++ unsigned int RxBufSize; ++ unsigned int RxNumBuffers; ++ unsigned int RxServiceMax; ++ unsigned int TxServiceMax; ++ unsigned int TxNumBuffers; ++ unsigned int CpcsUU; ++ unsigned int TxVc_CellRate; ++ unsigned int TxVc_AtmHeader; ++}channel_parm_t; ++ ++typedef struct _aal5_parm ++{ ++ unsigned int base; ++ unsigned int offset; ++ unsigned int int_line; ++ channel_parm_t chan[8]; ++}aal5_parm_t; ++ ++ ++typedef struct _sar_parm ++{ ++ unsigned int base; ++ unsigned int reset_bit; ++ unsigned int offset; ++ unsigned int UniNni; ++}sar_parm_t; ++ ++typedef struct _pvc_table ++{ ++ int bInUse; ++ int vpi; ++ int vci; ++}pvc_table; ++ ++static aal5_parm_t aal5Parm; ++static sar_parm_t sarParm; ++static char *pAal5, *pSar, *pReset; ++static int oam_type; ++static unsigned int oamPingStatus; ++static int oamAtmHdr; ++static int oamLbTimeout; ++static char parm_data[1024]; ++static char aal5Data[1024]; ++static char sarData[1024]; ++static char resetData[256]; ++static pvc_table pvc_result[MAX_PVC_TABLE_ENTRY]; ++ ++/* external function */ ++extern int __guDbgLevel; ++ ++/* gloabal function */ ++unsigned int oamFarLBCount[4]; ++/* end of gloabal function */ ++ ++/* internal APIs */ ++static int tn7sar_atm_header(int vpi, int vci); ++static void tn7sar_record_pvc(int atmheader); ++ ++/*end of internal APIs */ ++spinlock_t sar_lock; ++ ++/* HAL OS support functions */ ++ ++ ++unsigned long tn7sar_strtoul(const char *str, char **endptr, int base) ++{ ++ unsigned long ret; ++ ++ ret= simple_strtoul(str, endptr, base); ++ return ret; ++} ++ ++static void *tn7sar_malloc(unsigned int size) ++{ ++ return(kmalloc(size, GFP_KERNEL)); ++} ++ ++static unsigned long lockflags; ++static void tn7sar_critical_on(void) ++{ ++ spin_lock_irqsave(&sar_lock,lockflags); ++} ++ ++static void tn7sar_critical_off(void) ++{ ++ spin_unlock_irqrestore(&sar_lock,lockflags); ++} ++ ++static void tn7sar_data_invalidate(void *pmem, int size) ++{ ++ unsigned int i,Size=(((unsigned int)pmem)&0xf)+size; ++ ++ for (i=0;i> 4); ++ vpi = 0xff & (atmheader >> 20); ++ for(i=0;idata, (int)local_list->len); ++ local_list ++; ++ } ++ local_list = frag_list; ++ if((mode>>31)) /*vci, vpi is attached */ ++ { ++ atmHdr = *(unsigned int *)frag_list->data; ++ tn7sar_record_pvc(atmHdr); ++ if(atmHdr & 0x8) //oam cell ++ { ++ atmHdr &= 0xfffffff0; ++ if(atmHdr == oamAtmHdr) ++ { ++ if(oamPingStatus == OAM_PING_PENDING) ++ { ++ oamPingStatus = OAM_PING_SUCCESS; ++ oamFarLBCount[oam_type] = oamFarLBCount[oam_type] + 1; ++ } ++ return 0; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static int ++tn7sar_receive(OS_DEVICE *os_dev,FRAGLIST *frag_list, unsigned int frag_count, unsigned int packet_size, ++ HAL_RECEIVEINFO *hal_receive_info, unsigned int mode) ++{ ++ int ch; ++ struct atm_dev *dev; ++ Tn7AtmPrivate *priv; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ int bRet; ++ ++ ++ dprintf(4, "tn7sar_receive\n"); ++ ++ dev = (struct atm_dev *)os_dev; ++ priv= (Tn7AtmPrivate *)dev->dev_data; ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ ++ /* Mode contains channel info */ ++ ch = (mode & 0xFF); ++ ++ if(ch == 15) ++ { ++ tn7sar_process_unmatched_oam(frag_list, frag_count, packet_size, mode); ++ pHalFunc->RxReturn(hal_receive_info, 0); ++ return 0; ++ } ++ ++ if(frag_count > 1 || frag_list->len == 0) ++ { ++ printk("Packet fragment count > 1, not handdle.\n"); ++ return 1; ++ } ++ ++ tn7sar_data_invalidate(frag_list->data, (int)frag_list->len); ++ bRet=tn7atm_receive(os_dev, ch, packet_size, frag_list->OsInfo, frag_list->data); ++ ++ if(bRet==0) ++ { ++ sarStat.rxPktCnt++; ++ sarStat.rxBytes += packet_size; ++ pHalFunc->RxReturn(hal_receive_info, 1); ++ } ++ else ++ { ++ pHalFunc->RxReturn(hal_receive_info, 0); ++ } ++ ++ return bRet; ++} ++ ++static int ++tn7sar_send_complete(OS_SENDINFO *osSendInfo) ++{ ++ return (tn7atm_send_complete(osSendInfo)); ++} ++ ++void ++tn7sar_teardown_complete(OS_DEVICE *OsDev, int ch, int Dir) ++{ ++ return; ++} ++ ++ ++/* ++unsigned int tn7sar_virt(unsigned int address) ++{ ++ return phys_to_virt(address); ++} ++*/ ++ ++int tn7sar_init_module(OS_FUNCTIONS *os_funcs) ++{ ++ dprintf(4, "tn7sar_init_module\n"); ++ if( os_funcs == 0 ) ++ { ++ return(-1); ++ } ++ os_funcs->Control = tn7sar_control; ++ os_funcs->CriticalOn = tn7sar_critical_on; ++ os_funcs->CriticalOff = tn7sar_critical_off; ++ os_funcs->DataCacheHitInvalidate = tn7sar_data_invalidate; ++ os_funcs->DataCacheHitWriteback = tn7sar_data_writeback; ++ os_funcs->DeviceFindInfo = tn7sar_find_device; ++ os_funcs->DeviceFindParmUint = tn7sar_get_device_parm_uint; ++ os_funcs->DeviceFindParmValue = tn7sar_get_device_parm_value; ++ os_funcs->Free = tn7sar_free; ++ os_funcs->FreeRxBuffer = tn7sar_free_buffer; ++ os_funcs->FreeDev = tn7sar_free_dev; ++ os_funcs->FreeDmaXfer = tn7sar_free_dma_xfer; ++ os_funcs->IsrRegister = tn7sar_sarhal_isr_register; ++ os_funcs->IsrUnRegister = tn7sar_isr_unregister; ++ os_funcs->Malloc = tn7sar_malloc; ++ os_funcs->MallocRxBuffer = tn7sar_malloc_rxbuffer; ++ os_funcs->MallocDev = tn7sar_malloc_dev; ++ os_funcs->MallocDmaXfer = tn7sar_malloc_dma_xfer; ++ os_funcs->Memset = tn7sar_memset; ++ os_funcs->Printf = tn7sar_printf; ++ os_funcs->Receive = tn7sar_receive; ++ os_funcs->SendComplete = tn7sar_send_complete; ++ os_funcs->Strcmpi = strcmp; ++ os_funcs->Sprintf = sprintf; ++ os_funcs->Strlen = strlen; ++ os_funcs->Strstr = strstr; ++ os_funcs->Strtoul = tn7sar_strtoul; ++ os_funcs->TeardownComplete = tn7sar_teardown_complete; ++ ++ return(0); ++} ++ ++ ++static void tn7sar_init_dev_parm(void) ++{ ++ int i; ++ ++ ++ /* aal5 */ ++ //strcpy(aal5Parm.id, "aal5"); ++ aal5Parm.base = 0x03000000; ++ aal5Parm.offset = 0; ++ aal5Parm.int_line=15; ++ aal5Parm.chan[0].RxBufSize=1600; ++ aal5Parm.chan[0].RxNumBuffers = 32; ++ aal5Parm.chan[0].RxServiceMax = 50; ++ aal5Parm.chan[0].TxServiceMax=50; ++ aal5Parm.chan[0].TxNumBuffers=32; ++ aal5Parm.chan[0].CpcsUU=0x5aa5; ++ aal5Parm.chan[0].TxVc_CellRate=0x3000; ++ aal5Parm.chan[0].TxVc_AtmHeader=0x00000640; ++ for(i=1;i<8;i++) ++ { ++ memcpy(&aal5Parm.chan[i], &aal5Parm.chan[0], sizeof(aal5Parm.chan[0])); ++ } ++ ++ ++ /* sar */ ++ //strcpy(sarParm.id, "sar"); ++ sarParm.base = 0x03000000; ++ sarParm.reset_bit = 9; ++ sarParm.offset = 0; ++ sarParm.UniNni = 0; ++ ++ pAal5 = aal5Data; ++ pSar = sarData; ++ pReset = resetData; ++ strcpy(pAal5, AAL5_PARM); ++ strcpy(pSar, SAR_PARM); ++ strcpy(pReset, RESET_PARM); ++ ++} ++ ++ ++int tn7sar_get_stats(void *priv1) ++{ ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ Tn7AtmPrivate *priv; ++ int i, j; ++ unsigned int *pSarStat, *pStateBase; ++ char statString[64]; ++ int len; ++ ++ dprintf(2, "tn7sar_get_stats\n"); ++ ++ priv = (Tn7AtmPrivate *)priv1; ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ //memset(&sarStat, 0, sizeof(sarStat)); ++ sarStat.txErrors = 0; ++ sarStat.rxErrors = 0; ++ for(i=0;ilut[i].inuse) ++ { ++ for(j=0;j<1;j++) ++ { ++ len=sprintf(statString, "Stats;0;%d", priv->lut[i].chanid); ++ statString[len]=0; ++ dprintf(2, "statString=%s\n",statString); ++ pHalFunc->Control(pHalDev, statString, "Get", &pSarStat); ++ pStateBase = pSarStat; ++ while(pSarStat) ++ { ++ if((char *)*pSarStat == NULL) ++ break; ++ dprintf(2, "%s\n", (char *) *pSarStat); ++ pSarStat++; ++ dprintf(2, "%s\n", (char *) *pSarStat); ++ sarStat.rxErrors += os_atoul((char *) *pSarStat); ++ pSarStat++; ++ } ++ ++ kfree(pStateBase); ++ } ++ } ++ } ++ return 0; ++} ++ ++int tn7sar_setup_oam_channel(Tn7AtmPrivate *priv) ++{ ++ ++ CHANNEL_INFO chInfo; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ int chan=15; ++ dprintf(4, "tn7sar_setup_oam_channel\n"); ++ ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ memset(&chInfo, 0xff, sizeof(chInfo)); ++ ++ /* channel specific */ ++ chInfo.Channel = 15; /* hardcoded for last channel */ ++ chInfo.Direction = 0; ++ chInfo.Vci = 30; /* just need below 32 */ ++ chInfo.Vpi = 0; ++ chInfo.TxVc_QosType = 2; ++ ++ /*default */ ++ chInfo.PktType = PACKET_TYPE_TRANS; ++ chInfo.TxServiceMax = 2; ++ chInfo.RxServiceMax = 2; ++ chInfo.TxNumQueues = 1; ++ chInfo.TxNumBuffers = 4; ++ chInfo.RxNumBuffers = 4; ++ chInfo.RxBufSize = 256; ++ chInfo.RxVc_OamToHost = 0; ++ chInfo.RxVp_OamToHost = 0; ++ chInfo.FwdUnkVc = 1; //enable forwarding of unknown vc ++ chInfo.TxVc_AtmHeader = tn7sar_atm_header((int)chInfo.Vpi, chInfo.Vci); ++ chInfo.RxVc_AtmHeader = tn7sar_atm_header((int)chInfo.Vpi, chInfo.Vci); ++ chInfo.TxVp_AtmHeader = tn7sar_atm_header((int)chInfo.Vpi, 0); ++ chInfo.RxVp_AtmHeader = tn7sar_atm_header((int)chInfo.Vpi, 0); ++ ++ dprintf(4, "TxVc_AtmHeader=0x%x\n", chInfo.TxVc_AtmHeader); ++ ++ if(pHalFunc->ChannelSetup(pHalDev, &chInfo, NULL)) ++ { ++ printk("failed to setup channel =%d.\n", chan); ++ return -1; ++ } ++ ++ // claiming the channel ++ priv->lut[chan].vpi = 0; ++ priv->lut[chan].vci = 30; ++ priv->lut[chan].chanid = chan; ++ priv->lut[chan].inuse = 1; ++ return 0; ++} ++ ++int tn7sar_init(struct atm_dev *dev, Tn7AtmPrivate *priv) ++{ ++ int retCode; ++ int hal_funcs_size; ++ ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ OS_FUNCTIONS *pOsFunc; ++ int oamMod; ++ char *pLbTimeout; ++ int lbTimeout; ++ ++ ++ dprintf(4, "tn7sar_init\n"); ++ ++ pOsFunc = (OS_FUNCTIONS *)kmalloc(sizeof(OS_FUNCTIONS), GFP_KERNEL); ++ ++ ++ priv->pSarOsFunc = ( void *)pOsFunc; ++ ++ /* init boot parms */ ++ tn7sar_init_dev_parm(); ++ ++ /* init sar os call back functions */ ++ retCode = tn7sar_init_module(pOsFunc); ++ if (retCode != 0) /* error */ ++ { ++ printk("Failed to init SAR OS Functions\n"); ++ return (1); ++ } ++ ++ /* Init sar hal */ ++ retCode = cpaal5InitModule(&pHalDev, (OS_DEVICE*) dev, &pHalFunc, ++ pOsFunc, sizeof(OS_FUNCTIONS), &hal_funcs_size, 0); ++ if (retCode != 0) /* error */ ++ { ++ printk("Failed to init SAR HAL\n"); ++ return (1); ++ } ++ ++ /* sanity check */ ++ if (pHalDev == NULL || pHalFunc == NULL || hal_funcs_size != sizeof(HAL_FUNCTIONS) ) ++ { ++ printk("Invalid SAR hal and/or functions.\n"); ++ return (1); ++ } ++ ++ /* remeber HAL pointers */ ++ priv->pSarHalDev = (void *)pHalDev; ++ priv->pSarHalFunc = (void *)pHalFunc; ++ ++ /* Probe for the Device to get hardware info from driver */ ++ retCode = pHalFunc->Probe(pHalDev); ++ if (retCode !=0) ++ { ++ printk("SAR hal probing error.\n"); ++ return (1); ++ } ++ ++ /* init sar hal */ ++ retCode = pHalFunc->Init(pHalDev); ++ if (retCode != 0) /* error */ ++ { ++ ++ printk("pHalFunc->Init failed. err code =%d\n", retCode); ++ return (1); ++ } ++ ++ /* open hal module */ ++ retCode = pHalFunc->Open(pHalDev); ++ if (retCode != 0) /* error */ ++ { ++ printk("pHalFunc->open failed, err code: %d\n",retCode ); ++ return (1); ++ } ++ ++ /* init sar for firmware oam */ ++ oamMod= 1; ++ pHalFunc->Control(pHalDev,"OamMode", "Set", &oamMod); ++ ++ /* read in oam lb timeout value */ ++ pLbTimeout = prom_getenv("oam_lb_timeout"); ++ if(pLbTimeout) ++ { ++ lbTimeout =tn7sar_strtoul(pLbTimeout, NULL, 10); ++ oamLbTimeout = lbTimeout; ++ pHalFunc->Control(pHalDev,"OamLbTimeout", "Set", &lbTimeout); ++ } ++ else ++ { ++ oamLbTimeout = 5000; ++ } ++ ++ oamFarLBCount[0]=0; ++ oamFarLBCount[1]=0; ++ oamFarLBCount[2]=0; ++ oamFarLBCount[3]=0; ++ ++ memset(&sarStat, 0 , sizeof(sarStat)); ++ ++ /* setup channel 15 for oam operation */ ++ tn7sar_setup_oam_channel(priv); ++ dprintf(4, "tn7sar_init done"); ++ return 0; ++} ++ ++static int ++tn7sar_atm_header(int vpi, int vci) ++{ ++ union ++ { ++ unsigned char byte[4]; ++ unsigned int dword; ++ }atm_h; ++ int itmp = 0; ++ ++ //vci ++ itmp = vci &0xf; ++ atm_h.byte[0] = 0; ++ atm_h.byte[0] |= (itmp << 4); ++ atm_h.byte[1] = ((vci & 0xff0) >> 4); ++ atm_h.byte[2] = 0; ++ atm_h.byte[2] |= ((vci & 0xf000) >>12);; ++ atm_h.byte[2] |= ((vpi & 0xf) << 4); ++ atm_h.byte[3] = 0; ++ atm_h.byte[3] = ((vpi & 0xff0) >> 4); ++ return atm_h.dword; ++} ++ ++int tn7sar_activate_vc(Tn7AtmPrivate *priv, short vpi, int vci, int pcr, int scr, int mbs, int cdvt, int chan, int qos) ++{ ++ CHANNEL_INFO chInfo; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ ++ dprintf(4, "tn7sar_activate_vc\n"); ++ ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ memset(&chInfo, 0xff, sizeof(chInfo)); ++ ++ /* channel specific */ ++ chInfo.Channel = chan; ++ chInfo.Direction = 0; ++ chInfo.Vci = vci; ++ chInfo.Vpi = vpi; ++ chInfo.TxVc_QosType = qos; ++ chInfo.Priority = qos; ++ ++ if(chInfo.TxVc_QosType == 1) /* if the connection is VBR than set the DaMask value to tell the schedular to accumalte the credit */ ++ { ++ chInfo.DaMask = 1; ++ } ++ chInfo.TxVc_Mbs = mbs; /* use pcr as MBS */ ++ pcr = SAR_FREQUNCY/pcr; ++ scr = SAR_FREQUNCY/scr; ++ chInfo.TxVc_CellRate = scr; ++ chInfo.TxVc_Pcr = pcr; ++ ++ /*default */ ++ chInfo.PktType = PACKET_TYPE_AAL5; ++ chInfo.TxServiceMax = TX_SERVICE_MAX; ++ chInfo.RxServiceMax = RX_SERVICE_MAX; ++ chInfo.TxNumQueues = TX_QUEUE_NUM; ++ chInfo.TxNumBuffers = TX_BUFFER_NUM; ++ chInfo.RxNumBuffers = RX_BUFFER_NUM; ++ chInfo.RxBufSize = RX_BUFFER_SIZE; ++ chInfo.RxVc_OamToHost = 0; ++ chInfo.RxVp_OamToHost = 0; ++ chInfo.TxVc_AtmHeader = tn7sar_atm_header((int)vpi, vci); ++ chInfo.RxVc_AtmHeader = tn7sar_atm_header((int)vpi, vci); ++ chInfo.TxVp_AtmHeader = tn7sar_atm_header((int)vpi, 0); ++ chInfo.RxVp_AtmHeader = tn7sar_atm_header((int)vpi, 0); ++ chInfo.CpcsUU = 0; ++ ++ dprintf(4, "TxVc_AtmHeader=0x%x\n", chInfo.TxVc_AtmHeader); ++ ++ if(pHalFunc->ChannelSetup(pHalDev, &chInfo, NULL)) ++ { ++ printk("failed to setup channel =%d.\n", chan); ++ return -1; ++ } ++ ++ ++ return 0; ++} ++ ++int tn7sar_send_packet(Tn7AtmPrivate *priv, int chan, void *new_skb, void *data,unsigned int len, int priority) ++{ ++ FRAGLIST fragList; ++ unsigned int mode; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ ++ dprintf(4, "tn7sar_send_packet\n"); ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ fragList.len = len; ++ fragList.data = (void *)data; ++ ++ xdump((char *)fragList.data , fragList.len, 6); ++ ++ /*mode bit ++ 31-19 unused ++ 18 oam cell, 1 = true, 0=false ++ 17-16 oam type, 0=F4 seg, 1=F4 End, 2=F5 seg, 3=F5 end ++ 15-08 transimit queue, current, 0=priority queue, 1=normal queue ++ 07-00 channel number ++ */ ++ mode = 0; ++ mode |= (0xff & chan); ++ mode |= ((0xff & priority) << 8); ++ ++ dprintf(4, "mode = %d\n", mode); ++ ++ tn7sar_data_writeback(fragList.data, len); ++ if(pHalFunc->Send(pHalDev, &fragList, 1, len, new_skb, mode) != 0) ++ { ++ dprintf(1, "SAR hal failed to send packet.\n"); ++ return 1; ++ } ++ //tn7sar_get_stats(priv); ++ sarStat.txPktCnt++; ++ sarStat.txBytes +=len; ++ return 0; ++} ++ ++ ++ ++int tn7sar_handle_interrupt(struct atm_dev *dev, Tn7AtmPrivate *priv) ++{ ++ int more; ++ int rc; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ int (*halIsr)(HAL_DEVICE *halDev, int *work); ++ ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ halIsr = priv->halIsr; ++ ++ rc = halIsr(pHalDev, &more); ++ ++ pHalFunc->PacketProcessEnd(pHalDev); ++ ++ return rc; ++} ++ ++ ++int tn7sar_deactivate_vc(Tn7AtmPrivate *priv, int chan) ++{ ++ unsigned int mode; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ ++ dprintf(4, "tn7sar_deactivate_vc\n"); ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ mode = 0xf; //tear down everything, wait for return; ++ ++ pHalFunc->ChannelTeardown(pHalDev, chan, mode); ++ return 0; ++} ++ ++void tn7sar_exit(struct atm_dev *dev, Tn7AtmPrivate *priv) ++{ ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ ++ dprintf(4, "tn7sar_exit()\n"); ++ ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ tn7sar_deactivate_vc(priv, 15); // de-activate oam channel ++ ++ pHalFunc->Close(pHalDev, 2); ++ pHalFunc->Shutdown(pHalDev); ++ ++ kfree(priv->pSarOsFunc); ++ ++} ++ ++void tn7sar_get_sar_version(Tn7AtmPrivate *priv, char **pVer) ++{ ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ ++ dprintf(4, "tn7sar_get_sar_version()\n"); ++ ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ pHalFunc->Control(pHalDev, "Version", "Get", pVer); ++} ++ ++ ++int tn7sar_get_near_end_loopback_count(unsigned int *pF4count, unsigned int *pF5count) ++{ ++ unsigned int f4c, f5c; ++ ++ f4c = *(volatile unsigned int *)SAR_PDSP_OAM_F4LB_COUNT_REG_ADDR; ++ f5c = *(volatile unsigned int *)SAR_PDSP_OAM_F5LB_COUNT_REG_ADDR; ++ *pF4count = f4c; ++ *pF5count = f5c; ++ ++ return 0; ++} ++ ++ ++int tn7sar_unmatched_oam_generation(void *privContext, int vpi, int vci, int type) ++{ ++ ++ unsigned int regv = 0; ++ int chan=15; ++ static unsigned int tag; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ Tn7AtmPrivate *priv; ++ unsigned int llid[4]={0xffffffff,0xffffffff,0xffffffff,0xffffffff}; ++ ++ dprintf(4, "tn7sar_unknow_oam_generation()\n"); ++ ++ priv = (Tn7AtmPrivate *)privContext; ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ if(vci==0) ++ { ++ oamPingStatus = OAM_PING_FAILED; ++ return 0; ++ } ++ /* calculate atm header */ ++ oamAtmHdr = tn7sar_atm_header(vpi,vci); ++ ++ /* config the atm header */ ++ pHalFunc->Control(pHalDev,"TxVc_AtmHeader.15", "Set", &oamAtmHdr); ++ ++ /*record oam type */ ++ oam_type = type; ++ ++ regv = (0xff & chan); ++ ++ switch(type) ++ { ++ case 0: ++ regv |= (1<<12); //f5 end ++ dprintf(2, "f5 loop back\n"); ++ break; ++ case 1: ++ regv |= (1<<13); // f4 end ++ break; ++ case 2: ++ regv |= (1<<14); //f5 seg ++ break; ++ case 3: ++ regv |= (1<<15); //f4 seg ++ break; ++ default: ++ break; ++ } ++ oamPingStatus = OAM_PING_PENDING; ++ pHalFunc->OamLoopbackConfig(pHalDev, regv, llid, tag); ++ tag++; ++ return 0; ++ ++} ++ ++int tn7sar_oam_generation(void *privContext, int chan, int type, int vpi, int vci, int timeout) ++{ ++ unsigned int regv = 0; ++ static unsigned int tag; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ Tn7AtmPrivate *priv; ++ unsigned int llid[4]={0xffffffff,0xffffffff,0xffffffff,0xffffffff}; ++ ++ dprintf(2, "tn7sar_oam_generation()\n"); ++ ++ priv = (Tn7AtmPrivate *)privContext; ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ if(timeout >= 5000) ++ { ++ if(timeout == 6000) ++ { ++ tn7sar_clear_pvc_table(); ++ return 0; ++ } ++ timeout = oamLbTimeout; ++ } ++ ++ ++ pHalFunc->Control(pHalDev,"OamLbTimeout", "Set", &timeout); ++ ++ if(chan == ATM_NO_DMA_CHAN) ++ { ++ tn7sar_unmatched_oam_generation(priv, vpi, vci, type); ++ return 0; ++ } ++ ++ /* calculate atm header */ ++ oamAtmHdr = tn7sar_atm_header(vpi,vci); ++ ++ oam_type = type; ++ ++ regv = (0xff & chan); ++ switch(type) ++ { ++ case 0: ++ regv |= (1<<12); //f5 end ++ dprintf(2, "f5 loop back\n"); ++ break; ++ case 1: ++ regv |= (1<<13); // f4 end ++ break; ++ case 2: ++ regv |= (1<<14); //f5 seg ++ break; ++ case 3: ++ regv |= (1<<15); //f4 seg ++ break; ++ default: ++ break; ++ } ++ oamPingStatus = OAM_PING_PENDING; ++ pHalFunc->OamLoopbackConfig(pHalDev, regv, llid, tag); ++ tag++; ++ ++ return 0; ++} ++ ++int tn7sar_proc_oam_ping(char* buf, char **start, off_t offset, int count,int *eof, void *data) ++{ ++ int len = 0; ++ ++ len += sprintf(buf+len, "%d\n", oamPingStatus); ++ ++ return len; ++} ++ ++int tn7sar_proc_pvc_table(char* buf, char **start, off_t offset, int count,int *eof, void *data) ++{ ++ int len = 0; ++ int i; ++ ++ for(i=0;i<16;i++) ++ { ++ if(pvc_result[i].bInUse) ++ { ++ len += sprintf(buf+len, "%d,%d\n", pvc_result[i].vpi,pvc_result[i].vci); ++ } ++ else ++ { ++ len += sprintf(buf+len, "0,0\n"); ++ } ++ } ++ return len; ++} ++ ++ ++ ++int tn7sar_proc_sar_stat(char* buf, char **start, off_t offset, int count,int *eof, void *data) ++{ ++ int len = 0; ++ int limit = count - 80; ++ struct atm_dev *dev; ++ Tn7AtmPrivate *priv; ++ int i, j, k; ++ int stat_len; ++ char statString[32]; ++ unsigned int *pStateBase, *pSarStat; ++ HAL_FUNCTIONS *pHalFunc; ++ HAL_DEVICE *pHalDev; ++ int dBytes; ++ ++ dev = (struct atm_dev *)data; ++ priv = (Tn7AtmPrivate *)dev->dev_data; ++ ++ pHalFunc = (HAL_FUNCTIONS *)priv->pSarHalFunc; ++ pHalDev = (HAL_DEVICE *)priv->pSarHalDev; ++ ++ len += sprintf(buf+len, "SAR HAL Statistics\n"); ++ for(i=0;ilut[i].inuse) ++ { ++ if(len<=limit) ++ len += sprintf(buf+len, "\nChannel %d:\n",priv->lut[i].chanid); ++ k=0; ++ for(j=0;j<4;j++) ++ { ++ stat_len =sprintf(statString, "Stats;%d;%d", j,priv->lut[i].chanid); ++ statString[stat_len]=0; ++ pHalFunc->Control(pHalDev, statString, "Get", &pSarStat); ++ pStateBase = pSarStat; ++ while(pSarStat) ++ { ++ if((char *)*pSarStat == NULL) ++ break; ++ if(len<=limit) ++ { ++ dBytes = sprintf(buf+len, "%s: ",(char *) *pSarStat); ++ len += dBytes; ++ k += dBytes; ++ } ++ pSarStat++; ++ if(len<=limit) ++ { ++ dBytes = sprintf(buf+len, "%s; ",(char *) *pSarStat); ++ len += dBytes; ++ k += dBytes; ++ } ++ pSarStat++; ++ ++ if(k > 60) ++ { ++ k=0; ++ if(len<=limit) ++ len += sprintf(buf+len, "\n"); ++ } ++ } ++ ++ kfree(pStateBase); ++ } ++ } ++ } ++ ++ return len; ++} ++ ++void tn7sar_get_sar_firmware_version(unsigned int *pdsp_version_ms, unsigned int *pdsp_version_ls) ++{ ++ ++ *pdsp_version_ms = (SarPdspFirmware[9]>>20) & 0xF; ++ *pdsp_version_ls = (SarPdspFirmware[9]>>12) & 0xFF; ++ return; ++} +diff -urN linux.old/drivers/atm/sangam_atm/tnetd7300_sar_firm.h linux.dev/drivers/atm/sangam_atm/tnetd7300_sar_firm.h +--- linux.old/drivers/atm/sangam_atm/tnetd7300_sar_firm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/tnetd7300_sar_firm.h 2005-08-23 04:46:50.111841568 +0200 +@@ -0,0 +1,988 @@ ++//SarPdspFirmware Revision: 49 ++ ++static int SarPdspFirmware[] = { ++ 0xb0a8d1f1, ++ 0x000003d8, ++ 0x00000000, ++ 0x00000004, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x00000000, ++ 0x21000900, ++ 0x24049080, ++ 0x24000080, ++ 0x240000c0, ++ 0x10e0e0e1, ++ 0x10e0e0e2, ++ 0x10e0e0e3, ++ 0x10e0e0e4, ++ 0x10e0e0e5, ++ 0x10e0e0e6, ++ 0x10e0e0e7, ++ 0x10e0e0e8, ++ 0x10e0e0e9, ++ 0x10e0e0ea, ++ 0x10e0e0eb, ++ 0x10e0e0ec, ++ 0x10e0e0ed, ++ 0x10e0e0ee, ++ 0x10e0e0ef, ++ 0x10e0e0f0, ++ 0x10e0e0f1, ++ 0x10e0e0f2, ++ 0x10e0e0f3, ++ 0x10e0e0f4, ++ 0x10e0e0f5, ++ 0x10e0e0f6, ++ 0x10e0e0f7, ++ 0x10e0e0f8, ++ 0x10e0e0f9, ++ 0x10e0e0fa, ++ 0x10e0e0fb, ++ 0x10e0e0fc, ++ 0x10e0e0fd, ++ 0x10e0e0fe, ++ 0x10e0e0ff, ++ 0x81042680, ++ 0x810c2680, ++ 0x81042680, ++ 0x2483c080, ++ 0x81180b80, ++ 0x2484c080, ++ 0x811a0b80, ++ 0x2485c080, ++ 0x811c0b80, ++ 0x240100dd, ++ 0xa07d06fd, ++ 0x240400dd, ++ 0xa07d04fd, ++ 0x24c000dd, ++ 0x2400169d, ++ 0xa07d5cfd, ++ 0x511f9d03, ++ 0x01019d9d, ++ 0x7f0000fd, ++ 0xd11eff05, ++ 0x97c06890, ++ 0x1d00e5e5, ++ 0x2301229e, ++ 0x81bc2890, ++ 0x24000000, ++ 0xc917ff02, ++ 0x81000100, ++ 0x01010000, ++ 0xc918ff02, ++ 0x81000100, ++ 0x01010000, ++ 0xc919ff02, ++ 0x81000100, ++ 0xd110e70a, ++ 0xd11cff09, ++ 0x1d00e5e5, ++ 0xd100e704, ++ 0xd114ff06, ++ 0x2301179e, ++ 0x79000004, ++ 0xd70ffffd, ++ 0x91382486, ++ 0x2301059e, ++ 0xc903ff07, ++ 0xa06047e0, ++ 0xb10043e6, ++ 0xc910e602, ++ 0x81000106, ++ 0x24006025, ++ 0x2300d39e, ++ 0xd11dff09, ++ 0x1f00e5e5, ++ 0xc901e705, ++ 0xd111ff06, ++ 0x91382586, ++ 0x2301059e, ++ 0x79000003, ++ 0xd715fffc, ++ 0x2301179e, ++ 0xc910e706, ++ 0x110f2760, ++ 0x240000c6, ++ 0x24000086, ++ 0x13106006, ++ 0x7b00005a, ++ 0x11079f80, ++ 0x51008010, ++ 0xc912ff0f, ++ 0xd100ff04, ++ 0xd101ff05, ++ 0xa06046e0, ++ 0x79000004, ++ 0xa06044e0, ++ 0x79000002, ++ 0xa06045e0, ++ 0xb10043e6, ++ 0x61150602, ++ 0x2101c500, ++ 0xc910e602, ++ 0xa1001006, ++ 0x24000025, ++ 0x2300d39e, ++ 0xd11fff05, ++ 0x97c06a90, ++ 0x1f00e5e5, ++ 0x2301229e, ++ 0x81bc2a90, ++ 0xd11cff09, ++ 0x1d00e5e5, ++ 0xc900e705, ++ 0xd10fff06, ++ 0x91382486, ++ 0x2301059e, ++ 0x79000003, ++ 0xd714fffc, ++ 0x2301179e, ++ 0xc907ff07, ++ 0xa0604be0, ++ 0xb10043e6, ++ 0xc910e602, ++ 0x81000106, ++ 0x24006025, ++ 0x2300d39e, ++ 0xd111e70a, ++ 0xd11dff09, ++ 0x1f00e5e5, ++ 0xd101e704, ++ 0xd115ff06, ++ 0x2301179e, ++ 0x79000004, ++ 0xd711fffd, ++ 0x91382586, ++ 0x2301059e, ++ 0xc911e706, ++ 0x0b042760, ++ 0x240000c6, ++ 0x24000086, ++ 0x13106006, ++ 0x7b000024, ++ 0x11709f80, ++ 0x5100800e, ++ 0xc913ff0d, ++ 0xd104ff04, ++ 0xd105ff05, ++ 0xa0604ae0, ++ 0x79000004, ++ 0xa06048e0, ++ 0x79000002, ++ 0xa06049e0, ++ 0xb10043e6, ++ 0xc910e602, ++ 0xa1001106, ++ 0x24000025, ++ 0x2300d39e, ++ 0xc90bff02, ++ 0x7900000b, ++ 0xc90aff02, ++ 0x79000012, ++ 0xcf08ff89, ++ 0xb10002e0, ++ 0xcf18e087, ++ 0x790000b6, ++ 0x24000080, ++ 0x24fb00c0, ++ 0xa06003e0, ++ 0x7f000082, ++ 0xb10024e6, ++ 0xb10025e0, ++ 0xa06628e6, ++ 0xa06029e0, ++ 0x248000c6, ++ 0xa06624e6, ++ 0x671006f0, ++ 0x81082186, ++ 0x7f0000ee, ++ 0xb10027e6, ++ 0x61100604, ++ 0xa0662be6, ++ 0x810c2186, ++ 0x79000006, ++ 0xd70cffea, ++ 0xa0662be6, ++ 0x1f1be6e6, ++ 0x81382686, ++ 0x813c2680, ++ 0x248000c6, ++ 0xa06627e6, ++ 0x7f0000e3, ++ 0x110f0600, ++ 0x81100b00, ++ 0x01502545, ++ 0x90457888, ++ 0x5103091c, ++ 0x6901092a, ++ 0xc910e603, ++ 0xd108e90d, ++ 0x79000027, ++ 0x01582545, ++ 0x9045788a, ++ 0xd108e904, ++ 0x1f08e9e9, ++ 0x01552545, ++ 0x80451829, ++ 0x50eaeb20, ++ 0x0101ebeb, ++ 0x015c2545, ++ 0x8045388b, ++ 0x7900001c, ++ 0x015c2545, ++ 0x9045788b, ++ 0x6900eb05, ++ 0x1d08e9e9, ++ 0x01552545, ++ 0x80451829, ++ 0x79000004, ++ 0x0501ebeb, ++ 0x015c2545, ++ 0x8045388b, ++ 0x10ecece8, ++ 0x79000010, ++ 0x24000000, ++ 0x5110000e, ++ 0x690f6903, ++ 0x24000069, ++ 0x79000002, ++ 0x01016969, ++ 0x01010000, ++ 0x81100b69, ++ 0x01542545, ++ 0x90451809, ++ 0x6f0209f7, ++ 0xa1001069, ++ 0x81100b06, ++ 0x01572545, ++ 0x80451869, ++ 0xa06841e8, ++ 0xa1414006, ++ 0x209e0000, ++ 0x81100b06, ++ 0xd11fe603, ++ 0x9164388d, ++ 0x8108248d, ++ 0xd100e507, ++ 0x97406490, ++ 0x9108248d, ++ 0x813c2480, ++ 0x2302b4de, ++ 0x1d00e7e7, ++ 0x79000006, ++ 0x97406590, ++ 0x9108258d, ++ 0x813c2580, ++ 0x1d01e7e7, ++ 0x2302b9de, ++ 0x8164388d, ++ 0x209e0000, ++ 0x81040105, ++ 0x91002286, ++ 0x97086290, ++ 0x81042280, ++ 0xd100e504, ++ 0x2302b4de, ++ 0x1f00e7e7, ++ 0x209e0000, ++ 0x2302b9de, ++ 0x1f01e7e7, ++ 0x209e0000, ++ 0xd109ff00, ++ 0xa0702cf0, ++ 0x79000001, ++ 0xd109ff00, ++ 0xb1002de6, ++ 0xd11ee609, ++ 0xb1000de0, ++ 0xc91fe044, ++ 0x24c338c6, ++ 0x10000006, ++ 0x81382686, ++ 0x87406690, ++ 0x813c2680, ++ 0x7900003e, ++ 0x110f0600, ++ 0x81100b00, ++ 0x24000045, ++ 0x24000025, ++ 0x61100603, ++ 0x24006045, ++ 0x24006025, ++ 0x01704545, ++ 0x90451888, ++ 0x0b034600, ++ 0x11070000, ++ 0x69040004, ++ 0xc916ff2c, ++ 0x01019e9e, ++ 0x7900002f, ++ 0xc90cff04, ++ 0x6f0200fd, ++ 0xd308e8a1, ++ 0x7f0000fb, ++ 0x69020008, ++ 0xd308e89e, ++ 0xb1002fe6, ++ 0x91b82880, ++ 0xc91ce002, ++ 0x1f1ce6e6, ++ 0x10080806, ++ 0x79000015, ++ 0xb1002fe6, ++ 0x69030003, ++ 0x13c06666, ++ 0x79000011, ++ 0x91807809, ++ 0xc910ea09, ++ 0x81082689, ++ 0x01018a8a, ++ 0xc91ee60a, ++ 0x1d10eaea, ++ 0x240557c0, ++ 0x60c08a07, ++ 0x1f1de6e6, ++ 0x79000005, ++ 0x2400018a, ++ 0x1f10eaea, ++ 0x1f1fe6e6, ++ 0xd71ee6f8, ++ 0x51000002, ++ 0x11c76666, ++ 0x81382686, ++ 0x87406690, ++ 0x91082689, ++ 0x813c2680, ++ 0xb1002ee6, ++ 0xd103e609, ++ 0x81807809, ++ 0xc908e807, ++ 0x21039400, ++ 0x81002386, ++ 0x87086390, ++ 0x81042380, ++ 0xc908e802, ++ 0x21039400, ++ 0x209e0000, ++ 0xb10008ef, ++ 0x110f0f00, ++ 0x81100b00, ++ 0x24000025, ++ 0x61100f02, ++ 0x24005025, ++ 0x01952545, ++ 0x9045382e, ++ 0xc91def03, ++ 0x24000900, ++ 0x2301c09e, ++ 0xc91cef03, ++ 0x24001900, ++ 0x2301c09e, ++ 0xc91bef03, ++ 0x24000a00, ++ 0x2301c09e, ++ 0xc91aef03, ++ 0x24001a00, ++ 0x2301c09e, ++ 0x8045382e, ++ 0x01a82545, ++ 0x9045388e, ++ 0xc915ef03, ++ 0x24000000, ++ 0x2301c09e, ++ 0xc914ef03, ++ 0x24001000, ++ 0x2301c09e, ++ 0x8045388e, ++ 0x61100f02, ++ 0x24006025, ++ 0x016d2545, ++ 0x9045382e, ++ 0xc919ef03, ++ 0x24000900, ++ 0x2301c09e, ++ 0xc918ef03, ++ 0x24001900, ++ 0x2301c09e, ++ 0xc917ef03, ++ 0x24000a00, ++ 0x2301c09e, ++ 0xc916ef03, ++ 0x24001a00, ++ 0x2301c09e, ++ 0x8045382e, ++ 0x017c2545, ++ 0x9045388e, ++ 0xc913ef03, ++ 0x24000000, ++ 0x2301c09e, ++ 0xc912ef03, ++ 0x24001000, ++ 0x2301c09e, ++ 0x8045388e, ++ 0xd11eef19, ++ 0x11f02f00, ++ 0x51000017, ++ 0x24001520, ++ 0x81140b20, ++ 0x81b01a0f, ++ 0x1f02e7e7, ++ 0x24c000c0, ++ 0x24001580, ++ 0xa0605ce0, ++ 0xc90fef04, ++ 0x1d04e7e7, ++ 0x1d05e7e7, ++ 0x7900000c, ++ 0xc90eef04, ++ 0x1d04e7e7, ++ 0x1f05e7e7, ++ 0x79000008, ++ 0xc90def04, ++ 0x1f04e7e7, ++ 0x1d05e7e7, ++ 0x79000004, ++ 0xc90cef03, ++ 0x1f04e7e7, ++ 0x1f05e7e7, ++ 0x2100b900, ++ 0xd11eef03, ++ 0x1e00eeee, ++ 0x209e0000, ++ 0x1c00eeee, ++ 0x209e0000, ++ 0x110f0606, ++ 0x81140b06, ++ 0x13100606, ++ 0x91b01a83, ++ 0x24000025, ++ 0x61100304, ++ 0x24005025, ++ 0xc905e702, ++ 0x24006025, ++ 0x110f0300, ++ 0x81100b00, ++ 0x81120b00, ++ 0x51150611, ++ 0x61100302, ++ 0x24005025, ++ 0x1d01e5e5, ++ 0x51160639, ++ 0x511a0650, ++ 0x511c0657, ++ 0x5118065e, ++ 0x511e0685, ++ 0x61100302, ++ 0x24006025, ++ 0x1f01e5e5, ++ 0x51170634, ++ 0x511b064b, ++ 0x511d0652, ++ 0x51190658, ++ 0x511f067f, ++ 0xc903e708, ++ 0x1d03e7e7, ++ 0x24000060, ++ 0xa1000a60, ++ 0x244000c0, ++ 0x24001580, ++ 0xa0605ce0, ++ 0x21007d00, ++ 0xcf02e7fc, ++ 0x1d02e7e7, ++ 0x1f03e7e7, ++ 0xc904e703, ++ 0x1f08e3e3, ++ 0x79000002, ++ 0x1d08e3e3, ++ 0xc905e705, ++ 0x01682545, ++ 0x9045588d, ++ 0x2302879e, ++ 0x79000004, ++ 0x01902545, ++ 0x9045588d, ++ 0x2302819e, ++ 0x24001872, ++ 0x24000152, ++ 0xb10009e0, ++ 0x108080d3, ++ 0x10c0c092, ++ 0x2400102c, ++ 0x2302c8de, ++ 0x91021c97, ++ 0x91001cd8, ++ 0x91061c98, ++ 0x91041cd9, ++ 0x910a1c99, ++ 0x91081cda, ++ 0x910e1c9a, ++ 0x910c1cdb, ++ 0x91261d9b, ++ 0x91287d9c, ++ 0x23028dde, ++ 0x1f02e7e7, ++ 0x1d03e7e7, ++ 0x7d000070, ++ 0x01902545, ++ 0x9045798d, ++ 0x79000003, ++ 0x01682545, ++ 0x9045788d, ++ 0x0b09eee0, ++ 0x24001472, ++ 0xd108e303, ++ 0xc900e00b, ++ 0x79000002, ++ 0xc910e009, ++ 0xd101e503, ++ 0x2302819e, ++ 0x79000002, ++ 0x2302879e, ++ 0x91013d12, ++ 0x9504bd93, ++ 0x23028dde, ++ 0x7d00005d, ++ 0xd108ee03, ++ 0x1d10e7e7, ++ 0x7900009a, ++ 0x1d11e7e7, ++ 0x79000098, ++ 0x01902545, ++ 0x9045798d, ++ 0x79000003, ++ 0x01682545, ++ 0x9045788d, ++ 0x0b0aeee0, ++ 0x24001072, ++ 0x7f0000e8, ++ 0x01a02545, ++ 0x9045b98d, ++ 0x79000003, ++ 0x01742545, ++ 0x9045b88d, ++ 0x0b01efe0, ++ 0x24001172, ++ 0x7f0000e0, ++ 0x2302d1de, ++ 0x79000002, ++ 0x2302d6de, ++ 0x000c2545, ++ 0x9045198f, ++ 0xd100ef07, ++ 0x1d02efef, ++ 0xc901ef0c, ++ 0xc905ef0b, ++ 0x1d01efef, ++ 0x1d05efef, ++ 0x79000008, ++ 0xd102ef04, ++ 0x1f02efef, ++ 0x8045198f, ++ 0x79000078, ++ 0xd101ef04, ++ 0x1f01efef, ++ 0x1f05efef, ++ 0x8045198f, ++ 0x69180673, ++ 0x01ac2545, ++ 0x2302dbde, ++ 0xd100ef03, ++ 0x23036c9e, ++ 0x7900006e, ++ 0xc800e40b, ++ 0x110f0020, ++ 0x81100b20, ++ 0x100c0c45, ++ 0x61100002, ++ 0x01604545, ++ 0x9045188f, ++ 0xd101ef04, ++ 0x1f01efef, ++ 0x1f07efef, ++ 0x8045188f, ++ 0x01010000, ++ 0x6f1300f4, ++ 0x79000060, ++ 0x2302d1de, ++ 0x79000002, ++ 0x2302d6de, ++ 0x000c2545, ++ 0x9045198f, ++ 0xc903ef05, ++ 0x1d03efef, ++ 0x1f04efef, ++ 0x8045198f, ++ 0x79000056, ++ 0xc904ef55, ++ 0x1d04efef, ++ 0xc901ef04, ++ 0xc906ef03, ++ 0x1d01efef, ++ 0x1d06efef, ++ 0x8045198f, ++ 0x691e064e, ++ 0x01ac2545, ++ 0x2302dbde, ++ 0xc800e40c, ++ 0x110f0020, ++ 0x81100b20, ++ 0x100c0c45, ++ 0x61100002, ++ 0x01604545, ++ 0x9045188f, ++ 0xc901ef05, ++ 0xc908ef04, ++ 0x1d01efef, ++ 0x1d07efef, ++ 0x8045188f, ++ 0x01010000, ++ 0x6f1300f3, ++ 0x7900003d, ++ 0x10ededf0, ++ 0xc908e303, ++ 0x13401010, ++ 0x209e0000, ++ 0x13301010, ++ 0x209e0000, ++ 0x10ededf0, ++ 0xc908e303, ++ 0x130a1010, ++ 0x209e0000, ++ 0x13081010, ++ 0x209e0000, ++ 0x24000266, ++ 0x2400c800, ++ 0x24000020, ++ 0xd108ee17, ++ 0x01012020, ++ 0xc91cff09, ++ 0x6e0020fe, ++ 0xc910e702, ++ 0x20de0000, ++ 0x1f10e7e7, ++ 0x110f0600, ++ 0x11f02727, ++ 0x12002727, ++ 0x20de0000, ++ 0x1d10e7e7, ++ 0x2302b4de, ++ 0x511d0605, ++ 0x511c0602, ++ 0x7900001e, ++ 0x01a62545, ++ 0x79000002, ++ 0x01722545, ++ 0x90451880, ++ 0x01018080, ++ 0x80451880, ++ 0x79000017, ++ 0x01012020, ++ 0xc91dff09, ++ 0x6e0020fe, ++ 0xc911e702, ++ 0x20de0000, ++ 0x1f11e7e7, ++ 0x09040600, ++ 0x110f2727, ++ 0x12002727, ++ 0x20de0000, ++ 0x1d11e7e7, ++ 0x2302b9de, ++ 0x7f0000ea, ++ 0x81b82786, ++ 0x240000d1, ++ 0x87c06790, ++ 0x81bc2780, ++ 0x20de0000, ++ 0x81b82986, ++ 0x87c06990, ++ 0x81bc2980, ++ 0x20de0000, ++ 0x91b43a88, ++ 0x2301029e, ++ 0x51150608, ++ 0xc908e305, ++ 0x51120303, ++ 0x01010303, ++ 0x79000002, ++ 0x24000003, ++ 0x01012323, ++ 0x81b01a83, ++ 0x21007d00, ++ 0x902cfc88, ++ 0x10c8c893, ++ 0x108888d4, ++ 0x10c9c994, ++ 0x108989d5, ++ 0x10caca95, ++ 0x108a8ad6, ++ 0x10cbcb96, ++ 0x108b8bd7, ++ 0xd108e303, ++ 0x2400a80c, ++ 0x20de0000, ++ 0x2400aa0c, ++ 0x20de0000, ++ 0xd108e303, ++ 0x24007c0c, ++ 0x20de0000, ++ 0x24007e0c, ++ 0x20de0000, ++ 0x24000000, ++ 0x90453904, ++ 0xd108e303, ++ 0x24007c0c, ++ 0x20de0000, ++ 0x24007e0c, ++ 0x20de0000, ++ 0xb1002fe6, ++ 0x91b82880, ++ 0xc91ce002, ++ 0x209e0000, ++ 0xb1002ee6, ++ 0x69187279, ++ 0xd110f230, ++ 0xc903e769, ++ 0xc90be604, ++ 0xc904e767, ++ 0xd105e766, ++ 0x7900000c, ++ 0xc90ae604, ++ 0xd104e763, ++ 0xd105e762, ++ 0x79000008, ++ 0xc907e604, ++ 0xc904e75f, ++ 0xc905e75e, ++ 0x79000004, ++ 0xc906e65c, ++ 0xd104e75b, ++ 0xc905e75a, ++ 0x91003c80, ++ 0x6897c058, ++ 0x68d88057, ++ 0x91043c80, ++ 0x6898c055, ++ 0x68d98054, ++ 0x91083c80, ++ 0x6899c052, ++ 0x68da8051, ++ 0x910c3c80, ++ 0x689ac04f, ++ 0x68db804e, ++ 0xb10009e0, ++ 0x6892c04c, ++ 0x68d3804b, ++ 0x24000160, ++ 0xa1000a60, ++ 0x244000c0, ++ 0x24001580, ++ 0xa0605ce0, ++ 0x1d03e7e7, ++ 0x109393c8, ++ 0x10d4d488, ++ 0x109494c9, ++ 0x10d5d589, ++ 0x109595ca, ++ 0x10d6d68a, ++ 0x109696cb, ++ 0x10d7d78b, ++ 0x8110fc88, ++ 0x209e0000, ++ 0x91003c80, ++ 0x6893c00c, ++ 0x68d4800b, ++ 0x91043c80, ++ 0x6894c009, ++ 0x68d58008, ++ 0x91083c80, ++ 0x6895c006, ++ 0x68d68005, ++ 0x910c3c80, ++ 0x6896c003, ++ 0x68d78002, ++ 0x79000010, ++ 0x24ffff80, ++ 0x24ffffc0, ++ 0x68809306, ++ 0x68e0f405, ++ 0x68e0f504, ++ 0x68e0f603, ++ 0x6880d702, ++ 0x79000008, ++ 0x24000080, ++ 0x240000c0, ++ 0x68809323, ++ 0x68e0f422, ++ 0x68e0f521, ++ 0x68e0f620, ++ 0x6880d71f, ++ 0x1d10f2f2, ++ 0x2400002c, ++ 0x2302c8de, ++ 0x24000f80, ++ 0x240000c0, ++ 0x0101c0c0, ++ 0xd100e504, ++ 0xc91cff06, ++ 0x6e80c0fd, ++ 0x21016d00, ++ 0xc91dff03, ++ 0x6e80c0fa, ++ 0x21016d00, ++ 0xd104e606, ++ 0xc909e608, ++ 0xb1000ce0, ++ 0x0101e0e0, ++ 0xa0600ce0, ++ 0x79000004, ++ 0xb1000be0, ++ 0x0101e0e0, ++ 0xa0600be0, ++ 0xb1002fe6, ++ 0xd100e504, ++ 0x2302b4de, ++ 0x24000022, ++ 0x209e0000, ++ 0x2302b9de, ++ 0x24000042, ++ 0x209e0000, ++ 0xd104e609, ++ 0x01782545, ++ 0x9045180e, ++ 0x110f0e00, ++ 0x81100b00, ++ 0x2400a445, ++ 0x51002502, ++ 0x01504545, ++ 0x90451888, ++ 0xc909e87d, ++ 0xb1002fe6, ++ 0x1f1fe6e6, ++ 0x10080806, ++ 0x21015f00, ++ 0x6914721b, ++ 0x01782545, ++ 0x2303bade, ++ 0x900c188f, ++ 0x1d02efef, ++ 0xc901ef05, ++ 0xc905ef04, ++ 0x1d01efef, ++ 0x1d05efef, ++ 0x800c188f, ++ 0xc909e66e, ++ 0x2303d0de, ++ 0xc800e40c, ++ 0x110f0020, ++ 0x81100b20, ++ 0x100c0c45, ++ 0x61100002, ++ 0x01604545, ++ 0x9045188f, ++ 0xc901ef05, ++ 0xc907ef04, ++ 0x1d01efef, ++ 0x1d07efef, ++ 0x8045188f, ++ 0x01010000, ++ 0x6f1300f3, ++ 0x7900005e, ++ 0x6910725d, ++ 0x01782545, ++ 0x2303bade, ++ 0x900c188f, ++ 0x1f03efef, ++ 0xd101ef03, ++ 0x1f01efef, ++ 0x1f06efef, ++ 0x800c188f, ++ 0xc909e654, ++ 0x2303d0de, ++ 0xc800e40b, ++ 0x110f0020, ++ 0x81100b20, ++ 0x100c0c45, ++ 0x61100002, ++ 0x01604545, ++ 0x9045188f, ++ 0xd101ef04, ++ 0x1f01efef, ++ 0x1f08efef, ++ 0x8045188f, ++ 0x01010000, ++ 0x6f1300f4, ++ 0x79000045, ++ 0x01782545, ++ 0x9045788e, ++ 0x1d02efef, ++ 0x1d12efef, ++ 0xc905ef04, ++ 0x1d05efef, ++ 0x1d01efef, ++ 0x7900000c, ++ 0xc915ef04, ++ 0x1d15efef, ++ 0x1d11efef, ++ 0x79000008, ++ 0xc907ef04, ++ 0x1d07efef, ++ 0x1d01efef, ++ 0x79000004, ++ 0xc917ef03, ++ 0x1d17efef, ++ 0x1d11efef, ++ 0x017c2545, ++ 0x8045388f, ++ 0x110f0e00, ++ 0x81100b00, ++ 0x2400a845, ++ 0x51002502, ++ 0x01504545, ++ 0x9045388f, ++ 0x1d02efef, ++ 0x1d12efef, ++ 0xc905ef04, ++ 0x1d05efef, ++ 0x1d01efef, ++ 0x79000004, ++ 0xc915ef03, ++ 0x1d15efef, ++ 0x1d11efef, ++ 0x8045388f, ++ 0x7900001f, ++ 0xc909e60d, ++ 0x9045180e, ++ 0x110f0e00, ++ 0x81100b00, ++ 0xc90ae603, ++ 0x2400a80c, ++ 0x79000003, ++ 0xc90be617, ++ 0x2400aa0c, ++ 0x51002503, ++ 0x01500c0c, ++ 0x24005025, ++ 0x20de0000, ++ 0xc904e611, ++ 0xc906e603, ++ 0x24007c0c, ++ 0x79000003, ++ 0xc907e60d, ++ 0x24007e0c, ++ 0x51002502, ++ 0x01600c0c, ++ 0x20de0000, ++ 0x01ac2545, ++ 0x24000000, ++ 0x90453804, ++ 0xd10be603, ++ 0x24007c0c, ++ 0x20de0000, ++ 0x24007e0c, ++ 0x20de0000, ++ 0x209e0000}; +diff -urN linux.old/drivers/atm/sangam_atm/turbodsl.c linux.dev/drivers/atm/sangam_atm/turbodsl.c +--- linux.old/drivers/atm/sangam_atm/turbodsl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/atm/sangam_atm/turbodsl.c 2005-08-23 04:46:50.111841568 +0200 +@@ -0,0 +1,223 @@ ++ ++ ++/* ++ * ++ * Turbo DSL Implementaion ++ * ++ * Zhicheng Tang ztang@ti.com ++ * ++ * 2002 (c) Texas Instruments Inc. ++ * ++*/ ++ ++/* defines and variables */ ++#define RFC2684_BRIDGED_HDR_SIZE 10 ++unsigned char LLC_BRIDGED_HEADER_2684[RFC2684_BRIDGED_HDR_SIZE] = ++ {0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00}; ++ ++#define RFC2684_ROUTED_HDR_SIZE 6 ++unsigned char LLC_ROUTED_HEADER_2684[6] ={0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; ++ ++unsigned long PPP_LLC_HEADER = 0xCF03FEFE; ++ ++/* struct definition */ ++enum ++{ ++ AAL5_ENCAP_PPP_LLC, ++ AAL5_ENCAP_PPP_VCMUX, ++ AAL5_ENCAP_RFC2684_LLC_BRIDGED, ++ AAL5_ENCAP_RFC2684_LLC_ROUTED ++}; ++ ++/* Etherent header */ ++typedef struct _turbodsl_ether_header ++{ ++ unsigned char dst_mac_addr[6]; ++ unsigned char src_mac_addr[6]; ++ unsigned short ether_type; ++} turbodsl_ether_header_t; ++ ++ ++/* Ip header define */ ++typedef struct _turbodsl_ip_header ++{ ++ ++ unsigned short vit; ++ unsigned short total_length; ++ unsigned short ip_id; ++ unsigned char flag; /* bit 0 = 0, bit1 = don't fragment, bit2=more frag */ ++ unsigned char fragment_offset; /* offset include remaining 5 bits above, which make it 13 bits */ ++ unsigned char time_to_live; ++ unsigned char protocol; ++ unsigned short checksum; ++ unsigned int src_ip; ++ unsigned int dst_ip; ++} turbodsl_ip_header_t; ++ ++/* Arp packet define */ ++typedef struct _turbodsl_arp_header ++{ ++ unsigned short hardware_type; ++ unsigned short protocol_type; ++ unsigned char h_len; ++ unsigned char p_len; ++ unsigned short operation ; ++ unsigned char snd_hw_address[6]; ++ unsigned char snd_pt_address[4]; ++ unsigned char dst_hw_address[6]; ++ unsigned char dst_pt_address[4]; ++} turbodsl_arp_header_t; ++ ++#define FIN_FLAG 1 ++#define SYN_FLAG 1<<1 ++#define RST_FLAG 1<<2 ++#define PSH_FLAG 1<<3 ++#define ACK_FLAG 1<<4 ++#define URG_FLAG 1<<5 ++ ++typedef struct _turbodsl_tcp_header ++{ ++ unsigned short src_port; ++ unsigned short dst_port; ++ unsigned int seq_num; ++ unsigned int ack_num; ++ unsigned char offset; /* only bits 4-7 are for offset */ ++ unsigned char flags; /* bits: 0-FIN, 1-SYN, 2-RST, 3-PSH, 4-ACK, 5-URG */ ++ unsigned short windows; ++ unsigned short checksum; ++ unsigned short urgent_ptr; ++} turbodsl_tcp_header_t; ++ ++ ++ ++/*************************************************************************** ++ * Function: turbodsl_memory_compare ++ * Descripation: Memory compare ++ ****************************************************************************/ ++int turbodsl_memory_compare(unsigned char *pIn, unsigned char *pOut, unsigned int len) ++ { ++ int i; ++ ++ for(i=0;i<(int)len; i++) ++ { ++ if(pIn[i] != pOut[i]) ++ return 0; ++ } ++ return 1; ++ } ++ ++/*************************************************************************** ++ * Function: turbodsl_check_aal5_encap_type ++ * Descripation: Determine AAL5 Encapsulation type ++ * Input: ++ * unsigned char *pData, AAL5 Packet buffer pointer ++ ****************************************************************************/ ++int turbodsl_check_aal5_encap_type(unsigned char *pData) ++ { ++ ++ if(turbodsl_memory_compare(pData, LLC_BRIDGED_HEADER_2684, 6)) ++ return AAL5_ENCAP_RFC2684_LLC_BRIDGED; ++ if(turbodsl_memory_compare(pData, LLC_ROUTED_HEADER_2684, 6)) ++ return AAL5_ENCAP_RFC2684_LLC_ROUTED; ++ if(turbodsl_memory_compare(pData, (unsigned char *)&PPP_LLC_HEADER, sizeof(PPP_LLC_HEADER))) ++ return AAL5_ENCAP_PPP_LLC; ++ ++ return AAL5_ENCAP_PPP_VCMUX; ++ } ++ ++/*************************************************************************** ++ * Function: turbodsl_check_priority_type ++ * Descripation: Determine AAL5 Encapsulation type ++ * Input: ++ * unsigned char *pData, AAL5 Packet buffer pointer. ++ * short vpi, VPI. ++ * int vci, VCI ++ ****************************************************************************/ ++int turbodsl_check_priority_type(unsigned char *pData) ++ { ++ int encap; ++ unsigned char *pP; ++ unsigned short etherType; ++ turbodsl_ip_header_t *pIp; ++ turbodsl_tcp_header_t *pTcp; ++ unsigned short ip_length; ++ ++ dprintf(2, "turbodsl_check_priority_type ==>\n"); ++ ++ encap = turbodsl_check_aal5_encap_type(pData); ++ pP = pData; ++ ++ switch(encap) ++ { ++ case AAL5_ENCAP_RFC2684_LLC_BRIDGED: ++ pP += RFC2684_BRIDGED_HDR_SIZE; //skip off aal5 encap ++ pP += 12; //skip of mac address ++ etherType = *(unsigned short *)pP; ++ if(etherType != 0x6488 && etherType != 0x0008) ++ { ++ //Not an IP packet ++ return 1; ++ } ++ ++ pP +=2; //skip ether type ++ if(etherType == 0x6488) ++ { ++ pP += 6; ++ } ++ break; ++ case AAL5_ENCAP_RFC2684_LLC_ROUTED: ++ pP += RFC2684_ROUTED_HDR_SIZE; //skip of encap ++ pP += 2; //skip ether type ++ break; ++ case AAL5_ENCAP_PPP_LLC: ++ pP += sizeof(PPP_LLC_HEADER); ++ if(*pP == 0xff && *(pP+1) == 0x03) //ppp hdlc header ++ pP += 2; ++ break; ++ case AAL5_ENCAP_PPP_VCMUX: ++ if(*pP == 0xff && *(pP+1) == 0x03) //ppp hdlc header ++ pP += 2; ++ break; ++ default: ++ return 1; ++ } ++ ++ pIp = (turbodsl_ip_header_t *)pP; ++ if(pIp->vit != 0x0045) ++ { ++ //Not a IP packet ++ return 1; ++ } ++ ++ if(pIp->protocol != 0x06) ++ { ++ //not tcp packet ++ return 1; ++ } ++ ++ pTcp = (turbodsl_tcp_header_t *)(pP + sizeof(turbodsl_ip_header_t)); ++ ++ ip_length = (pIp->total_length>>8) + (pIp->total_length<<8); ++ ++ if((pTcp->flags & ACK_FLAG) && ip_length <=40) ++ return 0; ++ ++ return 1; ++ } ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -urN linux.old/include/linux/atmdev.h linux.dev/include/linux/atmdev.h +--- linux.old/include/linux/atmdev.h 2005-08-22 23:18:37.812526104 +0200 ++++ linux.dev/include/linux/atmdev.h 2005-08-23 06:33:33.425389944 +0200 +@@ -30,6 +30,9 @@ + #define ATM_DS3_PCR (8000*12) + /* DS3: 12 cells in a 125 usec time slot */ + ++#define ATM_PDU_OVHD 0 /* number of bytes to charge against buffer ++ quota per PDU */ ++ + #define ATM_SD(s) ((s)->sk->protinfo.af_atm) + + +@@ -94,7 +97,8 @@ + /* set backend handler */ + #define ATM_NEWBACKENDIF _IOW('a',ATMIOC_SPECIAL+3,atm_backend_t) + /* use backend to make new if */ +- ++#define ATM_STOPTX _IOW('a',ATMIOC_SPECIAL+4,struct atmif_sioc) ++ /* Stop Tx on Sangam DSL */ + /* + * These are backend handkers that can be set via the ATM_SETBACKEND call + * above. In the future we may support dynamic loading of these - for now, +@@ -199,7 +203,9 @@ + "SESSION", "HASSAP", "BOUND", "CLOSE" + + +-#ifdef __KERNEL__ ++#ifndef __KERNEL__ ++#undef __AAL_STAT_ITEMS ++#else + + #include /* wait_queue_head_t */ + #include /* struct timeval */ +@@ -291,6 +297,7 @@ + int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); + void *dev_data; /* per-device data */ + void *proto_data; /* per-protocol data */ ++ struct timeval timestamp; /* AAL timestamps */ + struct k_atm_aal_stats *stats; /* pointer to AAL stats group */ + wait_queue_head_t sleep; /* if socket is busy */ + struct sock *sk; /* socket backpointer */ +@@ -333,13 +340,14 @@ + struct k_atm_dev_stats stats; /* statistics */ + char signal; /* signal status (ATM_PHY_SIG_*) */ + int link_rate; /* link rate (default: OC3) */ +- atomic_t refcnt; /* reference count */ +- spinlock_t lock; /* protect internal members */ ++ atomic_t refcnt; /* reference count */ ++ spinlock_t lock; /* protect internal members */ + #ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_entry; /* proc entry */ + char *proc_name; /* proc entry name */ + #endif +- struct list_head dev_list; /* linkage */ ++ struct list_head dev_list; /* linkage */ ++ + }; + + diff --git a/openwrt/target/linux/ar7-2.4/patches/005-wdt_driver.patch b/openwrt/target/linux/ar7-2.4/patches/005-wdt_driver.patch new file mode 100644 index 0000000000..9b01a353da --- /dev/null +++ b/openwrt/target/linux/ar7-2.4/patches/005-wdt_driver.patch @@ -0,0 +1,392 @@ +diff -ruN linux-2.4.30-patch006/drivers/char/ar7_wdt.c linux-2.4.30-patch007/drivers/char/ar7_wdt.c +--- linux-2.4.30-patch006/drivers/char/ar7_wdt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.30-patch007/drivers/char/ar7_wdt.c 2005-10-27 09:39:40.000000000 +0200 +@@ -0,0 +1,335 @@ ++/* linux/drivers/char/ar7_wdt.c ++ ++ TI AR7 watch dog timer support ++ ++ Copyright (c) 2005 Enrik Berkhan ++ ++ Som code taken from: ++ National Semiconductor SCx200 Watchdog support ++ Copyright (c) 2001,2002 Christer Weinigel ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The author(s) of this software shall not be held liable for damages ++ of any nature resulting due to the use of this software. This ++ software is provided AS-IS with no warranties. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#define NAME "ar7_wdt" ++#define LONGNAME "TI AR7 Watchdog Timer" ++ ++MODULE_AUTHOR("Enrik Berkhan "); ++MODULE_DESCRIPTION(LONGNAME); ++MODULE_LICENSE("GPL"); ++ ++#ifndef CONFIG_WATCHDOG_NOWAYOUT ++#define CONFIG_WATCHDOG_NOWAYOUT 0 ++#endif ++ ++static int margin = 60; ++MODULE_PARM(margin, "i"); ++MODULE_PARM_DESC(margin, "Watchdog margin in seconds (1 - ~68)"); ++ ++static int nowayout = CONFIG_WATCHDOG_NOWAYOUT; ++MODULE_PARM(nowayout, "i"); ++MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); ++ ++typedef struct { ++ uint32_t kick_lock; ++ uint32_t kick; ++ uint32_t change_lock; ++ uint32_t change ; ++ uint32_t disable_lock; ++ uint32_t disable; ++ uint32_t prescale_lock; ++ uint32_t prescale; ++} ar7_wdt_t; ++ ++volatile ar7_wdt_t *ar7_wdt = (ar7_wdt_t *)AVALANCHE_WATCHDOG_TIMER_BASE; ++ ++static struct semaphore open_semaphore; ++static unsigned expect_close; ++ ++/* XXX correct? assumed to be sysfreq/2. get this dynamically ... */ ++#define vbus_freq 62500000 ++ ++/* XXX currently fixed, allows max margin ~68.72 secs */ ++#define prescale_value 0xFFFF ++ ++static void ar7_wdt_kick(uint32_t value) ++{ ++ ar7_wdt->kick_lock = 0x5555; ++ if ((ar7_wdt->kick_lock & 3) == 1) { ++ ar7_wdt->kick_lock = 0xAAAA; ++ if ((ar7_wdt->kick_lock & 3) == 3) { ++ ar7_wdt->kick = value; ++ return; ++ } ++ } ++ printk(KERN_ERR NAME "failed to unlock WDT kick reg\n"); ++} ++ ++static void ar7_wdt_prescale(uint32_t value) ++{ ++ ar7_wdt->prescale_lock = 0x5A5A; ++ if ((ar7_wdt->prescale_lock & 3) == 1) { ++ ar7_wdt->prescale_lock = 0xA5A5; ++ if ((ar7_wdt->prescale_lock & 3) == 3) { ++ ar7_wdt->prescale = value; ++ return; ++ } ++ } ++ printk(KERN_ERR NAME "failed to unlock WDT prescale reg\n"); ++} ++ ++static void ar7_wdt_change(uint32_t value) ++{ ++ ar7_wdt->change_lock = 0x6666; ++ if ((ar7_wdt->change_lock & 3) == 1) { ++ ar7_wdt->change_lock = 0xBBBB; ++ if ((ar7_wdt->change_lock & 3) == 3) { ++ ar7_wdt->change = value; ++ return; ++ } ++ } ++ printk(KERN_ERR NAME "failed to unlock WDT change reg\n"); ++} ++ ++static void ar7_wdt_disable(uint32_t value) ++{ ++ ar7_wdt->disable_lock = 0x7777; ++ if ((ar7_wdt->disable_lock & 3) == 1) { ++ ar7_wdt->disable_lock = 0xCCCC; ++ if ((ar7_wdt->disable_lock & 3) == 2) { ++ ar7_wdt->disable_lock = 0xDDDD; ++ if ((ar7_wdt->disable_lock & 3) == 3) { ++ ar7_wdt->disable = value; ++ return; ++ } ++ } ++ } ++ printk(KERN_ERR NAME "failed to unlock WDT disable reg\n"); ++ return; ++} ++ ++static void ar7_wdt_update_margin(int new_margin) ++{ ++ uint32_t change; ++ ++ change = new_margin * (vbus_freq / prescale_value); ++ if (change < 1) change = 1; ++ if (change > 0xFFFF) change = 0xFFFF; ++ ar7_wdt_change(change); ++ margin = change * prescale_value / vbus_freq; ++ printk(KERN_INFO NAME ++ ": timer margin %d seconds (prescale %d, change %d, freq %d)\n", ++ margin, prescale_value, change, vbus_freq); ++} ++ ++static void ar7_wdt_enable_wdt(void) ++{ ++ printk(KERN_DEBUG NAME ": enabling watchdog timer\n"); ++ ar7_wdt_disable(1); ++ ar7_wdt_kick(1); ++} ++ ++static void ar7_wdt_disable_wdt(void) ++{ ++ printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); ++ ar7_wdt_disable(0); ++} ++ ++static int ar7_wdt_open(struct inode *inode, struct file *file) ++{ ++ /* only allow one at a time */ ++ if (down_trylock(&open_semaphore)) ++ return -EBUSY; ++ ar7_wdt_enable_wdt(); ++ expect_close = 0; ++ ++ return 0; ++} ++ ++static int ar7_wdt_release(struct inode *inode, struct file *file) ++{ ++ if (!expect_close) { ++ printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); ++ } else if (!nowayout) { ++ ar7_wdt_disable_wdt(); ++ } ++ up(&open_semaphore); ++ ++ return 0; ++} ++ ++static int ar7_wdt_notify_sys(struct notifier_block *this, ++ unsigned long code, void *unused) ++{ ++ if (code == SYS_HALT || code == SYS_POWER_OFF) ++ if (!nowayout) ++ ar7_wdt_disable_wdt(); ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block ar7_wdt_notifier = ++{ ++ .notifier_call = ar7_wdt_notify_sys ++}; ++ ++static ssize_t ar7_wdt_write(struct file *file, const char *data, ++ size_t len, loff_t *ppos) ++{ ++ if (ppos != &file->f_pos) ++ return -ESPIPE; ++ ++ /* check for a magic close character */ ++ if (len) ++ { ++ size_t i; ++ ++ ar7_wdt_kick(1); ++ ++ expect_close = 0; ++ for (i = 0; i < len; ++i) { ++ char c; ++ if (get_user(c, data+i)) ++ return -EFAULT; ++ if (c == 'V') ++ expect_close = 1; ++ } ++ ++ } ++ return len; ++} ++ ++static int ar7_wdt_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ static struct watchdog_info ident = { ++ .identity = LONGNAME, ++ .firmware_version = 1, ++ .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), ++ }; ++ int new_margin; ++ ++ switch (cmd) { ++ default: ++ return -ENOTTY; ++ case WDIOC_GETSUPPORT: ++ if(copy_to_user((struct watchdog_info *)arg, &ident, ++ sizeof(ident))) ++ return -EFAULT; ++ return 0; ++ case WDIOC_GETSTATUS: ++ case WDIOC_GETBOOTSTATUS: ++ if (put_user(0, (int *)arg)) ++ return -EFAULT; ++ return 0; ++ case WDIOC_KEEPALIVE: ++ ar7_wdt_kick(1); ++ return 0; ++ case WDIOC_SETTIMEOUT: ++ if (get_user(new_margin, (int *)arg)) ++ return -EFAULT; ++ if (new_margin < 1) ++ return -EINVAL; ++ ++ ar7_wdt_update_margin(new_margin); ++ ar7_wdt_kick(1); ++ ++ case WDIOC_GETTIMEOUT: ++ if (put_user(margin, (int *)arg)) ++ return -EFAULT; ++ return 0; ++ } ++} ++ ++static struct file_operations ar7_wdt_fops = { ++ .owner = THIS_MODULE, ++ .write = ar7_wdt_write, ++ .ioctl = ar7_wdt_ioctl, ++ .open = ar7_wdt_open, ++ .release = ar7_wdt_release, ++}; ++ ++static struct miscdevice ar7_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &ar7_wdt_fops, ++}; ++ ++static __initdata char *last_initiator[] = { ++ [HARDWARE_RESET] = "hardware reset", ++ [SOFTWARE_RESET0] = "SW0 software reset", ++ [SOFTWARE_RESET1] = "SW1 software reset", ++ [WATCHDOG_RESET] = "watchdog" ++}; ++ ++static int __init ar7_wdt_init(void) ++{ ++ int r; ++ ++ if (!request_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE, ++ sizeof(ar7_wdt_t), LONGNAME)) { ++ printk(KERN_WARNING NAME ": watchdog I/O region busy\n"); ++ return -EBUSY; ++ } ++ ++ printk(KERN_INFO NAME ": last system reset initiated by %s\n", ++ last_initiator[avalanche_get_sys_last_reset_status()]); ++ ++ ++ ar7_wdt_disable_wdt(); ++ ar7_wdt_prescale(prescale_value); ++ ar7_wdt_update_margin(margin); ++ ++ sema_init(&open_semaphore, 1); ++ ++ r = misc_register(&ar7_wdt_miscdev); ++ if (r) { ++ printk(KERN_ERR NAME ": unable to register misc device\n"); ++ release_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE, ++ sizeof(ar7_wdt_t)); ++ return r; ++ } ++ ++ r = register_reboot_notifier(&ar7_wdt_notifier); ++ if (r) { ++ printk(KERN_ERR NAME ": unable to register reboot notifier\n"); ++ misc_deregister(&ar7_wdt_miscdev); ++ release_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE, ++ sizeof(ar7_wdt_t)); ++ return r; ++ } ++ ++ return 0; ++} ++ ++static void __exit ar7_wdt_cleanup(void) ++{ ++ unregister_reboot_notifier(&ar7_wdt_notifier); ++ misc_deregister(&ar7_wdt_miscdev); ++ release_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE, sizeof(ar7_wdt_t)); ++} ++ ++module_init(ar7_wdt_init); ++module_exit(ar7_wdt_cleanup); +diff -ruN linux-2.4.30-patch006/drivers/char/Config.in linux-2.4.30-patch007/drivers/char/Config.in +--- linux-2.4.30-patch006/drivers/char/Config.in 2005-10-27 11:25:29.000000000 +0200 ++++ linux-2.4.30-patch007/drivers/char/Config.in 2005-10-27 11:17:32.000000000 +0200 +@@ -251,6 +251,9 @@ + bool 'Watchdog Timer Support' CONFIG_WATCHDOG + if [ "$CONFIG_WATCHDOG" != "n" ]; then + bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT ++ if [ "$CONFIG_AR7" = "y" ] ; then ++ tristate ' TI AR7 Watchdog Timer' CONFIG_AR7_WDT ++ else + tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT + tristate ' Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT + tristate ' ALi M7101 PMU on ALi 1535D+ Watchdog Timer' CONFIG_ALIM1535_WDT +@@ -271,7 +274,6 @@ + tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT + dep_tristate ' SC1200 Watchdog Timer (EXPERIMENTAL)' CONFIG_SC1200_WDT $CONFIG_EXPERIMENTAL + tristate ' NatSemi SCx200 Watchdog' CONFIG_SCx200_WDT +- tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG + tristate ' W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT + tristate ' WDT Watchdog timer' CONFIG_WDT + tristate ' WDT PCI Watchdog timer' CONFIG_WDTPCI +@@ -282,6 +284,8 @@ + fi + fi + tristate ' ZF MachZ Watchdog' CONFIG_MACHZ_WDT ++ fi ++ tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate ' Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22 + fi +diff -ruN linux-2.4.30-patch006/drivers/char/Makefile linux-2.4.30-patch007/drivers/char/Makefile +--- linux-2.4.30-patch006/drivers/char/Makefile 2005-10-27 11:19:38.000000000 +0200 ++++ linux-2.4.30-patch007/drivers/char/Makefile 2005-10-27 09:39:40.000000000 +0200 +@@ -342,6 +342,7 @@ + obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o + obj-$(CONFIG_INDYDOG) += indydog.o + obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o ++obj-$(CONFIG_AR7_WDT) += ar7_wdt.o + + subdir-$(CONFIG_MWAVE) += mwave + ifeq ($(CONFIG_MWAVE),y) +diff -ruN linux-2.4.30-patch006/include/asm-mips/ar7/sangam.h linux-2.4.30-patch007/include/asm-mips/ar7/sangam.h +--- linux-2.4.30-patch006/include/asm-mips/ar7/sangam.h 2005-10-27 11:25:51.000000000 +0200 ++++ linux-2.4.30-patch007/include/asm-mips/ar7/sangam.h 2005-10-27 11:13:37.000000000 +0200 +@@ -152,7 +152,7 @@ + #define AVALANCHE_EMIF_SDRAM_CFG (AVALANCHE_EMIF_CONTROL_BASE + 0x8) + #define AVALANCHE_RST_CTRL_PRCR (KSEG1ADDR(0x08611600)) + #define AVALANCHE_RST_CTRL_SWRCR (KSEG1ADDR(0x08611604)) +-#define AVALANCHE_RST_CTRL_RSR (KSEG1ADDR(0x08611600)) ++#define AVALANCHE_RST_CTRL_RSR (KSEG1ADDR(0x08611608)) + + #define AVALANCHE_POWER_CTRL_PDCR (KSEG1ADDR(0x08610A00)) + #define AVALANCHE_WAKEUP_CTRL_WKCR (KSEG1ADDR(0x08610A0C)) diff --git a/openwrt/target/linux/ar7-2.4/patches/006-sched_use_tsc.patch b/openwrt/target/linux/ar7-2.4/patches/006-sched_use_tsc.patch new file mode 100644 index 0000000000..5b64310738 --- /dev/null +++ b/openwrt/target/linux/ar7-2.4/patches/006-sched_use_tsc.patch @@ -0,0 +1,84 @@ +diff -urN linux.old/arch/mips/kernel/time.c linux.dev/arch/mips/kernel/time.c +--- linux.old/arch/mips/kernel/time.c 2005-11-14 11:06:38.661262000 +0100 ++++ linux.dev/arch/mips/kernel/time.c 2005-11-15 20:02:50.059676750 +0100 +@@ -151,6 +151,27 @@ + unsigned int (*mips_hpt_read)(void); + void (*mips_hpt_init)(unsigned int); + ++extern __u32 get_htscl(void) ++{ ++ return timerhi; ++} ++ ++static __u64 tscll_last = 0; ++ ++extern __u64 get_tscll(void) ++{ ++ __u64 h = (__u64) timerhi; ++ __u32 c = read_c0_count(); ++ ++ h <<= 32; ++ h += c; ++ ++ while (h < tscll_last) ++ h += (((__u64) 1) << 32); ++ ++ tscll_last = h; ++ return h; ++} + + /* + * timeofday services, for syscalls. +@@ -761,3 +782,5 @@ + EXPORT_SYMBOL(to_tm); + EXPORT_SYMBOL(rtc_set_time); + EXPORT_SYMBOL(rtc_get_time); ++EXPORT_SYMBOL(get_htscl); ++EXPORT_SYMBOL(get_tscll); +diff -urN linux.old/include/asm-mips/timex.h linux.dev/include/asm-mips/timex.h +--- linux.old/include/asm-mips/timex.h 2005-11-14 11:06:38.685263500 +0100 ++++ linux.dev/include/asm-mips/timex.h 2005-11-14 11:02:21.069163500 +0100 +@@ -31,6 +31,19 @@ + return read_c0_count(); + } + ++extern __u32 get_htscl(void); ++extern __u64 get_tscll(void); ++ ++#define rdtsc(low, high) \ ++ high = get_htscl(); \ ++ low = read_c0_count(); ++ ++#define rdtscl(low) \ ++ low = read_c0_count(); ++ ++#define rdtscll(val) \ ++ val = get_tscll(); ++ + #define vxtime_lock() do {} while (0) + #define vxtime_unlock() do {} while (0) + +diff -urN linux.old/include/net/pkt_sched.h linux.dev/include/net/pkt_sched.h +--- linux.old/include/net/pkt_sched.h 2005-11-14 11:06:38.709265000 +0100 ++++ linux.dev/include/net/pkt_sched.h 2005-11-14 11:02:21.069163500 +0100 +@@ -5,7 +5,11 @@ + #define PSCHED_JIFFIES 2 + #define PSCHED_CPU 3 + ++#ifdef __mips__ ++#define PSCHED_CLOCK_SOURCE PSCHED_CPU ++#else + #define PSCHED_CLOCK_SOURCE PSCHED_JIFFIES ++#endif + + #include + #include +@@ -271,7 +275,7 @@ + #define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz) + #define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz) + +-#ifdef CONFIG_X86_TSC ++#if defined(CONFIG_X86_TSC) || defined(__mips__) + + #define PSCHED_GET_TIME(stamp) \ + ({ u64 __cur; \ diff --git a/openwrt/target/linux/brcm-2.4/Config.in b/openwrt/target/linux/brcm-2.4/Config.in new file mode 100644 index 0000000000..c344a97e81 --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/Config.in @@ -0,0 +1,18 @@ +config BR2_PACKAGE_KMOD_BRCM_WL + prompt "kmod-brcm-wl...................... Broadcom Wireless Network Driver" + tristate + depends BR2_LINUX_2_4_BRCM + default y + help + Proprietary driver for Broadcom Wireless chipsets + +config BR2_PACKAGE_KMOD_BRCM_WL2 + prompt "kmod-brcm-wl2..................... Broadcom Wireless Network Driver (new)" + tristate + depends BR2_LINUX_2_4_BRCM + default m + help + Proprietary driver for Broadcom Wireless chipsets + New version with Multi-BSS capability + + diff --git a/openwrt/target/linux/brcm-2.4/Makefile b/openwrt/target/linux/brcm-2.4/Makefile new file mode 100644 index 0000000000..435b542df3 --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/Makefile @@ -0,0 +1,71 @@ +include $(TOPDIR)/rules.mk + +LINUX_VERSION:=2.4.32 +LINUX_RELEASE:=1 +LINUX_KERNEL_MD5SUM:=38f4d0830e95a20f4bfed17622d5557c + +include ../rules.mk +include ./config + +# broadcom specific kmod packages +$(eval $(call KMOD_template,BRCM_WL,brcm-wl,\ + $(MODULES_DIR)/kernel/drivers/net/wl/wl.o \ +,CONFIG_WL,,20,wl)) + +$(eval $(call KMOD_template,BRCM_WL2,brcm-wl2,\ + $(BUILD_DIR)/wl/wl2/wl.o \ +,CONFIG_WL,,20,wl)) + +$(eval $(call KMOD_template,LP,lp,\ + $(MODULES_DIR)/kernel/drivers/parport/parport.o \ + $(MODULES_DIR)/kernel/drivers/parport/parport_splink.o \ + $(MODULES_DIR)/kernel/drivers/char/lp.o \ + $(MODULES_DIR)/kernel/drivers/char/ppdev.o \ +,CONFIG_PARPORT,,50,parport parport_splink lp)) + +include ../generic-$(KERNEL)/modules.mk +include ../kernel.mk + + +$(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked + [ -d ../generic-$(KERNEL)/patches ] && $(PATCH) $(LINUX_DIR) ../generic-$(KERNEL)/patches $(MAKE_TRACE) + [ -d ./patches ] && $(PATCH) $(LINUX_DIR) ./patches $(MAKE_TRACE) + @cp config $(LINUX_DIR)/.config + touch $@ + + +############################################### +# Proprietary driver for BCM43xx +############################################### + +LINUX_BINARY_DRIVER_SITE=http://openwrt.org/downloads/sources +# proprietary driver, extracted from Linksys GPL sourcetree WRT54GS 4.70.6 +LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.5.tar.gz +LINUX_BINARY_WL_MD5SUM=78e839842bdc04022bb44469f92b1131 + +$(DL_DIR)/$(LINUX_BINARY_WL_DRIVER): + $(SCRIPT_DIR)/download.pl $(DL_DIR) $(LINUX_BINARY_WL_DRIVER) $(LINUX_BINARY_WL_MD5SUM) $(LINUX_BINARY_DRIVER_SITE) $(MAKE_TRACE) + +$(LINUX_DIR)/.unpacked: $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) +$(LINUX_DIR)/.depend_done: $(LINUX_DIR)/.drivers-unpacked +$(LINUX_DIR)/.modules_done: $(LINUX_DIR)/.drivers-unpacked +$(STAMP_DIR)/.linux-compile: $(LINUX_DIR)/.drivers-installed + +$(LINUX_DIR)/.drivers-unpacked: $(LINUX_DIR)/.unpacked + -mkdir -p $(BUILD_DIR) + zcat $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - + zcat $(DL_DIR)/$(LINUX_ET_DRIVER) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - + # copy binary wlan driver + mkdir -p $(LINUX_DIR)/drivers/net/wl + cp -fpR $(BUILD_DIR)/wl/*.o $(LINUX_DIR)/drivers/net/wl + touch $@ + +$(LINUX_DIR)/.drivers-installed: $(LINUX_DIR)/.modules_done + mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl + @-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/wl.o ] || cp $(LINUX_DIR)/drivers/net/wl/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/ + touch $@ + +linux-dirclean: drivers-clean + +drivers-clean: + rm -rf $(BUILD_DIR)/wl diff --git a/openwrt/target/linux/brcm-2.4/config b/openwrt/target/linux/brcm-2.4/config new file mode 100644 index 0000000000..26d9cd102a --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/config @@ -0,0 +1,1390 @@ +# +# 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 is not set + +# +# 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_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_MIPS_BRCM=y +CONFIG_BCM947XX=y +CONFIG_BCM4710=y +CONFIG_BCM4310=y +CONFIG_BCM4704=y +CONFIG_BCM5365=y +# 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_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 init=/etc/preinit noinitrd console=ttyS0,115200" +CONFIG_PCI=y +CONFIG_NONCOHERENT_IO=y +CONFIG_NEW_TIME_C=y +CONFIG_NEW_IRQ=y +CONFIG_HND=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# 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_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# 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=y +# CONFIG_BUILD_ELF64 is not set +CONFIG_NET=y +CONFIG_PCI=y +# CONFIG_PCI_NEW is not set +CONFIG_PCI_AUTO=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +CONFIG_CARDBUS=y +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_PCIE is not set +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE 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 is not set +# 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 is not set +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 is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_BCM947XX=y +# 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_SPLINK=m +# 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=m +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_RTSP=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_TIME=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_RTSP=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_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_OFFBOARD=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_ATIIXP is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_PDC202XX_BURST=y +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +CONFIG_IDEDMA_IVB=y +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_PDC202XX=y +# 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=m +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=5 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_SCSI_DEBUG_QUEUES is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +# CONFIG_SCSI_SATA_VITESSE is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_SCSI_PCMCIA 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 + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +CONFIG_HND=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_SUNLANCE is not set +# CONFIG_HAPPYMEAL 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_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +CONFIG_B44=y +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_FORCEDETH is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 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_AIRO is not set +# CONFIG_HERMES is not set +CONFIG_WL=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_ATMEL 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 + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA 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_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=m +# 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 + +# +# PCMCIA character devices +# +CONFIG_PCMCIA_SERIAL_CS=m +# CONFIG_SYNCLINK_CS 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=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_UHCI is not set +CONFIG_USB_UHCI_ALT=m +CONFIG_USB_OHCI=m +CONFIG_USB_AUDIO=m +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_HP8200e=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_USB_HID is not set +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_PWC=m +# CONFIG_USB_SE401 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG is not set +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD 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=m +CONFIG_BLUEZ_HCIUSB_SCO=y +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_REMOTE_DEBUG 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 +# CONFIG_FW_LOADER is not set diff --git a/openwrt/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/openwrt/target/linux/brcm-2.4/patches/001-bcm47xx.patch new file mode 100644 index 0000000000..9d919156b6 --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -0,0 +1,23751 @@ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/cfe_env.c linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c +--- linux-2.4.32/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c 2005-12-19 01:56:35.104829500 +0100 +@@ -0,0 +1,234 @@ ++/* ++ * NVRAM variable manipulation (Linux kernel half) ++ * ++ * Copyright 2001-2003, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define NVRAM_SIZE (0x1ff0) ++static char _nvdata[NVRAM_SIZE] __initdata; ++static char _valuestr[256] __initdata; ++ ++/* ++ * TLV types. These codes are used in the "type-length-value" ++ * encoding of the items stored in the NVRAM device (flash or EEPROM) ++ * ++ * The layout of the flash/nvram is as follows: ++ * ++ * ++ * ++ * The type code of "ENV_TLV_TYPE_END" marks the end of the list. ++ * The "length" field marks the length of the data section, not ++ * including the type and length fields. ++ * ++ * Environment variables are stored as follows: ++ * ++ * = ++ * ++ * If bit 0 (low bit) is set, the length is an 8-bit value. ++ * If bit 0 (low bit) is clear, the length is a 16-bit value ++ * ++ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still ++ * indicates the size of the length field. ++ * ++ * Flags are from the constants below: ++ * ++ */ ++#define ENV_LENGTH_16BITS 0x00 /* for low bit */ ++#define ENV_LENGTH_8BITS 0x01 ++ ++#define ENV_TYPE_USER 0x80 ++ ++#define ENV_CODE_SYS(n,l) (((n)<<1)|(l)) ++#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER) ++ ++/* ++ * The actual TLV types we support ++ */ ++ ++#define ENV_TLV_TYPE_END 0x00 ++#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS) ++ ++/* ++ * Environment variable flags ++ */ ++ ++#define ENV_FLG_NORMAL 0x00 /* normal read/write */ ++#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */ ++#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */ ++ ++#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */ ++#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */ ++ ++ ++/* ********************************************************************* ++ * _nvram_read(buffer,offset,length) ++ * ++ * Read data from the NVRAM device ++ * ++ * Input parameters: ++ * buffer - destination buffer ++ * offset - offset of data to read ++ * length - number of bytes to read ++ * ++ * Return value: ++ * number of bytes read, or <0 if error occured ++ ********************************************************************* */ ++static int ++_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length) ++{ ++ int i; ++ if (offset > NVRAM_SIZE) ++ return -1; ++ ++ for ( i = 0; i < length; i++) { ++ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i]; ++ } ++ return length; ++} ++ ++ ++static char* ++_strnchr(const char *dest,int c,size_t cnt) ++{ ++ while (*dest && (cnt > 0)) { ++ if (*dest == c) return (char *) dest; ++ dest++; ++ cnt--; ++ } ++ return NULL; ++} ++ ++ ++ ++/* ++ * Core support API: Externally visible. ++ */ ++ ++/* ++ * Get the value of an NVRAM variable ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++ ++char* ++cfe_env_get(unsigned char *nv_buf, char* name) ++{ ++ int size; ++ unsigned char *buffer; ++ unsigned char *ptr; ++ unsigned char *envval; ++ unsigned int reclen; ++ unsigned int rectype; ++ int offset; ++ int flg; ++ ++ size = NVRAM_SIZE; ++ buffer = &_nvdata[0]; ++ ++ ptr = buffer; ++ offset = 0; ++ ++ /* Read the record type and length */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ ++ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) { ++ ++ /* Adjust pointer for TLV type */ ++ rectype = *(ptr); ++ offset++; ++ size--; ++ ++ /* ++ * Read the length. It can be either 1 or 2 bytes ++ * depending on the code ++ */ ++ if (rectype & ENV_LENGTH_8BITS) { ++ /* Read the record type and length - 8 bits */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ reclen = *(ptr); ++ size--; ++ offset++; ++ } ++ else { ++ /* Read the record type and length - 16 bits, MSB first */ ++ if (_nvram_read(nv_buf, ptr,offset,2) != 2) { ++ goto error; ++ } ++ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); ++ size -= 2; ++ offset += 2; ++ } ++ ++ if (reclen > size) ++ break; /* should not happen, bad NVRAM */ ++ ++ switch (rectype) { ++ case ENV_TLV_TYPE_ENV: ++ /* Read the TLV data */ ++ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen) ++ goto error; ++ flg = *ptr++; ++ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1)); ++ if (envval) { ++ *envval++ = '\0'; ++ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr)); ++ _valuestr[(reclen-1)-(envval-ptr)] = '\0'; ++#if 0 ++ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr); ++#endif ++ if(!strcmp(ptr, name)){ ++ return _valuestr; ++ } ++ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name)) ++ return _valuestr; ++ } ++ break; ++ ++ default: ++ /* Unknown TLV type, skip it. */ ++ break; ++ } ++ ++ /* ++ * Advance to next TLV ++ */ ++ ++ size -= (int)reclen; ++ offset += reclen; ++ ++ /* Read the next record type */ ++ ptr = buffer; ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) ++ goto error; ++ } ++ ++error: ++ return NULL; ++ ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile +--- linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,33 @@ ++# ++# Makefile for Broadcom BCM947XX boards ++# ++# Copyright 2001-2003, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $ ++# ++ ++OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S ++SYSTEM ?= $(TOPDIR)/vmlinux ++ ++all: vmlinuz ++ ++# Don't build dependencies, this may die if $(CC) isn't gcc ++dep: ++ ++# Create a gzipped version named vmlinuz for compatibility ++vmlinuz: piggy ++ gzip -c9 $< > $@ ++ ++piggy: $(SYSTEM) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ ++ ++mrproper: clean ++ ++clean: ++ rm -f vmlinuz piggy +diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S +--- linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,51 @@ ++/* ++ * Generic interrupt handler for Broadcom MIPS boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: int-handler.S,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * MIPS IRQ Source ++ * -------- ------ ++ * 0 Software (ignored) ++ * 1 Software (ignored) ++ * 2 Combined hardware interrupt (hw0) ++ * 3 Hardware ++ * 4 Hardware ++ * 5 Hardware ++ * 6 Hardware ++ * 7 R4k timer ++ */ ++ ++ .text ++ .set noreorder ++ .set noat ++ .align 5 ++ NESTED(brcmIRQ, PT_SIZE, sp) ++ SAVE_ALL ++ CLI ++ .set at ++ .set noreorder ++ ++ jal brcm_irq_dispatch ++ move a0, sp ++ ++ j ret_from_irq ++ nop ++ ++ END(brcmIRQ) +diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/irq.c linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c +--- linux-2.4.32/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,130 @@ ++/* ++ * Generic interrupt control functions for Broadcom MIPS boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: irq.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) ++ ++extern asmlinkage void brcmIRQ(void); ++extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); ++ ++void ++brcm_irq_dispatch(struct pt_regs *regs) ++{ ++ u32 cause; ++ ++ cause = read_c0_cause() & ++ read_c0_status() & ++ CAUSEF_IP; ++ ++#ifdef CONFIG_KERNPROF ++ change_c0_status(cause | 1, 1); ++#else ++ clear_c0_status(cause); ++#endif ++ ++ if (cause & CAUSEF_IP7) ++ do_IRQ(7, regs); ++ if (cause & CAUSEF_IP2) ++ do_IRQ(2, regs); ++ if (cause & CAUSEF_IP3) ++ do_IRQ(3, regs); ++ if (cause & CAUSEF_IP4) ++ do_IRQ(4, regs); ++ if (cause & CAUSEF_IP5) ++ do_IRQ(5, regs); ++ if (cause & CAUSEF_IP6) ++ do_IRQ(6, regs); ++} ++ ++static void ++enable_brcm_irq(unsigned int irq) ++{ ++ if (irq < 8) ++ set_c0_status(1 << (irq + 8)); ++ else ++ set_c0_status(IE_IRQ0); ++} ++ ++static void ++disable_brcm_irq(unsigned int irq) ++{ ++ if (irq < 8) ++ clear_c0_status(1 << (irq + 8)); ++ else ++ clear_c0_status(IE_IRQ0); ++} ++ ++static void ++ack_brcm_irq(unsigned int irq) ++{ ++ /* Already done in brcm_irq_dispatch */ ++} ++ ++static unsigned int ++startup_brcm_irq(unsigned int irq) ++{ ++ enable_brcm_irq(irq); ++ ++ return 0; /* never anything pending */ ++} ++ ++static void ++end_brcm_irq(unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) ++ enable_brcm_irq(irq); ++} ++ ++static struct hw_interrupt_type brcm_irq_type = { ++ typename: "MIPS", ++ startup: startup_brcm_irq, ++ shutdown: disable_brcm_irq, ++ enable: enable_brcm_irq, ++ disable: disable_brcm_irq, ++ ack: ack_brcm_irq, ++ end: end_brcm_irq, ++ NULL ++}; ++ ++void __init ++init_IRQ(void) ++{ ++ int i; ++ ++ for (i = 0; i < NR_IRQS; i++) { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = 0; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &brcm_irq_type; ++ } ++ ++ set_except_vector(0, brcmIRQ); ++ change_c0_status(ST0_IM, ALLINTS); ++ ++#ifdef CONFIG_REMOTE_DEBUG ++ printk("Breaking into debugger...\n"); ++ set_debug_traps(); ++ breakpoint(); ++#endif ++} +diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile +--- linux-2.4.32/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++ ++.S.s: ++ $(CPP) $(AFLAGS) $< -o $*.s ++.S.o: ++ $(CC) $(AFLAGS) -c $< -o $*.o ++ ++O_TARGET := brcm.o ++ ++obj-y := int-handler.o irq.o ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/arch/mips/bcm947xx/gpio.c linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c +--- linux-2.4.32/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,158 @@ ++/* ++ * GPIO char driver ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++static sb_t *gpio_sbh; ++static int gpio_major; ++static devfs_handle_t gpio_dir; ++static struct { ++ char *name; ++ devfs_handle_t handle; ++} gpio_file[] = { ++ { "in", NULL }, ++ { "out", NULL }, ++ { "outen", NULL }, ++ { "control", NULL } ++}; ++ ++static int ++gpio_open(struct inode *inode, struct file * file) ++{ ++ if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file)) ++ return -ENODEV; ++ ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++static int ++gpio_release(struct inode *inode, struct file * file) ++{ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static ssize_t ++gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ u32 val; ++ ++ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { ++ case 0: ++ val = sb_gpioin(gpio_sbh); ++ break; ++ case 1: ++ val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ case 2: ++ val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ case 3: ++ val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ default: ++ return -ENODEV; ++ } ++ ++ if (put_user(val, (u32 *) buf)) ++ return -EFAULT; ++ ++ return sizeof(val); ++} ++ ++static ssize_t ++gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ++{ ++ u32 val; ++ ++ if (get_user(val, (u32 *) buf)) ++ return -EFAULT; ++ ++ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { ++ case 0: ++ return -EACCES; ++ case 1: ++ sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ case 2: ++ sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ case 3: ++ sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ default: ++ return -ENODEV; ++ } ++ ++ return sizeof(val); ++} ++ ++static struct file_operations gpio_fops = { ++ owner: THIS_MODULE, ++ open: gpio_open, ++ release: gpio_release, ++ read: gpio_read, ++ write: gpio_write, ++}; ++ ++static int __init ++gpio_init(void) ++{ ++ int i; ++ ++ if (!(gpio_sbh = sb_kattach())) ++ return -ENODEV; ++ ++ sb_gpiosetcore(gpio_sbh); ++ ++ if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0) ++ return gpio_major; ++ ++ gpio_dir = devfs_mk_dir(NULL, "gpio", NULL); ++ ++ for (i = 0; i < ARRAYSIZE(gpio_file); i++) { ++ gpio_file[i].handle = devfs_register(gpio_dir, ++ gpio_file[i].name, ++ DEVFS_FL_DEFAULT, gpio_major, i, ++ S_IFCHR | S_IRUGO | S_IWUGO, ++ &gpio_fops, NULL); ++ } ++ ++ return 0; ++} ++ ++static void __exit ++gpio_exit(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAYSIZE(gpio_file); i++) ++ devfs_unregister(gpio_file[i].handle); ++ devfs_unregister(gpio_dir); ++ devfs_unregister_chrdev(gpio_major, "gpio"); ++ sb_detach(gpio_sbh); ++} ++ ++module_init(gpio_init); ++module_exit(gpio_exit); +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h 2005-12-16 23:39:10.672819750 +0100 +@@ -0,0 +1,391 @@ ++/* ++ * Broadcom device-specific manifest constants. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _BCMDEVS_H ++#define _BCMDEVS_H ++ ++ ++/* Known PCI vendor Id's */ ++#define VENDOR_EPIGRAM 0xfeda ++#define VENDOR_BROADCOM 0x14e4 ++#define VENDOR_3COM 0x10b7 ++#define VENDOR_NETGEAR 0x1385 ++#define VENDOR_DIAMOND 0x1092 ++#define VENDOR_DELL 0x1028 ++#define VENDOR_HP 0x0e11 ++#define VENDOR_APPLE 0x106b ++ ++/* PCI Device Id's */ ++#define BCM4210_DEVICE_ID 0x1072 /* never used */ ++#define BCM4211_DEVICE_ID 0x4211 ++#define BCM4230_DEVICE_ID 0x1086 /* never used */ ++#define BCM4231_DEVICE_ID 0x4231 ++ ++#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ ++#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ ++#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ ++#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ ++ ++#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ ++#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ ++ ++#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ ++#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ ++ ++#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */ ++#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ ++#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ ++#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ ++#define BCM47XX_USB_ID 0x4715 /* 47xx usb */ ++#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ ++#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ ++#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ ++#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ ++#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ ++#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ ++ ++#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ ++ ++#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */ ++#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */ ++#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */ ++#define BCM4610_ENET_ID 0x4613 /* 4610 enet */ ++#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */ ++#define BCM4610_USB_ID 0x4615 /* 4610 usb */ ++ ++#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */ ++#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ ++#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ ++#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ ++ ++#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */ ++#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */ ++ ++#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */ ++#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */ ++#define BCM4307_ENET_ID 0x4306 /* 4307 enet */ ++#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */ ++ ++#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ ++#define BCM4306_D11G_ID2 0x4325 ++#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ ++#define BCM4306_UART_ID 0x4322 /* 4306 uart */ ++#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ ++#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ ++ ++#define BCM4309_PKG_ID 1 /* 4309 package id */ ++ ++#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ ++#define BCM4303_PKG_ID 2 /* 4303 package id */ ++ ++#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */ ++#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */ ++#define BCM4310_UART_ID 0x4312 /* 4310 uart */ ++#define BCM4310_ENET_ID 0x4313 /* 4310 enet */ ++#define BCM4310_USB_ID 0x4315 /* 4310 usb */ ++ ++#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ ++#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ ++ ++ ++#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */ ++#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ ++ ++#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */ ++ ++#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */ ++#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */ ++ ++#define FPGA_JTAGM_ID 0x4330 /* ??? */ ++ ++/* Address map */ ++#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ ++#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ ++#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ ++#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ ++#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ ++ ++/* Core register space */ ++#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ ++#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ ++#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ ++#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ ++#define BCM4710_REG_USB 0x18004000 /* USB core registers */ ++#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ ++#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ ++#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ ++#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ ++ ++#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ ++#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ ++#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ ++#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ ++#define BCM4710_PROG 0x1f800000 /* Programable interface */ ++#define BCM4710_FLASH 0x1fc00000 /* Flash */ ++ ++#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) ++ ++#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) ++#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) ++ ++#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ ++#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ ++#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ ++#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ ++ ++#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */ ++ ++#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */ ++#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */ ++ ++#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */ ++ ++/* PCMCIA vendor Id's */ ++ ++#define VENDOR_BROADCOM_PCMCIA 0x02d0 ++ ++/* SDIO vendor Id's */ ++#define VENDOR_BROADCOM_SDIO 0x00BF ++ ++ ++/* boardflags */ ++#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */ ++#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */ ++#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */ ++#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */ ++#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */ ++#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */ ++#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */ ++#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */ ++#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */ ++#define BFL_FEM 0x0800 /* This board supports the Front End Module */ ++#define BFL_EXTLNA 0x1000 /* This board has an external LNA */ ++#define BFL_HGPA 0x2000 /* This board has a high gain PA */ ++#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ ++#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ ++ ++/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ ++#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */ ++#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ ++#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ ++#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ ++#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */ ++#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ ++#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ ++#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ ++#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ ++#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ ++ ++/* Bus types */ ++#define SB_BUS 0 /* Silicon Backplane */ ++#define PCI_BUS 1 /* PCI target */ ++#define PCMCIA_BUS 2 /* PCMCIA target */ ++#define SDIO_BUS 3 /* SDIO target */ ++#define JTAG_BUS 4 /* JTAG */ ++ ++/* Allows optimization for single-bus support */ ++#ifdef BCMBUSTYPE ++#define BUSTYPE(bus) (BCMBUSTYPE) ++#else ++#define BUSTYPE(bus) (bus) ++#endif ++ ++/* power control defines */ ++#define PLL_DELAY 150 /* us pll on delay */ ++#define FREF_DELAY 200 /* us fref change delay */ ++#define MIN_SLOW_CLK 32 /* us Slow clock period */ ++#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ ++ ++/* Reference Board Types */ ++ ++#define BU4710_BOARD 0x0400 ++#define VSIM4710_BOARD 0x0401 ++#define QT4710_BOARD 0x0402 ++ ++#define BU4610_BOARD 0x0403 ++#define VSIM4610_BOARD 0x0404 ++ ++#define BU4307_BOARD 0x0405 ++#define BCM94301CB_BOARD 0x0406 ++#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */ ++#define BCM94301MP_BOARD 0x0407 ++#define BCM94307MP_BOARD 0x0408 ++#define BCMAP4307_BOARD 0x0409 ++ ++#define BU4309_BOARD 0x040a ++#define BCM94309CB_BOARD 0x040b ++#define BCM94309MP_BOARD 0x040c ++#define BCM4309AP_BOARD 0x040d ++ ++#define BCM94302MP_BOARD 0x040e ++ ++#define VSIM4310_BOARD 0x040f ++#define BU4711_BOARD 0x0410 ++#define BCM94310U_BOARD 0x0411 ++#define BCM94310AP_BOARD 0x0412 ++#define BCM94310MP_BOARD 0x0414 ++ ++#define BU4306_BOARD 0x0416 ++#define BCM94306CB_BOARD 0x0417 ++#define BCM94306MP_BOARD 0x0418 ++ ++#define BCM94710D_BOARD 0x041a ++#define BCM94710R1_BOARD 0x041b ++#define BCM94710R4_BOARD 0x041c ++#define BCM94710AP_BOARD 0x041d ++ ++ ++#define BU2050_BOARD 0x041f ++ ++ ++#define BCM94309G_BOARD 0x0421 ++ ++#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */ ++ ++#define BU4704_BOARD 0x0423 ++#define BU4702_BOARD 0x0424 ++ ++#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ ++ ++#define BU4317_BOARD 0x0426 ++ ++ ++#define BCM94702MN_BOARD 0x0428 ++ ++/* BCM4702 1U CompactPCI Board */ ++#define BCM94702CPCI_BOARD 0x0429 ++ ++/* BCM4702 with BCM95380 VLAN Router */ ++#define BCM95380RR_BOARD 0x042a ++ ++/* cb4306 with SiGe PA */ ++#define BCM94306CBSG_BOARD 0x042b ++ ++/* mp4301 with 2050 radio */ ++#define BCM94301MPL_BOARD 0x042c ++ ++/* cb4306 with SiGe PA */ ++#define PCSG94306_BOARD 0x042d ++ ++/* bu4704 with sdram */ ++#define BU4704SD_BOARD 0x042e ++ ++/* Dual 11a/11g Router */ ++#define BCM94704AGR_BOARD 0x042f ++ ++/* 11a-only minipci */ ++#define BCM94308MP_BOARD 0x0430 ++ ++ ++ ++/* BCM94317 boards */ ++#define BCM94317CB_BOARD 0x0440 ++#define BCM94317MP_BOARD 0x0441 ++#define BCM94317PCMCIA_BOARD 0x0442 ++#define BCM94317SDIO_BOARD 0x0443 ++ ++#define BU4712_BOARD 0x0444 ++#define BU4712SD_BOARD 0x045d ++#define BU4712L_BOARD 0x045f ++ ++/* BCM4712 boards */ ++#define BCM94712AP_BOARD 0x0445 ++#define BCM94712P_BOARD 0x0446 ++ ++/* BCM4318 boards */ ++#define BU4318_BOARD 0x0447 ++#define CB4318_BOARD 0x0448 ++#define MPG4318_BOARD 0x0449 ++#define MP4318_BOARD 0x044a ++#define SD4318_BOARD 0x044b ++ ++/* BCM63XX boards */ ++#define BCM96338_BOARD 0x6338 ++#define BCM96345_BOARD 0x6345 ++#define BCM96348_BOARD 0x6348 ++ ++/* Another mp4306 with SiGe */ ++#define BCM94306P_BOARD 0x044c ++ ++/* CF-like 4317 modules */ ++#define BCM94317CF_BOARD 0x044d ++ ++/* mp4303 */ ++#define BCM94303MP_BOARD 0x044e ++ ++/* mpsgh4306 */ ++#define BCM94306MPSGH_BOARD 0x044f ++ ++/* BRCM 4306 w/ Front End Modules */ ++#define BCM94306MPM 0x0450 ++#define BCM94306MPL 0x0453 ++ ++/* 4712agr */ ++#define BCM94712AGR_BOARD 0x0451 ++ ++/* The real CF 4317 board */ ++#define CFI4317_BOARD 0x0452 ++ ++/* pcmcia 4303 */ ++#define PC4303_BOARD 0x0454 ++ ++/* 5350K */ ++#define BCM95350K_BOARD 0x0455 ++ ++/* 5350R */ ++#define BCM95350R_BOARD 0x0456 ++ ++/* 4306mplna */ ++#define BCM94306MPLNA_BOARD 0x0457 ++ ++/* 4320 boards */ ++#define BU4320_BOARD 0x0458 ++#define BU4320S_BOARD 0x0459 ++#define BCM94320PH_BOARD 0x045a ++ ++/* 4306mph */ ++#define BCM94306MPH_BOARD 0x045b ++ ++/* 4306pciv */ ++#define BCM94306PCIV_BOARD 0x045c ++ ++#define BU4712SD_BOARD 0x045d ++ ++#define BCM94320PFLSH_BOARD 0x045e ++ ++#define BU4712L_BOARD 0x045f ++#define BCM94712LGR_BOARD 0x0460 ++#define BCM94320R_BOARD 0x0461 ++ ++#define BU5352_BOARD 0x0462 ++ ++#define BCM94318MPGH_BOARD 0x0463 ++ ++ ++#define BCM95352GR_BOARD 0x0467 ++ ++/* bcm95351agr */ ++#define BCM95351AGR_BOARD 0x0470 ++ ++/* # of GPIO pins */ ++#define GPIO_NUMPINS 16 ++ ++#endif /* _BCMDEVS_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h 2005-12-16 23:39:10.672819750 +0100 +@@ -0,0 +1,152 @@ ++/* ++ * local version of endian.h - byte order defines ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++*/ ++ ++#ifndef _BCMENDIAN_H_ ++#define _BCMENDIAN_H_ ++ ++#include ++ ++/* Byte swap a 16 bit value */ ++#define BCMSWAP16(val) \ ++ ((uint16)( \ ++ (((uint16)(val) & (uint16)0x00ffU) << 8) | \ ++ (((uint16)(val) & (uint16)0xff00U) >> 8) )) ++ ++/* Byte swap a 32 bit value */ ++#define BCMSWAP32(val) \ ++ ((uint32)( \ ++ (((uint32)(val) & (uint32)0x000000ffUL) << 24) | \ ++ (((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \ ++ (((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \ ++ (((uint32)(val) & (uint32)0xff000000UL) >> 24) )) ++ ++/* 2 Byte swap a 32 bit value */ ++#define BCMSWAP32BY16(val) \ ++ ((uint32)( \ ++ (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \ ++ (((uint32)(val) & (uint32)0xffff0000UL) >> 16) )) ++ ++ ++static INLINE uint16 ++bcmswap16(uint16 val) ++{ ++ return BCMSWAP16(val); ++} ++ ++static INLINE uint32 ++bcmswap32(uint32 val) ++{ ++ return BCMSWAP32(val); ++} ++ ++static INLINE uint32 ++bcmswap32by16(uint32 val) ++{ ++ return BCMSWAP32BY16(val); ++} ++ ++/* buf - start of buffer of shorts to swap */ ++/* len - byte length of buffer */ ++static INLINE void ++bcmswap16_buf(uint16 *buf, uint len) ++{ ++ len = len/2; ++ ++ while(len--){ ++ *buf = bcmswap16(*buf); ++ buf++; ++ } ++} ++ ++#ifndef hton16 ++#ifndef IL_BIGENDIAN ++#define HTON16(i) BCMSWAP16(i) ++#define hton16(i) bcmswap16(i) ++#define hton32(i) bcmswap32(i) ++#define ntoh16(i) bcmswap16(i) ++#define ntoh32(i) bcmswap32(i) ++#define ltoh16(i) (i) ++#define ltoh32(i) (i) ++#define htol16(i) (i) ++#define htol32(i) (i) ++#else ++#define HTON16(i) (i) ++#define hton16(i) (i) ++#define hton32(i) (i) ++#define ntoh16(i) (i) ++#define ntoh32(i) (i) ++#define ltoh16(i) bcmswap16(i) ++#define ltoh32(i) bcmswap32(i) ++#define htol16(i) bcmswap16(i) ++#define htol32(i) bcmswap32(i) ++#endif ++#endif ++ ++#ifndef IL_BIGENDIAN ++#define ltoh16_buf(buf, i) ++#define htol16_buf(buf, i) ++#else ++#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#endif ++ ++/* ++* load 16-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint16 ++ltoh16_ua(uint8 *bytes) ++{ ++ return (bytes[1]<<8)+bytes[0]; ++} ++ ++/* ++* load 32-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint32 ++ltoh32_ua(uint8 *bytes) ++{ ++ return (bytes[3]<<24)+(bytes[2]<<16)+(bytes[1]<<8)+bytes[0]; ++} ++ ++/* ++* load 16-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint16 ++ntoh16_ua(uint8 *bytes) ++{ ++ return (bytes[0]<<8)+bytes[1]; ++} ++ ++/* ++* load 32-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint32 ++ntoh32_ua(uint8 *bytes) ++{ ++ return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3]; ++} ++ ++#define ltoh_ua(ptr) ( \ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \ ++ (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \ ++) ++ ++#define ntoh_ua(ptr) ( \ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \ ++ (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \ ++) ++ ++#endif /* _BCMENDIAN_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenet47xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,229 @@ ++/* ++ * Hardware-specific definitions for ++ * Broadcom BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenet_47xx_h_ ++#define _bcmenet_47xx_h_ ++ ++#include ++#include ++#include ++ ++#define BCMENET_NFILTERS 64 /* # ethernet address filter entries */ ++#define BCMENET_MCHASHBASE 0x200 /* multicast hash filter base address */ ++#define BCMENET_MCHASHSIZE 256 /* multicast hash filter size in bytes */ ++#define BCMENET_MAX_DMA 4096 /* chip has 12 bits of DMA addressing */ ++ ++/* power management event wakeup pattern constants */ ++#define BCMENET_NPMP 4 /* chip supports 4 wakeup patterns */ ++#define BCMENET_PMPBASE 0x400 /* wakeup pattern base address */ ++#define BCMENET_PMPSIZE 0x80 /* 128bytes each pattern */ ++#define BCMENET_PMMBASE 0x600 /* wakeup mask base address */ ++#define BCMENET_PMMSIZE 0x10 /* 128bits each mask */ ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * Host Interface Registers ++ */ ++typedef volatile struct _bcmenettregs { ++ /* Device and Power Control */ ++ uint32 devcontrol; ++ uint32 PAD[2]; ++ uint32 biststatus; ++ uint32 wakeuplength; ++ uint32 PAD[3]; ++ ++ /* Interrupt Control */ ++ uint32 intstatus; ++ uint32 intmask; ++ uint32 gptimer; ++ uint32 PAD[23]; ++ ++ /* Ethernet MAC Address Filtering Control */ ++ uint32 PAD[2]; ++ uint32 enetftaddr; ++ uint32 enetftdata; ++ uint32 PAD[2]; ++ ++ /* Ethernet MAC Control */ ++ uint32 emactxmaxburstlen; ++ uint32 emacrxmaxburstlen; ++ uint32 emaccontrol; ++ uint32 emacflowcontrol; ++ ++ uint32 PAD[20]; ++ ++ /* DMA Lazy Interrupt Control */ ++ uint32 intrecvlazy; ++ uint32 PAD[63]; ++ ++ /* DMA engine */ ++ dma32regp_t dmaregs; ++ dma32diag_t dmafifo; ++ uint32 PAD[116]; ++ ++ /* EMAC Registers */ ++ uint32 rxconfig; ++ uint32 rxmaxlength; ++ uint32 txmaxlength; ++ uint32 PAD; ++ uint32 mdiocontrol; ++ uint32 mdiodata; ++ uint32 emacintmask; ++ uint32 emacintstatus; ++ uint32 camdatalo; ++ uint32 camdatahi; ++ uint32 camcontrol; ++ uint32 enetcontrol; ++ uint32 txcontrol; ++ uint32 txwatermark; ++ uint32 mibcontrol; ++ uint32 PAD[49]; ++ ++ /* EMAC MIB counters */ ++ bcmenetmib_t mib; ++ ++ uint32 PAD[585]; ++ ++ /* Sonics SiliconBackplane config registers */ ++ sbconfig_t sbconfig; ++} bcmenetregs_t; ++ ++/* device control */ ++#define DC_PM ((uint32)1 << 7) /* pattern filtering enable */ ++#define DC_IP ((uint32)1 << 10) /* internal ephy present (rev >= 1) */ ++#define DC_ER ((uint32)1 << 15) /* ephy reset */ ++#define DC_MP ((uint32)1 << 16) /* mii phy mode enable */ ++#define DC_CO ((uint32)1 << 17) /* mii phy mode: enable clocks */ ++#define DC_PA_MASK 0x7c0000 /* mii phy mode: mdc/mdio phy address */ ++#define DC_PA_SHIFT 18 ++#define DC_FS_MASK 0x03800000 /* fifo size (rev >= 8) */ ++#define DC_FS_SHIFT 23 ++#define DC_FS_4K 0 /* 4Kbytes */ ++#define DC_FS_512 1 /* 512bytes */ ++ ++/* wakeup length */ ++#define WL_P0_MASK 0x7f /* pattern 0 */ ++#define WL_D0 ((uint32)1 << 7) ++#define WL_P1_MASK 0x7f00 /* pattern 1 */ ++#define WL_P1_SHIFT 8 ++#define WL_D1 ((uint32)1 << 15) ++#define WL_P2_MASK 0x7f0000 /* pattern 2 */ ++#define WL_P2_SHIFT 16 ++#define WL_D2 ((uint32)1 << 23) ++#define WL_P3_MASK 0x7f000000 /* pattern 3 */ ++#define WL_P3_SHIFT 24 ++#define WL_D3 ((uint32)1 << 31) ++ ++/* intstatus and intmask */ ++#define I_PME ((uint32)1 << 6) /* power management event */ ++#define I_TO ((uint32)1 << 7) /* general purpose timeout */ ++#define I_PC ((uint32)1 << 10) /* descriptor error */ ++#define I_PD ((uint32)1 << 11) /* data error */ ++#define I_DE ((uint32)1 << 12) /* descriptor protocol error */ ++#define I_RU ((uint32)1 << 13) /* receive descriptor underflow */ ++#define I_RO ((uint32)1 << 14) /* receive fifo overflow */ ++#define I_XU ((uint32)1 << 15) /* transmit fifo underflow */ ++#define I_RI ((uint32)1 << 16) /* receive interrupt */ ++#define I_XI ((uint32)1 << 24) /* transmit interrupt */ ++#define I_EM ((uint32)1 << 26) /* emac interrupt */ ++#define I_MW ((uint32)1 << 27) /* mii write */ ++#define I_MR ((uint32)1 << 28) /* mii read */ ++ ++/* emaccontrol */ ++#define EMC_CG ((uint32)1 << 0) /* crc32 generation enable */ ++#define EMC_EP ((uint32)1 << 2) /* onchip ephy: powerdown (rev >= 1) */ ++#define EMC_ED ((uint32)1 << 3) /* onchip ephy: energy detected (rev >= 1) */ ++#define EMC_LC_MASK 0xe0 /* onchip ephy: led control (rev >= 1) */ ++#define EMC_LC_SHIFT 5 ++ ++/* emacflowcontrol */ ++#define EMF_RFH_MASK 0xff /* rx fifo hi water mark */ ++#define EMF_PG ((uint32)1 << 15) /* enable pause frame generation */ ++ ++/* interrupt receive lazy */ ++#define IRL_TO_MASK 0x00ffffff /* timeout */ ++#define IRL_FC_MASK 0xff000000 /* frame count */ ++#define IRL_FC_SHIFT 24 /* frame count */ ++ ++/* emac receive config */ ++#define ERC_DB ((uint32)1 << 0) /* disable broadcast */ ++#define ERC_AM ((uint32)1 << 1) /* accept all multicast */ ++#define ERC_RDT ((uint32)1 << 2) /* receive disable while transmitting */ ++#define ERC_PE ((uint32)1 << 3) /* promiscuous enable */ ++#define ERC_LE ((uint32)1 << 4) /* loopback enable */ ++#define ERC_FE ((uint32)1 << 5) /* enable flow control */ ++#define ERC_UF ((uint32)1 << 6) /* accept unicast flow control frame */ ++#define ERC_RF ((uint32)1 << 7) /* reject filter */ ++#define ERC_CA ((uint32)1 << 8) /* cam absent */ ++ ++/* emac mdio control */ ++#define MC_MF_MASK 0x7f /* mdc frequency */ ++#define MC_PE ((uint32)1 << 7) /* mii preamble enable */ ++ ++/* emac mdio data */ ++#define MD_DATA_MASK 0xffff /* r/w data */ ++#define MD_TA_MASK 0x30000 /* turnaround value */ ++#define MD_TA_SHIFT 16 ++#define MD_TA_VALID (2 << MD_TA_SHIFT) /* valid ta */ ++#define MD_RA_MASK 0x7c0000 /* register address */ ++#define MD_RA_SHIFT 18 ++#define MD_PMD_MASK 0xf800000 /* physical media device */ ++#define MD_PMD_SHIFT 23 ++#define MD_OP_MASK 0x30000000 /* opcode */ ++#define MD_OP_SHIFT 28 ++#define MD_OP_WRITE (1 << MD_OP_SHIFT) /* write op */ ++#define MD_OP_READ (2 << MD_OP_SHIFT) /* read op */ ++#define MD_SB_MASK 0xc0000000 /* start bits */ ++#define MD_SB_SHIFT 30 ++#define MD_SB_START (0x1 << MD_SB_SHIFT) /* start of frame */ ++ ++/* emac intstatus and intmask */ ++#define EI_MII ((uint32)1 << 0) /* mii mdio interrupt */ ++#define EI_MIB ((uint32)1 << 1) /* mib interrupt */ ++#define EI_FLOW ((uint32)1 << 2) /* flow control interrupt */ ++ ++/* emac cam data high */ ++#define CD_V ((uint32)1 << 16) /* valid bit */ ++ ++/* emac cam control */ ++#define CC_CE ((uint32)1 << 0) /* cam enable */ ++#define CC_MS ((uint32)1 << 1) /* mask select */ ++#define CC_RD ((uint32)1 << 2) /* read */ ++#define CC_WR ((uint32)1 << 3) /* write */ ++#define CC_INDEX_MASK 0x3f0000 /* index */ ++#define CC_INDEX_SHIFT 16 ++#define CC_CB ((uint32)1 << 31) /* cam busy */ ++ ++/* emac ethernet control */ ++#define EC_EE ((uint32)1 << 0) /* emac enable */ ++#define EC_ED ((uint32)1 << 1) /* emac disable */ ++#define EC_ES ((uint32)1 << 2) /* emac soft reset */ ++#define EC_EP ((uint32)1 << 3) /* external phy select */ ++ ++/* emac transmit control */ ++#define EXC_FD ((uint32)1 << 0) /* full duplex */ ++#define EXC_FM ((uint32)1 << 1) /* flowmode */ ++#define EXC_SB ((uint32)1 << 2) /* single backoff enable */ ++#define EXC_SS ((uint32)1 << 3) /* small slottime */ ++ ++/* emac mib control */ ++#define EMC_RZ ((uint32)1 << 0) /* autoclear on read */ ++ ++#endif /* _bcmenet_47xx_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetmib.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetmib.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetmib.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,81 @@ ++/* ++ * Hardware-specific MIB definition for ++ * Broadcom Home Networking Division ++ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenetmib_h_ ++#define _bcmenetmib_h_ ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * EMAC MIB Registers ++ */ ++typedef volatile struct { ++ uint32 tx_good_octets; ++ uint32 tx_good_pkts; ++ uint32 tx_octets; ++ uint32 tx_pkts; ++ uint32 tx_broadcast_pkts; ++ uint32 tx_multicast_pkts; ++ uint32 tx_len_64; ++ uint32 tx_len_65_to_127; ++ uint32 tx_len_128_to_255; ++ uint32 tx_len_256_to_511; ++ uint32 tx_len_512_to_1023; ++ uint32 tx_len_1024_to_max; ++ uint32 tx_jabber_pkts; ++ uint32 tx_oversize_pkts; ++ uint32 tx_fragment_pkts; ++ uint32 tx_underruns; ++ uint32 tx_total_cols; ++ uint32 tx_single_cols; ++ uint32 tx_multiple_cols; ++ uint32 tx_excessive_cols; ++ uint32 tx_late_cols; ++ uint32 tx_defered; ++ uint32 tx_carrier_lost; ++ uint32 tx_pause_pkts; ++ uint32 PAD[8]; ++ ++ uint32 rx_good_octets; ++ uint32 rx_good_pkts; ++ uint32 rx_octets; ++ uint32 rx_pkts; ++ uint32 rx_broadcast_pkts; ++ uint32 rx_multicast_pkts; ++ uint32 rx_len_64; ++ uint32 rx_len_65_to_127; ++ uint32 rx_len_128_to_255; ++ uint32 rx_len_256_to_511; ++ uint32 rx_len_512_to_1023; ++ uint32 rx_len_1024_to_max; ++ uint32 rx_jabber_pkts; ++ uint32 rx_oversize_pkts; ++ uint32 rx_fragment_pkts; ++ uint32 rx_missed_pkts; ++ uint32 rx_crc_align_errs; ++ uint32 rx_undersize; ++ uint32 rx_crc_errs; ++ uint32 rx_align_errs; ++ uint32 rx_symbol_errs; ++ uint32 rx_pause_pkts; ++ uint32 rx_nonpause_pkts; ++} bcmenetmib_t; ++ ++#endif /* _bcmenetmib_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetphy.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetphy.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetphy.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetphy.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,58 @@ ++/* ++ * Misc Broadcom BCM47XX MDC/MDIO enet phy definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenetphy_h_ ++#define _bcmenetphy_h_ ++ ++/* phy address */ ++#define MAXEPHY 32 /* mdio phy addresses are 5bit quantities */ ++#define EPHY_MASK 0x1f ++#define EPHY_NONE 31 /* nvram: no phy present at all */ ++#define EPHY_NOREG 30 /* nvram: no local phy regs */ ++ ++/* just a few phy registers */ ++#define CTL_RESET (1 << 15) /* reset */ ++#define CTL_LOOP (1 << 14) /* loopback */ ++#define CTL_SPEED (1 << 13) /* speed selection 0=10, 1=100 */ ++#define CTL_ANENAB (1 << 12) /* autonegotiation enable */ ++#define CTL_RESTART (1 << 9) /* restart autonegotiation */ ++#define CTL_DUPLEX (1 << 8) /* duplex mode 0=half, 1=full */ ++ ++#define ADV_10FULL (1 << 6) /* autonegotiate advertise 10full */ ++#define ADV_10HALF (1 << 5) /* autonegotiate advertise 10half */ ++#define ADV_100FULL (1 << 8) /* autonegotiate advertise 100full */ ++#define ADV_100HALF (1 << 7) /* autonegotiate advertise 100half */ ++ ++/* link partner ability register */ ++#define LPA_SLCT 0x001f /* same as advertise selector */ ++#define LPA_10HALF 0x0020 /* can do 10mbps half-duplex */ ++#define LPA_10FULL 0x0040 /* can do 10mbps full-duplex */ ++#define LPA_100HALF 0x0080 /* can do 100mbps half-duplex */ ++#define LPA_100FULL 0x0100 /* can do 100mbps full-duplex */ ++#define LPA_100BASE4 0x0200 /* can do 100mbps 4k packets */ ++#define LPA_RESV 0x1c00 /* unused */ ++#define LPA_RFAULT 0x2000 /* link partner faulted */ ++#define LPA_LPACK 0x4000 /* link partner acked us */ ++#define LPA_NPAGE 0x8000 /* next page bit */ ++ ++#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) ++#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) ++ ++#define STAT_REMFAULT (1 << 4) /* remote fault */ ++#define STAT_LINK (1 << 2) /* link status */ ++#define STAT_JAB (1 << 1) /* jabber detected */ ++#define AUX_FORCED (1 << 2) /* forced 10/100 */ ++#define AUX_SPEED (1 << 1) /* speed 0=10mbps 1=100mbps */ ++#define AUX_DUPLEX (1 << 0) /* duplex 0=half 1=full */ ++ ++#endif /* _bcmenetphy_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetrxh.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,43 @@ ++/* ++ * Hardware-specific Receive Data Header for the ++ * Broadcom Home Networking Division ++ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenetrxh_h_ ++#define _bcmenetrxh_h_ ++ ++/* ++ * The Ethernet MAC core returns an 8-byte Receive Frame Data Header ++ * with every frame consisting of ++ * 16bits of frame length, followed by ++ * 16bits of EMAC rx descriptor info, followed by 32bits of undefined. ++ */ ++typedef volatile struct { ++ uint16 len; ++ uint16 flags; ++ uint16 pad[12]; ++} bcmenetrxh_t; ++ ++#define RXHDR_LEN 28 ++ ++#define RXF_L ((uint16)1 << 11) /* last buffer in a frame */ ++#define RXF_MISS ((uint16)1 << 7) /* received due to promisc mode */ ++#define RXF_BRDCAST ((uint16)1 << 6) /* dest is broadcast address */ ++#define RXF_MULT ((uint16)1 << 5) /* dest is multicast address */ ++#define RXF_LG ((uint16)1 << 4) /* frame length > rxmaxlength */ ++#define RXF_NO ((uint16)1 << 3) /* odd number of nibbles */ ++#define RXF_RXER ((uint16)1 << 2) /* receive symbol error */ ++#define RXF_CRC ((uint16)1 << 1) /* crc error */ ++#define RXF_OV ((uint16)1 << 0) /* fifo overflow */ ++ ++#endif /* _bcmenetrxh_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,141 @@ ++/* ++ * NVRAM variable manipulation ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmnvram_h_ ++#define _bcmnvram_h_ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++#include ++ ++struct nvram_header { ++ uint32 magic; ++ uint32 len; ++ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ ++ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ ++ uint32 config_ncdl; /* ncdl values for memc */ ++}; ++ ++struct nvram_tuple { ++ char *name; ++ char *value; ++ struct nvram_tuple *next; ++}; ++ ++/* ++ * Initialize NVRAM access. May be unnecessary or undefined on certain ++ * platforms. ++ */ ++extern int BCMINIT(nvram_init)(void *sbh); ++ ++/* ++ * Disable NVRAM access. May be unnecessary or undefined on certain ++ * platforms. ++ */ ++extern void BCMINIT(nvram_exit)(void *sbh); ++ ++/* ++ * Get the value of an NVRAM variable. The pointer returned may be ++ * invalid after a set. ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++extern char * BCMINIT(nvram_get)(const char *name); ++ ++/* ++ * Read the reset GPIO value from the nvram and set the GPIO ++ * as input ++ */ ++extern int BCMINITFN(nvram_resetgpio_init)(void *sbh); ++ ++/* ++ * Get the value of an NVRAM variable. ++ * @param name name of variable to get ++ * @return value of variable or NUL if undefined ++ */ ++#define nvram_safe_get(name) (BCMINIT(nvram_get)(name) ? : "") ++ ++/* ++ * Match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is string equal ++ * to match or FALSE otherwise ++ */ ++static INLINE int ++nvram_match(char *name, char *match) { ++ const char *value = BCMINIT(nvram_get)(name); ++ return (value && !strcmp(value, match)); ++} ++ ++/* ++ * Inversely match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is not string ++ * equal to invmatch or FALSE otherwise ++ */ ++static INLINE int ++nvram_invmatch(char *name, char *invmatch) { ++ const char *value = BCMINIT(nvram_get)(name); ++ return (value && strcmp(value, invmatch)); ++} ++ ++/* ++ * Set the value of an NVRAM variable. The name and value strings are ++ * copied into private storage. Pointers to previously set values ++ * may become invalid. The new value may be immediately ++ * retrieved but will not be permanently stored until a commit. ++ * @param name name of variable to set ++ * @param value value of variable ++ * @return 0 on success and errno on failure ++ */ ++extern int BCMINIT(nvram_set)(const char *name, const char *value); ++ ++/* ++ * Unset an NVRAM variable. Pointers to previously set values ++ * remain valid until a set. ++ * @param name name of variable to unset ++ * @return 0 on success and errno on failure ++ * NOTE: use nvram_commit to commit this change to flash. ++ */ ++extern int BCMINIT(nvram_unset)(const char *name); ++ ++/* ++ * Commit NVRAM variables to permanent storage. All pointers to values ++ * may be invalid after a commit. ++ * NVRAM values are undefined after a commit. ++ * @return 0 on success and errno on failure ++ */ ++extern int BCMINIT(nvram_commit)(void); ++ ++/* ++ * Get all NVRAM variables (format name=value\0 ... \0\0). ++ * @param buf buffer to store variables ++ * @param count size of buffer in bytes ++ * @return 0 on success and errno on failure ++ */ ++extern int BCMINIT(nvram_getall)(char *buf, int count); ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ ++#define NVRAM_VERSION 1 ++#define NVRAM_HEADER_SIZE 20 ++#define NVRAM_SPACE 0x8000 ++ ++#define NVRAM_MAX_VALUE_LEN 255 ++#define NVRAM_MAX_PARAM_LEN 64 ++ ++#endif /* _bcmnvram_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmparams.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmparams.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmparams.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmparams.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,25 @@ ++/* ++ * Misc system wide parameters. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _bcmparams_h_ ++#define _bcmparams_h_ ++ ++#define VLAN_MAXVID 15 /* Max. VLAN ID supported/allowed */ ++ ++#define VLAN_NUMPRIS 8 /* # of prio, start from 0 */ ++ ++#define DEV_NUMIFS 16 /* Max. # of devices/interfaces supported */ ++ ++#define WL_MAXBSSCFG 16 /* maximum number of BSS Configs we can configure */ ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,23 @@ ++/* ++ * Misc useful routines to access NIC local SROM/OTP . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmsrom_h_ ++#define _bcmsrom_h_ ++ ++extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, int *count); ++ ++extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++ ++#endif /* _bcmsrom_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,313 @@ ++/* ++ * Misc useful os-independent macros and functions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _bcmutils_h_ ++#define _bcmutils_h_ ++ ++/*** driver-only section ***/ ++#ifdef BCMDRIVER ++#include ++ ++#define _BCM_U 0x01 /* upper */ ++#define _BCM_L 0x02 /* lower */ ++#define _BCM_D 0x04 /* digit */ ++#define _BCM_C 0x08 /* cntrl */ ++#define _BCM_P 0x10 /* punct */ ++#define _BCM_S 0x20 /* white space (space/lf/tab) */ ++#define _BCM_X 0x40 /* hex digit */ ++#define _BCM_SP 0x80 /* hard space (0x20) */ ++ ++#define GPIO_PIN_NOTDEFINED 0x20 ++ ++extern unsigned char bcm_ctype[]; ++#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) ++ ++#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) ++#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) ++#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) ++#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) ++#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) ++#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) ++#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) ++#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) ++#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) ++ ++/* ++ * Spin at most 'us' microseconds while 'exp' is true. ++ * Caller should explicitly test 'exp' when this completes ++ * and take appropriate error action if 'exp' is still true. ++ */ ++#define SPINWAIT(exp, us) { \ ++ uint countdown = (us) + 9; \ ++ while ((exp) && (countdown >= 10)) {\ ++ OSL_DELAY(10); \ ++ countdown -= 10; \ ++ } \ ++} ++ ++/* generic osl packet queue */ ++struct pktq { ++ void *head; /* first packet to dequeue */ ++ void *tail; /* last packet to dequeue */ ++ uint len; /* number of queued packets */ ++ uint maxlen; /* maximum number of queued packets */ ++ bool priority; /* enqueue by packet priority */ ++ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */ ++}; ++#define DEFAULT_QLEN 128 ++ ++#define pktq_len(q) ((q)->len) ++#define pktq_avail(q) ((q)->maxlen - (q)->len) ++#define pktq_head(q) ((q)->head) ++#define pktq_full(q) ((q)->len >= (q)->maxlen) ++#define _pktq_pri(q, pri) ((q)->prio_map[pri]) ++#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0)) ++ ++/* externs */ ++/* packet */ ++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pkttotlen(osl_t *osh, void *); ++extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]); ++extern void pktenq(struct pktq *q, void *p, bool lifo); ++extern void *pktdeq(struct pktq *q); ++extern void *pktdeqtail(struct pktq *q); ++/* string */ ++extern uint bcm_atoi(char *s); ++extern uchar bcm_toupper(uchar c); ++extern ulong bcm_strtoul(char *cp, char **endp, uint base); ++extern char *bcmstrstr(char *haystack, char *needle); ++extern char *bcmstrcat(char *dest, const char *src); ++extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); ++/* ethernet address */ ++extern char *bcm_ether_ntoa(char *ea, char *buf); ++extern int bcm_ether_atoe(char *p, char *ea); ++/* delay */ ++extern void bcm_mdelay(uint ms); ++/* variable access */ ++extern char *getvar(char *vars, char *name); ++extern int getintvar(char *vars, char *name); ++extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); ++#define bcmlog(fmt, a1, a2) ++#define bcmdumplog(buf, size) *buf = '\0' ++#define bcmdumplogent(buf, idx) -1 ++ ++#endif /* #ifdef BCMDRIVER */ ++ ++/*** driver/apps-shared section ***/ ++ ++#define BCME_STRLEN 64 ++#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) ++ ++ ++/* ++ * error codes could be added but the defined ones shouldn't be changed/deleted ++ * these error codes are exposed to the user code ++ * when ever a new error code is added to this list ++ * please update errorstring table with the related error string and ++ * update osl files with os specific errorcode map ++*/ ++ ++#define BCME_ERROR -1 /* Error generic */ ++#define BCME_BADARG -2 /* Bad Argument */ ++#define BCME_BADOPTION -3 /* Bad option */ ++#define BCME_NOTUP -4 /* Not up */ ++#define BCME_NOTDOWN -5 /* Not down */ ++#define BCME_NOTAP -6 /* Not AP */ ++#define BCME_NOTSTA -7 /* Not STA */ ++#define BCME_BADKEYIDX -8 /* BAD Key Index */ ++#define BCME_RADIOOFF -9 /* Radio Off */ ++#define BCME_NOTBANDLOCKED -10 /* Not bandlocked */ ++#define BCME_NOCLK -11 /* No Clock*/ ++#define BCME_BADRATESET -12 /* BAD RateSet*/ ++#define BCME_BADBAND -13 /* BAD Band */ ++#define BCME_BUFTOOSHORT -14 /* Buffer too short */ ++#define BCME_BUFTOOLONG -15 /* Buffer too Long */ ++#define BCME_BUSY -16 /* Busy*/ ++#define BCME_NOTASSOCIATED -17 /* Not associated*/ ++#define BCME_BADSSIDLEN -18 /* BAD SSID Len */ ++#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel*/ ++#define BCME_BADCHAN -20 /* BAD Channel */ ++#define BCME_BADADDR -21 /* BAD Address*/ ++#define BCME_NORESOURCE -22 /* No resources*/ ++#define BCME_UNSUPPORTED -23 /* Unsupported*/ ++#define BCME_BADLEN -24 /* Bad Length*/ ++#define BCME_NOTREADY -25 /* Not ready Yet*/ ++#define BCME_EPERM -26 /* Not Permitted */ ++#define BCME_NOMEM -27 /* No Memory */ ++#define BCME_ASSOCIATED -28 /* Associated */ ++#define BCME_RANGE -29 /* Range Error*/ ++#define BCME_NOTFOUND -30 /* Not found */ ++#define BCME_LAST BCME_NOTFOUND ++ ++#ifndef ABS ++#define ABS(a) (((a)<0)?-(a):(a)) ++#endif ++ ++#ifndef MIN ++#define MIN(a, b) (((a)<(b))?(a):(b)) ++#endif ++ ++#ifndef MAX ++#define MAX(a, b) (((a)>(b))?(a):(b)) ++#endif ++ ++#define CEIL(x, y) (((x) + ((y)-1)) / (y)) ++#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) ++#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) ++#define ISPOWEROF2(x) ((((x)-1)&(x))==0) ++#define VALID_MASK(mask) !((mask) & ((mask) + 1)) ++#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) ++#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) ++ ++/* bit map related macros */ ++#ifndef setbit ++#define NBBY 8 /* 8 bits per byte */ ++#define setbit(a,i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) ++#define clrbit(a,i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) ++#define isset(a,i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) ++#define isclr(a,i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) ++#endif ++ ++#define NBITS(type) (sizeof(type) * 8) ++#define NBITVAL(bits) (1 << (bits)) ++#define MAXBITVAL(bits) ((1 << (bits)) - 1) ++ ++/* crc defines */ ++#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ ++#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ ++#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ ++#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ ++#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++ ++/* bcm_format_flags() bit description structure */ ++typedef struct bcm_bit_desc { ++ uint32 bit; ++ char* name; ++} bcm_bit_desc_t; ++ ++/* tag_ID/length/value_buffer tuple */ ++typedef struct bcm_tlv { ++ uint8 id; ++ uint8 len; ++ uint8 data[1]; ++} bcm_tlv_t; ++ ++/* Check that bcm_tlv_t fits into the given buflen */ ++#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) ++ ++/* buffer length for ethernet address from bcm_ether_ntoa() */ ++#define ETHER_ADDR_STR_LEN 18 ++ ++/* unaligned load and store macros */ ++#ifdef IL_BIGENDIAN ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); ++} ++ ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[0] = (v >> 24) & 0xff; ++ a[1] = (v >> 16) & 0xff; ++ a[2] = (v >> 8) & 0xff; ++ a[3] = v & 0xff; ++} ++ ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[0] << 8) | a[1]); ++} ++ ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[0] = (v >> 8) & 0xff; ++ a[1] = v & 0xff; ++} ++ ++#else ++ ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); ++} ++ ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[3] = (v >> 24) & 0xff; ++ a[2] = (v >> 16) & 0xff; ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} ++ ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[1] << 8) | a[0]); ++} ++ ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} ++ ++#endif ++ ++/* externs */ ++/* crc */ ++extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); ++extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); ++extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); ++/* format/print */ ++/* IE parsing */ ++extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); ++extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); ++extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); ++ ++/* bcmerror*/ ++extern const char *bcmerrorstr(int bcmerror); ++ ++/* multi-bool data type: set of bools, mbool is true if any is set */ ++typedef uint32 mbool; ++#define mboolset(mb, bit) (mb |= bit) /* set one bool */ ++#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */ ++#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */ ++#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) ++ ++/* power conversion */ ++extern uint16 bcm_qdbm_to_mw(uint8 qdbm); ++extern uint8 bcm_mw_to_qdbm(uint16 mw); ++ ++/* generic datastruct to help dump routines */ ++struct fielddesc { ++ char *nameandfmt; ++ uint32 offset; ++ uint32 len; ++}; ++ ++typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset); ++extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str, char *buf, uint32 bufsize); ++ ++extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); ++ ++#endif /* _bcmutils_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bitfuncs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bitfuncs.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bitfuncs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bitfuncs.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,85 @@ ++/* ++ * bit manipulation utility functions ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _BITFUNCS_H ++#define _BITFUNCS_H ++ ++#include ++ ++/* local prototypes */ ++static INLINE uint32 find_msbit(uint32 x); ++ ++ ++/* ++ * find_msbit: returns index of most significant set bit in x, with index ++ * range defined as 0-31. NOTE: returns zero if input is zero. ++ */ ++ ++#if defined(USE_PENTIUM_BSR) && defined(__GNUC__) ++ ++/* ++ * Implementation for Pentium processors and gcc. Note that this ++ * instruction is actually very slow on some processors (e.g., family 5, ++ * model 2, stepping 12, "Pentium 75 - 200"), so we use the generic ++ * implementation instead. ++ */ ++static INLINE uint32 find_msbit(uint32 x) ++{ ++ uint msbit; ++ __asm__("bsrl %1,%0" ++ :"=r" (msbit) ++ :"r" (x)); ++ return msbit; ++} ++ ++#else ++ ++/* ++ * Generic Implementation ++ */ ++ ++#define DB_POW_MASK16 0xffff0000 ++#define DB_POW_MASK8 0x0000ff00 ++#define DB_POW_MASK4 0x000000f0 ++#define DB_POW_MASK2 0x0000000c ++#define DB_POW_MASK1 0x00000002 ++ ++static INLINE uint32 find_msbit(uint32 x) ++{ ++ uint32 temp_x = x; ++ uint msbit = 0; ++ if (temp_x & DB_POW_MASK16) { ++ temp_x >>= 16; ++ msbit = 16; ++ } ++ if (temp_x & DB_POW_MASK8) { ++ temp_x >>= 8; ++ msbit += 8; ++ } ++ if (temp_x & DB_POW_MASK4) { ++ temp_x >>= 4; ++ msbit += 4; ++ } ++ if (temp_x & DB_POW_MASK2) { ++ temp_x >>= 2; ++ msbit += 2; ++ } ++ if (temp_x & DB_POW_MASK1) { ++ msbit += 1; ++ } ++ return(msbit); ++} ++ ++#endif ++ ++#endif /* _BITFUNCS_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/cfe_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/cfe_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/cfe_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/cfe_osl.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,191 @@ ++/* ++ * CFE boot loader OS Abstraction Layer. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _cfe_osl_h_ ++#define _cfe_osl_h_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* dump string */ ++extern int (*xprinthook)(const char *str); ++#define puts(str) do { if (xprinthook) xprinthook(str); } while (0) ++ ++/* assert and panic */ ++#define ASSERT(exp) do {} while (0) ++ ++/* PCMCIA attribute space access macros */ ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ ++ bzero(buf, size) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ ++ do {} while (0) ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(loc, offset, size) \ ++ (offset == 8 ? 0 : 0xffffffff) ++#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \ ++ do {} while (0) ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) (0) ++#define OSL_PCI_SLOT(osh) (0) ++ ++/* register access macros */ ++#define wreg32(r, v) (*(volatile uint32*)(r) = (uint32)(v)) ++#define rreg32(r) (*(volatile uint32*)(r)) ++#ifdef IL_BIGENDIAN ++#define wreg16(r, v) (*(volatile uint16*)((ulong)(r)^2) = (uint16)(v)) ++#define rreg16(r) (*(volatile uint16*)((ulong)(r)^2)) ++#define wreg8(r, v) (*(volatile uint8*)((ulong)(r)^3) = (uint8)(v)) ++#define rreg8(r) (*(volatile uint8*)((ulong)(r)^3)) ++#else ++#define wreg16(r, v) (*(volatile uint16*)(r) = (uint16)(v)) ++#define rreg16(r) (*(volatile uint16*)(r)) ++#define wreg8(r, v) (*(volatile uint8*)(r) = (uint8)(v)) ++#define rreg8(r) (*(volatile uint8*)(r)) ++#endif ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = rreg8((r)); break; \ ++ case sizeof(uint16): __osl_v = rreg16((r)); break; \ ++ case sizeof(uint32): __osl_v = rreg32((r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): wreg8((r), (v)); break; \ ++ case sizeof(uint16): wreg16((r), (v)); break; \ ++ case sizeof(uint32): wreg32((r), (v)); break; \ ++ } \ ++} while (0) ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++/* bcopy, bcmp, and bzero */ ++#define bcmp(b1, b2, len) lib_memcmp((b1), (b2), (len)) ++ ++#define osl_attach(pdev) ((osl_t*)pdev) ++#define osl_detach(osh) ++ ++/* general purpose memory allocation */ ++#define MALLOC(osh, size) KMALLOC((size),0) ++#define MFREE(osh, addr, size) KFREE((addr)) ++#define MALLOCED(osh) (0) ++#define MALLOC_DUMP(osh, buf, sz) ++#define MALLOC_FAILED(osh) (0) ++ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) ((void*)UNCADDR((ulong)(va))) ++ ++/* host/bus architecture-specific address byte swap */ ++#define BUS_SWAP32(v) (v) ++ ++/* get processor cycle count */ ++#define OSL_GETCYCLES(x) ((x) = 0) ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) cfe_usleep((cfe_cpu_speed/CPUCFG_CYCLESPERCPUTICK/1000000*(usec))) ++ ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ((void*)UNCADDR((ulong)(pa))) ++#define REG_UNMAP(va) do {} while (0) ++ ++/* dereference an address that may cause a bus exception */ ++#define BUSPROBE(val, addr) osl_busprobe(&(val), (uint32)(addr)) ++extern int osl_busprobe(uint32 *val, uint32 addr); ++ ++/* allocate/free shared (dma-able) consistent (uncached) memory */ ++#define DMA_CONSISTENT_ALIGN 4096 ++#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ ++ osl_dma_alloc_consistent((size), (pap)) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ ++ osl_dma_free_consistent((void*)(va)) ++extern void *osl_dma_alloc_consistent(uint size, ulong *pap); ++extern void osl_dma_free_consistent(void *va); ++ ++/* map/unmap direction */ ++#define DMA_TX 1 ++#define DMA_RX 2 ++ ++/* map/unmap shared (dma-able) memory */ ++#define DMA_MAP(osh, va, size, direction, lb) ({ \ ++ cfe_flushcache(CFE_CACHE_FLUSH_D); \ ++ PHYSADDR((ulong)(va)); \ ++}) ++#define DMA_UNMAP(osh, pa, size, direction, p) \ ++ do {} while (0) ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) lib_memset((r), '\0', (len)) ++ ++/* generic packet structure */ ++#define LBUFSZ 4096 ++#define LBDATASZ (LBUFSZ - sizeof(struct lbuf)) ++struct lbuf { ++ struct lbuf *next; /* pointer to next lbuf if in a chain */ ++ struct lbuf *link; /* pointer to next lbuf if in a list */ ++ uchar *head; /* start of buffer */ ++ uchar *end; /* end of buffer */ ++ uchar *data; /* start of data */ ++ uchar *tail; /* end of data */ ++ uint len; /* nbytes of data */ ++ void *cookie; /* generic cookie */ ++}; ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) ((void*)osl_pktget((len))) ++#define PKTFREE(osh, lb, send) osl_pktfree((struct lbuf*)(lb)) ++#define PKTDATA(osh, lb) (((struct lbuf*)(lb))->data) ++#define PKTLEN(osh, lb) (((struct lbuf*)(lb))->len) ++#define PKTHEADROOM(osh, lb) (PKTDATA(osh,lb)-(((struct lbuf*)(lb))->head)) ++#define PKTTAILROOM(osh, lb) ((((struct lbuf*)(lb))->end)-(((struct lbuf*)(lb))->tail)) ++#define PKTNEXT(osh, lb) (((struct lbuf*)(lb))->next) ++#define PKTSETNEXT(lb, x) (((struct lbuf*)(lb))->next = (struct lbuf*)(x)) ++#define PKTSETLEN(osh, lb, len) osl_pktsetlen((struct lbuf*)(lb), (len)) ++#define PKTPUSH(osh, lb, bytes) osl_pktpush((struct lbuf*)(lb), (bytes)) ++#define PKTPULL(osh, lb, bytes) osl_pktpull((struct lbuf*)(lb), (bytes)) ++#define PKTDUP(osh, lb) osl_pktdup((struct lbuf*)(lb)) ++#define PKTCOOKIE(lb) (((struct lbuf*)(lb))->cookie) ++#define PKTSETCOOKIE(lb, x) (((struct lbuf*)(lb))->cookie = (void*)(x)) ++#define PKTLINK(lb) (((struct lbuf*)(lb))->link) ++#define PKTSETLINK(lb, x) (((struct lbuf*)(lb))->link = (struct lbuf*)(x)) ++#define PKTPRIO(lb) (0) ++#define PKTSETPRIO(lb, x) do {} while (0) ++extern struct lbuf *osl_pktget(uint len); ++extern void osl_pktfree(struct lbuf *lb); ++extern void osl_pktsetlen(struct lbuf *lb, uint len); ++extern uchar *osl_pktpush(struct lbuf *lb, uint bytes); ++extern uchar *osl_pktpull(struct lbuf *lb, uint bytes); ++extern struct lbuf *osl_pktdup(struct lbuf *lb); ++extern int osl_error(int bcmerror); ++ ++#endif /* _cfe_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/epivers.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h +--- linux-2.4.32/arch/mips/bcm947xx/include/epivers.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,69 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ * ++*/ ++ ++#ifndef _epivers_h_ ++#define _epivers_h_ ++ ++#ifdef linux ++#include ++#endif ++ ++/* Vendor Name, ASCII, 32 chars max */ ++#ifdef COMPANYNAME ++#define HPNA_VENDOR COMPANYNAME ++#else ++#define HPNA_VENDOR "Broadcom Corporation" ++#endif ++ ++/* Driver Date, ASCII, 32 chars max */ ++#define HPNA_DRV_BUILD_DATE __DATE__ ++ ++/* Hardware Manufacture Date, ASCII, 32 chars max */ ++#define HPNA_HW_MFG_DATE "Not Specified" ++ ++/* See documentation for Device Type values, 32 values max */ ++#ifndef HPNA_DEV_TYPE ++ ++#if defined(CONFIG_BRCM_VJ) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY } ++ ++#elif defined(CONFIG_BCRM_93725) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY } ++ ++#else ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC } ++ ++#endif ++ ++#endif /* !HPNA_DEV_TYPE */ ++ ++ ++#define EPI_MAJOR_VERSION 3 ++ ++#define EPI_MINOR_VERSION 130 ++ ++#define EPI_RC_NUMBER 20 ++ ++#define EPI_INCREMENTAL_NUMBER 0 ++ ++#define EPI_BUILD_NUMBER 0 ++ ++#define EPI_VERSION 3,130,20,0 ++ ++#define EPI_VERSION_NUM 0x03821400 ++ ++/* Driver Version String, ASCII, 32 chars max */ ++#define EPI_VERSION_STR "3.130.20.0" ++#define EPI_ROUTER_VERSION_STR "3.131.20.0" ++ ++#endif /* _epivers_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/epivers.h.in linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h.in +--- linux-2.4.32/arch/mips/bcm947xx/include/epivers.h.in 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h.in 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,69 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ * ++*/ ++ ++#ifndef _epivers_h_ ++#define _epivers_h_ ++ ++#ifdef linux ++#include ++#endif ++ ++/* Vendor Name, ASCII, 32 chars max */ ++#ifdef COMPANYNAME ++#define HPNA_VENDOR COMPANYNAME ++#else ++#define HPNA_VENDOR "Broadcom Corporation" ++#endif ++ ++/* Driver Date, ASCII, 32 chars max */ ++#define HPNA_DRV_BUILD_DATE __DATE__ ++ ++/* Hardware Manufacture Date, ASCII, 32 chars max */ ++#define HPNA_HW_MFG_DATE "Not Specified" ++ ++/* See documentation for Device Type values, 32 values max */ ++#ifndef HPNA_DEV_TYPE ++ ++#if defined(CONFIG_BRCM_VJ) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY } ++ ++#elif defined(CONFIG_BCRM_93725) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY } ++ ++#else ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC } ++ ++#endif ++ ++#endif /* !HPNA_DEV_TYPE */ ++ ++ ++#define EPI_MAJOR_VERSION @EPI_MAJOR_VERSION@ ++ ++#define EPI_MINOR_VERSION @EPI_MINOR_VERSION@ ++ ++#define EPI_RC_NUMBER @EPI_RC_NUMBER@ ++ ++#define EPI_INCREMENTAL_NUMBER @EPI_INCREMENTAL_NUMBER@ ++ ++#define EPI_BUILD_NUMBER @EPI_BUILD_NUMBER@ ++ ++#define EPI_VERSION @EPI_VERSION@ ++ ++#define EPI_VERSION_NUM @EPI_VERSION_NUM@ ++ ++/* Driver Version String, ASCII, 32 chars max */ ++#define EPI_VERSION_STR "@EPI_VERSION_STR@" ++#define EPI_ROUTER_VERSION_STR "@EPI_ROUTER_VERSION_STR@" ++ ++#endif /* _epivers_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/etsockio.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/etsockio.h +--- linux-2.4.32/arch/mips/bcm947xx/include/etsockio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/etsockio.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,59 @@ ++/* ++ * Driver-specific socket ioctls ++ * used by BSD, Linux, and PSOS ++ * Broadcom BCM44XX 10/100Mbps Ethernet Device Driver ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _etsockio_h_ ++#define _etsockio_h_ ++ ++/* THESE MUST BE CONTIGUOUS AND CONSISTENT WITH VALUES IN ETC.H */ ++ ++ ++#if defined(linux) ++#define SIOCSETCUP (SIOCDEVPRIVATE + 0) ++#define SIOCSETCDOWN (SIOCDEVPRIVATE + 1) ++#define SIOCSETCLOOP (SIOCDEVPRIVATE + 2) ++#define SIOCGETCDUMP (SIOCDEVPRIVATE + 3) ++#define SIOCSETCSETMSGLEVEL (SIOCDEVPRIVATE + 4) ++#define SIOCSETCPROMISC (SIOCDEVPRIVATE + 5) ++#define SIOCSETCTXDOWN (SIOCDEVPRIVATE + 6) /* obsolete */ ++#define SIOCSETCSPEED (SIOCDEVPRIVATE + 7) ++#define SIOCTXGEN (SIOCDEVPRIVATE + 8) ++#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9) ++#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10) ++#define SIOCSETCQOS (SIOCDEVPRIVATE + 11) ++ ++#else /* !linux */ ++ ++#define SIOCSETCUP _IOWR('e', 130 + 0, struct ifreq) ++#define SIOCSETCDOWN _IOWR('e', 130 + 1, struct ifreq) ++#define SIOCSETCLOOP _IOWR('e', 130 + 2, struct ifreq) ++#define SIOCGETCDUMP _IOWR('e', 130 + 3, struct ifreq) ++#define SIOCSETCSETMSGLEVEL _IOWR('e', 130 + 4, struct ifreq) ++#define SIOCSETCPROMISC _IOWR('e', 130 + 5, struct ifreq) ++#define SIOCSETCTXDOWN _IOWR('e', 130 + 6, struct ifreq) /* obsolete */ ++#define SIOCSETCSPEED _IOWR('e', 130 + 7, struct ifreq) ++#define SIOCTXGEN _IOWR('e', 130 + 8, struct ifreq) ++ ++#endif ++ ++/* arg to SIOCTXGEN */ ++struct txg { ++ uint32 num; /* number of frames to send */ ++ uint32 delay; /* delay in microseconds between sending each */ ++ uint32 size; /* size of ether frame to send */ ++ uchar buf[1514]; /* starting ether frame data */ ++}; ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/flash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/flash.h +--- linux-2.4.32/arch/mips/bcm947xx/include/flash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/flash.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,188 @@ ++/* ++ * flash.h: Common definitions for flash access. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++/* Types of flashes we know about */ ++typedef enum _flash_type {OLD, BSC, SCS, AMD, SST, SFLASH} flash_type_t; ++ ++/* Commands to write/erase the flases */ ++typedef struct _flash_cmds{ ++ flash_type_t type; ++ bool need_unlock; ++ uint16 pre_erase; ++ uint16 erase_block; ++ uint16 erase_chip; ++ uint16 write_word; ++ uint16 write_buf; ++ uint16 clear_csr; ++ uint16 read_csr; ++ uint16 read_id; ++ uint16 confirm; ++ uint16 read_array; ++} flash_cmds_t; ++ ++#define UNLOCK_CMD_WORDS 2 ++ ++typedef struct _unlock_cmd { ++ uint addr[UNLOCK_CMD_WORDS]; ++ uint16 cmd[UNLOCK_CMD_WORDS]; ++} unlock_cmd_t; ++ ++/* Flash descriptors */ ++typedef struct _flash_desc { ++ uint16 mfgid; /* Manufacturer Id */ ++ uint16 devid; /* Device Id */ ++ uint size; /* Total size in bytes */ ++ uint width; /* Device width in bytes */ ++ flash_type_t type; /* Device type old, S, J */ ++ uint bsize; /* Block size */ ++ uint nb; /* Number of blocks */ ++ uint ff; /* First full block */ ++ uint lf; /* Last full block */ ++ uint nsub; /* Number of subblocks */ ++ uint *subblocks; /* Offsets for subblocks */ ++ char *desc; /* Description */ ++} flash_desc_t; ++ ++ ++#ifdef DECLARE_FLASHES ++flash_cmds_t sflash_cmd_t = ++ { SFLASH, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ ++flash_cmds_t flash_cmds[] = { ++/* type needu preera eraseb erasech write wbuf clcsr rdcsr rdid confrm read */ ++ { BSC, 0, 0x00, 0x20, 0x00, 0x40, 0x00, 0x50, 0x70, 0x90, 0xd0, 0xff }, ++ { SCS, 0, 0x00, 0x20, 0x00, 0x40, 0xe8, 0x50, 0x70, 0x90, 0xd0, 0xff }, ++ { AMD, 1, 0x80, 0x30, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, ++ { SST, 1, 0x80, 0x50, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, ++ { 0 } ++}; ++ ++unlock_cmd_t unlock_cmd_amd = { ++#ifdef MIPSEB ++/* addr: */ { 0x0aa8, 0x0556}, ++#else ++/* addr: */ { 0x0aaa, 0x0554}, ++#endif ++/* data: */ { 0xaa, 0x55} ++}; ++ ++unlock_cmd_t unlock_cmd_sst = { ++#ifdef MIPSEB ++/* addr: */ { 0xaaa8, 0x5556}, ++#else ++/* addr: */ { 0xaaaa, 0x5554}, ++#endif ++/* data: */ { 0xaa, 0x55} ++}; ++ ++#define AMD_CMD 0xaaa ++#define SST_CMD 0xaaaa ++ ++/* intel unlock block cmds */ ++#define INTEL_UNLOCK1 0x60 ++#define INTEL_UNLOCK2 0xD0 ++ ++/* Just eight blocks of 8KB byte each */ ++ ++uint blk8x8k[] = { 0x00000000, ++ 0x00002000, ++ 0x00004000, ++ 0x00006000, ++ 0x00008000, ++ 0x0000a000, ++ 0x0000c000, ++ 0x0000e000, ++ 0x00010000 ++}; ++ ++/* Funky AMD arrangement for 29xx800's */ ++uint amd800[] = { 0x00000000, /* 16KB */ ++ 0x00004000, /* 32KB */ ++ 0x0000c000, /* 8KB */ ++ 0x0000e000, /* 8KB */ ++ 0x00010000, /* 8KB */ ++ 0x00012000, /* 8KB */ ++ 0x00014000, /* 32KB */ ++ 0x0001c000, /* 16KB */ ++ 0x00020000 ++}; ++ ++/* AMD arrangement for 29xx160's */ ++uint amd4112[] = { 0x00000000, /* 32KB */ ++ 0x00008000, /* 8KB */ ++ 0x0000a000, /* 8KB */ ++ 0x0000c000, /* 16KB */ ++ 0x00010000 ++}; ++uint amd2114[] = { 0x00000000, /* 16KB */ ++ 0x00004000, /* 8KB */ ++ 0x00006000, /* 8KB */ ++ 0x00008000, /* 32KB */ ++ 0x00010000 ++}; ++ ++ ++flash_desc_t sflash_desc = ++ { 0, 0, 0, 0, SFLASH, 0, 0, 0, 0, 0, NULL, "SFLASH" }; ++ ++flash_desc_t flashes[] = { ++ { 0x00b0, 0x00d0, 0x0200000, 2, SCS, 0x10000, 32, 0, 31, 0, NULL, "Intel 28F160S3/5 1Mx16" }, ++ { 0x00b0, 0x00d4, 0x0400000, 2, SCS, 0x10000, 64, 0, 63, 0, NULL, "Intel 28F320S3/5 2Mx16" }, ++ { 0x0089, 0x8890, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160B3 1Mx16 TopB" }, ++ { 0x0089, 0x8891, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160B3 1Mx16 BotB" }, ++ { 0x0089, 0x8896, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320B3 2Mx16 TopB" }, ++ { 0x0089, 0x8897, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320B3 2Mx16 BotB" }, ++ { 0x0089, 0x8898, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640B3 4Mx16 TopB" }, ++ { 0x0089, 0x8899, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640B3 4Mx16 BotB" }, ++ { 0x0089, 0x88C2, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160C3 1Mx16 TopB" }, ++ { 0x0089, 0x88C3, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160C3 1Mx16 BotB" }, ++ { 0x0089, 0x88C4, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320C3 2Mx16 TopB" }, ++ { 0x0089, 0x88C5, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320C3 2Mx16 BotB" }, ++ { 0x0089, 0x88CC, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640C3 4Mx16 TopB" }, ++ { 0x0089, 0x88CD, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640C3 4Mx16 BotB" }, ++ { 0x0089, 0x0014, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J5 2Mx16" }, ++ { 0x0089, 0x0015, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J5 4Mx16" }, ++ { 0x0089, 0x0016, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J3 2Mx16" }, ++ { 0x0089, 0x0017, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J3 4Mx16" }, ++ { 0x0089, 0x0018, 0x1000000, 2, SCS, 0x20000, 128, 0, 127, 0, NULL, "Intel 28F128J3 8Mx16" }, ++ { 0x00b0, 0x00e3, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Sharp 28F320BJE 2Mx16 BotB" }, ++ { 0x0001, 0x224a, 0x0100000, 2, AMD, 0x10000, 16, 0, 13, 8, amd800, "AMD 29DL800BT 512Kx16 TopB" }, ++ { 0x0001, 0x22cb, 0x0100000, 2, AMD, 0x10000, 16, 2, 15, 8, amd800, "AMD 29DL800BB 512Kx16 BotB" }, ++ { 0x0001, 0x22c4, 0x0200000, 2, AMD, 0x10000, 32, 0, 30, 4, amd2114, "AMD 29lv160DT 1Mx16 TopB" }, ++ { 0x0001, 0x2249, 0x0200000, 2, AMD, 0x10000, 32, 1, 31, 4, amd4112, "AMD 29lv160DB 1Mx16 BotB" }, ++ { 0x0001, 0x22f6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320DT 2Mx16 TopB" }, ++ { 0x0001, 0x22f9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320DB 2Mx16 BotB" }, ++ { 0x0001, 0x227e, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" }, ++ { 0x0001, 0x2200, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320MB 2Mx16 BotB" }, ++ { 0x0020, 0x22CA, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "ST 29w320DT 2Mx16 TopB" }, ++ { 0x0020, 0x22CB, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "ST 29w320DB 2Mx16 BotB" }, ++ { 0x00C2, 0x00A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, ++ { 0x00C2, 0x00A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, ++ { 0x0004, 0x22F6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MBM29LV320TE 2Mx16 TopB" }, ++ { 0x0004, 0x22F9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MBM29LV320BE 2Mx16 BotB" }, ++ { 0x0098, 0x009A, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "TC58FVT321 2Mx16 TopB" }, ++ { 0x0098, 0x009C, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "TC58FVB321 2Mx16 BotB" }, ++ { 0x00C2, 0x22A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, ++ { 0x00C2, 0x22A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, ++ { 0x00BF, 0x2783, 0x0400000, 2, SST, 0x10000, 64, 0, 63, 0, NULL, "SST39VF320 2Mx16" }, ++ { 0, 0, 0, 0, OLD, 0, 0, 0, 0, 0, NULL, NULL }, ++}; ++ ++#else ++ ++extern flash_cmds_t flash_cmds[]; ++extern unlock_cmd_t unlock_cmd; ++extern flash_desc_t flashes[]; ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/flashutl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/flashutl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/flashutl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/flashutl.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,27 @@ ++/* ++ * BCM47XX FLASH driver interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _flashutl_h_ ++#define _flashutl_h_ ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++int sysFlashInit(char *flash_str); ++int sysFlashRead(uint off, uchar *dst, uint bytes); ++int sysFlashWrite(uint off, uchar *src, uint bytes); ++void nvWrite(unsigned short *data, unsigned int len); ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _flashutl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h +--- linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,71 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _hnddma_h_ ++#define _hnddma_h_ ++ ++/* export structure */ ++typedef volatile struct { ++ /* rx error counters */ ++ uint rxgiants; /* rx giant frames */ ++ uint rxnobuf; /* rx out of dma descriptors */ ++ /* tx error counters */ ++ uint txnobuf; /* tx out of dma descriptors */ ++} hnddma_t; ++ ++#ifndef di_t ++#define di_t void ++#endif ++ ++#ifndef osl_t ++#define osl_t void ++#endif ++ ++/* externs */ ++extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level); ++extern void dma_detach(di_t *di); ++extern void dma_txreset(di_t *di); ++extern void dma_rxreset(di_t *di); ++extern void dma_txinit(di_t *di); ++extern bool dma_txenabled(di_t *di); ++extern void dma_rxinit(di_t *di); ++extern void dma_rxenable(di_t *di); ++extern bool dma_rxenabled(di_t *di); ++extern void dma_txsuspend(di_t *di); ++extern void dma_txresume(di_t *di); ++extern bool dma_txsuspended(di_t *di); ++extern bool dma_txsuspendedidle(di_t *di); ++extern bool dma_txstopped(di_t *di); ++extern bool dma_rxstopped(di_t *di); ++extern int dma_txfast(di_t *di, void *p, uint32 coreflags); ++extern void dma_fifoloopbackenable(di_t *di); ++extern void *dma_rx(di_t *di); ++extern void dma_rxfill(di_t *di); ++extern void dma_txreclaim(di_t *di, bool forceall); ++extern void dma_rxreclaim(di_t *di); ++extern uintptr dma_getvar(di_t *di, char *name); ++extern void *dma_getnexttxp(di_t *di, bool forceall); ++extern void *dma_peeknexttxp(di_t *di); ++extern void *dma_getnextrxp(di_t *di, bool forceall); ++extern void dma_txblock(di_t *di); ++extern void dma_txunblock(di_t *di); ++extern uint dma_txactive(di_t *di); ++extern void dma_txrotate(di_t *di); ++ ++extern void dma_rxpiomode(dma32regs_t *); ++extern void dma_txpioloopback(dma32regs_t *); ++ ++ ++#endif /* _hnddma_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h +--- linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,16 @@ ++/* ++ * Alternate include file for HND sbmips.h since CFE also ships with ++ * a sbmips.h. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include "sbmips.h" +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,371 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _linux_osl_h_ ++#define _linux_osl_h_ ++ ++#include ++ ++/* use current 2.4.x calling conventions */ ++#include ++ ++/* assert and panic */ ++#ifdef __GNUC__ ++#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) ++#if GCC_VERSION > 30100 ++#define ASSERT(exp) do {} while (0) ++#else ++/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/ ++#define ASSERT(exp) ++#endif ++#endif ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) osl_delay(usec) ++extern void osl_delay(uint usec); ++ ++/* PCMCIA attribute space access macros */ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++struct pcmcia_dev { ++ dev_link_t link; /* PCMCIA device pointer */ ++ dev_node_t node; /* PCMCIA node structure */ ++ void *base; /* Mapped attribute memory window */ ++ size_t size; /* Size of window */ ++ void *drv; /* Driver data */ ++}; ++#endif ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ ++ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ ++ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) ++extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); ++extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(osh, offset, size) \ ++ osl_pci_read_config((osh), (offset), (size)) ++#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ ++ osl_pci_write_config((osh), (offset), (size), (val)) ++extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset); ++extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) osl_pci_bus(osh) ++#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) ++extern uint osl_pci_bus(osl_t *osh); ++extern uint osl_pci_slot(osl_t *osh); ++ ++/* OSL initialization */ ++extern osl_t *osl_attach(void *pdev); ++extern void osl_detach(osl_t *osh); ++ ++/* host/bus architecture-specific byte swap */ ++#define BUS_SWAP32(v) (v) ++ ++/* general purpose memory allocation */ ++ ++#if defined(BCMDBG_MEM) ++ ++#define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__) ++#define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__) ++#define MALLOCED(osh) osl_malloced((osh)) ++#define MALLOC_DUMP(osh, buf, sz) osl_debug_memdump((osh), (buf), (sz)) ++extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file); ++extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file); ++extern char *osl_debug_memdump(osl_t *osh, char *buf, uint sz); ++ ++#else ++ ++#define MALLOC(osh, size) osl_malloc((osh), (size)) ++#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) ++#define MALLOCED(osh) osl_malloced((osh)) ++ ++#endif /* BCMDBG_MEM */ ++ ++#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) ++ ++extern void *osl_malloc(osl_t *osh, uint size); ++extern void osl_mfree(osl_t *osh, void *addr, uint size); ++extern uint osl_malloced(osl_t *osh); ++extern uint osl_malloc_failed(osl_t *osh); ++ ++/* allocate/free shared (dma-able) consistent memory */ ++#define DMA_CONSISTENT_ALIGN PAGE_SIZE ++#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ ++ osl_dma_alloc_consistent((osh), (size), (pap)) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ ++ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) ++extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); ++extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); ++ ++/* map/unmap direction */ ++#define DMA_TX 1 ++#define DMA_RX 2 ++ ++/* map/unmap shared (dma-able) memory */ ++#define DMA_MAP(osh, va, size, direction, p) \ ++ osl_dma_map((osh), (va), (size), (direction)) ++#define DMA_UNMAP(osh, pa, size, direction, p) \ ++ osl_dma_unmap((osh), (pa), (size), (direction)) ++extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); ++extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); ++ ++/* register access macros */ ++#if defined(BCMJTAG) ++#include ++#define R_REG(r) bcmjtag_read(NULL, (uint32)(r), sizeof (*(r))) ++#define W_REG(r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r))) ++#endif ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ * Macros expand to calls to functions defined in linux_osl.c . ++ */ ++#ifndef BINOSL ++ ++/* string library, kernel mode */ ++#define printf(fmt, args...) printk(fmt, ## args) ++#include ++#include ++ ++/* register access macros */ ++#if !defined(BCMJTAG) ++#ifndef IL_BIGENDIAN ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ ++ readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#else /* IL_BIGENDIAN */ ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif ++#endif ++ ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++/* bcopy, bcmp, and bzero */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++/* uncached virtual address */ ++#ifdef mips ++#define OSL_UNCACHED(va) KSEG1ADDR((va)) ++#include ++#else ++#define OSL_UNCACHED(va) (va) ++#endif ++ ++/* get processor cycle count */ ++#if defined(mips) ++#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) ++#elif defined(__i386__) ++#define OSL_GETCYCLES(x) rdtscl((x)) ++#else ++#define OSL_GETCYCLES(x) ((x) = 0) ++#endif ++ ++/* dereference an address that may cause a bus exception */ ++#ifdef mips ++#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17)) ++#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module") ++#else ++#define BUSPROBE(val, addr) get_dbe((val), (addr)) ++#include ++#endif ++#else ++#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; }) ++#endif ++ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) ++#define REG_UNMAP(va) iounmap((void *)(va)) ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset((r), '\0', (len)) ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) ++#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) ++#define PKTHEADROOM(osh, skb) (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head)) ++#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) ++#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) ++#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) ++#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) ++#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) ++#define PKTDUP(osh, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC) ++#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum) ++#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x)) ++#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) ++#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) ++#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) ++#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); ++ ++#else /* BINOSL */ ++ ++/* string library */ ++#ifndef LINUX_OSL ++#undef printf ++#define printf(fmt, args...) osl_printf((fmt), ## args) ++#undef sprintf ++#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args) ++#undef strcmp ++#define strcmp(s1, s2) osl_strcmp((s1), (s2)) ++#undef strncmp ++#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) ++#undef strlen ++#define strlen(s) osl_strlen((s)) ++#undef strcpy ++#define strcpy(d, s) osl_strcpy((d), (s)) ++#undef strncpy ++#define strncpy(d, s, n) osl_strncpy((d), (s), (n)) ++#endif ++extern int osl_printf(const char *format, ...); ++extern int osl_sprintf(char *buf, const char *format, ...); ++extern int osl_strcmp(const char *s1, const char *s2); ++extern int osl_strncmp(const char *s1, const char *s2, uint n); ++extern int osl_strlen(const char *s); ++extern char* osl_strcpy(char *d, const char *s); ++extern char* osl_strncpy(char *d, const char *s, uint n); ++ ++/* register access macros */ ++#if !defined(BCMJTAG) ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ ++ osl_readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif ++ ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++extern uint8 osl_readb(volatile uint8 *r); ++extern uint16 osl_readw(volatile uint16 *r); ++extern uint32 osl_readl(volatile uint32 *r); ++extern void osl_writeb(uint8 v, volatile uint8 *r); ++extern void osl_writew(uint16 v, volatile uint16 *r); ++extern void osl_writel(uint32 v, volatile uint32 *r); ++ ++/* bcopy, bcmp, and bzero */ ++extern void bcopy(const void *src, void *dst, int len); ++extern int bcmp(const void *b1, const void *b2, int len); ++extern void bzero(void *b, int len); ++ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) osl_uncached((va)) ++extern void *osl_uncached(void *va); ++ ++/* get processor cycle count */ ++#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) ++extern uint osl_getcycles(void); ++ ++/* dereference an address that may target abort */ ++#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) ++extern int osl_busprobe(uint32 *val, uint32 addr); ++ ++/* map/unmap physical to virtual */ ++#define REG_MAP(pa, size) osl_reg_map((pa), (size)) ++#define REG_UNMAP(va) osl_reg_unmap((va)) ++extern void *osl_reg_map(uint32 pa, uint size); ++extern void osl_reg_unmap(void *va); ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) bzero((r), (len)) ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) ++#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) ++#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) ++#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) ++#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) ++#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x)) ++#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) ++#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) ++#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) ++#define PKTCOOKIE(skb) osl_pktcookie((skb)) ++#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x)) ++#define PKTLINK(skb) osl_pktlink((skb)) ++#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) ++#define PKTPRIO(skb) osl_pktprio((skb)) ++#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); ++extern uchar *osl_pktdata(osl_t *osh, void *skb); ++extern uint osl_pktlen(osl_t *osh, void *skb); ++extern uint osl_pktheadroom(osl_t *osh, void *skb); ++extern uint osl_pkttailroom(osl_t *osh, void *skb); ++extern void *osl_pktnext(osl_t *osh, void *skb); ++extern void osl_pktsetnext(void *skb, void *x); ++extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); ++extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); ++extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); ++extern void *osl_pktdup(osl_t *osh, void *skb); ++extern void *osl_pktcookie(void *skb); ++extern void osl_pktsetcookie(void *skb, void *x); ++extern void *osl_pktlink(void *skb); ++extern void osl_pktsetlink(void *skb, void *x); ++extern uint osl_pktprio(void *skb); ++extern void osl_pktsetprio(void *skb, uint x); ++ ++#endif /* BINOSL */ ++ ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int bcmerror); ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++#endif /* _linux_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h +--- linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,411 @@ ++/* ++ * Linux-specific abstractions to gain some independence from linux kernel versions. ++ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _linuxver_h_ ++#define _linuxver_h_ ++ ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) ++/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ ++#ifdef __UNDEF_NO_VERSION__ ++#undef __NO_VERSION__ ++#else ++#define __NO_VERSION__ ++#endif ++#endif ++ ++#if defined(MODULE) && defined(MODVERSIONS) ++#include ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ++#include ++#endif ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ++#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") ++#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) ++#endif ++ ++/* linux/malloc.h is deprecated, use linux/slab.h instead. */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)) ++#include ++#else ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) ++#include ++#else ++#include ++#ifndef work_struct ++#define work_struct tq_struct ++#endif ++#ifndef INIT_WORK ++#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) ++#endif ++#ifndef schedule_work ++#define schedule_work(_work) schedule_task((_work)) ++#endif ++#ifndef flush_scheduled_work ++#define flush_scheduled_work() flush_scheduled_tasks() ++#endif ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* Some distributions have their own 2.6.x compatibility layers */ ++#ifndef IRQ_NONE ++typedef void irqreturn_t; ++#define IRQ_NONE ++#define IRQ_HANDLED ++#define IRQ_RETVAL(x) ++#endif ++#else ++typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); ++#endif ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)) ++/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which ++ * does this, but it's not in 2.4 so we do our own for now. */ ++static inline void ++cs_error(client_handle_t handle, int func, int ret) ++{ ++ error_info_t err = { func, ret }; ++ CardServices(ReportError, handle, &err); ++} ++#endif ++ ++#endif /* CONFIG_PCMCIA */ ++ ++#ifndef __exit ++#define __exit ++#endif ++#ifndef __devexit ++#define __devexit ++#endif ++#ifndef __devinit ++#define __devinit __init ++#endif ++#ifndef __devinitdata ++#define __devinitdata ++#endif ++#ifndef __devexit_p ++#define __devexit_p(x) x ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) ++ ++#define pci_get_drvdata(dev) (dev)->sysdata ++#define pci_set_drvdata(dev, value) (dev)->sysdata=(value) ++ ++/* ++ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration ++ */ ++ ++struct pci_device_id { ++ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ ++ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ ++ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ ++ unsigned long driver_data; /* Data private to the driver */ ++}; ++ ++struct pci_driver { ++ struct list_head node; ++ char *name; ++ const struct pci_device_id *id_table; /* NULL if wants all devices */ ++ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ ++ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ ++ void (*suspend)(struct pci_dev *dev); /* Device suspended */ ++ void (*resume)(struct pci_dev *dev); /* Device woken up */ ++}; ++ ++#define MODULE_DEVICE_TABLE(type, name) ++#define PCI_ANY_ID (~0) ++ ++/* compatpci.c */ ++#define pci_module_init pci_register_driver ++extern int pci_register_driver(struct pci_driver *drv); ++extern void pci_unregister_driver(struct pci_driver *drv); ++ ++#endif /* PCI registration */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) ++#ifdef MODULE ++#define module_init(x) int init_module(void) { return x(); } ++#define module_exit(x) void cleanup_module(void) { x(); } ++#else ++#define module_init(x) __initcall(x); ++#define module_exit(x) __exitcall(x); ++#endif ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)) ++#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44)) ++#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23)) ++#define pci_enable_device(dev) do { } while (0) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14)) ++#define net_device device ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)) ++ ++/* ++ * DMA mapping ++ * ++ * See linux/Documentation/DMA-mapping.txt ++ */ ++ ++#ifndef PCI_DMA_TODEVICE ++#define PCI_DMA_TODEVICE 1 ++#define PCI_DMA_FROMDEVICE 2 ++#endif ++ ++typedef u32 dma_addr_t; ++ ++/* Pure 2^n version of get_order */ ++static inline int get_order(unsigned long size) ++{ ++ int order; ++ ++ size = (size-1) >> (PAGE_SHIFT-1); ++ order = -1; ++ do { ++ size >>= 1; ++ order++; ++ } while (size); ++ return order; ++} ++ ++static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ++ dma_addr_t *dma_handle) ++{ ++ void *ret; ++ int gfp = GFP_ATOMIC | GFP_DMA; ++ ++ ret = (void *)__get_free_pages(gfp, get_order(size)); ++ ++ if (ret != NULL) { ++ memset(ret, 0, size); ++ *dma_handle = virt_to_bus(ret); ++ } ++ return ret; ++} ++static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, ++ void *vaddr, dma_addr_t dma_handle) ++{ ++ free_pages((unsigned long)vaddr, get_order(size)); ++} ++#ifdef ILSIM ++extern uint pci_map_single(void *dev, void *va, uint size, int direction); ++extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); ++#else ++#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) ++#define pci_unmap_single(cookie, address, size, dir) ++#endif ++ ++#endif /* DMA mapping */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) ++ ++#define dev_kfree_skb_any(a) dev_kfree_skb(a) ++#define netif_down(dev) do { (dev)->start = 0; } while(0) ++ ++/* pcmcia-cs provides its own netdevice compatibility layer */ ++#ifndef _COMPAT_NETDEVICE_H ++ ++/* ++ * SoftNet ++ * ++ * For pre-softnet kernels we need to tell the upper layer not to ++ * re-enter start_xmit() while we are in there. However softnet ++ * guarantees not to enter while we are in there so there is no need ++ * to do the netif_stop_queue() dance unless the transmit queue really ++ * gets stuck. This should also improve performance according to tests ++ * done by Aman Singla. ++ */ ++ ++#define dev_kfree_skb_irq(a) dev_kfree_skb(a) ++#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0) ++#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) ++ ++static inline void netif_start_queue(struct net_device *dev) ++{ ++ dev->tbusy = 0; ++ dev->interrupt = 0; ++ dev->start = 1; ++} ++ ++#define netif_queue_stopped(dev) (dev)->tbusy ++#define netif_running(dev) (dev)->start ++ ++#endif /* _COMPAT_NETDEVICE_H */ ++ ++#define netif_device_attach(dev) netif_start_queue(dev) ++#define netif_device_detach(dev) netif_stop_queue(dev) ++ ++/* 2.4.x renamed bottom halves to tasklets */ ++#define tasklet_struct tq_struct ++static inline void tasklet_schedule(struct tasklet_struct *tasklet) ++{ ++ queue_task(tasklet, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++} ++ ++static inline void tasklet_init(struct tasklet_struct *tasklet, ++ void (*func)(unsigned long), ++ unsigned long data) ++{ ++ tasklet->next = NULL; ++ tasklet->sync = 0; ++ tasklet->routine = (void (*)(void *))func; ++ tasklet->data = (void *)data; ++} ++#define tasklet_kill(tasklet) {do{} while(0);} ++ ++/* 2.4.x introduced del_timer_sync() */ ++#define del_timer_sync(timer) del_timer(timer) ++ ++#else ++ ++#define netif_down(dev) ++ ++#endif /* SoftNet */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) ++ ++/* ++ * Emit code to initialise a tq_struct's routine and data pointers ++ */ ++#define PREPARE_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ (_tq)->routine = _routine; \ ++ (_tq)->data = _data; \ ++ } while (0) ++ ++/* ++ * Emit code to initialise all of a tq_struct ++ */ ++#define INIT_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ INIT_LIST_HEAD(&(_tq)->list); \ ++ (_tq)->sync = 0; \ ++ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ ++ } while (0) ++ ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6)) ++ ++/* Power management related routines */ ++ ++static inline int ++pci_save_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_read_config_dword(dev, i * 4,&buffer[i]); ++ } ++ return 0; ++} ++ ++static inline int ++pci_restore_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_write_config_dword(dev,i * 4, buffer[i]); ++ } ++ /* ++ * otherwise, write the context information we know from bootup. ++ * This works around a problem where warm-booting from Windows ++ * combined with a D3(hot)->D0 transition causes PCI config ++ * header data to be forgotten. ++ */ ++ else { ++ for (i = 0; i < 6; i ++) ++ pci_write_config_dword(dev, ++ PCI_BASE_ADDRESS_0 + (i * 4), ++ pci_resource_start(dev, i)); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ++ } ++ return 0; ++} ++ ++#endif /* PCI power management */ ++ ++/* Old cp0 access macros deprecated in 2.4.19 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)) ++#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) ++#endif ++ ++/* Module refcount handled internally in 2.6.x */ ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do {} while (0) ++#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT ++#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT ++#else ++#define OLD_MOD_INC_USE_COUNT do {} while (0) ++#define OLD_MOD_DEC_USE_COUNT do {} while (0) ++#endif ++ ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) do {} while (0) ++#endif ++ ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(dev) kfree(dev) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* struct packet_type redefined in 2.6.x */ ++#define af_packet_priv data ++#endif ++ ++#endif /* _linuxver_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/min_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/min_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/min_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/min_osl.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,126 @@ ++/* ++ * HND Minimal OS Abstraction Layer. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _min_osl_h_ ++#define _min_osl_h_ ++ ++#include ++#include ++#include ++ ++/* Cache support */ ++extern void caches_on(void); ++extern void blast_dcache(void); ++extern void blast_icache(void); ++ ++/* uart output */ ++extern void putc(int c); ++ ++/* lib functions */ ++extern int printf(const char *fmt, ...); ++extern int sprintf(char *buf, const char *fmt, ...); ++extern int strcmp(const char *s1, const char *s2); ++extern int strncmp(const char *s1, const char *s2, uint n); ++extern char *strcpy(char *dest, const char *src); ++extern char *strncpy(char *dest, const char *src, uint n); ++extern uint strlen(const char *s); ++extern char *strchr(const char *str,int c); ++extern char *strrchr(const char *str, int c); ++extern char *strcat(char *d, const char *s); ++extern void *memset(void *dest, int c, uint n); ++extern void *memcpy(void *dest, const void *src, uint n); ++extern int memcmp(const void *s1, const void *s2, uint n); ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++/* assert & debugging */ ++#define ASSERT(exp) do {} while (0) ++ ++/* PCMCIA attribute space access macros */ ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ ++ ASSERT(0) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ ++ ASSERT(0) ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(loc, offset, size) \ ++ (offset == 8 ? 0 : 0xffffffff) ++#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \ ++ do {} while (0) ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) (0) ++#define OSL_PCI_SLOT(osh) (0) ++ ++/* register access macros */ ++#define wreg32(r, v) (*(volatile uint32*)(r) = (uint32)(v)) ++#define rreg32(r) (*(volatile uint32*)(r)) ++#define wreg16(r, v) (*(volatile uint16*)(r) = (uint16)(v)) ++#define rreg16(r) (*(volatile uint16*)(r)) ++#define wreg8(r, v) (*(volatile uint8*)(r) = (uint8)(v)) ++#define rreg8(r) (*(volatile uint8*)(r)) ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = rreg8((r)); break; \ ++ case sizeof(uint16): __osl_v = rreg16((r)); break; \ ++ case sizeof(uint32): __osl_v = rreg32((r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): wreg8((r), (v)); break; \ ++ case sizeof(uint16): wreg16((r), (v)); break; \ ++ case sizeof(uint32): wreg32((r), (v)); break; \ ++ } \ ++} while (0) ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++/* general purpose memory allocation */ ++#define MALLOC(osh, size) malloc(size) ++#define MFREE(osh, addr, size) free(addr) ++#define MALLOCED(osh) 0 ++#define MALLOC_FAILED(osh) 0 ++#define MALLOC_DUMP(osh, buf, sz) ++extern int free(void *ptr); ++extern void *malloc(uint size); ++ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) ((void*)KSEG1ADDR((ulong)(va))) ++ ++/* host/bus architecture-specific address byte swap */ ++#define BUS_SWAP32(v) (v) ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) udelay(usec) ++extern void udelay(uint32 usec); ++ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ((void*)KSEG1ADDR((ulong)(pa))) ++#define REG_UNMAP(va) do {} while (0) ++ ++/* dereference an address that may cause a bus exception */ ++#define BUSPROBE(val, addr) (uint32 *)(addr) = (val) ++ ++/* Misc stubs */ ++#define osl_attach(pdev) ((osl_t*)pdev) ++#define osl_detach(osh) ++extern void *osl_init(void); ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int); ++ ++#endif /* _min_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,552 @@ ++/* ++ * HND Run Time Environment for standalone MIPS programs. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _MISPINC_H ++#define _MISPINC_H ++ ++ ++/* MIPS defines */ ++ ++#ifdef _LANGUAGE_ASSEMBLY ++ ++/* ++ * Symbolic register names for 32 bit ABI ++ */ ++#define zero $0 /* wired zero */ ++#define AT $1 /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define t0 $8 /* caller saved */ ++#define t1 $9 ++#define t2 $10 ++#define t3 $11 ++#define t4 $12 ++#define t5 $13 ++#define t6 $14 ++#define t7 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel scratch */ ++#define k1 $27 ++#define gp $28 /* global pointer */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* same like fp! */ ++#define ra $31 /* return address */ ++ ++ ++/* ++ * CP0 Registers ++ */ ++ ++#define C0_INX $0 ++#define C0_RAND $1 ++#define C0_TLBLO0 $2 ++#define C0_TLBLO C0_TLBLO0 ++#define C0_TLBLO1 $3 ++#define C0_CTEXT $4 ++#define C0_PGMASK $5 ++#define C0_WIRED $6 ++#define C0_BADVADDR $8 ++#define C0_COUNT $9 ++#define C0_TLBHI $10 ++#define C0_COMPARE $11 ++#define C0_SR $12 ++#define C0_STATUS C0_SR ++#define C0_CAUSE $13 ++#define C0_EPC $14 ++#define C0_PRID $15 ++#define C0_CONFIG $16 ++#define C0_LLADDR $17 ++#define C0_WATCHLO $18 ++#define C0_WATCHHI $19 ++#define C0_XCTEXT $20 ++#define C0_DIAGNOSTIC $22 ++#define C0_BROADCOM C0_DIAGNOSTIC ++#define C0_PERFORMANCE $25 ++#define C0_ECC $26 ++#define C0_CACHEERR $27 ++#define C0_TAGLO $28 ++#define C0_TAGHI $29 ++#define C0_ERREPC $30 ++#define C0_DESAVE $31 ++ ++/* ++ * LEAF - declare leaf routine ++ */ ++#define LEAF(symbol) \ ++ .globl symbol; \ ++ .align 2; \ ++ .type symbol,@function; \ ++ .ent symbol,0; \ ++symbol: .frame sp,0,ra ++ ++/* ++ * END - mark end of function ++ */ ++#define END(function) \ ++ .end function; \ ++ .size function,.-function ++ ++#define _ULCAST_ ++ ++#else ++ ++/* ++ * The following macros are especially useful for __asm__ ++ * inline assembler. ++ */ ++#ifndef __STR ++#define __STR(x) #x ++#endif ++#ifndef STR ++#define STR(x) __STR(x) ++#endif ++ ++#define _ULCAST_ (unsigned long) ++ ++ ++/* ++ * CP0 Registers ++ */ ++ ++#define C0_INX 0 /* CP0: TLB Index */ ++#define C0_RAND 1 /* CP0: TLB Random */ ++#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ ++#define C0_CTEXT 4 /* CP0: Context */ ++#define C0_PGMASK 5 /* CP0: TLB PageMask */ ++#define C0_WIRED 6 /* CP0: TLB Wired */ ++#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ ++#define C0_COUNT 9 /* CP0: Count */ ++#define C0_TLBHI 10 /* CP0: TLB EntryHi */ ++#define C0_COMPARE 11 /* CP0: Compare */ ++#define C0_SR 12 /* CP0: Processor Status */ ++#define C0_STATUS C0_SR /* CP0: Processor Status */ ++#define C0_CAUSE 13 /* CP0: Exception Cause */ ++#define C0_EPC 14 /* CP0: Exception PC */ ++#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ ++#define C0_CONFIG 16 /* CP0: Config */ ++#define C0_LLADDR 17 /* CP0: LLAddr */ ++#define C0_WATCHLO 18 /* CP0: WatchpointLo */ ++#define C0_WATCHHI 19 /* CP0: WatchpointHi */ ++#define C0_XCTEXT 20 /* CP0: XContext */ ++#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ ++#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ ++#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ ++#define C0_ECC 26 /* CP0: ECC */ ++#define C0_CACHEERR 27 /* CP0: CacheErr */ ++#define C0_TAGLO 28 /* CP0: TagLo */ ++#define C0_TAGHI 29 /* CP0: TagHi */ ++#define C0_ERREPC 30 /* CP0: ErrorEPC */ ++#define C0_DESAVE 31 /* CP0: DebugSave */ ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* ++ * Memory segments (32bit kernel mode addresses) ++ */ ++#undef KUSEG ++#undef KSEG0 ++#undef KSEG1 ++#undef KSEG2 ++#undef KSEG3 ++#define KUSEG 0x00000000 ++#define KSEG0 0x80000000 ++#define KSEG1 0xa0000000 ++#define KSEG2 0xc0000000 ++#define KSEG3 0xe0000000 ++#define PHYSADDR_MASK 0x1fffffff ++ ++/* ++ * Map an address to a certain kernel segment ++ */ ++#undef PHYSADDR ++#undef KSEG0ADDR ++#undef KSEG1ADDR ++#undef KSEG2ADDR ++#undef KSEG3ADDR ++ ++#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) ++#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) ++#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) ++#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) ++#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) ++ ++ ++#ifndef Index_Invalidate_I ++/* ++ * Cache Operations ++ */ ++#define Index_Invalidate_I 0x00 ++#define Index_Writeback_Inv_D 0x01 ++#define Index_Invalidate_SI 0x02 ++#define Index_Writeback_Inv_SD 0x03 ++#define Index_Load_Tag_I 0x04 ++#define Index_Load_Tag_D 0x05 ++#define Index_Load_Tag_SI 0x06 ++#define Index_Load_Tag_SD 0x07 ++#define Index_Store_Tag_I 0x08 ++#define Index_Store_Tag_D 0x09 ++#define Index_Store_Tag_SI 0x0A ++#define Index_Store_Tag_SD 0x0B ++#define Create_Dirty_Excl_D 0x0d ++#define Create_Dirty_Excl_SD 0x0f ++#define Hit_Invalidate_I 0x10 ++#define Hit_Invalidate_D 0x11 ++#define Hit_Invalidate_SI 0x12 ++#define Hit_Invalidate_SD 0x13 ++#define Fill_I 0x14 ++#define Hit_Writeback_Inv_D 0x15 ++ /* 0x16 is unused */ ++#define Hit_Writeback_Inv_SD 0x17 ++#define R5K_Page_Invalidate_S 0x17 ++#define Hit_Writeback_I 0x18 ++#define Hit_Writeback_D 0x19 ++ /* 0x1a is unused */ ++#define Hit_Writeback_SD 0x1b ++ /* 0x1c is unused */ ++ /* 0x1e is unused */ ++#define Hit_Set_Virtual_SI 0x1e ++#define Hit_Set_Virtual_SD 0x1f ++#endif ++ ++ ++/* ++ * R4x00 interrupt enable / cause bits ++ */ ++#define IE_SW0 (_ULCAST_(1) << 8) ++#define IE_SW1 (_ULCAST_(1) << 9) ++#define IE_IRQ0 (_ULCAST_(1) << 10) ++#define IE_IRQ1 (_ULCAST_(1) << 11) ++#define IE_IRQ2 (_ULCAST_(1) << 12) ++#define IE_IRQ3 (_ULCAST_(1) << 13) ++#define IE_IRQ4 (_ULCAST_(1) << 14) ++#define IE_IRQ5 (_ULCAST_(1) << 15) ++ ++#ifndef ST0_UM ++/* ++ * Bitfields in the mips32 cp0 status register ++ */ ++#define ST0_IE 0x00000001 ++#define ST0_EXL 0x00000002 ++#define ST0_ERL 0x00000004 ++#define ST0_UM 0x00000010 ++#define ST0_SWINT0 0x00000100 ++#define ST0_SWINT1 0x00000200 ++#define ST0_HWINT0 0x00000400 ++#define ST0_HWINT1 0x00000800 ++#define ST0_HWINT2 0x00001000 ++#define ST0_HWINT3 0x00002000 ++#define ST0_HWINT4 0x00004000 ++#define ST0_HWINT5 0x00008000 ++#define ST0_IM 0x0000ff00 ++#define ST0_NMI 0x00080000 ++#define ST0_SR 0x00100000 ++#define ST0_TS 0x00200000 ++#define ST0_BEV 0x00400000 ++#define ST0_RE 0x02000000 ++#define ST0_RP 0x08000000 ++#define ST0_CU 0xf0000000 ++#define ST0_CU0 0x10000000 ++#define ST0_CU1 0x20000000 ++#define ST0_CU2 0x40000000 ++#define ST0_CU3 0x80000000 ++#endif ++ ++ ++/* ++ * Bitfields in the mips32 cp0 cause register ++ */ ++#define C_EXC 0x0000007c ++#define C_EXC_SHIFT 2 ++#define C_INT 0x0000ff00 ++#define C_INT_SHIFT 8 ++#define C_SW0 (_ULCAST_(1) << 8) ++#define C_SW1 (_ULCAST_(1) << 9) ++#define C_IRQ0 (_ULCAST_(1) << 10) ++#define C_IRQ1 (_ULCAST_(1) << 11) ++#define C_IRQ2 (_ULCAST_(1) << 12) ++#define C_IRQ3 (_ULCAST_(1) << 13) ++#define C_IRQ4 (_ULCAST_(1) << 14) ++#define C_IRQ5 (_ULCAST_(1) << 15) ++#define C_WP 0x00400000 ++#define C_IV 0x00800000 ++#define C_CE 0x30000000 ++#define C_CE_SHIFT 28 ++#define C_BD 0x80000000 ++ ++/* Values in C_EXC */ ++#define EXC_INT 0 ++#define EXC_TLBM 1 ++#define EXC_TLBL 2 ++#define EXC_TLBS 3 ++#define EXC_AEL 4 ++#define EXC_AES 5 ++#define EXC_IBE 6 ++#define EXC_DBE 7 ++#define EXC_SYS 8 ++#define EXC_BPT 9 ++#define EXC_RI 10 ++#define EXC_CU 11 ++#define EXC_OV 12 ++#define EXC_TR 13 ++#define EXC_WATCH 23 ++#define EXC_MCHK 24 ++ ++ ++/* ++ * Bits in the cp0 config register. ++ */ ++#define CONF_CM_CACHABLE_NO_WA 0 ++#define CONF_CM_CACHABLE_WA 1 ++#define CONF_CM_UNCACHED 2 ++#define CONF_CM_CACHABLE_NONCOHERENT 3 ++#define CONF_CM_CACHABLE_CE 4 ++#define CONF_CM_CACHABLE_COW 5 ++#define CONF_CM_CACHABLE_CUW 6 ++#define CONF_CM_CACHABLE_ACCELERATED 7 ++#define CONF_CM_CMASK 7 ++#define CONF_CU (_ULCAST_(1) << 3) ++#define CONF_DB (_ULCAST_(1) << 4) ++#define CONF_IB (_ULCAST_(1) << 5) ++#define CONF_SE (_ULCAST_(1) << 12) ++#define CONF_SC (_ULCAST_(1) << 17) ++#define CONF_AC (_ULCAST_(1) << 23) ++#define CONF_HALT (_ULCAST_(1) << 25) ++ ++ ++/* ++ * Bits in the cp0 config register select 1. ++ */ ++#define CONF1_FP 0x00000001 /* FPU present */ ++#define CONF1_EP 0x00000002 /* EJTAG present */ ++#define CONF1_CA 0x00000004 /* mips16 implemented */ ++#define CONF1_WR 0x00000008 /* Watch registers present */ ++#define CONF1_PC 0x00000010 /* Performance counters present */ ++#define CONF1_DA_SHIFT 7 /* D$ associativity */ ++#define CONF1_DA_MASK 0x00000380 ++#define CONF1_DA_BASE 1 ++#define CONF1_DL_SHIFT 10 /* D$ line size */ ++#define CONF1_DL_MASK 0x00001c00 ++#define CONF1_DL_BASE 2 ++#define CONF1_DS_SHIFT 13 /* D$ sets/way */ ++#define CONF1_DS_MASK 0x0000e000 ++#define CONF1_DS_BASE 64 ++#define CONF1_IA_SHIFT 16 /* I$ associativity */ ++#define CONF1_IA_MASK 0x00070000 ++#define CONF1_IA_BASE 1 ++#define CONF1_IL_SHIFT 19 /* I$ line size */ ++#define CONF1_IL_MASK 0x00380000 ++#define CONF1_IL_BASE 2 ++#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ ++#define CONF1_IS_MASK 0x01c00000 ++#define CONF1_IS_BASE 64 ++#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ ++#define CONF1_MS_SHIFT 25 ++ ++/* PRID register */ ++#define PRID_COPT_MASK 0xff000000 ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++#define PRID_REV_MASK 0x000000ff ++ ++#define PRID_COMP_LEGACY 0x000000 ++#define PRID_COMP_MIPS 0x010000 ++#define PRID_COMP_BROADCOM 0x020000 ++#define PRID_COMP_ALCHEMY 0x030000 ++#define PRID_COMP_SIBYTE 0x040000 ++#define PRID_IMP_BCM4710 0x4000 ++#define PRID_IMP_BCM3302 0x9000 ++#define PRID_IMP_BCM3303 0x9100 ++ ++#define PRID_IMP_UNKNOWN 0xff00 ++ ++#define BCM330X(id) \ ++ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ ++ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) ++ ++/* Bits in C0_BROADCOM */ ++#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ ++#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ ++#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ ++#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ ++ ++/* PreFetch Cache aka Read Ahead Cache */ ++ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ ++ ++/* PFC operations */ ++#define PFC_I 0x00000001 /* Enable PFC use for instructions */ ++#define PFC_D 0x00000002 /* Enable PFC use for data */ ++#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ ++#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ ++#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ ++#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ ++#define PFC_DPF 0x00000040 /* Enable directional prefetching */ ++#define PFC_FLUSH 0x00000100 /* Flush the PFC */ ++#define PFC_BRR 0x40000000 /* Bus error indication */ ++#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ ++ ++/* Handy defaults */ ++#define PFC_DISABLED 0 ++#define PFC_AUTO 0xffffffff /* auto select the default mode */ ++#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) ++#define PFC_INST_NOPF (PFC_I | PFC_CINV) ++#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) ++#define PFC_DATA_NOPF (PFC_D | PFC_CINV) ++#define PFC_I_AND_D (PFC_INST | PFC_DATA) ++#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) ++ ++ ++/* ++ * These are the UART port assignments, expressed as offsets from the base ++ * register. These assignments should hold for any serial port based on ++ * a 8250, 16450, or 16550(A). ++ */ ++ ++#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ ++#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ ++#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ ++#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ ++#define UART_LCR 3 /* Out: Line Control Register */ ++#define UART_MCR 4 /* Out: Modem Control Register */ ++#define UART_LSR 5 /* In: Line Status Register */ ++#define UART_MSR 6 /* In: Modem Status Register */ ++#define UART_SCR 7 /* I/O: Scratch Register */ ++#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ ++#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ ++#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ ++#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ ++#define UART_LSR_RXRDY 0x01 /* Receiver ready */ ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* ++ * Macros to access the system control coprocessor ++ */ ++ ++#define MFC0(source, sel) \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ ++ "move\t%0,$1\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res) \ ++ : \ ++ :"$1"); \ ++ __res; \ ++}) ++ ++#define MTC0(source, sel, value) \ ++do { \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "move\t$1,%z0\n\t" \ ++ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ : \ ++ :"jr" (value) \ ++ :"$1"); \ ++} while (0) ++ ++#define get_c0_count() \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "mfc0\t%0,$9\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res)); \ ++ __res; \ ++}) ++ ++static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; ++ ++ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) ++ lsz = CONF1_IL_BASE << lsz; ++ sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); ++ ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} ++ ++static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; ++ ++ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) ++ lsz = CONF1_DL_BASE << lsz; ++ sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); ++ ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} ++ ++#define cache_op(base, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, (%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++#define cache_unroll4(base, delta, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1,0(%0); \ ++ cache %1,delta(%0); \ ++ cache %1,(2 * delta)(%0); \ ++ cache %1,(3 * delta)(%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++#endif /* !_LANGUAGE_ASSEMBLY */ ++ ++#endif /* _MISPINC_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/nvports.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/nvports.h +--- linux-2.4.32/arch/mips/bcm947xx/include/nvports.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/nvports.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,55 @@ ++/* ++ * BCM53xx RoboSwitch utility functions ++ * ++ * Copyright (C) 2002 Broadcom Corporation ++ * $Id$ ++ */ ++ ++#ifndef _nvports_h_ ++#define _nvports_h_ ++ ++#define uint32 unsigned long ++#define uint16 unsigned short ++#define uint unsigned int ++#define uint8 unsigned char ++#define uint64 unsigned long long ++ ++enum FORCE_PORT { ++ FORCE_OFF, ++ FORCE_10H, ++ FORCE_10F, ++ FORCE_100H, ++ FORCE_100F, ++ FORCE_DOWN, ++ POWER_OFF ++}; ++ ++typedef struct _PORT_ATTRIBS ++{ ++ uint autoneg; ++ uint force; ++ uint native; ++} PORT_ATTRIBS; ++ ++extern uint ++nvExistsPortAttrib(char *attrib, uint portno); ++ ++extern int ++nvExistsAnyForcePortAttrib(uint portno); ++ ++extern void ++nvSetPortAttrib(char *attrib, uint portno); ++ ++extern void ++nvUnsetPortAttrib(char *attrib, uint portno); ++ ++extern void ++nvUnsetAllForcePortAttrib(uint portno); ++ ++extern PORT_ATTRIBS ++nvGetSwitchPortAttribs(uint portno); ++ ++#endif /* _nvports_h_ */ ++ ++ ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,42 @@ ++/* ++ * OS Abstraction Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _osl_h_ ++#define _osl_h_ ++ ++/* osl handle type forward declaration */ ++typedef struct os_handle osl_t; ++ ++#if defined(linux) ++#include ++#elif defined(NDIS) ++#include ++#elif defined(_CFE_) ++#include ++#elif defined(_HNDRTE_) ++#include ++#elif defined(_MINOSL_) ++#include ++#elif PMON ++#include ++#elif defined(MACOSX) ++#include ++#else ++#error "Unsupported OSL requested" ++#endif ++ ++/* handy */ ++#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val))) ++#define MAXPRIO 7 /* 0-7 */ ++ ++#endif /* _osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h +--- linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-12-16 23:39:10.752824750 +0100 +@@ -0,0 +1,451 @@ ++/* ++ * pcicfg.h: PCI configuration constants and structures. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _h_pci_ ++#define _h_pci_ ++ ++/* The following inside ifndef's so we don't collide with NTDDK.H */ ++#ifndef PCI_MAX_BUS ++#define PCI_MAX_BUS 0x100 ++#endif ++#ifndef PCI_MAX_DEVICES ++#define PCI_MAX_DEVICES 0x20 ++#endif ++#ifndef PCI_MAX_FUNCTION ++#define PCI_MAX_FUNCTION 0x8 ++#endif ++ ++#ifndef PCI_INVALID_VENDORID ++#define PCI_INVALID_VENDORID 0xffff ++#endif ++#ifndef PCI_INVALID_DEVICEID ++#define PCI_INVALID_DEVICEID 0xffff ++#endif ++ ++ ++/* Convert between bus-slot-function-register and config addresses */ ++ ++#define PCICFG_BUS_SHIFT 16 /* Bus shift */ ++#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ ++#define PCICFG_FUN_SHIFT 8 /* Function shift */ ++#define PCICFG_OFF_SHIFT 0 /* Register shift */ ++ ++#define PCICFG_BUS_MASK 0xff /* Bus mask */ ++#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ ++#define PCICFG_FUN_MASK 7 /* Function mask */ ++#define PCICFG_OFF_MASK 0xff /* Bus mask */ ++ ++#define PCI_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ ++ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ ++ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ ++ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) ++ ++#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) ++#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) ++#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) ++#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) ++ ++/* PCIE Config space accessing MACROS*/ ++ ++#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ ++#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ ++#define PCIECFG_FUN_SHIFT 16 /* Function shift */ ++#define PCIECFG_OFF_SHIFT 0 /* Register shift */ ++ ++#define PCIECFG_BUS_MASK 0xff /* Bus mask */ ++#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ ++#define PCIECFG_FUN_MASK 7 /* Function mask */ ++#define PCIECFG_OFF_MASK 0x3ff /* Register mask */ ++ ++#define PCIE_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ ++ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ ++ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ ++ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) ++ ++#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) ++#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) ++#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) ++#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) ++ ++ ++/* The actual config space */ ++ ++#define PCI_BAR_MAX 6 ++ ++#define PCI_ROM_BAR 8 ++ ++#define PCR_RSVDA_MAX 2 ++ ++/* pci config status reg has a bit to indicate that capability ptr is present*/ ++ ++#define PCI_CAPPTR_PRESENT 0x0010 ++ ++typedef struct _pci_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long base[PCI_BAR_MAX]; ++ unsigned long cardbus_cis; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long baserom; ++ unsigned long rsvd_a[PCR_RSVDA_MAX]; ++ unsigned char int_line; ++ unsigned char int_pin; ++ unsigned char min_gnt; ++ unsigned char max_lat; ++ unsigned char dev_dep[192]; ++} pci_config_regs; ++ ++#define SZPCR (sizeof (pci_config_regs)) ++#define MINSZPCR 64 /* offsetof (dev_dep[0] */ ++ ++/* A structure for the config registers is nice, but in most ++ * systems the config space is not memory mapped, so we need ++ * filed offsetts. :-( ++ */ ++#define PCI_CFG_VID 0 ++#define PCI_CFG_DID 2 ++#define PCI_CFG_CMD 4 ++#define PCI_CFG_STAT 6 ++#define PCI_CFG_REV 8 ++#define PCI_CFG_PROGIF 9 ++#define PCI_CFG_SUBCL 0xa ++#define PCI_CFG_BASECL 0xb ++#define PCI_CFG_CLSZ 0xc ++#define PCI_CFG_LATTIM 0xd ++#define PCI_CFG_HDR 0xe ++#define PCI_CFG_BIST 0xf ++#define PCI_CFG_BAR0 0x10 ++#define PCI_CFG_BAR1 0x14 ++#define PCI_CFG_BAR2 0x18 ++#define PCI_CFG_BAR3 0x1c ++#define PCI_CFG_BAR4 0x20 ++#define PCI_CFG_BAR5 0x24 ++#define PCI_CFG_CIS 0x28 ++#define PCI_CFG_SVID 0x2c ++#define PCI_CFG_SSID 0x2e ++#define PCI_CFG_ROMBAR 0x30 ++#define PCI_CFG_CAPPTR 0x34 ++#define PCI_CFG_INT 0x3c ++#define PCI_CFG_PIN 0x3d ++#define PCI_CFG_MINGNT 0x3e ++#define PCI_CFG_MAXLAT 0x3f ++ ++/* Classes and subclasses */ ++ ++typedef enum { ++ PCI_CLASS_OLD = 0, ++ PCI_CLASS_DASDI, ++ PCI_CLASS_NET, ++ PCI_CLASS_DISPLAY, ++ PCI_CLASS_MMEDIA, ++ PCI_CLASS_MEMORY, ++ PCI_CLASS_BRIDGE, ++ PCI_CLASS_COMM, ++ PCI_CLASS_BASE, ++ PCI_CLASS_INPUT, ++ PCI_CLASS_DOCK, ++ PCI_CLASS_CPU, ++ PCI_CLASS_SERIAL, ++ PCI_CLASS_INTELLIGENT = 0xe, ++ PCI_CLASS_SATELLITE, ++ PCI_CLASS_CRYPT, ++ PCI_CLASS_DSP, ++ PCI_CLASS_MAX ++} pci_classes; ++ ++typedef enum { ++ PCI_DASDI_SCSI, ++ PCI_DASDI_IDE, ++ PCI_DASDI_FLOPPY, ++ PCI_DASDI_IPI, ++ PCI_DASDI_RAID, ++ PCI_DASDI_OTHER = 0x80 ++} pci_dasdi_subclasses; ++ ++typedef enum { ++ PCI_NET_ETHER, ++ PCI_NET_TOKEN, ++ PCI_NET_FDDI, ++ PCI_NET_ATM, ++ PCI_NET_OTHER = 0x80 ++} pci_net_subclasses; ++ ++typedef enum { ++ PCI_DISPLAY_VGA, ++ PCI_DISPLAY_XGA, ++ PCI_DISPLAY_3D, ++ PCI_DISPLAY_OTHER = 0x80 ++} pci_display_subclasses; ++ ++typedef enum { ++ PCI_MMEDIA_VIDEO, ++ PCI_MMEDIA_AUDIO, ++ PCI_MMEDIA_PHONE, ++ PCI_MEDIA_OTHER = 0x80 ++} pci_mmedia_subclasses; ++ ++typedef enum { ++ PCI_MEMORY_RAM, ++ PCI_MEMORY_FLASH, ++ PCI_MEMORY_OTHER = 0x80 ++} pci_memory_subclasses; ++ ++typedef enum { ++ PCI_BRIDGE_HOST, ++ PCI_BRIDGE_ISA, ++ PCI_BRIDGE_EISA, ++ PCI_BRIDGE_MC, ++ PCI_BRIDGE_PCI, ++ PCI_BRIDGE_PCMCIA, ++ PCI_BRIDGE_NUBUS, ++ PCI_BRIDGE_CARDBUS, ++ PCI_BRIDGE_RACEWAY, ++ PCI_BRIDGE_OTHER = 0x80 ++} pci_bridge_subclasses; ++ ++typedef enum { ++ PCI_COMM_UART, ++ PCI_COMM_PARALLEL, ++ PCI_COMM_MULTIUART, ++ PCI_COMM_MODEM, ++ PCI_COMM_OTHER = 0x80 ++} pci_comm_subclasses; ++ ++typedef enum { ++ PCI_BASE_PIC, ++ PCI_BASE_DMA, ++ PCI_BASE_TIMER, ++ PCI_BASE_RTC, ++ PCI_BASE_PCI_HOTPLUG, ++ PCI_BASE_OTHER = 0x80 ++} pci_base_subclasses; ++ ++typedef enum { ++ PCI_INPUT_KBD, ++ PCI_INPUT_PEN, ++ PCI_INPUT_MOUSE, ++ PCI_INPUT_SCANNER, ++ PCI_INPUT_GAMEPORT, ++ PCI_INPUT_OTHER = 0x80 ++} pci_input_subclasses; ++ ++typedef enum { ++ PCI_DOCK_GENERIC, ++ PCI_DOCK_OTHER = 0x80 ++} pci_dock_subclasses; ++ ++typedef enum { ++ PCI_CPU_386, ++ PCI_CPU_486, ++ PCI_CPU_PENTIUM, ++ PCI_CPU_ALPHA = 0x10, ++ PCI_CPU_POWERPC = 0x20, ++ PCI_CPU_MIPS = 0x30, ++ PCI_CPU_COPROC = 0x40, ++ PCI_CPU_OTHER = 0x80 ++} pci_cpu_subclasses; ++ ++typedef enum { ++ PCI_SERIAL_IEEE1394, ++ PCI_SERIAL_ACCESS, ++ PCI_SERIAL_SSA, ++ PCI_SERIAL_USB, ++ PCI_SERIAL_FIBER, ++ PCI_SERIAL_SMBUS, ++ PCI_SERIAL_OTHER = 0x80 ++} pci_serial_subclasses; ++ ++typedef enum { ++ PCI_INTELLIGENT_I2O, ++} pci_intelligent_subclasses; ++ ++typedef enum { ++ PCI_SATELLITE_TV, ++ PCI_SATELLITE_AUDIO, ++ PCI_SATELLITE_VOICE, ++ PCI_SATELLITE_DATA, ++ PCI_SATELLITE_OTHER = 0x80 ++} pci_satellite_subclasses; ++ ++typedef enum { ++ PCI_CRYPT_NETWORK, ++ PCI_CRYPT_ENTERTAINMENT, ++ PCI_CRYPT_OTHER = 0x80 ++} pci_crypt_subclasses; ++ ++typedef enum { ++ PCI_DSP_DPIO, ++ PCI_DSP_OTHER = 0x80 ++} pci_dsp_subclasses; ++ ++/* Header types */ ++typedef enum { ++ PCI_HEADER_NORMAL, ++ PCI_HEADER_BRIDGE, ++ PCI_HEADER_CARDBUS ++} pci_header_types; ++ ++ ++/* Overlay for a PCI-to-PCI bridge */ ++ ++#define PPB_RSVDA_MAX 2 ++#define PPB_RSVDD_MAX 8 ++ ++typedef struct _ppb_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long rsvd_a[PPB_RSVDA_MAX]; ++ unsigned char prim_bus; ++ unsigned char sec_bus; ++ unsigned char sub_bus; ++ unsigned char sec_lat; ++ unsigned char io_base; ++ unsigned char io_lim; ++ unsigned short sec_status; ++ unsigned short mem_base; ++ unsigned short mem_lim; ++ unsigned short pf_mem_base; ++ unsigned short pf_mem_lim; ++ unsigned long pf_mem_base_hi; ++ unsigned long pf_mem_lim_hi; ++ unsigned short io_base_hi; ++ unsigned short io_lim_hi; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long rsvd_b; ++ unsigned char rsvd_c; ++ unsigned char int_pin; ++ unsigned short bridge_ctrl; ++ unsigned char chip_ctrl; ++ unsigned char diag_ctrl; ++ unsigned short arb_ctrl; ++ unsigned long rsvd_d[PPB_RSVDD_MAX]; ++ unsigned char dev_dep[192]; ++} ppb_config_regs; ++ ++ ++/* PCI CAPABILITY DEFINES */ ++#define PCI_CAP_POWERMGMTCAP_ID 0x01 ++#define PCI_CAP_MSICAP_ID 0x05 ++#define PCI_CAP_PCIECAP_ID 0x10 ++ ++/* Data structure to define the Message Signalled Interrupt facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_msi { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short msgctrl; ++ unsigned int msgaddr; ++} pciconfig_cap_msi; ++ ++/* Data structure to define the Power managment facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_pwrmgmt { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pme_cap; ++ unsigned short pme_sts_ctrl; ++ unsigned char pme_bridge_ext; ++ unsigned char data; ++} pciconfig_cap_pwrmgmt; ++ ++/* Data structure to define the PCIE capability */ ++typedef struct _pciconfig_cap_pcie { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pcie_cap; ++ unsigned int dev_cap; ++ unsigned short dev_ctrl; ++ unsigned short dev_status; ++ unsigned int link_cap; ++ unsigned short link_ctrl; ++ unsigned short link_status; ++} pciconfig_cap_pcie; ++ ++/* PCIE Enhanced CAPABILITY DEFINES */ ++#define PCIE_EXTCFG_OFFSET 0x100 ++#define PCIE_ADVERRREP_CAPID 0x0001 ++#define PCIE_VC_CAPID 0x0002 ++#define PCIE_DEVSNUM_CAPID 0x0003 ++#define PCIE_PWRBUDGET_CAPID 0x0004 ++ ++/* Header to define the PCIE specific capabilities in the extended config space */ ++typedef struct _pcie_enhanced_caphdr { ++ unsigned short capID; ++ unsigned short cap_ver : 4; ++ unsigned short next_ptr : 12; ++} pcie_enhanced_caphdr; ++ ++ ++/* Everything below is BRCM HND proprietary */ ++ ++#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ ++#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ ++#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ ++#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ ++#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ ++#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ ++#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ ++#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */ ++#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address register */ ++#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ ++#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ ++#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ ++ ++#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ ++#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ ++ ++/* PCI_INT_STATUS */ ++#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ ++ ++/* PCI_INT_MASK */ ++#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ ++#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ ++#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ ++ ++/* PCI_SPROM_CONTROL */ ++#define SPROM_BLANK 0x04 /* indicating a blank sprom */ ++#define SPROM_WRITEEN 0x10 /* sprom write enable */ ++#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ ++ ++#define SPROM_SIZE 256 /* sprom size in 16-bit */ ++#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ ++ ++/* PCI_CFG_CMD_STAT */ ++#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pmon_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pmon_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/pmon_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pmon_osl.h 2005-12-16 23:39:10.752824750 +0100 +@@ -0,0 +1,126 @@ ++/* ++ * MIPS PMON boot loader OS Abstraction Layer. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _pmon_osl_h_ ++#define _pmon_osl_h_ ++ ++#include ++#include ++#include ++#include ++ ++extern int printf(char *fmt,...); ++extern int sprintf(char *dst,char *fmt,...); ++ ++#define OSL_UNCACHED(va) phy2k1(log2phy((va))) ++#define REG_MAP(pa, size) phy2k1((pa)) ++#define REG_UNMAP(va) /* nop */ ++ ++/* Common macros */ ++ ++#define BUSPROBE(val, addr) ((val) = *(addr)) ++ ++#define ASSERT(exp) ++ ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) bzero(buf, size) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) ++ ++/* kludge */ ++#define OSL_PCI_READ_CONFIG(loc, offset, size) ((offset == 8)? 0: 0xffffffff) ++#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) ASSERT(0) ++ ++#define wreg32(r,v) (*(volatile uint32 *)(r) = (v)) ++#define rreg32(r) (*(volatile uint32 *)(r)) ++#ifdef IL_BIGENDIAN ++#define wreg16(r,v) (*(volatile uint16 *)((uint32)r^2) = (v)) ++#define rreg16(r) (*(volatile uint16 *)((uint32)r^2)) ++#else ++#define wreg16(r,v) (*(volatile uint16 *)(r) = (v)) ++#define rreg16(r) (*(volatile uint16 *)(r)) ++#endif ++ ++#include ++#define bcopy(src, dst, len) memcpy(dst, src, len) ++#define bcmp(b1, b2, len) memcmp(b1, b2, len) ++#define bzero(b, len) memset(b, '\0', len) ++ ++/* register access macros */ ++#define R_REG(r) ((sizeof *(r) == sizeof (uint32))? rreg32(r): rreg16(r)) ++#define W_REG(r,v) ((sizeof *(r) == sizeof (uint32))? wreg32(r,(uint32)v): wreg16(r,(uint16)v)) ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset(r, '\0', len) ++ ++/* Host/Bus architecture specific swap. Noop for little endian systems, possible swap on big endian */ ++#define BUS_SWAP32(v) (v) ++ ++#define OSL_DELAY(usec) delay_us(usec) ++extern void delay_us(uint usec); ++ ++#define OSL_GETCYCLES(x) ((x) = 0) ++ ++#define osl_attach(pdev) (pdev) ++#define osl_detach(osh) ++ ++#define MALLOC(osh, size) malloc(size) ++#define MFREE(osh, addr, size) free(addr) ++#define MALLOCED(osh) (0) ++#define MALLOC_DUMP(osh, buf, sz) ++#define MALLOC_FAILED(osh) ++extern void *malloc(); ++extern void free(void *addr); ++ ++#define DMA_CONSISTENT_ALIGN sizeof (int) ++#define DMA_ALLOC_CONSISTENT(osh, size, pap) et_dma_alloc_consistent(osh, size, pap) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa) ++extern void* et_dma_alloc_consistent(void *osh, uint size, ulong *pap); ++#define DMA_TX 0 ++#define DMA_RX 1 ++ ++#define DMA_MAP(osh, va, size, direction, p) osl_dma_map(osh, (void*)va, size, direction) ++#define DMA_UNMAP(osh, pa, size, direction, p) /* nop */ ++extern void* osl_dma_map(void *osh, void *va, uint size, uint direction); ++ ++struct lbuf { ++ struct lbuf *next; /* pointer to next lbuf on freelist */ ++ uchar *buf; /* pointer to buffer */ ++ uint len; /* nbytes of data */ ++}; ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++/* packet primitives */ ++#define PKTGET(drv, len, send) et_pktget(drv, len, send) ++#define PKTFREE(drv, lb, send) et_pktfree(drv, (struct lbuf*)lb, send) ++#define PKTDATA(drv, lb) ((uchar*)OSL_UNCACHED(((struct lbuf*)lb)->buf)) ++#define PKTLEN(drv, lb) ((struct lbuf*)lb)->len ++#define PKTHEADROOM(drv, lb) (0) ++#define PKTTAILROOM(drv, lb) (0) ++#define PKTNEXT(drv, lb) NULL ++#define PKTSETNEXT(lb, x) ASSERT(0) ++#define PKTSETLEN(drv, lb, bytes) ((struct lbuf*)lb)->len = bytes ++#define PKTPUSH(drv, lb, bytes) ASSERT(0) ++#define PKTPULL(drv, lb, bytes) ASSERT(0) ++#define PKTDUP(drv, lb) ASSERT(0) ++#define PKTLINK(lb) ((struct lbuf*)lb)->next ++#define PKTSETLINK(lb, x) ((struct lbuf*)lb)->next = (struct lbuf*)x ++#define PKTPRIO(lb) (0) ++#define PKTSETPRIO(lb, x) do {} while (0) ++extern void *et_pktget(void *drv, uint len, bool send); ++extern void et_pktfree(void *drv, struct lbuf *lb, bool send); ++ ++#endif /* _pmon_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/802.11.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/802.11.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/802.11.h 2005-12-16 23:39:10.752824750 +0100 +@@ -0,0 +1,930 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Fundamental types and constants relating to 802.11 ++ * ++ * $Id$ ++ */ ++ ++#ifndef _802_11_H_ ++#define _802_11_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++#ifndef _NET_ETHERNET_H_ ++#include ++#endif ++ ++#include ++ ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ ++ ++/* Generic 802.11 frame constants */ ++#define DOT11_A3_HDR_LEN 24 ++#define DOT11_A4_HDR_LEN 30 ++#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN ++#define DOT11_FCS_LEN 4 ++#define DOT11_ICV_LEN 4 ++#define DOT11_ICV_AES_LEN 8 ++#define DOT11_QOS_LEN 2 ++ ++#define DOT11_KEY_INDEX_SHIFT 6 ++#define DOT11_IV_LEN 4 ++#define DOT11_IV_TKIP_LEN 8 ++#define DOT11_IV_AES_OCB_LEN 4 ++#define DOT11_IV_AES_CCM_LEN 8 ++ ++/* Includes MIC */ ++#define DOT11_MAX_MPDU_BODY_LEN 2304 ++/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ ++#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ ++ DOT11_QOS_LEN + \ ++ DOT11_IV_AES_CCM_LEN + \ ++ DOT11_MAX_MPDU_BODY_LEN + \ ++ DOT11_ICV_LEN + \ ++ DOT11_FCS_LEN) ++ ++#define DOT11_MAX_SSID_LEN 32 ++ ++/* dot11RTSThreshold */ ++#define DOT11_DEFAULT_RTS_LEN 2347 ++#define DOT11_MAX_RTS_LEN 2347 ++ ++/* dot11FragmentationThreshold */ ++#define DOT11_MIN_FRAG_LEN 256 ++#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength of the attached PHY */ ++#define DOT11_DEFAULT_FRAG_LEN 2346 ++ ++/* dot11BeaconPeriod */ ++#define DOT11_MIN_BEACON_PERIOD 1 ++#define DOT11_MAX_BEACON_PERIOD 0xFFFF ++ ++/* dot11DTIMPeriod */ ++#define DOT11_MIN_DTIM_PERIOD 1 ++#define DOT11_MAX_DTIM_PERIOD 0xFF ++ ++/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ ++#define DOT11_LLC_SNAP_HDR_LEN 8 ++#define DOT11_OUI_LEN 3 ++struct dot11_llc_snap_header { ++ uint8 dsap; /* always 0xAA */ ++ uint8 ssap; /* always 0xAA */ ++ uint8 ctl; /* always 0x03 */ ++ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 ++ Bridge-Tunnel: 0x00 0x00 0xF8 */ ++ uint16 type; /* ethertype */ ++} PACKED; ++ ++/* RFC1042 header used by 802.11 per 802.1H */ ++#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) ++ ++/* Generic 802.11 MAC header */ ++/* ++ * N.B.: This struct reflects the full 4 address 802.11 MAC header. ++ * The fields are defined such that the shorter 1, 2, and 3 ++ * address headers just use the first k fields. ++ */ ++struct dot11_header { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr a1; /* address 1 */ ++ struct ether_addr a2; /* address 2 */ ++ struct ether_addr a3; /* address 3 */ ++ uint16 seq; /* sequence control */ ++ struct ether_addr a4; /* address 4 */ ++} PACKED; ++ ++/* Control frames */ ++ ++struct dot11_rts_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++ struct ether_addr ta; /* transmitter address */ ++} PACKED; ++#define DOT11_RTS_LEN 16 ++ ++struct dot11_cts_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++} PACKED; ++#define DOT11_CTS_LEN 10 ++ ++struct dot11_ack_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++} PACKED; ++#define DOT11_ACK_LEN 10 ++ ++struct dot11_ps_poll_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* AID */ ++ struct ether_addr bssid; /* receiver address, STA in AP */ ++ struct ether_addr ta; /* transmitter address */ ++} PACKED; ++#define DOT11_PS_POLL_LEN 16 ++ ++struct dot11_cf_end_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++ struct ether_addr bssid; /* transmitter address, STA in AP */ ++} PACKED; ++#define DOT11_CS_END_LEN 16 ++ ++/* Management frame header */ ++struct dot11_management_header { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr da; /* receiver address */ ++ struct ether_addr sa; /* transmitter address */ ++ struct ether_addr bssid; /* BSS ID */ ++ uint16 seq; /* sequence control */ ++} PACKED; ++#define DOT11_MGMT_HDR_LEN 24 ++ ++/* Management frame payloads */ ++ ++struct dot11_bcn_prb { ++ uint32 timestamp[2]; ++ uint16 beacon_interval; ++ uint16 capability; ++} PACKED; ++#define DOT11_BCN_PRB_LEN 12 ++ ++struct dot11_auth { ++ uint16 alg; /* algorithm */ ++ uint16 seq; /* sequence control */ ++ uint16 status; /* status code */ ++} PACKED; ++#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge info elt */ ++ ++struct dot11_assoc_req { ++ uint16 capability; /* capability information */ ++ uint16 listen; /* listen interval */ ++} PACKED; ++#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ ++ ++struct dot11_reassoc_req { ++ uint16 capability; /* capability information */ ++ uint16 listen; /* listen interval */ ++ struct ether_addr ap; /* Current AP address */ ++} PACKED; ++#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ ++ ++struct dot11_assoc_resp { ++ uint16 capability; /* capability information */ ++ uint16 status; /* status code */ ++ uint16 aid; /* association ID */ ++} PACKED; ++ ++struct dot11_action_measure { ++ uint8 category; ++ uint8 action; ++ uint8 token; ++ uint8 data[1]; ++} PACKED; ++#define DOT11_ACTION_MEASURE_LEN 3 ++ ++struct dot11_action_switch_channel { ++ uint8 category; ++ uint8 action; ++ uint8 data[5]; /* for switch IE */ ++} PACKED; ++ ++/************** ++ 802.11h related definitions. ++**************/ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 power; ++} dot11_power_cnst_t; ++ ++typedef struct { ++ uint8 min; ++ uint8 max; ++} dot11_power_cap_t; ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 tx_pwr; ++ uint8 margin; ++} dot11_tpc_rep_t; ++#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 first_channel; ++ uint8 num_channels; ++} dot11_supp_channels_t; ++ ++/* csa mode type */ ++#define DOT11_CSA_MODE_ADVISORY 0 ++#define DOT11_CSA_MODE_NO_TX 1 ++struct dot11_channel_switch { ++ uint8 id; ++ uint8 len; ++ uint8 mode; ++ uint8 channel; ++ uint8 count; ++} PACKED; ++typedef struct dot11_channel_switch dot11_channel_switch_t; ++ ++/* length of IE data, not including 2 byte header */ ++#define DOT11_SWITCH_IE_LEN 3 ++ ++/* 802.11h Measurement Request/Report IEs */ ++/* Measurement Type field */ ++#define DOT11_MEASURE_TYPE_BASIC 0 ++#define DOT11_MEASURE_TYPE_CCA 1 ++#define DOT11_MEASURE_TYPE_RPI 2 ++ ++/* Measurement Mode field */ ++ ++/* Measurement Request Modes */ ++#define DOT11_MEASURE_MODE_ENABLE (1<<1) ++#define DOT11_MEASURE_MODE_REQUEST (1<<2) ++#define DOT11_MEASURE_MODE_REPORT (1<<3) ++/* Measurement Report Modes */ ++#define DOT11_MEASURE_MODE_LATE (1<<0) ++#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) ++#define DOT11_MEASURE_MODE_REFUSED (1<<2) ++/* Basic Measurement Map bits */ ++#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) ++#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) ++#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) ++#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) ++#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++} dot11_meas_req_t; ++#define DOT11_MNG_IE_MREQ_LEN 14 ++/* length of Measure Request IE data not including variable len */ ++#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 ++ ++struct dot11_meas_rep { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++ union ++ { ++ struct { ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++ uint8 map; ++ } PACKED basic; ++ uint8 data[1]; ++ } PACKED rep; ++} PACKED; ++typedef struct dot11_meas_rep dot11_meas_rep_t; ++ ++/* length of Measure Report IE data not including variable len */ ++#define DOT11_MNG_IE_MREP_FIXED_LEN 3 ++ ++struct dot11_meas_rep_basic { ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++ uint8 map; ++} PACKED; ++typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; ++#define DOT11_MEASURE_BASIC_REP_LEN 12 ++ ++struct dot11_quiet { ++ uint8 id; ++ uint8 len; ++ uint8 count; /* TBTTs until beacon interval in quiet starts */ ++ uint8 period; /* Beacon intervals between periodic quiet periods ? */ ++ uint16 duration;/* Length of quiet period, in TU's */ ++ uint16 offset; /* TU's offset from TBTT in Count field */ ++} PACKED; ++typedef struct dot11_quiet dot11_quiet_t; ++ ++typedef struct { ++ uint8 channel; ++ uint8 map; ++} chan_map_tuple_t; ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 eaddr[ETHER_ADDR_LEN]; ++ uint8 interval; ++ chan_map_tuple_t map[1]; ++} dot11_ibss_dfs_t; ++ ++/* WME Elements */ ++#define WME_OUI "\x00\x50\xf2" ++#define WME_VER 1 ++#define WME_TYPE 2 ++#define WME_SUBTYPE_IE 0 /* Information Element */ ++#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ ++#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ ++ ++/* WME Access Category Indices (ACIs) */ ++#define AC_BE 0 /* Best Effort */ ++#define AC_BK 1 /* Background */ ++#define AC_VI 2 /* Video */ ++#define AC_VO 3 /* Voice */ ++#define AC_MAX 4 ++ ++/* WME Information Element (IE) */ ++struct wme_ie { ++ uint8 oui[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 version; ++ uint8 acinfo; ++} PACKED; ++typedef struct wme_ie wme_ie_t; ++#define WME_IE_LEN 7 ++ ++struct wme_acparam { ++ uint8 ACI; ++ uint8 ECW; ++ uint16 TXOP; /* stored in network order (ls octet first) */ ++} PACKED; ++typedef struct wme_acparam wme_acparam_t; ++ ++/* WME Parameter Element (PE) */ ++struct wme_params { ++ uint8 oui[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 version; ++ uint8 acinfo; ++ uint8 rsvd; ++ wme_acparam_t acparam[4]; ++} PACKED; ++typedef struct wme_params wme_params_t; ++#define WME_PARAMS_IE_LEN 24 ++ ++/* acinfo */ ++#define WME_COUNT_MASK 0x0f ++/* ACI */ ++#define WME_AIFS_MASK 0x0f ++#define WME_ACM_MASK 0x10 ++#define WME_ACI_MASK 0x60 ++#define WME_ACI_SHIFT 5 ++/* ECW */ ++#define WME_CWMIN_MASK 0x0f ++#define WME_CWMAX_MASK 0xf0 ++#define WME_CWMAX_SHIFT 4 ++ ++#define WME_TXOP_UNITS 32 ++ ++/* AP: default params to be announced in the Beacon Frames/Probe Responses Table 12 WME Draft*/ ++/* AP: default params to be Used in the AP Side Table 14 WME Draft January 2004 802.11-03-504r5 */ ++#define WME_AC_BK_ACI_STA 0x27 ++#define WME_AC_BK_ECW_STA 0xA4 ++#define WME_AC_BK_TXOP_STA 0x0000 ++#define WME_AC_BE_ACI_STA 0x03 ++#define WME_AC_BE_ECW_STA 0xA4 ++#define WME_AC_BE_TXOP_STA 0x0000 ++#define WME_AC_VI_ACI_STA 0x42 ++#define WME_AC_VI_ECW_STA 0x43 ++#define WME_AC_VI_TXOP_STA 0x005e ++#define WME_AC_VO_ACI_STA 0x62 ++#define WME_AC_VO_ECW_STA 0x32 ++#define WME_AC_VO_TXOP_STA 0x002f ++ ++#define WME_AC_BK_ACI_AP 0x27 ++#define WME_AC_BK_ECW_AP 0xA4 ++#define WME_AC_BK_TXOP_AP 0x0000 ++#define WME_AC_BE_ACI_AP 0x03 ++#define WME_AC_BE_ECW_AP 0x64 ++#define WME_AC_BE_TXOP_AP 0x0000 ++#define WME_AC_VI_ACI_AP 0x41 ++#define WME_AC_VI_ECW_AP 0x43 ++#define WME_AC_VI_TXOP_AP 0x005e ++#define WME_AC_VO_ACI_AP 0x61 ++#define WME_AC_VO_ECW_AP 0x32 ++#define WME_AC_VO_TXOP_AP 0x002f ++ ++/* WME Traffic Specification (TSPEC) element */ ++#define WME_SUBTYPE_TSPEC 2 ++#define WME_TSPEC_HDR_LEN 2 ++#define WME_TSPEC_BODY_OFF 2 ++struct wme_tspec { ++ uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ ++ uint8 type; /* WME_TYPE */ ++ uint8 subtype; /* WME_SUBTYPE_TSPEC */ ++ uint8 version; /* WME_VERSION */ ++ uint16 ts_info; /* TS Info */ ++ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ ++ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ ++ uint32 min_service_interval; /* Minimum Service Interval (us) */ ++ uint32 max_service_interval; /* Maximum Service Interval (us) */ ++ uint32 inactivity_interval; /* Inactivity Interval (us) */ ++ uint32 service_start; /* Service Start Time (us) */ ++ uint32 min_rate; /* Minimum Data Rate (bps) */ ++ uint32 mean_rate; /* Mean Data Rate (bps) */ ++ uint32 max_burst_size; /* Maximum Burst Size (bytes) */ ++ uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ ++ uint32 peak_rate; /* Peak Data Rate (bps) */ ++ uint32 delay_bound; /* Delay Bound (us) */ ++ uint16 surplus_bandwidth; /* Surplus Bandwidth Allowance Factor */ ++ uint16 medium_time; /* Medium Time (32 us/s periods) */ ++} PACKED; ++typedef struct wme_tspec wme_tspec_t; ++#define WME_TSPEC_LEN 56 /* not including 2-byte header */ ++ ++/* ts_info */ ++/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ ++#define TS_INFO_PRIO_SHIFT_HI 11 ++#define TS_INFO_PRIO_MASK_HI (0x7 << TS_INFO_PRIO_SHIFT_HI) ++#define TS_INFO_PRIO_SHIFT_LO 1 ++#define TS_INFO_PRIO_MASK_LO (0x7 << TS_INFO_PRIO_SHIFT_LO) ++#define TS_INFO_CONTENTION_SHIFT 7 ++#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) ++#define TS_INFO_DIRECTION_SHIFT 5 ++#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) ++#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) ++#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) ++#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) ++ ++/* nom_msdu_size */ ++#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ ++#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ ++ ++/* surplus_bandwidth */ ++/* Represented as 3 bits of integer, binary point, 13 bits fraction */ ++#define INTEGER_SHIFT 13 ++#define FRACTION_MASK 0x1FFF ++ ++/* Management Notification Frame */ ++struct dot11_management_notification { ++ uint8 category; /* DOT11_ACTION_NOTIFICATION */ ++ uint8 action; ++ uint8 token; ++ uint8 status; ++ uint8 data[1]; /* Elements */ ++} PACKED; ++#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ ++ ++/* WME Action Codes */ ++#define WME_SETUP_REQUEST 0 ++#define WME_SETUP_RESPONSE 1 ++#define WME_TEARDOWN 2 ++ ++/* WME Setup Response Status Codes */ ++#define WME_ADMISSION_ACCEPTED 0 ++#define WME_INVALID_PARAMETERS 1 ++#define WME_ADMISSION_REFUSED 3 ++ ++/* Macro to take a pointer to a beacon or probe response ++ * header and return the char* pointer to the SSID info element ++ */ ++#define BCN_PRB_SSID(hdr) ((char*)(hdr) + DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_LEN) ++ ++/* Authentication frame payload constants */ ++#define DOT11_OPEN_SYSTEM 0 ++#define DOT11_SHARED_KEY 1 ++#define DOT11_CHALLENGE_LEN 128 ++ ++/* Frame control macros */ ++#define FC_PVER_MASK 0x3 ++#define FC_PVER_SHIFT 0 ++#define FC_TYPE_MASK 0xC ++#define FC_TYPE_SHIFT 2 ++#define FC_SUBTYPE_MASK 0xF0 ++#define FC_SUBTYPE_SHIFT 4 ++#define FC_TODS 0x100 ++#define FC_TODS_SHIFT 8 ++#define FC_FROMDS 0x200 ++#define FC_FROMDS_SHIFT 9 ++#define FC_MOREFRAG 0x400 ++#define FC_MOREFRAG_SHIFT 10 ++#define FC_RETRY 0x800 ++#define FC_RETRY_SHIFT 11 ++#define FC_PM 0x1000 ++#define FC_PM_SHIFT 12 ++#define FC_MOREDATA 0x2000 ++#define FC_MOREDATA_SHIFT 13 ++#define FC_WEP 0x4000 ++#define FC_WEP_SHIFT 14 ++#define FC_ORDER 0x8000 ++#define FC_ORDER_SHIFT 15 ++ ++/* sequence control macros */ ++#define SEQNUM_SHIFT 4 ++#define FRAGNUM_MASK 0xF ++ ++/* Frame Control type/subtype defs */ ++ ++/* FC Types */ ++#define FC_TYPE_MNG 0 ++#define FC_TYPE_CTL 1 ++#define FC_TYPE_DATA 2 ++ ++/* Management Subtypes */ ++#define FC_SUBTYPE_ASSOC_REQ 0 ++#define FC_SUBTYPE_ASSOC_RESP 1 ++#define FC_SUBTYPE_REASSOC_REQ 2 ++#define FC_SUBTYPE_REASSOC_RESP 3 ++#define FC_SUBTYPE_PROBE_REQ 4 ++#define FC_SUBTYPE_PROBE_RESP 5 ++#define FC_SUBTYPE_BEACON 8 ++#define FC_SUBTYPE_ATIM 9 ++#define FC_SUBTYPE_DISASSOC 10 ++#define FC_SUBTYPE_AUTH 11 ++#define FC_SUBTYPE_DEAUTH 12 ++#define FC_SUBTYPE_ACTION 13 ++ ++/* Control Subtypes */ ++#define FC_SUBTYPE_PS_POLL 10 ++#define FC_SUBTYPE_RTS 11 ++#define FC_SUBTYPE_CTS 12 ++#define FC_SUBTYPE_ACK 13 ++#define FC_SUBTYPE_CF_END 14 ++#define FC_SUBTYPE_CF_END_ACK 15 ++ ++/* Data Subtypes */ ++#define FC_SUBTYPE_DATA 0 ++#define FC_SUBTYPE_DATA_CF_ACK 1 ++#define FC_SUBTYPE_DATA_CF_POLL 2 ++#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 ++#define FC_SUBTYPE_NULL 4 ++#define FC_SUBTYPE_CF_ACK 5 ++#define FC_SUBTYPE_CF_POLL 6 ++#define FC_SUBTYPE_CF_ACK_POLL 7 ++#define FC_SUBTYPE_QOS_DATA 8 ++#define FC_SUBTYPE_QOS_NULL 12 ++ ++/* type-subtype combos */ ++#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) ++ ++#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) ++ ++#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) ++#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) ++#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) ++#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) ++#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) ++#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) ++#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) ++#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) ++#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) ++#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) ++#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) ++ ++#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) ++#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) ++#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) ++#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) ++#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) ++#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) ++ ++#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) ++#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) ++#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) ++#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) ++#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) ++ ++/* QoS Control Field */ ++ ++/* 802.1D Tag */ ++#define QOS_PRIO_SHIFT 0 ++#define QOS_PRIO_MASK 0x0007 ++#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) ++ ++#define QOS_TID_SHIFT 0 ++#define QOS_TID_MASK 0x000f ++#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) ++ ++/* Ack Policy (0 means Acknowledge) */ ++#define QOS_ACK_SHIFT 5 ++#define QOS_ACK_MASK 0x0060 ++#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) ++ ++/* Management Frames */ ++ ++/* Management Frame Constants */ ++ ++/* Fixed fields */ ++#define DOT11_MNG_AUTH_ALGO_LEN 2 ++#define DOT11_MNG_AUTH_SEQ_LEN 2 ++#define DOT11_MNG_BEACON_INT_LEN 2 ++#define DOT11_MNG_CAP_LEN 2 ++#define DOT11_MNG_AP_ADDR_LEN 6 ++#define DOT11_MNG_LISTEN_INT_LEN 2 ++#define DOT11_MNG_REASON_LEN 2 ++#define DOT11_MNG_AID_LEN 2 ++#define DOT11_MNG_STATUS_LEN 2 ++#define DOT11_MNG_TIMESTAMP_LEN 8 ++ ++/* DUR/ID field in assoc resp is 0xc000 | AID */ ++#define DOT11_AID_MASK 0x3fff ++ ++/* Reason Codes */ ++#define DOT11_RC_RESERVED 0 ++#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ ++#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */ ++#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station is ++ leaving (or has left) IBSS or ESS */ ++#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ ++#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle ++ all currently associated stations */ ++#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from ++ nonauthenticated station */ ++#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from ++ nonassociated station */ ++#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is ++ leaving (or has left) BSS */ ++#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is ++ not authenticated with responding station */ ++#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ ++ ++/* Status Codes */ ++#define DOT11_STATUS_SUCCESS 0 /* Successful */ ++#define DOT11_STATUS_FAILURE 1 /* Unspecified failure */ ++#define DOT11_STATUS_CAP_MISMATCH 10 /* Cannot support all requested capabilities ++ in the Capability Information field */ ++#define DOT11_STATUS_REASSOC_FAIL 11 /* Reassociation denied due to inability to ++ confirm that association exists */ ++#define DOT11_STATUS_ASSOC_FAIL 12 /* Association denied due to reason outside ++ the scope of this standard */ ++#define DOT11_STATUS_AUTH_MISMATCH 13 /* Responding station does not support the ++ specified authentication algorithm */ ++#define DOT11_STATUS_AUTH_SEQ 14 /* Received an Authentication frame with ++ authentication transaction sequence number ++ out of expected sequence */ ++#define DOT11_STATUS_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of challenge failure */ ++#define DOT11_STATUS_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout waiting ++ for next frame in sequence */ ++#define DOT11_STATUS_ASSOC_BUSY_FAIL 17 /* Association denied because AP is unable to ++ handle additional associated stations */ ++#define DOT11_STATUS_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting station ++ not supporting all of the data rates in the ++ BSSBasicRateSet parameter */ ++#define DOT11_STATUS_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting station ++ not supporting the Short Preamble option */ ++#define DOT11_STATUS_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting station ++ not supporting the PBCC Modulation option */ ++#define DOT11_STATUS_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting station ++ not supporting the Channel Agility option */ ++#define DOT11_STATUS_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum Management ++ capability is required. */ ++#define DOT11_STATUS_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info in the ++ Power Cap element is unacceptable. */ ++#define DOT11_STATUS_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info in the ++ Supported Channel element is unacceptable */ ++#define DOT11_STATUS_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting station ++ not supporting the Short Slot Time option */ ++#define DOT11_STATUS_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting station ++ not supporting the ER-PBCC Modulation option */ ++#define DOT11_STATUS_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting station ++ not supporting the DSS-OFDM option */ ++ ++/* Info Elts, length of INFORMATION portion of Info Elts */ ++#define DOT11_MNG_DS_PARAM_LEN 1 ++#define DOT11_MNG_IBSS_PARAM_LEN 2 ++ ++/* TIM Info element has 3 bytes fixed info in INFORMATION field, ++ * followed by 1 to 251 bytes of Partial Virtual Bitmap */ ++#define DOT11_MNG_TIM_FIXED_LEN 3 ++#define DOT11_MNG_TIM_DTIM_COUNT 0 ++#define DOT11_MNG_TIM_DTIM_PERIOD 1 ++#define DOT11_MNG_TIM_BITMAP_CTL 2 ++#define DOT11_MNG_TIM_PVB 3 ++ ++/* TLV defines */ ++#define TLV_TAG_OFF 0 ++#define TLV_LEN_OFF 1 ++#define TLV_HDR_LEN 2 ++#define TLV_BODY_OFF 2 ++ ++/* Management Frame Information Element IDs */ ++#define DOT11_MNG_SSID_ID 0 ++#define DOT11_MNG_RATES_ID 1 ++#define DOT11_MNG_FH_PARMS_ID 2 ++#define DOT11_MNG_DS_PARMS_ID 3 ++#define DOT11_MNG_CF_PARMS_ID 4 ++#define DOT11_MNG_TIM_ID 5 ++#define DOT11_MNG_IBSS_PARMS_ID 6 ++#define DOT11_MNG_COUNTRY_ID 7 ++#define DOT11_MNG_HOPPING_PARMS_ID 8 ++#define DOT11_MNG_HOPPING_TABLE_ID 9 ++#define DOT11_MNG_REQUEST_ID 10 ++#define DOT11_MNG_CHALLENGE_ID 16 ++#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ ++#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ ++#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ ++#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ ++#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ ++#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement*/ ++#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ ++#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ ++#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ ++#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ ++#define DOT11_MNG_ERP_ID 42 ++#define DOT11_MNG_NONERP_ID 47 ++#ifdef BCMWPA2 ++#define DOT11_MNG_RSN_ID 48 ++#endif /* BCMWPA2 */ ++#define DOT11_MNG_EXT_RATES_ID 50 ++#define DOT11_MNG_WPA_ID 221 ++#define DOT11_MNG_PROPR_ID 221 ++ ++/* ERP info element bit values */ ++#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ ++#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present in the BSS */ ++#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for ERP-OFDM frames */ ++#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, 1 == not allowed */ ++ ++/* Capability Information Field */ ++#define DOT11_CAP_ESS 0x0001 ++#define DOT11_CAP_IBSS 0x0002 ++#define DOT11_CAP_POLLABLE 0x0004 ++#define DOT11_CAP_POLL_RQ 0x0008 ++#define DOT11_CAP_PRIVACY 0x0010 ++#define DOT11_CAP_SHORT 0x0020 ++#define DOT11_CAP_PBCC 0x0040 ++#define DOT11_CAP_AGILITY 0x0080 ++#define DOT11_CAP_SPECTRUM 0x0100 ++#define DOT11_CAP_SHORTSLOT 0x0400 ++#define DOT11_CAP_CCK_OFDM 0x2000 ++ ++/* Action Frame Constants */ ++#define DOT11_ACTION_CAT_ERR_MASK 0x80 ++#define DOT11_ACTION_CAT_SPECT_MNG 0x00 ++#define DOT11_ACTION_NOTIFICATION 0x11 /* 17 */ ++ ++#define DOT11_ACTION_ID_M_REQ 0 ++#define DOT11_ACTION_ID_M_REP 1 ++#define DOT11_ACTION_ID_TPC_REQ 2 ++#define DOT11_ACTION_ID_TPC_REP 3 ++#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 ++ ++/* MLME Enumerations */ ++#define DOT11_BSSTYPE_INFRASTRUCTURE 0 ++#define DOT11_BSSTYPE_INDEPENDENT 1 ++#define DOT11_BSSTYPE_ANY 2 ++#define DOT11_SCANTYPE_ACTIVE 0 ++#define DOT11_SCANTYPE_PASSIVE 1 ++ ++/* 802.11 A PHY constants */ ++#define APHY_SLOT_TIME 9 ++#define APHY_SIFS_TIME 16 ++#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) ++#define APHY_PREAMBLE_TIME 16 ++#define APHY_SIGNAL_TIME 4 ++#define APHY_SYMBOL_TIME 4 ++#define APHY_SERVICE_NBITS 16 ++#define APHY_TAIL_NBITS 6 ++#define APHY_CWMIN 15 ++ ++/* 802.11 B PHY constants */ ++#define BPHY_SLOT_TIME 20 ++#define BPHY_SIFS_TIME 10 ++#define BPHY_DIFS_TIME 50 ++#define BPHY_PLCP_TIME 192 ++#define BPHY_PLCP_SHORT_TIME 96 ++#define BPHY_CWMIN 31 ++ ++/* 802.11 G constants */ ++#define DOT11_OFDM_SIGNAL_EXTENSION 6 ++ ++#define PHY_CWMAX 1023 ++ ++#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ ++ ++/* dot11Counters Table - 802.11 spec., Annex D */ ++typedef struct d11cnt { ++ uint32 txfrag; /* dot11TransmittedFragmentCount */ ++ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ ++ uint32 txfail; /* dot11FailedCount */ ++ uint32 txretry; /* dot11RetryCount */ ++ uint32 txretrie; /* dot11MultipleRetryCount */ ++ uint32 rxdup; /* dot11FrameduplicateCount */ ++ uint32 txrts; /* dot11RTSSuccessCount */ ++ uint32 txnocts; /* dot11RTSFailureCount */ ++ uint32 txnoack; /* dot11ACKFailureCount */ ++ uint32 rxfrag; /* dot11ReceivedFragmentCount */ ++ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ ++ uint32 rxcrc; /* dot11FCSErrorCount */ ++ uint32 txfrmsnt; /* dot11TransmittedFrameCount */ ++ uint32 rxundec; /* dot11WEPUndecryptableCount */ ++} d11cnt_t; ++ ++/* BRCM OUI */ ++#define BRCM_OUI "\x00\x10\x18" ++ ++/* BRCM info element */ ++struct brcm_ie { ++ uchar id; /* 221, DOT11_MNG_PROPR_ID */ ++ uchar len; ++ uchar oui[3]; ++ uchar ver; ++ uchar assoc; /* # of assoc STAs */ ++ uchar flags; /* misc flags */ ++} PACKED; ++#define BRCM_IE_LEN 8 ++typedef struct brcm_ie brcm_ie_t; ++#define BRCM_IE_VER 2 ++#define BRCM_IE_LEGACY_AES_VER 1 ++ ++/* brcm_ie flags */ ++#define BRF_ABCAP 0x1 /* afterburner capable */ ++#define BRF_ABRQRD 0x2 /* afterburner requested */ ++#define BRF_LZWDS 0x4 /* lazy wds enabled */ ++#define BRF_ABCOUNTER_MASK 0xf0 /* afterburner wds "state" counter */ ++#define BRF_ABCOUNTER_SHIFT 4 ++ ++#define AB_WDS_TIMEOUT_MAX 15 /* afterburner wds Max count indicating not locally capable */ ++#define AB_WDS_TIMEOUT_MIN 1 /* afterburner wds, use zero count as indicating "downrev" */ ++ ++ ++/* OUI for BRCM proprietary IE */ ++#define BRCM_PROP_OUI "\x00\x90\x4C" ++ ++/* Vendor IE structure */ ++struct vndr_ie { ++ uchar id; ++ uchar len; ++ uchar oui [3]; ++ uchar data [1]; /* Variable size data */ ++}PACKED; ++typedef struct vndr_ie vndr_ie_t; ++ ++#define VNDR_IE_HDR_LEN 2 /* id + len field */ ++#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ ++#define VNDR_IE_MAX_LEN 256 ++ ++/* WPA definitions */ ++#define WPA_VERSION 1 ++#define WPA_OUI "\x00\x50\xF2" ++ ++#ifdef BCMWPA2 ++#define WPA2_VERSION 1 ++#define WPA2_VERSION_LEN 2 ++#define WPA2_OUI "\x00\x0F\xAC" ++#endif /* BCMWPA2 */ ++ ++#define WPA_OUI_LEN 3 ++ ++/* RSN authenticated key managment suite */ ++#define RSN_AKM_NONE 0 /* None (IBSS) */ ++#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ ++#define RSN_AKM_PSK 2 /* Pre-shared Key */ ++ ++ ++/* Key related defines */ ++#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ ++#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ ++#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ ++#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ ++ ++#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ ++#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ ++#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ ++#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ ++#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ ++#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ ++#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ ++#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ ++#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ ++#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ ++#define TKIP_MIC_SUP_RX 16 /* offset to Supplicant MIC RX key */ ++#define TKIP_MIC_SUP_TX 24 /* offset to Supplicant MIC TX key */ ++#define AES_KEY_SIZE 16 /* size of AES key */ ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _802_11_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmeth.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmeth.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmeth.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmeth.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,103 @@ ++/* ++ * Broadcom Ethernettype protocol definitions ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++/* ++ * Broadcom Ethernet protocol defines ++ * ++ */ ++ ++#ifndef _BCMETH_H_ ++#define _BCMETH_H_ ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++/* ETHER_TYPE_BRCM is defined in ethernet.h */ ++ ++/* ++ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field ++ * in one of two formats: (only subtypes 32768-65535 are in use now) ++ * ++ * subtypes 0-32767: ++ * 8 bit subtype (0-127) ++ * 8 bit length in bytes (0-255) ++ * ++ * subtypes 32768-65535: ++ * 16 bit big-endian subtype ++ * 16 bit big-endian length in bytes (0-65535) ++ * ++ * length is the number of additional bytes beyond the 4 or 6 byte header ++ * ++ * Reserved values: ++ * 0 reserved ++ * 5-15 reserved for iLine protocol assignments ++ * 17-126 reserved, assignable ++ * 127 reserved ++ * 32768 reserved ++ * 32769-65534 reserved, assignable ++ * 65535 reserved ++ */ ++ ++/* ++ * While adding the subtypes and their specific processing code make sure ++ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition ++ */ ++ ++#define BCMILCP_SUBTYPE_RATE 1 ++#define BCMILCP_SUBTYPE_LINK 2 ++#define BCMILCP_SUBTYPE_CSA 3 ++#define BCMILCP_SUBTYPE_LARQ 4 ++#define BCMILCP_SUBTYPE_VENDOR 5 ++#define BCMILCP_SUBTYPE_FLH 17 ++ ++#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 ++#define BCMILCP_SUBTYPE_CERT 32770 ++#define BCMILCP_SUBTYPE_SES 32771 ++ ++ ++#define BCMILCP_BCM_SUBTYPE_RESERVED 0 ++#define BCMILCP_BCM_SUBTYPE_EVENT 1 ++#define BCMILCP_BCM_SUBTYPE_SES 2 ++/* ++The EAPOL type is not used anymore. Instead EAPOL messages are now embedded ++within BCMILCP_BCM_SUBTYPE_EVENT type messages ++*/ ++/*#define BCMILCP_BCM_SUBTYPE_EAPOL 3*/ ++ ++#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 ++#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 ++ ++/* These fields are stored in network order */ ++typedef struct bcmeth_hdr ++{ ++ uint16 subtype; /* Vendor specific..32769*/ ++ uint16 length; ++ uint8 version; /* Version is 0*/ ++ uint8 oui[3]; /* Broadcom OUI*/ ++ /* user specific Data */ ++ uint16 usr_subtype; ++} PACKED bcmeth_hdr_t; ++ ++ ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmip.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmip.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmip.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmip.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,42 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * ++ * Fundamental constants relating to IP Protocol ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmip_h_ ++#define _bcmip_h_ ++ ++/* IP header */ ++#define IPV4_VERIHL_OFFSET 0 /* version and ihl byte offset */ ++#define IPV4_TOS_OFFSET 1 /* TOS offset */ ++#define IPV4_PROT_OFFSET 9 /* protocol type offset */ ++#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ ++#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ ++#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ ++ ++#define IPV4_VER_MASK 0xf0 ++#define IPV4_IHL_MASK 0x0f ++ ++#define IPV4_PROT_UDP 17 /* UDP protocol type */ ++ ++#define IPV4_ADDR_LEN 4 /* IP v4 address length */ ++ ++#define IPV4_VER_NUM 0x40 /* IP v4 version number */ ++ ++/* NULL IP address check */ ++#define IPV4_ISNULLADDR(a) ((((uint8 *)(a))[0] + ((uint8 *)(a))[1] + \ ++ ((uint8 *)(a))[2] + ((uint8 *)(a))[3]) == 0) ++ ++#define IPV4_ADDR_STR_LEN 16 ++ ++#endif /* #ifndef _bcmip_h_ */ ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/ethernet.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/ethernet.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,169 @@ ++/******************************************************************************* ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. ++ ******************************************************************************/ ++ ++#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ ++#define _NET_ETHERNET_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include "typedefs.h" ++#endif ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++/* ++ * The number of bytes in an ethernet (MAC) address. ++ */ ++#define ETHER_ADDR_LEN 6 ++ ++/* ++ * The number of bytes in the type field. ++ */ ++#define ETHER_TYPE_LEN 2 ++ ++/* ++ * The number of bytes in the trailing CRC field. ++ */ ++#define ETHER_CRC_LEN 4 ++ ++/* ++ * The length of the combined header. ++ */ ++#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) ++ ++/* ++ * The minimum packet length. ++ */ ++#define ETHER_MIN_LEN 64 ++ ++/* ++ * The minimum packet user data length. ++ */ ++#define ETHER_MIN_DATA 46 ++ ++/* ++ * The maximum packet length. ++ */ ++#define ETHER_MAX_LEN 1518 ++ ++/* ++ * The maximum packet user data length. ++ */ ++#define ETHER_MAX_DATA 1500 ++ ++/* ether types */ ++#define ETHER_TYPE_IP 0x0800 /* IP */ ++#define ETHER_TYPE_ARP 0x0806 /* ARP */ ++#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ ++#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ ++#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ ++#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication*/ ++ ++/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ ++#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ ++#define ETHER_BRCM_CRAM 0x1 /* Broadcom subtype cram protocol */ ++ ++/* ether header */ ++#define ETHER_DEST_OFFSET 0 /* dest address offset */ ++#define ETHER_SRC_OFFSET 6 /* src address offset */ ++#define ETHER_TYPE_OFFSET 12 /* ether type offset */ ++ ++/* ++ * A macro to validate a length with ++ */ ++#define ETHER_IS_VALID_LEN(foo) \ ++ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) ++ ++ ++#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ ++/* ++ * Structure of a 10Mb/s Ethernet header. ++ */ ++struct ether_header { ++ uint8 ether_dhost[ETHER_ADDR_LEN]; ++ uint8 ether_shost[ETHER_ADDR_LEN]; ++ uint16 ether_type; ++} PACKED; ++ ++/* ++ * Structure of a 48-bit Ethernet address. ++ */ ++struct ether_addr { ++ uint8 octet[ETHER_ADDR_LEN]; ++} PACKED; ++#endif ++ ++/* ++ * Takes a pointer, sets locally admininistered ++ * address bit in the 48-bit Ethernet address. ++ */ ++#define ETHER_SET_LOCALADDR(ea) ( ((uint8 *)(ea))[0] = \ ++ (((uint8 *)(ea))[0] | 2) ) ++ ++/* ++ * Takes a pointer, returns true if a 48-bit multicast address ++ * (including broadcast, since it is all ones) ++ */ ++#define ETHER_ISMULTI(ea) (((uint8 *)(ea))[0] & 1) ++ ++ ++/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ ++#define ether_cmp(a, b) ( \ ++ !(((short*)a)[0] == ((short*)b)[0]) | \ ++ !(((short*)a)[1] == ((short*)b)[1]) | \ ++ !(((short*)a)[2] == ((short*)b)[2])) ++ ++/* copy an ethernet address - assumes the pointers can be referenced as shorts */ ++#define ether_copy(s, d) { \ ++ ((short*)d)[0] = ((short*)s)[0]; \ ++ ((short*)d)[1] = ((short*)s)[1]; \ ++ ((short*)d)[2] = ((short*)s)[2]; } ++ ++/* ++ * Takes a pointer, returns true if a 48-bit broadcast (all ones) ++ */ ++#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ ++ ((uint8 *)(ea))[1] & \ ++ ((uint8 *)(ea))[2] & \ ++ ((uint8 *)(ea))[3] & \ ++ ((uint8 *)(ea))[4] & \ ++ ((uint8 *)(ea))[5]) == 0xff) ++ ++static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; ++ ++/* ++ * Takes a pointer, returns true if a 48-bit null address (all zeros) ++ */ ++#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ ++ ((uint8 *)(ea))[1] | \ ++ ((uint8 *)(ea))[2] | \ ++ ((uint8 *)(ea))[3] | \ ++ ((uint8 *)(ea))[4] | \ ++ ((uint8 *)(ea))[5]) == 0) ++ ++/* Differentiated Services Codepoint - upper 6 bits of tos in iphdr */ ++#define DSCP_MASK 0xFC /* upper 6 bits */ ++#define DSCP_SHIFT 2 ++#define DSCP_WME_PRI_MASK 0xE0 /* upper 3 bits */ ++#define DSCP_WME_PRI_SHIFT 5 ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _NET_ETHERNET_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/vlan.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/vlan.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/vlan.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/vlan.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,50 @@ ++/* ++ * 802.1Q VLAN protocol definitions ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _vlan_h_ ++#define _vlan_h_ ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */ ++#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */ ++#define VLAN_PRI_SHIFT 13 /* user priority */ ++ ++#define VLAN_PRI_MASK 7 /* 3 bits of priority */ ++ ++#define VLAN_TAG_LEN 4 ++#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) ++ ++struct ethervlan_header { ++ uint8 ether_dhost[ETHER_ADDR_LEN]; ++ uint8 ether_shost[ETHER_ADDR_LEN]; ++ uint16 vlan_type; /* 0x8100 */ ++ uint16 vlan_tag; /* priority, cfi and vid */ ++ uint16 ether_type; ++}; ++ ++#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _vlan_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/wpa.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/wpa.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/wpa.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/wpa.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,140 @@ ++/* ++ * Fundamental types and constants relating to WPA ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _proto_wpa_h_ ++#define _proto_wpa_h_ ++ ++#include ++#include ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++/* Reason Codes */ ++ ++/* 10 and 11 are from TGh. */ ++#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ ++#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ ++/* 12 is unused */ ++/* 13 through 23 taken from P802.11i/D3.0, November 2002 */ ++#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ ++#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ ++#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ ++#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ ++#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from (re-)assoc. request/probe response */ ++#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ ++#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ ++#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ ++#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ ++#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ ++#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ ++ ++#define WPA2_PMKID_LEN 16 ++ ++/* WPA IE fixed portion */ ++typedef struct ++{ ++ uint8 tag; /* TAG */ ++ uint8 length; /* TAG length */ ++ uint8 oui[3]; /* IE OUI */ ++ uint8 oui_type; /* OUI type */ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED version; /* IE version */ ++} PACKED wpa_ie_fixed_t; ++#define WPA_IE_OUITYPE_LEN 4 ++#define WPA_IE_FIXED_LEN 8 ++#define WPA_IE_TAG_FIXED_LEN 6 ++ ++typedef struct { ++ uint8 tag; /* TAG */ ++ uint8 length; /* TAG length */ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED version; /* IE version */ ++} PACKED wpa_rsn_ie_fixed_t; ++#define WPA_RSN_IE_FIXED_LEN 4 ++#define WPA_RSN_IE_TAG_FIXED_LEN 2 ++typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; ++ ++/* WPA suite/multicast suite */ ++typedef struct ++{ ++ uint8 oui[3]; ++ uint8 type; ++} PACKED wpa_suite_t, wpa_suite_mcast_t; ++#define WPA_SUITE_LEN 4 ++ ++/* WPA unicast suite list/key management suite list */ ++typedef struct ++{ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED count; ++ wpa_suite_t list[1]; ++} PACKED wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; ++#define WPA_IE_SUITE_COUNT_LEN 2 ++typedef struct ++{ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED count; ++ wpa_pmkid_t list[1]; ++} PACKED wpa_pmkid_list_t; ++ ++/* WPA cipher suites */ ++#define WPA_CIPHER_NONE 0 /* None */ ++#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ ++#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ ++#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ ++#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ ++#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ ++ ++#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ ++ (cipher) == WPA_CIPHER_WEP_40 || \ ++ (cipher) == WPA_CIPHER_WEP_104 || \ ++ (cipher) == WPA_CIPHER_TKIP || \ ++ (cipher) == WPA_CIPHER_AES_OCB || \ ++ (cipher) == WPA_CIPHER_AES_CCM) ++ ++/* WPA TKIP countermeasures parameters */ ++#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ ++#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ ++ ++/* WPA capabilities defined in 802.11i */ ++#define WPA_CAP_4_REPLAY_CNTRS 2 ++#define WPA_CAP_16_REPLAY_CNTRS 3 ++#define WPA_CAP_REPLAY_CNTR_SHIFT 2 ++#define WPA_CAP_REPLAY_CNTR_MASK 0x000c ++ ++/* WPA Specific defines */ ++#define WPA_CAP_LEN 2 ++ ++#define WPA_CAP_WPA2_PREAUTH 1 ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _proto_wpa_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/rts/crc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/rts/crc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/rts/crc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/rts/crc.h 2005-12-16 23:39:10.928835750 +0100 +@@ -0,0 +1,69 @@ ++/******************************************************************************* ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * crc.h - a function to compute crc for iLine10 headers ++ ******************************************************************************/ ++ ++#ifndef _RTS_CRC_H_ ++#define _RTS_CRC_H_ 1 ++ ++#include "typedefs.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ ++#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ ++#define HCS_GOOD_VALUE 0x39 /* Good final header checksum value */ ++ ++#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ ++#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++ ++#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ ++#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++ ++void hcs(uint8 *, uint); ++uint8 crc8(uint8 *, uint, uint8); ++uint16 crc16(uint8 *, uint, uint16); ++uint32 crc32(uint8 *, uint, uint32); ++ ++/* macros for common usage */ ++ ++#define APPEND_CRC8(pbytes, nbytes) \ ++do { \ ++ uint8 tmp = crc8(pbytes, nbytes, CRC8_INIT_VALUE) ^ 0xff; \ ++ (pbytes)[(nbytes)] = tmp; \ ++ (nbytes) += 1; \ ++} while (0) ++ ++#define APPEND_CRC16(pbytes, nbytes) \ ++do { \ ++ uint16 tmp = crc16(pbytes, nbytes, CRC16_INIT_VALUE) ^ 0xffff; \ ++ (pbytes)[(nbytes) + 0] = (tmp >> 0) & 0xff; \ ++ (pbytes)[(nbytes) + 1] = (tmp >> 8) & 0xff; \ ++ (nbytes) += 2; \ ++} while (0) ++ ++#define APPEND_CRC32(pbytes, nbytes) \ ++do { \ ++ uint32 tmp = crc32(pbytes, nbytes, CRC32_INIT_VALUE) ^ 0xffffffff; \ ++ (pbytes)[(nbytes) + 0] = (tmp >> 0) & 0xff; \ ++ (pbytes)[(nbytes) + 1] = (tmp >> 8) & 0xff; \ ++ (pbytes)[(nbytes) + 2] = (tmp >> 16) & 0xff; \ ++ (pbytes)[(nbytes) + 3] = (tmp >> 24) & 0xff; \ ++ (nbytes) += 4; \ ++} while (0) ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _RTS_CRC_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,440 @@ ++/* ++ * SiliconBackplane Chipcommon core hardware definitions. ++ * ++ * The chipcommon core provides chip identification, SB control, ++ * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, ++ * gpio interface, extbus, and support for serial and parallel flashes. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#ifndef _SBCHIPC_H ++#define _SBCHIPC_H ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++typedef volatile struct { ++ uint32 chipid; /* 0x0 */ ++ uint32 capabilities; ++ uint32 corecontrol; /* corerev >= 1 */ ++ uint32 bist; ++ ++ /* OTP */ ++ uint32 otpstatus; /* 0x10, corerev >= 10 */ ++ uint32 otpcontrol; ++ uint32 otpprog; ++ uint32 PAD; ++ ++ /* Interrupt control */ ++ uint32 intstatus; /* 0x20 */ ++ uint32 intmask; ++ uint32 chipcontrol; /* 0x28, rev >= 11 */ ++ uint32 chipstatus; /* 0x2c, rev >= 11 */ ++ ++ /* Jtag Master */ ++ uint32 jtagcmd; /* 0x30, rev >= 10 */ ++ uint32 jtagir; ++ uint32 jtagdr; ++ uint32 jtagctrl; ++ ++ /* serial flash interface registers */ ++ uint32 flashcontrol; /* 0x40 */ ++ uint32 flashaddress; ++ uint32 flashdata; ++ uint32 PAD[1]; ++ ++ /* Silicon backplane configuration broadcast control */ ++ uint32 broadcastaddress; /* 0x50 */ ++ uint32 broadcastdata; ++ uint32 PAD[2]; ++ ++ /* gpio - cleared only by power-on-reset */ ++ uint32 gpioin; /* 0x60 */ ++ uint32 gpioout; ++ uint32 gpioouten; ++ uint32 gpiocontrol; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[2]; ++ ++ /* Watchdog timer */ ++ uint32 watchdog; /* 0x80 */ ++ uint32 PAD[1]; ++ ++ /*GPIO based LED powersave registers corerev >= 16*/ ++ uint32 gpiotimerval; /*0x88 */ ++ uint32 gpiotimeroutmask; ++ ++ /* clock control */ ++ uint32 clockcontrol_n; /* 0x90 */ ++ uint32 clockcontrol_sb; /* aka m0 */ ++ uint32 clockcontrol_pci; /* aka m1 */ ++ uint32 clockcontrol_m2; /* mii/uart/mipsref */ ++ uint32 clockcontrol_mips; /* aka m3 */ ++ uint32 clkdiv; /* corerev >= 3 */ ++ uint32 PAD[2]; ++ ++ /* pll delay registers (corerev >= 4) */ ++ uint32 pll_on_delay; /* 0xb0 */ ++ uint32 fref_sel_delay; ++ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ ++ uint32 PAD[1]; ++ ++ /* Instaclock registers (corerev >= 10) */ ++ uint32 system_clk_ctl; /* 0xc0 */ ++ uint32 clkstatestretch; ++ uint32 PAD[14]; ++ ++ /* ExtBus control registers (corerev >= 3) */ ++ uint32 pcmcia_config; /* 0x100 */ ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ uint32 ide_config; ++ uint32 ide_memwait; ++ uint32 ide_attrwait; ++ uint32 ide_iowait; ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[116]; ++ ++ /* uarts */ ++ uint8 uart0data; /* 0x300 */ ++ uint8 uart0imr; ++ uint8 uart0fcr; ++ uint8 uart0lcr; ++ uint8 uart0mcr; ++ uint8 uart0lsr; ++ uint8 uart0msr; ++ uint8 uart0scratch; ++ uint8 PAD[248]; /* corerev >= 1 */ ++ ++ uint8 uart1data; /* 0x400 */ ++ uint8 uart1imr; ++ uint8 uart1fcr; ++ uint8 uart1lcr; ++ uint8 uart1mcr; ++ uint8 uart1lsr; ++ uint8 uart1msr; ++ uint8 uart1scratch; ++} chipcregs_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#define CC_CHIPID 0 ++#define CC_CAPABILITIES 4 ++#define CC_JTAGCMD 0x30 ++#define CC_JTAGIR 0x34 ++#define CC_JTAGDR 0x38 ++#define CC_JTAGCTRL 0x3c ++#define CC_WATCHDOG 0x80 ++#define CC_CLKC_N 0x90 ++#define CC_CLKC_M0 0x94 ++#define CC_CLKC_M1 0x98 ++#define CC_CLKC_M2 0x9c ++#define CC_CLKC_M3 0xa0 ++#define CC_CLKDIV 0xa4 ++#define CC_SYS_CLK_CTL 0xc0 ++#define CC_OTP 0x800 ++ ++/* chipid */ ++#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ ++#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ ++#define CID_REV_SHIFT 16 /* Chip Revision shift */ ++#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ ++#define CID_PKG_SHIFT 20 /* Package Option shift */ ++#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ ++#define CID_CC_SHIFT 24 ++ ++/* capabilities */ ++#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */ ++#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ ++#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */ ++#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ ++#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */ ++#define CAP_EXTBUS 0x00000040 /* External bus present */ ++#define CAP_FLASH_MASK 0x00000700 /* Type of flash */ ++#define CAP_PLL_MASK 0x00038000 /* Type of PLL */ ++#define CAP_PWR_CTL 0x00040000 /* Power control */ ++#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ ++#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ ++#define CAP_OTPSIZE_BASE 5 /* OTP Size base */ ++#define CAP_JTAGP 0x00400000 /* JTAG Master Present */ ++#define CAP_ROM 0x00800000 /* Internal boot rom active */ ++ ++/* PLL type */ ++#define PLL_NONE 0x00000000 ++#define PLL_TYPE1 0x00010000 /* 48Mhz base, 3 dividers */ ++#define PLL_TYPE2 0x00020000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE3 0x00030000 /* 25Mhz, 2 dividers */ ++#define PLL_TYPE4 0x00008000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE5 0x00018000 /* 25Mhz, 4 dividers */ ++#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ ++#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */ ++ ++/* corecontrol */ ++#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ ++#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ ++ ++/* Fields in the otpstatus register */ ++#define OTPS_PROGFAIL 0x80000000 ++#define OTPS_PROTECT 0x00000007 ++#define OTPS_HW_PROTECT 0x00000001 ++#define OTPS_SW_PROTECT 0x00000002 ++#define OTPS_CID_PROTECT 0x00000004 ++ ++/* Fields in the otpcontrol register */ ++#define OTPC_RECWAIT 0xff000000 ++#define OTPC_PROGWAIT 0x00ffff00 ++#define OTPC_PRW_SHIFT 8 ++#define OTPC_MAXFAIL 0x00000038 ++#define OTPC_VSEL 0x00000006 ++#define OTPC_SELVL 0x00000001 ++ ++/* Fields in otpprog */ ++#define OTPP_COL_MASK 0x000000ff ++#define OTPP_ROW_MASK 0x0000ff00 ++#define OTPP_ROW_SHIFT 8 ++#define OTPP_READERR 0x10000000 ++#define OTPP_VALUE 0x20000000 ++#define OTPP_VALUE_SHIFT 29 ++#define OTPP_READ 0x40000000 ++#define OTPP_START 0x80000000 ++#define OTPP_BUSY 0x80000000 ++ ++/* jtagcmd */ ++#define JCMD_START 0x80000000 ++#define JCMD_BUSY 0x80000000 ++#define JCMD_PAUSE 0x40000000 ++#define JCMD0_ACC_MASK 0x0000f000 ++#define JCMD0_ACC_IRDR 0x00000000 ++#define JCMD0_ACC_DR 0x00001000 ++#define JCMD0_ACC_IR 0x00002000 ++#define JCMD0_ACC_RESET 0x00003000 ++#define JCMD0_ACC_IRPDR 0x00004000 ++#define JCMD0_ACC_PDR 0x00005000 ++#define JCMD0_IRW_MASK 0x00000f00 ++#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ ++#define JCMD_ACC_IRDR 0x00000000 ++#define JCMD_ACC_DR 0x00010000 ++#define JCMD_ACC_IR 0x00020000 ++#define JCMD_ACC_RESET 0x00030000 ++#define JCMD_ACC_IRPDR 0x00040000 ++#define JCMD_ACC_PDR 0x00050000 ++#define JCMD_IRW_MASK 0x00001f00 ++#define JCMD_IRW_SHIFT 8 ++#define JCMD_DRW_MASK 0x0000003f ++ ++/* jtagctrl */ ++#define JCTRL_FORCE_CLK 4 /* Force clock */ ++#define JCTRL_EXT_EN 2 /* Enable external targets */ ++#define JCTRL_EN 1 /* Enable Jtag master */ ++ ++/* Fields in clkdiv */ ++#define CLKD_SFLASH 0x0f000000 ++#define CLKD_SFLASH_SHIFT 24 ++#define CLKD_OTP 0x000f0000 ++#define CLKD_OTP_SHIFT 16 ++#define CLKD_JTAG 0x00000f00 ++#define CLKD_JTAG_SHIFT 8 ++#define CLKD_UART 0x000000ff ++ ++/* intstatus/intmask */ ++#define CI_GPIO 0x00000001 /* gpio intr */ ++#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */ ++#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ ++ ++/* slow_clk_ctl */ ++#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ ++#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ ++#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ ++#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ ++#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ ++#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ ++#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ ++#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */ ++#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */ ++#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ ++#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ ++#define SCC_CD_SHIFT 16 ++ ++/* system_clk_ctl */ ++#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ ++#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ ++#define SYCC_FP 0x00000004 /* ForcePLLOn */ ++#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ ++#define SYCC_HR 0x00000010 /* Force HT */ ++#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4+divisor)) */ ++#define SYCC_CD_SHIFT 16 ++ ++/* gpiotimerval*/ ++#define GPIO_ONTIME_SHIFT 16 ++ ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++#define CN_PLLC_MASK 0xf0000 /* pll control */ ++#define CN_PLLC_SHIFT 16 ++ ++/* clockcontrol_sb/pci/uart */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 ++ ++/* N3M Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 ++ ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++ ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 ++ ++/* Type 2 Clock control magic field values */ ++#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ ++#define CC_T2M2_BIAS 3 /* m2 bias */ ++ ++#define CC_T2MC_M1BYP 1 ++#define CC_T2MC_M2BYP 2 ++#define CC_T2MC_M3BYP 4 ++ ++/* Type 6 Clock control magic field values */ ++#define CC_T6_MMASK 1 /* bits of interest in m */ ++#define CC_T6_M0 120000000 /* sb clock for m = 0 */ ++#define CC_T6_M1 100000000 /* sb clock for m = 1 */ ++#define SB2MIPS_T6(sb) (2 * (sb)) ++ ++/* Common clock base */ ++#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ ++#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLL's */ ++ ++/* Clock control values for 200Mhz in 5350 */ ++#define CLKC_5350_N 0x0311 ++#define CLKC_5350_M 0x04020009 ++ ++/* Flash types in the chipcommon capabilities register */ ++#define FLASH_NONE 0x000 /* No flash */ ++#define SFLASH_ST 0x100 /* ST serial flash */ ++#define SFLASH_AT 0x200 /* Atmel serial flash */ ++#define PFLASH 0x700 /* Parallel flash */ ++ ++/* Bits in the config registers */ ++#define CC_CFG_EN 0x0001 /* Enable */ ++#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ ++#define CC_CFG_EM_ASYNC 0x0002 /* Async/Parallel flash */ ++#define CC_CFG_EM_SYNC 0x0004 /* Synchronous */ ++#define CC_CFG_EM_PCMCIA 0x0008 /* PCMCIA */ ++#define CC_CFG_EM_IDE 0x000a /* IDE */ ++#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ ++#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */ ++#define CC_CFG_CE 0x0080 /* Sync: Clock enable */ ++#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */ ++ ++/* Start/busy bit in flashcontrol */ ++#define SFLASH_START 0x80000000 ++#define SFLASH_BUSY SFLASH_START ++ ++/* flashcontrol opcodes for ST flashes */ ++#define SFLASH_ST_WREN 0x0006 /* Write Enable */ ++#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ ++#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ ++#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ ++#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ ++#define SFLASH_ST_PP 0x0302 /* Page Program */ ++#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ ++#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ ++#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ ++#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ ++ ++/* Status register bits for ST flashes */ ++#define SFLASH_ST_WIP 0x01 /* Write In Progress */ ++#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ ++#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ ++#define SFLASH_ST_BP_SHIFT 2 ++#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ ++ ++/* flashcontrol opcodes for Atmel flashes */ ++#define SFLASH_AT_READ 0x07e8 ++#define SFLASH_AT_PAGE_READ 0x07d2 ++#define SFLASH_AT_BUF1_READ ++#define SFLASH_AT_BUF2_READ ++#define SFLASH_AT_STATUS 0x01d7 ++#define SFLASH_AT_BUF1_WRITE 0x0384 ++#define SFLASH_AT_BUF2_WRITE 0x0387 ++#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 ++#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 ++#define SFLASH_AT_BUF1_PROGRAM 0x0288 ++#define SFLASH_AT_BUF2_PROGRAM 0x0289 ++#define SFLASH_AT_PAGE_ERASE 0x0281 ++#define SFLASH_AT_BLOCK_ERASE 0x0250 ++#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 ++#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 ++#define SFLASH_AT_BUF1_LOAD 0x0253 ++#define SFLASH_AT_BUF2_LOAD 0x0255 ++#define SFLASH_AT_BUF1_COMPARE 0x0260 ++#define SFLASH_AT_BUF2_COMPARE 0x0261 ++#define SFLASH_AT_BUF1_REPROGRAM 0x0258 ++#define SFLASH_AT_BUF2_REPROGRAM 0x0259 ++ ++/* Status register bits for Atmel flashes */ ++#define SFLASH_AT_READY 0x80 ++#define SFLASH_AT_MISMATCH 0x40 ++#define SFLASH_AT_ID_MASK 0x38 ++#define SFLASH_AT_ID_SHIFT 3 ++ ++/* OTP regions */ ++#define OTP_HW_REGION OTPS_HW_PROTECT ++#define OTP_SW_REGION OTPS_SW_PROTECT ++#define OTP_CID_REGION OTPS_CID_PROTECT ++ ++/* OTP regions (Byte offsets from otp size) */ ++#define OTP_SWLIM_OFF (-8) ++#define OTP_CIDBASE_OFF 0 ++#define OTP_CIDLIM_OFF 8 ++ ++/* Predefined OTP words (Word offset from otp size) */ ++#define OTP_BOUNDARY_OFF (-4) ++#define OTP_HWSIGN_OFF (-3) ++#define OTP_SWSIGN_OFF (-2) ++#define OTP_CIDSIGN_OFF (-1) ++ ++#define OTP_CID_OFF 0 ++#define OTP_PKG_OFF 1 ++#define OTP_FID_OFF 2 ++#define OTP_RSV_OFF 3 ++#define OTP_LIM_OFF 4 ++ ++#define OTP_SIGNATURE 0x578a ++#define OTP_MAGIC 0x4e56 ++ ++#endif /* _SBCHIPC_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,342 @@ ++/* ++ * Broadcom SiliconBackplane hardware register definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBCONFIG_H ++#define _SBCONFIG_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* ++ * SiliconBackplane Address Map. ++ * All regions may not exist on all chips. ++ */ ++#define SB_SDRAM_BASE 0x00000000 /* Physical SDRAM */ ++#define SB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ ++#define SB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ ++#define SB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define SB_ENUM_BASE 0x18000000 /* Enumeration space base */ ++#define SB_ENUM_LIM 0x18010000 /* Enumeration space limit */ ++ ++#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ ++#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ ++ ++#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */ ++#define SB_FLASH1 0x1fc00000 /* Flash Region 1 */ ++#define SB_FLASH1_SZ 0x00400000 /* Size of Flash Region 1 */ ++ ++#define SB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ ++#define SB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ ++#define SB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */ ++#define SB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ ++#define SB_EUART (SB_EXTIF_BASE + 0x00800000) ++#define SB_LED (SB_EXTIF_BASE + 0x00900000) ++ ++ ++/* enumeration space related defs */ ++#define SB_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ ++#define SB_MAXCORES ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE) ++#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ ++#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ ++ ++/* mips address */ ++#define SB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++/* ++ * Sonics Configuration Space Registers. ++ */ ++#define SBIPSFLAG 0x08 ++#define SBTPSFLAG 0x18 ++#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ ++#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ ++#define SBADMATCH3 0x60 ++#define SBADMATCH2 0x68 ++#define SBADMATCH1 0x70 ++#define SBIMSTATE 0x90 ++#define SBINTVEC 0x94 ++#define SBTMSTATELOW 0x98 ++#define SBTMSTATEHIGH 0x9c ++#define SBBWA0 0xa0 ++#define SBIMCONFIGLOW 0xa8 ++#define SBIMCONFIGHIGH 0xac ++#define SBADMATCH0 0xb0 ++#define SBTMCONFIGLOW 0xb8 ++#define SBTMCONFIGHIGH 0xbc ++#define SBBCONFIG 0xc0 ++#define SBBSTATE 0xc8 ++#define SBACTCNFG 0xd8 ++#define SBFLAGST 0xe8 ++#define SBIDLOW 0xf8 ++#define SBIDHIGH 0xfc ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++typedef volatile struct _sbconfig { ++ uint32 PAD[2]; ++ uint32 sbipsflag; /* initiator port ocp slave flag */ ++ uint32 PAD[3]; ++ uint32 sbtpsflag; /* target port ocp slave flag */ ++ uint32 PAD[11]; ++ uint32 sbtmerrloga; /* (sonics >= 2.3) */ ++ uint32 PAD; ++ uint32 sbtmerrlog; /* (sonics >= 2.3) */ ++ uint32 PAD[3]; ++ uint32 sbadmatch3; /* address match3 */ ++ uint32 PAD; ++ uint32 sbadmatch2; /* address match2 */ ++ uint32 PAD; ++ uint32 sbadmatch1; /* address match1 */ ++ uint32 PAD[7]; ++ uint32 sbimstate; /* initiator agent state */ ++ uint32 sbintvec; /* interrupt mask */ ++ uint32 sbtmstatelow; /* target state */ ++ uint32 sbtmstatehigh; /* target state */ ++ uint32 sbbwa0; /* bandwidth allocation table0 */ ++ uint32 PAD; ++ uint32 sbimconfiglow; /* initiator configuration */ ++ uint32 sbimconfighigh; /* initiator configuration */ ++ uint32 sbadmatch0; /* address match0 */ ++ uint32 PAD; ++ uint32 sbtmconfiglow; /* target configuration */ ++ uint32 sbtmconfighigh; /* target configuration */ ++ uint32 sbbconfig; /* broadcast configuration */ ++ uint32 PAD; ++ uint32 sbbstate; /* broadcast state */ ++ uint32 PAD[3]; ++ uint32 sbactcnfg; /* activate configuration */ ++ uint32 PAD[3]; ++ uint32 sbflagst; /* current sbflags */ ++ uint32 PAD[3]; ++ uint32 sbidlow; /* identification */ ++ uint32 sbidhigh; /* identification */ ++} sbconfig_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* sbipsflag */ ++#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ ++#define SBIPS_INT1_SHIFT 0 ++#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ ++#define SBIPS_INT2_SHIFT 8 ++#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ ++#define SBIPS_INT3_SHIFT 16 ++#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ ++#define SBIPS_INT4_SHIFT 24 ++ ++/* sbtpsflag */ ++#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ ++#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ ++ ++/* sbtmerrlog */ ++#define SBTMEL_CM 0x00000007 /* command */ ++#define SBTMEL_CI 0x0000ff00 /* connection id */ ++#define SBTMEL_EC 0x0f000000 /* error code */ ++#define SBTMEL_ME 0x80000000 /* multiple error */ ++ ++/* sbimstate */ ++#define SBIM_PC 0xf /* pipecount */ ++#define SBIM_AP_MASK 0x30 /* arbitration policy */ ++#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ ++#define SBIM_AP_TS 0x10 /* use timesliaces only */ ++#define SBIM_AP_TK 0x20 /* use token only */ ++#define SBIM_AP_RSV 0x30 /* reserved */ ++#define SBIM_IBE 0x20000 /* inbanderror */ ++#define SBIM_TO 0x40000 /* timeout */ ++#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ ++#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ ++ ++/* sbtmstatelow */ ++#define SBTML_RESET 0x1 /* reset */ ++#define SBTML_REJ_MASK 0x6 /* reject */ ++#define SBTML_REJ_SHIFT 1 ++#define SBTML_CLK 0x10000 /* clock enable */ ++#define SBTML_FGC 0x20000 /* force gated clocks on */ ++#define SBTML_FL_MASK 0x3ffc0000 /* core-specific flags */ ++#define SBTML_PE 0x40000000 /* pme enable */ ++#define SBTML_BE 0x80000000 /* bist enable */ ++ ++/* sbtmstatehigh */ ++#define SBTMH_SERR 0x1 /* serror */ ++#define SBTMH_INT 0x2 /* interrupt */ ++#define SBTMH_BUSY 0x4 /* busy */ ++#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */ ++#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */ ++#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */ ++#define SBTMH_GCR 0x20000000 /* gated clock request */ ++#define SBTMH_BISTF 0x40000000 /* bist failed */ ++#define SBTMH_BISTD 0x80000000 /* bist done */ ++ ++ ++/* sbbwa0 */ ++#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ ++#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ ++#define SBBWA_TAB1_SHIFT 16 ++ ++/* sbimconfiglow */ ++#define SBIMCL_STO_MASK 0x7 /* service timeout */ ++#define SBIMCL_RTO_MASK 0x70 /* request timeout */ ++#define SBIMCL_RTO_SHIFT 4 ++#define SBIMCL_CID_MASK 0xff0000 /* connection id */ ++#define SBIMCL_CID_SHIFT 16 ++ ++/* sbimconfighigh */ ++#define SBIMCH_IEM_MASK 0xc /* inband error mode */ ++#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ ++#define SBIMCH_TEM_SHIFT 4 ++#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ ++#define SBIMCH_BEM_SHIFT 6 ++ ++/* sbadmatch0 */ ++#define SBAM_TYPE_MASK 0x3 /* address type */ ++#define SBAM_AD64 0x4 /* reserved */ ++#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ ++#define SBAM_ADINT0_SHIFT 3 ++#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ ++#define SBAM_ADINT1_SHIFT 3 ++#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ ++#define SBAM_ADINT2_SHIFT 3 ++#define SBAM_ADEN 0x400 /* enable */ ++#define SBAM_ADNEG 0x800 /* negative decode */ ++#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ ++#define SBAM_BASE0_SHIFT 8 ++#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ ++#define SBAM_BASE1_SHIFT 12 ++#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ ++#define SBAM_BASE2_SHIFT 16 ++ ++/* sbtmconfiglow */ ++#define SBTMCL_CD_MASK 0xff /* clock divide */ ++#define SBTMCL_CO_MASK 0xf800 /* clock offset */ ++#define SBTMCL_CO_SHIFT 11 ++#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ ++#define SBTMCL_IF_SHIFT 18 ++#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ ++#define SBTMCL_IM_SHIFT 24 ++ ++/* sbtmconfighigh */ ++#define SBTMCH_BM_MASK 0x3 /* busy mode */ ++#define SBTMCH_RM_MASK 0x3 /* retry mode */ ++#define SBTMCH_RM_SHIFT 2 ++#define SBTMCH_SM_MASK 0x30 /* stop mode */ ++#define SBTMCH_SM_SHIFT 4 ++#define SBTMCH_EM_MASK 0x300 /* sb error mode */ ++#define SBTMCH_EM_SHIFT 8 ++#define SBTMCH_IM_MASK 0xc00 /* int mode */ ++#define SBTMCH_IM_SHIFT 10 ++ ++/* sbbconfig */ ++#define SBBC_LAT_MASK 0x3 /* sb latency */ ++#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ ++#define SBBC_MAX0_SHIFT 16 ++#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ ++#define SBBC_MAX1_SHIFT 20 ++ ++/* sbbstate */ ++#define SBBS_SRD 0x1 /* st reg disable */ ++#define SBBS_HRD 0x2 /* hold reg disable */ ++ ++/* sbidlow */ ++#define SBIDL_CS_MASK 0x3 /* config space */ ++#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ ++#define SBIDL_AR_SHIFT 3 ++#define SBIDL_SYNCH 0x40 /* sync */ ++#define SBIDL_INIT 0x80 /* initiator */ ++#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ ++#define SBIDL_MINLAT_SHIFT 8 ++#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ ++#define SBIDL_MAXLAT_SHIFT 12 ++#define SBIDL_FIRST 0x10000 /* this initiator is first */ ++#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ ++#define SBIDL_CW_SHIFT 18 ++#define SBIDL_TP_MASK 0xf00000 /* target ports */ ++#define SBIDL_TP_SHIFT 20 ++#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ ++#define SBIDL_IP_SHIFT 24 ++#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ ++#define SBIDL_RV_SHIFT 28 ++#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ ++#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ ++ ++/* sbidhigh */ ++#define SBIDH_RC_MASK 0x000f /* revision code */ ++#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ ++#define SBIDH_RCE_SHIFT 8 ++#define SBCOREREV(sbidh) \ ++ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) ++#define SBIDH_CC_MASK 0x8ff0 /* core code */ ++#define SBIDH_CC_SHIFT 4 ++#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ ++#define SBIDH_VC_SHIFT 16 ++ ++#define SB_COMMIT 0xfd8 /* update buffered registers value */ ++ ++/* vendor codes */ ++#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ ++ ++/* core codes */ ++#define SB_CC 0x800 /* chipcommon core */ ++#define SB_ILINE20 0x801 /* iline20 core */ ++#define SB_SDRAM 0x803 /* sdram core */ ++#define SB_PCI 0x804 /* pci core */ ++#define SB_MIPS 0x805 /* mips core */ ++#define SB_ENET 0x806 /* enet mac core */ ++#define SB_CODEC 0x807 /* v90 codec core */ ++#define SB_USB 0x808 /* usb 1.1 host/device core */ ++#define SB_ADSL 0x809 /* ADSL core */ ++#define SB_ILINE100 0x80a /* iline100 core */ ++#define SB_IPSEC 0x80b /* ipsec core */ ++#define SB_PCMCIA 0x80d /* pcmcia core */ ++#define SB_SOCRAM 0x80e /* internal memory core */ ++#define SB_MEMC 0x80f /* memc sdram core */ ++#define SB_EXTIF 0x811 /* external interface core */ ++#define SB_D11 0x812 /* 802.11 MAC core */ ++#define SB_MIPS33 0x816 /* mips3302 core */ ++#define SB_USB11H 0x817 /* usb 1.1 host core */ ++#define SB_USB11D 0x818 /* usb 1.1 device core */ ++#define SB_USB20H 0x819 /* usb 2.0 host core */ ++#define SB_USB20D 0x81a /* usb 2.0 device core */ ++#define SB_SDIOH 0x81b /* sdio host core */ ++#define SB_ROBO 0x81c /* roboswitch core */ ++#define SB_ATA100 0x81d /* parallel ATA core */ ++#define SB_SATAXOR 0x81e /* serial ATA & XOR DMA core */ ++#define SB_GIGETH 0x81f /* gigabit ethernet core */ ++#define SB_PCIE 0x820 /* pci express core */ ++#define SB_SRAMC 0x822 /* SRAM controller core */ ++#define SB_MINIMAC 0x823 /* MINI MAC/phy core */ ++ ++#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */ ++ ++/* Not really related to Silicon Backplane, but a couple of software ++ * conventions for the use the flash space: ++ */ ++ ++/* Minumum amount of flash we support */ ++#define FLASH_MIN 0x00020000 /* Minimum flash size */ ++ ++/* A boot/binary may have an embedded block that describes its size */ ++#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ ++#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ ++#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ ++#define BISZ_TXTST_IDX 1 /* 1: text start */ ++#define BISZ_TXTEND_IDX 2 /* 2: text start */ ++#define BISZ_DATAST_IDX 3 /* 3: text start */ ++#define BISZ_DATAEND_IDX 4 /* 4: text start */ ++#define BISZ_BSSST_IDX 5 /* 5: text start */ ++#define BISZ_BSSEND_IDX 6 /* 6: text start */ ++#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ ++ ++#endif /* _SBCONFIG_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,242 @@ ++/* ++ * Hardware-specific External Interface I/O core definitions ++ * for the BCM47xx family of SiliconBackplane-based chips. ++ * ++ * The External Interface core supports a total of three external chip selects ++ * supporting external interfaces. One of the external chip selects is ++ * used for Flash, one is used for PCMCIA, and the other may be ++ * programmed to support either a synchronous interface or an ++ * asynchronous interface. The asynchronous interface can be used to ++ * support external devices such as UARTs and the BCM2019 Bluetooth ++ * baseband processor. ++ * The external interface core also contains 2 on-chip 16550 UARTs, clock ++ * frequency control, a watchdog interrupt timer, and a GPIO interface. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBEXTIF_H ++#define _SBEXTIF_H ++ ++/* external interface address space */ ++#define EXTIF_PCMCIA_MEMBASE(x) (x) ++#define EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000) ++#define EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000) ++#define EXTIF_CFGIF_BASE(x) ((x) + 0x800000) ++#define EXTIF_FLASH_BASE(x) ((x) + 0xc00000) ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * The multiple instances of output and output enable registers ++ * are present to allow driver software for multiple cores to control ++ * gpio outputs without needing to share a single register pair. ++ */ ++struct gpiouser { ++ uint32 out; ++ uint32 outen; ++}; ++#define NGPIOUSER 5 ++ ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 extstatus; ++ uint32 PAD[2]; ++ ++ /* pcmcia control registers */ ++ uint32 pcmcia_config; ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ ++ /* programmable interface control registers */ ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ ++ /* flash control registers */ ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[4]; ++ ++ uint32 watchdog; ++ ++ /* clock control */ ++ uint32 clockcontrol_n; ++ uint32 clockcontrol_sb; ++ uint32 clockcontrol_pci; ++ uint32 clockcontrol_mii; ++ uint32 PAD[3]; ++ ++ /* gpio */ ++ uint32 gpioin; ++ struct gpiouser gpio[NGPIOUSER]; ++ uint32 PAD; ++ uint32 ejtagouten; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[153]; ++ ++ uint8 uartdata; ++ uint8 PAD[3]; ++ uint8 uartimer; ++ uint8 PAD[3]; ++ uint8 uartfcr; ++ uint8 PAD[3]; ++ uint8 uartlcr; ++ uint8 PAD[3]; ++ uint8 uartmcr; ++ uint8 PAD[3]; ++ uint8 uartlsr; ++ uint8 PAD[3]; ++ uint8 uartmsr; ++ uint8 PAD[3]; ++ uint8 uartscratch; ++ uint8 PAD[3]; ++} extifregs_t; ++ ++/* corecontrol */ ++#define CC_UE (1 << 0) /* uart enable */ ++ ++/* extstatus */ ++#define ES_EM (1 << 0) /* endian mode (ro) */ ++#define ES_EI (1 << 1) /* external interrupt pin (ro) */ ++#define ES_GI (1 << 2) /* gpio interrupt pin (ro) */ ++ ++/* gpio bit mask */ ++#define GPIO_BIT0 (1 << 0) ++#define GPIO_BIT1 (1 << 1) ++#define GPIO_BIT2 (1 << 2) ++#define GPIO_BIT3 (1 << 3) ++#define GPIO_BIT4 (1 << 4) ++#define GPIO_BIT5 (1 << 5) ++#define GPIO_BIT6 (1 << 6) ++#define GPIO_BIT7 (1 << 7) ++ ++ ++/* pcmcia/prog/flash_config */ ++#define CF_EN (1 << 0) /* enable */ ++#define CF_EM_MASK 0xe /* mode */ ++#define CF_EM_SHIFT 1 ++#define CF_EM_FLASH 0x0 /* flash/asynchronous mode */ ++#define CF_EM_SYNC 0x2 /* synchronous mode */ ++#define CF_EM_PCMCIA 0x4 /* pcmcia mode */ ++#define CF_DS (1 << 4) /* destsize: 0=8bit, 1=16bit */ ++#define CF_BS (1 << 5) /* byteswap */ ++#define CF_CD_MASK 0xc0 /* clock divider */ ++#define CF_CD_SHIFT 6 ++#define CF_CD_DIV2 0x0 /* backplane/2 */ ++#define CF_CD_DIV3 0x40 /* backplane/3 */ ++#define CF_CD_DIV4 0x80 /* backplane/4 */ ++#define CF_CE (1 << 8) /* clock enable */ ++#define CF_SB (1 << 9) /* size/bytestrobe (synch only) */ ++ ++/* pcmcia_memwait */ ++#define PM_W0_MASK 0x3f /* waitcount0 */ ++#define PM_W1_MASK 0x1f00 /* waitcount1 */ ++#define PM_W1_SHIFT 8 ++#define PM_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PM_W2_SHIFT 16 ++#define PM_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PM_W3_SHIFT 24 ++ ++/* pcmcia_attrwait */ ++#define PA_W0_MASK 0x3f /* waitcount0 */ ++#define PA_W1_MASK 0x1f00 /* waitcount1 */ ++#define PA_W1_SHIFT 8 ++#define PA_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PA_W2_SHIFT 16 ++#define PA_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PA_W3_SHIFT 24 ++ ++/* pcmcia_iowait */ ++#define PI_W0_MASK 0x3f /* waitcount0 */ ++#define PI_W1_MASK 0x1f00 /* waitcount1 */ ++#define PI_W1_SHIFT 8 ++#define PI_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PI_W2_SHIFT 16 ++#define PI_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PI_W3_SHIFT 24 ++ ++/* prog_waitcount */ ++#define PW_W0_MASK 0x0000001f /* waitcount0 */ ++#define PW_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PW_W1_SHIFT 8 ++#define PW_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PW_W2_SHIFT 16 ++#define PW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PW_W3_SHIFT 24 ++ ++#define PW_W0 0x0000000c ++#define PW_W1 0x00000a00 ++#define PW_W2 0x00020000 ++#define PW_W3 0x01000000 ++ ++/* flash_waitcount */ ++#define FW_W0_MASK 0x1f /* waitcount0 */ ++#define FW_W1_MASK 0x1f00 /* waitcount1 */ ++#define FW_W1_SHIFT 8 ++#define FW_W2_MASK 0x1f0000 /* waitcount2 */ ++#define FW_W2_SHIFT 16 ++#define FW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define FW_W3_SHIFT 24 ++ ++/* watchdog */ ++#define WATCHDOG_CLOCK 48000000 /* Hz */ ++ ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++ ++/* clockcontrol_sb/pci/mii */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 ++ ++/* Clock control default values */ ++#define CC_DEF_N 0x0009 /* Default values for bcm4710 */ ++#define CC_DEF_100 0x04020011 ++#define CC_DEF_33 0x11030011 ++#define CC_DEF_25 0x11050011 ++ ++/* Clock control values for 125Mhz */ ++#define CC_125_N 0x0802 ++#define CC_125_M 0x04020009 ++#define CC_125_M25 0x11090009 ++#define CC_125_M33 0x11090005 ++ ++/* Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 ++ ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++ ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 ++ ++#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ ++ ++#endif /* _SBEXTIF_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,312 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _sbhnddma_h_ ++#define _sbhnddma_h_ ++ ++ ++/* 2byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint16 fifocontrol; ++ uint16 fifodata; ++ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */ ++ uint16 PAD; ++} pio2regs_t; ++ ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio2regs_t tx; ++ pio2regs_t rx; ++} pio2regp_t; ++ ++/* 4byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 fifocontrol; ++ uint32 fifodata; ++} pio4regs_t; ++ ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio4regs_t tx; ++ pio4regs_t rx; ++} pio4regp_t; ++ ++ ++ ++/* DMA structure: ++ * support two DMA engines: 32 bits address or 64 bit addressing ++ * basic DMA register set is per channel(transmit or receive) ++ * a pair of channels is defined for convenience ++ */ ++ ++ ++/*** 32 bits addressing ***/ ++ ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 addr; /* descriptor ring base address (4K aligned) */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 status; /* current active descriptor, et al */ ++} dma32regs_t; ++ ++typedef volatile struct { ++ dma32regs_t xmt; /* dma tx channel */ ++ dma32regs_t rcv; /* dma rx channel */ ++} dma32regp_t; ++ ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma32diag_t; ++ ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl; /* misc control bits & bufcount */ ++ uint32 addr; /* data buffer address */ ++} dma32dd_t; ++ ++/* ++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. ++ */ ++#define D32MAXRINGSZ 4096 ++#define D32RINGALIGN 4096 ++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) ++ ++/* transmit channel control */ ++#define XC_XE ((uint32)1 << 0) /* transmit enable */ ++#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ ++#define XC_LE ((uint32)1 << 2) /* loopback enable */ ++#define XC_FL ((uint32)1 << 4) /* flush request */ ++#define XC_AE ((uint32)3 << 16) /* address extension bits */ ++#define XC_AE_SHIFT 16 ++ ++/* transmit descriptor table pointer */ ++#define XP_LD_MASK 0xfff /* last valid descriptor */ ++ ++/* transmit channel status */ ++#define XS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define XS_XS_MASK 0xf000 /* transmit state */ ++#define XS_XS_SHIFT 12 ++#define XS_XS_DISABLED 0x0000 /* disabled */ ++#define XS_XS_ACTIVE 0x1000 /* active */ ++#define XS_XS_IDLE 0x2000 /* idle wait */ ++#define XS_XS_STOPPED 0x3000 /* stopped */ ++#define XS_XS_SUSP 0x4000 /* suspend pending */ ++#define XS_XE_MASK 0xf0000 /* transmit errors */ ++#define XS_XE_SHIFT 16 ++#define XS_XE_NOERR 0x00000 /* no error */ ++#define XS_XE_DPE 0x10000 /* descriptor protocol error */ ++#define XS_XE_DFU 0x20000 /* data fifo underrun */ ++#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ ++#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ ++#define XS_AD_MASK 0xfff00000 /* active descriptor */ ++#define XS_AD_SHIFT 20 ++ ++/* receive channel control */ ++#define RC_RE ((uint32)1 << 0) /* receive enable */ ++#define RC_RO_MASK 0xfe /* receive frame offset */ ++#define RC_RO_SHIFT 1 ++#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ ++#define RC_AE ((uint32)3 << 16) /* address extension bits */ ++#define RC_AE_SHIFT 16 ++ ++/* receive descriptor table pointer */ ++#define RP_LD_MASK 0xfff /* last valid descriptor */ ++ ++/* receive channel status */ ++#define RS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define RS_RS_MASK 0xf000 /* receive state */ ++#define RS_RS_SHIFT 12 ++#define RS_RS_DISABLED 0x0000 /* disabled */ ++#define RS_RS_ACTIVE 0x1000 /* active */ ++#define RS_RS_IDLE 0x2000 /* idle wait */ ++#define RS_RS_STOPPED 0x3000 /* reserved */ ++#define RS_RE_MASK 0xf0000 /* receive errors */ ++#define RS_RE_SHIFT 16 ++#define RS_RE_NOERR 0x00000 /* no error */ ++#define RS_RE_DPE 0x10000 /* descriptor protocol error */ ++#define RS_RE_DFO 0x20000 /* data fifo overflow */ ++#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ ++#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ ++#define RS_AD_MASK 0xfff00000 /* active descriptor */ ++#define RS_AD_SHIFT 20 ++ ++/* fifoaddr */ ++#define FA_OFF_MASK 0xffff /* offset */ ++#define FA_SEL_MASK 0xf0000 /* select */ ++#define FA_SEL_SHIFT 16 ++#define FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define FA_SEL_RDD 0x40000 /* receive dma data */ ++#define FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ ++/* descriptor control flags */ ++#define CTRL_BC_MASK 0x1fff /* buffer byte count */ ++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ ++#define CTRL_AE_SHIFT 16 ++#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ ++#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ ++ ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define CTRL_CORE_MASK 0x0ff00000 ++ ++/*** 64 bits addressing ***/ ++ ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ ++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ ++ uint32 status0; /* current descriptor, xmt state */ ++ uint32 status1; /* active descriptor, xmt error */ ++} dma64regs_t; ++ ++typedef volatile struct { ++ dma64regs_t tx; /* dma64 tx channel */ ++ dma64regs_t rx; /* dma64 rx channel */ ++} dma64regp_t; ++ ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma64diag_t; ++ ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl1; /* misc control bits & bufcount */ ++ uint32 ctrl2; /* buffer count and address extension */ ++ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */ ++ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */ ++} dma64dd_t; ++ ++/* ++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. ++ */ ++#define D64MAXRINGSZ 8192 ++#define D64RINGALIGN 8192 ++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) ++ ++/* transmit channel control */ ++#define D64_XC_XE 0x00000001 /* transmit enable */ ++#define D64_XC_SE 0x00000002 /* transmit suspend request */ ++#define D64_XC_LE 0x00000004 /* loopback enable */ ++#define D64_XC_FL 0x00000010 /* flush request */ ++#define D64_XC_AE 0x00110000 /* address extension bits */ ++#define D64_XC_AE_SHIFT 16 ++ ++/* transmit descriptor table pointer */ ++#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ ++ ++/* transmit channel status */ ++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ ++#define D64_XS0_XS_SHIFT 28 ++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ ++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ ++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ ++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ ++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ ++ ++#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ ++#define D64_XS1_XE_SHIFT 28 ++#define D64_XS1_XE_NOERR 0x00000000 /* no error */ ++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ ++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ ++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ ++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_XS1_XE_COREE 0x50000000 /* core error */ ++ ++/* receive channel control */ ++#define D64_RC_RE 0x00000001 /* receive enable */ ++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ ++#define D64_RC_RO_SHIFT 1 ++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ ++#define D64_RC_AE 0x00110000 /* address extension bits */ ++#define D64_RC_AE_SHIFT 16 ++ ++/* receive descriptor table pointer */ ++#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ ++ ++/* receive channel status */ ++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ ++#define D64_RS0_RS_SHIFT 28 ++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ ++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ ++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ ++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ ++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ ++ ++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ ++#define D64_RS1_RE_SHIFT 28 ++#define D64_RS1_RE_NOERR 0x00000000 /* no error */ ++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ ++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ ++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ ++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_RS1_RE_COREE 0x50000000 /* core error */ ++ ++/* fifoaddr */ ++#define D64_FA_OFF_MASK 0xffff /* offset */ ++#define D64_FA_SEL_MASK 0xf0000 /* select */ ++#define D64_FA_SEL_SHIFT 16 ++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ ++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ ++/* descriptor control flags 1 */ ++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ ++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ ++ ++/* descriptor control flags 2 */ ++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ ++#define D64_CTRL2_AE 0x00110000 /* address extension bits */ ++#define D64_CTRL2_AE_SHIFT 16 ++ ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define D64_CTRL_CORE_MASK 0x0ff00000 ++ ++ ++#endif /* _sbhnddma_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,148 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBMEMC_H ++#define _SBMEMC_H ++ ++#ifdef _LANGUAGE_ASSEMBLY ++ ++#define MEMC_CONTROL 0x00 ++#define MEMC_CONFIG 0x04 ++#define MEMC_REFRESH 0x08 ++#define MEMC_BISTSTAT 0x0c ++#define MEMC_MODEBUF 0x10 ++#define MEMC_BKCLS 0x14 ++#define MEMC_PRIORINV 0x18 ++#define MEMC_DRAMTIM 0x1c ++#define MEMC_INTSTAT 0x20 ++#define MEMC_INTMASK 0x24 ++#define MEMC_INTINFO 0x28 ++#define MEMC_NCDLCTL 0x30 ++#define MEMC_RDNCDLCOR 0x34 ++#define MEMC_WRNCDLCOR 0x38 ++#define MEMC_MISCDLYCTL 0x3c ++#define MEMC_DQSGATENCDL 0x40 ++#define MEMC_SPARE 0x44 ++#define MEMC_TPADDR 0x48 ++#define MEMC_TPDATA 0x4c ++#define MEMC_BARRIER 0x50 ++#define MEMC_CORE 0x54 ++ ++ ++#else ++ ++/* Sonics side: MEMC core registers */ ++typedef volatile struct sbmemcregs { ++ uint32 control; ++ uint32 config; ++ uint32 refresh; ++ uint32 biststat; ++ uint32 modebuf; ++ uint32 bkcls; ++ uint32 priorinv; ++ uint32 dramtim; ++ uint32 intstat; ++ uint32 intmask; ++ uint32 intinfo; ++ uint32 reserved1; ++ uint32 ncdlctl; ++ uint32 rdncdlcor; ++ uint32 wrncdlcor; ++ uint32 miscdlyctl; ++ uint32 dqsgatencdl; ++ uint32 spare; ++ uint32 tpaddr; ++ uint32 tpdata; ++ uint32 barrier; ++ uint32 core; ++} sbmemcregs_t; ++ ++#endif ++ ++/* MEMC Core Init values (OCP ID 0x80f) */ ++ ++/* For sdr: */ ++#define MEMC_SD_CONFIG_INIT 0x00048000 ++#define MEMC_SD_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_SD_DRAMTIM3_INIT 0x000754da ++#define MEMC_SD_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_SD_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */ ++#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b ++#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */ ++#define MEMC_SD_CONTROL_INIT0 0x00000002 ++#define MEMC_SD_CONTROL_INIT1 0x00000008 ++#define MEMC_SD_CONTROL_INIT2 0x00000004 ++#define MEMC_SD_CONTROL_INIT3 0x00000010 ++#define MEMC_SD_CONTROL_INIT4 0x00000001 ++#define MEMC_SD_MODEBUF_INIT 0x00000000 ++#define MEMC_SD_REFRESH_INIT 0x0000840f ++ ++ ++/* This is for SDRM8X8X4 */ ++#define MEMC_SDR_INIT 0x0008 ++#define MEMC_SDR_MODE 0x32 ++#define MEMC_SDR_NCDL 0x00020032 ++#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ ++ ++/* For ddr: */ ++#define MEMC_CONFIG_INIT 0x00048000 ++#define MEMC_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_DRAMTIM25_INIT 0x000754d9 ++#define MEMC_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ ++#define MEMC_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_1_WRNCDLCOR_INIT 0x14500200 ++#define MEMC_DQSGATENCDL_INIT 0x00030000 ++#define MEMC_MISCDLYCTL_INIT 0x21061c1b ++#define MEMC_1_MISCDLYCTL_INIT 0x21021400 ++#define MEMC_NCDLCTL_INIT 0x00002001 ++#define MEMC_CONTROL_INIT0 0x00000002 ++#define MEMC_CONTROL_INIT1 0x00000008 ++#define MEMC_MODEBUF_INIT0 0x00004000 ++#define MEMC_CONTROL_INIT2 0x00000010 ++#define MEMC_MODEBUF_INIT1 0x00000100 ++#define MEMC_CONTROL_INIT3 0x00000010 ++#define MEMC_CONTROL_INIT4 0x00000008 ++#define MEMC_REFRESH_INIT 0x0000840f ++#define MEMC_CONTROL_INIT5 0x00000004 ++#define MEMC_MODEBUF_INIT2 0x00000000 ++#define MEMC_CONTROL_INIT6 0x00000010 ++#define MEMC_CONTROL_INIT7 0x00000001 ++ ++ ++/* This is for DDRM16X16X2 */ ++#define MEMC_DDR_INIT 0x0009 ++#define MEMC_DDR_MODE 0x62 ++#define MEMC_DDR_NCDL 0x0005050a ++#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ ++ ++/* mask for sdr/ddr calibration registers */ ++#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff ++#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff ++#define MEMC_DQSGATENCDL_G_MASK 0x000000ff ++ ++/* masks for miscdlyctl registers */ ++#define MEMC_MISC_SM_MASK 0x30000000 ++#define MEMC_MISC_SM_SHIFT 28 ++#define MEMC_MISC_SD_MASK 0x0f000000 ++#define MEMC_MISC_SD_SHIFT 24 ++ ++/* hw threshhold for calculating wr/rd for sdr memc */ ++#define MEMC_CD_THRESHOLD 128 ++ ++/* Low bit of init register says if memc is ddr or sdr */ ++#define MEMC_CONFIG_DDR 0x00000001 ++ ++#endif /* _SBMEMC_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,62 @@ ++/* ++ * Broadcom SiliconBackplane MIPS definitions ++ * ++ * SB MIPS cores are custom MIPS32 processors with SiliconBackplane ++ * OCP interfaces. The CP0 processor ID is 0x00024000, where bits ++ * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP ++ * interface. The core revision is stored in the SB ID register in SB ++ * configuration space. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBMIPS_H ++#define _SBMIPS_H ++ ++#include ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 PAD[2]; ++ uint32 biststatus; ++ uint32 PAD[4]; ++ uint32 intstatus; ++ uint32 intmask; ++ uint32 timer; ++} mipsregs_t; ++ ++extern uint32 sb_flag(sb_t *sbh); ++extern uint sb_irq(sb_t *sbh); ++ ++extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); ++ ++extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap); ++extern void sb_jtagm_disable(void *h); ++extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr); ++extern void BCMINIT(sb_mips_init)(sb_t *sbh); ++extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh); ++extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); ++extern void BCMINIT(enable_pfc)(uint32 mode); ++extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh); ++ ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _SBMIPS_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,199 @@ ++/* ++ * BCM43XX SiliconBackplane PCIE core hardware definitions. ++ * ++ * $Id: ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ ++ ++#ifndef _SBPCIE_H ++#define _SBPCIE_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* PCIE Enumeration space offsets*/ ++#define PCIE_CORE_CONFIG_OFFSET 0x0 ++#define PCIE_FUNC0_CONFIG_OFFSET 0x400 ++#define PCIE_FUNC1_CONFIG_OFFSET 0x500 ++#define PCIE_FUNC2_CONFIG_OFFSET 0x600 ++#define PCIE_FUNC3_CONFIG_OFFSET 0x700 ++#define PCIE_SPROM_SHADOW_OFFSET 0x800 ++#define PCIE_SBCONFIG_OFFSET 0xE00 ++ ++/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */ ++#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0 ++#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000 ++#define PCIE_BAR0_PCIECORE_OFFSET 0x2000 ++#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000 ++ ++/* SB side: PCIE core and host control registers */ ++typedef struct sbpcieregs { ++ ++ uint32 PAD[3]; ++ uint32 biststatus; /* bist Status: 0x00C*/ ++ uint32 PAD[6]; ++ uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028*/ ++ uint32 PAD[54]; ++ uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ ++ uint32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ ++ uint32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ ++ uint32 PAD[4]; ++ ++ /* pcie core supports in direct access to config space */ ++ uint32 configaddr; /* pcie config space access: Address field: 0x120*/ ++ uint32 configdata; /* pcie config space access: Data field: 0x124*/ ++ ++ /* mdio access to serdes */ ++ uint32 mdiocontrol; /* controls the mdio access: 0x128 */ ++ uint32 mdiodata; /* Data to the mdio access: 0x12c */ ++ ++ /* pcie protocol phy/dllp/tlp register access mechanism*/ ++ uint32 pcieaddr; /* address of the internal registeru: 0x130 */ ++ uint32 pciedata; /* Data to/from the internal regsiter: 0x134 */ ++ ++ uint32 PAD[434]; ++ uint16 sprom[36]; /* SPROM shadow Area */ ++} sbpcieregs_t; ++ ++/* SB to PCIE translation masks */ ++#define SBTOPCIE0_MASK 0xfc000000 ++#define SBTOPCIE1_MASK 0xfc000000 ++#define SBTOPCIE2_MASK 0xc0000000 ++ ++/* Access type bits (0:1)*/ ++#define SBTOPCIE_MEM 0 ++#define SBTOPCIE_IO 1 ++#define SBTOPCIE_CFG0 2 ++#define SBTOPCIE_CFG1 3 ++ ++/*Prefetch enable bit 2*/ ++#define SBTOPCIE_PF 4 ++ ++/*Write Burst enable for memory write bit 3*/ ++#define SBTOPCIE_WR_BURST 8 ++ ++/* config access */ ++#define CONFIGADDR_FUNC_MASK 0x7000 ++#define CONFIGADDR_FUNC_SHF 12 ++#define CONFIGADDR_REG_MASK 0x0FFF ++#define CONFIGADDR_REG_SHF 0 ++ ++/* PCIE protocol regs Indirect Address */ ++#define PCIEADDR_PROT_MASK 0x300 ++#define PCIEADDR_PROT_SHF 8 ++#define PCIEADDR_PL_TLP 0 ++#define PCIEADDR_PL_DLLP 1 ++#define PCIEADDR_PL_PLP 2 ++ ++/* PCIE protocol PHY diagnostic registers */ ++#define PCIE_PLP_MODEREG 0x200 /* Mode*/ ++#define PCIE_PLP_STATUSREG 0x204 /* Status*/ ++#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */ ++#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number*/ ++#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number*/ ++#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */ ++#define PCIE_PLP_ATTNREG 0x218 /* Attention */ ++#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */ ++#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */ ++#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error*/ ++#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */ ++#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg*/ ++#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */ ++#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */ ++#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag*/ ++#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag*/ ++ ++/* PCIE protocol DLLP diagnostic registers */ ++#define PCIE_DLLP_LCREG 0x100 /* Link Control*/ ++#define PCIE_DLLP_LSREG 0x104 /* Link Status */ ++#define PCIE_DLLP_LAREG 0x108 /* Link Attention*/ ++#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */ ++#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num*/ ++#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num*/ ++#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num*/ ++#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */ ++#define PCIE_DLLP_LRREG 0x120 /* Link Replay*/ ++#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout*/ ++#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold*/ ++#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr*/ ++#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr*/ ++#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr*/ ++#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write*/ ++#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */ ++#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */ ++#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter*/ ++#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter*/ ++#define PCIE_DLLP_TESTREG 0x14C /* Test */ ++#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST*/ ++ ++/* PCIE protocol TLP diagnostic registers */ ++#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */ ++#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ ++#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address*/ ++#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address*/ ++#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req*/ ++#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address*/ ++#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address*/ ++#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req*/ ++#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address*/ ++#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address*/ ++#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req*/ ++#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len*/ ++#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs*/ ++#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req*/ ++#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len*/ ++#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0*/ ++#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1*/ ++#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2*/ ++#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */ ++#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */ ++#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */ ++#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len*/ ++#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0*/ ++#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1*/ ++#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func*/ ++#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter*/ ++#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value*/ ++#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1*/ ++#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2*/ ++#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3*/ ++#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4*/ ++ ++/* MDIO control */ ++#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ ++#define MDIOCTL_DIVISOR_VAL 0x2 ++#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ ++#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */ ++ ++/* MDIO Data */ ++#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ ++#define MDIODATA_TA 0x00020000 /* Turnaround */ ++#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ ++#define MDIODATA_REGADDR_MASK 0x003c0000 /* Regaddr Mask */ ++#define MDIODATA_DEVADDR_SHF 22 /* Physmedia devaddr shift */ ++#define MDIODATA_DEVADDR_MASK 0x0fc00000 /* Physmedia devaddr Mask */ ++#define MDIODATA_WRITE 0x10000000 /* write Transaction */ ++#define MDIODATA_READ 0x20000000 /* Read Transaction */ ++#define MDIODATA_START 0x40000000 /* start of Transaction */ ++ ++/* MDIO devices (SERDES modules) */ ++#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ ++#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ ++#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ ++ ++/* SERDES registers */ ++#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ ++#define SERDES_RX_CDR 6 /* CDR */ ++#define SERDES_RX_CDRBW 7 /* CDR BW */ ++ ++#endif /* _SBPCIE_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,122 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ ++ ++#ifndef _SBPCI_H ++#define _SBPCI_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* Sonics side: PCI core and host control registers */ ++typedef struct sbpciregs { ++ uint32 control; /* PCI control */ ++ uint32 PAD[3]; ++ uint32 arbcontrol; /* PCI arbiter control */ ++ uint32 PAD[3]; ++ uint32 intstatus; /* Interrupt status */ ++ uint32 intmask; /* Interrupt mask */ ++ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ ++ uint32 PAD[9]; ++ uint32 bcastaddr; /* Sonics broadcast address */ ++ uint32 bcastdata; /* Sonics broadcast data */ ++ uint32 PAD[2]; ++ uint32 gpioin; /* ro: gpio input (>=rev2) */ ++ uint32 gpioout; /* rw: gpio output (>=rev2) */ ++ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ ++ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ ++ uint32 PAD[36]; ++ uint32 sbtopci0; /* Sonics to PCI translation 0 */ ++ uint32 sbtopci1; /* Sonics to PCI translation 1 */ ++ uint32 sbtopci2; /* Sonics to PCI translation 2 */ ++ uint32 PAD[445]; ++ uint16 sprom[36]; /* SPROM shadow Area */ ++ uint32 PAD[46]; ++} sbpciregs_t; ++ ++/* PCI control */ ++#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ ++#define PCI_RST 0x02 /* Value driven out to pin */ ++#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ ++#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ ++ ++/* PCI arbiter control */ ++#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ ++#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ ++#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */ ++#define PCI_PARKID_SHIFT 1 ++#define PCI_PARKID_LAST 0 /* Last requestor */ ++#define PCI_PARKID_4710 1 /* 4710 */ ++#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */ ++#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */ ++ ++/* Interrupt status/mask */ ++#define PCI_INTA 0x01 /* PCI INTA# is asserted */ ++#define PCI_INTB 0x02 /* PCI INTB# is asserted */ ++#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ ++#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ ++#define PCI_PME 0x10 /* PCI PME# is asserted */ ++ ++/* (General) PCI/SB mailbox interrupts, two bits per pci function */ ++#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ ++#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ ++#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ ++#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ ++#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ ++#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ ++#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ ++#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ ++ ++/* Sonics broadcast address */ ++#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ ++ ++/* Sonics to PCI translation types */ ++#define SBTOPCI0_MASK 0xfc000000 ++#define SBTOPCI1_MASK 0xfc000000 ++#define SBTOPCI2_MASK 0xc0000000 ++#define SBTOPCI_MEM 0 ++#define SBTOPCI_IO 1 ++#define SBTOPCI_CFG0 2 ++#define SBTOPCI_CFG1 3 ++#define SBTOPCI_PREF 0x4 /* prefetch enable */ ++#define SBTOPCI_BURST 0x8 /* burst enable */ ++#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ ++#define SBTOPCI_RC_READ 0x00 /* memory read */ ++#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ ++#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ ++ ++/* PCI core index in SROM shadow area */ ++#define SRSH_PI_OFFSET 0 /* first word */ ++#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ ++#define SRSH_PI_SHIFT 12 /* bit 15:12 */ ++ ++/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */ ++#define cap_list rsvd_a[0] ++#define bar0_window dev_dep[0x80 - 0x40] ++#define bar1_window dev_dep[0x84 - 0x40] ++#define sprom_control dev_dep[0x88 - 0x40] ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern void sbpci_ban(uint16 core); ++extern int sbpci_init(sb_t *sbh); ++extern void sbpci_check(sb_t *sbh); ++ ++#endif /* !_LANGUAGE_ASSEMBLY */ ++ ++#endif /* _SBPCI_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,146 @@ ++/* ++ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ ++ ++#ifndef _SBPCMCIA_H ++#define _SBPCMCIA_H ++ ++ ++/* All the addresses that are offsets in attribute space are divided ++ * by two to account for the fact that odd bytes are invalid in ++ * attribute space and our read/write routines make the space appear ++ * as if they didn't exist. Still we want to show the original numbers ++ * as documented in the hnd_pcmcia core manual. ++ */ ++ ++/* PCMCIA Function Configuration Registers */ ++#define PCMCIA_FCR (0x700 / 2) ++ ++#define FCR0_OFF 0 ++#define FCR1_OFF (0x40 / 2) ++#define FCR2_OFF (0x80 / 2) ++#define FCR3_OFF (0xc0 / 2) ++ ++#define PCMCIA_FCR0 (0x700 / 2) ++#define PCMCIA_FCR1 (0x740 / 2) ++#define PCMCIA_FCR2 (0x780 / 2) ++#define PCMCIA_FCR3 (0x7c0 / 2) ++ ++/* Standard PCMCIA FCR registers */ ++ ++#define PCMCIA_COR 0 ++ ++#define COR_RST 0x80 ++#define COR_LEV 0x40 ++#define COR_IRQEN 0x04 ++#define COR_BLREN 0x01 ++#define COR_FUNEN 0x01 ++ ++ ++#define PCICIA_FCSR (2 / 2) ++#define PCICIA_PRR (4 / 2) ++#define PCICIA_SCR (6 / 2) ++#define PCICIA_ESR (8 / 2) ++ ++ ++#define PCM_MEMOFF 0x0000 ++#define F0_MEMOFF 0x1000 ++#define F1_MEMOFF 0x2000 ++#define F2_MEMOFF 0x3000 ++#define F3_MEMOFF 0x4000 ++ ++/* Memory base in the function fcr's */ ++#define MEM_ADDR0 (0x728 / 2) ++#define MEM_ADDR1 (0x72a / 2) ++#define MEM_ADDR2 (0x72c / 2) ++ ++/* PCMCIA base plus Srom access in fcr0: */ ++#define PCMCIA_ADDR0 (0x072e / 2) ++#define PCMCIA_ADDR1 (0x0730 / 2) ++#define PCMCIA_ADDR2 (0x0732 / 2) ++ ++#define MEM_SEG (0x0734 / 2) ++#define SROM_CS (0x0736 / 2) ++#define SROM_DATAL (0x0738 / 2) ++#define SROM_DATAH (0x073a / 2) ++#define SROM_ADDRL (0x073c / 2) ++#define SROM_ADDRH (0x073e / 2) ++ ++/* Values for srom_cs: */ ++#define SROM_IDLE 0 ++#define SROM_WRITE 1 ++#define SROM_READ 2 ++#define SROM_WEN 4 ++#define SROM_WDS 7 ++#define SROM_DONE 8 ++ ++/* CIS stuff */ ++ ++/* The CIS stops where the FCRs start */ ++#define CIS_SIZE PCMCIA_FCR ++ ++/* Standard tuples we know about */ ++ ++#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ ++#define CISTPL_FUNCE 0x22 /* Function extensions */ ++#define CISTPL_CFTABLE 0x1b /* Config table entry */ ++ ++/* Function extensions for LANs */ ++ ++#define LAN_TECH 1 /* Technology type */ ++#define LAN_SPEED 2 /* Raw bit rate */ ++#define LAN_MEDIA 3 /* Transmission media */ ++#define LAN_NID 4 /* Node identification (aka MAC addr) */ ++#define LAN_CONN 5 /* Connector standard */ ++ ++ ++/* CFTable */ ++#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ ++#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ ++#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ ++ ++/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll ++ * take one for HNBU, and use "extensions" (a la FUNCE) within it. ++ */ ++ ++#define CISTPL_BRCM_HNBU 0x80 ++ ++/* Subtypes of BRCM_HNBU: */ ++ ++#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ ++#define HNBU_CHIPID 0x01 /* Six bytes with PCI vendor & ++ * device id and chiprev ++ */ ++#define HNBU_BOARDREV 0x02 /* Two bytes board revision */ ++#define HNBU_PAPARMS 0x03 /* PA parameters: 1 (old), 8 (sreomrev == 1) ++ * or 9 (sromrev > 1) bytes */ ++#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ ++#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ ++#define HNBU_AA 0x06 /* Antennas available */ ++#define HNBU_AG 0x07 /* Antenna gain */ ++#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ ++#define HNBU_LEDS 0x09 /* LED set */ ++#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) ++ * in rev 2 ++ */ ++#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ ++#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ ++ ++ ++/* sbtmstatelow */ ++#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ ++#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ ++ ++/* sbtmstatehigh */ ++#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ ++ ++#endif /* _SBPCMCIA_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,75 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBSDRAM_H ++#define _SBSDRAM_H ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* Sonics side: SDRAM core registers */ ++typedef volatile struct sbsdramregs { ++ uint32 initcontrol; /* Generates external SDRAM initialization sequence */ ++ uint32 config; /* Initializes external SDRAM mode register */ ++ uint32 refresh; /* Controls external SDRAM refresh rate */ ++ uint32 pad1; ++ uint32 pad2; ++} sbsdramregs_t; ++ ++#endif ++ ++/* SDRAM initialization control (initcontrol) register bits */ ++#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */ ++#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */ ++#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */ ++#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */ ++#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */ ++#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */ ++#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */ ++#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */ ++#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */ ++#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */ ++#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */ ++#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */ ++#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */ ++ ++/* SDRAM configuration (config) register bits */ ++#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */ ++#define SDRAM_BURST8 0x0001 /* Use burst of 8 */ ++#define SDRAM_BURST4 0x0002 /* Use burst of 4 */ ++#define SDRAM_BURST2 0x0003 /* Use burst of 2 */ ++#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */ ++#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */ ++ ++/* SDRAM refresh control (refresh) register bits */ ++#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */ ++#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */ ++ ++/* SDRAM Core default Init values (OCP ID 0x803) */ ++#define SDRAM_INIT MEM4MX16X2 ++#define SDRAM_CONFIG SDRAM_BURSTFULL ++#define SDRAM_REFRESH SDRAM_REF(0x40) ++ ++#define MEM1MX16 0x009 /* 2 MB */ ++#define MEM1MX16X2 0x409 /* 4 MB */ ++#define MEM2MX8X2 0x809 /* 4 MB */ ++#define MEM2MX8X4 0xc09 /* 8 MB */ ++#define MEM2MX32 0x439 /* 8 MB */ ++#define MEM4MX16 0x019 /* 8 MB */ ++#define MEM4MX16X2 0x419 /* 16 MB */ ++#define MEM8MX8X2 0x819 /* 16 MB */ ++#define MEM8MX16 0x829 /* 16 MB */ ++#define MEM4MX32 0x429 /* 16 MB */ ++#define MEM8MX8X4 0xc19 /* 32 MB */ ++#define MEM8MX16X2 0xc29 /* 32 MB */ ++ ++#endif /* _SBSDRAM_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,37 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane embedded ram core ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBSOCRAM_H ++#define _SBSOCRAM_H ++ ++#define SOCRAM_MEMSIZE 0x00 ++#define SOCRAM_BISTSTAT 0x0c ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* Memcsocram core registers */ ++typedef volatile struct sbsocramregs { ++ uint32 memsize; ++ uint32 biststat; ++} sbsocramregs_t; ++ ++#endif ++ ++/* Them memory size is 2 to the power of the following ++ * base added to the contents of the memsize register. ++ */ ++#define SOCRAM_MEMSIZE_BASESHIFT 16 ++ ++#endif /* _SBSOCRAM_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,140 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of Broadcom HNBU SiliconBackplane-based chips. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _sbutils_h_ ++#define _sbutils_h_ ++ ++/* ++ * Datastructure to export all chip specific common variables ++ * public (read-only) portion of sbutils handle returned by ++ * sb_attach()/sb_kattach() ++*/ ++ ++struct sb_pub { ++ ++ uint bustype; /* SB_BUS, PCI_BUS */ ++ uint buscoretype; /* SB_PCI, SB_PCMCIA, SB_PCIE*/ ++ uint buscorerev; /* buscore rev */ ++ uint buscoreidx; /* buscore index */ ++ int ccrev; /* chip common core rev */ ++ uint boardtype; /* board type */ ++ uint boardvendor; /* board vendor */ ++ uint chip; /* chip number */ ++ uint chiprev; /* chip revision */ ++ uint chippkg; /* chip package option */ ++ uint sonicsrev; /* sonics backplane rev */ ++}; ++ ++typedef const struct sb_pub sb_t; ++ ++/* ++ * Many of the routines below take an 'sbh' handle as their first arg. ++ * Allocate this by calling sb_attach(). Free it by calling sb_detach(). ++ * At any one time, the sbh is logically focused on one particular sb core ++ * (the "current core"). ++ * Use sb_setcore() or sb_setcoreidx() to change the association to another core. ++ */ ++ ++/* exported externs */ ++extern sb_t * BCMINIT(sb_attach)(uint pcidev, osl_t *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); ++extern sb_t * BCMINIT(sb_kattach)(void); ++extern void sb_detach(sb_t *sbh); ++extern uint BCMINIT(sb_chip)(sb_t *sbh); ++extern uint BCMINIT(sb_chiprev)(sb_t *sbh); ++extern uint BCMINIT(sb_chipcrev)(sb_t *sbh); ++extern uint BCMINIT(sb_chippkg)(sb_t *sbh); ++extern uint BCMINIT(sb_pcirev)(sb_t *sbh); ++extern bool BCMINIT(sb_war16165)(sb_t *sbh); ++extern uint BCMINIT(sb_pcmciarev)(sb_t *sbh); ++extern uint BCMINIT(sb_boardvendor)(sb_t *sbh); ++extern uint BCMINIT(sb_boardtype)(sb_t *sbh); ++extern uint sb_bus(sb_t *sbh); ++extern uint sb_buscoretype(sb_t *sbh); ++extern uint sb_buscorerev(sb_t *sbh); ++extern uint sb_corelist(sb_t *sbh, uint coreid[]); ++extern uint sb_coreid(sb_t *sbh); ++extern uint sb_coreidx(sb_t *sbh); ++extern uint sb_coreunit(sb_t *sbh); ++extern uint sb_corevendor(sb_t *sbh); ++extern uint sb_corerev(sb_t *sbh); ++extern void *sb_osh(sb_t *sbh); ++extern void *sb_coreregs(sb_t *sbh); ++extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val); ++extern bool sb_iscoreup(sb_t *sbh); ++extern void *sb_setcoreidx(sb_t *sbh, uint coreidx); ++extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit); ++extern int sb_corebist(sb_t *sbh, uint coreid, uint coreunit); ++extern void sb_commit(sb_t *sbh); ++extern uint32 sb_base(uint32 admatch); ++extern uint32 sb_size(uint32 admatch); ++extern void sb_core_reset(sb_t *sbh, uint32 bits); ++extern void sb_core_tofixup(sb_t *sbh); ++extern void sb_core_disable(sb_t *sbh, uint32 bits); ++extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m); ++extern uint32 sb_clock(sb_t *sbh); ++extern void sb_pci_setup(sb_t *sbh, uint coremask); ++extern void sb_pcmcia_init(sb_t *sbh); ++extern void sb_watchdog(sb_t *sbh, uint ticks); ++extern void *sb_gpiosetcore(sb_t *sbh); ++extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioin(sb_t *sbh); ++extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority); ++extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority); ++ ++extern void sb_clkctl_init(sb_t *sbh); ++extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh); ++extern bool sb_clkctl_clk(sb_t *sbh, uint mode); ++extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on); ++extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, ++ void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg); ++extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to); ++extern void sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif); ++extern uint sb_pcie_readreg(void *sbh, void* arg1, uint offset); ++extern uint sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val); ++extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val); ++ ++ ++ ++/* ++* Build device path. Path size must be >= SB_DEVPATH_BUFSZ. ++* The returned path is NULL terminated and has trailing '/'. ++* Return 0 on success, nonzero otherwise. ++*/ ++extern int sb_devpath(sb_t *sbh, char *path, int size); ++ ++/* clkctl xtal what flags */ ++#define XTAL 0x1 /* primary crystal oscillator (2050) */ ++#define PLL 0x2 /* main chip pll */ ++ ++/* clkctl clk mode */ ++#define CLK_FAST 0 /* force fast (pll) clock */ ++#define CLK_DYNAMIC 2 /* enable dynamic clock control */ ++ ++ ++/* GPIO usage priorities */ ++#define GPIO_DRV_PRIORITY 0 ++#define GPIO_APP_PRIORITY 1 ++ ++/* device path */ ++#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ ++ ++#endif /* _sbutils_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sflash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _sflash_h_ ++#define _sflash_h_ ++ ++#include ++#include ++ ++struct sflash { ++ uint blocksize; /* Block size */ ++ uint numblocks; /* Number of blocks */ ++ uint32 type; /* Type */ ++ uint size; /* Total size in bytes */ ++}; ++ ++/* Utility functions */ ++extern int sflash_poll(chipcregs_t *cc, uint offset); ++extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf); ++extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern int sflash_erase(chipcregs_t *cc, uint offset); ++extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern struct sflash * sflash_init(chipcregs_t *cc); ++ ++#endif /* _sflash_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h +--- linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h 2005-12-16 23:39:10.940836500 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * TRX image file header format. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++ ++#define TRX_MAGIC 0x30524448 /* "HDR0" */ ++#define TRX_VERSION 1 ++#define TRX_MAX_LEN 0x3A0000 ++#define TRX_NO_HEADER 1 /* Do not write TRX header */ ++#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ ++#define TRX_MAX_OFFSET 3 ++ ++struct trx_header { ++ uint32 magic; /* "HDR0" */ ++ uint32 len; /* Length of file including header */ ++ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ ++ uint32 flag_version; /* 0:15 flags, 16:31 version */ ++ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ ++}; ++ ++/* Compatibility */ ++typedef struct trx_header TRXHDR, *PTRXHDR; +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h +--- linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h 2005-12-16 23:39:10.940836500 +0100 +@@ -0,0 +1,326 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _TYPEDEFS_H_ ++#define _TYPEDEFS_H_ ++ ++ ++/* Define 'SITE_TYPEDEFS' in the compile to include a site specific ++ * typedef file "site_typedefs.h". ++ * ++ * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs" ++ * section of this file makes inferences about the compile environment ++ * based on defined symbols and possibly compiler pragmas. ++ * ++ * Following these two sections is the "Default Typedefs" ++ * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is ++ * defined. This section has a default set of typedefs and a few ++ * proprocessor symbols (TRUE, FALSE, NULL, ...). ++ */ ++ ++#ifdef SITE_TYPEDEFS ++ ++/******************************************************************************* ++ * Site Specific Typedefs ++ *******************************************************************************/ ++ ++#include "site_typedefs.h" ++ ++#else ++ ++/******************************************************************************* ++ * Inferred Typedefs ++ *******************************************************************************/ ++ ++/* Infer the compile environment based on preprocessor symbols and pramas. ++ * Override type definitions as needed, and include configuration dependent ++ * header files to define types. ++ */ ++ ++#ifdef __cplusplus ++ ++#define TYPEDEF_BOOL ++#ifndef FALSE ++#define FALSE false ++#endif ++#ifndef TRUE ++#define TRUE true ++#endif ++ ++#else /* ! __cplusplus */ ++ ++#if defined(_WIN32) ++ ++#define TYPEDEF_BOOL ++typedef unsigned char bool; /* consistent w/BOOL */ ++ ++#endif /* _WIN32 */ ++ ++#endif /* ! __cplusplus */ ++ ++/* use the Windows ULONG_PTR type when compiling for 64 bit */ ++#if defined(_WIN64) ++#include ++#define TYPEDEF_UINTPTR ++typedef ULONG_PTR uintptr; ++#endif ++ ++#ifdef _HNDRTE_ ++typedef long unsigned int size_t; ++#endif ++ ++#ifdef _MSC_VER /* Microsoft C */ ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++typedef signed __int64 int64; ++typedef unsigned __int64 uint64; ++#endif ++ ++#if defined(MACOSX) && defined(KERNEL) ++#define TYPEDEF_BOOL ++#endif ++ ++ ++#if defined(linux) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#define TYPEDEF_ULONG ++#endif ++ ++#if !defined(linux) && !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#endif ++ ++ ++/* Do not support the (u)int64 types with strict ansi for GNU C */ ++#if defined(__GNUC__) && defined(__STRICT_ANSI__) ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++#endif ++ ++/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode ++ * for singned or unsigned */ ++#if defined(__ICL) ++ ++#define TYPEDEF_INT64 ++ ++#if defined(__STDC__) ++#define TYPEDEF_UINT64 ++#endif ++ ++#endif /* __ICL */ ++ ++ ++#if !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) ++ ++/* pick up ushort & uint from standard types.h */ ++#if defined(linux) && defined(__KERNEL__) ++ ++#include /* sys/types.h and linux/types.h are oil and water */ ++ ++#else ++ ++#include ++ ++#endif ++ ++#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ */ ++ ++#if defined(MACOSX) && defined(KERNEL) ++#include ++#endif ++ ++ ++/* use the default typedefs in the next section of this file */ ++#define USE_TYPEDEF_DEFAULTS ++ ++#endif /* SITE_TYPEDEFS */ ++ ++ ++/******************************************************************************* ++ * Default Typedefs ++ *******************************************************************************/ ++ ++#ifdef USE_TYPEDEF_DEFAULTS ++#undef USE_TYPEDEF_DEFAULTS ++ ++#ifndef TYPEDEF_BOOL ++typedef /*@abstract@*/ unsigned char bool; ++#endif ++ ++/*----------------------- define uchar, ushort, uint, ulong ------------------*/ ++ ++#ifndef TYPEDEF_UCHAR ++typedef unsigned char uchar; ++#endif ++ ++#ifndef TYPEDEF_USHORT ++typedef unsigned short ushort; ++#endif ++ ++#ifndef TYPEDEF_UINT ++typedef unsigned int uint; ++#endif ++ ++#ifndef TYPEDEF_ULONG ++typedef unsigned long ulong; ++#endif ++ ++/*----------------------- define [u]int8/16/32/64, uintptr --------------------*/ ++ ++#ifndef TYPEDEF_UINT8 ++typedef unsigned char uint8; ++#endif ++ ++#ifndef TYPEDEF_UINT16 ++typedef unsigned short uint16; ++#endif ++ ++#ifndef TYPEDEF_UINT32 ++typedef unsigned int uint32; ++#endif ++ ++#ifndef TYPEDEF_UINT64 ++typedef unsigned long long uint64; ++#endif ++ ++#ifndef TYPEDEF_UINTPTR ++typedef unsigned int uintptr; ++#endif ++ ++#ifndef TYPEDEF_INT8 ++typedef signed char int8; ++#endif ++ ++#ifndef TYPEDEF_INT16 ++typedef signed short int16; ++#endif ++ ++#ifndef TYPEDEF_INT32 ++typedef signed int int32; ++#endif ++ ++#ifndef TYPEDEF_INT64 ++typedef signed long long int64; ++#endif ++ ++/*----------------------- define float32/64, float_t -----------------------*/ ++ ++#ifndef TYPEDEF_FLOAT32 ++typedef float float32; ++#endif ++ ++#ifndef TYPEDEF_FLOAT64 ++typedef double float64; ++#endif ++ ++/* ++ * abstracted floating point type allows for compile time selection of ++ * single or double precision arithmetic. Compiling with -DFLOAT32 ++ * selects single precision; the default is double precision. ++ */ ++ ++#ifndef TYPEDEF_FLOAT_T ++ ++#if defined(FLOAT32) ++typedef float32 float_t; ++#else /* default to double precision floating point */ ++typedef float64 float_t; ++#endif ++ ++#endif /* TYPEDEF_FLOAT_T */ ++ ++/*----------------------- define macro values -----------------------------*/ ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#ifndef OFF ++#define OFF 0 ++#endif ++ ++#ifndef ON ++#define ON 1 ++#endif ++ ++#define AUTO (-1) ++ ++/* Reclaiming text and data : ++ The following macros specify special linker sections that can be reclaimed ++ after a system is considered 'up'. ++ */ ++#if defined(__GNUC__) && defined(BCMRECLAIM) ++extern bool bcmreclaimed; ++#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data##_ini ++#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn##_ini ++#define BCMINIT(_id) _id##_ini ++#else ++#define BCMINITDATA(_data) _data ++#define BCMINITFN(_fn) _fn ++#define BCMINIT(_id) _id ++#define bcmreclaimed 0 ++#endif ++ ++/*----------------------- define PTRSZ, INLINE ----------------------------*/ ++ ++#ifndef PTRSZ ++#define PTRSZ sizeof (char*) ++#endif ++ ++#ifndef INLINE ++ ++#ifdef _MSC_VER ++ ++#define INLINE __inline ++ ++#elif __GNUC__ ++ ++#define INLINE __inline__ ++ ++#else ++ ++#define INLINE ++ ++#endif /* _MSC_VER */ ++ ++#endif /* INLINE */ ++ ++#undef TYPEDEF_BOOL ++#undef TYPEDEF_UCHAR ++#undef TYPEDEF_USHORT ++#undef TYPEDEF_UINT ++#undef TYPEDEF_ULONG ++#undef TYPEDEF_UINT8 ++#undef TYPEDEF_UINT16 ++#undef TYPEDEF_UINT32 ++#undef TYPEDEF_UINT64 ++#undef TYPEDEF_UINTPTR ++#undef TYPEDEF_INT8 ++#undef TYPEDEF_INT16 ++#undef TYPEDEF_INT32 ++#undef TYPEDEF_INT64 ++#undef TYPEDEF_FLOAT32 ++#undef TYPEDEF_FLOAT64 ++#undef TYPEDEF_FLOAT_T ++ ++#endif /* USE_TYPEDEF_DEFAULTS */ ++ ++#endif /* _TYPEDEFS_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/wlioctl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/wlioctl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/wlioctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/wlioctl.h 2005-12-16 23:39:10.940836500 +0100 +@@ -0,0 +1,1030 @@ ++/* ++ * Custom OID/ioctl definitions for ++ * Broadcom 802.11abg Networking Device Driver ++ * ++ * Definitions subject to change without notice. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _wlioctl_h_ ++#define _wlioctl_h_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* require default structure packing */ ++#if !defined(__GNUC__) ++#pragma pack(push,8) ++#endif ++ ++#define WL_NUMRATES 255 /* max # of rates in a rateset */ ++ ++typedef struct wl_rateset { ++ uint32 count; /* # rates in this set */ ++ uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ ++} wl_rateset_t; ++ ++#define WL_CHANSPEC_CHAN_MASK 0x0fff ++#define WL_CHANSPEC_BAND_MASK 0xf000 ++#define WL_CHANSPEC_BAND_SHIFT 12 ++#define WL_CHANSPEC_BAND_A 0x1000 ++#define WL_CHANSPEC_BAND_B 0x2000 ++ ++/* ++ * Per-bss information structure. ++ */ ++ ++#define WL_BSS_INFO_VERSION 107 /* current version of wl_bss_info struct */ ++ ++typedef struct wl_bss_info { ++ uint32 version; /* version field */ ++ uint32 length; /* byte length of data in this record, starting at version and including IEs */ ++ struct ether_addr BSSID; ++ uint16 beacon_period; /* units are Kusec */ ++ uint16 capability; /* Capability information */ ++ uint8 SSID_len; ++ uint8 SSID[32]; ++ struct { ++ uint count; /* # rates in this set */ ++ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ ++ } rateset; /* supported rates */ ++ uint8 channel; /* Channel no. */ ++ uint16 atim_window; /* units are Kusec */ ++ uint8 dtim_period; /* DTIM period */ ++ int16 RSSI; /* receive signal strength (in dBm) */ ++ int8 phy_noise; /* noise (in dBm) */ ++ uint32 ie_length; /* byte length of Information Elements */ ++ /* variable length Information Elements */ ++} wl_bss_info_t; ++ ++typedef struct wlc_ssid { ++ uint32 SSID_len; ++ uchar SSID[32]; ++} wlc_ssid_t; ++ ++typedef struct wl_scan_params { ++ wlc_ssid_t ssid; /* default is {0, ""} */ ++ struct ether_addr bssid;/* default is bcast */ ++ int8 bss_type; /* default is any, DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT */ ++ int8 scan_type; /* -1 use default, DOT11_SCANTYPE_ACTIVE/PASSIVE */ ++ int32 nprobes; /* -1 use default, number of probes per channel */ ++ int32 active_time; /* -1 use default, dwell time per channel for active scanning */ ++ int32 passive_time; /* -1 use default, dwell time per channel for passive scanning */ ++ int32 home_time; /* -1 use default, dwell time for the home channel between channel scans */ ++ int32 channel_num; /* 0 use default (all available channels), count of channels in channel_list */ ++ uint16 channel_list[1]; /* list of chanspecs */ ++} wl_scan_params_t; ++/* size of wl_scan_params not including variable length array */ ++#define WL_SCAN_PARAMS_FIXED_SIZE 64 ++ ++typedef struct wl_scan_results { ++ uint32 buflen; ++ uint32 version; ++ uint32 count; ++ wl_bss_info_t bss_info[1]; ++} wl_scan_results_t; ++/* size of wl_scan_results not including variable length array */ ++#define WL_SCAN_RESULTS_FIXED_SIZE 12 ++ ++/* uint32 list */ ++typedef struct wl_uint32_list { ++ /* in - # of elements, out - # of entries */ ++ uint32 count; ++ /* variable length uint32 list */ ++ uint32 element[1]; ++} wl_uint32_list_t; ++ ++#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NULL */ ++ ++typedef struct wl_channels_in_country { ++ uint32 buflen; ++ uint32 band; ++ char country_abbrev[WLC_CNTRY_BUF_SZ]; ++ uint32 count; ++ uint32 channel[1]; ++} wl_channels_in_country_t; ++ ++typedef struct wl_country_list { ++ uint32 buflen; ++ uint32 band_set; ++ uint32 band; ++ uint32 count; ++ char country_abbrev[1]; ++} wl_country_list_t; ++ ++#define WL_RM_TYPE_BASIC 1 ++#define WL_RM_TYPE_CCA 2 ++#define WL_RM_TYPE_RPI 3 ++ ++#define WL_RM_FLAG_PARALLEL (1<<0) ++ ++#define WL_RM_FLAG_LATE (1<<1) ++#define WL_RM_FLAG_INCAPABLE (1<<2) ++#define WL_RM_FLAG_REFUSED (1<<3) ++ ++typedef struct wl_rm_req_elt { ++ int8 type; ++ int8 flags; ++ uint16 chanspec; ++ uint32 token; /* token for this measurement */ ++ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ ++ uint32 tsf_l; /* TSF low 32-bits */ ++ uint32 dur; /* TUs */ ++} wl_rm_req_elt_t; ++ ++typedef struct wl_rm_req { ++ uint32 token; /* overall measurement set token */ ++ uint32 count; /* number of measurement reqests */ ++ wl_rm_req_elt_t req[1]; /* variable length block of requests */ ++} wl_rm_req_t; ++#define WL_RM_REQ_FIXED_LEN 8 ++ ++typedef struct wl_rm_rep_elt { ++ int8 type; ++ int8 flags; ++ uint16 chanspec; ++ uint32 token; /* token for this measurement */ ++ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ ++ uint32 tsf_l; /* TSF low 32-bits */ ++ uint32 dur; /* TUs */ ++ uint32 len; /* byte length of data block */ ++ uint8 data[1]; /* variable length data block */ ++} wl_rm_rep_elt_t; ++#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ ++ ++#define WL_RPI_REP_BIN_NUM 8 ++typedef struct wl_rm_rpi_rep { ++ uint8 rpi[WL_RPI_REP_BIN_NUM]; ++ int8 rpi_max[WL_RPI_REP_BIN_NUM]; ++} wl_rm_rpi_rep_t; ++ ++typedef struct wl_rm_rep { ++ uint32 token; /* overall measurement set token */ ++ uint32 len; /* length of measurement report block */ ++ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ ++} wl_rm_rep_t; ++#define WL_RM_REP_FIXED_LEN 8 ++ ++ ++#if defined(BCMSUP_PSK) ++typedef enum sup_auth_status { ++ WLC_SUP_DISCONNECTED = 0, ++ WLC_SUP_CONNECTING, ++ WLC_SUP_IDREQUIRED, ++ WLC_SUP_AUTHENTICATING, ++ WLC_SUP_AUTHENTICATED, ++ WLC_SUP_KEYXCHANGE, ++ WLC_SUP_KEYED, ++ WLC_SUP_TIMEOUT ++} sup_auth_status_t; ++#endif /* BCMCCX | BCMSUP_PSK */ ++ ++/* Enumerate crypto algorithms */ ++#define CRYPTO_ALGO_OFF 0 ++#define CRYPTO_ALGO_WEP1 1 ++#define CRYPTO_ALGO_TKIP 2 ++#define CRYPTO_ALGO_WEP128 3 ++#define CRYPTO_ALGO_AES_CCM 4 ++#define CRYPTO_ALGO_AES_OCB_MSDU 5 ++#define CRYPTO_ALGO_AES_OCB_MPDU 6 ++#define CRYPTO_ALGO_NALG 7 ++ ++#define WSEC_GEN_MIC_ERROR 0x0001 ++#define WSEC_GEN_REPLAY 0x0002 ++ ++#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ ++#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ ++#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ ++#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ ++ ++typedef struct wl_wsec_key { ++ uint32 index; /* key index */ ++ uint32 len; /* key length */ ++ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ ++ uint32 pad_1[18]; ++ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ ++ uint32 flags; /* misc flags */ ++ uint32 pad_2[2]; ++ int pad_3; ++ int iv_initialized; /* has IV been initialized already? */ ++ int pad_4; ++ /* Rx IV */ ++ struct { ++ uint32 hi; /* upper 32 bits of IV */ ++ uint16 lo; /* lower 16 bits of IV */ ++ } rxiv; ++ uint32 pad_5[2]; ++ struct ether_addr ea; /* per station */ ++} wl_wsec_key_t; ++ ++ ++#define WSEC_MIN_PSK_LEN 8 ++#define WSEC_MAX_PSK_LEN 64 ++ ++/* Flag for key material needing passhash'ing */ ++#define WSEC_PASSPHRASE (1<<0) ++ ++/* recepticle for WLC_SET_WSEC_PMK parameter */ ++typedef struct { ++ ushort key_len; /* octets in key material */ ++ ushort flags; /* key handling qualification */ ++ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ ++} wsec_pmk_t; ++ ++/* wireless security bitvec */ ++#define WEP_ENABLED 0x0001 ++#define TKIP_ENABLED 0x0002 ++#define AES_ENABLED 0x0004 ++#define WSEC_SWFLAG 0x0008 ++#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ ++ ++/* WPA authentication mode bitvec */ ++#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ ++#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ ++#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ ++#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ ++/*#define WPA_AUTH_8021X 0x0020*/ /* 802.1x, reserved */ ++ ++#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ ++#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ ++ ++ ++ ++/* pmkid */ ++#define MAXPMKID 16 ++ ++typedef struct _pmkid ++{ ++ struct ether_addr BSSID; ++ uint8 PMKID[WPA2_PMKID_LEN]; ++} pmkid_t; ++ ++typedef struct _pmkid_list ++{ ++ uint32 npmkid; ++ pmkid_t pmkid[1]; ++} pmkid_list_t; ++ ++typedef struct _pmkid_cand { ++ struct ether_addr BSSID; ++ uint8 preauth; ++} pmkid_cand_t; ++ ++typedef struct _pmkid_cand_list { ++ uint32 npmkid_cand; ++ pmkid_cand_t pmkid_cand[1]; ++} pmkid_cand_list_t; ++ ++ ++typedef struct wl_led_info { ++ uint32 index; /* led index */ ++ uint32 behavior; ++ bool activehi; ++} wl_led_info_t; ++ ++typedef struct wlc_assoc_info { ++ uint32 req_len; ++ uint32 resp_len; ++ uint32 flags; ++ struct dot11_assoc_req req; ++ struct ether_addr reassoc_bssid; /* used in reassoc's */ ++ struct dot11_assoc_resp resp; ++} wl_assoc_info_t; ++/* flags */ ++#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ ++/* srom read/write struct passed through ioctl */ ++typedef struct { ++ uint byteoff; /* byte offset */ ++ uint nbytes; /* number of bytes */ ++ uint16 buf[1]; ++} srom_rw_t; ++ ++/* R_REG and W_REG struct passed through ioctl */ ++typedef struct { ++ uint32 byteoff; /* byte offset of the field in d11regs_t */ ++ uint32 val; /* read/write value of the field */ ++ uint32 size; /* sizeof the field */ ++ uint band; /* band (optional) */ ++} rw_reg_t; ++ ++/* Structure used by GET/SET_ATTEN ioctls */ ++typedef struct { ++ uint16 auto_ctrl; /* 1: Automatic control, 0: overriden */ ++ uint16 bb; /* Baseband attenuation */ ++ uint16 radio; /* Radio attenuation */ ++ uint16 txctl1; /* Radio TX_CTL1 value */ ++} atten_t; ++ ++/* Used to get specific STA parameters */ ++typedef struct { ++ uint32 val; ++ struct ether_addr ea; ++} scb_val_t; ++ ++ ++/* Event data type */ ++typedef struct wlc_event { ++ wl_event_msg_t event; /* encapsulated event */ ++ struct ether_addr *addr; /* used to keep a trace of the potential present of ++ an address in wlc_event_msg_t */ ++ void *data; /* used to hang additional data on an event */ ++ struct wlc_event *next; /* enables ordered list of pending events */ ++} wlc_event_t; ++ ++#define BCM_MAC_STATUS_INDICATION (0x40010200L) ++ ++typedef struct { ++ uint16 ver; /* version of this struct */ ++ uint16 len; /* length in bytes of this structure */ ++ uint16 cap; /* sta's advertized capabilities */ ++ uint32 flags; /* flags defined below */ ++ uint32 idle; /* time since data pkt rx'd from sta */ ++ struct ether_addr ea; /* Station address */ ++ wl_rateset_t rateset; /* rateset in use */ ++ uint32 in; /* seconds elapsed since associated */ ++ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA*/ ++} sta_info_t; ++ ++#define WL_STA_VER 2 ++ ++/* flags fields */ ++#define WL_STA_BRCM 0x01 ++#define WL_STA_WME 0x02 ++#define WL_STA_ABCAP 0x04 ++#define WL_STA_AUTHE 0x08 ++#define WL_STA_ASSOC 0x10 ++#define WL_STA_AUTHO 0x20 ++#define WL_STA_WDS 0x40 ++#define WL_WDS_LINKUP 0x80 ++ ++ ++/* ++ * Country locale determines which channels are available to us. ++ */ ++typedef enum _wlc_locale { ++ WLC_WW = 0, /* Worldwide */ ++ WLC_THA, /* Thailand */ ++ WLC_ISR, /* Israel */ ++ WLC_JDN, /* Jordan */ ++ WLC_PRC, /* China */ ++ WLC_JPN, /* Japan */ ++ WLC_FCC, /* USA */ ++ WLC_EUR, /* Europe */ ++ WLC_USL, /* US Low Band only */ ++ WLC_JPH, /* Japan High Band only */ ++ WLC_ALL, /* All the channels in this band */ ++ WLC_11D, /* Represents locale recieved by 11d beacons */ ++ WLC_LAST_LOCALE, ++ WLC_UNDEFINED_LOCALE = 0xf ++} wlc_locale_t; ++ ++/* channel encoding */ ++typedef struct channel_info { ++ int hw_channel; ++ int target_channel; ++ int scan_channel; ++} channel_info_t; ++ ++/* For ioctls that take a list of MAC addresses */ ++struct maclist { ++ uint count; /* number of MAC addresses */ ++ struct ether_addr ea[1]; /* variable length array of MAC addresses */ ++}; ++ ++/* get pkt count struct passed through ioctl */ ++typedef struct get_pktcnt { ++ uint rx_good_pkt; ++ uint rx_bad_pkt; ++ uint tx_good_pkt; ++ uint tx_bad_pkt; ++} get_pktcnt_t; ++ ++/* Linux network driver ioctl encoding */ ++typedef struct wl_ioctl { ++ uint cmd; /* common ioctl definition */ ++ void *buf; /* pointer to user buffer */ ++ uint len; /* length of user buffer */ ++ bool set; /* get or set request (optional) */ ++ uint used; /* bytes read or written (optional) */ ++ uint needed; /* bytes needed (optional) */ ++} wl_ioctl_t; ++ ++/* ++ * Structure for passing hardware and software ++ * revision info up from the driver. ++ */ ++typedef struct wlc_rev_info { ++ uint vendorid; /* PCI vendor id */ ++ uint deviceid; /* device id of chip */ ++ uint radiorev; /* radio revision */ ++ uint chiprev; /* chip revision */ ++ uint corerev; /* core revision */ ++ uint boardid; /* board identifier (usu. PCI sub-device id) */ ++ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ ++ uint boardrev; /* board revision */ ++ uint driverrev; /* driver version */ ++ uint ucoderev; /* microcode version */ ++ uint bus; /* bus type */ ++ uint chipnum; /* chip number */ ++} wlc_rev_info_t; ++ ++#define WL_BRAND_MAX 10 ++typedef struct wl_instance_info { ++ uint instance; ++ char brand[WL_BRAND_MAX]; ++} wl_instance_info_t; ++ ++/* check this magic number */ ++#define WLC_IOCTL_MAGIC 0x14e46c77 ++ ++/* bump this number if you change the ioctl interface */ ++#define WLC_IOCTL_VERSION 1 ++ ++#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ ++#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ ++ ++/* common ioctl definitions */ ++#define WLC_GET_MAGIC 0 ++#define WLC_GET_VERSION 1 ++#define WLC_UP 2 ++#define WLC_DOWN 3 ++#define WLC_DUMP 6 ++#define WLC_GET_MSGLEVEL 7 ++#define WLC_SET_MSGLEVEL 8 ++#define WLC_GET_PROMISC 9 ++#define WLC_SET_PROMISC 10 ++#define WLC_GET_RATE 12 ++/* #define WLC_SET_RATE 13 */ /* no longer supported */ ++#define WLC_GET_INSTANCE 14 ++/* #define WLC_GET_FRAG 15 */ /* no longer supported */ ++/* #define WLC_SET_FRAG 16 */ /* no longer supported */ ++/* #define WLC_GET_RTS 17 */ /* no longer supported */ ++/* #define WLC_SET_RTS 18 */ /* no longer supported */ ++#define WLC_GET_INFRA 19 ++#define WLC_SET_INFRA 20 ++#define WLC_GET_AUTH 21 ++#define WLC_SET_AUTH 22 ++#define WLC_GET_BSSID 23 ++#define WLC_SET_BSSID 24 ++#define WLC_GET_SSID 25 ++#define WLC_SET_SSID 26 ++#define WLC_RESTART 27 ++#define WLC_GET_CHANNEL 29 ++#define WLC_SET_CHANNEL 30 ++#define WLC_GET_SRL 31 ++#define WLC_SET_SRL 32 ++#define WLC_GET_LRL 33 ++#define WLC_SET_LRL 34 ++#define WLC_GET_PLCPHDR 35 ++#define WLC_SET_PLCPHDR 36 ++#define WLC_GET_RADIO 37 ++#define WLC_SET_RADIO 38 ++#define WLC_GET_PHYTYPE 39 ++/* #define WLC_GET_WEP 42 */ /* no longer supported */ ++/* #define WLC_SET_WEP 43 */ /* no longer supported */ ++#define WLC_GET_KEY 44 ++#define WLC_SET_KEY 45 ++#define WLC_GET_REGULATORY 46 ++#define WLC_SET_REGULATORY 47 ++#define WLC_SCAN 50 ++#define WLC_SCAN_RESULTS 51 ++#define WLC_DISASSOC 52 ++#define WLC_REASSOC 53 ++#define WLC_GET_ROAM_TRIGGER 54 ++#define WLC_SET_ROAM_TRIGGER 55 ++#define WLC_GET_TXANT 61 ++#define WLC_SET_TXANT 62 ++#define WLC_GET_ANTDIV 63 ++#define WLC_SET_ANTDIV 64 ++/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ ++/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ ++#define WLC_GET_CLOSED 67 ++#define WLC_SET_CLOSED 68 ++#define WLC_GET_MACLIST 69 ++#define WLC_SET_MACLIST 70 ++#define WLC_GET_RATESET 71 ++#define WLC_SET_RATESET 72 ++#define WLC_GET_LOCALE 73 ++#define WLC_LONGTRAIN 74 ++#define WLC_GET_BCNPRD 75 ++#define WLC_SET_BCNPRD 76 ++#define WLC_GET_DTIMPRD 77 ++#define WLC_SET_DTIMPRD 78 ++#define WLC_GET_SROM 79 ++#define WLC_SET_SROM 80 ++#define WLC_GET_WEP_RESTRICT 81 ++#define WLC_SET_WEP_RESTRICT 82 ++#define WLC_GET_COUNTRY 83 ++#define WLC_SET_COUNTRY 84 ++#define WLC_GET_REVINFO 98 ++#define WLC_GET_MACMODE 105 ++#define WLC_SET_MACMODE 106 ++#define WLC_GET_GMODE 109 ++#define WLC_SET_GMODE 110 ++#define WLC_GET_CURR_RATESET 114 /* current rateset */ ++#define WLC_GET_SCANSUPPRESS 115 ++#define WLC_SET_SCANSUPPRESS 116 ++#define WLC_GET_AP 117 ++#define WLC_SET_AP 118 ++#define WLC_GET_EAP_RESTRICT 119 ++#define WLC_SET_EAP_RESTRICT 120 ++#define WLC_GET_WDSLIST 123 ++#define WLC_SET_WDSLIST 124 ++#define WLC_GET_RSSI 127 ++#define WLC_GET_WSEC 133 ++#define WLC_SET_WSEC 134 ++#define WLC_GET_BSS_INFO 136 ++#define WLC_GET_LAZYWDS 138 ++#define WLC_SET_LAZYWDS 139 ++#define WLC_GET_BANDLIST 140 ++#define WLC_GET_BAND 141 ++#define WLC_SET_BAND 142 ++#define WLC_GET_SHORTSLOT 144 ++#define WLC_GET_SHORTSLOT_OVERRIDE 145 ++#define WLC_SET_SHORTSLOT_OVERRIDE 146 ++#define WLC_GET_SHORTSLOT_RESTRICT 147 ++#define WLC_SET_SHORTSLOT_RESTRICT 148 ++#define WLC_GET_GMODE_PROTECTION 149 ++#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 ++#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 ++#define WLC_UPGRADE 152 ++/* #define WLC_GET_MRATE 153 */ /* no longer supported */ ++/* #define WLC_SET_MRATE 154 */ /* no longer supported */ ++#define WLC_GET_ASSOCLIST 159 ++#define WLC_GET_CLK 160 ++#define WLC_SET_CLK 161 ++#define WLC_GET_UP 162 ++#define WLC_OUT 163 ++#define WLC_GET_WPA_AUTH 164 ++#define WLC_SET_WPA_AUTH 165 ++#define WLC_GET_GMODE_PROTECTION_CONTROL 178 ++#define WLC_SET_GMODE_PROTECTION_CONTROL 179 ++#define WLC_GET_PHYLIST 180 ++#define WLC_GET_KEY_SEQ 183 ++#define WLC_GET_GMODE_PROTECTION_CTS 198 ++#define WLC_SET_GMODE_PROTECTION_CTS 199 ++#define WLC_GET_PIOMODE 203 ++#define WLC_SET_PIOMODE 204 ++#define WLC_SET_LED 209 ++#define WLC_GET_LED 210 ++#define WLC_GET_CHANNEL_SEL 215 ++#define WLC_START_CHANNEL_SEL 216 ++#define WLC_GET_VALID_CHANNELS 217 ++#define WLC_GET_FAKEFRAG 218 ++#define WLC_SET_FAKEFRAG 219 ++#define WLC_GET_WET 230 ++#define WLC_SET_WET 231 ++#define WLC_GET_KEY_PRIMARY 235 ++#define WLC_SET_KEY_PRIMARY 236 ++#define WLC_GET_RADAR 242 ++#define WLC_SET_RADAR 243 ++#define WLC_SET_SPECT_MANAGMENT 244 ++#define WLC_GET_SPECT_MANAGMENT 245 ++#define WLC_WDS_GET_REMOTE_HWADDR 246 /* currently handled in wl_linux.c/wl_vx.c */ ++#define WLC_SET_CS_SCAN_TIMER 248 ++#define WLC_GET_CS_SCAN_TIMER 249 ++#define WLC_SEND_PWR_CONSTRAINT 254 ++#define WLC_CURRENT_PWR 256 ++#define WLC_GET_CHANNELS_IN_COUNTRY 260 ++#define WLC_GET_COUNTRY_LIST 261 ++#define WLC_GET_VAR 262 /* get value of named variable */ ++#define WLC_SET_VAR 263 /* set named variable to value */ ++#define WLC_NVRAM_GET 264 ++#define WLC_NVRAM_SET 265 ++#define WLC_SET_WSEC_PMK 268 ++#define WLC_GET_AUTH_MODE 269 ++#define WLC_SET_AUTH_MODE 270 ++#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ ++#define WLC_NVOTPW 274 ++/* #define WLC_OTPW 275 */ /* no longer supported */ ++#define WLC_SET_LOCALE 278 ++#define WLC_LAST 279 /* do not change - use get_var/set_var */ ++ ++/* ++ * Minor kludge alert: ++ * Duplicate a few definitions that irelay requires from epiioctl.h here ++ * so caller doesn't have to include this file and epiioctl.h . ++ * If this grows any more, it would be time to move these irelay-specific ++ * definitions out of the epiioctl.h and into a separate driver common file. ++ */ ++#ifndef EPICTRL_COOKIE ++#define EPICTRL_COOKIE 0xABADCEDE ++#endif ++ ++/* vx wlc ioctl's offset */ ++#define CMN_IOCTL_OFF 0x180 ++ ++/* ++ * custom OID support ++ * ++ * 0xFF - implementation specific OID ++ * 0xE4 - first byte of Broadcom PCI vendor ID ++ * 0x14 - second byte of Broadcom PCI vendor ID ++ * 0xXX - the custom OID number ++ */ ++ ++/* begin 0x1f values beyond the start of the ET driver range. */ ++#define WL_OID_BASE 0xFFE41420 ++ ++/* NDIS overrides */ ++#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) ++#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) ++ ++#define WL_DECRYPT_STATUS_SUCCESS 1 ++#define WL_DECRYPT_STATUS_FAILURE 2 ++#define WL_DECRYPT_STATUS_UNKNOWN 3 ++ ++/* allows user-mode app to poll the status of USB image upgrade */ ++#define WLC_UPGRADE_SUCCESS 0 ++#define WLC_UPGRADE_PENDING 1 ++ ++#ifdef CONFIG_USBRNDIS_RETAIL ++/* struct passed in for WLC_NDCONFIG_ITEM */ ++typedef struct { ++ char *name; ++ void *param; ++} ndconfig_item_t; ++#endif ++ ++/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ ++#define WL_RADIO_SW_DISABLE (1<<0) ++#define WL_RADIO_HW_DISABLE (1<<1) ++#define WL_RADIO_MPC_DISABLE (1<<2) ++#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any 802.11 channel */ ++ ++/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ ++#define WL_TXPWR_OVERRIDE (1<<31) ++ ++/* "diag" iovar argument and error code */ ++#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ ++#define WL_DIAG_MEMORY 3 /* d11 memory test */ ++#define WL_DIAG_LED 4 /* LED test */ ++#define WL_DIAG_REG 5 /* d11/phy register test */ ++#define WL_DIAG_SROM 6 /* srom read/crc test */ ++#define WL_DIAG_DMA 7 /* DMA test */ ++ ++#define WL_DIAGERR_SUCCESS 0 ++#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ ++#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ ++#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ ++#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ ++#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ ++#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ ++#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ ++#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ ++#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ ++#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ ++ ++/* Bus types */ ++#define WL_SB_BUS 0 /* Silicon Backplane */ ++#define WL_PCI_BUS 1 /* PCI target */ ++#define WL_PCMCIA_BUS 2 /* PCMCIA target */ ++ ++/* band types */ ++#define WLC_BAND_AUTO 0 /* auto-select */ ++#define WLC_BAND_A 1 /* "a" band (5 Ghz) */ ++#define WLC_BAND_B 2 /* "b" band (2.4 Ghz) */ ++#define WLC_BAND_ALL 3 /* all bands */ ++ ++/* phy types (returned by WLC_GET_PHYTPE) */ ++#define WLC_PHY_TYPE_A 0 ++#define WLC_PHY_TYPE_B 1 ++#define WLC_PHY_TYPE_G 2 ++#define WLC_PHY_TYPE_NULL 0xf ++ ++/* MAC list modes */ ++#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ ++#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ ++#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ ++ ++/* ++ * ++ */ ++#define GMODE_LEGACY_B 0 ++#define GMODE_AUTO 1 ++#define GMODE_ONLY 2 ++#define GMODE_B_DEFERRED 3 ++#define GMODE_PERFORMANCE 4 ++#define GMODE_LRS 5 ++#define GMODE_MAX 6 ++ ++/* values for PLCPHdr_override */ ++#define WLC_PLCP_AUTO -1 ++#define WLC_PLCP_SHORT 0 ++#define WLC_PLCP_LONG 1 ++ ++/* values for g_protection_override */ ++#define WLC_G_PROTECTION_AUTO -1 ++#define WLC_G_PROTECTION_OFF 0 ++#define WLC_G_PROTECTION_ON 1 ++ ++/* values for g_protection_control */ ++#define WLC_G_PROTECTION_CTL_OFF 0 ++#define WLC_G_PROTECTION_CTL_LOCAL 1 ++#define WLC_G_PROTECTION_CTL_OVERLAP 2 ++ ++/* Values for PM */ ++#define PM_OFF 0 ++#define PM_MAX 1 ++#define PM_FAST 2 ++ ++ ++ ++typedef struct { ++ int npulses; /* required number of pulses at n * t_int */ ++ int ncontig; /* required number of pulses at t_int */ ++ int min_pw; /* minimum pulse width (20 MHz clocks) */ ++ int max_pw; /* maximum pulse width (20 MHz clocks) */ ++ uint16 thresh0; /* Radar detection, thresh 0 */ ++ uint16 thresh1; /* Radar detection, thresh 1 */ ++} wl_radar_args_t; ++ ++/* radar iovar SET defines */ ++#define WL_RADRA_DETECTOR_OFF 0 /* radar dector off */ ++#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ ++#define WL_RADAR_SIMULATED 2 /* force radar detector to declare detection once */ ++ ++/* dfs_status iovar-related defines */ ++ ++/* cac - channel availability check, ++ * ism - in-service monitoring ++ * csa - channel switching anouncement ++ */ ++ ++/* cac state values */ ++#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ ++#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ ++#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ ++#define WL_DFS_CACSTATE_CSA 3 /* csa */ ++#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ ++#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ ++#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ ++#define WL_DFS_CACSTATES 7 /* this many states exist */ ++ ++/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ ++typedef struct { ++ uint state; /* noted by WL_DFS_CACSTATE_XX. */ ++ uint duration; /* time spent in ms in state. */ ++ /* as dfs enters ISM state, it removes the operational channel from quiet channel list ++ * and notes the channel in channel_cleared. set to 0 if no channel is cleared ++ */ ++ uint channel_cleared; ++} wl_dfs_status_t; ++ ++#define NUM_PWRCTRL_RATES 12 ++ ++ ++/* 802.11h enforcement levels */ ++#define SPECT_MNGMT_OFF 0 /* 11h disabled */ ++#define SPECT_MNGMT_LOOSE 1 /* allow scan lists to contain non-11h AP */ ++#define SPECT_MNGMT_STRICT 2 /* prune out non-11h APs from scan list */ ++#define SPECT_MNGMT_11D 3 /* switch to 802.11D mode */ ++ ++#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ ++#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ ++#define WL_CHAN_BAND_A (1 << 2) /* A-band channel */ ++#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ ++#define WL_CHAN_INACTIVE (1 << 4) /* temporarily out of service due to radar */ ++#define WL_CHAN_RADAR_PASSIVE (1 << 5) /* radar channel is in passive mode */ ++ ++#define WL_MPC_VAL 0x00400000 ++#define WL_APSTA_VAL 0x00800000 ++#define WL_DFS_VAL 0x01000000 ++ ++/* max # of leds supported by GPIO (gpio pin# == led index#) */ ++#define WL_LED_NUMGPIO 16 /* gpio 0-15 */ ++ ++/* led per-pin behaviors */ ++#define WL_LED_OFF 0 /* always off */ ++#define WL_LED_ON 1 /* always on */ ++#define WL_LED_ACTIVITY 2 /* activity */ ++#define WL_LED_RADIO 3 /* radio enabled */ ++#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ ++#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ ++#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ ++#define WL_LED_WI1 7 ++#define WL_LED_WI2 8 ++#define WL_LED_WI3 9 ++#define WL_LED_ASSOC 10 /* associated state indicator */ ++#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ ++#define WL_LED_NUMBEHAVIOR 12 ++ ++/* led behavior numeric value format */ ++#define WL_LED_BEH_MASK 0x7f /* behavior mask */ ++#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ ++ ++ ++/* WDS link local endpoint WPA role */ ++#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ ++#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ ++#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ ++ ++/* number of bytes needed to define a 128-bit mask for MAC event reporting */ ++#define WL_EVENTING_MASK_LEN 16 ++ ++/* Structures and constants used for "vndr_ie" IOVar interface */ ++#define VNDR_IE_CMD_LEN 4 /* length of the set command string: "add", "del" (+ NULL) */ ++ ++/* 802.11 Mgmt Packet flags */ ++#define VNDR_IE_BEACON_FLAG 0x1 ++#define VNDR_IE_PRBRSP_FLAG 0x2 ++#define VNDR_IE_ASSOCRSP_FLAG 0x4 ++#define VNDR_IE_AUTHRSP_FLAG 0x8 ++ ++typedef struct { ++ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ ++ vndr_ie_t vndr_ie_data; /* vendor IE data */ ++} vndr_ie_info_t; ++ ++typedef struct { ++ int iecount; /* number of entries in the vndr_ie_list[] array */ ++ vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ ++} vndr_ie_buf_t; ++ ++typedef struct { ++ char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NULL */ ++ vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ ++} vndr_ie_setbuf_t; ++ ++/* join target preference types */ ++#define WL_JOIN_PREF_RSSI 1 /* by RSSI, mandatory */ ++#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers, optional, RSN and WPA as values */ ++#define WL_JOIN_PREF_BAND 3 /* by 802.11 band, optional, WLC_BAND_XXXX as values */ ++ ++/* band preference */ ++#define WLJP_BAND_ASSOC_PREF 255 /* use assoc preference settings */ ++ /* others use WLC_BAND_XXXX as values */ ++ ++/* any multicast cipher suite */ ++#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" ++ ++#if !defined(__GNUC__) ++#pragma pack(pop) ++#endif ++ ++#define NFIFO 6 /* # tx/rx fifopairs */ ++ ++#define WL_CNT_T_VERSION 1 /* current version of wl_cnt_t struct */ ++ ++typedef struct { ++ uint16 version; /* see definition of WL_CNT_T_VERSION */ ++ uint16 length; /* length of entire structure */ ++ ++ /* transmit stat counters */ ++ uint32 txframe; /* tx data frames */ ++ uint32 txbyte; /* tx data bytes */ ++ uint32 txretrans; /* tx mac retransmits */ ++ uint32 txerror; /* tx data errors */ ++ uint32 txctl; /* tx management frames */ ++ uint32 txprshort; /* tx short preamble frames */ ++ uint32 txserr; /* tx status errors */ ++ uint32 txnobuf; /* tx out of buffers errors */ ++ uint32 txnoassoc; /* tx discard because we're not associated */ ++ uint32 txrunt; /* tx runt frames */ ++ uint32 txchit; /* tx header cache hit (fastpath) */ ++ uint32 txcmiss; /* tx header cache miss (slowpath) */ ++ ++ /* transmit chip error counters */ ++ uint32 txuflo; /* tx fifo underflows */ ++ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ ++ uint32 txphycrs; ++ ++ /* receive stat counters */ ++ uint32 rxframe; /* rx data frames */ ++ uint32 rxbyte; /* rx data bytes */ ++ uint32 rxerror; /* rx data errors */ ++ uint32 rxctl; /* rx management frames */ ++ uint32 rxnobuf; /* rx out of buffers errors */ ++ uint32 rxnondata; /* rx non data frames in the data channel errors */ ++ uint32 rxbadds; /* rx bad DS errors */ ++ uint32 rxbadcm; /* rx bad control or management frames */ ++ uint32 rxfragerr; /* rx fragmentation errors */ ++ uint32 rxrunt; /* rx runt frames */ ++ uint32 rxgiant; /* rx giant frames */ ++ uint32 rxnoscb; /* rx no scb error */ ++ uint32 rxbadproto; /* rx invalid frames */ ++ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac*/ ++ uint32 rxbadda; /* rx frames tossed for invalid da */ ++ uint32 rxfilter; /* rx frames filtered out */ ++ ++ /* receive chip error counters */ ++ uint32 rxoflo; /* rx fifo overflow errors */ ++ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ ++ ++ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ ++ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ ++ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ ++ ++ /* misc counters */ ++ uint32 dmade; /* tx/rx dma descriptor errors */ ++ uint32 dmada; /* tx/rx dma data errors */ ++ uint32 dmape; /* tx/rx dma descriptor protocol errors */ ++ uint32 reset; /* reset count */ ++ uint32 tbtt; /* cnts the TBTT int's */ ++ uint32 txdmawar; ++ ++ /* MAC counters: 32-bit version of d11.h's macstat_t */ ++ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, ++ Control Management (includes retransmissions) */ ++ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ ++ uint32 txctsfrm; /* number of CTS sent out by the MAC */ ++ uint32 txackfrm; /* number of ACK frames sent out */ ++ uint32 txdnlfrm; /* Not used */ ++ uint32 txbcnfrm; /* beacons transmitted */ ++ uint32 txfunfl[8]; /* per-fifo tx underflows */ ++ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS or BCN) */ ++ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for ++ driver enqueued frames*/ ++ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ ++ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ ++ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not ++ data/control/management*/ ++ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ ++ uint32 rxbadplcp; /* parity check of the PLCP header failed */ ++ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ ++ uint32 rxstrt; /* Number of received frames with a good PLCP (i.e. passing parity check) */ ++ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ ++ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ ++ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ ++ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ ++ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS)*/ ++ uint32 rxackucast; /* number of ucast ACKS received (good FCS)*/ ++ uint32 rxdfrmocast; /* number of received DATA frames with good FCS and not matching RA */ ++ uint32 rxmfrmocast; /* number of received MGMT frames with good FCS and not matching RA */ ++ uint32 rxcfrmocast; /* number of received CNTRL frame with good FCS and not matching RA */ ++ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ ++ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ ++ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ ++ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ ++ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC (unlikely ++ to see these) */ ++ uint32 rxbeaconmbss; /* beacons received from member of BSS */ ++ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from other BSS (WDS FRAME) */ ++ uint32 rxbeaconobss; /* beacons received from other BSS */ ++ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames expecting a ++ response */ ++ uint32 bcntxcancl; /* transmit beacons cancelled due to receipt of beacon (IBSS) */ ++ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ ++ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ ++ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ ++ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ ++ uint32 pmqovfl; /* Number of PMQ overflows */ ++ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into the PRQ fifo */ ++ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ ++ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did not get ACK */ ++ uint32 txcgprssuc; /* Tx Probe Rresponse Success (ACK was received) */ ++ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ fifo because ++ a probe response could not be sent out within the time limit defined ++ in M_PRS_MAXTIME */ ++ uint32 rxnack; /* Number of NACKS received (Afterburner) */ ++ uint32 frmscons; /* Number of frames completed without transmission because of an ++ Afterburner re-queue */ ++ uint32 txnack; /* Number of NACKs transmtitted (Afterburner) */ ++ uint32 txglitch_nack; /* obsolete */ ++ uint32 txburst; /* obsolete */ ++ uint32 rxburst; /* obsolete */ ++ ++ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ ++ uint32 txfrag; /* dot11TransmittedFragmentCount */ ++ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ ++ uint32 txfail; /* dot11FailedCount */ ++ uint32 txretry; /* dot11RetryCount */ ++ uint32 txretrie; /* dot11MultipleRetryCount */ ++ uint32 rxdup; /* dot11FrameduplicateCount */ ++ uint32 txrts; /* dot11RTSSuccessCount */ ++ uint32 txnocts; /* dot11RTSFailureCount */ ++ uint32 txnoack; /* dot11ACKFailureCount */ ++ uint32 rxfrag; /* dot11ReceivedFragmentCount */ ++ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ ++ uint32 rxcrc; /* dot11FCSErrorCount */ ++ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ ++ uint32 rxundec; /* dot11WEPUndecryptableCount */ ++ ++ /* WPA2 counters (see rxundec for DecryptFailureCount) */ ++ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ ++ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ ++ uint32 tkipreplay; /* TKIPReplays */ ++ uint32 ccmpfmterr; /* CCMPFormatErrors */ ++ uint32 ccmpreplay; /* CCMPReplays */ ++ uint32 ccmpundec; /* CCMPDecryptErrors */ ++ uint32 fourwayfail; /* FourWayHandshakeFailures */ ++ uint32 wepundec; /* dot11WEPUndecryptableCount */ ++ uint32 wepicverr; /* dot11WEPICVErrorCount */ ++ uint32 decsuccess; /* DecryptSuccessCount */ ++ uint32 tkipicverr; /* TKIPICVErrorCount */ ++ uint32 wepexcluded; /* dot11WEPExcludedCount */ ++} wl_cnt_t; ++ ++#endif /* _wlioctl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile +--- linux-2.4.32/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile 2005-12-19 01:56:51.733868750 +0100 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++ ++EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ ++O_TARGET := bcm947xx.o ++ ++export-objs := nvram_linux.o setup.o ++obj-y := prom.o setup.o time.o sbmips.o gpio.o ++obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o ++obj-$(CONFIG_PCI) += sbpci.o pcibios.o ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c +--- linux-2.4.32/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c 2005-12-19 01:05:00.079582750 +0100 +@@ -0,0 +1,320 @@ ++/* ++ * NVRAM variable manipulation (common) ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value); ++extern void BCMINIT(_nvram_free)(struct nvram_tuple *t); ++extern int BCMINIT(_nvram_read)(void *buf); ++ ++char * BCMINIT(_nvram_get)(const char *name); ++int BCMINIT(_nvram_set)(const char *name, const char *value); ++int BCMINIT(_nvram_unset)(const char *name); ++int BCMINIT(_nvram_getall)(char *buf, int count); ++int BCMINIT(_nvram_commit)(struct nvram_header *header); ++int BCMINIT(_nvram_init)(void); ++void BCMINIT(_nvram_exit)(void); ++ ++static struct nvram_tuple * BCMINITDATA(nvram_hash)[257]; ++static struct nvram_tuple * nvram_dead; ++ ++/* Free all tuples. Should be locked. */ ++static void ++BCMINITFN(nvram_free)(void) ++{ ++ uint i; ++ struct nvram_tuple *t, *next; ++ ++ /* Free hash table */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = next) { ++ next = t->next; ++ BCMINIT(_nvram_free)(t); ++ } ++ BCMINIT(nvram_hash)[i] = NULL; ++ } ++ ++ /* Free dead table */ ++ for (t = nvram_dead; t; t = next) { ++ next = t->next; ++ BCMINIT(_nvram_free)(t); ++ } ++ nvram_dead = NULL; ++ ++ /* Indicate to per-port code that all tuples have been freed */ ++ BCMINIT(_nvram_free)(NULL); ++} ++ ++/* String hash */ ++static INLINE uint ++hash(const char *s) ++{ ++ uint hash = 0; ++ ++ while (*s) ++ hash = 31 * hash + *s++; ++ ++ return hash; ++} ++ ++/* (Re)initialize the hash table. Should be locked. */ ++static int ++BCMINITFN(nvram_rehash)(struct nvram_header *header) ++{ ++ char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq; ++ ++ /* (Re)initialize hash table */ ++ BCMINIT(nvram_free)(); ++ ++ /* Parse and set "name=value\0 ... \0\0" */ ++ name = (char *) &header[1]; ++ end = (char *) header + NVRAM_SPACE - 2; ++ end[0] = end[1] = '\0'; ++ for (; *name; name = value + strlen(value) + 1) { ++ if (!(eq = strchr(name, '='))) ++ break; ++ *eq = '\0'; ++ value = eq + 1; ++ BCMINIT(_nvram_set)(name, value); ++ *eq = '='; ++ } ++ ++ /* Set special SDRAM parameters */ ++ if (!BCMINIT(_nvram_get)("sdram_init")) { ++ sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16)); ++ BCMINIT(_nvram_set)("sdram_init", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_config")) { ++ sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff)); ++ BCMINIT(_nvram_set)("sdram_config", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_refresh")) { ++ sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff)); ++ BCMINIT(_nvram_set)("sdram_refresh", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_ncdl")) { ++ sprintf(buf, "0x%08X", header->config_ncdl); ++ BCMINIT(_nvram_set)("sdram_ncdl", buf); ++ } ++ ++ return 0; ++} ++ ++/* Get the value of an NVRAM variable. Should be locked. */ ++char * ++BCMINITFN(_nvram_get)(const char *name) ++{ ++ uint i; ++ struct nvram_tuple *t; ++ char *value; ++ ++ if (!name) ++ return NULL; ++ ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (t = BCMINIT(nvram_hash)[i]; t && strcmp(t->name, name); t = t->next); ++ ++ value = t ? t->value : NULL; ++ ++ return value; ++} ++ ++/* Get the value of an NVRAM variable. Should be locked. */ ++int ++BCMINITFN(_nvram_set)(const char *name, const char *value) ++{ ++ uint i; ++ struct nvram_tuple *t, *u, **prev; ++ ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); ++ ++ /* (Re)allocate tuple */ ++ if (!(u = BCMINIT(_nvram_realloc)(t, name, value))) ++ return -12; /* -ENOMEM */ ++ ++ /* Value reallocated */ ++ if (t && t == u) ++ return 0; ++ ++ /* Move old tuple to the dead table */ ++ if (t) { ++ *prev = t->next; ++ t->next = nvram_dead; ++ nvram_dead = t; ++ } ++ ++ /* Add new tuple to the hash table */ ++ u->next = BCMINIT(nvram_hash)[i]; ++ BCMINIT(nvram_hash)[i] = u; ++ ++ return 0; ++} ++ ++/* Unset the value of an NVRAM variable. Should be locked. */ ++int ++BCMINITFN(_nvram_unset)(const char *name) ++{ ++ uint i; ++ struct nvram_tuple *t, **prev; ++ ++ if (!name) ++ return 0; ++ ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); ++ ++ /* Move it to the dead table */ ++ if (t) { ++ *prev = t->next; ++ t->next = nvram_dead; ++ nvram_dead = t; ++ } ++ ++ return 0; ++} ++ ++/* Get all NVRAM variables. Should be locked. */ ++int ++BCMINITFN(_nvram_getall)(char *buf, int count) ++{ ++ uint i; ++ struct nvram_tuple *t; ++ int len = 0; ++ ++ bzero(buf, count); ++ ++ /* Write name=value\0 ... \0\0 */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { ++ if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1)) ++ len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1; ++ else ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++/* Regenerate NVRAM. Should be locked. */ ++int ++BCMINITFN(_nvram_commit)(struct nvram_header *header) ++{ ++ char *init, *config, *refresh, *ncdl; ++ char *ptr, *end; ++ int i; ++ struct nvram_tuple *t; ++ struct nvram_header tmp; ++ uint8 crc; ++ ++ /* Regenerate header */ ++ header->magic = NVRAM_MAGIC; ++ header->crc_ver_init = (NVRAM_VERSION << 8); ++ if (!(init = BCMINIT(_nvram_get)("sdram_init")) || ++ !(config = BCMINIT(_nvram_get)("sdram_config")) || ++ !(refresh = BCMINIT(_nvram_get)("sdram_refresh")) || ++ !(ncdl = BCMINIT(_nvram_get)("sdram_ncdl"))) { ++ header->crc_ver_init |= SDRAM_INIT << 16; ++ header->config_refresh = SDRAM_CONFIG; ++ header->config_refresh |= SDRAM_REFRESH << 16; ++ header->config_ncdl = 0; ++ } else { ++ header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16; ++ header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff; ++ header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16; ++ header->config_ncdl = bcm_strtoul(ncdl, NULL, 0); ++ } ++ ++ /* Clear data area */ ++ ptr = (char *) header + sizeof(struct nvram_header); ++ bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header)); ++ ++ /* Leave space for a double NUL at the end */ ++ end = (char *) header + NVRAM_SPACE - 2; ++ ++ /* Write out all tuples */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { ++ if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) ++ break; ++ ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; ++ } ++ } ++ ++ /* End with a double NUL */ ++ ptr += 2; ++ ++ /* Set new length */ ++ header->len = ROUNDUP(ptr - (char *) header, 4); ++ ++ /* Little-endian CRC8 over the last 11 bytes of the header */ ++ tmp.crc_ver_init = htol32(header->crc_ver_init); ++ tmp.config_refresh = htol32(header->config_refresh); ++ tmp.config_ncdl = htol32(header->config_ncdl); ++ crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE); ++ ++ /* Continue CRC8 over data bytes */ ++ crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc); ++ ++ /* Set new CRC8 */ ++ header->crc_ver_init |= crc; ++ ++ /* Reinitialize hash table */ ++ return BCMINIT(nvram_rehash)(header); ++} ++ ++/* Initialize hash table. Should be locked. */ ++int ++BCMINITFN(_nvram_init)(void) ++{ ++ struct nvram_header *header; ++ int ret; ++ void *osh; ++ ++ /* get kernel osl handler */ ++ osh = osl_attach(NULL); ++ ++ if (!(header = (struct nvram_header *) MALLOC(osh, NVRAM_SPACE))) { ++ printf("nvram_init: out of memory, malloced %d bytes\n", MALLOCED(osh)); ++ return -12; /* -ENOMEM */ ++ } ++ ++ if ((ret = BCMINIT(_nvram_read)(header)) == 0 && ++ header->magic == NVRAM_MAGIC) ++ BCMINIT(nvram_rehash)(header); ++ ++ MFREE(osh, header, NVRAM_SPACE); ++ return ret; ++} ++ ++/* Free hash table. Should be locked. */ ++void ++BCMINITFN(_nvram_exit)(void) ++{ ++ BCMINIT(nvram_free)(); ++} +diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c +--- linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c 2005-12-19 01:09:59.782313000 +0100 +@@ -0,0 +1,653 @@ ++/* ++ * NVRAM variable manipulation (Linux kernel half) ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* In BSS to minimize text size and page aligned so it can be mmap()-ed */ ++static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE))); ++ ++#ifdef MODULE ++ ++#define early_nvram_get(name) nvram_get(name) ++ ++#else /* !MODULE */ ++ ++/* Global SB handle */ ++extern void *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; ++ ++static int cfe_env; ++extern char *cfe_env_get(char *nv_buf, const char *name); ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++#define KB * 1024 ++#define MB * 1024 * 1024 ++ ++/* Probe for NVRAM header */ ++static void __init ++early_nvram_init(void) ++{ ++ struct nvram_header *header; ++ chipcregs_t *cc; ++ struct sflash *info = NULL; ++ int i; ++ uint32 base, off, lim; ++ u32 *src, *dst; ++ ++ if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) { ++ base = KSEG1ADDR(SB_FLASH2); ++ switch (readl(&cc->capabilities) & CAP_FLASH_MASK) { ++ case PFLASH: ++ lim = SB_FLASH2_SZ; ++ break; ++ ++ case SFLASH_ST: ++ case SFLASH_AT: ++ if ((info = sflash_init(cc)) == NULL) ++ return; ++ lim = info->size; ++ break; ++ ++ case FLASH_NONE: ++ default: ++ return; ++ } ++ } else { ++ /* extif assumed, Stop at 4 MB */ ++ base = KSEG1ADDR(SB_FLASH1); ++ lim = SB_FLASH1_SZ; ++ } ++ ++ /* XXX: hack for supporting the CFE environment stuff on WGT634U */ ++ src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); ++ dst = (u32 *) nvram_buf; ++ if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) { ++ printk("early_nvram_init: WGT634U NVRAM found.\n"); ++ ++ for (i = 0; i < 0x1ff0; i++) { ++ if (*src == 0xFFFFFFFF) ++ break; ++ *dst++ = *src++; ++ } ++ cfe_env = 1; ++ return; ++ } ++ ++ off = FLASH_MIN; ++ while (off <= lim) { ++ /* Windowed flash access */ ++ header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ off <<= 1; ++ } ++ ++ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ ++ header = (struct nvram_header *) KSEG1ADDR(base + 4 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ header = (struct nvram_header *) KSEG1ADDR(base + 1 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ printk("early_nvram_init: NVRAM not found\n"); ++ return; ++ ++found: ++ src = (u32 *) header; ++ dst = (u32 *) nvram_buf; ++ for (i = 0; i < sizeof(struct nvram_header); i += 4) ++ *dst++ = *src++; ++ for (; i < header->len && i < NVRAM_SPACE; i += 4) ++ *dst++ = ltoh32(*src++); ++} ++ ++/* Early (before mm or mtd) read-only access to NVRAM */ ++static char * __init ++early_nvram_get(const char *name) ++{ ++ char *var, *value, *end, *eq; ++ ++ if (!name) ++ return NULL; ++ ++ /* Too early? */ ++ if (sbh == NULL) ++ return NULL; ++ ++ if (!nvram_buf[0]) ++ early_nvram_init(); ++ ++ if (cfe_env) ++ return cfe_env_get(nvram_buf, name); ++ ++ /* Look for name=value and return value */ ++ var = &nvram_buf[sizeof(struct nvram_header)]; ++ end = nvram_buf + sizeof(nvram_buf) - 2; ++ end[0] = end[1] = '\0'; ++ for (; *var; var = value + strlen(value) + 1) { ++ if (!(eq = strchr(var, '='))) ++ break; ++ value = eq + 1; ++ if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) ++ return value; ++ } ++ ++ return NULL; ++} ++ ++#endif /* !MODULE */ ++ ++extern char * _nvram_get(const char *name); ++extern int _nvram_set(const char *name, const char *value); ++extern int _nvram_unset(const char *name); ++extern int _nvram_getall(char *buf, int count); ++extern int _nvram_commit(struct nvram_header *header); ++extern int _nvram_init(void); ++extern void _nvram_exit(void); ++ ++/* Globals */ ++static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED; ++static struct semaphore nvram_sem; ++static unsigned long nvram_offset = 0; ++static int nvram_major = -1; ++static devfs_handle_t nvram_handle = NULL; ++static struct mtd_info *nvram_mtd = NULL; ++ ++int ++_nvram_read(char *buf) ++{ ++ struct nvram_header *header = (struct nvram_header *) buf; ++ size_t len; ++ ++ if (!nvram_mtd || ++ MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) || ++ len != NVRAM_SPACE || ++ header->magic != NVRAM_MAGIC) { ++ /* Maybe we can recover some data from early initialization */ ++ memcpy(buf, nvram_buf, NVRAM_SPACE); ++ } ++ ++ return 0; ++} ++ ++struct nvram_tuple * ++_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value) ++{ ++ if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE) ++ return NULL; ++ ++ if (!t) { ++ if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC))) ++ return NULL; ++ ++ /* Copy name */ ++ t->name = (char *) &t[1]; ++ strcpy(t->name, name); ++ ++ t->value = NULL; ++ } ++ ++ /* Copy value */ ++ if (!t->value || strcmp(t->value, value)) { ++ t->value = &nvram_buf[nvram_offset]; ++ strcpy(t->value, value); ++ nvram_offset += strlen(value) + 1; ++ } ++ ++ return t; ++} ++ ++void ++_nvram_free(struct nvram_tuple *t) ++{ ++ if (!t) ++ nvram_offset = 0; ++ else ++ kfree(t); ++} ++ ++int ++nvram_set(const char *name, const char *value) ++{ ++ unsigned long flags; ++ int ret; ++ struct nvram_header *header; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ if ((ret = _nvram_set(name, value))) { ++ /* Consolidate space and try again */ ++ if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) { ++ if (_nvram_commit(header) == 0) ++ ret = _nvram_set(name, value); ++ kfree(header); ++ } ++ } ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return ret; ++} ++ ++char * ++real_nvram_get(const char *name) ++{ ++ unsigned long flags; ++ char *value; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ value = _nvram_get(name); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return value; ++} ++ ++char * ++nvram_get(const char *name) ++{ ++ if (nvram_major >= 0) ++ return real_nvram_get(name); ++ else ++ return early_nvram_get(name); ++} ++ ++int ++nvram_unset(const char *name) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_unset(name); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return ret; ++} ++ ++static void ++erase_callback(struct erase_info *done) ++{ ++ wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv; ++ wake_up(wait_q); ++} ++ ++int ++nvram_commit(void) ++{ ++ char *buf; ++ size_t erasesize, len; ++ unsigned int i; ++ int ret; ++ struct nvram_header *header; ++ unsigned long flags; ++ u_int32_t offset; ++ DECLARE_WAITQUEUE(wait, current); ++ wait_queue_head_t wait_q; ++ struct erase_info erase; ++ ++ if (!nvram_mtd) { ++ printk("nvram_commit: NVRAM not found\n"); ++ return -ENODEV; ++ } ++ ++ if (in_interrupt()) { ++ printk("nvram_commit: not committing in interrupt\n"); ++ return -EINVAL; ++ } ++ ++ /* Backup sector blocks to be erased */ ++ erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize); ++ if (!(buf = kmalloc(erasesize, GFP_KERNEL))) { ++ printk("nvram_commit: out of memory\n"); ++ return -ENOMEM; ++ } ++ ++ down(&nvram_sem); ++ ++ if ((i = erasesize - NVRAM_SPACE) > 0) { ++ offset = nvram_mtd->size - erasesize; ++ len = 0; ++ ret = MTD_READ(nvram_mtd, offset, i, &len, buf); ++ if (ret || len != i) { ++ printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i); ++ ret = -EIO; ++ goto done; ++ } ++ header = (struct nvram_header *)(buf + i); ++ } else { ++ offset = nvram_mtd->size - NVRAM_SPACE; ++ header = (struct nvram_header *)buf; ++ } ++ ++ /* Regenerate NVRAM */ ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_commit(header); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ if (ret) ++ goto done; ++ ++ /* Erase sector blocks */ ++ init_waitqueue_head(&wait_q); ++ for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) { ++ erase.mtd = nvram_mtd; ++ erase.addr = offset; ++ erase.len = nvram_mtd->erasesize; ++ erase.callback = erase_callback; ++ erase.priv = (u_long) &wait_q; ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ add_wait_queue(&wait_q, &wait); ++ ++ /* Unlock sector blocks */ ++ if (nvram_mtd->unlock) ++ nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize); ++ ++ if ((ret = MTD_ERASE(nvram_mtd, &erase))) { ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&wait_q, &wait); ++ printk("nvram_commit: erase error\n"); ++ goto done; ++ } ++ ++ /* Wait for erase to finish */ ++ schedule(); ++ remove_wait_queue(&wait_q, &wait); ++ } ++ ++ /* Write partition up to end of data area */ ++ offset = nvram_mtd->size - erasesize; ++ i = erasesize - NVRAM_SPACE + header->len; ++ ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf); ++ if (ret || len != i) { ++ printk("nvram_commit: write error\n"); ++ ret = -EIO; ++ goto done; ++ } ++ ++ offset = nvram_mtd->size - erasesize; ++ ret = MTD_READ(nvram_mtd, offset, 4, &len, buf); ++ ++ done: ++ up(&nvram_sem); ++ kfree(buf); ++ return ret; ++} ++ ++int ++nvram_getall(char *buf, int count) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_getall(buf, count); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL(nvram_get); ++EXPORT_SYMBOL(nvram_getall); ++EXPORT_SYMBOL(nvram_set); ++EXPORT_SYMBOL(nvram_unset); ++EXPORT_SYMBOL(nvram_commit); ++ ++/* User mode interface below */ ++ ++static ssize_t ++dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ char tmp[100], *name = tmp, *value; ++ ssize_t ret; ++ unsigned long off; ++ ++ if (count > sizeof(tmp)) { ++ if (!(name = kmalloc(count, GFP_KERNEL))) ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(name, buf, count)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ++ if (*name == '\0') { ++ /* Get all variables */ ++ ret = nvram_getall(name, count); ++ if (ret == 0) { ++ if (copy_to_user(buf, name, count)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ret = count; ++ } ++ } else { ++ if (!(value = nvram_get(name))) { ++ ret = 0; ++ goto done; ++ } ++ ++ /* Provide the offset into mmap() space */ ++ off = (unsigned long) value - (unsigned long) nvram_buf; ++ ++ if (put_user(off, (unsigned long *) buf)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ++ ret = sizeof(unsigned long); ++ } ++ ++ flush_cache_all(); ++ ++done: ++ if (name != tmp) ++ kfree(name); ++ ++ return ret; ++} ++ ++static ssize_t ++dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ++{ ++ char tmp[100], *name = tmp, *value; ++ ssize_t ret; ++ ++ if (count > sizeof(tmp)) { ++ if (!(name = kmalloc(count, GFP_KERNEL))) ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(name, buf, count)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ++ value = name; ++ name = strsep(&value, "="); ++ if (value) ++ ret = nvram_set(name, value) ? : count; ++ else ++ ret = nvram_unset(name) ? : count; ++ ++ done: ++ if (name != tmp) ++ kfree(name); ++ ++ return ret; ++} ++ ++static int ++dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ if (cmd != NVRAM_MAGIC) ++ return -EINVAL; ++ return nvram_commit(); ++} ++ ++static int ++dev_nvram_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ unsigned long offset = virt_to_phys(nvram_buf); ++ ++ if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, ++ vma->vm_page_prot)) ++ return -EAGAIN; ++ ++ return 0; ++} ++ ++static int ++dev_nvram_open(struct inode *inode, struct file * file) ++{ ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++static int ++dev_nvram_release(struct inode *inode, struct file * file) ++{ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static struct file_operations dev_nvram_fops = { ++ owner: THIS_MODULE, ++ open: dev_nvram_open, ++ release: dev_nvram_release, ++ read: dev_nvram_read, ++ write: dev_nvram_write, ++ ioctl: dev_nvram_ioctl, ++ mmap: dev_nvram_mmap, ++}; ++ ++static void ++dev_nvram_exit(void) ++{ ++ int order = 0; ++ struct page *page, *end; ++ ++ if (nvram_handle) ++ devfs_unregister(nvram_handle); ++ ++ if (nvram_major >= 0) ++ devfs_unregister_chrdev(nvram_major, "nvram"); ++ ++ if (nvram_mtd) ++ put_mtd_device(nvram_mtd); ++ ++ while ((PAGE_SIZE << order) < NVRAM_SPACE) ++ order++; ++ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); ++ for (page = virt_to_page(nvram_buf); page <= end; page++) ++ mem_map_unreserve(page); ++ ++ _nvram_exit(); ++} ++ ++static int __init ++dev_nvram_init(void) ++{ ++ int order = 0, ret = 0; ++ struct page *page, *end; ++ unsigned int i; ++ ++ /* Allocate and reserve memory to mmap() */ ++ while ((PAGE_SIZE << order) < NVRAM_SPACE) ++ order++; ++ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); ++ for (page = virt_to_page(nvram_buf); page <= end; page++) ++ mem_map_reserve(page); ++ ++#ifdef CONFIG_MTD ++ /* Find associated MTD device */ ++ for (i = 0; i < MAX_MTD_DEVICES; i++) { ++ nvram_mtd = get_mtd_device(NULL, i); ++ if (nvram_mtd) { ++ if (!strcmp(nvram_mtd->name, "nvram") && ++ nvram_mtd->size >= NVRAM_SPACE) ++ break; ++ put_mtd_device(nvram_mtd); ++ } ++ } ++ if (i >= MAX_MTD_DEVICES) ++ nvram_mtd = NULL; ++#endif ++ ++ /* Initialize hash table lock */ ++ spin_lock_init(&nvram_lock); ++ ++ /* Initialize commit semaphore */ ++ init_MUTEX(&nvram_sem); ++ ++ /* Register char device */ ++ if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) { ++ ret = nvram_major; ++ goto err; ++ } ++ ++ /* Initialize hash table */ ++ _nvram_init(); ++ ++ /* Create /dev/nvram handle */ ++ nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0, ++ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL); ++ ++ /* Set the SDRAM NCDL value into NVRAM if not already done */ ++ if (getintvar(NULL, "sdram_ncdl") == 0) { ++ unsigned int ncdl; ++ char buf[] = "0x00000000"; ++ ++ if ((ncdl = sb_memc_get_ncdl(sbh))) { ++ sprintf(buf, "0x%08x", ncdl); ++ nvram_set("sdram_ncdl", buf); ++ nvram_commit(); ++ } ++ } ++ ++ return 0; ++ ++ err: ++ dev_nvram_exit(); ++ return ret; ++} ++ ++module_init(dev_nvram_init); ++module_exit(dev_nvram_exit); +diff -Nur linux-2.4.32/arch/mips/bcm947xx/pcibios.c linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c +--- linux-2.4.32/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c 2005-12-16 23:39:10.944836750 +0100 +@@ -0,0 +1,355 @@ ++/* ++ * Low-Level PCI and SB support for BCM47xx (Linux support code) ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Global SB handle */ ++extern sb_t *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++ ++static int ++sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_write_config_word(struct pci_dev *dev, int where, u16 value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops pcibios_ops = { ++ sbpci_read_config_byte, ++ sbpci_read_config_word, ++ sbpci_read_config_dword, ++ sbpci_write_config_byte, ++ sbpci_write_config_word, ++ sbpci_write_config_dword ++}; ++ ++ ++void __init ++pcibios_init(void) ++{ ++ ulong flags; ++ ++ if (!(sbh = sb_kattach())) ++ panic("sb_kattach failed"); ++ spin_lock_init(&sbh_lock); ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ sbpci_init(sbh); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000)); ++ ++ mdelay(300); //By Joey for Atheros Card ++ ++ /* Scan the SB bus */ ++ pci_scan_bus(0, &pcibios_ops, NULL); ++ ++} ++ ++char * __init ++pcibios_setup(char *str) ++{ ++ if (!strncmp(str, "ban=", 4)) { ++ sbpci_ban(simple_strtoul(str + 4, NULL, 0)); ++ return NULL; ++ } ++ ++ return (str); ++} ++ ++static u32 pci_iobase = 0x100; ++static u32 pci_membase = SB_PCI_DMA; ++ ++void __init ++pcibios_fixup_bus(struct pci_bus *b) ++{ ++ struct list_head *ln; ++ struct pci_dev *d; ++ struct resource *res; ++ int pos, size; ++ u32 *base; ++ u8 irq; ++ ++ printk("PCI: Fixing up bus %d\n", b->number); ++ ++ /* Fix up SB */ ++ if (b->number == 0) { ++ for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { ++ d = pci_dev_b(ln); ++ /* Fix up interrupt lines */ ++ pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq); ++ d->irq = irq + 2; ++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); ++ } ++ } ++ ++ /* Fix up external PCI */ ++ else { ++ for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { ++ d = pci_dev_b(ln); ++ /* Fix up resource bases */ ++ for (pos = 0; pos < 6; pos++) { ++ res = &d->resource[pos]; ++ base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase; ++ if (res->end) { ++ size = res->end - res->start + 1; ++ if (*base & (size - 1)) ++ *base = (*base + size) & ~(size - 1); ++ res->start = *base; ++ res->end = res->start + size - 1; ++ *base += size; ++ pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); ++ } ++ /* Fix up PCI bridge BAR0 only */ ++ if (b->number == 1 && PCI_SLOT(d->devfn) == 0) ++ break; ++ } ++ /* Fix up interrupt lines */ ++ if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL)) ++ d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq; ++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); ++ } ++ } ++} ++ ++unsigned int ++pcibios_assign_all_busses(void) ++{ ++ return 1; ++} ++ ++void ++pcibios_align_resource(void *data, struct resource *res, ++ unsigned long size, unsigned long align) ++{ ++} ++ ++int ++pcibios_enable_resources(struct pci_dev *dev) ++{ ++ u16 cmd, old_cmd; ++ int idx; ++ struct resource *r; ++ ++ /* External PCI only */ ++ if (dev->bus->number == 0) ++ return 0; ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ old_cmd = cmd; ++ for(idx=0; idx<6; idx++) { ++ r = &dev->resource[idx]; ++ if (r->flags & IORESOURCE_IO) ++ cmd |= PCI_COMMAND_IO; ++ if (r->flags & IORESOURCE_MEM) ++ cmd |= PCI_COMMAND_MEMORY; ++ } ++ if (dev->resource[PCI_ROM_RESOURCE].start) ++ cmd |= PCI_COMMAND_MEMORY; ++ if (cmd != old_cmd) { ++ printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ } ++ return 0; ++} ++ ++int ++pcibios_enable_device(struct pci_dev *dev, int mask) ++{ ++ ulong flags; ++ uint coreidx; ++ ++ /* External PCI device enable */ ++ if (dev->bus->number != 0) ++ return pcibios_enable_resources(dev); ++ ++ /* These cores come out of reset enabled */ ++ if (dev->device == SB_MIPS || ++ dev->device == SB_MIPS33 || ++ dev->device == SB_EXTIF || ++ dev->device == SB_CC) ++ return 0; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ coreidx = sb_coreidx(sbh); ++ if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn))) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ /* ++ * The USB core requires a special bit to be set during core ++ * reset to enable host (OHCI) mode. Resetting the SB core in ++ * pcibios_enable_device() is a hack for compatibility with ++ * vanilla usb-ohci so that it does not have to know about ++ * SB. A driver that wants to use the USB core in device mode ++ * should know about SB and should reset the bit back to 0 ++ * after calling pcibios_enable_device(). ++ */ ++ if (sb_coreid(sbh) == SB_USB) { ++ sb_core_disable(sbh, sb_coreflags(sbh, 0, 0)); ++ sb_core_reset(sbh, 1 << 29); ++ } else ++ sb_core_reset(sbh, 0); ++ ++ sb_setcoreidx(sbh, coreidx); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ return 0; ++} ++ ++void ++pcibios_update_resource(struct pci_dev *dev, struct resource *root, ++ struct resource *res, int resource) ++{ ++ unsigned long where, size; ++ u32 reg; ++ ++ /* External PCI only */ ++ if (dev->bus->number == 0) ++ return; ++ ++ where = PCI_BASE_ADDRESS_0 + (resource * 4); ++ size = res->end - res->start; ++ pci_read_config_dword(dev, where, ®); ++ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); ++ pci_write_config_dword(dev, where, reg); ++} ++ ++static void __init ++quirk_sbpci_bridge(struct pci_dev *dev) ++{ ++ if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0) ++ return; ++ ++ printk("PCI: Fixing up bridge\n"); ++ ++ /* Enable PCI bridge bus mastering and memory space */ ++ pci_set_master(dev); ++ pcibios_enable_resources(dev); ++ ++ /* Enable PCI bridge BAR1 prefetch and burst */ ++ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3); ++} ++ ++struct pci_fixup pcibios_fixups[] = { ++ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge }, ++ { 0 } ++}; ++ ++/* ++ * If we set up a device for bus mastering, we need to check the latency ++ * timer as certain crappy BIOSes forget to set it properly. ++ */ ++unsigned int pcibios_max_latency = 255; ++ ++void pcibios_set_master(struct pci_dev *dev) ++{ ++ u8 lat; ++ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); ++ if (lat < 16) ++ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; ++ else if (lat > pcibios_max_latency) ++ lat = pcibios_max_latency; ++ else ++ return; ++ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); ++ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/prom.c linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c +--- linux-2.4.32/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c 2005-12-16 23:39:10.944836750 +0100 +@@ -0,0 +1,41 @@ ++/* ++ * Early initialization code for BCM94710 boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: prom.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++void __init ++prom_init(int argc, const char **argv) ++{ ++ unsigned long mem; ++ ++ mips_machgroup = MACH_GROUP_BRCM; ++ mips_machtype = MACH_BCM947XX; ++ ++ /* Figure out memory size by finding aliases */ ++ for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { ++ if (*(unsigned long *)((unsigned long)(prom_init) + mem) == ++ *(unsigned long *)(prom_init)) ++ break; ++ } ++ add_memory_region(0, mem, BOOT_MEM_RAM); ++} ++ ++void __init ++prom_free_prom_memory(void) ++{ ++} +diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbmips.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c +--- linux-2.4.32/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c 2005-12-16 23:39:10.944836750 +0100 +@@ -0,0 +1,1038 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane MIPS core routines ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Returns TRUE if an external UART exists at the given base ++ * register. ++ */ ++static bool ++BCMINITFN(serial_exists)(uint8 *regs) ++{ ++ uint8 save_mcr, status1; ++ ++ save_mcr = R_REG(®s[UART_MCR]); ++ W_REG(®s[UART_MCR], UART_MCR_LOOP | 0x0a); ++ status1 = R_REG(®s[UART_MSR]) & 0xf0; ++ W_REG(®s[UART_MCR], save_mcr); ++ ++ return (status1 == 0x90); ++} ++ ++/* ++ * Initializes UART access. The callback function will be called once ++ * per found UART. ++ */ ++void ++BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) ++{ ++ void *regs; ++ ulong base; ++ uint irq; ++ int i, n; ++ ++ if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) { ++ extifregs_t *eir = (extifregs_t *) regs; ++ sbconfig_t *sb; ++ ++ /* Determine external UART register base */ ++ sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF); ++ base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1))); ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ /* Disable GPIO interrupt initially */ ++ W_REG(&eir->gpiointpolarity, 0); ++ W_REG(&eir->gpiointmask, 0); ++ ++ /* Search for external UARTs */ ++ n = 2; ++ for (i = 0; i < 2; i++) { ++ regs = (void *) REG_MAP(base + (i * 8), 8); ++ if (BCMINIT(serial_exists)(regs)) { ++ /* Set GPIO 1 to be the external UART IRQ */ ++ W_REG(&eir->gpiointmask, 2); ++ if (add) ++ add(regs, irq, 13500000, 0); ++ } ++ } ++ ++ /* Add internal UART if enabled */ ++ if (R_REG(&eir->corecontrol) & CC_UE) ++ if (add) ++ add((void *) &eir->uartdata, irq, sb_clock(sbh), 2); ++ } else if ((regs = sb_setcore(sbh, SB_CC, 0))) { ++ chipcregs_t *cc = (chipcregs_t *) regs; ++ uint32 rev, cap, pll, baud_base, div; ++ ++ /* Determine core revision and capabilities */ ++ rev = sb_corerev(sbh); ++ cap = R_REG(&cc->capabilities); ++ pll = cap & CAP_PLL_MASK; ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ if (pll == PLL_TYPE1) { ++ /* PLL clock */ ++ baud_base = sb_clock_rate(pll, ++ R_REG(&cc->clockcontrol_n), ++ R_REG(&cc->clockcontrol_m2)); ++ div = 1; ++ } else { ++ if (rev >= 11) { ++ /* Fixed ALP clock */ ++ baud_base = 20000000; ++ div = 1; ++ /* Set the override bit so we don't divide it */ ++ W_REG(&cc->corecontrol, CC_UARTCLKO); ++ } else if (rev >= 3) { ++ /* Internal backplane clock */ ++ baud_base = sb_clock(sbh); ++ div = 2; /* Minimum divisor */ ++ W_REG(&cc->clkdiv, ++ ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div)); ++ } else { ++ /* Fixed internal backplane clock */ ++ baud_base = 88000000; ++ div = 48; ++ } ++ ++ /* Clock source depends on strapping if UartClkOverride is unset */ ++ if ((rev > 0) && ++ ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) { ++ if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) { ++ /* Internal divided backplane clock */ ++ baud_base /= div; ++ } else { ++ /* Assume external clock of 1.8432 MHz */ ++ baud_base = 1843200; ++ } ++ } ++ } ++ ++ /* Add internal UARTs */ ++ n = cap & CAP_UARTS_MASK; ++ for (i = 0; i < n; i++) { ++ /* Register offset changed after revision 0 */ ++ if (rev) ++ regs = (void *)((ulong) &cc->uart0data + (i * 256)); ++ else ++ regs = (void *)((ulong) &cc->uart0data + (i * 8)); ++ ++ if (add) ++ add(regs, irq, baud_base, 0); ++ } ++ } ++} ++ ++/* ++ * Initialize jtag master and return handle for ++ * jtag_rwreg. Returns NULL on failure. ++ */ ++void * ++sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap) ++{ ++ void *regs; ++ ++ if ((regs = sb_setcore(sbh, SB_CC, 0)) != NULL) { ++ chipcregs_t *cc = (chipcregs_t *) regs; ++ uint32 tmp; ++ ++ /* ++ * Determine jtagm availability from ++ * core revision and capabilities. ++ */ ++ tmp = sb_corerev(sbh); ++ /* ++ * Corerev 10 has jtagm, but the only chip ++ * with it does not have a mips, and ++ * the layout of the jtagcmd register is ++ * different. We'll only accept >= 11. ++ */ ++ if (tmp < 11) ++ return (NULL); ++ ++ tmp = R_REG(&cc->capabilities); ++ if ((tmp & CAP_JTAGP) == 0) ++ return (NULL); ++ ++ /* Set clock divider if requested */ ++ if (clkd != 0) { ++ tmp = R_REG(&cc->clkdiv); ++ tmp = (tmp & ~CLKD_JTAG) | ++ ((clkd << CLKD_JTAG_SHIFT) & CLKD_JTAG); ++ W_REG(&cc->clkdiv, tmp); ++ } ++ ++ /* Enable jtagm */ ++ tmp = JCTRL_EN | (exttap ? JCTRL_EXT_EN : 0); ++ W_REG(&cc->jtagctrl, tmp); ++ } ++ ++ return (regs); ++} ++ ++void ++sb_jtagm_disable(void *h) ++{ ++ chipcregs_t *cc = (chipcregs_t *)h; ++ ++ W_REG(&cc->jtagctrl, R_REG(&cc->jtagctrl) & ~JCTRL_EN); ++} ++ ++/* ++ * Read/write a jtag register. Assumes a target with ++ * 8 bit IR and 32 bit DR. ++ */ ++#define IRWIDTH 8 ++#define DRWIDTH 32 ++uint32 ++jtag_rwreg(void *h, uint32 ir, uint32 dr) ++{ ++ chipcregs_t *cc = (chipcregs_t *) h; ++ uint32 tmp; ++ ++ W_REG(&cc->jtagir, ir); ++ W_REG(&cc->jtagdr, dr); ++ tmp = JCMD_START | JCMD_ACC_IRDR | ++ ((IRWIDTH - 1) << JCMD_IRW_SHIFT) | ++ (DRWIDTH - 1); ++ W_REG(&cc->jtagcmd, tmp); ++ while (((tmp = R_REG(&cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) { ++ /* OSL_DELAY(1); */ ++ } ++ ++ tmp = R_REG(&cc->jtagdr); ++ return (tmp); ++} ++ ++/* Returns the SB interrupt flag of the current core. */ ++uint32 ++sb_flag(sb_t *sbh) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ regs = sb_coreregs(sbh); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK); ++} ++ ++static const uint32 sbips_int_mask[] = { ++ 0, ++ SBIPS_INT1_MASK, ++ SBIPS_INT2_MASK, ++ SBIPS_INT3_MASK, ++ SBIPS_INT4_MASK ++}; ++ ++static const uint32 sbips_int_shift[] = { ++ 0, ++ 0, ++ SBIPS_INT2_SHIFT, ++ SBIPS_INT3_SHIFT, ++ SBIPS_INT4_SHIFT ++}; ++ ++/* ++ * Returns the MIPS IRQ assignment of the current core. If unassigned, ++ * 0 is returned. ++ */ ++uint ++sb_irq(sb_t *sbh) ++{ ++ uint idx; ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag, sbipsflag; ++ uint irq = 0; ++ ++ flag = sb_flag(sbh); ++ ++ idx = sb_coreidx(sbh); ++ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */ ++ sbipsflag = R_REG(&sb->sbipsflag); ++ for (irq = 1; irq <= 4; irq++) { ++ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag) ++ break; ++ } ++ if (irq == 5) ++ irq = 0; ++ } ++ ++ sb_setcoreidx(sbh, idx); ++ ++ return irq; ++} ++ ++/* Clears the specified MIPS IRQ. */ ++static void ++BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ W_REG(&sb->sbintvec, 0); ++ else ++ OR_REG(&sb->sbipsflag, sbips_int_mask[irq]); ++} ++ ++/* ++ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS ++ * IRQ 0 may be assigned more than once. ++ */ ++static void ++BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag; ++ ++ regs = sb_setcore(sbh, coreid, coreunit); ++ ASSERT(regs); ++ flag = sb_flag(sbh); ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ OR_REG(&sb->sbintvec, 1 << flag); ++ else { ++ flag <<= sbips_int_shift[irq]; ++ ASSERT(!(flag & ~sbips_int_mask[irq])); ++ flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq]; ++ W_REG(&sb->sbipsflag, flag); ++ } ++} ++ ++/* ++ * Initializes clocks and interrupts. SB and NVRAM access must be ++ * initialized prior to calling. ++ */ ++void ++BCMINITFN(sb_mips_init)(sb_t *sbh) ++{ ++ ulong hz, ns, tmp; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ char *value; ++ uint irq; ++ ++ /* Figure out current SB clock speed */ ++ if ((hz = sb_clock(sbh)) == 0) ++ hz = 100000000; ++ ns = 1000000000 / hz; ++ ++ /* Setup external interface timing */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ /* Initialize extif so we can get to the LEDs and external UART */ ++ W_REG(&eir->prog_config, CF_EN); ++ ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++ ++ /* Set programmable interface timing for external uart */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */ ++ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++ } else if ((cc = sb_setcore(sbh, SB_CC, 0))) { ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */ ++ tmp |= CEIL(120, ns); /* W0 = 120nS */ ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { ++ W_REG(&cc->flash_waitcount, tmp); ++ W_REG(&cc->pcmcia_memwait, tmp); ++ } ++ else ++ { ++ if (sb_corerev(sbh) < 9) ++ W_REG(&cc->flash_waitcount, tmp); ++ ++ if ((sb_corerev(sbh) < 9) || ++ ((BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) && BCMINIT(sb_chiprev)(sbh) == 0)) { ++ W_REG(&cc->pcmcia_memwait, tmp); ++ } ++ } ++ } ++ ++ /* Chip specific initialization */ ++ switch (BCMINIT(sb_chip)(sbh)) { ++ case BCM4710_DEVICE_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ BCMINIT(sb_clearirq)(sbh, irq); ++ BCMINIT(sb_setirq)(sbh, 0, SB_CODEC, 0); ++ BCMINIT(sb_setirq)(sbh, 0, SB_EXTIF, 0); ++ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 1); ++ BCMINIT(sb_setirq)(sbh, 3, SB_ILINE20, 0); ++ BCMINIT(sb_setirq)(sbh, 4, SB_PCI, 0); ++ ASSERT(eir); ++ value = BCMINIT(nvram_get)("et0phyaddr"); ++ if (value && !strcmp(value, "31")) { ++ /* Enable internal UART */ ++ W_REG(&eir->corecontrol, CC_UE); ++ /* Give USB its own interrupt */ ++ BCMINIT(sb_setirq)(sbh, 1, SB_USB, 0); ++ } else { ++ /* Disable internal UART */ ++ W_REG(&eir->corecontrol, 0); ++ /* Give Ethernet its own interrupt */ ++ BCMINIT(sb_setirq)(sbh, 1, SB_ENET, 0); ++ BCMINIT(sb_setirq)(sbh, 0, SB_USB, 0); ++ } ++ break; ++ case BCM5350_DEVICE_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ BCMINIT(sb_clearirq)(sbh, irq); ++ BCMINIT(sb_setirq)(sbh, 0, SB_CC, 0); ++ BCMINIT(sb_setirq)(sbh, 1, SB_D11, 0); ++ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 0); ++ BCMINIT(sb_setirq)(sbh, 3, SB_PCI, 0); ++ BCMINIT(sb_setirq)(sbh, 4, SB_USB, 0); ++ break; ++ } ++} ++ ++uint32 ++BCMINITFN(sb_mips_clock)(sb_t *sbh) ++{ ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate = 0; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ pll_type = PLL_TYPE1; ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE5) { ++ rate = 200000000; ++ goto out; ++ } ++ else if (pll_type == PLL_TYPE3) { ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) { /* 5365 is also type3 */ ++ rate = 200000000; ++ goto out; ++ } else ++ m = R_REG(&cc->clockcontrol_m2); /* 5350 uses m2 to control mips */ ++ } else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else ++ goto out; ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ rate = 100000000; ++ else ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ ++ if (pll_type == PLL_TYPE6) ++ rate = SB2MIPS_T6(rate); ++ ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return rate; ++} ++ ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) ++ ++static void ++BCMINITFN(handler)(void) ++{ ++ /* Step 11 */ ++ __asm__ ( ++ ".set\tmips32\n\t" ++ "ssnop\n\t" ++ "ssnop\n\t" ++ /* Disable interrupts */ ++ /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */ ++ "mfc0 $15, $12\n\t" ++ /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */ ++ "li $14, -31746\n\t" ++ "and $15, $15, $14\n\t" ++ "mtc0 $15, $12\n\t" ++ "eret\n\t" ++ "nop\n\t" ++ "nop\n\t" ++ ".set\tmips0" ++ ); ++} ++ ++/* The following MUST come right after handler() */ ++static void ++BCMINITFN(afterhandler)(void) ++{ ++} ++ ++/* ++ * Set the MIPS, backplane and PCI clocks as closely as possible. ++ */ ++bool ++BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock) ++{ ++ extifregs_t *eir = NULL; ++ chipcregs_t *cc = NULL; ++ mipsregs_t *mipsr = NULL; ++ volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2; ++ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg; ++ uint32 pll_type, sync_mode; ++ uint ic_size, ic_lsize; ++ uint idx, i; ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 pci25; ++ } n3m_table_t; ++ static n3m_table_t BCMINITDATA(type1_table)[] = { ++ { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */ ++ { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */ ++ { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */ ++ { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */ ++ { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */ ++ { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */ ++ { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */ ++ { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */ ++ { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */ ++ { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */ ++ { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */ ++ { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */ ++ { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */ ++ { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */ ++ { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */ ++ { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */ ++ { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */ ++ { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */ ++ { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */ ++ { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */ ++ }; ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 m2; /* that is the clockcontrol_m2 */ ++ } type3_table_t; ++ static type3_table_t type3_table[] = { /* for 5350, mips clock is always double sb clock */ ++ { 150000000, 0x311, 0x4020005 }, ++ { 200000000, 0x311, 0x4020003 }, ++ }; ++ typedef struct { ++ uint32 mipsclock; ++ uint32 sbclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 m2; ++ uint32 m3; ++ uint32 ratio_cfg; ++ uint32 ratio_parm; ++ } n4m_table_t; ++ ++ static n4m_table_t BCMINITDATA(type2_table)[] = { ++ { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555 }, ++ { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, ++ { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, ++ { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 11, 0x0aaa0555 } ++ }; ++ ++ static n4m_table_t BCMINITDATA(type4_table)[] = { ++ { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, ++ { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8, 0x012a00a9 }, ++ { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, 0x254a14a9 }, ++ { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9, 0x02520129 }, ++ { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, ++ { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9, 0x02520129 }, ++ { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, 0x0aaa0555 } ++ }; ++ ++ static n4m_table_t BCMINITDATA(type7_table)[] = { ++ { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, ++ { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, 0x0aaa0555 }, ++ { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, 0x0aaa0555 } ++ }; ++ ++ ulong start, end, dst; ++ bool ret = FALSE; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ clockcontrol_m2 = NULL; ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ pll_type = PLL_TYPE1; ++ clockcontrol_n = &eir->clockcontrol_n; ++ clockcontrol_sb = &eir->clockcontrol_sb; ++ clockcontrol_pci = &eir->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ if (pll_type == PLL_TYPE6) { ++ clockcontrol_n = NULL; ++ clockcontrol_sb = NULL; ++ clockcontrol_pci = NULL; ++ } else { ++ clockcontrol_n = &cc->clockcontrol_n; ++ clockcontrol_sb = &cc->clockcontrol_sb; ++ clockcontrol_pci = &cc->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } ++ } else ++ goto done; ++ ++ if (pll_type == PLL_TYPE6) { ++ /* Silence compilers */ ++ orig_n = orig_sb = orig_pci = 0; ++ } else { ++ /* Store the current clock register values */ ++ orig_n = R_REG(clockcontrol_n); ++ orig_sb = R_REG(clockcontrol_sb); ++ orig_pci = R_REG(clockcontrol_pci); ++ } ++ ++ if (pll_type == PLL_TYPE1) { ++ /* Keep the current PCI clock if not specified */ ++ if (pciclock == 0) { ++ pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci)); ++ pciclock = (pciclock <= 25000000) ? 25000000 : 33000000; ++ } ++ ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(type1_table)); i++) { ++ ASSERT(BCMINIT(type1_table)[i].mipsclock == ++ sb_clock_rate(pll_type, BCMINIT(type1_table)[i].n, BCMINIT(type1_table)[i].sb)); ++ if (BCMINIT(type1_table)[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(BCMINIT(type1_table)[i].mipsclock <= mipsclock); ++ ++ /* No PLL change */ ++ if ((orig_n == BCMINIT(type1_table)[i].n) && ++ (orig_sb == BCMINIT(type1_table)[i].sb) && ++ (orig_pci == BCMINIT(type1_table)[i].pci33)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, BCMINIT(type1_table)[i].n); ++ W_REG(clockcontrol_sb, BCMINIT(type1_table)[i].sb); ++ if (pciclock == 25000000) ++ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci25); ++ else ++ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci33); ++ ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ ++ while (1); ++ } else if ((pll_type == PLL_TYPE3) && ++ (BCMINIT(sb_chip)(sbh) != BCM5365_DEVICE_ID)) { ++ /* 5350 */ ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ ++ for (i = 0; i < ARRAYSIZE(type3_table); i++) { ++ if (type3_table[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(type3_table[i].mipsclock <= mipsclock); ++ ++ /* No PLL change */ ++ orig_m2 = R_REG(&cc->clockcontrol_m2); ++ if ((orig_n == type3_table[i].n) && ++ (orig_m2 == type3_table[i].m2)) { ++ goto done; ++ } ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, type3_table[i].n); ++ W_REG(clockcontrol_m2, type3_table[i].m2); ++ ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ while (1); ++ } else if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) { ++ n4m_table_t *table = NULL, *te; ++ uint tabsz = 0; ++ ++ ASSERT(cc); ++ ++ orig_mips = R_REG(&cc->clockcontrol_mips); ++ ++ if (pll_type == PLL_TYPE6) { ++ uint32 new_mips = 0; ++ ++ ret = TRUE; ++ if (mipsclock <= SB2MIPS_T6(CC_T6_M1)) ++ new_mips = CC_T6_MMASK; ++ ++ if (orig_mips == new_mips) ++ goto done; ++ ++ W_REG(&cc->clockcontrol_mips, new_mips); ++ goto end_fill; ++ } ++ ++ if (pll_type == PLL_TYPE2) { ++ table = BCMINIT(type2_table); ++ tabsz = ARRAYSIZE(BCMINIT(type2_table)); ++ } else if (pll_type == PLL_TYPE4) { ++ table = BCMINIT(type4_table); ++ tabsz = ARRAYSIZE(BCMINIT(type4_table)); ++ } else if (pll_type == PLL_TYPE7) { ++ table = BCMINIT(type7_table); ++ tabsz = ARRAYSIZE(BCMINIT(type7_table)); ++ } else ++ ASSERT("No table for plltype" == NULL); ++ ++ /* Store the current clock register values */ ++ orig_m2 = R_REG(&cc->clockcontrol_m2); ++ orig_ratio_parm = 0; ++ orig_ratio_cfg = 0; ++ ++ /* Look up current ratio */ ++ for (i = 0; i < tabsz; i++) { ++ if ((orig_n == table[i].n) && ++ (orig_sb == table[i].sb) && ++ (orig_pci == table[i].pci33) && ++ (orig_m2 == table[i].m2) && ++ (orig_mips == table[i].m3)) { ++ orig_ratio_parm = table[i].ratio_parm; ++ orig_ratio_cfg = table[i].ratio_cfg; ++ break; ++ } ++ } ++ ++ /* Search for the closest MIPS clock greater or equal to a preferred value */ ++ for (i = 0; i < tabsz; i++) { ++ ASSERT(table[i].mipsclock == ++ sb_clock_rate(pll_type, table[i].n, table[i].m3)); ++ if ((mipsclock <= table[i].mipsclock) && ++ ((sbclock == 0) || (sbclock <= table[i].sbclock))) ++ break; ++ } ++ if (i == tabsz) { ++ ret = FALSE; ++ goto done; ++ } else { ++ te = &table[i]; ++ ret = TRUE; ++ } ++ ++ /* No PLL change */ ++ if ((orig_n == te->n) && ++ (orig_sb == te->sb) && ++ (orig_pci == te->pci33) && ++ (orig_m2 == te->m2) && ++ (orig_mips == te->m3)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, te->n); ++ W_REG(clockcontrol_sb, te->sb); ++ W_REG(clockcontrol_pci, te->pci33); ++ W_REG(&cc->clockcontrol_m2, te->m2); ++ W_REG(&cc->clockcontrol_mips, te->m3); ++ ++ /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */ ++ if ((pll_type == PLL_TYPE7) && ++ (te->sb != te->m2) && ++ (sb_clock_rate(pll_type, te->n, te->m2) == 120000000)) ++ W_REG(&cc->chipcontrol, R_REG(&cc->chipcontrol) | 0x100); ++ ++ /* No ratio change */ ++ if (orig_ratio_parm == te->ratio_parm) ++ goto end_fill; ++ ++ icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize); ++ ++ /* Preload the code into the cache */ ++ start = ((ulong) &&start_fill) & ~(ic_lsize - 1); ++ end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); ++ while (start < end) { ++ cache_op(start, Fill_I); ++ start += ic_lsize; ++ } ++ ++ /* Copy the handler */ ++ start = (ulong) &BCMINIT(handler); ++ end = (ulong) &BCMINIT(afterhandler); ++ dst = KSEG1ADDR(0x180); ++ for (i = 0; i < (end - start); i += 4) ++ *((ulong *)(dst + i)) = *((ulong *)(start + i)); ++ ++ /* Preload handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += 4) ++ cache_op(dst + i, Fill_I); ++ ++ /* Clear BEV bit */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV); ++ ++ /* Enable interrupts */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE)); ++ ++ /* Enable MIPS timer interrupt */ ++ if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(mipsr = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(mipsr); ++ W_REG(&mipsr->intmask, 1); ++ ++ start_fill: ++ /* step 1, set clock ratios */ ++ MTC0(C0_BROADCOM, 3, te->ratio_parm); ++ MTC0(C0_BROADCOM, 1, te->ratio_cfg); ++ ++ /* step 2: program timer intr */ ++ W_REG(&mipsr->timer, 100); ++ (void) R_REG(&mipsr->timer); ++ ++ /* step 3, switch to async */ ++ sync_mode = MFC0(C0_BROADCOM, 4); ++ MTC0(C0_BROADCOM, 4, 1 << 22); ++ ++ /* step 4, set cfg active */ ++ MTC0(C0_BROADCOM, 2, 0x9); ++ ++ ++ /* steps 5 & 6 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ ++ /* step 7, clear cfg_active */ ++ MTC0(C0_BROADCOM, 2, 0); ++ ++ /* Additional Step: set back to orig sync mode */ ++ MTC0(C0_BROADCOM, 4, sync_mode); ++ ++ /* step 8, fake soft reset */ ++ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4); ++ ++ end_fill: ++ /* step 9 set watchdog timer */ ++ sb_watchdog(sbh, 20); ++ (void) R_REG(&cc->chipid); ++ ++ /* step 11 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "sync\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ while (1); ++ } ++ ++done: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} ++ ++/* ++ * This also must be run from the cache on 47xx ++ * so there are no mips core BIU ops in progress ++ * when the PFC is enabled. ++ */ ++ ++static void ++BCMINITFN(_enable_pfc)(uint32 mode) ++{ ++ /* write range */ ++ *(volatile uint32 *)PFC_CR1 = 0xffff0000; ++ ++ /* enable */ ++ *(volatile uint32 *)PFC_CR0 = mode; ++} ++ ++void ++BCMINITFN(enable_pfc)(uint32 mode) ++{ ++ ulong start, end; ++ int i; ++ ++ /* If auto then choose the correct mode for this ++ platform, currently we only ever select one mode */ ++ if (mode == PFC_AUTO) ++ mode = PFC_INST; ++ ++ /* enable prefetch cache if available */ ++ if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) { ++ start = (ulong) &BCMINIT(_enable_pfc); ++ end = (ulong) &BCMINIT(enable_pfc); ++ ++ /* Preload handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += 4) ++ cache_op(start + i, Fill_I); ++ ++ BCMINIT(_enable_pfc)(mode); ++ } ++} ++ ++/* returns the ncdl value to be programmed into sdram_ncdl for calibration */ ++uint32 ++BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh) ++{ ++ sbmemcregs_t *memc; ++ uint32 ret = 0; ++ uint32 config, rd, wr, misc, dqsg, cd, sm, sd; ++ uint idx, rev; ++ ++ idx = sb_coreidx(sbh); ++ ++ memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0); ++ if (memc == 0) ++ goto out; ++ ++ rev = sb_corerev(sbh); ++ ++ config = R_REG(&memc->config); ++ wr = R_REG(&memc->wrncdlcor); ++ rd = R_REG(&memc->rdncdlcor); ++ misc = R_REG(&memc->miscdlyctl); ++ dqsg = R_REG(&memc->dqsgatencdl); ++ ++ rd &= MEMC_RDNCDLCOR_RD_MASK; ++ wr &= MEMC_WRNCDLCOR_WR_MASK; ++ dqsg &= MEMC_DQSGATENCDL_G_MASK; ++ ++ if (config & MEMC_CONFIG_DDR) { ++ ret = (wr << 16) | (rd << 8) | dqsg; ++ } else { ++ if (rev > 0) ++ cd = rd; ++ else ++ cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD); ++ sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT; ++ sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT; ++ ret = (sm << 16) | (sd << 8) | cd; ++ } ++ ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbpci.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c +--- linux-2.4.32/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c 2005-12-16 23:39:10.948837000 +0100 +@@ -0,0 +1,588 @@ ++/* ++ * Low-Level PCI and SB support for BCM47xx ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Can free sbpci_init() memory after boot */ ++#ifndef linux ++#define __init ++#endif ++ ++/* Emulated configuration space */ ++static pci_config_regs sb_config_regs[SB_MAXCORES]; ++ ++/* Banned cores */ ++static uint16 pci_ban[32] = { 0 }; ++static uint pci_banned = 0; ++ ++/* CardBus mode */ ++static bool cardbus = FALSE; ++ ++/* Disable PCI host core */ ++static bool pci_disabled = FALSE; ++ ++/* ++ * Functions for accessing external PCI configuration space ++ */ ++ ++/* Assume one-hot slot wiring */ ++#define PCI_SLOT_MAX 16 ++ ++static uint32 ++config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off) ++{ ++ uint coreidx; ++ sbpciregs_t *regs; ++ uint32 addr = 0; ++ ++ /* CardBusMode supports only one device */ ++ if (cardbus && dev > 1) ++ return 0; ++ ++ coreidx = sb_coreidx(sbh); ++ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Type 0 transaction */ ++ if (bus == 1) { ++ /* Skip unwired slots */ ++ if (dev < PCI_SLOT_MAX) { ++ /* Slide the PCI window to the appropriate slot */ ++ W_REG(®s->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK)); ++ addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) | ++ (func << 8) | (off & ~3); ++ } ++ } ++ ++ /* Type 1 transaction */ ++ else { ++ W_REG(®s->sbtopci1, SBTOPCI_CFG1); ++ addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ ++ return addr; ++} ++ ++static int ++extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (pci_disabled || ++ !(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ val = 0xffffffff; ++ ++ val >>= 8 * (off & 3); ++ if (len == 4) ++ *((uint32 *) buf) = val; ++ else if (len == 2) ++ *((uint16 *) buf) = (uint16) val; ++ else if (len == 1) ++ *((uint8 *) buf) = (uint8) val; ++ else ++ ret = -1; ++ ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++static int ++extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (pci_disabled || ++ !(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ goto done; ++ ++ if (len == 4) ++ val = *((uint32 *) buf); ++ else if (len == 2) { ++ val &= ~(0xffff << (8 * (off & 3))); ++ val |= *((uint16 *) buf) << (8 * (off & 3)); ++ } else if (len == 1) { ++ val &= ~(0xff << (8 * (off & 3))); ++ val |= *((uint8 *) buf) << (8 * (off & 3)); ++ } else ++ ret = -1; ++ ++ W_REG(reg, val); ++ ++ done: ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++/* ++ * Functions for accessing translated SB configuration space ++ */ ++ ++static int ++sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); ++ ++ if (len == 4) ++ *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); ++ else if (len == 2) ++ *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); ++ else if (len == 1) ++ *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off)); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++static int ++sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint coreidx, n; ++ void *regs; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); ++ ++ /* Emulate BAR sizing */ ++ if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) && ++ len == 4 && *((uint32 *) buf) == ~0) { ++ coreidx = sb_coreidx(sbh); ++ if ((regs = sb_setcoreidx(sbh, dev))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ /* Highest numbered address match register */ ++ n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT; ++ if (off == OFFSETOF(pci_config_regs, base[0])) ++ cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1) ++ cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2) ++ cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3) ++ cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1); ++ } ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++ } ++ ++ if (len == 4) ++ *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf)); ++ else if (len == 2) ++ *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf)); ++ else if (len == 1) ++ *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++int ++sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_read_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_read_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++int ++sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_write_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_write_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++void ++sbpci_ban(uint16 core) ++{ ++ if (pci_banned < ARRAYSIZE(pci_ban)) ++ pci_ban[pci_banned++] = core; ++} ++ ++static int ++sbpci_init_pci(sb_t *sbh) ++{ ++ uint chip, chiprev, chippkg, host; ++ uint32 boardflags; ++ sbpciregs_t *pci; ++ sbconfig_t *sb; ++ uint32 val; ++ ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); ++ ++ if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) { ++ printf("PCI: no core\n"); ++ pci_disabled = TRUE; ++ return -1; ++ } ++ sb_core_reset(sbh, 0); ++ ++ boardflags = (uint32) getintvar(NULL, "boardflags"); ++ ++ if ((chip == BCM4310_DEVICE_ID) && (chiprev == 0)) ++ pci_disabled = TRUE; ++ ++ /* ++ * The 200-pin BCM4712 package does not bond out PCI. Even when ++ * PCI is bonded out, some boards may leave the pins ++ * floating. ++ */ ++ if (((chip == BCM4712_DEVICE_ID) && ++ ((chippkg == BCM4712SMALL_PKG_ID) || ++ (chippkg == BCM4712MID_PKG_ID))) || ++ (boardflags & BFL_NOPCI)) ++ pci_disabled = TRUE; ++ ++ /* ++ * If the PCI core should not be touched (disabled, not bonded ++ * out, or pins floating), do not even attempt to access core ++ * registers. Otherwise, try to determine if it is in host ++ * mode. ++ */ ++ if (pci_disabled) ++ host = 0; ++ else ++ host = !BUSPROBE(val, &pci->control); ++ ++ if (!host) { ++ /* Disable PCI interrupts in client mode */ ++ sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); ++ W_REG(&sb->sbintvec, 0); ++ ++ /* Disable the PCI bridge in client mode */ ++ sbpci_ban(SB_PCI); ++ printf("PCI: Disabled\n"); ++ } else { ++ /* Reset the external PCI bus and enable the clock */ ++ W_REG(&pci->control, 0x5); /* enable the tristate drivers */ ++ W_REG(&pci->control, 0xd); /* enable the PCI clock */ ++ OSL_DELAY(150); /* delay > 100 us */ ++ W_REG(&pci->control, 0xf); /* deassert PCI reset */ ++ W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */ ++ OSL_DELAY(1); /* delay 1 us */ ++ ++ /* Enable CardBusMode */ ++ cardbus = nvram_match("cardbus", "1"); ++ if (cardbus) { ++ printf("PCI: Enabling CardBus\n"); ++ /* GPIO 1 resets the CardBus device on bcm94710ap */ ++ sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400); ++ } ++ ++ /* 64 MB I/O access window */ ++ W_REG(&pci->sbtopci0, SBTOPCI_IO); ++ /* 64 MB configuration access window */ ++ W_REG(&pci->sbtopci1, SBTOPCI_CFG0); ++ /* 1 GB memory access window */ ++ W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); ++ ++ /* Enable PCI bridge BAR0 prefetch and burst */ ++ val = 6; ++ sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val)); ++ ++ /* Enable PCI interrupts */ ++ W_REG(&pci->intmask, PCI_INTA); ++ } ++ ++ return 0; ++} ++ ++static int ++sbpci_init_cores(sb_t *sbh) ++{ ++ uint chip, chiprev, chippkg, coreidx, i; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ void *regs; ++ char varname[8]; ++ uint wlidx = 0; ++ uint16 vendor, core; ++ uint8 class, subclass, progif; ++ uint32 val; ++ uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK }; ++ uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT }; ++ ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); ++ coreidx = sb_coreidx(sbh); ++ ++ /* Scan the SB bus */ ++ bzero(sb_config_regs, sizeof(sb_config_regs)); ++ for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) { ++ cfg->vendor = 0xffff; ++ if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs))) ++ continue; ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* Read ID register and parse vendor and core */ ++ val = R_REG(&sb->sbidhigh); ++ vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT; ++ core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; ++ progif = 0; ++ ++ /* Check if this core is banned */ ++ for (i = 0; i < pci_banned; i++) ++ if (core == pci_ban[i]) ++ break; ++ if (i < pci_banned) ++ continue; ++ ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ILINE100: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM4610_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ core = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", wlidx); ++ wlidx++; ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; ++ } else { ++ /* 4310 */ ++ core = BCM4310_D11B_ID; ++ } ++ } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; ++ } ++ ++ /* Supported translations */ ++ cfg->vendor = htol16(vendor); ++ cfg->device = htol16(core); ++ cfg->rev_id = chiprev; ++ cfg->prog_if = progif; ++ cfg->sub_class = subclass; ++ cfg->base_class = class; ++ cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0))); ++ cfg->base[1] = htol32(sb_base(R_REG(&sb->sbadmatch1))); ++ cfg->base[2] = htol32(sb_base(R_REG(&sb->sbadmatch2))); ++ cfg->base[3] = htol32(sb_base(R_REG(&sb->sbadmatch3))); ++ cfg->base[4] = 0; ++ cfg->base[5] = 0; ++ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) ++ cfg->header_type = PCI_HEADER_BRIDGE; ++ else ++ cfg->header_type = PCI_HEADER_NORMAL; ++ /* Save core interrupt flag */ ++ cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ /* Default to MIPS shared interrupt 0 */ ++ cfg->int_line = 0; ++ /* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ val = R_REG(&sb->sbipsflag); ++ for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) { ++ if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin) ++ break; ++ } ++ if (cfg->int_line > 4) ++ cfg->int_line = 0; ++ } ++ /* Emulated core */ ++ *((uint32 *) &cfg->sprom_control) = 0xffffffff; ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++} ++ ++int __init ++sbpci_init(sb_t *sbh) ++{ ++ sbpci_init_pci(sbh); ++ sbpci_init_cores(sbh); ++ return 0; ++} ++ ++void ++sbpci_check(sb_t *sbh) ++{ ++ uint coreidx; ++ sbpciregs_t *pci; ++ uint32 sbtopci1; ++ uint32 buf[64], *ptr, i; ++ ulong pa; ++ volatile uint j; ++ ++ coreidx = sb_coreidx(sbh); ++ pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Clear the test array */ ++ pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL); ++ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); ++ memset(ptr, 0, sizeof(buf)); ++ ++ /* Point PCI window 1 to memory */ ++ sbtopci1 = R_REG(&pci->sbtopci1); ++ W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK)); ++ ++ /* Fill the test array via PCI window 1 */ ++ ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf)); ++ for (i = 0; i < ARRAYSIZE(buf); i++) { ++ for (j = 0; j < 2; j++); ++ W_REG(&ptr[i], i); ++ } ++ REG_UNMAP(ptr); ++ ++ /* Restore PCI window 1 */ ++ W_REG(&pci->sbtopci1, sbtopci1); ++ ++ /* Check the test array */ ++ DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL); ++ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); ++ for (i = 0; i < ARRAYSIZE(buf); i++) { ++ if (ptr[i] != i) ++ break; ++ } ++ ++ /* Change the clock if the test fails */ ++ if (i < ARRAYSIZE(buf)) { ++ uint32 req, cur; ++ ++ cur = sb_clock(sbh); ++ printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000); ++ for (req = 104000000; req < 176000000; req += 4000000) { ++ printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000); ++ /* This will only reset if the clocks are valid and have changed */ ++ sb_mips_setclock(sbh, req, 0, 0); ++ } ++ /* Should not reach here */ ++ ASSERT(0); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/setup.c linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c +--- linux-2.4.32/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c 2005-12-20 00:29:40.187416500 +0100 +@@ -0,0 +1,234 @@ ++/* ++ * Generic setup routines for Broadcom MIPS boards ++ * ++ * Copyright (C) 2005 Felix Fietkau ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Global SB handle */ ++sb_t *bcm947xx_sbh = NULL; ++spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED; ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++ ++extern void bcm947xx_time_init(void); ++extern void bcm947xx_timer_setup(struct irqaction *irq); ++ ++#ifdef CONFIG_REMOTE_DEBUG ++extern void set_debug_traps(void); ++extern void rs_kgdb_hook(struct serial_state *); ++extern void breakpoint(void); ++#endif ++ ++#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ++extern struct ide_ops std_ide_ops; ++#endif ++ ++/* Kernel command line */ ++char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE; ++ ++void ++bcm947xx_machine_restart(char *command) ++{ ++ printk("Please stand by while rebooting the system...\n"); ++ ++ /* Set the watchdog timer to reset immediately */ ++ __cli(); ++ sb_watchdog(sbh, 1); ++ while (1); ++} ++ ++void ++bcm947xx_machine_halt(void) ++{ ++ printk("System halted\n"); ++ ++ /* Disable interrupts and watchdog and spin forever */ ++ __cli(); ++ sb_watchdog(sbh, 0); ++ while (1); ++} ++ ++#ifdef CONFIG_SERIAL ++ ++static int ser_line = 0; ++ ++typedef struct { ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++} serial_port; ++ ++static serial_port ports[4]; ++static int num_ports = 0; ++ ++static void ++serial_add(void *regs, uint irq, uint baud_base, uint reg_shift) ++{ ++ ports[num_ports].regs = regs; ++ ports[num_ports].irq = irq; ++ ports[num_ports].baud_base = baud_base; ++ ports[num_ports].reg_shift = reg_shift; ++ num_ports++; ++} ++ ++static void ++do_serial_add(serial_port *port) ++{ ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++ struct serial_struct s; ++ ++ regs = port->regs; ++ irq = port->irq; ++ baud_base = port->baud_base; ++ reg_shift = port->reg_shift; ++ ++ memset(&s, 0, sizeof(s)); ++ ++ s.line = ser_line++; ++ s.iomem_base = regs; ++ s.irq = irq + 2; ++ s.baud_base = baud_base / 16; ++ s.flags = ASYNC_BOOT_AUTOCONF; ++ s.io_type = SERIAL_IO_MEM; ++ s.iomem_reg_shift = reg_shift; ++ ++ if (early_serial_setup(&s) != 0) { ++ printk(KERN_ERR "Serial setup failed!\n"); ++ } ++} ++ ++#endif /* CONFIG_SERIAL */ ++ ++void __init ++brcm_setup(void) ++{ ++ char *s; ++ int i; ++ char *value; ++ ++ /* Get global SB handle */ ++ sbh = sb_kattach(); ++ ++ /* Initialize clocks and interrupts */ ++ sb_mips_init(sbh); ++ ++ if (BCM330X(current_cpu_data.processor_id) && ++ (read_c0_diag() & BRCM_PFC_AVAIL)) { ++ /* ++ * Now that the sbh is inited set the proper PFC value ++ */ ++ printk("Setting the PFC to its default value\n"); ++ enable_pfc(PFC_AUTO); ++ } ++ ++ ++#ifdef CONFIG_SERIAL ++ sb_serial_init(sbh, serial_add); ++ ++ /* reverse serial ports if nvram variable starts with console=ttyS1 */ ++ /* Initialize UARTs */ ++ s = nvram_get("kernel_args"); ++ if (!s) s = ""; ++ if (!strncmp(s, "console=ttyS1", 13)) { ++ for (i = num_ports; i; i--) ++ do_serial_add(&ports[i - 1]); ++ } else { ++ for (i = 0; i < num_ports; i++) ++ do_serial_add(&ports[i]); ++ } ++#endif ++ ++#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ++ ide_ops = &std_ide_ops; ++#endif ++ ++ /* Override default command line arguments */ ++ value = nvram_get("kernel_cmdline"); ++ if (value && strlen(value) && strncmp(value, "empty", 5)) ++ strncpy(arcs_cmdline, value, sizeof(arcs_cmdline)); ++ ++ ++ /* Generic setup */ ++ _machine_restart = bcm947xx_machine_restart; ++ _machine_halt = bcm947xx_machine_halt; ++ _machine_power_off = bcm947xx_machine_halt; ++ ++ board_time_init = bcm947xx_time_init; ++ board_timer_setup = bcm947xx_timer_setup; ++} ++ ++const char * ++get_system_type(void) ++{ ++ static char s[32]; ++ ++ if (bcm947xx_sbh) { ++ sprintf(s, "Broadcom BCM%X chip rev %d", sb_chip(bcm947xx_sbh), ++ sb_chiprev(bcm947xx_sbh)); ++ return s; ++ } ++ else ++ return "Broadcom BCM947XX"; ++} ++ ++void __init ++bus_error_init(void) ++{ ++} ++ ++EXPORT_SYMBOL(bcm947xx_sbh); +diff -Nur linux-2.4.32/arch/mips/bcm947xx/sflash.c linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c +--- linux-2.4.32/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c 2005-12-16 23:39:10.948837000 +0100 +@@ -0,0 +1,418 @@ ++/* ++ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Private global state */ ++static struct sflash sflash; ++ ++/* Issue a serial flash command */ ++static INLINE void ++sflash_cmd(chipcregs_t *cc, uint opcode) ++{ ++ W_REG(&cc->flashcontrol, SFLASH_START | opcode); ++ while (R_REG(&cc->flashcontrol) & SFLASH_BUSY); ++} ++ ++/* Initialize serial flash access */ ++struct sflash * ++sflash_init(chipcregs_t *cc) ++{ ++ uint32 id, id2; ++ ++ bzero(&sflash, sizeof(sflash)); ++ ++ sflash.type = R_REG(&cc->capabilities) & CAP_FLASH_MASK; ++ ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Probe for ST chips */ ++ sflash_cmd(cc, SFLASH_ST_DP); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id = R_REG(&cc->flashdata); ++ switch (id) { ++ case 0x11: ++ /* ST M25P20 2 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 4; ++ break; ++ case 0x12: ++ /* ST M25P40 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ break; ++ case 0x13: ++ /* ST M25P80 8 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 16; ++ break; ++ case 0x14: ++ /* ST M25P16 16 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 32; ++ break; ++ case 0x15: ++ /* ST M25P32 32 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 64; ++ break; ++ case 0xbf: ++ W_REG(&cc->flashaddress, 1); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id2 = R_REG(&cc->flashdata); ++ if (id2 == 0x44) { ++ /* SST M25VF80 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ } ++ break; ++ } ++ break; ++ ++ case SFLASH_AT: ++ /* Probe for Atmel chips */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ id = R_REG(&cc->flashdata) & 0x3c; ++ switch (id) { ++ case 0xc: ++ /* Atmel AT45DB011 1Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 512; ++ break; ++ case 0x14: ++ /* Atmel AT45DB021 2Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 1024; ++ break; ++ case 0x1c: ++ /* Atmel AT45DB041 4Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 2048; ++ break; ++ case 0x24: ++ /* Atmel AT45DB081 8Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 4096; ++ break; ++ case 0x2c: ++ /* Atmel AT45DB161 16Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 4096; ++ break; ++ case 0x34: ++ /* Atmel AT45DB321 32Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 8192; ++ break; ++ case 0x3c: ++ /* Atmel AT45DB642 64Mbit Serial Flash */ ++ sflash.blocksize = 1024; ++ sflash.numblocks = 8192; ++ break; ++ } ++ break; ++ } ++ ++ sflash.size = sflash.blocksize * sflash.numblocks; ++ return sflash.size ? &sflash : NULL; ++} ++ ++/* Read len bytes starting at offset into buf. Returns number of bytes read. */ ++int ++sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf) ++{ ++ int cnt; ++ uint32 *from, *to; ++ ++ if (!len) ++ return 0; ++ ++ if ((offset + len) > sflash.size) ++ return -22; ++ ++ if ((len >= 4) && (offset & 3)) ++ cnt = 4 - (offset & 3); ++ else if ((len >= 4) && ((uint32)buf & 3)) ++ cnt = 4 - ((uint32)buf & 3); ++ else ++ cnt = len; ++ ++ from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset); ++ to = (uint32 *)buf; ++ ++ if (cnt < 4) { ++ bcopy(from, to, cnt); ++ return cnt; ++ } ++ ++ while (cnt >= 4) { ++ *to++ = *from++; ++ cnt -= 4; ++ } ++ ++ return (len - cnt); ++} ++ ++/* Poll for command completion. Returns zero when complete. */ ++int ++sflash_poll(chipcregs_t *cc, uint offset) ++{ ++ if (offset >= sflash.size) ++ return -22; ++ ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Check for ST Write In Progress bit */ ++ sflash_cmd(cc, SFLASH_ST_RDSR); ++ return R_REG(&cc->flashdata) & SFLASH_ST_WIP; ++ case SFLASH_AT: ++ /* Check for Atmel Ready bit */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ return !(R_REG(&cc->flashdata) & SFLASH_AT_READY); ++ } ++ ++ return 0; ++} ++ ++/* Write len bytes starting at offset into buf. Returns number of bytes ++ * written. Caller should poll for completion. ++ */ ++int ++sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++{ ++ struct sflash *sfl; ++ int ret = 0; ++ bool is4712b0; ++ uint32 page, byte, mask; ++ ++ if (!len) ++ return 0; ++ ++ if ((offset + len) > sflash.size) ++ return -22; ++ ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ mask = R_REG(&cc->chipid); ++ is4712b0 = (((mask & CID_ID_MASK) == BCM4712_DEVICE_ID) && ++ ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT))); ++ /* Enable writes */ ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ if (is4712b0) { ++ mask = 1 << 14; ++ W_REG(&cc->flashaddress, offset); ++ W_REG(&cc->flashdata, *buf++); ++ /* Set chip select */ ++ OR_REG(&cc->gpioout, mask); ++ /* Issue a page program with the first byte */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ ret = 1; ++ offset++; ++ len--; ++ while (len > 0) { ++ if ((offset & 255) == 0) { ++ /* Page boundary, drop cs and return */ ++ AND_REG(&cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -11; ++ } ++ return ret; ++ } else { ++ /* Write single byte */ ++ sflash_cmd(cc, *buf++); ++ } ++ ret++; ++ offset++; ++ len--; ++ } ++ /* All done, drop cs if needed */ ++ if ((offset & 255) != 1) { ++ /* Drop cs */ ++ AND_REG(&cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -12; ++ } ++ } ++ } else { ++ ret = 1; ++ W_REG(&cc->flashaddress, offset); ++ W_REG(&cc->flashdata, *buf); ++ /* Page program */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ } ++ break; ++ case SFLASH_AT: ++ mask = sfl->blocksize - 1; ++ page = (offset & ~mask) << 1; ++ byte = offset & mask; ++ /* Read main memory page into buffer 1 */ ++ if (byte || len < sfl->blocksize) { ++ W_REG(&cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_LOAD); ++ /* 250 us for AT45DB321B */ ++ SPINWAIT(sflash_poll(cc, offset), 1000); ++ ASSERT(!sflash_poll(cc, offset)); ++ } ++ /* Write into buffer 1 */ ++ for (ret = 0; ret < len && byte < sfl->blocksize; ret++) { ++ W_REG(&cc->flashaddress, byte++); ++ W_REG(&cc->flashdata, *buf++); ++ sflash_cmd(cc, SFLASH_AT_BUF1_WRITE); ++ } ++ /* Write buffer 1 into main memory page */ ++ W_REG(&cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM); ++ break; ++ } ++ ++ return ret; ++} ++ ++/* Erase a region. Returns number of bytes scheduled for erasure. ++ * Caller should poll for completion. ++ */ ++int ++sflash_erase(chipcregs_t *cc, uint offset) ++{ ++ struct sflash *sfl; ++ ++ if (offset >= sflash.size) ++ return -22; ++ ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ W_REG(&cc->flashaddress, offset); ++ sflash_cmd(cc, SFLASH_ST_SE); ++ return sfl->blocksize; ++ case SFLASH_AT: ++ W_REG(&cc->flashaddress, offset << 1); ++ sflash_cmd(cc, SFLASH_AT_PAGE_ERASE); ++ return sfl->blocksize; ++ } ++ ++ return 0; ++} ++ ++/* ++ * writes the appropriate range of flash, a NULL buf simply erases ++ * the region of flash ++ */ ++int ++sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++{ ++ struct sflash *sfl; ++ uchar *block = NULL, *cur_ptr, *blk_ptr; ++ uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder; ++ uint blk_offset, blk_len, copied; ++ int bytes, ret = 0; ++ ++ /* Check address range */ ++ if (len <= 0) ++ return 0; ++ ++ sfl = &sflash; ++ if ((offset + len) > sfl->size) ++ return -1; ++ ++ blocksize = sfl->blocksize; ++ mask = blocksize - 1; ++ ++ /* Allocate a block of mem */ ++ if (!(block = MALLOC(NULL, blocksize))) ++ return -1; ++ ++ while (len) { ++ /* Align offset */ ++ cur_offset = offset & ~mask; ++ cur_length = blocksize; ++ cur_ptr = block; ++ ++ remainder = blocksize - (offset & mask); ++ if (len < remainder) ++ cur_retlen = len; ++ else ++ cur_retlen = remainder; ++ ++ /* buf == NULL means erase only */ ++ if (buf) { ++ /* Copy existing data into holding block if necessary */ ++ if ((offset & mask) || (len < blocksize)) { ++ blk_offset = cur_offset; ++ blk_len = cur_length; ++ blk_ptr = cur_ptr; ++ ++ /* Copy entire block */ ++ while(blk_len) { ++ copied = sflash_read(cc, blk_offset, blk_len, blk_ptr); ++ blk_offset += copied; ++ blk_len -= copied; ++ blk_ptr += copied; ++ } ++ } ++ ++ /* Copy input data into holding block */ ++ memcpy(cur_ptr + (offset & mask), buf, cur_retlen); ++ } ++ ++ /* Erase block */ ++ if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0) ++ goto done; ++ while (sflash_poll(cc, (uint) cur_offset)); ++ ++ /* buf == NULL means erase only */ ++ if (!buf) { ++ offset += cur_retlen; ++ len -= cur_retlen; ++ continue; ++ } ++ ++ /* Write holding block */ ++ while (cur_length > 0) { ++ if ((bytes = sflash_write(cc, ++ (uint) cur_offset, ++ (uint) cur_length, ++ (uchar *) cur_ptr)) < 0) { ++ ret = bytes; ++ goto done; ++ } ++ while (sflash_poll(cc, (uint) cur_offset)); ++ cur_offset += bytes; ++ cur_length -= bytes; ++ cur_ptr += bytes; ++ } ++ ++ offset += cur_retlen; ++ len -= cur_retlen; ++ buf += cur_retlen; ++ } ++ ++ ret = len; ++done: ++ if (block) ++ MFREE(NULL, block, blocksize); ++ return ret; ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/time.c linux-2.4.32-brcm/arch/mips/bcm947xx/time.c +--- linux-2.4.32/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/time.c 2005-12-16 23:39:10.948837000 +0100 +@@ -0,0 +1,118 @@ ++/* ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: time.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Global SB handle */ ++extern void *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++ ++extern int panic_timeout; ++static int watchdog = 0; ++static u8 *mcr = NULL; ++ ++void __init ++bcm947xx_time_init(void) ++{ ++ unsigned int hz; ++ extifregs_t *eir; ++ ++ /* ++ * Use deterministic values for initial counter interrupt ++ * so that calibrate delay avoids encountering a counter wrap. ++ */ ++ write_c0_count(0); ++ write_c0_compare(0xffff); ++ ++ if (!(hz = sb_mips_clock(sbh))) ++ hz = 100000000; ++ ++ printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh), ++ (hz + 500000) / 1000000); ++ ++ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ ++ mips_hpt_frequency = hz / 2; ++ ++ /* Set watchdog interval in ms */ ++ watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0); ++ ++ /* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */ ++ if (watchdog > 0) { ++ if (watchdog < 3000) ++ watchdog = 3000; ++ } ++ ++ ++ /* Set panic timeout in seconds */ ++ panic_timeout = watchdog / 1000; ++ ++ /* Setup blink */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF); ++ unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1))); ++ mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1); ++ } ++} ++ ++static void ++bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ /* Generic MIPS timer code */ ++ timer_interrupt(irq, dev_id, regs); ++ ++ /* Set the watchdog timer to reset after the specified number of ms */ ++ if (watchdog > 0) ++ sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog); ++ ++#ifdef CONFIG_HWSIM ++ (*((int *)0xa0000f1c))++; ++#else ++ /* Blink one of the LEDs in the external UART */ ++ if (mcr && !(jiffies % (HZ/2))) ++ writeb(readb(mcr) ^ UART_MCR_OUT2, mcr); ++#endif ++} ++ ++static struct irqaction bcm947xx_timer_irqaction = { ++ bcm947xx_timer_interrupt, ++ SA_INTERRUPT, ++ 0, ++ "timer", ++ NULL, ++ NULL ++}; ++ ++void __init ++bcm947xx_timer_setup(struct irqaction *irq) ++{ ++ /* Enable the timer interrupt */ ++ setup_irq(7, &bcm947xx_timer_irqaction); ++} +diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/config-shared.in +--- linux-2.4.32/arch/mips/config-shared.in 2005-01-19 15:09:27.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/config-shared.in 2005-12-16 23:39:11.080845250 +0100 +@@ -205,6 +205,14 @@ + fi + define_bool CONFIG_MIPS_RTC y + fi ++dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL ++dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ bool ' Support for Broadcom BCM4710' CONFIG_BCM4710 ++ bool ' Support for Broadcom BCM4310' CONFIG_BCM4310 ++ bool ' Support for Broadcom BCM4704' CONFIG_BCM4704 ++ bool ' Support for Broadcom BCM5365' CONFIG_BCM5365 ++fi + bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI + bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 + bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 +@@ -226,6 +234,11 @@ + define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n + + # ++# Provide an option for a default kernel command line ++# ++string 'Default kernel command string' CONFIG_CMDLINE "" ++ ++# + # Select some configuration options automatically based on user selections. + # + if [ "$CONFIG_ACER_PICA_61" = "y" ]; then +@@ -533,6 +546,13 @@ + define_bool CONFIG_SWAP_IO_SPACE_L y + define_bool CONFIG_BOOT_ELF32 y + fi ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ define_bool CONFIG_PCI y ++ define_bool CONFIG_NONCOHERENT_IO y ++ define_bool CONFIG_NEW_TIME_C y ++ define_bool CONFIG_NEW_IRQ y ++ define_bool CONFIG_HND y ++fi + if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then + define_bool CONFIG_ARC32 y + define_bool CONFIG_ARC_MEMORY y +@@ -1011,7 +1031,11 @@ + + bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE + bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG +-bool 'Remote GDB kernel debugging' CONFIG_KGDB ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG ++else ++ bool 'Remote GDB kernel debugging' CONFIG_KGDB ++fi + dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB + if [ "$CONFIG_KGDB" = "y" ]; then + define_bool CONFIG_DEBUG_INFO y +diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c +--- linux-2.4.32/arch/mips/kernel/cpu-probe.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c 2005-12-16 23:39:11.084845500 +0100 +@@ -174,7 +174,7 @@ + + static inline void cpu_probe_legacy(struct cpuinfo_mips *c) + { +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_R2000: + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; +@@ -184,7 +184,7 @@ + c->tlbsize = 64; + break; + case PRID_IMP_R3000: +- if ((c->processor_id & 0xff) == PRID_REV_R3000A) ++ if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; + else +@@ -199,12 +199,12 @@ + break; + case PRID_IMP_R4000: + if (read_c0_config() & CONF_SC) { +- if ((c->processor_id & 0xff) >= PRID_REV_R4400) ++ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) + c->cputype = CPU_R4400PC; + else + c->cputype = CPU_R4000PC; + } else { +- if ((c->processor_id & 0xff) >= PRID_REV_R4400) ++ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + c->cputype = CPU_R4000SC; +@@ -450,7 +450,7 @@ + static inline void cpu_probe_mips(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; +@@ -491,10 +491,10 @@ + { + decode_config1(c); + c->options |= MIPS_CPU_PREFETCH; +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: +- switch ((c->processor_id >> 24) & 0xff) { ++ switch ((c->processor_id >> 24) & PRID_REV_MASK) { + case 0: + c->cputype = CPU_AU1000; + break; +@@ -522,10 +522,34 @@ + } + } + ++static inline void cpu_probe_broadcom(struct cpuinfo_mips *c) ++{ ++ decode_config1(c); ++ c->options |= MIPS_CPU_PREFETCH; ++ switch (c->processor_id & PRID_IMP_MASK) { ++ case PRID_IMP_BCM4710: ++ c->cputype = CPU_BCM4710; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; ++ c->scache.flags = MIPS_CACHE_NOT_PRESENT; ++ break; ++ case PRID_IMP_4KC: ++ case PRID_IMP_BCM3302: ++ c->cputype = CPU_BCM3302; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; ++ c->scache.flags = MIPS_CACHE_NOT_PRESENT; ++ break; ++ default: ++ c->cputype = CPU_UNKNOWN; ++ break; ++ } ++} ++ + static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_SB1: + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; +@@ -547,7 +571,7 @@ + static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; +@@ -572,7 +596,7 @@ + c->cputype = CPU_UNKNOWN; + + c->processor_id = read_c0_prid(); +- switch (c->processor_id & 0xff0000) { ++ switch (c->processor_id & PRID_COMP_MASK) { + + case PRID_COMP_LEGACY: + cpu_probe_legacy(c); +@@ -583,6 +607,9 @@ + case PRID_COMP_ALCHEMY: + cpu_probe_alchemy(c); + break; ++ case PRID_COMP_BROADCOM: ++ cpu_probe_broadcom(c); ++ break; + case PRID_COMP_SIBYTE: + cpu_probe_sibyte(c); + break; +diff -Nur linux-2.4.32/arch/mips/kernel/head.S linux-2.4.32-brcm/arch/mips/kernel/head.S +--- linux-2.4.32/arch/mips/kernel/head.S 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/head.S 2005-12-16 23:39:11.084845500 +0100 +@@ -28,12 +28,20 @@ + #include + #include + ++#ifdef CONFIG_BCM4710 ++#undef eret ++#define eret nop; nop; eret ++#endif ++ + .text ++ j kernel_entry ++ nop ++ + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. + */ +- .fill 0x400 ++ .fill 0x3f4 + + /* The following two symbols are used for kernel profiling. */ + EXPORT(stext) +diff -Nur linux-2.4.32/arch/mips/kernel/proc.c linux-2.4.32-brcm/arch/mips/kernel/proc.c +--- linux-2.4.32/arch/mips/kernel/proc.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/proc.c 2005-12-16 23:39:11.084845500 +0100 +@@ -78,9 +78,10 @@ + [CPU_AU1550] "Au1550", + [CPU_24K] "MIPS 24K", + [CPU_AU1200] "Au1200", ++ [CPU_BCM4710] "BCM4710", ++ [CPU_BCM3302] "BCM3302", + }; + +- + static int show_cpuinfo(struct seq_file *m, void *v) + { + unsigned int version = current_cpu_data.processor_id; +diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kernel/setup.c +--- linux-2.4.32/arch/mips/kernel/setup.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/setup.c 2005-12-16 23:39:11.140849000 +0100 +@@ -495,6 +495,7 @@ + void swarm_setup(void); + void hp_setup(void); + void au1x00_setup(void); ++ void brcm_setup(void); + void frame_info_init(void); + + frame_info_init(); +@@ -693,6 +694,11 @@ + pmc_yosemite_setup(); + break; + #endif ++#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310) ++ case MACH_GROUP_BRCM: ++ brcm_setup(); ++ break; ++#endif + default: + panic("Unsupported architecture"); + } +diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kernel/traps.c +--- linux-2.4.32/arch/mips/kernel/traps.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/traps.c 2005-12-16 23:39:11.140849000 +0100 +@@ -913,6 +913,7 @@ + void __init trap_init(void) + { + extern char except_vec1_generic; ++ extern char except_vec2_generic; + extern char except_vec3_generic, except_vec3_r4000; + extern char except_vec_ejtag_debug; + extern char except_vec4; +@@ -922,6 +923,7 @@ + + /* Copy the generic exception handler code to it's final destination. */ + memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); ++ memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + + /* + * Setup default vectors +@@ -980,6 +982,12 @@ + set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); + ++ if (current_cpu_data.cputype == CPU_SB1) { ++ /* Enable timer interrupt and scd mapped interrupt */ ++ clear_c0_status(0xf000); ++ set_c0_status(0xc00); ++ } ++ + if (cpu_has_fpu && !cpu_has_nofpuex) + set_except_vector(15, handle_fpe); + +diff -Nur linux-2.4.32/arch/mips/Makefile linux-2.4.32-brcm/arch/mips/Makefile +--- linux-2.4.32/arch/mips/Makefile 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/Makefile 2005-12-16 23:39:10.668819500 +0100 +@@ -715,6 +715,19 @@ + endif + + # ++# Broadcom BCM947XX variants ++# ++ifdef CONFIG_BCM947XX ++LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o ++SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx ++LOADADDR := 0x80001000 ++ ++zImage: vmlinux ++ $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed ++export LOADADDR ++endif ++ ++# + # Choosing incompatible machines durings configuration will result in + # error messages during linking. Select a default linkscript if + # none has been choosen above. +@@ -767,6 +780,7 @@ + $(MAKE) -C arch/$(ARCH)/tools clean + $(MAKE) -C arch/mips/baget clean + $(MAKE) -C arch/mips/lasat clean ++ $(MAKE) -C arch/mips/bcm947xx/compressed clean + + archmrproper: + @$(MAKEBOOT) mrproper +diff -Nur linux-2.4.32/arch/mips/mm/c-r4k.c linux-2.4.32-brcm/arch/mips/mm/c-r4k.c +--- linux-2.4.32/arch/mips/mm/c-r4k.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/mm/c-r4k.c 2005-12-16 23:39:11.144849250 +0100 +@@ -1114,3 +1114,47 @@ + build_clear_page(); + build_copy_page(); + } ++ ++#ifdef CONFIG_BCM4704 ++static void __init mips32_icache_fill(unsigned long addr, uint nbytes) ++{ ++ unsigned long ic_lsize = current_cpu_data.icache.linesz; ++ int i; ++ for (i = 0; i < nbytes; i += ic_lsize) ++ fill_icache_line((addr + i)); ++} ++ ++/* ++ * This must be run from the cache on 4704A0 ++ * so there are no mips core BIU ops in progress ++ * when the PFC is enabled. ++ */ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ ++static void __init enable_pfc(u32 mode) ++{ ++ /* write range */ ++ *(volatile u32 *)PFC_CR1 = 0xffff0000; ++ ++ /* enable */ ++ *(volatile u32 *)PFC_CR0 = mode; ++} ++#endif ++ ++ ++void check_enable_mips_pfc(int val) ++{ ++ ++#ifdef CONFIG_BCM4704 ++ struct cpuinfo_mips *c = ¤t_cpu_data; ++ ++ /* enable prefetch cache */ ++ if (((c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) == PRID_IMP_BCM3302) ++ && (read_c0_diag() & (1 << 29))) { ++ mips32_icache_fill((unsigned long) &enable_pfc, 64); ++ enable_pfc(val); ++ } ++#endif ++} ++ ++ +diff -Nur linux-2.4.32/arch/mips/pci/Makefile linux-2.4.32-brcm/arch/mips/pci/Makefile +--- linux-2.4.32/arch/mips/pci/Makefile 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/pci/Makefile 2005-12-16 23:39:11.144849250 +0100 +@@ -13,7 +13,9 @@ + obj-$(CONFIG_MIPS_MSC) += ops-msc.o + obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o + obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o ++ifndef CONFIG_BCM947XX + obj-y += pci.o ++endif + obj-$(CONFIG_PCI_AUTO) += pci_auto.o + + include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/serial.c +--- linux-2.4.32/drivers/char/serial.c 2005-11-16 20:12:54.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/char/serial.c 2005-12-16 23:39:11.200852750 +0100 +@@ -422,6 +422,10 @@ + return inb(info->port+1); + #endif + case SERIAL_IO_MEM: ++#ifdef CONFIG_BCM4310 ++ readb((unsigned long) info->iomem_base + ++ (UART_SCR<iomem_reg_shift)); ++#endif + return readb((unsigned long) info->iomem_base + + (offset<iomem_reg_shift)); + default: +@@ -442,6 +446,9 @@ + case SERIAL_IO_MEM: + writeb(value, (unsigned long) info->iomem_base + + (offset<iomem_reg_shift)); ++#ifdef CONFIG_BCM4704 ++ *((volatile unsigned int *) KSEG1ADDR(0x18000000)); ++#endif + break; + default: + outb(value, info->port+offset); +@@ -1704,7 +1711,7 @@ + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) +- quot = baud_base / baud; ++ quot = (baud_base + (baud / 2)) / baud; + } + /* If the quotient is zero refuse the change */ + if (!quot && old_termios) { +@@ -1721,12 +1728,12 @@ + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) +- quot = baud_base / baud; ++ quot = (baud_base + (baud / 2)) / baud; + } + } + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) +- quot = baud_base / 9600; ++ quot = (baud_base + 4800) / 9600; + /* + * Work around a bug in the Oxford Semiconductor 952 rev B + * chip which causes it to seriously miscalculate baud rates +@@ -5982,6 +5989,13 @@ + * Divisor, bytesize and parity + */ + state = rs_table + co->index; ++ /* ++ * Safe guard: state structure must have been initialized ++ */ ++ if (state->iomem_base == NULL) { ++ printk("!unable to setup serial console!\n"); ++ return -1; ++ } + if (doflow) + state->flags |= ASYNC_CONS_FLOW; + info = &async_sercons; +@@ -5995,7 +6009,7 @@ + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; +- quot = state->baud_base / baud; ++ quot = (state->baud_base + (baud / 2)) / baud; + cval = cflag & (CSIZE | CSTOPB); + #if defined(__powerpc__) || defined(__alpha__) + cval >>= 8; +diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Config.in +--- linux-2.4.32/drivers/net/Config.in 2005-01-19 15:09:56.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/Config.in 2005-12-16 23:39:11.232854750 +0100 +@@ -2,6 +2,8 @@ + # Network device configuration + # + ++tristate 'Broadcom Home Network Division' CONFIG_HND $CONFIG_PCI ++ + source drivers/net/arcnet/Config.in + + tristate 'Dummy net driver support' CONFIG_DUMMY +diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c +--- linux-2.4.32/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c 2005-12-16 23:39:11.284858000 +0100 +@@ -0,0 +1,936 @@ ++/* ++ * Misc useful routines to access NIC SROM/OTP . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include /* for sprom content groking */ ++ ++#define VARS_MAX 4096 /* should be reduced */ ++ ++#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ ++#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ ++ ++static int initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count); ++static int initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count); ++static int initvars_flash_sb(void *sbh, char **vars, int *count); ++static int srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count); ++static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd); ++static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data); ++static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data); ++static int sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc); ++ ++static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count); ++static int initvars_flash(osl_t *osh, char **vp, int len, char *devpath); ++ ++/* ++ * Initialize local vars from the right source for this platform. ++ * Return 0 on success, nonzero on error. ++ */ ++int ++srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, int *count) ++{ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ if (vars == NULL || count == NULL) ++ return (0); ++ ++ switch (BUSTYPE(bustype)) { ++ case SB_BUS: ++ case JTAG_BUS: ++ return initvars_flash_sb(sbh, vars, count); ++ ++ case PCI_BUS: ++ ASSERT(curmap); /* can not be NULL */ ++ return initvars_srom_pci(sbh, curmap, vars, count); ++ ++ case PCMCIA_BUS: ++ return initvars_cis_pcmcia(sbh, osh, vars, count); ++ ++ ++ default: ++ ASSERT(0); ++ } ++ return (-1); ++} ++ ++/* support only 16-bit word read from srom */ ++int ++srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) ++{ ++ void *srom; ++ uint i, off, nw; ++ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; ++ ++ off = byteoff / 2; ++ nw = nbytes / 2; ++ ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ if (!curmap) ++ return 1; ++ srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET; ++ if (sprom_read_pci(srom, off, buf, nw, FALSE)) ++ return 1; ++ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { ++ for (i = 0; i < nw; i++) { ++ if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i))) ++ return 1; ++ } ++ } else { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* support only 16-bit word write into srom */ ++int ++srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) ++{ ++ uint16 *srom; ++ uint i, off, nw, crc_range; ++ uint16 image[SPROM_SIZE], *p; ++ uint8 crc; ++ volatile uint32 val32; ++ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; ++ ++ crc_range = (((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS)) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2; ++ ++ /* if changes made inside crc cover range */ ++ if (byteoff < crc_range) { ++ nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2; ++ /* read data including entire first 64 words from srom */ ++ if (srom_read(bustype, curmap, osh, 0, nw * 2, image)) ++ return 1; ++ /* make changes */ ++ bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); ++ /* calculate crc */ ++ htol16_buf(image, crc_range); ++ crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); ++ ltoh16_buf(image, crc_range); ++ image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); ++ p = image; ++ off = 0; ++ } else { ++ p = buf; ++ off = byteoff / 2; ++ nw = nbytes / 2; ++ } ++ ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET); ++ /* enable writes to the SPROM */ ++ val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); ++ val32 |= SPROM_WRITEEN; ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ /* write srom */ ++ for (i = 0; i < nw; i++) { ++ W_REG(&srom[off + i], p[i]); ++ bcm_mdelay(WRITE_WORD_DELAY); ++ } ++ /* disable writes to the SPROM */ ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN); ++ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { ++ /* enable writes to the SPROM */ ++ if (sprom_cmd_pcmcia(osh, SROM_WEN)) ++ return 1; ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ /* write srom */ ++ for (i = 0; i < nw; i++) { ++ sprom_write_pcmcia(osh, (uint16)(off + i), p[i]); ++ bcm_mdelay(WRITE_WORD_DELAY); ++ } ++ /* disable writes to the SPROM */ ++ if (sprom_cmd_pcmcia(osh, SROM_WDS)) ++ return 1; ++ } else { ++ return 1; ++ } ++ ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ return 0; ++} ++ ++ ++static int ++srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count) ++{ ++ char eabuf[32]; ++ char *vp, *base; ++ uint8 tup, tlen, sromrev = 1; ++ int i, j; ++ uint varsize; ++ bool ag_init = FALSE; ++ uint32 w32; ++ ++ ASSERT(vars); ++ ASSERT(count); ++ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return -2; ++ ++ i = 0; ++ do { ++ tup = cis[i++]; ++ tlen = cis[i++]; ++ if ((i + tlen) >= CIS_SIZE) ++ break; ++ ++ switch (tup) { ++ case CISTPL_MANFID: ++ vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]); ++ vp++; ++ vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]); ++ vp++; ++ break; ++ ++ case CISTPL_FUNCE: ++ if (cis[i] == LAN_NID) { ++ ASSERT(cis[i + 1] == ETHER_ADDR_LEN); ++ bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf); ++ vp += sprintf(vp, "il0macaddr=%s", eabuf); ++ vp++; ++ } ++ break; ++ ++ case CISTPL_CFTABLE: ++ vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]); ++ vp++; ++ break; ++ ++ case CISTPL_BRCM_HNBU: ++ switch (cis[i]) { ++ case HNBU_SROMREV: ++ sromrev = cis[i + 1]; ++ break; ++ ++ case HNBU_CHIPID: ++ vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]); ++ vp++; ++ vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]); ++ vp++; ++ if (tlen == 7) { ++ vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]); ++ vp++; ++ } ++ break; ++ ++ case HNBU_BOARDREV: ++ vp += sprintf(vp, "boardrev=%d", cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_AA: ++ vp += sprintf(vp, "aa0=%d", cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_AG: ++ vp += sprintf(vp, "ag0=%d", cis[i + 1]); ++ vp++; ++ ag_init = TRUE; ++ break; ++ ++ case HNBU_CC: ++ ASSERT(sromrev > 1); ++ vp += sprintf(vp, "cc=%d", cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_PAPARMS: ++ if (tlen == 2) { ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]); ++ vp++; ++ } else if (tlen >= 9) { ++ if (tlen == 10) { ++ ASSERT(sromrev == 2); ++ vp += sprintf(vp, "opo=%d", cis[i + 9]); ++ vp++; ++ } else ++ ASSERT(tlen == 9); ++ ++ for (j = 0; j < 3; j++) { ++ vp += sprintf(vp, "pa0b%d=%d", j, ++ (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]); ++ vp++; ++ } ++ vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]); ++ vp++; ++ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]); ++ vp++; ++ } else ++ ASSERT(tlen >= 9); ++ break; ++ ++ case HNBU_OEM: ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", ++ cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4], ++ cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]); ++ vp++; ++ break; ++ ++ case HNBU_BOARDFLAGS: ++ w32 = (cis[i + 2] << 8) + cis[i + 1]; ++ if (tlen == 5) ++ w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16); ++ vp += sprintf(vp, "boardflags=0x%x", w32); ++ vp++; ++ break; ++ ++ case HNBU_LEDS: ++ if (cis[i + 1] != 0xff) { ++ vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]); ++ vp++; ++ } ++ if (cis[i + 2] != 0xff) { ++ vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]); ++ vp++; ++ } ++ if (cis[i + 3] != 0xff) { ++ vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]); ++ vp++; ++ } ++ if (cis[i + 4] != 0xff) { ++ vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]); ++ vp++; ++ } ++ break; ++ ++ case HNBU_CCODE: ++ ASSERT(sromrev > 1); ++ vp += sprintf(vp, "ccode=%c%c", cis[i + 1], cis[i + 2]); ++ vp++; ++ vp += sprintf(vp, "cctl=0x%x", cis[i + 3]); ++ vp++; ++ break; ++ ++ case HNBU_CCKPO: ++ ASSERT(sromrev > 2); ++ vp += sprintf(vp, "cckpo=0x%x", (cis[i + 2] << 8) | cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_OFDMPO: ++ ASSERT(sromrev > 2); ++ vp += sprintf(vp, "ofdmpo=0x%x", (cis[i + 4] << 24) | ++ (cis[i + 3] << 16) | (cis[i + 2] << 8) | cis[i + 1]); ++ vp++; ++ break; ++ } ++ break; ++ ++ } ++ i += tlen; ++ } while (tup != 0xff); ++ ++ /* Set the srom version */ ++ vp += sprintf(vp, "sromrev=%d", sromrev); ++ vp++; ++ ++ /* if there is no antenna gain field, set default */ ++ if (ag_init == FALSE) { ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "ag0=%d", 0xff); ++ vp++; ++ } ++ ++ /* final nullbyte terminator */ ++ *vp++ = '\0'; ++ varsize = (uint)(vp - base); ++ ++ ASSERT((vp - base) < VARS_MAX); ++ ++ if (varsize == VARS_MAX) { ++ *vars = base; ++ } else { ++ vp = MALLOC(osh, varsize); ++ ASSERT(vp); ++ if (vp) ++ bcopy(base, vp, varsize); ++ MFREE(osh, base, VARS_MAX); ++ *vars = vp; ++ if (!vp) { ++ *count = 0; ++ return -2; ++ } ++ } ++ *count = varsize; ++ ++ return (0); ++} ++ ++ ++/* set PCMCIA sprom command register */ ++static int ++sprom_cmd_pcmcia(osl_t *osh, uint8 cmd) ++{ ++ uint8 status = 0; ++ uint wait_cnt = 1000; ++ ++ /* write sprom command register */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1); ++ ++ /* wait status */ ++ while (wait_cnt--) { ++ OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1); ++ if (status & SROM_DONE) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* read a word from the PCMCIA srom */ ++static int ++sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data) ++{ ++ uint8 addr_l, addr_h, data_l, data_h; ++ ++ addr_l = (uint8)((addr * 2) & 0xff); ++ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); ++ ++ /* set address */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); ++ ++ /* do read */ ++ if (sprom_cmd_pcmcia(osh, SROM_READ)) ++ return 1; ++ ++ /* read data */ ++ data_h = data_l = 0; ++ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1); ++ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1); ++ ++ *data = (data_h << 8) | data_l; ++ return 0; ++} ++ ++/* write a word to the PCMCIA srom */ ++static int ++sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data) ++{ ++ uint8 addr_l, addr_h, data_l, data_h; ++ ++ addr_l = (uint8)((addr * 2) & 0xff); ++ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); ++ data_l = (uint8)(data & 0xff); ++ data_h = (uint8)((data >> 8) & 0xff); ++ ++ /* set address */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); ++ ++ /* write data */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1); ++ ++ /* do write */ ++ return sprom_cmd_pcmcia(osh, SROM_WRITE); ++} ++ ++/* ++ * Read in and validate sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) ++{ ++ int err = 0; ++ uint i; ++ ++ /* read the sprom */ ++ for (i = 0; i < nwords; i++) ++ buf[i] = R_REG(&sprom[wordoff + i]); ++ ++ if (check_crc) { ++ /* fixup the endianness so crc8 will pass */ ++ htol16_buf(buf, nwords * 2); ++ if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) ++ err = 1; ++ /* now correct the endianness of the byte array */ ++ ltoh16_buf(buf, nwords * 2); ++ } ++ ++ return err; ++} ++ ++/* ++* Create variable table from memory. ++* Return 0 on success, nonzero on error. ++*/ ++static int ++initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count) ++{ ++ int c = (int)(end - start); ++ ++ /* do it only when there is more than just the null string */ ++ if (c > 1) { ++ char *vp = MALLOC(osh, c); ++ ASSERT(vp); ++ if (!vp) ++ return BCME_NOMEM; ++ bcopy(start, vp, c); ++ *vars = vp; ++ *count = c; ++ } ++ else { ++ *vars = NULL; ++ *count = 0; ++ } ++ ++ return 0; ++} ++ ++/* ++* Find variables with from flash. 'base' points to the beginning ++* of the table upon enter and to the end of the table upon exit when success. ++* Return 0 on success, nonzero on error. ++*/ ++static int ++initvars_flash(osl_t *osh, char **base, int size, char *devpath) ++{ ++ char *vp = *base; ++ char *flash; ++ int err; ++ char *s; ++ uint l, dl, copy_len; ++ ++ /* allocate memory and read in flash */ ++ if (!(flash = MALLOC(osh, NVRAM_SPACE))) ++ return BCME_NOMEM; ++ if ((err = BCMINIT(nvram_getall)(flash, NVRAM_SPACE))) ++ goto exit; ++ ++ /* grab vars with the prefix in name */ ++ dl = strlen(devpath); ++ for (s = flash; s && *s; s += l + 1) { ++ l = strlen(s); ++ ++ /* skip non-matching variable */ ++ if (strncmp(s, devpath, dl)) ++ continue; ++ ++ /* is there enough room to copy? */ ++ copy_len = l - dl + 1; ++ if (size < (int)copy_len) { ++ err = BCME_BUFTOOSHORT; ++ goto exit; ++ } ++ ++ /* no prefix, just the name=value */ ++ strcpy(vp, &s[dl]); ++ vp += copy_len; ++ size -= copy_len; ++ } ++ ++ /* add null string as terminator */ ++ if (size < 1) { ++ err = BCME_BUFTOOSHORT; ++ goto exit; ++ } ++ *vp++ = '\0'; ++ ++ *base = vp; ++ ++exit: MFREE(osh, flash, NVRAM_SPACE); ++ return err; ++} ++ ++/* ++ * Initialize nonvolatile variable table from flash. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_flash_sb(void *sbh, char **vars, int *count) ++{ ++ osl_t *osh = sb_osh(sbh); ++ char devpath[SB_DEVPATH_BUFSZ]; ++ char *vp, *base; ++ int err; ++ ++ ASSERT(vars); ++ ASSERT(count); ++ ++ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) ++ return err; ++ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return BCME_NOMEM; ++ ++ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) ++ goto err; ++ ++ err = initvars_table(osh, base, vp, vars, count); ++ ++err: MFREE(osh, base, VARS_MAX); ++ return err; ++} ++ ++/* ++ * Initialize nonvolatile variable table from sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count) ++{ ++ uint16 w, b[64]; ++ uint8 sromrev; ++ struct ether_addr ea; ++ char eabuf[32]; ++ uint32 w32; ++ int woff, i; ++ char *vp, *base; ++ osl_t *osh = sb_osh(sbh); ++ bool flash = FALSE; ++ char name[SB_DEVPATH_BUFSZ+16], *value; ++ char devpath[SB_DEVPATH_BUFSZ]; ++ int err; ++ ++ /* ++ * Apply CRC over SROM content regardless SROM is present or not, ++ * and use variable sromrev's existance in flash to decide ++ * if we should return an error when CRC fails or read SROM variables ++ * from flash. ++ */ ++ if (sprom_read_pci((void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof(b)/sizeof(b[0]), TRUE)) { ++ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) ++ return err; ++ sprintf(name, "%ssromrev", devpath); ++ if (!(value = getvar(NULL, name))) ++ return (-1); ++ sromrev = (uint8)bcm_strtoul(value, NULL, 0); ++ flash = TRUE; ++ } ++ /* srom is good */ ++ else { ++ /* top word of sprom contains version and crc8 */ ++ sromrev = b[63] & 0xff; ++ /* bcm4401 sroms misprogrammed */ ++ if (sromrev == 0x10) ++ sromrev = 1; ++ } ++ ++ /* srom version check */ ++ if (sromrev > 3) ++ return (-2); ++ ++ ASSERT(vars); ++ ASSERT(count); ++ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return -2; ++ ++ /* read variables from flash */ ++ if (flash) { ++ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) ++ goto err; ++ goto done; ++ } ++ ++ vp += sprintf(vp, "sromrev=%d", sromrev); ++ vp++; ++ ++ if (sromrev >= 3) { ++ /* New section takes over the 3th hardware function space */ ++ ++ /* Words 22+23 are 11a (mid) ofdm power offsets */ ++ w32 = ((uint32)b[23] << 16) | b[22]; ++ vp += sprintf(vp, "ofdmapo=%d", w32); ++ vp++; ++ ++ /* Words 24+25 are 11a (low) ofdm power offsets */ ++ w32 = ((uint32)b[25] << 16) | b[24]; ++ vp += sprintf(vp, "ofdmalpo=%d", w32); ++ vp++; ++ ++ /* Words 26+27 are 11a (high) ofdm power offsets */ ++ w32 = ((uint32)b[27] << 16) | b[26]; ++ vp += sprintf(vp, "ofdmahpo=%d", w32); ++ vp++; ++ ++ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ ++ w32 = ((uint32)b[43] << 24) | ((uint32)b[42] << 8); ++ vp += sprintf(vp, "gpiotimerval=%d", w32); ++ ++ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ ++ w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xFF) << 24) | /* oncount*/ ++ ((uint32)((unsigned char)(b[21] & 0xFF)) << 8); /* offcount */ ++ vp += sprintf(vp, "gpiotimerval=%d", w32); ++ ++ vp++; ++ } ++ ++ if (sromrev >= 2) { ++ /* New section takes over the 4th hardware function space */ ++ ++ /* Word 29 is max power 11a high/low */ ++ w = b[29]; ++ vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Words 30-32 set the 11alow pa settings, ++ * 33-35 are the 11ahigh ones. ++ */ ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]); ++ vp++; ++ vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]); ++ vp++; ++ } ++ w = b[59]; ++ if (w == 0) ++ vp += sprintf(vp, "ccode="); ++ else ++ vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); ++ vp++; ++ ++ } ++ ++ /* parameter section of sprom starts at byte offset 72 */ ++ woff = 72/2; ++ ++ /* first 6 bytes are il0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "il0macaddr=%s", eabuf); ++ vp++; ++ ++ /* next 6 bytes are et0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "et0macaddr=%s", eabuf); ++ vp++; ++ ++ /* next 6 bytes are et1macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "et1macaddr=%s", eabuf); ++ vp++; ++ ++ /* ++ * Enet phy settings one or two singles or a dual ++ * Bits 4-0 : MII address for enet0 (0x1f for not there) ++ * Bits 9-5 : MII address for enet1 (0x1f for not there) ++ * Bit 14 : Mdio for enet0 ++ * Bit 15 : Mdio for enet1 ++ */ ++ w = b[woff]; ++ vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1)); ++ vp++; ++ vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1)); ++ vp++; ++ ++ /* Word 46 has board rev, antennas 0/1 & Country code/control */ ++ w = b[46]; ++ vp += sprintf(vp, "boardrev=%d", w & 0xff); ++ vp++; ++ ++ if (sromrev > 1) ++ vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf); ++ else ++ vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf); ++ vp++; ++ ++ vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3); ++ vp++; ++ ++ vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3); ++ vp++; ++ ++ /* Words 47-49 set the (wl) pa settings */ ++ woff = 47; ++ ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]); ++ vp++; ++ vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]); ++ vp++; ++ } ++ ++ /* ++ * Words 50-51 set the customer-configured wl led behavior. ++ * 8 bits/gpio pin. High bit: activehi=0, activelo=1; ++ * LED behavior values defined in wlioctl.h . ++ */ ++ w = b[50]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* gpio0 */ ++ vp += sprintf(vp, "wl0gpio0=%d", (w & 0xff)); ++ vp++; ++ ++ /* gpio1 */ ++ vp += sprintf(vp, "wl0gpio1=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ w = b[51]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* gpio2 */ ++ vp += sprintf(vp, "wl0gpio2=%d", w & 0xff); ++ vp++; ++ ++ /* gpio3 */ ++ vp += sprintf(vp, "wl0gpio3=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ ++ /* Word 52 is max power 0/1 */ ++ w = b[52]; ++ vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Word 56 is idle tssi target 0/1 */ ++ w = b[56]; ++ vp += sprintf(vp, "pa0itssit=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Word 57 is boardflags, if not programmed make it zero */ ++ w32 = (uint32)b[57]; ++ if (w32 == 0xffff) w32 = 0; ++ if (sromrev > 1) { ++ /* Word 28 is the high bits of boardflags */ ++ w32 |= (uint32)b[28] << 16; ++ } ++ vp += sprintf(vp, "boardflags=%d", w32); ++ vp++; ++ ++ /* Word 58 is antenna gain 0/1 */ ++ w = b[58]; ++ vp += sprintf(vp, "ag0=%d", w & 0xff); ++ vp++; ++ ++ vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ if (sromrev == 1) { ++ /* set the oem string */ ++ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", ++ ((b[59] >> 8) & 0xff), (b[59] & 0xff), ++ ((b[60] >> 8) & 0xff), (b[60] & 0xff), ++ ((b[61] >> 8) & 0xff), (b[61] & 0xff), ++ ((b[62] >> 8) & 0xff), (b[62] & 0xff)); ++ vp++; ++ } else if (sromrev == 2) { ++ /* Word 60 OFDM tx power offset from CCK level */ ++ /* OFDM Power Offset - opo */ ++ vp += sprintf(vp, "opo=%d", b[60] & 0xff); ++ vp++; ++ } else { ++ /* Word 60: cck power offsets */ ++ vp += sprintf(vp, "cckpo=%d", b[60]); ++ vp++; ++ ++ /* Words 61+62: 11g ofdm power offsets */ ++ w32 = ((uint32)b[62] << 16) | b[61]; ++ vp += sprintf(vp, "ofdmgpo=%d", w32); ++ vp++; ++ } ++ ++ /* final nullbyte terminator */ ++ *vp++ = '\0'; ++ ++ ASSERT((vp - base) <= VARS_MAX); ++ ++done: err = initvars_table(osh, base, vp, vars, count); ++ ++err: MFREE(osh, base, VARS_MAX); ++ return err; ++} ++ ++/* ++ * Read the cis and call parsecis to initialize the vars. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count) ++{ ++ uint8 *cis = NULL; ++ int rc; ++ uint data_sz; ++ ++ data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE; ++ ++ if ((cis = MALLOC(osh, data_sz)) == NULL) ++ return (-2); ++ ++ if (sb_pcmciarev(sbh) == 1) { ++ if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) { ++ MFREE(osh, cis, data_sz); ++ return (-1); ++ } ++ /* fix up endianess for 16-bit data vs 8-bit parsing */ ++ ltoh16_buf((uint16 *)cis, data_sz); ++ } else ++ OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz); ++ ++ rc = srom_parsecis(osh, cis, vars, count); ++ ++ MFREE(osh, cis, data_sz); ++ ++ return (rc); ++} ++ +diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c +--- linux-2.4.32/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c 2005-12-16 23:39:11.288858250 +0100 +@@ -0,0 +1,1081 @@ ++/* ++ * Misc useful OS-independent routines. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#ifdef BCMDRIVER ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++#include ++#include ++#include ++ ++#ifdef BCMDRIVER ++/* copy a pkt buffer chain into a buffer */ ++uint ++pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++{ ++ uint n, ret = 0; ++ ++ if (len < 0) ++ len = 4096; /* "infinite" */ ++ ++ /* skip 'offset' bytes */ ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) ++ break; ++ offset -= PKTLEN(osh, p); ++ } ++ ++ if (!p) ++ return 0; ++ ++ /* copy the data */ ++ for (; p && len; p = PKTNEXT(osh, p)) { ++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); ++ bcopy(PKTDATA(osh, p) + offset, buf, n); ++ buf += n; ++ len -= n; ++ ret += n; ++ offset = 0; ++ } ++ ++ return ret; ++} ++ ++/* return total length of buffer chain */ ++uint ++pkttotlen(osl_t *osh, void *p) ++{ ++ uint total; ++ ++ total = 0; ++ for (; p; p = PKTNEXT(osh, p)) ++ total += PKTLEN(osh, p); ++ return (total); ++} ++ ++void ++pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]) ++{ ++ q->head = q->tail = NULL; ++ q->maxlen = maxlen; ++ q->len = 0; ++ if (prio_map) { ++ q->priority = TRUE; ++ bcopy(prio_map, q->prio_map, sizeof(q->prio_map)); ++ } ++ else ++ q->priority = FALSE; ++} ++ ++/* should always check pktq_full before calling pktenq */ ++void ++pktenq(struct pktq *q, void *p, bool lifo) ++{ ++ void *next, *prev; ++ ++ /* allow 10 pkts slack */ ++ ASSERT(q->len < (q->maxlen + 10)); ++ ++ /* Queueing chains not allowed */ ++ ASSERT(PKTLINK(p) == NULL); ++ ++ /* Queue is empty */ ++ if (q->tail == NULL) { ++ ASSERT(q->head == NULL); ++ q->head = q->tail = p; ++ } ++ ++ /* Insert at head or tail */ ++ else if (q->priority == FALSE) { ++ /* Insert at head (LIFO) */ ++ if (lifo) { ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ } ++ /* Insert at tail (FIFO) */ ++ else { ++ ASSERT(PKTLINK(q->tail) == NULL); ++ PKTSETLINK(q->tail, p); ++ PKTSETLINK(p, NULL); ++ q->tail = p; ++ } ++ } ++ ++ /* Insert by priority */ ++ else { ++ /* legal priorities 0-7 */ ++ ASSERT(PKTPRIO(p) <= MAXPRIO); ++ ++ ASSERT(q->head); ++ ASSERT(q->tail); ++ /* Shortcut to insertion at tail */ ++ if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) || ++ (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, PKTPRIO(q->tail)))) { ++ prev = q->tail; ++ next = NULL; ++ } ++ /* Insert at head or in the middle */ ++ else { ++ prev = NULL; ++ next = q->head; ++ } ++ /* Walk the queue */ ++ for (; next; prev = next, next = PKTLINK(next)) { ++ /* Priority queue invariant */ ++ ASSERT(!prev || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next))); ++ /* Insert at head of string of packets of same priority (LIFO) */ ++ if (lifo) { ++ if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next))) ++ break; ++ } ++ /* Insert at tail of string of packets of same priority (FIFO) */ ++ else { ++ if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, PKTPRIO(next))) ++ break; ++ } ++ } ++ /* Insert at tail */ ++ if (next == NULL) { ++ ASSERT(PKTLINK(q->tail) == NULL); ++ PKTSETLINK(q->tail, p); ++ PKTSETLINK(p, NULL); ++ q->tail = p; ++ } ++ /* Insert in the middle */ ++ else if (prev) { ++ PKTSETLINK(prev, p); ++ PKTSETLINK(p, next); ++ } ++ /* Insert at head */ ++ else { ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ } ++ } ++ ++ /* List invariants after insertion */ ++ ASSERT(q->head); ++ ASSERT(PKTLINK(q->tail) == NULL); ++ ++ q->len++; ++} ++ ++/* dequeue packet at head */ ++void* ++pktdeq(struct pktq *q) ++{ ++ void *p; ++ ++ if ((p = q->head)) { ++ ASSERT(q->tail); ++ q->head = PKTLINK(p); ++ PKTSETLINK(p, NULL); ++ q->len--; ++ if (q->head == NULL) ++ q->tail = NULL; ++ } ++ else { ++ ASSERT(q->tail == NULL); ++ } ++ ++ return (p); ++} ++ ++/* dequeue packet at tail */ ++void* ++pktdeqtail(struct pktq *q) ++{ ++ void *p; ++ void *next, *prev; ++ ++ if (q->head == q->tail) { /* last packet on queue or queue empty */ ++ p = q->head; ++ q->head = q->tail = NULL; ++ q->len = 0; ++ return(p); ++ } ++ ++ /* start walk at head */ ++ prev = NULL; ++ next = q->head; ++ ++ /* Walk the queue to find prev of q->tail */ ++ for (; next; prev = next, next = PKTLINK(next)) { ++ if (next == q->tail) ++ break; ++ } ++ ++ ASSERT(prev); ++ ++ PKTSETLINK(prev, NULL); ++ q->tail = prev; ++ q->len--; ++ p = next; ++ ++ return (p); ++} ++ ++unsigned char bcm_ctype[] = { ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ ++ _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ ++ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ ++ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ ++ _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ ++ _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */ ++}; ++ ++uchar ++bcm_toupper(uchar c) ++{ ++ if (bcm_islower(c)) ++ c -= 'a'-'A'; ++ return (c); ++} ++ ++ulong ++bcm_strtoul(char *cp, char **endp, uint base) ++{ ++ ulong result, value; ++ bool minus; ++ ++ minus = FALSE; ++ ++ while (bcm_isspace(*cp)) ++ cp++; ++ ++ if (cp[0] == '+') ++ cp++; ++ else if (cp[0] == '-') { ++ minus = TRUE; ++ cp++; ++ } ++ ++ if (base == 0) { ++ if (cp[0] == '0') { ++ if ((cp[1] == 'x') || (cp[1] == 'X')) { ++ base = 16; ++ cp = &cp[2]; ++ } else { ++ base = 8; ++ cp = &cp[1]; ++ } ++ } else ++ base = 10; ++ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { ++ cp = &cp[2]; ++ } ++ ++ result = 0; ++ ++ while (bcm_isxdigit(*cp) && ++ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { ++ result = result*base + value; ++ cp++; ++ } ++ ++ if (minus) ++ result = (ulong)(result * -1); ++ ++ if (endp) ++ *endp = (char *)cp; ++ ++ return (result); ++} ++ ++uint ++bcm_atoi(char *s) ++{ ++ uint n; ++ ++ n = 0; ++ ++ while (bcm_isdigit(*s)) ++ n = (n * 10) + *s++ - '0'; ++ return (n); ++} ++ ++/* return pointer to location of substring 'needle' in 'haystack' */ ++char* ++bcmstrstr(char *haystack, char *needle) ++{ ++ int len, nlen; ++ int i; ++ ++ if ((haystack == NULL) || (needle == NULL)) ++ return (haystack); ++ ++ nlen = strlen(needle); ++ len = strlen(haystack) - nlen + 1; ++ ++ for (i = 0; i < len; i++) ++ if (bcmp(needle, &haystack[i], nlen) == 0) ++ return (&haystack[i]); ++ return (NULL); ++} ++ ++char* ++bcmstrcat(char *dest, const char *src) ++{ ++ strcpy(&dest[strlen(dest)], src); ++ return (dest); ++} ++ ++#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) ++/* registry routine buffer preparation utility functions: ++ * parameter order is like strncpy, but returns count ++ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) ++ */ ++ulong ++wchar2ascii( ++ char *abuf, ++ ushort *wbuf, ++ ushort wbuflen, ++ ulong abuflen ++) ++{ ++ ulong copyct = 1; ++ ushort i; ++ ++ if (abuflen == 0) ++ return 0; ++ ++ /* wbuflen is in bytes */ ++ wbuflen /= sizeof(ushort); ++ ++ for (i = 0; i < wbuflen; ++i) { ++ if (--abuflen == 0) ++ break; ++ *abuf++ = (char) *wbuf++; ++ ++copyct; ++ } ++ *abuf = '\0'; ++ ++ return copyct; ++} ++#endif ++ ++char* ++bcm_ether_ntoa(char *ea, char *buf) ++{ ++ sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x", ++ (uchar)ea[0]&0xff, (uchar)ea[1]&0xff, (uchar)ea[2]&0xff, ++ (uchar)ea[3]&0xff, (uchar)ea[4]&0xff, (uchar)ea[5]&0xff); ++ return (buf); ++} ++ ++/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ ++int ++bcm_ether_atoe(char *p, char *ea) ++{ ++ int i = 0; ++ ++ for (;;) { ++ ea[i++] = (char) bcm_strtoul(p, &p, 16); ++ if (!*p++ || i == 6) ++ break; ++ } ++ ++ return (i == 6); ++} ++ ++void ++bcm_mdelay(uint ms) ++{ ++ uint i; ++ ++ for (i = 0; i < ms; i++) { ++ OSL_DELAY(1000); ++ } ++} ++ ++/* ++ * Search the name=value vars for a specific one and return its value. ++ * Returns NULL if not found. ++ */ ++char* ++getvar(char *vars, char *name) ++{ ++ char *s; ++ int len; ++ ++ len = strlen(name); ++ ++ /* first look in vars[] */ ++ for (s = vars; s && *s; ) { ++ if ((bcmp(s, name, len) == 0) && (s[len] == '=')) ++ return (&s[len+1]); ++ ++ while (*s++) ++ ; ++ } ++ ++ /* then query nvram */ ++ return (BCMINIT(nvram_get)(name)); ++} ++ ++/* ++ * Search the vars for a specific one and return its value as ++ * an integer. Returns 0 if not found. ++ */ ++int ++getintvar(char *vars, char *name) ++{ ++ char *val; ++ ++ if ((val = getvar(vars, name)) == NULL) ++ return (0); ++ ++ return (bcm_strtoul(val, NULL, 0)); ++} ++ ++ ++/* Search for token in comma separated token-string */ ++static int ++findmatch(char *string, char *name) ++{ ++ uint len; ++ char *c; ++ ++ len = strlen(name); ++ while ((c = strchr(string, ',')) != NULL) { ++ if (len == (uint)(c - string) && !strncmp(string, name, len)) ++ return 1; ++ string = c + 1; ++ } ++ ++ return (!strcmp(string, name)); ++} ++ ++/* Return gpio pin number assigned to the named pin */ ++/* ++* Variable should be in format: ++* ++* gpio=pin_name,pin_name ++* ++* This format allows multiple features to share the gpio with mutual ++* understanding. ++* ++* 'def_pin' is returned if a specific gpio is not defined for the requested functionality ++* and if def_pin is not used by others. ++*/ ++uint ++getgpiopin(char *vars, char *pin_name, uint def_pin) ++{ ++ char name[] = "gpioXXXX"; ++ char *val; ++ uint pin; ++ ++ /* Go thru all possibilities till a match in pin name */ ++ for (pin = 0; pin < GPIO_NUMPINS; pin ++) { ++ sprintf(name, "gpio%d", pin); ++ val = getvar(vars, name); ++ if (val && findmatch(val, pin_name)) ++ return pin; ++ } ++ ++ if (def_pin != GPIO_PIN_NOTDEFINED) { ++ /* make sure the default pin is not used by someone else */ ++ sprintf(name, "gpio%d", def_pin); ++ if (getvar(vars, name)) { ++ def_pin = GPIO_PIN_NOTDEFINED; ++ } ++ } ++ ++ return def_pin; ++} ++ ++ ++static char bcm_undeferrstr[BCME_STRLEN]; ++ ++static const char *bcmerrorstrtable[] = \ ++{ "OK", /* 0 */ ++ "Undefined error", /* BCME_ERROR */ ++ "Bad Argument", /* BCME_BADARG*/ ++ "Bad Option", /* BCME_BADOPTION*/ ++ "Not up", /* BCME_NOTUP */ ++ "Not down", /* BCME_NOTDOWN */ ++ "Not AP", /* BCME_NOTAP */ ++ "Not STA", /* BCME_NOTSTA */ ++ "Bad Key Index", /* BCME_BADKEYIDX */ ++ "Radio Off", /* BCME_RADIOOFF */ ++ "Not band locked", /* BCME_NOTBANDLOCKED */ ++ "No clock", /* BCME_NOCLK */ ++ "Bad Rate valueset", /* BCME_BADRATESET */ ++ "Bad Band", /* BCME_BADBAND */ ++ "Buffer too short", /* BCME_BUFTOOSHORT */ ++ "Buffer too length", /* BCME_BUFTOOLONG */ ++ "Busy", /* BCME_BUSY */ ++ "Not Associated", /* BCME_NOTASSOCIATED */ ++ "Bad SSID len", /* BCME_BADSSIDLEN */ ++ "Out of Range Channel", /* BCME_OUTOFRANGECHAN */ ++ "Bad Channel", /* BCME_BADCHAN */ ++ "Bad Address", /* BCME_BADADDR */ ++ "Not Enough Resources", /* BCME_NORESOURCE */ ++ "Unsupported", /* BCME_UNSUPPORTED */ ++ "Bad length", /* BCME_BADLENGTH */ ++ "Not Ready", /* BCME_NOTREADY */ ++ "Not Permitted", /* BCME_EPERM */ ++ "No Memory", /* BCME_NOMEM */ ++ "Associated", /* BCME_ASSOCIATED */ ++ "Not In Range", /* BCME_RANGE */ ++ "Not Found" /* BCME_NOTFOUND */ ++ }; ++ ++/* Convert the Error codes into related Error strings */ ++const char * ++bcmerrorstr(int bcmerror) ++{ ++ int abs_bcmerror; ++ ++ abs_bcmerror = ABS(bcmerror); ++ ++ /* check if someone added a bcmerror code but forgot to add errorstring */ ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); ++ if ( (bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { ++ sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); ++ return bcm_undeferrstr; ++ } ++ ++ ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); ++ ++ return bcmerrorstrtable[abs_bcmerror]; ++} ++#endif /* #ifdef BCMDRIVER */ ++ ++ ++/******************************************************************************* ++ * crc8 ++ * ++ * Computes a crc8 over the input data using the polynomial: ++ * ++ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 ++ * ++ * The caller provides the initial value (either CRC8_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC8_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ ******************************************************************************/ ++ ++static uint8 crc8_table[256] = { ++ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, ++ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, ++ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, ++ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, ++ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, ++ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, ++ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, ++ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, ++ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, ++ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, ++ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, ++ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, ++ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, ++ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, ++ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, ++ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, ++ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, ++ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, ++ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, ++ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, ++ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, ++ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, ++ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, ++ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, ++ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, ++ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, ++ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, ++ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, ++ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, ++ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, ++ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, ++ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F ++}; ++ ++#define CRC_INNER_LOOP(n, c, x) \ ++ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] ++ ++uint8 ++hndcrc8( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ ++) ++{ ++ /* hard code the crc loop instead of using CRC_INNER_LOOP macro ++ * to avoid the undefined and unnecessary (uint8 >> 8) operation. */ ++ while (nbytes-- > 0) ++ crc = crc8_table[(crc ^ *pdata++) & 0xff]; ++ ++ return crc; ++} ++ ++/******************************************************************************* ++ * crc16 ++ * ++ * Computes a crc16 over the input data using the polynomial: ++ * ++ * x^16 + x^12 +x^5 + 1 ++ * ++ * The caller provides the initial value (either CRC16_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC16_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ ******************************************************************************/ ++ ++static uint16 crc16_table[256] = { ++ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, ++ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, ++ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, ++ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, ++ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, ++ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, ++ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, ++ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, ++ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, ++ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, ++ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, ++ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, ++ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, ++ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, ++ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, ++ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, ++ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, ++ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, ++ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, ++ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, ++ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, ++ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, ++ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, ++ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, ++ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, ++ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, ++ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, ++ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, ++ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, ++ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, ++ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, ++ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 ++}; ++ ++uint16 ++hndcrc16( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint16 crc /* either CRC16_INIT_VALUE or previous return value */ ++) ++{ ++ while (nbytes-- > 0) ++ CRC_INNER_LOOP(16, crc, *pdata++); ++ return crc; ++} ++ ++static uint32 crc32_table[256] = { ++ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, ++ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, ++ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, ++ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, ++ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, ++ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, ++ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, ++ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, ++ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, ++ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, ++ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, ++ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, ++ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, ++ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, ++ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, ++ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, ++ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, ++ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, ++ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, ++ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, ++ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, ++ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, ++ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, ++ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, ++ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, ++ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, ++ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, ++ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, ++ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, ++ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, ++ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, ++ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, ++ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, ++ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, ++ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, ++ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, ++ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, ++ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, ++ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, ++ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, ++ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, ++ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, ++ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, ++ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, ++ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, ++ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, ++ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, ++ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, ++ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, ++ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, ++ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, ++ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, ++ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, ++ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, ++ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, ++ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, ++ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, ++ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, ++ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, ++ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, ++ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, ++ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, ++ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, ++ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D ++}; ++ ++uint32 ++hndcrc32( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint32 crc /* either CRC32_INIT_VALUE or previous return value */ ++) ++{ ++ uint8 *pend; ++#ifdef __mips__ ++ uint8 tmp[4]; ++ ulong *tptr = (ulong *)tmp; ++ ++ /* in case the beginning of the buffer isn't aligned */ ++ pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); ++ nbytes -= (pend - pdata); ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++ ++ /* handle bulk of data as 32-bit words */ ++ pend = pdata + (nbytes & 0xfffffffc); ++ while (pdata < pend) { ++ tptr = *((ulong *) pdata); ++ *((ulong *) pdata) += 1; ++ CRC_INNER_LOOP(32, crc, tmp[0]); ++ CRC_INNER_LOOP(32, crc, tmp[1]); ++ CRC_INNER_LOOP(32, crc, tmp[2]); ++ CRC_INNER_LOOP(32, crc, tmp[3]); ++ } ++ ++ /* 1-3 bytes at end of buffer */ ++ pend = pdata + (nbytes & 0x03); ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++#else ++ pend = pdata + nbytes; ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++#endif ++ ++ return crc; ++} ++ ++#ifdef notdef ++#define CLEN 1499 ++#define CBUFSIZ (CLEN+4) ++#define CNBUFS 5 ++ ++void testcrc32(void) ++{ ++ uint j,k,l; ++ uint8 *buf; ++ uint len[CNBUFS]; ++ uint32 crcr; ++ uint32 crc32tv[CNBUFS] = ++ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; ++ ++ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); ++ ++ /* step through all possible alignments */ ++ for (l=0;l<=4;l++) { ++ for (j=0; jlen; ++ elt = (bcm_tlv_t*)(elt->data + len); ++ *buflen -= (2 + len); ++ ++ /* validate next elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) ++ return NULL; ++ ++ return elt; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag ++ */ ++bcm_tlv_t * ++bcm_parse_tlvs(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ int len = elt->len; ++ ++ /* validate remaining totlen */ ++ if ((elt->id == key) && (totlen >= (len + 2))) ++ return (elt); ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag. Stop parsing when we see an element whose ID is greater ++ * than the target key. ++ */ ++bcm_tlv_t * ++bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ uint id = elt->id; ++ int len = elt->len; ++ ++ /* Punt if we start seeing IDs > than target key */ ++ if (id > key) ++ return(NULL); ++ ++ /* validate remaining totlen */ ++ if ((id == key) && (totlen >= (len + 2))) ++ return (elt); ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); ++ } ++ return NULL; ++} ++/* routine to dump fields in a fileddesc structure */ ++ ++uint ++bcmdumpfields(readreg_rtn read_rtn, void *arg0, void *arg1, struct fielddesc *fielddesc_array, char *buf, uint32 bufsize) ++{ ++ uint filled_len; ++ uint len; ++ struct fielddesc *cur_ptr; ++ ++ filled_len = 0; ++ cur_ptr = fielddesc_array; ++ ++ while (bufsize > (filled_len + 64)) { ++ if (cur_ptr->nameandfmt == NULL) ++ break; ++ len = sprintf(buf, cur_ptr->nameandfmt, read_rtn(arg0, arg1, cur_ptr->offset)); ++ buf += len; ++ filled_len += len; ++ cur_ptr++; ++ } ++ return filled_len; ++} ++ ++uint ++bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) ++{ ++ uint len; ++ ++ len = strlen(name) + 1; ++ ++ if ((len + datalen) > buflen) ++ return 0; ++ ++ strcpy(buf, name); ++ ++ /* append data onto the end of the name string */ ++ memcpy(&buf[len], data, datalen); ++ len += datalen; ++ ++ return len; ++} ++ ++/* Quarter dBm units to mW ++ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 ++ * Table is offset so the last entry is largest mW value that fits in ++ * a uint16. ++ */ ++ ++#define QDBM_OFFSET 153 ++#define QDBM_TABLE_LEN 40 ++ ++/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. ++ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 ++ */ ++#define QDBM_TABLE_LOW_BOUND 6493 ++ ++/* Largest mW value that will round down to the last table entry, ++ * QDBM_OFFSET + QDBM_TABLE_LEN-1. ++ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. ++ */ ++#define QDBM_TABLE_HIGH_BOUND 64938 ++ ++static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { ++/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ ++/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, ++/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, ++/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, ++/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, ++/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 ++}; ++ ++uint16 ++bcm_qdbm_to_mw(uint8 qdbm) ++{ ++ uint factor = 1; ++ int idx = qdbm - QDBM_OFFSET; ++ ++ if (idx > QDBM_TABLE_LEN) { ++ /* clamp to max uint16 mW value */ ++ return 0xFFFF; ++ } ++ ++ /* scale the qdBm index up to the range of the table 0-40 ++ * where an offset of 40 qdBm equals a factor of 10 mW. ++ */ ++ while (idx < 0) { ++ idx += 40; ++ factor *= 10; ++ } ++ ++ /* return the mW value scaled down to the correct factor of 10, ++ * adding in factor/2 to get proper rounding. */ ++ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); ++} ++ ++uint8 ++bcm_mw_to_qdbm(uint16 mw) ++{ ++ uint8 qdbm; ++ int offset; ++ uint mw_uint = mw; ++ uint boundary; ++ ++ /* handle boundary case */ ++ if (mw_uint <= 1) ++ return 0; ++ ++ offset = QDBM_OFFSET; ++ ++ /* move mw into the range of the table */ ++ while (mw_uint < QDBM_TABLE_LOW_BOUND) { ++ mw_uint *= 10; ++ offset -= 40; ++ } ++ ++ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { ++ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - nqdBm_to_mW_map[qdbm])/2; ++ if (mw_uint < boundary) break; ++ } ++ ++ qdbm += (uint8)offset; ++ ++ return(qdbm); ++} +diff -Nur linux-2.4.32/drivers/net/hnd/hnddma.c linux-2.4.32-brcm/drivers/net/hnd/hnddma.c +--- linux-2.4.32/drivers/net/hnd/hnddma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/hnddma.c 2005-12-16 23:39:11.288858250 +0100 +@@ -0,0 +1,1527 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA module. ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct dma_info; /* forward declaration */ ++#define di_t struct dma_info ++ ++#include ++#include ++ ++/* debug/trace */ ++#define DMA_ERROR(args) ++#define DMA_TRACE(args) ++ ++/* default dma message level (if input msg_level pointer is null in dma_attach()) */ ++static uint dma_msg_level = ++ 0; ++ ++#define MAXNAMEL 8 ++ ++/* dma engine software state */ ++typedef struct dma_info { ++ hnddma_t hnddma; /* exported structure */ ++ uint *msg_level; /* message level pointer */ ++ char name[MAXNAMEL]; /* callers name for diag msgs */ ++ ++ void *osh; /* os handle */ ++ sb_t *sbh; /* sb handle */ ++ ++ bool dma64; /* dma64 enabled */ ++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ ++ ++ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ ++ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ ++ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ ++ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ ++ ++ uint32 dma64align; /* either 8k or 4k depends on number of dd */ ++ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ ++ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ ++ uint ntxd; /* # tx descriptors tunable */ ++ uint txin; /* index of next descriptor to reclaim */ ++ uint txout; /* index of next descriptor to post */ ++ uint txavail; /* # free tx descriptors */ ++ void **txp; /* pointer to parallel array of pointers to packets */ ++ ulong txdpa; /* physical address of descriptor ring */ ++ uint txdalign; /* #bytes added to alloc'd mem to align txd */ ++ uint txdalloc; /* #bytes allocated for the ring */ ++ ++ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ ++ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ ++ uint nrxd; /* # rx descriptors tunable */ ++ uint rxin; /* index of next descriptor to reclaim */ ++ uint rxout; /* index of next descriptor to post */ ++ void **rxp; /* pointer to parallel array of pointers to packets */ ++ ulong rxdpa; /* physical address of descriptor ring */ ++ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ ++ uint rxdalloc; /* #bytes allocated for the ring */ ++ ++ /* tunables */ ++ uint rxbufsize; /* rx buffer size in bytes */ ++ uint nrxpost; /* # rx buffers to keep posted */ ++ uint rxoffset; /* rxcontrol offset */ ++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ ++ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */ ++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ ++ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */ ++} dma_info_t; ++ ++#ifdef BCMDMA64 ++#define DMA64_ENAB(di) ((di)->dma64) ++#else ++#define DMA64_ENAB(di) (0) ++#endif ++ ++/* descriptor bumping macros */ ++#define XXD(x, n) ((x) & ((n) - 1)) ++#define TXD(x) XXD((x), di->ntxd) ++#define RXD(x) XXD((x), di->nrxd) ++#define NEXTTXD(i) TXD(i + 1) ++#define PREVTXD(i) TXD(i - 1) ++#define NEXTRXD(i) RXD(i + 1) ++#define NTXDACTIVE(h, t) TXD(t - h) ++#define NRXDACTIVE(h, t) RXD(t - h) ++ ++/* macros to convert between byte offsets and indexes */ ++#define B2I(bytes, type) ((bytes) / sizeof(type)) ++#define I2B(index, type) ((index) * sizeof(type)) ++ ++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ ++#define PCI32ADDR_HIGH_SHIFT 30 ++ ++ ++/* prototypes */ ++static bool dma_isaddrext(dma_info_t *di); ++static bool dma_alloc(dma_info_t *di, uint direction); ++ ++static bool dma32_alloc(dma_info_t *di, uint direction); ++static void dma32_txreset(dma_info_t *di); ++static void dma32_rxreset(dma_info_t *di); ++static bool dma32_txsuspendedidle(dma_info_t *di); ++static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma32_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma32_getnextrxp(dma_info_t *di, bool forceall); ++static void dma32_txrotate(di_t *di); ++ ++/* prototype or stubs */ ++#ifdef BCMDMA64 ++static bool dma64_alloc(dma_info_t *di, uint direction); ++static void dma64_txreset(dma_info_t *di); ++static void dma64_rxreset(dma_info_t *di); ++static bool dma64_txsuspendedidle(dma_info_t *di); ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall); ++static void dma64_txrotate(di_t *di); ++#else ++static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; } ++static void dma64_txreset(dma_info_t *di) {} ++static void dma64_rxreset(dma_info_t *di) {} ++static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;} ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; } ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } ++static void dma64_txrotate(di_t *di) { return; } ++#endif ++ ++/* old dmaregs struct for compatibility */ ++typedef volatile struct { ++ /* transmit channel */ ++ uint32 xmtcontrol; /* enable, et al */ ++ uint32 xmtaddr; /* descriptor ring base address (4K aligned) */ ++ uint32 xmtptr; /* last descriptor posted to chip */ ++ uint32 xmtstatus; /* current active descriptor, et al */ ++ ++ /* receive channel */ ++ uint32 rcvcontrol; /* enable, et al */ ++ uint32 rcvaddr; /* descriptor ring base address (4K aligned) */ ++ uint32 rcvptr; /* last descriptor posted to chip */ ++ uint32 rcvstatus; /* current active descriptor, et al */ ++} dmaregs_t; ++ ++typedef struct { ++ uint ddoffset; ++ uint dataoffset; ++} compat_data; ++ ++static compat_data *ugly_hack = NULL; ++ ++void* ++dma_attold(void *drv, void *osh, char *name, dmaregs_t *regs, uint ntxd, uint nrxd, ++ uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level) ++{ ++ dma32regs_t *dtx = regs; ++ dma32regs_t *drx = dtx + 1; ++ ++ ugly_hack = kmalloc(sizeof(ugly_hack), GFP_KERNEL); ++ ugly_hack->ddoffset = ddoffset; ++ ugly_hack->dataoffset = dataoffset; ++ dma_attach((osl_t *) osh, name, NULL, dtx, drx, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, msg_level); ++ ugly_hack = NULL; ++} ++ ++ ++void* ++dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) ++{ ++ dma_info_t *di; ++ uint size; ++ ++ /* allocate private info structure */ ++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { ++ return (NULL); ++ } ++ bzero((char*)di, sizeof (dma_info_t)); ++ ++ di->msg_level = msg_level ? msg_level : &dma_msg_level; ++ ++ if (sbh != NULL) ++ di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64); ++ ++#ifndef BCMDMA64 ++ if (di->dma64) { ++ DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n")); ++ goto fail; ++ } ++#endif ++ ++ /* check arguments */ ++ ASSERT(ISPOWEROF2(ntxd)); ++ ASSERT(ISPOWEROF2(nrxd)); ++ if (nrxd == 0) ++ ASSERT(dmaregsrx == NULL); ++ if (ntxd == 0) ++ ASSERT(dmaregstx == NULL); ++ ++ ++ /* init dma reg pointer */ ++ if (di->dma64) { ++ ASSERT(ntxd <= D64MAXDD); ++ ASSERT(nrxd <= D64MAXDD); ++ di->d64txregs = (dma64regs_t *)dmaregstx; ++ di->d64rxregs = (dma64regs_t *)dmaregsrx; ++ ++ di->dma64align = D64RINGALIGN; ++ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { ++ /* for smaller dd table, HW relax the alignment requirement */ ++ di->dma64align = D64RINGALIGN / 2; ++ } ++ } else { ++ ASSERT(ntxd <= D32MAXDD); ++ ASSERT(nrxd <= D32MAXDD); ++ di->d32txregs = (dma32regs_t *)dmaregstx; ++ di->d32rxregs = (dma32regs_t *)dmaregsrx; ++ } ++ ++ ++ /* make a private copy of our callers name */ ++ strncpy(di->name, name, MAXNAMEL); ++ di->name[MAXNAMEL-1] = '\0'; ++ ++ di->osh = osh; ++ di->sbh = sbh; ++ ++ /* save tunables */ ++ di->ntxd = ntxd; ++ di->nrxd = nrxd; ++ di->rxbufsize = rxbufsize; ++ di->nrxpost = nrxpost; ++ di->rxoffset = rxoffset; ++ ++ /* ++ * figure out the DMA physical address offset for dd and data ++ * for old chips w/o sb, use zero ++ * for new chips w sb, ++ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset ++ * Other bus: use zero ++ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor ++ */ ++ di->ddoffsetlow = 0; ++ di->dataoffsetlow = 0; ++ if (ugly_hack != NULL) { ++ di->ddoffsetlow = ugly_hack->ddoffset; ++ di->dataoffsetlow = ugly_hack->dataoffset; ++ di->ddoffsethigh = 0; ++ di->dataoffsethigh = 0; ++ } else if (sbh != NULL) { ++ if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */ ++ if ((sbh->buscoretype == SB_PCIE) && di->dma64){ ++ di->ddoffsetlow = 0; ++ di->ddoffsethigh = SB_PCIE_DMA_H32; ++ } else { ++ di->ddoffsetlow = SB_PCI_DMA; ++ di->ddoffsethigh = 0; ++ } ++ di->dataoffsetlow = di->ddoffsetlow; ++ di->dataoffsethigh = di->ddoffsethigh; ++ } ++#if defined(__mips__) && defined(IL_BIGENDIAN) ++ /* use sdram swapped region for data buffers but not dma descriptors */ ++ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; ++#endif ++ } ++ ++ di->addrext = ((ugly_hack == NULL) ? dma_isaddrext(di) : 0); ++ ++ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", ++ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow)); ++ ++ /* allocate tx packet pointer vector */ ++ if (ntxd) { ++ size = ntxd * sizeof (void*); ++ if ((di->txp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char*)di->txp, size); ++ } ++ ++ /* allocate rx packet pointer vector */ ++ if (nrxd) { ++ size = nrxd * sizeof (void*); ++ if ((di->rxp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char*)di->rxp, size); ++ } ++ ++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ ++ if (ntxd) { ++ if (!dma_alloc(di, DMA_TX)) ++ goto fail; ++ } ++ ++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ ++ if (nrxd) { ++ if (!dma_alloc(di, DMA_RX)) ++ goto fail; ++ } ++ ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa)); ++ goto fail; ++ } ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa)); ++ goto fail; ++ } ++ ++ return ((void*)di); ++ ++fail: ++ dma_detach((void*)di); ++ return (NULL); ++} ++ ++static bool ++dma_alloc(dma_info_t *di, uint direction) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_alloc(di, direction); ++ } else { ++ return dma32_alloc(di, direction); ++ } ++} ++ ++/* may be called with core in reset */ ++void ++dma_detach(dma_info_t *di) ++{ ++ if (di == NULL) ++ return; ++ ++ DMA_TRACE(("%s: dma_detach\n", di->name)); ++ ++ /* shouldn't be here if descriptors are unreclaimed */ ++ ASSERT(di->txin == di->txout); ++ ASSERT(di->rxin == di->rxout); ++ ++ /* free dma descriptor rings */ ++ if (di->txd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign)); ++ if (di->rxd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign)); ++ ++ /* free packet pointer vectors */ ++ if (di->txp) ++ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*))); ++ if (di->rxp) ++ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*))); ++ ++ /* free our private info structure */ ++ MFREE(di->osh, (void*)di, sizeof (dma_info_t)); ++} ++ ++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ ++static bool ++dma_isaddrext(dma_info_t *di) ++{ ++ uint32 w; ++ ++ if (DMA64_ENAB(di)) { ++ OR_REG(&di->d64txregs->control, D64_XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~D64_XC_AE); ++ return ((w & XC_AE) == D64_XC_AE); ++ } else { ++ OR_REG(&di->d32txregs->control, XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~XC_AE); ++ return ((w & XC_AE) == XC_AE); ++ } ++} ++ ++void ++dma_txreset(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txreset\n", di->name)); ++ ++ if (DMA64_ENAB(di)) ++ dma64_txreset(di); ++ else ++ dma32_txreset(di); ++} ++ ++void ++dma_rxreset(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxreset\n", di->name)); ++ ++ if (DMA64_ENAB(di)) ++ dma64_rxreset(di); ++ else ++ dma32_rxreset(di); ++} ++ ++/* initialize descriptor table base address */ ++static void ++dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) ++{ ++ if (DMA64_ENAB(di)) { ++ if (direction == DMA_TX) { ++ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); ++ } else { ++ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); ++ } ++ } else { ++ uint32 offset = di->ddoffsetlow; ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ if (direction == DMA_TX) ++ W_REG(&di->d32txregs->addr, (pa + offset)); ++ else ++ W_REG(&di->d32rxregs->addr, (pa + offset)); ++ } else { ++ /* dma32 address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ ++ if (direction == DMA_TX) { ++ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT)); ++ } else { ++ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT)); ++ } ++ } ++ } ++} ++ ++/* init the tx or rx descriptor */ ++static INLINE void ++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl) ++{ ++ uint offset = di->dataoffsetlow; ++ ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ } else { ++ /* address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ ++ *ctrl |= (ae << CTRL_AE_SHIFT); ++ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ } ++} ++ ++/* init the tx or rx descriptor */ ++static INLINE void ++dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount) ++{ ++ uint32 bufaddr_low = pa + di->dataoffsetlow; ++ uint32 bufaddr_high = 0 + di->dataoffsethigh; ++ ++ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; ++ ++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low)); ++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high)); ++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); ++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); ++} ++ ++void ++dma_txinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txinit\n", di->name)); ++ ++ di->txin = di->txout = 0; ++ di->txavail = di->ntxd - 1; ++ ++ /* clear tx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t))); ++ W_REG(&di->d64txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } else { ++ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t))); ++ W_REG(&di->d32txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } ++} ++ ++bool ++dma_txenabled(dma_info_t *di) ++{ ++ uint32 xc; ++ ++ /* If the chip is dead, it is not enabled :-) */ ++ if (DMA64_ENAB(di)) { ++ xc = R_REG(&di->d64txregs->control); ++ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); ++ } else { ++ xc = R_REG(&di->d32txregs->control); ++ return ((xc != 0xffffffff) && (xc & XC_XE)); ++ } ++} ++ ++void ++dma_txsuspend(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_SE); ++ else ++ OR_REG(&di->d32txregs->control, XC_SE); ++} ++ ++void ++dma_txresume(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txresume\n", di->name)); ++ if (DMA64_ENAB(di)) ++ AND_REG(&di->d64txregs->control, ~D64_XC_SE); ++ else ++ AND_REG(&di->d32txregs->control, ~XC_SE); ++} ++ ++bool ++dma_txsuspendedidle(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return dma64_txsuspendedidle(di); ++ else ++ return dma32_txsuspendedidle(di); ++} ++ ++bool ++dma_txsuspended(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); ++ else ++ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE); ++} ++ ++bool ++dma_txstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); ++ else ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); ++} ++ ++bool ++dma_rxstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); ++ else ++ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); ++} ++ ++void ++dma_fifoloopbackenable(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_LE); ++ else ++ OR_REG(&di->d32txregs->control, XC_LE); ++} ++ ++void ++dma_rxinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxinit\n", di->name)); ++ ++ di->rxin = di->rxout = 0; ++ ++ /* clear rx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } else { ++ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } ++} ++ ++void ++dma_rxenable(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); ++ else ++ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); ++} ++ ++bool ++dma_rxenabled(dma_info_t *di) ++{ ++ uint32 rc; ++ ++ if (DMA64_ENAB(di)) { ++ rc = R_REG(&di->d64rxregs->control); ++ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); ++ } else { ++ rc = R_REG(&di->d32rxregs->control); ++ return ((rc != 0xffffffff) && (rc & RC_RE)); ++ } ++} ++ ++ ++/* !! tx entry routine */ ++int ++dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_txfast(di, p0, coreflags); ++ } else { ++ return dma32_txfast(di, p0, coreflags); ++ } ++} ++ ++/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */ ++void* ++dma_rx(dma_info_t *di) ++{ ++ void *p; ++ uint len; ++ int skiplen = 0; ++ ++ while ((p = dma_getnextrxp(di, FALSE))) { ++ /* skip giant packets which span multiple rx descriptors */ ++ if (skiplen > 0) { ++ skiplen -= di->rxbufsize; ++ if (skiplen < 0) ++ skiplen = 0; ++ PKTFREE(di->osh, p, FALSE); ++ continue; ++ } ++ ++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); ++ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); ++ ++ /* bad frame length check */ ++ if (len > (di->rxbufsize - di->rxoffset)) { ++ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); ++ if (len > 0) ++ skiplen = len - (di->rxbufsize - di->rxoffset); ++ PKTFREE(di->osh, p, FALSE); ++ di->hnddma.rxgiants++; ++ continue; ++ } ++ ++ /* set actual length */ ++ PKTSETLEN(di->osh, p, (di->rxoffset + len)); ++ ++ break; ++ } ++ ++ return (p); ++} ++ ++/* post receive buffers */ ++void ++dma_rxfill(dma_info_t *di) ++{ ++ void *p; ++ uint rxin, rxout; ++ uint32 ctrl; ++ uint n; ++ uint i; ++ uint32 pa; ++ uint rxbufsize; ++ ++ /* ++ * Determine how many receive buffers we're lacking ++ * from the full complement, allocate, initialize, ++ * and post them, then update the chip rx lastdscr. ++ */ ++ ++ rxin = di->rxin; ++ rxout = di->rxout; ++ rxbufsize = di->rxbufsize; ++ ++ n = di->nrxpost - NRXDACTIVE(rxin, rxout); ++ ++ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); ++ ++ for (i = 0; i < n; i++) { ++ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { ++ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); ++ di->hnddma.rxnobuf++; ++ break; ++ } ++ ++ /* Do a cached write instead of uncached write since DMA_MAP ++ * will flush the cache. */ ++ *(uint32*)(PKTDATA(di->osh, p)) = 0; ++ ++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); ++ ASSERT(ISALIGNED(pa, 4)); ++ ++ /* save the free packet pointer */ ++ ASSERT(di->rxp[rxout] == NULL); ++ di->rxp[rxout] = p; ++ ++ if (DMA64_ENAB(di)) { ++ /* prep the descriptor control value */ ++ if (rxout == (di->nrxd - 1)) ++ ctrl = CTRL_EOT; ++ ++ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize); ++ } else { ++ /* prep the descriptor control value */ ++ ctrl = rxbufsize; ++ if (rxout == (di->nrxd - 1)) ++ ctrl |= CTRL_EOT; ++ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl); ++ } ++ ++ rxout = NEXTRXD(rxout); ++ } ++ ++ di->rxout = rxout; ++ ++ /* update the chip lastdscr pointer */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++ } ++} ++ ++void ++dma_txreclaim(dma_info_t *di, bool forceall) ++{ ++ void *p; ++ ++ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); ++ ++ while ((p = dma_getnexttxp(di, forceall))) ++ PKTFREE(di->osh, p, TRUE); ++} ++ ++/* ++ * Reclaim next completed txd (txds if using chained buffers) and ++ * return associated packet. ++ * If 'force' is true, reclaim txd(s) and return associated packet ++ * regardless of the value of the hardware "curr" pointer. ++ */ ++void* ++dma_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnexttxp(di, forceall); ++ } else { ++ return dma32_getnexttxp(di, forceall); ++ } ++} ++ ++/* like getnexttxp but no reclaim */ ++void* ++dma_peeknexttxp(dma_info_t *di) ++{ ++ uint end, i; ++ ++ if (DMA64_ENAB(di)) { ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ } else { ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ } ++ ++ for (i = di->txin; i != end; i = NEXTTXD(i)) ++ if (di->txp[i]) ++ return (di->txp[i]); ++ ++ return (NULL); ++} ++ ++/* ++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). ++ */ ++void ++dma_txrotate(di_t *di) ++{ ++ if (DMA64_ENAB(di)) { ++ dma64_txrotate(di); ++ } else { ++ dma32_txrotate(di); ++ } ++} ++ ++void ++dma_rxreclaim(dma_info_t *di) ++{ ++ void *p; ++ ++ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); ++ ++ while ((p = dma_getnextrxp(di, TRUE))) ++ PKTFREE(di->osh, p, FALSE); ++} ++ ++void * ++dma_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnextrxp(di, forceall); ++ } else { ++ return dma32_getnextrxp(di, forceall); ++ } ++} ++ ++uintptr ++dma_getvar(dma_info_t *di, char *name) ++{ ++ if (!strcmp(name, "&txavail")) ++ return ((uintptr) &di->txavail); ++ else { ++ ASSERT(0); ++ } ++ return (0); ++} ++ ++void ++dma_txblock(dma_info_t *di) ++{ ++ di->txavail = 0; ++} ++ ++void ++dma_txunblock(dma_info_t *di) ++{ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++} ++ ++uint ++dma_txactive(dma_info_t *di) ++{ ++ return (NTXDACTIVE(di->txin, di->txout)); ++} ++ ++void ++dma_rxpiomode(dma32regs_t *regs) ++{ ++ W_REG(®s->control, RC_FM); ++} ++ ++void ++dma_txpioloopback(dma32regs_t *regs) ++{ ++ OR_REG(®s->control, XC_LE); ++} ++ ++ ++ ++ ++/*** 32 bits DMA non-inline functions ***/ ++static bool ++dma32_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ void *va; ++ ++ ddlen = sizeof (dma32dd_t); ++ ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) ++ size += D32RINGALIGN; ++ ++ ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } ++ ++ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); ++ } ++ ++ return TRUE; ++} ++ ++static void ++dma32_txreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ /* suspend tx DMA first */ ++ W_REG(&di->d32txregs->control, XC_SE); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED && ++ status != XS_XS_IDLE && ++ status != XS_XS_STOPPED, ++ 10000); ++ ++ W_REG(&di->d32txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED, ++ 10000); ++ ++ if (status != XS_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); ++ } ++ ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); ++} ++ ++static void ++dma32_rxreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ W_REG(&di->d32rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED, ++ 10000); ++ ++ if (status != RS_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } ++} ++ ++static bool ++dma32_txsuspendedidle(dma_info_t *di) ++{ ++ if (!(R_REG(&di->d32txregs->control) & XC_SE)) ++ return 0; ++ ++ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) ++ return 0; ++ ++ OSL_DELAY(2); ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); ++} ++ ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 ctrl; ++ uint32 pa; ++ ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ ++ txout = di->txout; ++ ctrl = 0; ++ ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); ++ ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; ++ ++ if (len == 0) ++ continue; ++ ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ ++ /* build the descriptor control value */ ++ ctrl = len & CTRL_BC_MASK; ++ ++ ctrl |= coreflags; ++ ++ if (p == p0) ++ ctrl |= CTRL_SOF; ++ if (next == NULL) ++ ctrl |= (CTRL_IOC | CTRL_EOF); ++ if (txout == (di->ntxd - 1)) ++ ctrl |= CTRL_EOT; ++ ++ if (DMA64_ENAB(di)) { ++ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len); ++ } else { ++ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl); ++ } ++ ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); ++ } ++ ++ /* if last txd eof not set, fix it */ ++ if (!(ctrl & CTRL_EOF)) ++ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF)); ++ ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; ++ ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t)); ++ } ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++ outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); ++} ++ ++static void* ++dma32_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ uint start, end, i; ++ void *txp; ++ ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); ++ ++ W_SM(&di->txd32[i].addr, 0xdeadbeef); ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ } ++ ++ di->txin = i; ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (txp); ++ ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); ++} ++ ++static void * ++dma32_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ uint i; ++ void *rxp; ++ ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); ++ ++ i = di->rxin; ++ ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); ++ ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) ++ return (NULL); ++ ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; ++ ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); ++ W_SM(&di->rxd32[i].addr, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); ++} ++ ++static void ++dma32_txrotate(di_t *di) ++{ ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; ++ ++ ASSERT(dma_txsuspendedidle(di)); ++ ++ nactive = dma_txactive(di); ++ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); ++ rot = TXD(ad - di->txin); ++ ++ ASSERT(rot < di->ntxd); ++ ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } ++ ++ first = di->txin; ++ last = PREVTXD(di->txout); ++ ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); ++ ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= CTRL_EOT; ++ W_SM(&di->txd32[new].ctrl, w); ++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); ++ ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd32[old].addr, 0xdeadbeef); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; ++ } ++ ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); ++} ++ ++/*** 64 bits DMA non-inline functions ***/ ++ ++#ifdef BCMDMA64 ++ ++static bool ++dma64_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ uint32 alignbytes; ++ void *va; ++ ++ ddlen = sizeof (dma64dd_t); ++ ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ ++ alignbytes = di->dma64align; ++ ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes)) ++ size += alignbytes; ++ ++ ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } ++ ++ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes)); ++ } ++ ++ return TRUE; ++} ++ ++static void ++dma64_txreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ /* suspend tx DMA first */ ++ W_REG(&di->d64txregs->control, D64_XC_SE); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED && ++ status != D64_XS0_XS_IDLE && ++ status != D64_XS0_XS_STOPPED, ++ 10000); ++ ++ W_REG(&di->d64txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED, ++ 10000); ++ ++ if (status != D64_XS0_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); ++ } ++ ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); ++} ++ ++static void ++dma64_rxreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ W_REG(&di->d64rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED, ++ 10000); ++ ++ if (status != D64_RS0_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } ++} ++ ++static bool ++dma64_txsuspendedidle(dma_info_t *di) ++{ ++ ++ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) ++ return 0; ++ ++ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) ++ return 1; ++ ++ return 0; ++} ++ ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 flags; ++ uint32 pa; ++ ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ ++ txout = di->txout; ++ flags = 0; ++ ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); ++ ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; ++ ++ if (len == 0) ++ continue; ++ ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ ++ flags = coreflags; ++ ++ if (p == p0) ++ flags |= D64_CTRL1_SOF; ++ if (next == NULL) ++ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); ++ if (txout == (di->ntxd - 1)) ++ flags |= D64_CTRL1_EOT; ++ ++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); ++ ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); ++ } ++ ++ /* if last txd eof not set, fix it */ ++ if (!(flags & D64_CTRL1_EOF)) ++ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); ++ ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; ++ ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); ++} ++ ++static void* ++dma64_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ uint start, end, i; ++ void *txp; ++ ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]); ++ ++ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); ++ ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ } ++ ++ di->txin = i; ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (txp); ++ ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); ++} ++ ++static void * ++dma64_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ uint i; ++ void *rxp; ++ ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); ++ ++ i = di->rxin; ++ ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); ++ ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t))) ++ return (NULL); ++ ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; ++ ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); ++ ++ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); ++} ++ ++static void ++dma64_txrotate(di_t *di) ++{ ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; ++ ++ ASSERT(dma_txsuspendedidle(di)); ++ ++ nactive = dma_txactive(di); ++ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); ++ rot = TXD(ad - di->txin); ++ ++ ASSERT(rot < di->ntxd); ++ ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } ++ ++ first = di->txin; ++ last = PREVTXD(di->txout); ++ ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); ++ ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= D64_CTRL1_EOT; ++ W_SM(&di->txd64[new].ctrl1, w); ++ ++ w = R_SM(&di->txd64[old].ctrl2); ++ W_SM(&di->txd64[new].ctrl2, w); ++ ++ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); ++ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); ++ ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; ++ } ++ ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); ++} ++ ++#endif ++ +diff -Nur linux-2.4.32/drivers/net/hnd/linux_osl.c linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c +--- linux-2.4.32/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c 2005-12-16 23:39:11.292858500 +0100 +@@ -0,0 +1,708 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#define LINUX_OSL ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef mips ++#include ++#endif ++#include ++ ++#define PCI_CFG_RETRY 10 ++ ++#define OS_HANDLE_MAGIC 0x1234abcd ++#define BCM_MEM_FILENAME_LEN 24 ++ ++typedef struct bcm_mem_link { ++ struct bcm_mem_link *prev; ++ struct bcm_mem_link *next; ++ uint size; ++ int line; ++ char file[BCM_MEM_FILENAME_LEN]; ++} bcm_mem_link_t; ++ ++struct os_handle { ++ uint magic; ++ void *pdev; ++ uint malloced; ++ uint failed; ++ bcm_mem_link_t *dbgmem_list; ++}; ++ ++static int16 linuxbcmerrormap[] = \ ++{ 0, /* 0 */ ++ -EINVAL, /* BCME_ERROR */ ++ -EINVAL, /* BCME_BADARG*/ ++ -EINVAL, /* BCME_BADOPTION*/ ++ -EINVAL, /* BCME_NOTUP */ ++ -EINVAL, /* BCME_NOTDOWN */ ++ -EINVAL, /* BCME_NOTAP */ ++ -EINVAL, /* BCME_NOTSTA */ ++ -EINVAL, /* BCME_BADKEYIDX */ ++ -EINVAL, /* BCME_RADIOOFF */ ++ -EINVAL, /* BCME_NOTBANDLOCKED */ ++ -EINVAL, /* BCME_NOCLK */ ++ -EINVAL, /* BCME_BADRATESET */ ++ -EINVAL, /* BCME_BADBAND */ ++ -E2BIG, /* BCME_BUFTOOSHORT */ ++ -E2BIG, /* BCME_BUFTOOLONG */ ++ -EBUSY, /* BCME_BUSY */ ++ -EINVAL, /* BCME_NOTASSOCIATED */ ++ -EINVAL, /* BCME_BADSSIDLEN */ ++ -EINVAL, /* BCME_OUTOFRANGECHAN */ ++ -EINVAL, /* BCME_BADCHAN */ ++ -EFAULT, /* BCME_BADADDR */ ++ -ENOMEM, /* BCME_NORESOURCE */ ++ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ ++ -EMSGSIZE, /* BCME_BADLENGTH */ ++ -EINVAL, /* BCME_NOTREADY */ ++ -EPERM, /* BCME_NOTPERMITTED */ ++ -ENOMEM, /* BCME_NOMEM */ ++ -EINVAL, /* BCME_ASSOCIATED */ ++ -ERANGE, /* BCME_RANGE */ ++ -EINVAL /* BCME_NOTFOUND */ ++}; ++ ++/* translate bcmerrors into linux errors*/ ++int ++osl_error(int bcmerror) ++{ ++ int abs_bcmerror; ++ int array_size = ARRAYSIZE(linuxbcmerrormap); ++ ++ abs_bcmerror = ABS(bcmerror); ++ ++ if (bcmerror > 0) ++ abs_bcmerror = 0; ++ ++ else if (abs_bcmerror >= array_size) ++ abs_bcmerror = BCME_ERROR; ++ ++ return linuxbcmerrormap[abs_bcmerror]; ++} ++ ++osl_t * ++osl_attach(void *pdev) ++{ ++ osl_t *osh; ++ ++ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); ++ ASSERT(osh); ++ ++ /* ++ * check the cases where ++ * 1.Error code Added to bcmerror table, but forgot to add it to the OS ++ * dependent error code ++ * 2. Error code is added to the bcmerror table, but forgot to add the ++ * corresponding errorstring(dummy call to bcmerrorstr) ++ */ ++ bcmerrorstr(0); ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); ++ ++ osh->magic = OS_HANDLE_MAGIC; ++ osh->malloced = 0; ++ osh->failed = 0; ++ osh->dbgmem_list = NULL; ++ osh->pdev = pdev; ++ ++ return osh; ++} ++ ++void ++osl_detach(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC)); ++ kfree(osh); ++} ++ ++void* ++osl_pktget(osl_t *osh, uint len, bool send) ++{ ++ struct sk_buff *skb; ++ ++ if ((skb = dev_alloc_skb(len)) == NULL) ++ return (NULL); ++ ++ skb_put(skb, len); ++ ++ /* ensure the cookie field is cleared */ ++ PKTSETCOOKIE(skb, NULL); ++ ++ return ((void*) skb); ++} ++ ++void ++osl_pktfree(void *p) ++{ ++ struct sk_buff *skb, *nskb; ++ ++ skb = (struct sk_buff*) p; ++ ++ /* perversion: we use skb->next to chain multi-skb packets */ ++ while (skb) { ++ nskb = skb->next; ++ skb->next = NULL; ++ if (skb->destructor) { ++ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ ++ dev_kfree_skb_any(skb); ++ } else { ++ /* can free immediately (even in_irq()) if destructor does not exist */ ++ dev_kfree_skb(skb); ++ } ++ skb = nskb; ++ } ++} ++ ++uint32 ++osl_pci_read_config(osl_t *osh, uint offset, uint size) ++{ ++ uint val; ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_read_config_dword(osh->pdev, offset, &val); ++ if (val != 0xffffffff) ++ break; ++ } while (retry--); ++ ++ ++ return (val); ++} ++ ++void ++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++{ ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_write_config_dword(osh->pdev, offset, val); ++ if (offset!=PCI_BAR0_WIN) ++ break; ++ if (osl_pci_read_config(osh,offset,size) == val) ++ break; ++ } while (retry--); ++ ++} ++ ++/* return bus # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_bus(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return ((struct pci_dev *)osh->pdev)->bus->number; ++} ++ ++/* return slot # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_slot(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); ++} ++ ++static void ++osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) ++{ ++} ++ ++void ++osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); ++} ++ ++void ++osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); ++} ++ ++ ++#ifdef BCMDBG_MEM ++ ++void* ++osl_debug_malloc(osl_t *osh, uint size, int line, char* file) ++{ ++ bcm_mem_link_t *p; ++ char* basename; ++ ++ ASSERT(size); ++ ++ if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL) ++ return (NULL); ++ ++ p->size = size; ++ p->line = line; ++ ++ basename = strrchr(file, '/'); ++ /* skip the '/' */ ++ if (basename) ++ basename++; ++ ++ if (!basename) ++ basename = file; ++ ++ strncpy(p->file, basename, BCM_MEM_FILENAME_LEN); ++ p->file[BCM_MEM_FILENAME_LEN - 1] = '\0'; ++ ++ /* link this block */ ++ p->prev = NULL; ++ p->next = osh->dbgmem_list; ++ if (p->next) ++ p->next->prev = p; ++ osh->dbgmem_list = p; ++ ++ return p + 1; ++} ++ ++void ++osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file) ++{ ++ bcm_mem_link_t *p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t)); ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ if (p->size == 0) { ++ printk("osl_debug_mfree: double free on addr 0x%x size %d at line %d file %s\n", ++ (uint)addr, size, line, file); ++ ASSERT(p->size); ++ return; ++ } ++ ++ if (p->size != size) { ++ printk("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr 0x%x at line %d file %s\n", ++ size, p->size, (uint)addr, line, file); ++ ASSERT(p->size == size); ++ return; ++ } ++ ++ /* unlink this block */ ++ if (p->prev) ++ p->prev->next = p->next; ++ if (p->next) ++ p->next->prev = p->prev; ++ if (osh->dbgmem_list == p) ++ osh->dbgmem_list = p->next; ++ p->next = p->prev = NULL; ++ ++ osl_mfree(osh, p, size + sizeof(bcm_mem_link_t)); ++} ++ ++char* ++osl_debug_memdump(osl_t *osh, char *buf, uint sz) ++{ ++ bcm_mem_link_t *p; ++ char *obuf; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ obuf = buf; ++ ++ buf += sprintf(buf, " Address\tSize\tFile:line\n"); ++ for (p = osh->dbgmem_list; p && ((buf - obuf) < (sz - 128)); p = p->next) ++ buf += sprintf(buf, "0x%08x\t%5d\t%s:%d\n", ++ (int)p + sizeof(bcm_mem_link_t), p->size, p->file, p->line); ++ ++ return (obuf); ++} ++ ++#endif /* BCMDBG_MEM */ ++ ++void* ++osl_malloc(osl_t *osh, uint size) ++{ ++ void *addr; ++ ++ /* only ASSERT if osh is defined */ ++ if (osh) ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ ++ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { ++ if(osh) ++ osh->failed++; ++ return (NULL); ++ } ++ if (osh) ++ osh->malloced += size; ++ ++ return (addr); ++} ++ ++void ++osl_mfree(osl_t *osh, void *addr, uint size) ++{ ++ if (osh) { ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ osh->malloced -= size; ++ } ++ kfree(addr); ++} ++ ++uint ++osl_malloced(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->malloced); ++} ++ ++uint osl_malloc_failed(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->failed); ++} ++ ++void* ++osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); ++} ++ ++void ++osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); ++} ++ ++uint ++osl_dma_map(osl_t *osh, void *va, uint size, int direction) ++{ ++ int dir; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ return (pci_map_single(osh->pdev, va, size, dir)); ++} ++ ++void ++osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) ++{ ++ int dir; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ pci_unmap_single(osh->pdev, (uint32)pa, size, dir); ++} ++ ++#if defined(BINOSL) ++void ++osl_assert(char *exp, char *file, int line) ++{ ++ char tempbuf[255]; ++ ++ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); ++ panic(tempbuf); ++} ++#endif /* BCMDBG || BINOSL */ ++ ++void ++osl_delay(uint usec) ++{ ++ uint d; ++ ++ while (usec > 0) { ++ d = MIN(usec, 1000); ++ udelay(d); ++ usec -= d; ++ } ++} ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ */ ++#ifdef BINOSL ++ ++int ++osl_printf(const char *format, ...) ++{ ++ va_list args; ++ char buf[1024]; ++ int len; ++ ++ /* sprintf into a local buffer because there *is* no "vprintk()".. */ ++ va_start(args, format); ++ len = vsprintf(buf, format, args); ++ va_end(args); ++ ++ if (len > sizeof (buf)) { ++ printk("osl_printf: buffer overrun\n"); ++ return (0); ++ } ++ ++ return (printk(buf)); ++} ++ ++int ++osl_sprintf(char *buf, const char *format, ...) ++{ ++ va_list args; ++ int rc; ++ ++ va_start(args, format); ++ rc = vsprintf(buf, format, args); ++ va_end(args); ++ return (rc); ++} ++ ++int ++osl_strcmp(const char *s1, const char *s2) ++{ ++ return (strcmp(s1, s2)); ++} ++ ++int ++osl_strncmp(const char *s1, const char *s2, uint n) ++{ ++ return (strncmp(s1, s2, n)); ++} ++ ++int ++osl_strlen(const char *s) ++{ ++ return (strlen(s)); ++} ++ ++char* ++osl_strcpy(char *d, const char *s) ++{ ++ return (strcpy(d, s)); ++} ++ ++char* ++osl_strncpy(char *d, const char *s, uint n) ++{ ++ return (strncpy(d, s, n)); ++} ++ ++void ++bcopy(const void *src, void *dst, int len) ++{ ++ memcpy(dst, src, len); ++} ++ ++int ++bcmp(const void *b1, const void *b2, int len) ++{ ++ return (memcmp(b1, b2, len)); ++} ++ ++void ++bzero(void *b, int len) ++{ ++ memset(b, '\0', len); ++} ++ ++uint32 ++osl_readl(volatile uint32 *r) ++{ ++ return (readl(r)); ++} ++ ++uint16 ++osl_readw(volatile uint16 *r) ++{ ++ return (readw(r)); ++} ++ ++uint8 ++osl_readb(volatile uint8 *r) ++{ ++ return (readb(r)); ++} ++ ++void ++osl_writel(uint32 v, volatile uint32 *r) ++{ ++ writel(v, r); ++} ++ ++void ++osl_writew(uint16 v, volatile uint16 *r) ++{ ++ writew(v, r); ++} ++ ++void ++osl_writeb(uint8 v, volatile uint8 *r) ++{ ++ writeb(v, r); ++} ++ ++void * ++osl_uncached(void *va) ++{ ++#ifdef mips ++ return ((void*)KSEG1ADDR(va)); ++#else ++ return ((void*)va); ++#endif ++} ++ ++uint ++osl_getcycles(void) ++{ ++ uint cycles; ++ ++#if defined(mips) ++ cycles = read_c0_count() * 2; ++#elif defined(__i386__) ++ rdtscl(cycles); ++#else ++ cycles = 0; ++#endif ++ return cycles; ++} ++ ++void * ++osl_reg_map(uint32 pa, uint size) ++{ ++ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); ++} ++ ++void ++osl_reg_unmap(void *va) ++{ ++ iounmap(va); ++} ++ ++int ++osl_busprobe(uint32 *val, uint32 addr) ++{ ++#ifdef mips ++ return get_dbe(*val, (uint32*)addr); ++#else ++ *val = readl(addr); ++ return 0; ++#endif ++} ++ ++uchar* ++osl_pktdata(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->data); ++} ++ ++uint ++osl_pktlen(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->len); ++} ++ ++uint ++osl_pktheadroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_headroom((struct sk_buff *) skb); ++} ++ ++uint ++osl_pkttailroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_tailroom((struct sk_buff *) skb); ++} ++ ++void* ++osl_pktnext(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->next); ++} ++ ++void ++osl_pktsetnext(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; ++} ++ ++void ++osl_pktsetlen(osl_t *osh, void *skb, uint len) ++{ ++ __skb_trim((struct sk_buff*)skb, len); ++} ++ ++uchar* ++osl_pktpush(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_push((struct sk_buff*)skb, bytes)); ++} ++ ++uchar* ++osl_pktpull(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_pull((struct sk_buff*)skb, bytes)); ++} ++ ++void* ++osl_pktdup(osl_t *osh, void *skb) ++{ ++ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); ++} ++ ++void* ++osl_pktcookie(void *skb) ++{ ++ return ((void*)((struct sk_buff*)skb)->csum); ++} ++ ++void ++osl_pktsetcookie(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->csum = (uint)x; ++} ++ ++void* ++osl_pktlink(void *skb) ++{ ++ return (((struct sk_buff*)skb)->prev); ++} ++ ++void ++osl_pktsetlink(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; ++} ++ ++uint ++osl_pktprio(void *skb) ++{ ++ return (((struct sk_buff*)skb)->priority); ++} ++ ++void ++osl_pktsetprio(void *skb, uint x) ++{ ++ ((struct sk_buff*)skb)->priority = x; ++} ++ ++ ++#endif /* BINOSL */ +diff -Nur linux-2.4.32/drivers/net/hnd/Makefile linux-2.4.32-brcm/drivers/net/hnd/Makefile +--- linux-2.4.32/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/Makefile 2005-12-16 23:39:11.284858000 +0100 +@@ -0,0 +1,19 @@ ++# ++# Makefile for the BCM47xx specific kernel interface routines ++# under Linux. ++# ++ ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ ++O_TARGET := hnd.o ++ ++HND_OBJS := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o ++ ++export-objs := shared_ksyms.o ++obj-y := shared_ksyms.o $(HND_OBJS) ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make ++ ++shared_ksyms.c: shared_ksyms.sh $(HND_OBJS) ++ sh -e $< $(HND_OBJS) > $@ +diff -Nur linux-2.4.32/drivers/net/hnd/sbutils.c linux-2.4.32-brcm/drivers/net/hnd/sbutils.c +--- linux-2.4.32/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/sbutils.c 2005-12-16 23:39:11.316860000 +0100 +@@ -0,0 +1,2837 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* debug/trace */ ++#define SB_ERROR(args) ++ ++ ++typedef uint32 (*sb_intrsoff_t)(void *intr_arg); ++typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); ++typedef bool (*sb_intrsenabled_t)(void *intr_arg); ++ ++/* misc sb info needed by some of the routines */ ++typedef struct sb_info { ++ ++ struct sb_pub sb; /* back plane public state(must be first field of sb_info */ ++ ++ void *osh; /* osl os handle */ ++ void *sdh; /* bcmsdh handle */ ++ ++ void *curmap; /* current regs va */ ++ void *regs[SB_MAXCORES]; /* other regs va */ ++ ++ uint curidx; /* current core index */ ++ uint dev_coreid; /* the core provides driver functions */ ++ ++ bool memseg; /* flag to toggle MEM_SEG register */ ++ ++ uint gpioidx; /* gpio control core index */ ++ uint gpioid; /* gpio control coretype */ ++ ++ uint numcores; /* # discovered cores */ ++ uint coreid[SB_MAXCORES]; /* id of each core */ ++ ++ void *intr_arg; /* interrupt callback function arg */ ++ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ ++ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ ++ sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */ ++ ++} sb_info_t; ++ ++/* local prototypes */ ++static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz); ++static void BCMINIT(sb_scan)(sb_info_t *si); ++static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val); ++static uint _sb_coreidx(sb_info_t *si); ++static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit); ++static uint BCMINIT(sb_pcidev2chip)(uint pcidev); ++static uint BCMINIT(sb_chip2numcores)(uint chip); ++static bool sb_ispcie(sb_info_t *si); ++static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen); ++static int sb_pci_fixcfg(sb_info_t *si); ++ ++/* routines to access mdio slave device registers */ ++static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val); ++static void BCMINIT(sb_war30841)(sb_info_t *si); ++ ++/* delay needed between the mdio control/ mdiodata register data access */ ++#define PR28829_DELAY() OSL_DELAY(10) ++ ++ ++/* global variable to indicate reservation/release of gpio's*/ ++static uint32 sb_gpioreservation = 0; ++ ++#define SB_INFO(sbh) (sb_info_t*)sbh ++#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) ++#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE)) ++#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE)) ++#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) ++#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) ++#define BADIDX (SB_MAXCORES+1) ++#define NOREV -1 ++ ++#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) ++#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE)) ++ ++/* sonicsrev */ ++#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) ++#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) ++ ++#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) ++#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) ++#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) ++#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) ++ ++/* ++ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ ++ * after core switching to avoid invalid register accesss inside ISR. ++ */ ++#define INTR_OFF(si, intr_val) \ ++ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } ++#define INTR_RESTORE(si, intr_val) \ ++ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } ++ ++/* dynamic clock control defines */ ++#define LPOMINFREQ 25000 /* low power oscillator min */ ++#define LPOMAXFREQ 43000 /* low power oscillator max */ ++#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ ++#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ ++#define PCIMINFREQ 25000000 /* 25 MHz */ ++#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ ++ ++#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ ++#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ ++ ++#define MIN_DUMPBUFLEN 32 /* debug */ ++ ++/* different register spaces to access thr'u pcie indirect access*/ ++#define PCIE_CONFIGREGS 1 ++#define PCIE_PCIEREGS 2 ++ ++/* GPIO Based LED powersave defines */ ++#define DEFAULT_GPIO_ONTIME 10 ++#define DEFAULT_GPIO_OFFTIME 90 ++ ++#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) ++ ++static uint32 ++sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) ++{ ++ uint8 tmp; ++ uint32 val, intr_val = 0; ++ ++ ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if(si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ ++ } ++ ++ val = R_REG(sbr); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++ ++ return (val); ++} ++ ++static void ++sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) ++{ ++ uint8 tmp; ++ volatile uint32 dummy; ++ uint32 intr_val = 0; ++ ++ ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if(si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ ++ } ++ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++#ifdef IL_BIGENDIAN ++ dummy = R_REG(sbr); ++ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++#else ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++#endif ++ } else ++ W_REG(sbr, v); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++} ++ ++/* ++ * Allocate a sb handle. ++ * devid - pci device id (used to determine chip#) ++ * osh - opaque OS handle ++ * regs - virtual address of initial core registers ++ * bustype - pci/pcmcia/sb/sdio/etc ++ * vars - pointer to a pointer area for "environment" variables ++ * varsz - pointer to int to return the size of the vars ++ */ ++sb_t * ++BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ sb_info_t *si; ++ ++ /* alloc sb_info_t */ ++ if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) { ++ SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); ++ return (NULL); ++ } ++ ++ if (BCMINIT(sb_doattach)(si, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { ++ MFREE(osh, si, sizeof (sb_info_t)); ++ return (NULL); ++ } ++ return (sb_t *)si; ++} ++ ++/* Using sb_kattach depends on SB_BUS support, either implicit */ ++/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */ ++#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) ++ ++/* global kernel resource */ ++static sb_info_t ksi; ++ ++/* generic kernel variant of sb_attach() */ ++sb_t * ++BCMINITFN(sb_kattach)() ++{ ++ uint32 *regs; ++ ++ if (ksi.curmap == NULL) { ++ uint32 cid; ++ ++ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); ++ cid = R_REG((uint32 *)regs); ++ if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) && ++ ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) && ++ ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) { ++ uint32 *scc, val; ++ ++ scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); ++ val = R_REG(scc); ++ SB_ERROR((" initial scc = 0x%x\n", val)); ++ val |= SCC_SS_XTAL; ++ W_REG(scc, val); ++ } ++ ++ if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, ++ SB_BUS, NULL, NULL, NULL) == NULL) { ++ return NULL; ++ } ++ } ++ ++ return (sb_t *)&ksi; ++} ++#endif ++ ++static sb_info_t * ++BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ uint origidx; ++ chipcregs_t *cc; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ ASSERT(GOODREGS(regs)); ++ ++ bzero((uchar*)si, sizeof (sb_info_t)); ++ ++ si->sb.buscoreidx = si->gpioidx = BADIDX; ++ ++ si->osh = osh; ++ si->curmap = regs; ++ si->sdh = sdh; ++ ++ /* check to see if we are a sb core mimic'ing a pci core */ ++ if (bustype == PCI_BUS) { ++ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) ++ bustype = SB_BUS; ++ else ++ bustype = PCI_BUS; ++ } ++ ++ si->sb.bustype = bustype; ++ if (si->sb.bustype != BUSTYPE(si->sb.bustype)) { ++ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", ++ si->sb.bustype, BUSTYPE(si->sb.bustype))); ++ return NULL; ++ } ++ ++ /* need to set memseg flag for CF card first before any sb registers access */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) ++ si->memseg = TRUE; ++ ++ /* kludge to enable the clock on the 4306 which lacks a slowclock */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) ++ sb_clkctl_xtal(&si->sb, XTAL|PLL, ON); ++ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32)); ++ if (!GOODCOREADDR(w)) ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE); ++ } ++ ++ /* initialize current core index value */ ++ si->curidx = _sb_coreidx(si); ++ ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_doattach: bad core index\n")); ++ return NULL; ++ } ++ ++ /* get sonics backplane revision */ ++ sb = REGS2SB(si->curmap); ++ si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; ++ ++ /* keep and reuse the initial register mapping */ ++ origidx = si->curidx; ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ si->regs[origidx] = regs; ++ ++ /* is core-0 a chipcommon core? */ ++ si->numcores = 1; ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0); ++ if (sb_coreid(&si->sb) != SB_CC) ++ cc = NULL; ++ ++ /* determine chip id and rev */ ++ if (cc) { ++ /* chip common core found! */ ++ si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK; ++ si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; ++ si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ } else { ++ /* The only pcmcia chip without a chipcommon core is a 4301 */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) ++ devid = BCM4301_DEVICE_ID; ++ ++ /* no chip common core -- must convert device id to chip id */ ++ if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) { ++ SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid)); ++ sb_setcoreidx(&si->sb, origidx); ++ return NULL; ++ } ++ } ++ ++ /* get chipcommon rev */ ++ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; ++ ++ /* determine numcores */ ++ if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6))) ++ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; ++ else ++ si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip); ++ ++ /* return to original core */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* sanity checks */ ++ ASSERT(si->sb.chip); ++ ++ /* scan for cores */ ++ BCMINIT(sb_scan)(si); ++ ++ /* fixup necessary chip/core configurations */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ if (sb_pci_fixcfg(si)) { ++ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n")); ++ return NULL; ++ } ++ } ++ ++ /* srom_var_init() depends on sb_scan() info */ ++ if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) { ++ SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n")); ++ return (NULL); ++ } ++ ++ if (cc == NULL) { ++ /* ++ * The chip revision number is hardwired into all ++ * of the pci function config rev fields and is ++ * independent from the individual core revision numbers. ++ * For example, the "A0" silicon of each chip is chip rev 0. ++ * For PCMCIA we get it from the CIS instead. ++ */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ ASSERT(vars); ++ si->sb.chiprev = getintvar(*vars, "chiprev"); ++ } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); ++ si->sb.chiprev = w & 0xff; ++ } else ++ si->sb.chiprev = 0; ++ } ++ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ w = getintvar(*vars, "regwindowsz"); ++ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; ++ } ++ ++ /* gpio control core is required */ ++ if (!GOODIDX(si->gpioidx)) { ++ SB_ERROR(("sb_doattach: gpio control core not found\n")); ++ return NULL; ++ } ++ ++ /* get boardtype and boardrev */ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ /* do a pci config read to get subsystem id and subvendor id */ ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); ++ si->sb.boardvendor = w & 0xffff; ++ si->sb.boardtype = (w >> 16) & 0xffff; ++ break; ++ ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ si->sb.boardvendor = getintvar(*vars, "manfid"); ++ si->sb.boardtype = getintvar(*vars, "prodid"); ++ break; ++ ++ case SB_BUS: ++ case JTAG_BUS: ++ si->sb.boardvendor = VENDOR_BROADCOM; ++ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) ++ si->sb.boardtype = 0xffff; ++ break; ++ } ++ ++ if (si->sb.boardtype == 0) { ++ SB_ERROR(("sb_doattach: unknown board type\n")); ++ ASSERT(si->sb.boardtype); ++ } ++ ++ /* setup the GPIO based LED powersave register */ ++ if (si->sb.ccrev >= 16) { ++ w = getintvar(*vars, "gpiotimerval"); ++ if (!w) ++ w = DEFAULT_GPIOTIMERVAL; ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); ++ } ++ ++ ++ return (si); ++} ++ ++uint ++sb_coreid(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++} ++ ++uint ++sb_coreidx(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->curidx); ++} ++ ++/* return current index of core */ ++static uint ++_sb_coreidx(sb_info_t *si) ++{ ++ sbconfig_t *sb; ++ uint32 sbaddr = 0; ++ ++ ASSERT(si); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ sb = REGS2SB(si->curmap); ++ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); ++ break; ++ ++ case PCI_BUS: ++ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); ++ break; ++ ++ case PCMCIA_BUS: { ++ uint8 tmp = 0; ++ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ sbaddr = (uint)tmp << 12; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ sbaddr |= (uint)tmp << 16; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ sbaddr |= (uint)tmp << 24; ++ break; ++ } ++ ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ sbaddr = (uint32)si->curmap; ++ break; ++#endif /* BCMJTAG */ ++ ++ default: ++ ASSERT(0); ++ } ++ ++ if (!GOODCOREADDR(sbaddr)) ++ return BADIDX; ++ ++ return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); ++} ++ ++uint ++sb_corevendor(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); ++} ++ ++uint ++sb_corerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint sbidh; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ sbidh = R_SBREG(si, &(sb)->sbidhigh); ++ ++ return (SBCOREREV(sbidh)); ++} ++ ++void * ++sb_osh(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return si->osh; ++} ++ ++#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) ++ ++/* set/clear sbtmstatelow core-specific flags */ ++uint32 ++sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTML_ALLOW) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatelow, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW); ++} ++ ++/* set/clear sbtmstatehigh core-specific flags */ ++uint32 ++sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTMH_FL_MASK) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatehigh, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK); ++} ++ ++/* caller needs to take care of core-specific bist hazards */ ++int ++sb_corebist(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ uint32 sblo; ++ uint coreidx; ++ sb_info_t *si; ++ int result = 0; ++ ++ si = SB_INFO(sbh); ++ ++ coreidx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(coreidx)) ++ result = BCME_ERROR; ++ else { ++ sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0); ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE)); ++ ++ SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000); ++ ++ if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF) ++ result = BCME_ERROR; ++ ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo); ++ } ++ ++ return result; ++} ++ ++bool ++sb_iscoreup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); ++} ++ ++/* ++ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, ++ * switch back to the original core, and return the new value. ++ */ ++static uint ++sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ uint origidx; ++ uint32 *r; ++ uint w; ++ uint intr_val = 0; ++ ++ ASSERT(GOODIDX(coreidx)); ++ ASSERT(regoff < SB_CORE_SIZE); ++ ASSERT((val & ~mask) == 0); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ /* switch core */ ++ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); ++ ++ /* mask and set */ ++ if (mask || val) { ++ if (regoff >= SBCONFIGOFF) { ++ w = (R_SBREG(si, r) & ~mask) | val; ++ W_SBREG(si, r, w); ++ } else { ++ w = (R_REG(r) & ~mask) | val; ++ W_REG(r, w); ++ } ++ } ++ ++ /* readback */ ++ if (regoff >= SBCONFIGOFF) ++ w = R_SBREG(si, r); ++ else ++ w = R_REG(r); ++ ++ /* restore core index */ ++ if (origidx != coreidx) ++ sb_setcoreidx(&si->sb, origidx); ++ ++ INTR_RESTORE(si, intr_val); ++ return (w); ++} ++ ++#define DWORD_ALIGN(x) (x & ~(0x03)) ++#define BYTE_POS(x) (x & 0x3) ++#define WORD_POS(x) (x & 0x1) ++ ++#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) ++#define WORD_SHIFT(x) (16 * WORD_POS(x)) ++ ++#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) ++#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) ++ ++#define read_pci_cfg_byte(a) \ ++ (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff) ++ ++#define read_pci_cfg_write(a) \ ++ (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff) ++ ++ ++/* return TRUE if requested capability exists in the PCI config space */ ++static bool ++sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen) ++{ ++ uint8 cap_id; ++ uint8 cap_ptr; ++ uint32 bufsize; ++ uint8 byte_val; ++ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return FALSE; ++ ++ /* check for Header type 0*/ ++ byte_val = read_pci_cfg_byte(PCI_CFG_HDR); ++ if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) ++ return FALSE; ++ ++ /* check if the capability pointer field exists */ ++ byte_val = read_pci_cfg_byte(PCI_CFG_STAT); ++ if (!(byte_val & PCI_CAPPTR_PRESENT)) ++ return FALSE; ++ ++ cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); ++ /* check if the capability pointer is 0x00 */ ++ if (cap_ptr == 0x00) ++ return FALSE; ++ ++ ++ /* loop thr'u the capability list and see if the pcie capabilty exists */ ++ ++ cap_id = read_pci_cfg_byte(cap_ptr); ++ ++ while (cap_id != req_cap_id) { ++ cap_ptr = read_pci_cfg_byte((cap_ptr+1)); ++ if (cap_ptr == 0x00) break; ++ cap_id = read_pci_cfg_byte(cap_ptr); ++ } ++ if (cap_id != req_cap_id) { ++ return FALSE; ++ } ++ /* found the caller requested capability */ ++ if ((buf != NULL) && (buflen != NULL)) { ++ bufsize = *buflen; ++ if (!bufsize) goto end; ++ *buflen = 0; ++ /* copy the cpability data excluding cap ID and next ptr */ ++ cap_ptr += 2; ++ if ((bufsize + cap_ptr) > SZPCR) ++ bufsize = SZPCR - cap_ptr; ++ *buflen = bufsize; ++ while (bufsize--) { ++ *buf = read_pci_cfg_byte(cap_ptr); ++ cap_ptr++; ++ buf++; ++ } ++ } ++end: ++ return TRUE; ++} ++ ++/* return TRUE if PCIE capability exists the pci config space */ ++static bool ++sb_ispcie(sb_info_t *si) ++{ ++ return(sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL)); ++} ++ ++/* scan the sb enumerated space to identify all cores */ ++static void ++BCMINITFN(sb_scan)(sb_info_t *si) ++{ ++ uint origidx; ++ uint i; ++ bool pci; ++ bool pcie; ++ uint pciidx; ++ uint pcieidx; ++ uint pcirev; ++ uint pcierev; ++ ++ ++ ++ /* numcores should already be set */ ++ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ si->sb.buscorerev = NOREV; ++ si->sb.buscoreidx = BADIDX; ++ ++ si->gpioidx = BADIDX; ++ ++ pci = pcie = FALSE; ++ pcirev = pcierev = NOREV; ++ pciidx = pcieidx = BADIDX; ++ ++ for (i = 0; i < si->numcores; i++) { ++ sb_setcoreidx(&si->sb, i); ++ si->coreid[i] = sb_coreid(&si->sb); ++ ++ if (si->coreid[i] == SB_PCI) { ++ pciidx = i; ++ pcirev = sb_corerev(&si->sb); ++ pci = TRUE; ++ } else if (si->coreid[i] == SB_PCIE) { ++ pcieidx = i; ++ pcierev = sb_corerev(&si->sb); ++ pcie = TRUE; ++ } else if (si->coreid[i] == SB_PCMCIA) { ++ si->sb.buscorerev = sb_corerev(&si->sb); ++ si->sb.buscoretype = si->coreid[i]; ++ si->sb.buscoreidx = i; ++ } ++ } ++ if (pci && pcie) { ++ if (sb_ispcie(si)) ++ pci = FALSE; ++ else ++ pcie = FALSE; ++ } ++ if (pci) { ++ si->sb.buscoretype = SB_PCI; ++ si->sb.buscorerev = pcirev; ++ si->sb.buscoreidx = pciidx; ++ } ++ else if (pcie) { ++ si->sb.buscoretype = SB_PCIE; ++ si->sb.buscorerev = pcierev; ++ si->sb.buscoreidx = pcieidx; ++ } ++ ++ /* ++ * Find the gpio "controlling core" type and index. ++ * Precedence: ++ * - if there's a chip common core - use that ++ * - else if there's a pci core (rev >= 2) - use that ++ * - else there had better be an extif core (4710 only) ++ */ ++ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { ++ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); ++ si->gpioid = SB_CC; ++ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { ++ si->gpioidx = si->sb.buscoreidx; ++ si->gpioid = SB_PCI; ++ } else if (sb_findcoreidx(si, SB_EXTIF, 0)) { ++ si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0); ++ si->gpioid = SB_EXTIF; ++ } else ++ ASSERT(si->gpioidx != BADIDX); ++ ++ /* return to original core index */ ++ sb_setcoreidx(&si->sb, origidx); ++} ++ ++/* may be called with core in reset */ ++void ++sb_detach(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ if (si == NULL) ++ return; ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ for (idx = 0; idx < SB_MAXCORES; idx++) ++ if (si->regs[idx]) { ++ REG_UNMAP(si->regs[idx]); ++ si->regs[idx] = NULL; ++ } ++ ++ if (si != &ksi) ++ MFREE(si->osh, si, sizeof (sb_info_t)); ++} ++ ++/* use pci dev id to determine chip id for chips not having a chipcommon core */ ++static uint ++BCMINITFN(sb_pcidev2chip)(uint pcidev) ++{ ++ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) ++ return (BCM4710_DEVICE_ID); ++ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) ++ return (BCM4402_DEVICE_ID); ++ if (pcidev == BCM4401_ENET_ID) ++ return (BCM4402_DEVICE_ID); ++ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) ++ return (BCM4307_DEVICE_ID); ++ if (pcidev == BCM4301_DEVICE_ID) ++ return (BCM4301_DEVICE_ID); ++ ++ return (0); ++} ++ ++/* convert chip number to number of i/o cores */ ++static uint ++BCMINITFN(sb_chip2numcores)(uint chip) ++{ ++ if (chip == BCM4710_DEVICE_ID) ++ return (9); ++ if (chip == BCM4402_DEVICE_ID) ++ return (3); ++ if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID)) ++ return (5); ++ if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */ ++ return (6); ++ if (chip == BCM4704_DEVICE_ID) ++ return (9); ++ if (chip == BCM5365_DEVICE_ID) ++ return (7); ++ ++ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); ++ ASSERT(0); ++ return (1); ++} ++ ++/* return index of coreid or BADIDX if not found */ ++static uint ++sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit) ++{ ++ uint found; ++ uint i; ++ ++ found = 0; ++ ++ for (i = 0; i < si->numcores; i++) ++ if (si->coreid[i] == coreid) { ++ if (found == coreunit) ++ return (i); ++ found++; ++ } ++ ++ return (BADIDX); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcoreidx(sb_t *sbh, uint coreidx) ++{ ++ sb_info_t *si; ++ uint32 sbaddr; ++ uint8 tmp; ++ ++ si = SB_INFO(sbh); ++ ++ if (coreidx >= si->numcores) ++ return (NULL); ++ ++ /* ++ * If the user has provided an interrupt mask enabled function, ++ * then assert interrupts are disabled before switching the core. ++ */ ++ ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); ++ ++ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++ ++ case PCI_BUS: ++ /* point bar0 window */ ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); ++ break; ++ ++ case PCMCIA_BUS: ++ tmp = (sbaddr >> 12) & 0x0f; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ tmp = (sbaddr >> 16) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ tmp = (sbaddr >> 24) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ break; ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void *)sbaddr; ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++#endif /* BCMJTAG */ ++ } ++ ++ si->curidx = coreidx; ++ ++ return (si->curmap); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcore(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ idx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(idx)) ++ return (NULL); ++ ++ return (sb_setcoreidx(sbh, idx)); ++} ++ ++/* return chip number */ ++uint ++BCMINITFN(sb_chip)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chip); ++} ++ ++/* return chip revision number */ ++uint ++BCMINITFN(sb_chiprev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chiprev); ++} ++ ++/* return chip common revision number */ ++uint ++BCMINITFN(sb_chipcrev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.ccrev); ++} ++ ++/* return chip package option */ ++uint ++BCMINITFN(sb_chippkg)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chippkg); ++} ++ ++/* return PCI core rev. */ ++uint ++BCMINITFN(sb_pcirev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); ++} ++ ++bool ++BCMINITFN(sb_war16165)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (PCI(si) && (si->sb.buscorerev <= 10)); ++} ++ ++static void ++BCMINITFN(sb_war30841)(sb_info_t *si) ++{ ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); ++} ++ ++/* return PCMCIA core rev. */ ++uint ++BCMINITFN(sb_pcmciarev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); ++} ++ ++/* return board vendor id */ ++uint ++BCMINITFN(sb_boardvendor)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.boardvendor); ++} ++ ++/* return boardtype */ ++uint ++BCMINITFN(sb_boardtype)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ char *var; ++ ++ si = SB_INFO(sbh); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { ++ /* boardtype format is a hex string */ ++ si->sb.boardtype = getintvar(NULL, "boardtype"); ++ ++ /* backward compatibility for older boardtype string format */ ++ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { ++ if (!strcmp(var, "bcm94710dev")) ++ si->sb.boardtype = BCM94710D_BOARD; ++ else if (!strcmp(var, "bcm94710ap")) ++ si->sb.boardtype = BCM94710AP_BOARD; ++ else if (!strcmp(var, "bu4710")) ++ si->sb.boardtype = BU4710_BOARD; ++ else if (!strcmp(var, "bcm94702mn")) ++ si->sb.boardtype = BCM94702MN_BOARD; ++ else if (!strcmp(var, "bcm94710r1")) ++ si->sb.boardtype = BCM94710R1_BOARD; ++ else if (!strcmp(var, "bcm94710r4")) ++ si->sb.boardtype = BCM94710R4_BOARD; ++ else if (!strcmp(var, "bcm94702cpci")) ++ si->sb.boardtype = BCM94702CPCI_BOARD; ++ else if (!strcmp(var, "bcm95380_rr")) ++ si->sb.boardtype = BCM95380RR_BOARD; ++ } ++ } ++ ++ return (si->sb.boardtype); ++} ++ ++/* return bus type of sbh device */ ++uint ++sb_bus(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.bustype); ++} ++ ++/* return bus core type */ ++uint ++sb_buscoretype(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscoretype); ++} ++ ++/* return bus core revision */ ++uint ++sb_buscorerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscorerev); ++} ++ ++/* return list of found cores */ ++uint ++sb_corelist(sb_t *sbh, uint coreid[]) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); ++ return (si->numcores); ++} ++ ++/* return current register mapping */ ++void * ++sb_coreregs(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ ++ return (si->curmap); ++} ++ ++ ++/* do buffered registers update */ ++void ++sb_commit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ASSERT(GOODIDX(origidx)); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch over to chipcommon core if there is one, else use pci */ ++ if (si->sb.ccrev != NOREV) { ++ chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&ccregs->broadcastaddress, SB_COMMIT); ++ W_REG(&ccregs->broadcastdata, 0x0); ++ } else if (PCI(si)) { ++ sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&pciregs->bcastaddr, SB_COMMIT); ++ W_REG(&pciregs->bcastdata, 0x0); ++ } else ++ ASSERT(0); ++ ++ /* restore core index */ ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++} ++ ++/* reset and re-enable a core */ ++void ++sb_core_reset(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ volatile uint32 dummy; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* ++ * Must do the disable sequence first to work for arbitrary current core state. ++ */ ++ sb_core_disable(sbh, bits); ++ ++ /* ++ * Now do the initialization sequence. ++ */ ++ ++ /* set reset while enabling the clock and forcing them on throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { ++ W_SBREG(si, &sb->sbtmstatehigh, 0); ++ } ++ if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { ++ AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); ++ } ++ ++ /* clear reset and allow it to propagate throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ /* leave clock enabled */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++} ++ ++void ++sb_core_tofixup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) || (PCI(si) && (si->sb.buscorerev >= 5)) ) ++ return; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); ++ } else { ++ if (sb_coreid(sbh) == SB_PCI) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ } else { ++ SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ } ++ } ++ ++ sb_commit(sbh); ++} ++ ++/* ++ * Set the initiator timeout for the "master core". ++ * The master core is defined to be the core in control ++ * of the chip and so it issues accesses to non-memory ++ * locations (Because of dma *any* core can access memeory). ++ * ++ * The routine uses the bus to decide who is the master: ++ * SB_BUS => mips ++ * JTAG_BUS => chipc ++ * PCI_BUS => pci or pcie ++ * PCMCIA_BUS => pcmcia ++ * SDIO_BUS => pcmcia ++ * ++ * This routine exists so callers can disable initiator ++ * timeouts so accesses to very slow devices like otp ++ * won't cause an abort. The routine allows arbitrary ++ * settings of the service and request timeouts, though. ++ * ++ * Returns the timeout state before changing it or -1 ++ * on error. ++ */ ++ ++#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) ++ ++uint32 ++sb_set_initiator_to(sb_t *sbh, uint32 to) ++{ ++ sb_info_t *si; ++ uint origidx, idx; ++ uint intr_val = 0; ++ uint32 tmp, ret = 0xffffffff; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ((to & ~TO_MASK) != 0) ++ return ret; ++ ++ /* Figure out the master core */ ++ idx = BADIDX; ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ idx = si->sb.buscoreidx; ++ break; ++ case JTAG_BUS: ++ idx = SB_CC_IDX; ++ break; ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ idx = sb_findcoreidx(si, SB_PCMCIA, 0); ++ break; ++ case SB_BUS: ++ if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX) ++ idx = sb_findcoreidx(si, SB_MIPS, 0); ++ break; ++ default: ++ ASSERT(0); ++ } ++ if (idx == BADIDX) ++ return ret; ++ ++ INTR_OFF(si, intr_val); ++ origidx = sb_coreidx(sbh); ++ ++ sb = REGS2SB(sb_setcoreidx(sbh, idx)); ++ ++ tmp = R_SBREG(si, &sb->sbimconfiglow); ++ ret = tmp & TO_MASK; ++ W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); ++ ++ sb_commit(sbh); ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return ret; ++} ++ ++void ++sb_core_disable(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ volatile uint32 dummy; ++ uint32 rej; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* if core is already in reset, just return */ ++ if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET) ++ return; ++ ++ /* reject value changed between sonics 2.2 and 2.3 */ ++ if (si->sb.sonicsrev == SONICS_2_2) ++ rej = (1 << SBTML_REJ_SHIFT); ++ else ++ rej = (2 << SBTML_REJ_SHIFT); ++ ++ /* if clocks are not enabled, put into reset and return */ ++ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) ++ goto disable; ++ ++ /* set target reject and spin until busy is clear (preserve core-specific bits) */ ++ OR_SBREG(si, &sb->sbtmstatelow, rej); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) { ++ OR_SBREG(si, &sb->sbimstate, SBIM_RJ); ++ dummy = R_SBREG(si, &sb->sbimstate); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); ++ } ++ ++ /* set reset and reject while enabling the clocks */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(10); ++ ++ /* don't forget to clear the initiator reject bit */ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) ++ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); ++ ++disable: ++ /* leave reset and reject asserted */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET)); ++ OSL_DELAY(1); ++} ++ ++/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */ ++void ++sb_watchdog(sb_t *sbh, uint ticks) ++{ ++ sb_info_t *si = SB_INFO(sbh); ++ ++ /* instant NMI */ ++ switch (si->gpioid) { ++ case SB_CC: ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++ break; ++ case SB_EXTIF: ++ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ break; ++ } ++} ++ ++/* initialize the pcmcia core */ ++void ++sb_pcmcia_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint8 cor; ++ ++ si = SB_INFO(sbh); ++ ++ /* enable d11 mac interrupts */ ++ if (si->sb.chip == BCM4301_DEVICE_ID) { ++ /* Have to use FCR2 in 4301 */ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ } else { ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ } ++ ++} ++ ++ ++/* ++ * Configure the pci core for pci client (NIC) action ++ * coremask is the bitvec of cores by index to be enabled. ++ */ ++void ++sb_pci_setup(sb_t *sbh, uint coremask) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ sbpciregs_t *pciregs; ++ uint32 sbflag; ++ uint32 w; ++ uint idx; ++ int reg_val; ++ ++ si = SB_INFO(sbh); ++ ++ /* if not pci bus, we're done */ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return; ++ ++ ASSERT(PCI(si) || PCIE(si)); ++ ASSERT(si->sb.buscoreidx != BADIDX); ++ ++ /* get current core index */ ++ idx = si->curidx; ++ ++ /* we interrupt on this backplane flag number */ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ ++ /* switch over to pci core */ ++ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx); ++ sb = REGS2SB(pciregs); ++ ++ /* ++ * Enable sb->pci interrupts. Assume ++ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. ++ */ ++ if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) { ++ /* pci config write to set this core bit in PCIIntMask */ ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); ++ w |= (coremask << PCI_SBIM_SHIFT); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); ++ } else { ++ /* set sbintvec bit for our flag number */ ++ OR_SBREG(si, &sb->sbintvec, (1 << sbflag)); ++ } ++ ++ if (PCI(si)) { ++ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); ++ if (si->sb.buscorerev >= 11) ++ OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); ++ if (si->sb.buscorerev < 5) { ++ SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ sb_commit(sbh); ++ } ++ } ++ ++ if (PCIE(si) && (si->sb.buscorerev == 0)) { ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); ++ reg_val |= 0x8; ++ sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, reg_val); ++ ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG); ++ reg_val &= ~(0x40); ++ sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val); ++ ++ BCMINIT(sb_war30841)(si); ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++} ++ ++uint32 ++sb_base(uint32 admatch) ++{ ++ uint32 base; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ base = 0; ++ ++ if (type == 0) { ++ base = admatch & SBAM_BASE0_MASK; ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE1_MASK; ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE2_MASK; ++ } ++ ++ return (base); ++} ++ ++uint32 ++sb_size(uint32 admatch) ++{ ++ uint32 size; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ size = 0; ++ ++ if (type == 0) { ++ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); ++ } ++ ++ return (size); ++} ++ ++/* return the core-type instantiation # of the current core */ ++uint ++sb_coreunit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ uint coreid; ++ uint coreunit; ++ uint i; ++ ++ si = SB_INFO(sbh); ++ coreunit = 0; ++ ++ idx = si->curidx; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ coreid = sb_coreid(sbh); ++ ++ /* count the cores of our type */ ++ for (i = 0; i < idx; i++) ++ if (si->coreid[i] == coreid) ++ coreunit++; ++ ++ return (coreunit); ++} ++ ++static INLINE uint32 ++factor6(uint32 x) ++{ ++ switch (x) { ++ case CC_F6_2: return 2; ++ case CC_F6_3: return 3; ++ case CC_F6_4: return 4; ++ case CC_F6_5: return 5; ++ case CC_F6_6: return 6; ++ case CC_F6_7: return 7; ++ default: return 0; ++ } ++} ++ ++/* calculate the speed the SB would run at given a set of clockcontrol values */ ++uint32 ++sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) ++{ ++ uint32 n1, n2, clock, m1, m2, m3, mc; ++ ++ n1 = n & CN_N1_MASK; ++ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; ++ ++ if (pll_type == PLL_TYPE6) { ++ if (m & CC_T6_MMASK) ++ return CC_T6_M1; ++ else ++ return CC_T6_M0; ++ } else if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ n1 = factor6(n1); ++ n2 += CC_F5_BIAS; ++ } else if (pll_type == PLL_TYPE2) { ++ n1 += CC_T2_BIAS; ++ n2 += CC_T2_BIAS; ++ ASSERT((n1 >= 2) && (n1 <= 7)); ++ ASSERT((n2 >= 5) && (n2 <= 23)); ++ } else if (pll_type == PLL_TYPE5) { ++ return (100000000); ++ } else ++ ASSERT(0); ++ /* PLL types 3 and 7 use BASE2 (25Mhz) */ ++ if ((pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE7)) { ++ clock = CC_CLOCK_BASE2 * n1 * n2; ++ } ++ else ++ clock = CC_CLOCK_BASE1 * n1 * n2; ++ ++ if (clock == 0) ++ return 0; ++ ++ m1 = m & CC_M1_MASK; ++ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; ++ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; ++ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ m1 = factor6(m1); ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) ++ m2 += CC_F5_BIAS; ++ else ++ m2 = factor6(m2); ++ m3 = factor6(m3); ++ ++ switch (mc) { ++ case CC_MC_BYPASS: return (clock); ++ case CC_MC_M1: return (clock / m1); ++ case CC_MC_M1M2: return (clock / (m1 * m2)); ++ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); ++ case CC_MC_M1M3: return (clock / (m1 * m3)); ++ default: return (0); ++ } ++ } else { ++ ASSERT(pll_type == PLL_TYPE2); ++ ++ m1 += CC_T2_BIAS; ++ m2 += CC_T2M2_BIAS; ++ m3 += CC_T2_BIAS; ++ ASSERT((m1 >= 2) && (m1 <= 7)); ++ ASSERT((m2 >= 3) && (m2 <= 10)); ++ ASSERT((m3 >= 2) && (m3 <= 7)); ++ ++ if ((mc & CC_T2MC_M1BYP) == 0) ++ clock /= m1; ++ if ((mc & CC_T2MC_M2BYP) == 0) ++ clock /= m2; ++ if ((mc & CC_T2MC_M3BYP) == 0) ++ clock /= m3; ++ ++ return(clock); ++ } ++} ++ ++/* returns the current speed the SB is running at */ ++uint32 ++sb_clock(sb_t *sbh) ++{ ++ sb_info_t *si; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ idx = si->curidx; ++ pll_type = PLL_TYPE1; ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if (pll_type == PLL_TYPE6) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE3) ++ { ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ m = R_REG(&cc->clockcontrol_sb); ++ else ++ m = R_REG(&cc->clockcontrol_m2); ++ } ++ else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else { ++ INTR_RESTORE(si, intr_val); ++ return 0; ++ } ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { ++ rate = 100000000; ++ } ++ else ++ { ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ if (pll_type == PLL_TYPE3) ++ rate = rate / 2; ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ INTR_RESTORE(si, intr_val); ++ ++ return rate; ++} ++ ++/* change logical "focus" to the gpio core for optimized access */ ++void* ++sb_gpiosetcore(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (sb_setcoreidx(sbh, si->gpioidx)); ++} ++ ++/* mask&set gpiocontrol bits */ ++uint32 ++sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiocontrol); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); ++ break; ++ ++ case SB_EXTIF: ++ return (0); ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output enable bits */ ++uint32 ++sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioouten); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioouten); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].outen); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output bits */ ++uint32 ++sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioout); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioout); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].out); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* reserve one gpio */ ++uint32 ++sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ ++ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; ++ } ++ ++ /* already reserved */ ++ if (sb_gpioreservation & gpio_bitmask) ++ return -1; ++ /* set reservation */ ++ sb_gpioreservation |= gpio_bitmask; ++ ++ return sb_gpioreservation; ++} ++ ++/* release one gpio */ ++/* ++ * releasing the gpio doesn't change the current value on the GPIO last write value ++ * persists till some one overwrites it ++*/ ++ ++uint32 ++sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ ++ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; ++ } ++ ++ /* already released */ ++ if (!(sb_gpioreservation & gpio_bitmask)) ++ return -1; ++ ++ /* clear reservation */ ++ sb_gpioreservation &= ~gpio_bitmask; ++ ++ return sb_gpioreservation; ++} ++ ++/* return the current gpioin register value */ ++uint32 ++sb_gpioin(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioin); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioin); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpioin); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); ++} ++ ++/* mask&set gpio interrupt polarity bits */ ++uint32 ++sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt polarity */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointpolarity); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio interrupt mask bits */ ++uint32 ++sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointmask); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt mask */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointmask); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* assign the gpio to an led */ ++uint32 ++sb_gpioled(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ /* gpio led powersave reg */ ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); ++} ++ ++/* mask&set gpio timer val */ ++uint32 ++sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); ++} ++ ++ ++/* return the slow clock source - LPO, XTAL, or PCI */ ++static uint ++sb_slowclk_src(sb_info_t *si) ++{ ++ chipcregs_t *cc; ++ ++ ++ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ ++ if (si->sb.ccrev < 6) { ++ if ((BUSTYPE(si->sb.bustype) == PCI_BUS) ++ && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS)) ++ return (SCC_SS_PCI); ++ else ++ return (SCC_SS_XTAL); ++ } else if (si->sb.ccrev < 10) { ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK); ++ } else /* Insta-clock */ ++ return (SCC_SS_XTAL); ++} ++ ++/* return the ILP (slowclock) min or max frequency */ ++static uint ++sb_slowclk_freq(sb_info_t *si, bool max) ++{ ++ chipcregs_t *cc; ++ uint32 slowclk; ++ uint div; ++ ++ ++ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ ++ /* shouldn't be here unless we've established the chip has dynamic clk control */ ++ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); ++ ++ slowclk = sb_slowclk_src(si); ++ if (si->sb.ccrev < 6) { ++ if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); ++ else ++ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); ++ } else if (si->sb.ccrev < 10) { ++ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ if (slowclk == SCC_SS_LPO) ++ return (max? LPOMAXFREQ : LPOMINFREQ); ++ else if (slowclk == SCC_SS_XTAL) ++ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); ++ else if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); ++ else ++ ASSERT(0); ++ } else { ++ /* Chipc rev 10 is InstaClock */ ++ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; ++ div = 4 * (div + 1); ++ return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); ++ } ++ return (0); ++} ++ ++static void ++sb_clkctl_setdelay(sb_info_t *si, void *chipcregs) ++{ ++ chipcregs_t * cc; ++ uint slowmaxfreq, pll_delay, slowclk; ++ uint pll_on_delay, fref_sel_delay; ++ ++ pll_delay = PLL_DELAY; ++ ++ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay ++ * since the xtal will also be powered down by dynamic clk control logic. ++ */ ++ slowclk = sb_slowclk_src(si); ++ if (slowclk != SCC_SS_XTAL) ++ pll_delay += XTAL_ON_DELAY; ++ ++ /* Starting with 4318 it is ILP that is used for the delays */ ++ slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE); ++ ++ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; ++ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; ++ ++ cc = (chipcregs_t *)chipcregs; ++ W_REG(&cc->pll_on_delay, pll_on_delay); ++ W_REG(&cc->fref_sel_delay, fref_sel_delay); ++} ++ ++int ++sb_pwrctl_slowclk(void *sbh, bool set, uint *div) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint intr_val = 0; ++ uint err = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ ++ if (si->sb.ccrev < 6) ++ return 1; ++ ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return 1; ++ ++ if (set && ((*div % 4) || (*div < 4))) ++ return 2; ++ ++ INTR_OFF(si, intr_val); ++ origidx = si->curidx; ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) { ++ err = 3; ++ goto done; ++ } ++ ++ if (set) { ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT)); ++ sb_clkctl_setdelay(sbh, (void *)cc); ++ } else ++ *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return err; ++} ++ ++/* initialize power control delay registers */ ++void sb_clkctl_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ return; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ /* 4317pc does not work with SlowClock less than 5 MHz */ ++ if ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->sb.ccrev >= 6) && (si->sb.ccrev < 10)) ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (ILP_DIV_5MHZ << SCC_CD_SHIFT)); ++ ++ /* set all Instaclk chip ILP to 1 MHz */ ++ else if (si->sb.ccrev >= 10) ++ SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); ++ ++ sb_clkctl_setdelay(si, (void *)cc); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++} ++void sb_pwrctl_init(sb_t *sbh) ++{ ++sb_clkctl_init(sbh); ++} ++/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ ++uint16 ++sb_clkctl_fast_pwrup_delay(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint slowminfreq; ++ uint16 fpdelay; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ fpdelay = 0; ++ origidx = si->curidx; ++ ++ INTR_OFF(si, intr_val); ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ goto done; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ slowminfreq = sb_slowclk_freq(si, FALSE); ++ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (fpdelay); ++} ++uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh) ++{ ++return sb_clkctl_fast_pwrup_delay(sbh); ++} ++/* turn primary xtal and/or pll off/on */ ++int ++sb_clkctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++ sb_info_t *si; ++ uint32 in, out, outen; ++ ++ si = SB_INFO(sbh); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ ++ ++ case PCMCIA_BUS: ++ return (0); ++ ++ ++ case PCI_BUS: ++ ++ /* pcie core doesn't have any mapping to control the xtal pu */ ++ if (PCIE(si)) ++ return -1; ++ ++ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32)); ++ out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); ++ outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32)); ++ ++ /* ++ * Avoid glitching the clock if GPRS is already using it. ++ * We can't actually read the state of the PLLPD so we infer it ++ * by the value of XTAL_PU which *is* readable via gpioin. ++ */ ++ if (on && (in & PCI_CFG_GPIO_XTAL)) ++ return (0); ++ ++ if (what & XTAL) ++ outen |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ outen |= PCI_CFG_GPIO_PLL; ++ ++ if (on) { ++ /* turn primary xtal on */ ++ if (what & XTAL) { ++ out |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); ++ OSL_DELAY(XTAL_ON_DELAY); ++ } ++ ++ /* turn pll on */ ++ if (what & PLL) { ++ out &= ~PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_DELAY(2000); ++ } ++ } else { ++ if (what & XTAL) ++ out &= ~PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); ++ } ++ ++ default: ++ return (-1); ++ } ++ ++ return (0); ++} ++ ++int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++return sb_clkctl_xtal(sbh,what,on); ++} ++ ++/* set dynamic clk control mode (forceslow, forcefast, dynamic) */ ++/* returns true if ignore pll off is set and false if it is not */ ++bool ++sb_clkctl_clk(sb_t *sbh, uint mode) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint32 scc; ++ bool forcefastclk=FALSE; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* chipcommon cores prior to rev6 don't support dynamic clock control */ ++ if (si->sb.ccrev < 6) ++ return (FALSE); ++ ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return (FALSE); ++ ++ INTR_OFF(si, intr_val); ++ ++ origidx = si->curidx; ++ ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ switch (mode) { ++ case CLK_FAST: /* force fast (pll) clock */ ++ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ ++ sb_clkctl_xtal(&si->sb, XTAL, ON); ++ ++ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); ++ break; ++ ++ case CLK_DYNAMIC: /* enable dynamic clock control */ ++ scc = R_REG(&cc->slow_clk_ctl); ++ scc &= ~(SCC_FS | SCC_IP | SCC_XC); ++ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) ++ scc |= SCC_XC; ++ W_REG(&cc->slow_clk_ctl, scc); ++ ++ /* for dynamic control, we have to release our xtal_pu "force on" */ ++ if (scc & SCC_XC) ++ sb_clkctl_xtal(&si->sb, XTAL, OFF); ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ /* Is the h/w forcing the use of the fast clk */ ++ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (forcefastclk); ++} ++ ++bool sb_pwrctl_clk(sb_t *sbh, uint mode) ++{ ++return sb_clkctl_clk(sbh, mode); ++} ++/* register driver interrupt disabling and restoring callback functions */ ++void ++sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ si->intr_arg = intr_arg; ++ si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; ++ si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; ++ si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; ++ /* save current core id. when this function called, the current core ++ * must be the core which provides driver functions(il, et, wl, etc.) ++ */ ++ si->dev_coreid = si->coreid[si->curidx]; ++} ++ ++ ++void ++sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif) ++{ ++ uint vendor, core, unit; ++ uint chip, chippkg; ++ char varname[8]; ++ uint8 class, subclass, progif; ++ ++ vendor = sb_corevendor(sbh); ++ core = sb_coreid(sbh); ++ unit = sb_coreunit(sbh); ++ ++ chip = BCMINIT(sb_chip)(sbh); ++ chippkg = BCMINIT(sb_chippkg)(sbh); ++ ++ progif = 0; ++ ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++ case SB_PCIE: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ core = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", unit); ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; ++ } ++ } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; ++ } ++ ++ *pcivendor = (uint16)vendor; ++ *pcidevice = (uint16)core; ++ *pciclass = class; ++ *pcisubclass = subclass; ++ *pciprogif = progif; ++} ++ ++ ++ ++ ++/* use the mdio interface to write to mdio slaves */ ++static int ++sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val) ++{ ++ uint mdiodata; ++ uint i = 0; ++ sbpcieregs_t *pcieregs; ++ ++ pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx); ++ ASSERT (pcieregs); ++ ++ /* enable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); ++ ++ mdiodata = MDIODATA_START | MDIODATA_WRITE | ++ (physmedia << MDIODATA_DEVADDR_SHF) | ++ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val; ++ ++ W_REG((&pcieregs->mdiodata), mdiodata); ++ ++ PR28829_DELAY(); ++ ++ /* retry till the transaction is complete */ ++ while ( i < 10 ) { ++ if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { ++ /* Disable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), 0); ++ return 0; ++ } ++ OSL_DELAY(1000); ++ i++; ++ } ++ ++ SB_ERROR(("sb_pcie_mdiowrite: timed out\n")); ++ /* Disable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), 0); ++ ASSERT(0); ++ return 1; ++ ++} ++ ++/* indirect way to read pcie config regs*/ ++uint ++sb_pcie_readreg(void *sb, void* arg1, uint offset) ++{ ++ sb_info_t *si; ++ sb_t *sbh; ++ uint retval = 0xFFFFFFFF; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; ++ ++ sbh = (sb_t *)sb; ++ si = SB_INFO(sbh); ++ ASSERT (PCIE(si)); ++ ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT (pcieregs); ++ ++ addrtype = (uint)((uintptr)arg1); ++ switch(addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG((&pcieregs->configaddr),offset); ++ retval = R_REG(&(pcieregs->configdata)); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG(&(pcieregs->pcieaddr),offset); ++ retval = R_REG(&(pcieregs->pciedata)); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ return retval; ++} ++ ++/* indirect way to write pcie config/mdio/pciecore regs*/ ++uint ++sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val) ++{ ++ sb_info_t *si; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; ++ ++ si = SB_INFO(sbh); ++ ASSERT (PCIE(si)); ++ ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT (pcieregs); ++ ++ addrtype = (uint)((uintptr)arg1); ++ ++ switch(addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG((&pcieregs->configaddr),offset); ++ W_REG((&pcieregs->configdata),val); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG((&pcieregs->pcieaddr),offset); ++ W_REG((&pcieregs->pciedata),val); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ return 0; ++} ++ ++ ++/* Build device path. Support SB, PCI, and JTAG for now. */ ++int ++sb_devpath(sb_t *sbh, char *path, int size) ++{ ++ ASSERT(path); ++ ASSERT(size >= SB_DEVPATH_BUFSZ); ++ ++ switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) { ++ case SB_BUS: ++ case JTAG_BUS: ++ sprintf(path, "sb/%u/", sb_coreidx(sbh)); ++ break; ++ case PCI_BUS: ++ ASSERT((SB_INFO(sbh))->osh); ++ sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh), ++ OSL_PCI_SLOT((SB_INFO(sbh))->osh)); ++ break; ++ case PCMCIA_BUS: ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n")); ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n")); ++ sprintf(path, "pc/%u/%u/", 1, 1); ++ break; ++ case SDIO_BUS: ++ SB_ERROR(("sb_devpath: device 0 assumed\n")); ++ sprintf(path, "sd/%u/", sb_coreidx(sbh)); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++ return 0; ++} ++ ++/* Fix chip's configuration. The current core may be changed upon return */ ++static int ++sb_pci_fixcfg(sb_info_t *si) ++{ ++ uint origidx, pciidx; ++ sbpciregs_t *pciregs; ++ sbpcieregs_t *pcieregs; ++ uint16 val16, *reg16; ++ char name[SB_DEVPATH_BUFSZ+16], *value; ++ char devpath[SB_DEVPATH_BUFSZ]; ++ ++ ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS); ++ ++ /* Fix PCI(e) SROM shadow area */ ++ /* save the current index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ /* check 'pi' is correct and fix it if not */ ++ if (si->sb.buscoretype == SB_PCIE) { ++ pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0); ++ ASSERT(pcieregs); ++ reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; ++ } ++ else if (si->sb.buscoretype == SB_PCI) { ++ pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0); ++ ASSERT(pciregs); ++ reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; ++ } ++ else { ++ ASSERT(0); ++ return -1; ++ } ++ pciidx = sb_coreidx(&si->sb); ++ val16 = R_REG(reg16); ++ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { ++ val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); ++ W_REG(reg16, val16); ++ } ++ ++ /* restore the original index */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* Fix bar0window */ ++ /* !do it last, it changes the current core! */ ++ if (sb_devpath(&si->sb, devpath, sizeof(devpath))) ++ return -1; ++ sprintf(name, "%sb0w", devpath); ++ if ((value = getvar(NULL, name))) { ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), ++ bcm_strtoul(value, NULL, 16)); ++ /* update curidx since the current core is changed */ ++ si->curidx = _sb_coreidx(si); ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_pci_fixcfg: bad core index\n")); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ +diff -Nur linux-2.4.32/drivers/net/hnd/shared_ksyms.sh linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh +--- linux-2.4.32/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh 2005-12-16 23:39:11.316860000 +0100 +@@ -0,0 +1,21 @@ ++#!/bin/sh ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: shared_ksyms.sh,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++# ++ ++cat < ++#include ++EOF ++ ++for file in $* ; do ++ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' ++done +diff -Nur linux-2.4.32/drivers/net/Makefile linux-2.4.32-brcm/drivers/net/Makefile +--- linux-2.4.32/drivers/net/Makefile 2005-01-19 15:09:56.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/Makefile 2005-12-16 23:39:11.284858000 +0100 +@@ -3,6 +3,8 @@ + # Makefile for the Linux network (ethercard) device drivers. + # + ++EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include ++ + obj-y := + obj-m := + obj-n := +@@ -39,6 +41,8 @@ + obj-$(CONFIG_ISDN) += slhc.o + endif + ++subdir-$(CONFIG_HND) += hnd ++subdir-$(CONFIG_WL) += wl + subdir-$(CONFIG_NET_PCMCIA) += pcmcia + subdir-$(CONFIG_NET_WIRELESS) += wireless + subdir-$(CONFIG_TULIP) += tulip +@@ -69,6 +74,13 @@ + obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o + obj-$(CONFIG_SUNGEM) += sungem.o + ++ifeq ($(CONFIG_HND),y) ++ obj-y += hnd/hnd.o ++endif ++ifeq ($(CONFIG_WL),y) ++ obj-y += wl/wl.o ++endif ++ + obj-$(CONFIG_MACE) += mace.o + obj-$(CONFIG_BMAC) += bmac.o + obj-$(CONFIG_GMAC) += gmac.o +diff -Nur linux-2.4.32/drivers/net/wireless/Config.in linux-2.4.32-brcm/drivers/net/wireless/Config.in +--- linux-2.4.32/drivers/net/wireless/Config.in 2004-11-17 12:54:21.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/wireless/Config.in 2005-12-16 23:39:11.364863000 +0100 +@@ -13,6 +13,7 @@ + fi + + if [ "$CONFIG_PCI" = "y" ]; then ++ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL + dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL +diff -Nur linux-2.4.32/drivers/net/wl/Makefile linux-2.4.32-brcm/drivers/net/wl/Makefile +--- linux-2.4.32/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/wl/Makefile 2005-12-16 23:39:11.364863000 +0100 +@@ -0,0 +1,26 @@ ++# ++# Makefile for the Broadcom wl driver ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ ++ ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include ++ ++O_TARGET := wl.o ++ ++obj-y := apsta_aeskeywrap.o apsta_aes.o apsta_bcmwpa.o apsta_d11ucode.o ++obj-y += apsta_hmac.o apsta_md5.o apsta_passhash.o apsta_prf.o apsta_rc4.o ++obj-y += apsta_rijndael-alg-fst.o apsta_sha1.o apsta_tkhash.o apsta_wlc_led.o ++obj-y += apsta_wlc_phy.o apsta_wlc_rate.o apsta_wlc_security.o ++obj-y += apsta_wlc_sup.o apsta_wlc_wet.o apsta_wl_linux.o apsta_wlc.o ++ ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/drivers/parport/Config.in linux-2.4.32-brcm/drivers/parport/Config.in +--- linux-2.4.32/drivers/parport/Config.in 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/parport/Config.in 2005-12-16 23:39:11.364863000 +0100 +@@ -11,6 +11,7 @@ + tristate 'Parallel port support' CONFIG_PARPORT + if [ "$CONFIG_PARPORT" != "n" ]; then + dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT ++ dep_tristate ' Asus WL500g parallel port' CONFIG_PARPORT_SPLINK $CONFIG_PARPORT + if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then + if [ "$CONFIG_SERIAL" = "m" ]; then + define_tristate CONFIG_PARPORT_PC_CML1 m +diff -Nur linux-2.4.32/drivers/parport/Makefile linux-2.4.32-brcm/drivers/parport/Makefile +--- linux-2.4.32/drivers/parport/Makefile 2004-08-08 01:26:05.000000000 +0200 ++++ linux-2.4.32-brcm/drivers/parport/Makefile 2005-12-16 23:39:11.364863000 +0100 +@@ -22,6 +22,7 @@ + + obj-$(CONFIG_PARPORT) += parport.o + obj-$(CONFIG_PARPORT_PC) += parport_pc.o ++obj-$(CONFIG_PARPORT_SPLINK) += parport_splink.o + obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o + obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o + obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o +diff -Nur linux-2.4.32/drivers/parport/parport_splink.c linux-2.4.32-brcm/drivers/parport/parport_splink.c +--- linux-2.4.32/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/parport/parport_splink.c 2005-12-16 23:39:11.364863000 +0100 +@@ -0,0 +1,345 @@ ++/* Low-level parallel port routines for the ASUS WL-500g built-in port ++ * ++ * Author: Nuno Grilo ++ * Based on parport_pc source ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SPLINK_ADDRESS 0xBF800010 ++ ++#undef DEBUG ++ ++#ifdef DEBUG ++#define DPRINTK printk ++#else ++#define DPRINTK(stuff...) ++#endif ++ ++ ++/* __parport_splink_frob_control differs from parport_splink_frob_control in that ++ * it doesn't do any extra masking. */ ++static __inline__ unsigned char __parport_splink_frob_control (struct parport *p, ++ unsigned char mask, ++ unsigned char val) ++{ ++ struct parport_pc_private *priv = p->physport->private_data; ++ unsigned char *io = (unsigned char *) p->base; ++ unsigned char ctr = priv->ctr; ++#ifdef DEBUG_PARPORT ++ printk (KERN_DEBUG ++ "__parport_splink_frob_control(%02x,%02x): %02x -> %02x\n", ++ mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); ++#endif ++ ctr = (ctr & ~mask) ^ val; ++ ctr &= priv->ctr_writable; /* only write writable bits. */ ++ *(io+2) = ctr; ++ priv->ctr = ctr; /* Update soft copy */ ++ return ctr; ++} ++ ++ ++ ++static void parport_splink_data_forward (struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); ++ __parport_splink_frob_control (p, 0x20, 0); ++} ++ ++static void parport_splink_data_reverse (struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); ++ __parport_splink_frob_control (p, 0x20, 0x20); ++} ++ ++/* ++static void parport_splink_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: IRQ handler called\n"); ++ parport_generic_irq(irq, (struct parport *) dev_id, regs); ++} ++*/ ++ ++static void parport_splink_enable_irq(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_enable_irq called\n"); ++ __parport_splink_frob_control (p, 0x10, 0x10); ++} ++ ++static void parport_splink_disable_irq(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_disable_irq called\n"); ++ __parport_splink_frob_control (p, 0x10, 0); ++} ++ ++static void parport_splink_init_state(struct pardevice *dev, struct parport_state *s) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_init_state called\n"); ++ s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0); ++ if (dev->irq_func && ++ dev->port->irq != PARPORT_IRQ_NONE) ++ /* Set ackIntEn */ ++ s->u.pc.ctr |= 0x10; ++} ++ ++static void parport_splink_save_state(struct parport *p, struct parport_state *s) ++{ ++ const struct parport_pc_private *priv = p->physport->private_data; ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_save_state called\n"); ++ s->u.pc.ctr = priv->ctr; ++} ++ ++static void parport_splink_restore_state(struct parport *p, struct parport_state *s) ++{ ++ struct parport_pc_private *priv = p->physport->private_data; ++ unsigned char *io = (unsigned char *) p->base; ++ unsigned char ctr = s->u.pc.ctr; ++ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_restore_state called\n"); ++ *(io+2) = ctr; ++ priv->ctr = ctr; ++} ++ ++static void parport_splink_setup_interrupt(void) { ++ return; ++} ++ ++static void parport_splink_write_data(struct parport *p, unsigned char d) { ++ DPRINTK(KERN_DEBUG "parport_splink: write data called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ *io = d; ++} ++ ++static unsigned char parport_splink_read_data(struct parport *p) { ++ DPRINTK(KERN_DEBUG "parport_splink: read data called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ return *io; ++} ++ ++static void parport_splink_write_control(struct parport *p, unsigned char d) ++{ ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); ++ ++ DPRINTK(KERN_DEBUG "parport_splink: write control called\n"); ++ /* Take this out when drivers have adapted to the newer interface. */ ++ if (d & 0x20) { ++ printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n", ++ p->name, p->cad->name); ++ parport_splink_data_reverse (p); ++ } ++ ++ __parport_splink_frob_control (p, wm, d & wm); ++} ++ ++static unsigned char parport_splink_read_control(struct parport *p) ++{ ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); ++ DPRINTK(KERN_DEBUG "parport_splink: read control called\n"); ++ const struct parport_pc_private *priv = p->physport->private_data; ++ return priv->ctr & wm; /* Use soft copy */ ++} ++ ++static unsigned char parport_splink_frob_control (struct parport *p, unsigned char mask, ++ unsigned char val) ++{ ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); ++ ++ DPRINTK(KERN_DEBUG "parport_splink: frob control called\n"); ++ /* Take this out when drivers have adapted to the newer interface. */ ++ if (mask & 0x20) { ++ printk (KERN_DEBUG "%s (%s): use data_%s for this!\n", ++ p->name, p->cad->name, ++ (val & 0x20) ? "reverse" : "forward"); ++ if (val & 0x20) ++ parport_splink_data_reverse (p); ++ else ++ parport_splink_data_forward (p); ++ } ++ ++ /* Restrict mask and val to control lines. */ ++ mask &= wm; ++ val &= wm; ++ ++ return __parport_splink_frob_control (p, mask, val); ++} ++ ++static unsigned char parport_splink_read_status(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: read status called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ return *(io+1); ++} ++ ++static void parport_splink_inc_use_count(void) ++{ ++#ifdef MODULE ++ MOD_INC_USE_COUNT; ++#endif ++} ++ ++static void parport_splink_dec_use_count(void) ++{ ++#ifdef MODULE ++ MOD_DEC_USE_COUNT; ++#endif ++} ++ ++static struct parport_operations parport_splink_ops = ++{ ++ parport_splink_write_data, ++ parport_splink_read_data, ++ ++ parport_splink_write_control, ++ parport_splink_read_control, ++ parport_splink_frob_control, ++ ++ parport_splink_read_status, ++ ++ parport_splink_enable_irq, ++ parport_splink_disable_irq, ++ ++ parport_splink_data_forward, ++ parport_splink_data_reverse, ++ ++ parport_splink_init_state, ++ parport_splink_save_state, ++ parport_splink_restore_state, ++ ++ parport_splink_inc_use_count, ++ parport_splink_dec_use_count, ++ ++ parport_ieee1284_epp_write_data, ++ parport_ieee1284_epp_read_data, ++ parport_ieee1284_epp_write_addr, ++ parport_ieee1284_epp_read_addr, ++ ++ parport_ieee1284_ecp_write_data, ++ parport_ieee1284_ecp_read_data, ++ parport_ieee1284_ecp_write_addr, ++ ++ parport_ieee1284_write_compat, ++ parport_ieee1284_read_nibble, ++ parport_ieee1284_read_byte, ++}; ++ ++/* --- Initialisation code -------------------------------- */ ++ ++static struct parport *parport_splink_probe_port (unsigned long int base) ++{ ++ struct parport_pc_private *priv; ++ struct parport_operations *ops; ++ struct parport *p; ++ ++ if (check_mem_region(base, 3)) { ++ printk (KERN_DEBUG "parport (0x%lx): iomem region not available\n", base); ++ return NULL; ++ } ++ priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL); ++ if (!priv) { ++ printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); ++ return NULL; ++ } ++ ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); ++ if (!ops) { ++ printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", ++ base); ++ kfree (priv); ++ return NULL; ++ } ++ memcpy (ops, &parport_splink_ops, sizeof (struct parport_operations)); ++ priv->ctr = 0xc; ++ priv->ctr_writable = 0xff; ++ ++ if (!(p = parport_register_port(base, PARPORT_IRQ_NONE, ++ PARPORT_DMA_NONE, ops))) { ++ printk (KERN_DEBUG "parport (0x%lx): registration failed!\n", ++ base); ++ kfree (priv); ++ kfree (ops); ++ return NULL; ++ } ++ ++ p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; ++ p->size = (p->modes & PARPORT_MODE_EPP)?8:3; ++ p->private_data = priv; ++ ++ parport_proc_register(p); ++ request_mem_region (p->base, 3, p->name); ++ ++ /* Done probing. Now put the port into a sensible start-up state. */ ++ parport_splink_write_data(p, 0); ++ parport_splink_data_forward (p); ++ ++ /* Now that we've told the sharing engine about the port, and ++ found out its characteristics, let the high-level drivers ++ know about it. */ ++ parport_announce_port (p); ++ ++ DPRINTK(KERN_DEBUG "parport (0x%lx): init ok!\n", ++ base); ++ return p; ++} ++ ++static void parport_splink_unregister_port(struct parport *p) { ++ struct parport_pc_private *priv = p->private_data; ++ struct parport_operations *ops = p->ops; ++ ++ if (p->irq != PARPORT_IRQ_NONE) ++ free_irq(p->irq, p); ++ release_mem_region(p->base, 3); ++ parport_proc_unregister(p); ++ kfree (priv); ++ parport_unregister_port(p); ++ kfree (ops); ++} ++ ++ ++int parport_splink_init(void) ++{ ++ int ret; ++ ++ DPRINTK(KERN_DEBUG "parport_splink init called\n"); ++ parport_splink_setup_interrupt(); ++ ret = !parport_splink_probe_port(SPLINK_ADDRESS); ++ ++ return ret; ++} ++ ++void parport_splink_cleanup(void) { ++ struct parport *p = parport_enumerate(), *tmp; ++ DPRINTK(KERN_DEBUG "parport_splink cleanup called\n"); ++ if (p->size) { ++ if (p->modes & PARPORT_MODE_PCSPP) { ++ while(p) { ++ tmp = p->next; ++ parport_splink_unregister_port(p); ++ p = tmp; ++ } ++ } ++ } ++} ++ ++MODULE_AUTHOR("Nuno Grilo "); ++MODULE_DESCRIPTION("Parport Driver for ASUS WL-500g router builtin Port"); ++MODULE_SUPPORTED_DEVICE("ASUS WL-500g builtin Parallel Port"); ++MODULE_LICENSE("GPL"); ++ ++module_init(parport_splink_init) ++module_exit(parport_splink_cleanup) ++ +diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_generic.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c +--- linux-2.4.32/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c 2005-12-16 23:39:11.368863250 +0100 +@@ -0,0 +1,912 @@ ++/* ++ * ++ * bcm47xx pcmcia driver ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Based on sa1100_generic.c from www.handhelds.org, ++ * and au1000_generic.c from oss.sgi.com. ++ * ++ * $Id: bcm4710_generic.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "cs_internal.h" ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "bcm4710pcmcia.h" ++ ++#ifdef PCMCIA_DEBUG ++static int pc_debug = PCMCIA_DEBUG; ++#endif ++ ++MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller"); ++ ++/* This structure maintains housekeeping state for each socket, such ++ * as the last known values of the card detect pins, or the Card Services ++ * callback value associated with the socket: ++ */ ++static struct bcm47xx_pcmcia_socket *pcmcia_socket; ++static int socket_count; ++ ++ ++/* Returned by the low-level PCMCIA interface: */ ++static struct pcmcia_low_level *pcmcia_low_level; ++ ++/* Event poll timer structure */ ++static struct timer_list poll_timer; ++ ++ ++/* Prototypes for routines which are used internally: */ ++ ++static int bcm47xx_pcmcia_driver_init(void); ++static void bcm47xx_pcmcia_driver_shutdown(void); ++static void bcm47xx_pcmcia_task_handler(void *data); ++static void bcm47xx_pcmcia_poll_event(unsigned long data); ++static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs); ++static struct tq_struct bcm47xx_pcmcia_task; ++ ++#ifdef CONFIG_PROC_FS ++static int bcm47xx_pcmcia_proc_status(char *buf, char **start, ++ off_t pos, int count, int *eof, void *data); ++#endif ++ ++ ++/* Prototypes for operations which are exported to the ++ * in-kernel PCMCIA core: ++ */ ++ ++static int bcm47xx_pcmcia_init(unsigned int sock); ++static int bcm47xx_pcmcia_suspend(unsigned int sock); ++static int bcm47xx_pcmcia_register_callback(unsigned int sock, ++ void (*handler)(void *, unsigned int), void *info); ++static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap); ++static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value); ++static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state); ++static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state); ++static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io); ++static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io); ++static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem); ++static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem); ++#ifdef CONFIG_PROC_FS ++static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base); ++#endif ++ ++static struct pccard_operations bcm47xx_pcmcia_operations = { ++ bcm47xx_pcmcia_init, ++ bcm47xx_pcmcia_suspend, ++ bcm47xx_pcmcia_register_callback, ++ bcm47xx_pcmcia_inquire_socket, ++ bcm47xx_pcmcia_get_status, ++ bcm47xx_pcmcia_get_socket, ++ bcm47xx_pcmcia_set_socket, ++ bcm47xx_pcmcia_get_io_map, ++ bcm47xx_pcmcia_set_io_map, ++ bcm47xx_pcmcia_get_mem_map, ++ bcm47xx_pcmcia_set_mem_map, ++#ifdef CONFIG_PROC_FS ++ bcm47xx_pcmcia_proc_setup ++#endif ++}; ++ ++ ++/* ++ * bcm47xx_pcmcia_driver_init() ++ * ++ * This routine performs a basic sanity check to ensure that this ++ * kernel has been built with the appropriate board-specific low-level ++ * PCMCIA support, performs low-level PCMCIA initialization, registers ++ * this socket driver with Card Services, and then spawns the daemon ++ * thread which is the real workhorse of the socket driver. ++ * ++ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information ++ * on the low-level kernel interface. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++static int __init bcm47xx_pcmcia_driver_init(void) ++{ ++ servinfo_t info; ++ struct pcmcia_init pcmcia_init; ++ struct pcmcia_state state; ++ unsigned int i; ++ unsigned long tmp; ++ ++ ++ printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE); ++ ++ CardServices(GetCardServicesInfo, &info); ++ ++ if (info.Revision != CS_RELEASE_CODE) { ++ printk(KERN_ERR "Card Services release codes do not match\n"); ++ return -1; ++ } ++ ++#ifdef CONFIG_BCM4710 ++ pcmcia_low_level=&bcm4710_pcmcia_ops; ++#else ++#error Unsupported Broadcom BCM47XX board. ++#endif ++ ++ pcmcia_init.handler=bcm47xx_pcmcia_interrupt; ++ ++ if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) { ++ printk(KERN_ERR "Unable to initialize PCMCIA service.\n"); ++ return -EIO; ++ } else { ++ printk("\t%d PCMCIA sockets initialized.\n", socket_count); ++ } ++ ++ pcmcia_socket = ++ kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count, ++ GFP_KERNEL); ++ memset(pcmcia_socket, 0, ++ sizeof(struct bcm47xx_pcmcia_socket) * socket_count); ++ if (!pcmcia_socket) { ++ printk(KERN_ERR "Card Services can't get memory \n"); ++ return -1; ++ } ++ ++ for (i = 0; i < socket_count; i++) { ++ if (pcmcia_low_level->socket_state(i, &state) < 0) { ++ printk(KERN_ERR "Unable to get PCMCIA status\n"); ++ return -EIO; ++ } ++ pcmcia_socket[i].k_state = state; ++ pcmcia_socket[i].cs_state.csc_mask = SS_DETECT; ++ ++ if (i == 0) { ++ pcmcia_socket[i].virt_io = ++ (unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000); ++ /* Substract ioport base which gets added by in/out */ ++ pcmcia_socket[i].virt_io -= mips_io_port_base; ++ pcmcia_socket[i].phys_attr = ++ (unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF); ++ pcmcia_socket[i].phys_mem = ++ (unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF); ++ } else { ++ printk(KERN_ERR "bcm4710: socket 1 not supported\n"); ++ return 1; ++ } ++ } ++ ++ /* Only advertise as many sockets as we can detect: */ ++ if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) { ++ printk(KERN_ERR "Unable to register socket service routine\n"); ++ return -ENXIO; ++ } ++ ++ /* Start the event poll timer. ++ * It will reschedule by itself afterwards. ++ */ ++ bcm47xx_pcmcia_poll_event(0); ++ ++ DEBUG(1, "bcm4710: initialization complete\n"); ++ return 0; ++ ++} ++ ++module_init(bcm47xx_pcmcia_driver_init); ++ ++ ++/* ++ * bcm47xx_pcmcia_driver_shutdown() ++ * ++ * Invokes the low-level kernel service to free IRQs associated with this ++ * socket controller and reset GPIO edge detection. ++ */ ++static void __exit bcm47xx_pcmcia_driver_shutdown(void) ++{ ++ int i; ++ ++ del_timer_sync(&poll_timer); ++ unregister_ss_entry(&bcm47xx_pcmcia_operations); ++ pcmcia_low_level->shutdown(); ++ flush_scheduled_tasks(); ++ for (i = 0; i < socket_count; i++) { ++ if (pcmcia_socket[i].virt_io) ++ iounmap((void *)pcmcia_socket[i].virt_io); ++ if (pcmcia_socket[i].phys_attr) ++ iounmap((void *)pcmcia_socket[i].phys_attr); ++ if (pcmcia_socket[i].phys_mem) ++ iounmap((void *)pcmcia_socket[i].phys_mem); ++ } ++ DEBUG(1, "bcm4710: shutdown complete\n"); ++} ++ ++module_exit(bcm47xx_pcmcia_driver_shutdown); ++ ++/* ++ * bcm47xx_pcmcia_init() ++ * We perform all of the interesting initialization tasks in ++ * bcm47xx_pcmcia_driver_init(). ++ * ++ * Returns: 0 ++ */ ++static int bcm47xx_pcmcia_init(unsigned int sock) ++{ ++ DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock); ++ ++ return 0; ++} ++ ++/* ++ * bcm47xx_pcmcia_suspend() ++ * ++ * We don't currently perform any actions on a suspend. ++ * ++ * Returns: 0 ++ */ ++static int bcm47xx_pcmcia_suspend(unsigned int sock) ++{ ++ DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock); ++ ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_events() ++ * ++ * Helper routine to generate a Card Services event mask based on ++ * state information obtained from the kernel low-level PCMCIA layer ++ * in a recent (and previous) sampling. Updates `prev_state'. ++ * ++ * Returns: an event mask for the given socket state. ++ */ ++static inline unsigned ++bcm47xx_pcmcia_events(struct pcmcia_state *state, ++ struct pcmcia_state *prev_state, ++ unsigned int mask, unsigned int flags) ++{ ++ unsigned int events=0; ++ ++ if (state->bvd1 != prev_state->bvd1) { ++ ++ DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1); ++ ++ events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD; ++ } ++ ++ if (state->bvd2 != prev_state->bvd2) { ++ ++ DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2); ++ ++ events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN; ++ } ++ ++ if (state->detect != prev_state->detect) { ++ ++ DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect); ++ ++ events |= mask & SS_DETECT; ++ } ++ ++ ++ if (state->ready != prev_state->ready) { ++ ++ DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready); ++ ++ events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY); ++ } ++ ++ if (events != 0) { ++ DEBUG(2, "events: %s%s%s%s%s\n", ++ (events & SS_DETECT) ? "DETECT " : "", ++ (events & SS_READY) ? "READY " : "", ++ (events & SS_BATDEAD) ? "BATDEAD " : "", ++ (events & SS_BATWARN) ? "BATWARN " : "", ++ (events & SS_STSCHG) ? "STSCHG " : ""); ++ } ++ ++ *prev_state=*state; ++ return events; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_task_handler() ++ * ++ * Processes serviceable socket events using the "eventd" thread context. ++ * ++ * Event processing (specifically, the invocation of the Card Services event ++ * callback) occurs in this thread rather than in the actual interrupt ++ * handler due to the use of scheduling operations in the PCMCIA core. ++ */ ++static void bcm47xx_pcmcia_task_handler(void *data) ++{ ++ struct pcmcia_state state; ++ int i, events, irq_status; ++ ++ DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__); ++ ++ for (i = 0; i < socket_count; i++) { ++ if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0) ++ printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n"); ++ ++ events = bcm47xx_pcmcia_events(&state, ++ &pcmcia_socket[i].k_state, ++ pcmcia_socket[i].cs_state.csc_mask, ++ pcmcia_socket[i].cs_state.flags); ++ ++ if (pcmcia_socket[i].handler != NULL) { ++ pcmcia_socket[i].handler(pcmcia_socket[i].handler_info, ++ events); ++ } ++ } ++} ++ ++static struct tq_struct bcm47xx_pcmcia_task = { ++ routine: bcm47xx_pcmcia_task_handler ++}; ++ ++ ++/* ++ * bcm47xx_pcmcia_poll_event() ++ * ++ * Let's poll for events in addition to IRQs since IRQ only is unreliable... ++ */ ++static void bcm47xx_pcmcia_poll_event(unsigned long dummy) ++{ ++ DEBUG(4, "%s(): polling for events\n", __FUNCTION__); ++ ++ poll_timer.function = bcm47xx_pcmcia_poll_event; ++ poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD; ++ add_timer(&poll_timer); ++ schedule_task(&bcm47xx_pcmcia_task); ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_interrupt() ++ * ++ * Service routine for socket driver interrupts (requested by the ++ * low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()). ++ * ++ * The actual interrupt-servicing work is performed by ++ * bcm47xx_pcmcia_task(), largely because the Card Services event- ++ * handling code performs scheduling operations which cannot be ++ * executed from within an interrupt context. ++ */ ++static void ++bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs) ++{ ++ DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq); ++ schedule_task(&bcm47xx_pcmcia_task); ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_register_callback() ++ * ++ * Implements the register_callback() operation for the in-kernel ++ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If ++ * the function pointer `handler' is not NULL, remember the callback ++ * location in the state for `sock', and increment the usage counter ++ * for the driver module. (The callback is invoked from the interrupt ++ * service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services ++ * of interesting events.) Otherwise, clear the callback pointer in the ++ * socket state and decrement the module usage count. ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_register_callback(unsigned int sock, ++ void (*handler)(void *, unsigned int), void *info) ++{ ++ if (handler == NULL) { ++ pcmcia_socket[sock].handler = NULL; ++ MOD_DEC_USE_COUNT; ++ } else { ++ MOD_INC_USE_COUNT; ++ pcmcia_socket[sock].handler = handler; ++ pcmcia_socket[sock].handler_info = info; ++ } ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_inquire_socket() ++ * ++ * Implements the inquire_socket() operation for the in-kernel PCMCIA ++ * service (formerly SS_InquireSocket in Card Services). Of note is ++ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of ++ * `cap' to "trick" Card Services into tolerating large "I/O memory" ++ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory ++ * resource database check. (Mapped memory is set up within the socket ++ * driver itself.) ++ * ++ * In conjunction with the STATIC_MAP capability is a new field, ++ * `io_offset', recommended by David Hinds. Rather than go through ++ * the SetIOMap interface (which is not quite suited for communicating ++ * window locations up from the socket driver), we just pass up ++ * an offset which is applied to client-requested base I/O addresses ++ * in alloc_io_space(). ++ * ++ * Returns: 0 on success, -1 if no pin has been configured for `sock' ++ */ ++static int ++bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap) ++{ ++ struct pcmcia_irq_info irq_info; ++ ++ if (sock >= socket_count) { ++ printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock); ++ return -1; ++ } ++ ++ /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the ++ * force_low argument to validate_mem() in rsrc_mgr.c -- since in ++ * general, the mapped * addresses of the PCMCIA memory regions ++ * will not be within 0xffff, setting force_low would be ++ * undesirable. ++ * ++ * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory ++ * resource database; we instead pass up physical address ranges ++ * and allow other parts of Card Services to deal with remapping. ++ * ++ * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but ++ * not 32-bit CardBus devices. ++ */ ++ cap->features = (SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD); ++ ++ irq_info.sock = sock; ++ irq_info.irq = -1; ++ ++ if (pcmcia_low_level->get_irq_info(&irq_info) < 0) { ++ printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock); ++ return -1; ++ } ++ ++ cap->irq_mask = 0; ++ cap->map_size = PAGE_SIZE; ++ cap->pci_irq = irq_info.irq; ++ cap->io_offset = pcmcia_socket[sock].virt_io; ++ ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_status() ++ * ++ * Implements the get_status() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetStatus in Card Services). Essentially just ++ * fills in bits in `status' according to internal driver state or ++ * the value of the voltage detect chipselect register. ++ * ++ * As a debugging note, during card startup, the PCMCIA core issues ++ * three set_socket() commands in a row the first with RESET deasserted, ++ * the second with RESET asserted, and the last with RESET deasserted ++ * again. Following the third set_socket(), a get_status() command will ++ * be issued. The kernel is looking for the SS_READY flag (see ++ * setup_socket(), reset_socket(), and unreset_socket() in cs.c). ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status) ++{ ++ struct pcmcia_state state; ++ ++ ++ if ((pcmcia_low_level->socket_state(sock, &state)) < 0) { ++ printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n"); ++ return -1; ++ } ++ ++ pcmcia_socket[sock].k_state = state; ++ ++ *status = state.detect ? SS_DETECT : 0; ++ ++ *status |= state.ready ? SS_READY : 0; ++ ++ /* The power status of individual sockets is not available ++ * explicitly from the hardware, so we just remember the state ++ * and regurgitate it upon request: ++ */ ++ *status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0; ++ ++ if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD) ++ *status |= state.bvd1 ? SS_STSCHG : 0; ++ else { ++ if (state.bvd1 == 0) ++ *status |= SS_BATDEAD; ++ else if (state.bvd2 == 0) ++ *status |= SS_BATWARN; ++ } ++ ++ *status |= state.vs_3v ? SS_3VCARD : 0; ++ ++ *status |= state.vs_Xv ? SS_XVCARD : 0; ++ ++ DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n", ++ (*status&SS_DETECT)?"DETECT ":"", ++ (*status&SS_READY)?"READY ":"", ++ (*status&SS_BATDEAD)?"BATDEAD ":"", ++ (*status&SS_BATWARN)?"BATWARN ":"", ++ (*status&SS_POWERON)?"POWERON ":"", ++ (*status&SS_STSCHG)?"STSCHG ":"", ++ (*status&SS_3VCARD)?"3VCARD ":"", ++ (*status&SS_XVCARD)?"XVCARD ":""); ++ ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_socket() ++ * ++ * Implements the get_socket() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetSocket in Card Services). Not a very ++ * exciting routine. ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state) ++{ ++ DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock); ++ ++ /* This information was given to us in an earlier call to set_socket(), ++ * so we're just regurgitating it here: ++ */ ++ *state = pcmcia_socket[sock].cs_state; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_set_socket() ++ * ++ * Implements the set_socket() operation for the in-kernel PCMCIA ++ * service (formerly SS_SetSocket in Card Services). We more or ++ * less punt all of this work and let the kernel handle the details ++ * of power configuration, reset, &c. We also record the value of ++ * `state' in order to regurgitate it to the PCMCIA core later. ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state) ++{ ++ struct pcmcia_configure configure; ++ ++ DEBUG(2, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n" ++ "\tVcc %d Vpp %d irq %d\n", ++ (state->csc_mask == 0) ? "" : "", ++ (state->csc_mask & SS_DETECT) ? "DETECT " : "", ++ (state->csc_mask & SS_READY) ? "READY " : "", ++ (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "", ++ (state->csc_mask & SS_BATWARN) ? "BATWARN " : "", ++ (state->csc_mask & SS_STSCHG) ? "STSCHG " : "", ++ (state->flags == 0) ? "" : "", ++ (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "", ++ (state->flags & SS_IOCARD) ? "IOCARD " : "", ++ (state->flags & SS_RESET) ? "RESET " : "", ++ (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "", ++ (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "", ++ state->Vcc, state->Vpp, state->io_irq); ++ ++ configure.sock = sock; ++ configure.vcc = state->Vcc; ++ configure.vpp = state->Vpp; ++ configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0; ++ configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0; ++ configure.reset = (state->flags & SS_RESET) ? 1 : 0; ++ ++ if (pcmcia_low_level->configure_socket(&configure) < 0) { ++ printk(KERN_ERR "Unable to configure socket %u\n", sock); ++ return -1; ++ } ++ ++ pcmcia_socket[sock].cs_state = *state; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_io_map() ++ * ++ * Implements the get_io_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetIOMap in Card Services). Just returns an ++ * I/O map descriptor which was assigned earlier by a set_io_map(). ++ * ++ * Returns: 0 on success, -1 if the map index was out of range ++ */ ++static int ++bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map) ++{ ++ DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock); ++ ++ if (map->map >= MAX_IO_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ *map = pcmcia_socket[sock].io_map[map->map]; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_set_io_map() ++ * ++ * Implements the set_io_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_SetIOMap in Card Services). We configure ++ * the map speed as requested, but override the address ranges ++ * supplied by Card Services. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++int ++bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) ++{ ++ unsigned int speed; ++ unsigned long start; ++ ++ DEBUG(2, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n" ++ "\tflags: %s%s%s%s%s%s%s%s\n", ++ map->map, map->speed, map->start, map->stop, ++ (map->flags == 0) ? "" : "", ++ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", ++ (map->flags & MAP_16BIT) ? "16BIT " : "", ++ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", ++ (map->flags & MAP_0WS) ? "0WS " : "", ++ (map->flags & MAP_WRPROT) ? "WRPROT " : "", ++ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "", ++ (map->flags & MAP_PREFETCH) ? "PREFETCH " : ""); ++ ++ if (map->map >= MAX_IO_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ if (map->flags & MAP_ACTIVE) { ++ speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED; ++ pcmcia_socket[sock].speed_io = speed; ++ } ++ ++ start = map->start; ++ ++ if (map->stop == 1) { ++ map->stop = PAGE_SIZE - 1; ++ } ++ ++ map->start = pcmcia_socket[sock].virt_io; ++ map->stop = map->start + (map->stop - start); ++ pcmcia_socket[sock].io_map[map->map] = *map; ++ DEBUG(2, "set_io_map %d start %x stop %x\n", ++ map->map, map->start, map->stop); ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_mem_map() ++ * ++ * Implements the get_mem_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetMemMap in Card Services). Just returns a ++ * memory map descriptor which was assigned earlier by a ++ * set_mem_map() request. ++ * ++ * Returns: 0 on success, -1 if the map index was out of range ++ */ ++static int ++bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map) ++{ ++ DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock); ++ ++ if (map->map >= MAX_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ *map = pcmcia_socket[sock].mem_map[map->map]; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_set_mem_map() ++ * ++ * Implements the set_mem_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_SetMemMap in Card Services). We configure ++ * the map speed as requested, but override the address ranges ++ * supplied by Card Services. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++static int ++bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map) ++{ ++ unsigned int speed; ++ unsigned long start; ++ u_long flags; ++ ++ if (map->map >= MAX_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ DEBUG(2, "\tmap %u speed %u\n\tsys_start %#lx\n" ++ "\tsys_stop %#lx\n\tcard_start %#x\n" ++ "\tflags: %s%s%s%s%s%s%s%s\n", ++ map->map, map->speed, map->sys_start, map->sys_stop, ++ map->card_start, (map->flags == 0) ? "" : "", ++ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", ++ (map->flags & MAP_16BIT) ? "16BIT " : "", ++ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", ++ (map->flags & MAP_0WS) ? "0WS " : "", ++ (map->flags & MAP_WRPROT) ? "WRPROT " : "", ++ (map->flags & MAP_ATTRIB) ? "ATTRIB " : "", ++ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : ""); ++ ++ if (map->flags & MAP_ACTIVE) { ++ /* When clients issue RequestMap, the access speed is not always ++ * properly configured: ++ */ ++ speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED; ++ ++ /* TBD */ ++ if (map->flags & MAP_ATTRIB) { ++ pcmcia_socket[sock].speed_attr = speed; ++ } else { ++ pcmcia_socket[sock].speed_mem = speed; ++ } ++ } ++ ++ save_flags(flags); ++ cli(); ++ start = map->sys_start; ++ ++ if (map->sys_stop == 0) ++ map->sys_stop = PAGE_SIZE - 1; ++ ++ if (map->flags & MAP_ATTRIB) { ++ map->sys_start = pcmcia_socket[sock].phys_attr + ++ map->card_start; ++ } else { ++ map->sys_start = pcmcia_socket[sock].phys_mem + ++ map->card_start; ++ } ++ ++ map->sys_stop = map->sys_start + (map->sys_stop - start); ++ pcmcia_socket[sock].mem_map[map->map] = *map; ++ restore_flags(flags); ++ DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n", ++ map->map, map->sys_start, map->sys_stop, ++ map->card_start); ++ return 0; ++} ++ ++ ++#if defined(CONFIG_PROC_FS) ++ ++/* ++ * bcm47xx_pcmcia_proc_setup() ++ * ++ * Implements the proc_setup() operation for the in-kernel PCMCIA ++ * service (formerly SS_ProcSetup in Card Services). ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++static void ++bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base) ++{ ++ struct proc_dir_entry *entry; ++ ++ if ((entry = create_proc_entry("status", 0, base)) == NULL) { ++ printk(KERN_ERR "Unable to install \"status\" procfs entry\n"); ++ return; ++ } ++ ++ entry->read_proc = bcm47xx_pcmcia_proc_status; ++ entry->data = (void *)sock; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_proc_status() ++ * ++ * Implements the /proc/bus/pccard/??/status file. ++ * ++ * Returns: the number of characters added to the buffer ++ */ ++static int ++bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos, ++ int count, int *eof, void *data) ++{ ++ char *p = buf; ++ unsigned int sock = (unsigned int)data; ++ ++ p += sprintf(p, "k_flags : %s%s%s%s%s%s%s\n", ++ pcmcia_socket[sock].k_state.detect ? "detect " : "", ++ pcmcia_socket[sock].k_state.ready ? "ready " : "", ++ pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "", ++ pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "", ++ pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "", ++ pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "", ++ pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : ""); ++ ++ p += sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n", ++ pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "", ++ pcmcia_socket[sock].k_state.ready ? "SS_READY " : "", ++ pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "", ++ (pcmcia_socket[sock].cs_state.flags & SS_IOCARD && ++ pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "", ++ ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 && ++ (pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "", ++ ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 && ++ (pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "", ++ pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "", ++ pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : ""); ++ ++ p += sprintf(p, "mask : %s%s%s%s%s\n", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : ""); ++ ++ p += sprintf(p, "cs_flags : %s%s%s%s%s\n", ++ pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ? ++ "SS_PWR_AUTO " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? ++ "SS_IOCARD " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_RESET ? ++ "SS_RESET " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ? ++ "SS_SPKR_ENA " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ? ++ "SS_OUTPUT_ENA " : ""); ++ ++ p += sprintf(p, "Vcc : %d\n", pcmcia_socket[sock].cs_state.Vcc); ++ p += sprintf(p, "Vpp : %d\n", pcmcia_socket[sock].cs_state.Vpp); ++ p += sprintf(p, "irq : %d\n", pcmcia_socket[sock].cs_state.io_irq); ++ p += sprintf(p, "I/O : %u\n", pcmcia_socket[sock].speed_io); ++ p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr); ++ p += sprintf(p, "common : %u\n", pcmcia_socket[sock].speed_mem); ++ return p-buf; ++} ++ ++ ++#endif /* defined(CONFIG_PROC_FS) */ +diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c +--- linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c 2005-12-16 23:39:11.368863250 +0100 +@@ -0,0 +1,266 @@ ++/* ++ * BCM4710 specific pcmcia routines. ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: bcm4710_pcmcia.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "cs_internal.h" ++ ++#include ++#include ++#include ++ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "bcm4710pcmcia.h" ++ ++/* Use a static var for irq dev_id */ ++static int bcm47xx_pcmcia_dev_id; ++ ++/* Do we think we have a card or not? */ ++static int bcm47xx_pcmcia_present = 0; ++ ++ ++static void bcm4710_pcmcia_reset(void) ++{ ++ extifregs_t *eir; ++ unsigned long s; ++ uint32 out0, out1, outen; ++ ++ ++ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); ++ ++ save_and_cli(s); ++ ++ /* Use gpio7 to reset the pcmcia slot */ ++ outen = readl(&eir->gpio[0].outen); ++ outen |= BCM47XX_PCMCIA_RESET; ++ out0 = readl(&eir->gpio[0].out); ++ out0 &= ~(BCM47XX_PCMCIA_RESET); ++ out1 = out0 | BCM47XX_PCMCIA_RESET; ++ ++ writel(out0, &eir->gpio[0].out); ++ writel(outen, &eir->gpio[0].outen); ++ mdelay(1); ++ writel(out1, &eir->gpio[0].out); ++ mdelay(1); ++ writel(out0, &eir->gpio[0].out); ++ ++ restore_flags(s); ++} ++ ++ ++static int bcm4710_pcmcia_init(struct pcmcia_init *init) ++{ ++ struct pci_dev *pdev; ++ extifregs_t *eir; ++ uint32 outen, intp, intm, tmp; ++ uint16 *attrsp; ++ int rc = 0, i; ++ extern unsigned long bcm4710_cpu_cycle; ++ ++ ++ if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_EXTIF, NULL))) { ++ printk(KERN_ERR "bcm4710_pcmcia: extif not found\n"); ++ return -ENODEV; ++ } ++ eir = (extifregs_t *) ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); ++ ++ /* Initialize the pcmcia i/f: 16bit no swap */ ++ writel(CF_EM_PCMCIA | CF_DS | CF_EN, &eir->pcmcia_config); ++ ++#ifdef notYet ++ ++ /* Set the timing for memory accesses */ ++ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ ++ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ ++ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ ++ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ ++ writel(tmp, &eir->pcmcia_memwait); /* 0x01020a0c for a 100Mhz clock */ ++ ++ /* Set the timing for I/O accesses */ ++ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ ++ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ ++ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ ++ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ ++ writel(tmp, &eir->pcmcia_iowait); /* 0x01020a0c for a 100Mhz clock */ ++ ++ /* Set the timing for attribute accesses */ ++ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ ++ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ ++ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ ++ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ ++ writel(tmp, &eir->pcmcia_attrwait); /* 0x01020a0c for a 100Mhz clock */ ++ ++#endif ++ /* Make sure gpio0 and gpio5 are inputs */ ++ outen = readl(&eir->gpio[0].outen); ++ outen &= ~(BCM47XX_PCMCIA_WP | BCM47XX_PCMCIA_STSCHG | BCM47XX_PCMCIA_RESET); ++ writel(outen, &eir->gpio[0].outen); ++ ++ /* Issue a reset to the pcmcia socket */ ++ bcm4710_pcmcia_reset(); ++ ++#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS ++ /* Setup gpio5 to be the STSCHG interrupt */ ++ intp = readl(&eir->gpiointpolarity); ++ writel(intp | BCM47XX_PCMCIA_STSCHG, &eir->gpiointpolarity); /* Active low */ ++ intm = readl(&eir->gpiointmask); ++ writel(intm | BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Enable it */ ++#endif ++ ++ DEBUG(2, "bcm4710_pcmcia after reset:\n"); ++ DEBUG(2, "\textstatus\t= 0x%08x:\n", readl(&eir->extstatus)); ++ DEBUG(2, "\tpcmcia_config\t= 0x%08x:\n", readl(&eir->pcmcia_config)); ++ DEBUG(2, "\tpcmcia_memwait\t= 0x%08x:\n", readl(&eir->pcmcia_memwait)); ++ DEBUG(2, "\tpcmcia_attrwait\t= 0x%08x:\n", readl(&eir->pcmcia_attrwait)); ++ DEBUG(2, "\tpcmcia_iowait\t= 0x%08x:\n", readl(&eir->pcmcia_iowait)); ++ DEBUG(2, "\tgpioin\t\t= 0x%08x:\n", readl(&eir->gpioin)); ++ DEBUG(2, "\tgpio_outen0\t= 0x%08x:\n", readl(&eir->gpio[0].outen)); ++ DEBUG(2, "\tgpio_out0\t= 0x%08x:\n", readl(&eir->gpio[0].out)); ++ DEBUG(2, "\tgpiointpolarity\t= 0x%08x:\n", readl(&eir->gpiointpolarity)); ++ DEBUG(2, "\tgpiointmask\t= 0x%08x:\n", readl(&eir->gpiointmask)); ++ ++#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS ++ /* Request pcmcia interrupt */ ++ rc = request_irq(BCM47XX_PCMCIA_IRQ, init->handler, SA_INTERRUPT, ++ "PCMCIA Interrupt", &bcm47xx_pcmcia_dev_id); ++#endif ++ ++ attrsp = (uint16 *)ioremap_nocache(EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF), 0x1000); ++ tmp = readw(&attrsp[0]); ++ DEBUG(2, "\tattr[0] = 0x%04x\n", tmp); ++ if ((tmp == 0x7fff) || (tmp == 0x7f00)) { ++ bcm47xx_pcmcia_present = 0; ++ } else { ++ bcm47xx_pcmcia_present = 1; ++ } ++ ++ /* There's only one socket */ ++ return 1; ++} ++ ++static int bcm4710_pcmcia_shutdown(void) ++{ ++ extifregs_t *eir; ++ uint32 intm; ++ ++ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); ++ ++ /* Disable the pcmcia i/f */ ++ writel(0, &eir->pcmcia_config); ++ ++ /* Reset gpio's */ ++ intm = readl(&eir->gpiointmask); ++ writel(intm & ~BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Disable it */ ++ ++ free_irq(BCM47XX_PCMCIA_IRQ, &bcm47xx_pcmcia_dev_id); ++ ++ return 0; ++} ++ ++static int ++bcm4710_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) ++{ ++ extifregs_t *eir; ++ ++ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); ++ ++ ++ if (sock != 0) { ++ printk(KERN_ERR "bcm4710 socket_state bad sock %d\n", sock); ++ return -1; ++ } ++ ++ if (bcm47xx_pcmcia_present) { ++ state->detect = 1; ++ state->ready = 1; ++ state->bvd1 = 1; ++ state->bvd2 = 1; ++ state->wrprot = (readl(&eir->gpioin) & BCM47XX_PCMCIA_WP) == BCM47XX_PCMCIA_WP; ++ state->vs_3v = 0; ++ state->vs_Xv = 0; ++ } else { ++ state->detect = 0; ++ state->ready = 0; ++ } ++ ++ return 1; ++} ++ ++ ++static int bcm4710_pcmcia_get_irq_info(struct pcmcia_irq_info *info) ++{ ++ if (info->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1; ++ ++ info->irq = BCM47XX_PCMCIA_IRQ; ++ ++ return 0; ++} ++ ++ ++static int ++bcm4710_pcmcia_configure_socket(const struct pcmcia_configure *configure) ++{ ++ if (configure->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1; ++ ++ ++ DEBUG(2, "Vcc %dV Vpp %dV output %d speaker %d reset %d\n", configure->vcc, ++ configure->vpp, configure->output, configure->speaker, configure->reset); ++ ++ if ((configure->vcc != 50) || (configure->vpp != 50)) { ++ printk("%s: bad Vcc/Vpp (%d:%d)\n", __FUNCTION__, configure->vcc, ++ configure->vpp); ++ } ++ ++ if (configure->reset) { ++ /* Issue a reset to the pcmcia socket */ ++ DEBUG(1, "%s: Reseting socket\n", __FUNCTION__); ++ bcm4710_pcmcia_reset(); ++ } ++ ++ ++ return 0; ++} ++ ++struct pcmcia_low_level bcm4710_pcmcia_ops = { ++ bcm4710_pcmcia_init, ++ bcm4710_pcmcia_shutdown, ++ bcm4710_pcmcia_socket_state, ++ bcm4710_pcmcia_get_irq_info, ++ bcm4710_pcmcia_configure_socket ++}; ++ +diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h +--- linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h 2005-12-16 23:39:11.368863250 +0100 +@@ -0,0 +1,118 @@ ++/* ++ * ++ * bcm47xx pcmcia driver ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Based on sa1100.h and include/asm-arm/arch-sa1100/pcmica.h ++ * from www.handhelds.org, ++ * and au1000_generic.c from oss.sgi.com. ++ * ++ * $Id: bcm4710pcmcia.h,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++ ++#if !defined(_BCM4710PCMCIA_H) ++#define _BCM4710PCMCIA_H ++ ++#include ++#include ++#include ++#include ++#include "cs_internal.h" ++ ++ ++/* The 47xx can only support one socket */ ++#define BCM47XX_PCMCIA_MAX_SOCK 1 ++ ++/* In the bcm947xx gpio's are used for some pcmcia functions */ ++#define BCM47XX_PCMCIA_WP 0x01 /* Bit 0 is WP input */ ++#define BCM47XX_PCMCIA_STSCHG 0x20 /* Bit 5 is STSCHG input/interrupt */ ++#define BCM47XX_PCMCIA_RESET 0x80 /* Bit 7 is RESET */ ++ ++#define BCM47XX_PCMCIA_IRQ 2 ++ ++/* The socket driver actually works nicely in interrupt-driven form, ++ * so the (relatively infrequent) polling is "just to be sure." ++ */ ++#define BCM47XX_PCMCIA_POLL_PERIOD (2 * HZ) ++ ++#define BCM47XX_PCMCIA_IO_SPEED (255) ++#define BCM47XX_PCMCIA_MEM_SPEED (300) ++ ++ ++struct pcmcia_state { ++ unsigned detect: 1, ++ ready: 1, ++ bvd1: 1, ++ bvd2: 1, ++ wrprot: 1, ++ vs_3v: 1, ++ vs_Xv: 1; ++}; ++ ++ ++struct pcmcia_configure { ++ unsigned sock: 8, ++ vcc: 8, ++ vpp: 8, ++ output: 1, ++ speaker: 1, ++ reset: 1; ++}; ++ ++struct pcmcia_irq_info { ++ unsigned int sock; ++ unsigned int irq; ++}; ++ ++/* This structure encapsulates per-socket state which we might need to ++ * use when responding to a Card Services query of some kind. ++ */ ++struct bcm47xx_pcmcia_socket { ++ socket_state_t cs_state; ++ struct pcmcia_state k_state; ++ unsigned int irq; ++ void (*handler)(void *, unsigned int); ++ void *handler_info; ++ pccard_io_map io_map[MAX_IO_WIN]; ++ pccard_mem_map mem_map[MAX_WIN]; ++ ioaddr_t virt_io, phys_attr, phys_mem; ++ unsigned short speed_io, speed_attr, speed_mem; ++}; ++ ++struct pcmcia_init { ++ void (*handler)(int irq, void *dev, struct pt_regs *regs); ++}; ++ ++struct pcmcia_low_level { ++ int (*init)(struct pcmcia_init *); ++ int (*shutdown)(void); ++ int (*socket_state)(unsigned sock, struct pcmcia_state *); ++ int (*get_irq_info)(struct pcmcia_irq_info *); ++ int (*configure_socket)(const struct pcmcia_configure *); ++}; ++ ++extern struct pcmcia_low_level bcm47xx_pcmcia_ops; ++ ++/* I/O pins replacing memory pins ++ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75) ++ * ++ * These signals change meaning when going from memory-only to ++ * memory-or-I/O interface: ++ */ ++#define iostschg bvd1 ++#define iospkr bvd2 ++ ++ ++/* ++ * Declaration for implementation specific low_level operations. ++ */ ++extern struct pcmcia_low_level bcm4710_pcmcia_ops; ++ ++#endif /* !defined(_BCM4710PCMCIA_H) */ +diff -Nur linux-2.4.32/drivers/pcmcia/Makefile linux-2.4.32-brcm/drivers/pcmcia/Makefile +--- linux-2.4.32/drivers/pcmcia/Makefile 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/Makefile 2005-12-16 23:39:11.364863000 +0100 +@@ -65,6 +65,10 @@ + au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o + au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o + ++obj-$(CONFIG_PCMCIA_BCM4710) += bcm4710_ss.o ++bcm4710_ss-objs := bcm4710_generic.o ++bcm4710_ss-objs += bcm4710_pcmcia.o ++ + obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o + obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o + obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o +@@ -102,5 +106,8 @@ + au1x00_ss.o: $(au1000_ss-objs-y) + $(LD) -r -o $@ $(au1000_ss-objs-y) + ++bcm4710_ss.o: $(bcm4710_ss-objs) ++ $(LD) -r -o $@ $(bcm4710_ss-objs) ++ + yenta_socket.o: $(yenta_socket-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) +diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm-mips/bootinfo.h +--- linux-2.4.32/include/asm-mips/bootinfo.h 2004-02-18 14:36:32.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/bootinfo.h 2005-12-16 23:39:11.400865250 +0100 +@@ -37,6 +37,7 @@ + #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ + #define MACH_GROUP_LASAT 21 + #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ ++#define MACH_GROUP_BRCM 23 /* Broadcom */ + + /* + * Valid machtype values for group unknown (low order halfword of mips_machtype) +@@ -194,6 +195,15 @@ + #define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ + + /* ++ * Valid machtypes for group Broadcom ++ */ ++#define MACH_BCM93725 0 ++#define MACH_BCM93725_VJ 1 ++#define MACH_BCM93730 2 ++#define MACH_BCM947XX 3 ++#define MACH_BCM933XX 4 ++ ++/* + * Valid machtype for group TITAN + */ + #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ +diff -Nur linux-2.4.32/include/asm-mips/cpu.h linux-2.4.32-brcm/include/asm-mips/cpu.h +--- linux-2.4.32/include/asm-mips/cpu.h 2005-01-19 15:10:11.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/cpu.h 2005-12-16 23:39:11.412866000 +0100 +@@ -22,6 +22,11 @@ + spec. + */ + ++#define PRID_COPT_MASK 0xff000000 ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++#define PRID_REV_MASK 0x000000ff ++ + #define PRID_COMP_LEGACY 0x000000 + #define PRID_COMP_MIPS 0x010000 + #define PRID_COMP_BROADCOM 0x020000 +@@ -58,6 +63,7 @@ + #define PRID_IMP_RM7000 0x2700 + #define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ + #define PRID_IMP_RM9000 0x3400 ++#define PRID_IMP_BCM4710 0x4000 + #define PRID_IMP_R5432 0x5400 + #define PRID_IMP_R5500 0x5500 + #define PRID_IMP_4KC 0x8000 +@@ -66,10 +72,16 @@ + #define PRID_IMP_4KEC 0x8400 + #define PRID_IMP_4KSC 0x8600 + #define PRID_IMP_25KF 0x8800 ++#define PRID_IMP_BCM3302 0x9000 ++#define PRID_IMP_BCM3303 0x9100 + #define PRID_IMP_24K 0x9300 + + #define PRID_IMP_UNKNOWN 0xff00 + ++#define BCM330X(id) \ ++ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ ++ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) ++ + /* + * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE + */ +@@ -174,7 +186,9 @@ + #define CPU_AU1550 57 + #define CPU_24K 58 + #define CPU_AU1200 59 +-#define CPU_LAST 59 ++#define CPU_BCM4710 60 ++#define CPU_BCM3302 61 ++#define CPU_LAST 61 + + /* + * ISA Level encodings +diff -Nur linux-2.4.32/include/asm-mips/r4kcache.h linux-2.4.32-brcm/include/asm-mips/r4kcache.h +--- linux-2.4.32/include/asm-mips/r4kcache.h 2004-02-18 14:36:32.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/r4kcache.h 2005-12-16 23:39:11.416866250 +0100 +@@ -567,4 +567,17 @@ + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); + } + ++extern inline void fill_icache_line(unsigned long addr) ++{ ++ __asm__ __volatile__( ++ ".set noreorder\n\t" ++ ".set mips3\n\t" ++ "cache %1, (%0)\n\t" ++ ".set mips0\n\t" ++ ".set reorder" ++ : ++ : "r" (addr), ++ "i" (Fill)); ++} ++ + #endif /* __ASM_R4KCACHE_H */ +diff -Nur linux-2.4.32/include/asm-mips/serial.h linux-2.4.32-brcm/include/asm-mips/serial.h +--- linux-2.4.32/include/asm-mips/serial.h 2005-01-19 15:10:12.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/serial.h 2005-12-16 23:39:11.428867000 +0100 +@@ -223,6 +223,13 @@ + #define TXX927_SERIAL_PORT_DEFNS + #endif + ++#ifdef CONFIG_BCM947XX ++/* reserve 4 ports to be configured at runtime */ ++#define BCM947XX_SERIAL_PORT_DEFNS { 0, }, { 0, }, { 0, }, { 0, }, ++#else ++#define BCM947XX_SERIAL_PORT_DEFNS ++#endif ++ + #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT + #define STD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ +@@ -470,6 +477,7 @@ + #define SERIAL_PORT_DFNS \ + ATLAS_SERIAL_PORT_DEFNS \ + AU1000_SERIAL_PORT_DEFNS \ ++ BCM947XX_SERIAL_PORT_DEFNS \ + COBALT_SERIAL_PORT_DEFNS \ + DDB5477_SERIAL_PORT_DEFNS \ + EV96100_SERIAL_PORT_DEFNS \ +diff -Nur linux-2.4.32/init/do_mounts.c linux-2.4.32-brcm/init/do_mounts.c +--- linux-2.4.32/init/do_mounts.c 2003-11-28 19:26:21.000000000 +0100 ++++ linux-2.4.32-brcm/init/do_mounts.c 2005-12-16 23:39:11.504871750 +0100 +@@ -253,7 +253,13 @@ + { "ftlb", 0x2c08 }, + { "ftlc", 0x2c10 }, + { "ftld", 0x2c18 }, ++#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO) + { "mtdblock", 0x1f00 }, ++ { "mtdblock0",0x1f00 }, ++ { "mtdblock1",0x1f01 }, ++ { "mtdblock2",0x1f02 }, ++ { "mtdblock3",0x1f03 }, ++#endif + { "nb", 0x2b00 }, + { NULL, 0 } + }; diff --git a/openwrt/target/linux/brcm-2.4/patches/002-wl_fix.patch b/openwrt/target/linux/brcm-2.4/patches/002-wl_fix.patch new file mode 100644 index 0000000000..ffb82aad35 --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/patches/002-wl_fix.patch @@ -0,0 +1,346 @@ +diff -Nur linux-2.4.30/include/linux/netdevice.h linux-2.4.30-wl-fix/include/linux/netdevice.h +--- linux-2.4.30/include/linux/netdevice.h 2004-11-17 12:54:22.000000000 +0100 ++++ linux-2.4.30-wl-fix/include/linux/netdevice.h 2005-05-09 16:31:08.000000000 +0200 +@@ -297,7 +297,7 @@ + * See for details. Jean II */ + struct iw_handler_def * wireless_handlers; + +- struct ethtool_ops *ethtool_ops; ++ + + /* + * This marks the end of the "visible" part of the structure. All +@@ -352,8 +355,8 @@ + + struct Qdisc *qdisc; + struct Qdisc *qdisc_sleeping; ++ struct Qdisc *qdisc_list; + struct Qdisc *qdisc_ingress; +- struct list_head qdisc_list; + unsigned long tx_queue_len; /* Max frames per queue allowed */ + + /* hard_start_xmit synchronizer */ +@@ -453,6 +460,7 @@ + /* this will get initialized at each interface type init routine */ + struct divert_blk *divert; + #endif /* CONFIG_NET_DIVERT */ ++ struct ethtool_ops *ethtool_ops; + }; + + /* 2.6 compatibility */ +diff -Nur linux-2.4.30/include/linux/skbuff.h linux-2.4.30-wl-fix/include/linux/skbuff.h +--- linux-2.4.30/include/linux/skbuff.h 2005-04-04 03:42:20.000000000 +0200 ++++ linux-2.4.30-wl-fix/include/linux/skbuff.h 2005-05-08 00:50:55.000000000 +0200 +@@ -135,10 +135,6 @@ + struct sock *sk; /* Socket we are owned by */ + struct timeval stamp; /* Time we arrived */ + struct net_device *dev; /* Device we arrived on/are leaving by */ +- struct net_device *real_dev; /* For support of point to point protocols +- (e.g. 802.3ad) over bonding, we must save the +- physical device that got the packet before +- replacing skb->dev with the virtual device. */ + + /* Transport layer header */ + union +@@ -219,6 +215,10 @@ + #ifdef CONFIG_NET_SCHED + __u32 tc_index; /* traffic control index */ + #endif ++ struct net_device *real_dev; /* For support of point to point protocols ++ (e.g. 802.3ad) over bonding, we must save the ++ physical device that got the packet before ++ replacing skb->dev with the virtual device. */ + }; + + #ifdef __KERNEL__ +diff -Nur linux-2.4.30/include/net/pkt_sched.h linux-2.4.30-wl-fix/include/net/pkt_sched.h +--- linux-2.4.30/include/net/pkt_sched.h 2004-11-17 12:54:22.000000000 +0100 ++++ linux-2.4.30-wl-fix/include/net/pkt_sched.h 2005-05-08 01:05:48.000000000 +0200 +@@ -59,8 +59,11 @@ + int (*enqueue)(struct sk_buff *, struct Qdisc *); + struct sk_buff * (*dequeue)(struct Qdisc *); + int (*requeue)(struct sk_buff *, struct Qdisc *); +- unsigned int (*drop)(struct Qdisc *); +- ++#ifdef CONFIG_BCM4710 ++ int (*drop)(struct Qdisc *); ++#else ++ unsigned int (*drop)(struct Qdisc *); ++#endif + int (*init)(struct Qdisc *, struct rtattr *arg); + void (*reset)(struct Qdisc *); + void (*destroy)(struct Qdisc *); +@@ -80,12 +83,19 @@ + #define TCQ_F_THROTTLED 2 + #define TCQ_F_INGRESS 4 + struct Qdisc_ops *ops; ++#ifdef CONFIG_BCM4710 ++ struct Qdisc *next; ++#endif + u32 handle; +- u32 parent; ++#ifndef CONFIG_BCM4710 ++ u32 parent; ++#endif + atomic_t refcnt; + struct sk_buff_head q; + struct net_device *dev; +- struct list_head list; ++#ifndef CONFIG_BCM4710 ++ struct list_head list; ++#endif + + struct tc_stats stats; + int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q); +diff -Nur linux-2.4.30/net/core/dev.c linux-2.4.30-wl-fix/net/core/dev.c +--- linux-2.4.30/net/core/dev.c 2005-04-04 03:42:20.000000000 +0200 ++++ linux-2.4.30-wl-fix/net/core/dev.c 2005-05-08 00:51:08.000000000 +0200 +@@ -2311,6 +2311,7 @@ + } + return ret; + ++#ifndef CONFIG_BCM4710 + case SIOCETHTOOL: + dev_load(ifr.ifr_name); + rtnl_lock(); +@@ -2324,6 +2325,7 @@ + ret = -EFAULT; + } + return ret; ++#endif + + /* + * These ioctl calls: +diff -Nur linux-2.4.30/net/core/Makefile linux-2.4.30-wl-fix/net/core/Makefile +--- linux-2.4.30/net/core/Makefile 2004-11-17 12:54:22.000000000 +0100 ++++ linux-2.4.30-wl-fix/net/core/Makefile 2005-05-08 00:51:02.000000000 +0200 +@@ -9,7 +9,11 @@ + + O_TARGET := core.o + ++ifeq ($(CONFIG_BCM4710),y) ++export-objs := netfilter.o profile.o neighbour.o ++else + export-objs := netfilter.o profile.o ethtool.o neighbour.o ++endif + + obj-y := sock.o skbuff.o iovec.o datagram.o scm.o + +@@ -21,8 +25,13 @@ + + obj-$(CONFIG_FILTER) += filter.o + ++ifeq ($(CONFIG_BCM4710),y) ++obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o \ ++ rtnetlink.o utils.o ++else + obj-$(CONFIG_NET) += dev.o ethtool.o dev_mcast.o dst.o neighbour.o \ + rtnetlink.o utils.o ++endif + + obj-$(CONFIG_NETFILTER) += netfilter.o + obj-$(CONFIG_NET_DIVERT) += dv.o +diff -Nur linux-2.4.30/net/sched/sch_api.c linux-2.4.30-wl-fix/net/sched/sch_api.c +--- linux-2.4.30/net/sched/sch_api.c 2004-11-17 12:54:22.000000000 +0100 ++++ linux-2.4.30-wl-fix/net/sched/sch_api.c 2005-05-08 00:51:14.000000000 +0200 +@@ -194,11 +194,12 @@ + { + struct Qdisc *q; + +- list_for_each_entry(q, &dev->qdisc_list, list) { ++ for (q = dev->qdisc_list; q; q = q->next) { + if (q->handle == handle) + return q; + } + return NULL; ++ + } + + struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) +@@ -371,8 +372,6 @@ + unsigned long cl = cops->get(parent, classid); + if (cl) { + err = cops->graft(parent, cl, new, old); +- if (new) +- new->parent = classid; + cops->put(parent, cl); + } + } +@@ -427,7 +426,6 @@ + + memset(sch, 0, size); + +- INIT_LIST_HEAD(&sch->list); + skb_queue_head_init(&sch->q); + + if (handle == TC_H_INGRESS) +@@ -453,7 +451,8 @@ + + if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { + write_lock(&qdisc_tree_lock); +- list_add_tail(&sch->list, &dev->qdisc_list); ++ sch->next = dev->qdisc_list; ++ dev->qdisc_list = sch; + write_unlock(&qdisc_tree_lock); + #ifdef CONFIG_NET_ESTIMATOR + if (tca[TCA_RATE-1]) +@@ -808,19 +807,16 @@ + if (idx > s_idx) + s_q_idx = 0; + read_lock(&qdisc_tree_lock); +- q_idx = 0; +- list_for_each_entry(q, &dev->qdisc_list, list) { +- if (q_idx < s_q_idx) { +- q_idx++; +- continue; +- } +- if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid, +- cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { +- read_unlock(&qdisc_tree_lock); +- goto done; +- } +- q_idx++; +- } ++ for (q = dev->qdisc_list, q_idx = 0; q; ++ q = q->next, q_idx++) { ++ if (q_idx < s_q_idx) ++ continue; ++ if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid, ++ cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { ++ read_unlock(&qdisc_tree_lock); ++ goto done; ++ } ++ } + read_unlock(&qdisc_tree_lock); + } + +@@ -1033,27 +1029,24 @@ + t = 0; + + read_lock(&qdisc_tree_lock); +- list_for_each_entry(q, &dev->qdisc_list, list) { +- if (t < s_t || !q->ops->cl_ops || +- (tcm->tcm_parent && +- TC_H_MAJ(tcm->tcm_parent) != q->handle)) { +- t++; +- continue; +- } +- if (t > s_t) +- memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); +- arg.w.fn = qdisc_class_dump; +- arg.skb = skb; +- arg.cb = cb; +- arg.w.stop = 0; +- arg.w.skip = cb->args[1]; +- arg.w.count = 0; +- q->ops->cl_ops->walk(q, &arg.w); +- cb->args[1] = arg.w.count; +- if (arg.w.stop) +- break; +- t++; +- } ++ for (q=dev->qdisc_list, t=0; q; q = q->next, t++) { ++ if (t < s_t) continue; ++ if (!q->ops->cl_ops) continue; ++ if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) != q->handle) ++ continue; ++ if (t > s_t) ++ memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); ++ arg.w.fn = qdisc_class_dump; ++ arg.skb = skb; ++ arg.cb = cb; ++ arg.w.stop = 0; ++ arg.w.skip = cb->args[1]; ++ arg.w.count = 0; ++ q->ops->cl_ops->walk(q, &arg.w); ++ cb->args[1] = arg.w.count; ++ if (arg.w.stop) ++ break; ++ } + read_unlock(&qdisc_tree_lock); + + cb->args[0] = t; +diff -Nur linux-2.4.30/net/sched/sch_generic.c linux-2.4.30-wl-fix/net/sched/sch_generic.c +--- linux-2.4.30/net/sched/sch_generic.c 2004-11-17 12:54:22.000000000 +0100 ++++ linux-2.4.30-wl-fix/net/sched/sch_generic.c 2005-05-08 00:51:20.000000000 +0200 +@@ -392,7 +392,6 @@ + return NULL; + memset(sch, 0, size); + +- INIT_LIST_HEAD(&sch->list); + skb_queue_head_init(&sch->q); + sch->ops = ops; + sch->enqueue = ops->enqueue; +@@ -422,11 +421,22 @@ + void qdisc_destroy(struct Qdisc *qdisc) + { + struct Qdisc_ops *ops = qdisc->ops; ++ struct net_device *dev; + + if (qdisc->flags&TCQ_F_BUILTIN || + !atomic_dec_and_test(&qdisc->refcnt)) + return; +- list_del(&qdisc->list); ++ ++ dev = qdisc->dev; ++ if (dev) { ++ struct Qdisc *q, **qp; ++ for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) { ++ if (q == qdisc) { ++ *qp = q->next; ++ break; ++ } ++ } ++ } + #ifdef CONFIG_NET_ESTIMATOR + qdisc_kill_estimator(&qdisc->stats); + #endif +@@ -455,9 +465,9 @@ + return; + } + write_lock(&qdisc_tree_lock); +- list_add_tail(&qdisc->list, &dev->qdisc_list); ++ qdisc->next = dev->qdisc_list; ++ dev->qdisc_list = qdisc; + write_unlock(&qdisc_tree_lock); +- + } else { + qdisc = &noqueue_qdisc; + } +@@ -501,7 +511,7 @@ + dev->qdisc = &noop_qdisc; + spin_unlock_bh(&dev->queue_lock); + dev->qdisc_sleeping = &noop_qdisc; +- INIT_LIST_HEAD(&dev->qdisc_list); ++ dev->qdisc_list = NULL; + write_unlock(&qdisc_tree_lock); + + dev_watchdog_init(dev); +@@ -523,7 +533,7 @@ + qdisc_destroy(qdisc); + } + #endif +- BUG_TRAP(list_empty(&dev->qdisc_list)); ++ BUG_TRAP(dev->qdisc_list == NULL); + BUG_TRAP(!timer_pending(&dev->watchdog_timer)); + spin_unlock_bh(&dev->queue_lock); + write_unlock(&qdisc_tree_lock); +diff -urN linux.old/net/core/dev.c linux.dev/net/core/dev.c +--- linux.old/net/core/dev.c 2005-05-28 17:42:07.000000000 +0200 ++++ linux.dev/net/core/dev.c 2005-05-28 20:38:06.000000000 +0200 +@@ -2223,6 +2223,7 @@ + cmd == SIOCGMIIPHY || + cmd == SIOCGMIIREG || + cmd == SIOCSMIIREG || ++ cmd == SIOCETHTOOL || + cmd == SIOCWANDEV) { + if (dev->do_ioctl) { + if (!netif_device_present(dev)) +@@ -2405,6 +2406,7 @@ + + default: + if (cmd == SIOCWANDEV || ++ (cmd == SIOCETHTOOL) || + (cmd >= SIOCDEVPRIVATE && + cmd <= SIOCDEVPRIVATE + 15)) { + dev_load(ifr.ifr_name); diff --git a/openwrt/target/linux/brcm-2.4/patches/003-bcm47xx_cache_fixes.patch b/openwrt/target/linux/brcm-2.4/patches/003-bcm47xx_cache_fixes.patch new file mode 100644 index 0000000000..e971e7fdfd --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/patches/003-bcm47xx_cache_fixes.patch @@ -0,0 +1,498 @@ +diff -urN linux.old/arch/mips/kernel/entry.S linux.dev/arch/mips/kernel/entry.S +--- linux.old/arch/mips/kernel/entry.S 2005-07-05 16:46:49.000000000 +0200 ++++ linux.dev/arch/mips/kernel/entry.S 2005-07-06 11:23:55.000000000 +0200 +@@ -100,6 +100,10 @@ + * and R4400 SC and MC versions. + */ + NESTED(except_vec3_generic, 0, sp) ++#ifdef CONFIG_BCM4710 ++ nop ++ nop ++#endif + #if R5432_CP0_INTERRUPT_WAR + mfc0 k0, CP0_INDEX + #endif +diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c +--- linux.old/arch/mips/mm/c-r4k.c 2005-07-05 16:46:49.000000000 +0200 ++++ linux.dev/arch/mips/mm/c-r4k.c 2005-07-06 11:23:55.000000000 +0200 +@@ -14,6 +14,12 @@ + #include + #include + ++#ifdef CONFIG_BCM4710 ++#include "../bcm947xx/include/typedefs.h" ++#include "../bcm947xx/include/sbconfig.h" ++#include ++#endif ++ + #include + #include + #include +@@ -40,6 +46,8 @@ + .bc_inv = (void *)no_sc_noop + }; + ++int bcm4710 = 0; ++EXPORT_SYMBOL(bcm4710); + struct bcache_ops *bcops = &no_sc_ops; + + #define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x2010) +@@ -64,8 +72,10 @@ + static inline void r4k_blast_dcache_page_setup(void) + { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; +- +- if (dc_lsize == 16) ++ ++ if (bcm4710) ++ r4k_blast_dcache_page = blast_dcache_page; ++ else if (dc_lsize == 16) + r4k_blast_dcache_page = blast_dcache16_page; + else if (dc_lsize == 32) + r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; +@@ -77,7 +87,9 @@ + { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + +- if (dc_lsize == 16) ++ if (bcm4710) ++ r4k_blast_dcache_page_indexed = blast_dcache_page_indexed; ++ else if (dc_lsize == 16) + r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; + else if (dc_lsize == 32) + r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; +@@ -89,7 +101,9 @@ + { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + +- if (dc_lsize == 16) ++ if (bcm4710) ++ r4k_blast_dcache = blast_dcache; ++ else if (dc_lsize == 16) + r4k_blast_dcache = blast_dcache16; + else if (dc_lsize == 32) + r4k_blast_dcache = blast_dcache32; +@@ -266,6 +280,7 @@ + r4k_blast_dcache(); + r4k_blast_icache(); + ++ if (!bcm4710) + switch (current_cpu_data.cputype) { + case CPU_R4000SC: + case CPU_R4000MC: +@@ -304,10 +319,10 @@ + * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we + * only flush the primary caches but R10000 and R12000 behave sane ... + */ +- if (current_cpu_data.cputype == CPU_R4000SC || ++ if (!bcm4710 && (current_cpu_data.cputype == CPU_R4000SC || + current_cpu_data.cputype == CPU_R4000MC || + current_cpu_data.cputype == CPU_R4400SC || +- current_cpu_data.cputype == CPU_R4400MC) ++ current_cpu_data.cputype == CPU_R4400MC)) + r4k_blast_scache(); + } + +@@ -383,12 +398,15 @@ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long addr, aend; + ++ addr = start & ~(dc_lsize - 1); ++ aend = (end - 1) & ~(dc_lsize - 1); ++ + if (!cpu_has_ic_fills_f_dc) { + if (end - start > dcache_size) + r4k_blast_dcache(); + else { +- addr = start & ~(dc_lsize - 1); +- aend = (end - 1) & ~(dc_lsize - 1); ++ BCM4710_PROTECTED_FILL_TLB(addr); ++ BCM4710_PROTECTED_FILL_TLB(aend); + + while (1) { + /* Hit_Writeback_Inv_D */ +@@ -403,8 +421,6 @@ + if (end - start > icache_size) + r4k_blast_icache(); + else { +- addr = start & ~(ic_lsize - 1); +- aend = (end - 1) & ~(ic_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); +@@ -413,6 +429,9 @@ + addr += ic_lsize; + } + } ++ ++ if (bcm4710) ++ flush_cache_all(); + } + + /* +@@ -443,7 +462,8 @@ + if (cpu_has_subset_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + +- r4k_blast_scache_page(addr); ++ if (!bcm4710) ++ r4k_blast_scache_page(addr); + ClearPageDcacheDirty(page); + + return; +@@ -451,6 +471,7 @@ + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); ++ + r4k_blast_dcache_page(addr); + ClearPageDcacheDirty(page); + } +@@ -477,7 +498,7 @@ + /* Catch bad driver code */ + BUG_ON(size == 0); + +- if (cpu_has_subset_pcaches) { ++ if (!bcm4710 && cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { +@@ -509,6 +530,8 @@ + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); ++ BCM4710_FILL_TLB(a); ++ BCM4710_FILL_TLB(end); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) +@@ -527,7 +550,7 @@ + /* Catch bad driver code */ + BUG_ON(size == 0); + +- if (cpu_has_subset_pcaches) { ++ if (!bcm4710 && (cpu_has_subset_pcaches)) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { +@@ -554,6 +577,8 @@ + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); ++ BCM4710_FILL_TLB(a); ++ BCM4710_FILL_TLB(end); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) +@@ -577,6 +602,8 @@ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; ++ BCM4710_PROTECTED_FILL_TLB(addr); ++ BCM4710_PROTECTED_FILL_TLB(addr + 4); + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); + if (MIPS4K_ICACHE_REFILL_WAR) { +@@ -986,10 +1013,12 @@ + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: +- probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); +- sc_present = probe_scache_kseg1(config); +- if (sc_present) +- c->options |= MIPS_CPU_CACHE_CDEX_S; ++ if (!bcm4710) { ++ probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); ++ sc_present = probe_scache_kseg1(config); ++ if (sc_present) ++ c->options |= MIPS_CPU_CACHE_CDEX_S; ++ } + break; + + case CPU_R10000: +@@ -1041,6 +1070,19 @@ + static inline void coherency_setup(void) + { + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); ++ ++#if defined(CONFIG_BCM4310) || defined(CONFIG_BCM4704) || defined(CONFIG_BCM5365) ++ if (BCM330X(current_cpu_data.processor_id)) { ++ uint32 cm; ++ ++ cm = read_c0_diag(); ++ /* Enable icache */ ++ cm |= (1 << 31); ++ /* Enable dcache */ ++ cm |= (1 << 30); ++ write_c0_diag(cm); ++ } ++#endif + + /* + * c0_status.cu=0 specifies that updates by the sc instruction use +@@ -1073,6 +1115,12 @@ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80); + ++ if (current_cpu_data.cputype == CPU_BCM4710 && (current_cpu_data.processor_id & PRID_REV_MASK) == 0) { ++ printk("Enabling BCM4710A0 cache workarounds.\n"); ++ bcm4710 = 1; ++ } else ++ bcm4710 = 0; ++ + probe_pcache(); + setup_scache(); + +diff -urN linux.old/arch/mips/mm/tlbex-mips32.S linux.dev/arch/mips/mm/tlbex-mips32.S +--- linux.old/arch/mips/mm/tlbex-mips32.S 2005-07-05 16:46:49.000000000 +0200 ++++ linux.dev/arch/mips/mm/tlbex-mips32.S 2005-07-06 11:23:56.000000000 +0200 +@@ -90,6 +90,9 @@ + .set noat + LEAF(except_vec0_r4000) + .set mips3 ++#ifdef CONFIG_BCM4704 ++ nop ++#endif + #ifdef CONFIG_SMP + mfc0 k1, CP0_CONTEXT + la k0, pgd_current +diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h +--- linux.old/include/asm-mips/r4kcache.h 2005-07-05 16:46:49.000000000 +0200 ++++ linux.dev/include/asm-mips/r4kcache.h 2005-07-06 12:52:57.000000000 +0200 +@@ -15,6 +15,18 @@ + #include + #include + ++#ifdef CONFIG_BCM4710 ++#define BCM4710_DUMMY_RREG() (((sbconfig_t *)(KSEG1ADDR(SB_ENUM_BASE + SBCONFIGOFF)))->sbimstate) ++ ++#define BCM4710_FILL_TLB(addr) (*(volatile unsigned long *)(addr)) ++#define BCM4710_PROTECTED_FILL_TLB(addr) ({ unsigned long x; get_dbe(x, (volatile unsigned long *)(addr)); }) ++#else ++#define BCM4710_DUMMY_RREG() ++ ++#define BCM4710_FILL_TLB(addr) ++#define BCM4710_PROTECTED_FILL_TLB(addr) ++#endif ++ + #define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set noreorder \n" \ +@@ -27,12 +39,25 @@ + + static inline void flush_icache_line_indexed(unsigned long addr) + { +- cache_op(Index_Invalidate_I, addr); ++ unsigned int way; ++ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; ++ ++ for (way = 0; way < current_cpu_data.dcache.ways; way++) { ++ cache_op(Index_Invalidate_I, addr); ++ addr += ws_inc; ++ } + } + + static inline void flush_dcache_line_indexed(unsigned long addr) + { +- cache_op(Index_Writeback_Inv_D, addr); ++ unsigned int way; ++ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; ++ ++ for (way = 0; way < current_cpu_data.dcache.ways; way++) { ++ BCM4710_DUMMY_RREG(); ++ cache_op(Index_Writeback_Inv_D, addr); ++ addr += ws_inc; ++ } + } + + static inline void flush_scache_line_indexed(unsigned long addr) +@@ -47,6 +72,7 @@ + + static inline void flush_dcache_line(unsigned long addr) + { ++ BCM4710_DUMMY_RREG(); + cache_op(Hit_Writeback_Inv_D, addr); + } + +@@ -91,6 +117,7 @@ + */ + static inline void protected_writeback_dcache_line(unsigned long addr) + { ++ BCM4710_DUMMY_RREG(); + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n" +@@ -138,6 +165,62 @@ + : "r" (base), \ + "i" (op)); + ++#define cache_unroll(base,op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, (%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++ ++static inline void blast_dcache(void) ++{ ++ unsigned long start = KSEG0; ++ unsigned long dcache_size = current_cpu_data.dcache.waysize * current_cpu_data.dcache.ways; ++ unsigned long end = (start + dcache_size); ++ ++ while(start < end) { ++ BCM4710_DUMMY_RREG(); ++ cache_unroll(start,Index_Writeback_Inv_D); ++ start += current_cpu_data.dcache.linesz; ++ } ++} ++ ++static inline void blast_dcache_page(unsigned long page) ++{ ++ unsigned long start = page; ++ unsigned long end = start + PAGE_SIZE; ++ ++ BCM4710_FILL_TLB(start); ++ do { ++ BCM4710_DUMMY_RREG(); ++ cache_unroll(start,Hit_Writeback_Inv_D); ++ start += current_cpu_data.dcache.linesz; ++ } while (start < end); ++} ++ ++static inline void blast_dcache_page_indexed(unsigned long page) ++{ ++ unsigned long start = page; ++ unsigned long end = start + PAGE_SIZE; ++ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; ++ unsigned long ws_end = current_cpu_data.dcache.ways << ++ current_cpu_data.dcache.waybit; ++ unsigned long ws, addr; ++ ++ for (ws = 0; ws < ws_end; ws += ws_inc) { ++ start = page + ws; ++ for (addr = start; addr < end; addr += current_cpu_data.dcache.linesz) { ++ BCM4710_DUMMY_RREG(); ++ cache_unroll(addr,Index_Writeback_Inv_D); ++ } ++ } ++} ++ + static inline void blast_dcache16(void) + { + unsigned long start = KSEG0; +@@ -148,8 +231,9 @@ + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) +- for (addr = start; addr < end; addr += 0x200) ++ for (addr = start; addr < end; addr += 0x200) { + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); ++ } + } + + static inline void blast_dcache16_page(unsigned long page) +@@ -173,8 +257,9 @@ + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) +- for (addr = start; addr < end; addr += 0x200) ++ for (addr = start; addr < end; addr += 0x200) { + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); ++ } + } + + static inline void blast_icache16(void) +@@ -196,6 +281,7 @@ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + ++ BCM4710_FILL_TLB(start); + do { + cache16_unroll32(start,Hit_Invalidate_I); + start += 0x200; +@@ -281,6 +367,7 @@ + : "r" (base), \ + "i" (op)); + ++ + static inline void blast_dcache32(void) + { + unsigned long start = KSEG0; +@@ -291,8 +378,9 @@ + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) +- for (addr = start; addr < end; addr += 0x400) ++ for (addr = start; addr < end; addr += 0x400) { + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); ++ } + } + + static inline void blast_dcache32_page(unsigned long page) +@@ -316,8 +404,9 @@ + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) +- for (addr = start; addr < end; addr += 0x400) ++ for (addr = start; addr < end; addr += 0x400) { + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); ++ } + } + + static inline void blast_icache32(void) +@@ -339,6 +428,7 @@ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + ++ BCM4710_FILL_TLB(start); + do { + cache32_unroll32(start,Hit_Invalidate_I); + start += 0x400; +@@ -443,6 +533,7 @@ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + ++ BCM4710_FILL_TLB(start); + do { + cache64_unroll32(start,Hit_Invalidate_I); + start += 0x800; +diff -urN linux.old/include/asm-mips/stackframe.h linux.dev/include/asm-mips/stackframe.h +--- linux.old/include/asm-mips/stackframe.h 2005-07-05 16:46:49.000000000 +0200 ++++ linux.dev/include/asm-mips/stackframe.h 2005-07-06 11:23:56.000000000 +0200 +@@ -209,6 +209,20 @@ + + #endif + ++#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4704) ++ ++#undef RESTORE_SP_AND_RET ++#define RESTORE_SP_AND_RET \ ++ lw sp, PT_R29(sp); \ ++ .set mips3; \ ++ nop; \ ++ nop; \ ++ eret; \ ++ .set mips0 ++ ++#endif ++ ++ + #define RESTORE_SP \ + lw sp, PT_R29(sp); \ + +diff -urN linux.old/mm/memory.c linux.dev/mm/memory.c +--- linux.old/mm/memory.c 2005-04-04 03:42:20.000000000 +0200 ++++ linux.dev/mm/memory.c 2005-07-06 11:23:56.000000000 +0200 +@@ -925,6 +925,7 @@ + flush_page_to_ram(new_page); + flush_cache_page(vma, address); + establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)))); ++ flush_icache_page(vma, new_page); + } + + /* diff --git a/openwrt/target/linux/brcm-2.4/patches/004-flash-map.patch b/openwrt/target/linux/brcm-2.4/patches/004-flash-map.patch new file mode 100644 index 0000000000..06c106bdf0 --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/patches/004-flash-map.patch @@ -0,0 +1,401 @@ +diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-flash/drivers/mtd/maps/bcm947xx-flash.c +--- linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-flash/drivers/mtd/maps/bcm947xx-flash.c 2005-12-19 01:29:52.464670750 +0100 +@@ -0,0 +1,366 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * Copyright (C) 2005 Waldemar Brodkorb ++ * ++ * original functions for finding root filesystem from Mike Baker ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Flash mapping for BCM947XX boards ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_MTD_PARTITIONS ++#include ++#endif ++#include ++ ++#include ++ ++#define WINDOW_ADDR 0x1c000000 ++#define WINDOW_SIZE (0x400000*2) ++#define BUSWIDTH 2 ++ ++static struct mtd_info *bcm947xx_mtd; ++ ++__u8 bcm947xx_map_read8(struct map_info *map, unsigned long ofs) ++{ ++ if (map->map_priv_2 == 1) ++ return __raw_readb(map->map_priv_1 + ofs); ++ ++ u16 val = __raw_readw(map->map_priv_1 + (ofs & ~1)); ++ if (ofs & 1) ++ return ((val >> 8) & 0xff); ++ else ++ return (val & 0xff); ++} ++ ++__u16 bcm947xx_map_read16(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readw(map->map_priv_1 + ofs); ++} ++ ++__u32 bcm947xx_map_read32(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readl(map->map_priv_1 + ofs); ++} ++ ++void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ if (len==1) { ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++ } else { ++ int i; ++ u16 *dest = (u16 *) to; ++ u16 *src = (u16 *) (map->map_priv_1 + from); ++ for (i = 0; i < (len / 2); i++) { ++ dest[i] = src[i]; ++ } ++ if (len & 1) ++ *((u8 *)dest+len-1) = src[i] & 0xff; ++ } ++} ++ ++void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void bcm947xx_map_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void bcm947xx_map_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void bcm947xx_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++struct map_info bcm947xx_map = { ++ name: "Physically mapped flash", ++ size: WINDOW_SIZE, ++ buswidth: BUSWIDTH, ++ read8: bcm947xx_map_read8, ++ read16: bcm947xx_map_read16, ++ read32: bcm947xx_map_read32, ++ copy_from: bcm947xx_map_copy_from, ++ write8: bcm947xx_map_write8, ++ write16: bcm947xx_map_write16, ++ write32: bcm947xx_map_write32, ++ copy_to: bcm947xx_map_copy_to ++}; ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ ++static struct mtd_partition bcm947xx_parts[] = { ++ { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, ++ { name: "linux", offset: 0, size: 0, }, ++ { name: "rootfs", offset: 0, size: 0, }, ++ { name: "nvram", offset: 0, size: 0, }, ++ { name: "OpenWrt", offset: 0, size: 0, }, ++ { name: NULL, }, ++}; ++ ++static int __init ++find_cfe_size(struct mtd_info *mtd, size_t size) ++{ ++ struct trx_header *trx; ++ unsigned char buf[512]; ++ int off; ++ size_t len; ++ int cfe_size_flag; ++ ++ trx = (struct trx_header *) buf; ++ ++ cfe_size_flag=0; ++ ++ for (off = (256*1024); off < size; off += mtd->erasesize) { ++ memset(buf, 0xe5, sizeof(buf)); ++ ++ /* ++ * Read into buffer ++ */ ++ if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || ++ len != sizeof(buf)) ++ continue; ++ ++ /* found a TRX header */ ++ if (le32_to_cpu(trx->magic) == TRX_MAGIC) { ++ goto done; ++ } ++ cfe_size_flag += 1; ++ } ++ ++ printk(KERN_NOTICE ++ "%s: Couldn't find bootloader size\n", ++ mtd->name); ++ return -1; ++ ++ done: ++ printk(KERN_NOTICE "bootloader size flag: %d\n", cfe_size_flag); ++ return cfe_size_flag; ++ ++} ++ ++static int __init ++find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) ++{ ++ struct trx_header *trx; ++ unsigned char buf[512]; ++ int off; ++ size_t len; ++ ++ trx = (struct trx_header *) buf; ++ ++ for (off = (256*1024); off < size; off += mtd->erasesize) { ++ memset(buf, 0xe5, sizeof(buf)); ++ ++ /* ++ * Read into buffer ++ */ ++ if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || ++ len != sizeof(buf)) ++ continue; ++ ++ /* found a TRX header */ ++ if (le32_to_cpu(trx->magic) == TRX_MAGIC) { ++ part->offset = le32_to_cpu(trx->offsets[2]) ? : ++ le32_to_cpu(trx->offsets[1]); ++ part->size = le32_to_cpu(trx->len); ++ ++ part->size -= part->offset; ++ part->offset += off; ++ ++ goto done; ++ } ++ } ++ ++ printk(KERN_NOTICE ++ "%s: Couldn't find root filesystem\n", ++ mtd->name); ++ return -1; ++ ++ done: ++ return part->size; ++} ++ ++struct mtd_partition * __init ++init_mtd_partitions(struct mtd_info *mtd, size_t size) ++{ ++ ++ int cfe_size_flag; ++ ++ /* if cfe_size_flag=0, cfe size is 256 kb, else 384 kb */ ++ cfe_size_flag = find_cfe_size(mtd,size); ++ ++ /* boot loader */ ++ bcm947xx_parts[0].offset = 0; ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[0].size = 1024*256; ++ } else { ++ /* netgear wgt634u has 384 kb bootloader */ ++ bcm947xx_parts[0].size = 1024*384; ++ } ++ ++ /* nvram */ ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[3].offset = size - mtd->erasesize; ++ } else { ++ /* nvram (old 128kb config partition on netgear wgt634u) */ ++ bcm947xx_parts[3].offset = bcm947xx_parts[0].size; ++ } ++ bcm947xx_parts[3].size = mtd->erasesize; ++ ++ /* linux (kernel and rootfs) */ ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[1].offset = bcm947xx_parts[0].size; ++ bcm947xx_parts[1].size = bcm947xx_parts[3].offset - ++ bcm947xx_parts[1].offset; ++ } else { ++ /* do not count the elf loader, which is on one block */ ++ bcm947xx_parts[1].offset = bcm947xx_parts[0].size + ++ bcm947xx_parts[3].size + mtd->erasesize; ++ bcm947xx_parts[1].size = size - ++ bcm947xx_parts[0].size - ++ (2*bcm947xx_parts[3].size) - ++ mtd->erasesize; ++ } ++ ++ /* find and size rootfs */ ++ if (find_root(mtd,size,&bcm947xx_parts[2])==0) { ++ /* entirely jffs2 */ ++ bcm947xx_parts[4].name = NULL; ++ bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset - ++ bcm947xx_parts[3].size; ++ } else { ++ /* legacy setup */ ++ /* calculate leftover flash, and assign it to the jffs2 partition */ ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + ++ bcm947xx_parts[2].size; ++ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) { ++ bcm947xx_parts[4].offset += mtd->erasesize - ++ (bcm947xx_parts[4].offset % mtd->erasesize); ++ } ++ bcm947xx_parts[4].size = bcm947xx_parts[3].offset - ++ bcm947xx_parts[4].offset; ++ } else { ++ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + ++ bcm947xx_parts[2].size; ++ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) { ++ bcm947xx_parts[4].offset += mtd->erasesize - ++ (bcm947xx_parts[4].offset % mtd->erasesize); ++ } ++ bcm947xx_parts[4].size = size - bcm947xx_parts[3].size - ++ bcm947xx_parts[4].offset; ++ } ++ } ++ ++ return bcm947xx_parts; ++} ++ ++#endif ++ ++ ++mod_init_t init_bcm947xx_map(void) ++{ ++ size_t size; ++ int ret = 0; ++#ifdef CONFIG_MTD_PARTITIONS ++ struct mtd_partition *parts; ++ int i; ++#endif ++ ++ bcm947xx_map.map_priv_1 = (unsigned long) ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ ++ if (!bcm947xx_map.map_priv_1) { ++ printk(KERN_ERR "Failed to ioremap\n"); ++ return -EIO; ++ } ++ ++ if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) { ++ printk(KERN_ERR "pflash: cfi_probe failed\n"); ++ iounmap((void *)bcm947xx_map.map_priv_1); ++ return -ENXIO; ++ } ++ ++ bcm947xx_mtd->module = THIS_MODULE; ++ ++ size = bcm947xx_mtd->size; ++ ++ printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR); ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ parts = init_mtd_partitions(bcm947xx_mtd, size); ++ for (i = 0; parts[i].name; i++); ++ ret = add_mtd_partitions(bcm947xx_mtd, parts, i); ++ if (ret) { ++ printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); ++ goto fail; ++ } ++#endif ++ ++ return 0; ++ ++ fail: ++ if (bcm947xx_mtd) ++ map_destroy(bcm947xx_mtd); ++ if (bcm947xx_map.map_priv_1) ++ iounmap((void *) bcm947xx_map.map_priv_1); ++ bcm947xx_map.map_priv_1 = 0; ++ return ret; ++} ++ ++mod_exit_t cleanup_bcm947xx_map(void) ++{ ++#ifdef CONFIG_MTD_PARTITIONS ++ del_mtd_partitions(bcm947xx_mtd); ++#endif ++ map_destroy(bcm947xx_mtd); ++ iounmap((void *) bcm947xx_map.map_priv_1); ++ bcm947xx_map.map_priv_1 = 0; ++} ++ ++module_init(init_bcm947xx_map); ++module_exit(cleanup_bcm947xx_map); +diff -Nur linux-2.4.32/drivers/mtd/maps/Config.in linux-2.4.32-flash/drivers/mtd/maps/Config.in +--- linux-2.4.32/drivers/mtd/maps/Config.in 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-flash/drivers/mtd/maps/Config.in 2005-12-18 15:53:52.003277250 +0100 +@@ -48,6 +48,7 @@ + fi + + if [ "$CONFIG_MIPS" = "y" ]; then ++ dep_tristate ' CFI Flash device mapped on Broadcom BCM947XX boards' CONFIG_MTD_BCM947XX $CONFIG_MTD_CFI + dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000 + dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500 + dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100 +diff -Nur linux-2.4.32/drivers/mtd/maps/Makefile linux-2.4.32-flash/drivers/mtd/maps/Makefile +--- linux-2.4.32/drivers/mtd/maps/Makefile 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-flash/drivers/mtd/maps/Makefile 2005-12-18 15:54:39.022215750 +0100 +@@ -3,6 +3,8 @@ + # + # $Id: Makefile,v 1.37 2003/01/24 14:26:38 dwmw2 Exp $ + ++EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include ++ + BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/) + + ifeq ($(BELOW25),y) +@@ -10,6 +12,7 @@ + endif + + # Chip mappings ++obj-$(CONFIG_MTD_BCM947XX) += bcm947xx-flash.o + obj-$(CONFIG_MTD_CDB89712) += cdb89712.o + obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o + obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o diff --git a/openwrt/target/linux/brcm-2.4/patches/005-bluetooth_sco_buffer_align.patch b/openwrt/target/linux/brcm-2.4/patches/005-bluetooth_sco_buffer_align.patch new file mode 100644 index 0000000000..77ade1c8b2 --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/patches/005-bluetooth_sco_buffer_align.patch @@ -0,0 +1,12 @@ +--- linux-2.4.30/drivers/bluetooth/hci_usb.c 2004-08-08 01:26:04.000000000 +0200 ++++ linux-2.4.30/drivers/bluetooth/hci_usb.c 2005-07-25 20:12:11.000000000 +0200 +@@ -259,6 +259,9 @@ + void *buf; + + mtu = husb->isoc_in_ep->wMaxPacketSize; ++#ifdef CONFIG_BCM4710 ++ mtu = (mtu + 1) & ~1; /* brcm: isoc buffers must be aligned on word boundary */ ++#endif + size = mtu * HCI_MAX_ISOC_FRAMES; + + buf = kmalloc(size, GFP_ATOMIC); diff --git a/openwrt/target/linux/brcm-2.4/patches/006-ide_workaround.patch b/openwrt/target/linux/brcm-2.4/patches/006-ide_workaround.patch new file mode 100644 index 0000000000..9f8d2ee29d --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/patches/006-ide_workaround.patch @@ -0,0 +1,18 @@ +diff -urN linux.old/arch/mips/lib/ide-std.c linux.dev/arch/mips/lib/ide-std.c +--- linux.old/arch/mips/lib/ide-std.c 2003-08-25 13:44:40.000000000 +0200 ++++ linux.dev/arch/mips/lib/ide-std.c 2005-08-12 23:55:23.886963936 +0200 +@@ -31,12 +31,14 @@ + static ide_ioreg_t std_ide_default_io_base(int index) + { + switch (index) { ++#if 0 + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + case 4: return 0x1e0; + case 5: return 0x160; ++#endif + default: + return 0; + } diff --git a/openwrt/target/linux/brcm-2.4/patches/007-sched_use_tsc.patch b/openwrt/target/linux/brcm-2.4/patches/007-sched_use_tsc.patch new file mode 100644 index 0000000000..5b64310738 --- /dev/null +++ b/openwrt/target/linux/brcm-2.4/patches/007-sched_use_tsc.patch @@ -0,0 +1,84 @@ +diff -urN linux.old/arch/mips/kernel/time.c linux.dev/arch/mips/kernel/time.c +--- linux.old/arch/mips/kernel/time.c 2005-11-14 11:06:38.661262000 +0100 ++++ linux.dev/arch/mips/kernel/time.c 2005-11-15 20:02:50.059676750 +0100 +@@ -151,6 +151,27 @@ + unsigned int (*mips_hpt_read)(void); + void (*mips_hpt_init)(unsigned int); + ++extern __u32 get_htscl(void) ++{ ++ return timerhi; ++} ++ ++static __u64 tscll_last = 0; ++ ++extern __u64 get_tscll(void) ++{ ++ __u64 h = (__u64) timerhi; ++ __u32 c = read_c0_count(); ++ ++ h <<= 32; ++ h += c; ++ ++ while (h < tscll_last) ++ h += (((__u64) 1) << 32); ++ ++ tscll_last = h; ++ return h; ++} + + /* + * timeofday services, for syscalls. +@@ -761,3 +782,5 @@ + EXPORT_SYMBOL(to_tm); + EXPORT_SYMBOL(rtc_set_time); + EXPORT_SYMBOL(rtc_get_time); ++EXPORT_SYMBOL(get_htscl); ++EXPORT_SYMBOL(get_tscll); +diff -urN linux.old/include/asm-mips/timex.h linux.dev/include/asm-mips/timex.h +--- linux.old/include/asm-mips/timex.h 2005-11-14 11:06:38.685263500 +0100 ++++ linux.dev/include/asm-mips/timex.h 2005-11-14 11:02:21.069163500 +0100 +@@ -31,6 +31,19 @@ + return read_c0_count(); + } + ++extern __u32 get_htscl(void); ++extern __u64 get_tscll(void); ++ ++#define rdtsc(low, high) \ ++ high = get_htscl(); \ ++ low = read_c0_count(); ++ ++#define rdtscl(low) \ ++ low = read_c0_count(); ++ ++#define rdtscll(val) \ ++ val = get_tscll(); ++ + #define vxtime_lock() do {} while (0) + #define vxtime_unlock() do {} while (0) + +diff -urN linux.old/include/net/pkt_sched.h linux.dev/include/net/pkt_sched.h +--- linux.old/include/net/pkt_sched.h 2005-11-14 11:06:38.709265000 +0100 ++++ linux.dev/include/net/pkt_sched.h 2005-11-14 11:02:21.069163500 +0100 +@@ -5,7 +5,11 @@ + #define PSCHED_JIFFIES 2 + #define PSCHED_CPU 3 + ++#ifdef __mips__ ++#define PSCHED_CLOCK_SOURCE PSCHED_CPU ++#else + #define PSCHED_CLOCK_SOURCE PSCHED_JIFFIES ++#endif + + #include + #include +@@ -271,7 +275,7 @@ + #define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz) + #define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz) + +-#ifdef CONFIG_X86_TSC ++#if defined(CONFIG_X86_TSC) || defined(__mips__) + + #define PSCHED_GET_TIME(stamp) \ + ({ u64 __cur; \ diff --git a/openwrt/target/linux/brcm-2.6/Makefile b/openwrt/target/linux/brcm-2.6/Makefile new file mode 100644 index 0000000000..02ed5c49d4 --- /dev/null +++ b/openwrt/target/linux/brcm-2.6/Makefile @@ -0,0 +1,19 @@ +include $(TOPDIR)/rules.mk + +LINUX_VERSION:=2.6.15 +LINUX_RELEASE:=1 +LINUX_KERNEL_MD5SUM:=cdf95e00f5111e31f78e1d97304d9522 + +include ../rules.mk +include ./config + +include ../generic-$(KERNEL)/modules.mk +include ../kernel.mk + + +$(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked + [ -d ../generic-$(KERNEL)/patches ] && $(PATCH) $(LINUX_DIR) ../generic-$(KERNEL)/patches $(MAKE_TRACE) + [ -d ./patches ] && $(PATCH) $(LINUX_DIR) ./patches $(MAKE_TRACE) + @cp config $(LINUX_DIR)/.config + touch $@ + diff --git a/openwrt/target/linux/brcm-2.6/config b/openwrt/target/linux/brcm-2.6/config new file mode 100644 index 0000000000..fc4234343a --- /dev/null +++ b/openwrt/target/linux/brcm-2.6/config @@ -0,0 +1,1664 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.15-rc6 +# Sat Dec 24 00:37:33 2005 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MACH_JAZZ is not set +CONFIG_BCM947XX=y +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_PNX8550_V2PCI is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# 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_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_MIPS_MT is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +# CONFIG_LBD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_LOAD_CIS is not set +# CONFIG_PCMCIA_IOCTL is not set +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +# CONFIG_PD6729 is not set +# CONFIG_I82092 is not set +CONFIG_PCCARD_NONSTATIC=m + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_RING=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +# 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_SYN_COOKIES is not set +CONFIG_IPSEC_NAT_TRAVERSAL=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y + +# +# TCP congestion control +# +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=m + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_BRIDGE_NETFILTER is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=y +CONFIG_IP_NF_IRC=y +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_PPTP=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_LAYER7=m +# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=y +CONFIG_IP_NF_MATCH_MULTIPORT=y +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TIME=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=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_OWNER=m +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +# CONFIG_IP_NF_MATCH_SCTP is not set +# CONFIG_IP_NF_MATCH_DCCP is not set +# CONFIG_IP_NF_MATCH_COMMENT is not set +CONFIG_IP_NF_MATCH_CONNMARK=m +# CONFIG_IP_NF_MATCH_CONNBYTES is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +CONFIG_IP_NF_MATCH_STRING=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=y +# CONFIG_IP_NF_TARGET_NFQUEUE is not set +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +# CONFIG_IP_NF_TARGET_SAME is not set +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_NAT_AMANDA=m +CONFIG_IP_NF_NAT_PPTP=m +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=y +# CONFIG_IP_NF_TARGET_CLASSIFY is not set +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CONNMARK=m +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_RAW is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_SET=m +CONFIG_IP_NF_SET_MAX=256 +CONFIG_IP_NF_SET_HASHSIZE=1024 +CONFIG_IP_NF_SET_IPMAP=m +CONFIG_IP_NF_SET_MACIPMAP=m +CONFIG_IP_NF_SET_PORTMAP=m +CONFIG_IP_NF_SET_IPHASH=m +CONFIG_IP_NF_SET_NETHASH=m +CONFIG_IP_NF_SET_IPTREE=m +CONFIG_IP_NF_MATCH_SET=m +CONFIG_IP_NF_TARGET_SET=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=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_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_NFQUEUE is not set +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_IP6_NF_TARGET_HL is not set +# CONFIG_IP6_NF_RAW is not set + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +CONFIG_ATM_CLIP_NO_ICMP=y +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=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_DSMARK=m +# CONFIG_NET_SCH_NETEM is not set +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +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_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ESTIMATOR=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +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_BAYCOM_SER_FDX is not set +# CONFIG_BAYCOM_SER_HDX is not set +# CONFIG_YAM is not set +# CONFIG_IRDA is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIUSB is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIDTL1 is not set +# CONFIG_BT_HCIBT3C is not set +# CONFIG_BT_HCIBLUECARD is not set +# CONFIG_BT_HCIBTUART is not set +# CONFIG_BT_HCIVHCI is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y + +# +# Connector - unified userspace <-> kernelspace linker +# +CONFIG_CONNECTOR=m + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=0 +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_BCM47XX=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=m +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_B44=y +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_LAN_SAA9730 is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW_DEBUG is not set +CONFIG_IPW2200=m +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_CS=m +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ATM drivers +# +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +# CONFIG_ATM_ENI is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_ATM_NICSTAR is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_FORE200E_MAYBE is not set +# CONFIG_ATM_HE is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI 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=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=m + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_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_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set + +# +# ALSA MIPS devices +# + +# +# USB devices +# +CONFIG_SND_USB_AUDIO=m + +# +# PCMCIA devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_ANYDATA is not set +CONFIG_USB_SERIAL_BELKIN=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# +CONFIG_USB_ATM=m +# CONFIG_USB_SPEEDTOUCH is not set +# CONFIG_USB_CXACRU is not set +# CONFIG_USB_XUSBATM is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_SECURITY is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_SQUASHFS_VMALLOC is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +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 + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# 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_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# 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=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 init=/etc/preinit noinitrd console=ttyS0,115200" + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# 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_TGR192 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_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m diff --git a/openwrt/target/linux/brcm-2.6/patches/001-bcm947xx.patch b/openwrt/target/linux/brcm-2.6/patches/001-bcm947xx.patch new file mode 100644 index 0000000000..739590b1cf --- /dev/null +++ b/openwrt/target/linux/brcm-2.6/patches/001-bcm947xx.patch @@ -0,0 +1,11913 @@ +diff -urN linux.old/arch/mips/Kconfig linux.dev/arch/mips/Kconfig +--- linux.old/arch/mips/Kconfig 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/arch/mips/Kconfig 2005-12-28 16:37:32.810257250 +0100 +@@ -244,6 +244,17 @@ + Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and + Olivetti M700-10 workstations. + ++config BCM947XX ++ bool "Support for BCM947xx based boards" ++ select DMA_NONCOHERENT ++ select HW_HAS_PCI ++ select IRQ_CPU ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ help ++ Support for BCM947xx based boards ++ + config LASAT + bool "Support for LASAT Networks platforms" + select DMA_NONCOHERENT +diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile +--- linux.old/arch/mips/Makefile 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/arch/mips/Makefile 2005-12-28 16:37:32.814257500 +0100 +@@ -689,6 +689,13 @@ + load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000 + + # ++# Broadcom BCM47XX boards ++# ++core-$(CONFIG_BCM947XX) += arch/mips/bcm947xx/ arch/mips/bcm947xx/broadcom/ ++cflags-$(CONFIG_BCM947XX) += -Iarch/mips/bcm947xx/include ++load-$(CONFIG_BCM947XX) := 0xffffffff80001000 ++ ++# + # SNI RM200 PCI + # + core-$(CONFIG_SNI_RM200_PCI) += arch/mips/sni/ +diff -urN linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile +--- linux.old/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/Makefile 2005-12-28 16:37:32.814257500 +0100 +@@ -0,0 +1,6 @@ ++# ++# Makefile for the BCM47xx specific kernel interface routines ++# under Linux. ++# ++ ++obj-y := irq.o int-handler.o prom.o setup.o time.o pci.o +diff -urN linux.old/arch/mips/bcm947xx/broadcom/Makefile linux.dev/arch/mips/bcm947xx/broadcom/Makefile +--- linux.old/arch/mips/bcm947xx/broadcom/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/Makefile 2005-12-28 16:37:32.814257500 +0100 +@@ -0,0 +1,6 @@ ++# ++# Makefile for the BCM47xx specific kernel interface routines ++# under Linux. ++# ++ ++obj-y := sbutils.o linux_osl.o bcmsrom.o bcmutils.o sbmips.o sbpci.o sflash.o nvram.o cfe_env.o +diff -urN linux.old/arch/mips/bcm947xx/broadcom/bcmsrom.c linux.dev/arch/mips/bcm947xx/broadcom/bcmsrom.c +--- linux.old/arch/mips/bcm947xx/broadcom/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/bcmsrom.c 2005-12-28 16:37:32.814257500 +0100 +@@ -0,0 +1,481 @@ ++/* ++ * Misc useful routines to access NIC SROM/OTP . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include /* for sprom content groking */ ++ ++#define VARS_MAX 4096 /* should be reduced */ ++ ++#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ ++#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ ++ ++static int initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count); ++static int sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc); ++ ++static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count); ++ ++/* ++ * Initialize local vars from the right source for this platform. ++ * Return 0 on success, nonzero on error. ++ */ ++int ++srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, int *count) ++{ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ if (vars == NULL || count == NULL) ++ return (0); ++ ++ switch (BUSTYPE(bustype)) { ++ ++ case PCI_BUS: ++ ASSERT(curmap); /* can not be NULL */ ++ return initvars_srom_pci(sbh, curmap, vars, count); ++ ++ default: ++ return 0; ++ } ++ return (-1); ++} ++ ++/* support only 16-bit word read from srom */ ++int ++srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) ++{ ++ void *srom; ++ uint off, nw; ++ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; ++ ++ off = byteoff / 2; ++ nw = nbytes / 2; ++ ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ if (!curmap) ++ return 1; ++ srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET; ++ if (sprom_read_pci(srom, off, buf, nw, FALSE)) ++ return 1; ++ } else { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* support only 16-bit word write into srom */ ++int ++srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) ++{ ++ uint16 *srom; ++ uint i, off, nw, crc_range; ++ uint16 image[SPROM_SIZE], *p; ++ uint8 crc; ++ volatile uint32 val32; ++ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; ++ ++ crc_range = (((BUSTYPE(bustype) == SDIO_BUS)) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2; ++ ++ /* if changes made inside crc cover range */ ++ if (byteoff < crc_range) { ++ nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2; ++ /* read data including entire first 64 words from srom */ ++ if (srom_read(bustype, curmap, osh, 0, nw * 2, image)) ++ return 1; ++ /* make changes */ ++ bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); ++ /* calculate crc */ ++ htol16_buf(image, crc_range); ++ crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); ++ ltoh16_buf(image, crc_range); ++ image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); ++ p = image; ++ off = 0; ++ } else { ++ p = buf; ++ off = byteoff / 2; ++ nw = nbytes / 2; ++ } ++ ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET); ++ /* enable writes to the SPROM */ ++ val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); ++ val32 |= SPROM_WRITEEN; ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ /* write srom */ ++ for (i = 0; i < nw; i++) { ++ W_REG(&srom[off + i], p[i]); ++ bcm_mdelay(WRITE_WORD_DELAY); ++ } ++ /* disable writes to the SPROM */ ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN); ++ } else { ++ return 1; ++ } ++ ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ return 0; ++} ++ ++ ++/* ++ * Read in and validate sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) ++{ ++ int err = 0; ++ uint i; ++ ++ /* read the sprom */ ++ for (i = 0; i < nwords; i++) ++ buf[i] = R_REG(&sprom[wordoff + i]); ++ ++ if (check_crc) { ++ /* fixup the endianness so crc8 will pass */ ++ htol16_buf(buf, nwords * 2); ++ if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) ++ err = 1; ++ /* now correct the endianness of the byte array */ ++ ltoh16_buf(buf, nwords * 2); ++ } ++ ++ return err; ++} ++ ++/* ++* Create variable table from memory. ++* Return 0 on success, nonzero on error. ++*/ ++static int ++initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count) ++{ ++ int c = (int)(end - start); ++ ++ /* do it only when there is more than just the null string */ ++ if (c > 1) { ++ char *vp = MALLOC(osh, c); ++ ASSERT(vp); ++ if (!vp) ++ return BCME_NOMEM; ++ bcopy(start, vp, c); ++ *vars = vp; ++ *count = c; ++ } ++ else { ++ *vars = NULL; ++ *count = 0; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Initialize nonvolatile variable table from sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count) ++{ ++ uint16 w, b[64]; ++ uint8 sromrev; ++ struct ether_addr ea; ++ char eabuf[32]; ++ uint32 w32; ++ int woff, i; ++ char *vp, *base; ++ osl_t *osh = sb_osh(sbh); ++ int err; ++ ++ /* ++ * Apply CRC over SROM content regardless SROM is present or not, ++ * and use variable sromrev's existance in flash to decide ++ * if we should return an error when CRC fails or read SROM variables ++ * from flash. ++ */ ++ sprom_read_pci((void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof(b)/sizeof(b[0]), TRUE); ++ ++ /* top word of sprom contains version and crc8 */ ++ sromrev = b[63] & 0xff; ++ /* bcm4401 sroms misprogrammed */ ++ if (sromrev == 0x10) ++ sromrev = 1; ++ ++ /* srom version check */ ++ if (sromrev > 3) ++ return (-2); ++ ++ ASSERT(vars); ++ ASSERT(count); ++ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return -2; ++ ++ vp += sprintf(vp, "sromrev=%d", sromrev); ++ vp++; ++ ++ if (sromrev >= 3) { ++ /* New section takes over the 3th hardware function space */ ++ ++ /* Words 22+23 are 11a (mid) ofdm power offsets */ ++ w32 = ((uint32)b[23] << 16) | b[22]; ++ vp += sprintf(vp, "ofdmapo=%d", w32); ++ vp++; ++ ++ /* Words 24+25 are 11a (low) ofdm power offsets */ ++ w32 = ((uint32)b[25] << 16) | b[24]; ++ vp += sprintf(vp, "ofdmalpo=%d", w32); ++ vp++; ++ ++ /* Words 26+27 are 11a (high) ofdm power offsets */ ++ w32 = ((uint32)b[27] << 16) | b[26]; ++ vp += sprintf(vp, "ofdmahpo=%d", w32); ++ vp++; ++ ++ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ ++ w32 = ((uint32)b[43] << 24) | ((uint32)b[42] << 8); ++ vp += sprintf(vp, "gpiotimerval=%d", w32); ++ ++ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ ++ w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xFF) << 24) | /* oncount*/ ++ ((uint32)((unsigned char)(b[21] & 0xFF)) << 8); /* offcount */ ++ vp += sprintf(vp, "gpiotimerval=%d", w32); ++ ++ vp++; ++ } ++ ++ if (sromrev >= 2) { ++ /* New section takes over the 4th hardware function space */ ++ ++ /* Word 29 is max power 11a high/low */ ++ w = b[29]; ++ vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Words 30-32 set the 11alow pa settings, ++ * 33-35 are the 11ahigh ones. ++ */ ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]); ++ vp++; ++ vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]); ++ vp++; ++ } ++ w = b[59]; ++ if (w == 0) ++ vp += sprintf(vp, "ccode="); ++ else ++ vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); ++ vp++; ++ ++ } ++ ++ /* parameter section of sprom starts at byte offset 72 */ ++ woff = 72/2; ++ ++ /* first 6 bytes are il0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "il0macaddr=%s", eabuf); ++ vp++; ++ ++ /* next 6 bytes are et0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "et0macaddr=%s", eabuf); ++ vp++; ++ ++ /* next 6 bytes are et1macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "et1macaddr=%s", eabuf); ++ vp++; ++ ++ /* ++ * Enet phy settings one or two singles or a dual ++ * Bits 4-0 : MII address for enet0 (0x1f for not there) ++ * Bits 9-5 : MII address for enet1 (0x1f for not there) ++ * Bit 14 : Mdio for enet0 ++ * Bit 15 : Mdio for enet1 ++ */ ++ w = b[woff]; ++ vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1)); ++ vp++; ++ vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1)); ++ vp++; ++ ++ /* Word 46 has board rev, antennas 0/1 & Country code/control */ ++ w = b[46]; ++ vp += sprintf(vp, "boardrev=%d", w & 0xff); ++ vp++; ++ ++ if (sromrev > 1) ++ vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf); ++ else ++ vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf); ++ vp++; ++ ++ vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3); ++ vp++; ++ ++ vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3); ++ vp++; ++ ++ /* Words 47-49 set the (wl) pa settings */ ++ woff = 47; ++ ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]); ++ vp++; ++ vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]); ++ vp++; ++ } ++ ++ /* ++ * Words 50-51 set the customer-configured wl led behavior. ++ * 8 bits/gpio pin. High bit: activehi=0, activelo=1; ++ * LED behavior values defined in wlioctl.h . ++ */ ++ w = b[50]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* gpio0 */ ++ vp += sprintf(vp, "wl0gpio0=%d", (w & 0xff)); ++ vp++; ++ ++ /* gpio1 */ ++ vp += sprintf(vp, "wl0gpio1=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ w = b[51]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* gpio2 */ ++ vp += sprintf(vp, "wl0gpio2=%d", w & 0xff); ++ vp++; ++ ++ /* gpio3 */ ++ vp += sprintf(vp, "wl0gpio3=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ ++ /* Word 52 is max power 0/1 */ ++ w = b[52]; ++ vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Word 56 is idle tssi target 0/1 */ ++ w = b[56]; ++ vp += sprintf(vp, "pa0itssit=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Word 57 is boardflags, if not programmed make it zero */ ++ w32 = (uint32)b[57]; ++ if (w32 == 0xffff) w32 = 0; ++ if (sromrev > 1) { ++ /* Word 28 is the high bits of boardflags */ ++ w32 |= (uint32)b[28] << 16; ++ } ++ vp += sprintf(vp, "boardflags=%d", w32); ++ vp++; ++ ++ /* Word 58 is antenna gain 0/1 */ ++ w = b[58]; ++ vp += sprintf(vp, "ag0=%d", w & 0xff); ++ vp++; ++ ++ vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ if (sromrev == 1) { ++ /* set the oem string */ ++ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", ++ ((b[59] >> 8) & 0xff), (b[59] & 0xff), ++ ((b[60] >> 8) & 0xff), (b[60] & 0xff), ++ ((b[61] >> 8) & 0xff), (b[61] & 0xff), ++ ((b[62] >> 8) & 0xff), (b[62] & 0xff)); ++ vp++; ++ } else if (sromrev == 2) { ++ /* Word 60 OFDM tx power offset from CCK level */ ++ /* OFDM Power Offset - opo */ ++ vp += sprintf(vp, "opo=%d", b[60] & 0xff); ++ vp++; ++ } else { ++ /* Word 60: cck power offsets */ ++ vp += sprintf(vp, "cckpo=%d", b[60]); ++ vp++; ++ ++ /* Words 61+62: 11g ofdm power offsets */ ++ w32 = ((uint32)b[62] << 16) | b[61]; ++ vp += sprintf(vp, "ofdmgpo=%d", w32); ++ vp++; ++ } ++ ++ /* final nullbyte terminator */ ++ *vp++ = '\0'; ++ ++ ASSERT((vp - base) <= VARS_MAX); ++ ++ err = initvars_table(osh, base, vp, vars, count); ++ ++ MFREE(osh, base, VARS_MAX); ++ return err; ++} ++ +diff -urN linux.old/arch/mips/bcm947xx/broadcom/bcmutils.c linux.dev/arch/mips/bcm947xx/broadcom/bcmutils.c +--- linux.old/arch/mips/bcm947xx/broadcom/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/bcmutils.c 2005-12-28 16:37:32.814257500 +0100 +@@ -0,0 +1,356 @@ ++/* ++ * Misc useful OS-independent routines. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++unsigned char bcm_ctype[] = { ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ ++ _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ ++ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ ++ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ ++ _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ ++ _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */ ++}; ++ ++uchar ++bcm_toupper(uchar c) ++{ ++ if (bcm_islower(c)) ++ c -= 'a'-'A'; ++ return (c); ++} ++ ++ulong ++bcm_strtoul(char *cp, char **endp, uint base) ++{ ++ ulong result, value; ++ bool minus; ++ ++ minus = FALSE; ++ ++ while (bcm_isspace(*cp)) ++ cp++; ++ ++ if (cp[0] == '+') ++ cp++; ++ else if (cp[0] == '-') { ++ minus = TRUE; ++ cp++; ++ } ++ ++ if (base == 0) { ++ if (cp[0] == '0') { ++ if ((cp[1] == 'x') || (cp[1] == 'X')) { ++ base = 16; ++ cp = &cp[2]; ++ } else { ++ base = 8; ++ cp = &cp[1]; ++ } ++ } else ++ base = 10; ++ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { ++ cp = &cp[2]; ++ } ++ ++ result = 0; ++ ++ while (bcm_isxdigit(*cp) && ++ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { ++ result = result*base + value; ++ cp++; ++ } ++ ++ if (minus) ++ result = (ulong)(result * -1); ++ ++ if (endp) ++ *endp = (char *)cp; ++ ++ return (result); ++} ++ ++uint ++bcm_atoi(char *s) ++{ ++ uint n; ++ ++ n = 0; ++ ++ while (bcm_isdigit(*s)) ++ n = (n * 10) + *s++ - '0'; ++ return (n); ++} ++ ++/* return pointer to location of substring 'needle' in 'haystack' */ ++char* ++bcmstrstr(char *haystack, char *needle) ++{ ++ int len, nlen; ++ int i; ++ ++ if ((haystack == NULL) || (needle == NULL)) ++ return (haystack); ++ ++ nlen = strlen(needle); ++ len = strlen(haystack) - nlen + 1; ++ ++ for (i = 0; i < len; i++) ++ if (bcmp(needle, &haystack[i], nlen) == 0) ++ return (&haystack[i]); ++ return (NULL); ++} ++ ++char* ++bcmstrcat(char *dest, const char *src) ++{ ++ strcpy(&dest[strlen(dest)], src); ++ return (dest); ++} ++ ++ ++char* ++bcm_ether_ntoa(char *ea, char *buf) ++{ ++ sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x", ++ (uchar)ea[0]&0xff, (uchar)ea[1]&0xff, (uchar)ea[2]&0xff, ++ (uchar)ea[3]&0xff, (uchar)ea[4]&0xff, (uchar)ea[5]&0xff); ++ return (buf); ++} ++ ++/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ ++int ++bcm_ether_atoe(char *p, char *ea) ++{ ++ int i = 0; ++ ++ for (;;) { ++ ea[i++] = (char) bcm_strtoul(p, &p, 16); ++ if (!*p++ || i == 6) ++ break; ++ } ++ ++ return (i == 6); ++} ++ ++void ++bcm_mdelay(uint ms) ++{ ++ uint i; ++ ++ for (i = 0; i < ms; i++) { ++ OSL_DELAY(1000); ++ } ++} ++ ++/* ++ * Search the name=value vars for a specific one and return its value. ++ * Returns NULL if not found. ++ */ ++char* ++getvar(char *vars, char *name) ++{ ++ char *s; ++ int len; ++ ++ len = strlen(name); ++ ++ /* first look in vars[] */ ++ for (s = vars; s && *s; ) { ++ if ((bcmp(s, name, len) == 0) && (s[len] == '=')) ++ return (&s[len+1]); ++ ++ while (*s++) ++ ; ++ } ++ ++ /* then query nvram */ ++ return (BCMINIT(nvram_get)(name)); ++} ++ ++/* ++ * Search the vars for a specific one and return its value as ++ * an integer. Returns 0 if not found. ++ */ ++int ++getintvar(char *vars, char *name) ++{ ++ char *val; ++ ++ if ((val = getvar(vars, name)) == NULL) ++ return (0); ++ ++ return (bcm_strtoul(val, NULL, 0)); ++} ++ ++ ++/* Search for token in comma separated token-string */ ++static int ++findmatch(char *string, char *name) ++{ ++ uint len; ++ char *c; ++ ++ len = strlen(name); ++ while ((c = strchr(string, ',')) != NULL) { ++ if (len == (uint)(c - string) && !strncmp(string, name, len)) ++ return 1; ++ string = c + 1; ++ } ++ ++ return (!strcmp(string, name)); ++} ++ ++/* Return gpio pin number assigned to the named pin */ ++/* ++* Variable should be in format: ++* ++* gpio=pin_name,pin_name ++* ++* This format allows multiple features to share the gpio with mutual ++* understanding. ++* ++* 'def_pin' is returned if a specific gpio is not defined for the requested functionality ++* and if def_pin is not used by others. ++*/ ++uint ++getgpiopin(char *vars, char *pin_name, uint def_pin) ++{ ++ char name[] = "gpioXXXX"; ++ char *val; ++ uint pin; ++ ++ /* Go thru all possibilities till a match in pin name */ ++ for (pin = 0; pin < GPIO_NUMPINS; pin ++) { ++ sprintf(name, "gpio%d", pin); ++ val = getvar(vars, name); ++ if (val && findmatch(val, pin_name)) ++ return pin; ++ } ++ ++ if (def_pin != GPIO_PIN_NOTDEFINED) { ++ /* make sure the default pin is not used by someone else */ ++ sprintf(name, "gpio%d", def_pin); ++ if (getvar(vars, name)) { ++ def_pin = GPIO_PIN_NOTDEFINED; ++ } ++ } ++ ++ return def_pin; ++} ++ ++ ++/******************************************************************************* ++ * crc8 ++ * ++ * Computes a crc8 over the input data using the polynomial: ++ * ++ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 ++ * ++ * The caller provides the initial value (either CRC8_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC8_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ ******************************************************************************/ ++ ++static uint8 crc8_table[256] = { ++ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, ++ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, ++ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, ++ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, ++ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, ++ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, ++ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, ++ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, ++ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, ++ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, ++ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, ++ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, ++ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, ++ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, ++ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, ++ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, ++ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, ++ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, ++ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, ++ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, ++ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, ++ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, ++ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, ++ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, ++ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, ++ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, ++ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, ++ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, ++ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, ++ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, ++ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, ++ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F ++}; ++ ++#define CRC_INNER_LOOP(n, c, x) \ ++ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] ++ ++uint8 ++hndcrc8( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ ++) ++{ ++ /* hard code the crc loop instead of using CRC_INNER_LOOP macro ++ * to avoid the undefined and unnecessary (uint8 >> 8) operation. */ ++ while (nbytes-- > 0) ++ crc = crc8_table[(crc ^ *pdata++) & 0xff]; ++ ++ return crc; ++} ++ ++#ifdef notdef ++#define CLEN 1499 ++#define CBUFSIZ (CLEN+4) ++#define CNBUFS 5 ++ ++#endif +diff -urN linux.old/arch/mips/bcm947xx/broadcom/cfe_env.c linux.dev/arch/mips/bcm947xx/broadcom/cfe_env.c +--- linux.old/arch/mips/bcm947xx/broadcom/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/cfe_env.c 2005-12-28 16:37:32.818257750 +0100 +@@ -0,0 +1,234 @@ ++/* ++ * NVRAM variable manipulation (Linux kernel half) ++ * ++ * Copyright 2001-2003, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define NVRAM_SIZE (0x1ff0) ++static char _nvdata[NVRAM_SIZE] __initdata; ++static char _valuestr[256] __initdata; ++ ++/* ++ * TLV types. These codes are used in the "type-length-value" ++ * encoding of the items stored in the NVRAM device (flash or EEPROM) ++ * ++ * The layout of the flash/nvram is as follows: ++ * ++ * ++ * ++ * The type code of "ENV_TLV_TYPE_END" marks the end of the list. ++ * The "length" field marks the length of the data section, not ++ * including the type and length fields. ++ * ++ * Environment variables are stored as follows: ++ * ++ * = ++ * ++ * If bit 0 (low bit) is set, the length is an 8-bit value. ++ * If bit 0 (low bit) is clear, the length is a 16-bit value ++ * ++ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still ++ * indicates the size of the length field. ++ * ++ * Flags are from the constants below: ++ * ++ */ ++#define ENV_LENGTH_16BITS 0x00 /* for low bit */ ++#define ENV_LENGTH_8BITS 0x01 ++ ++#define ENV_TYPE_USER 0x80 ++ ++#define ENV_CODE_SYS(n,l) (((n)<<1)|(l)) ++#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER) ++ ++/* ++ * The actual TLV types we support ++ */ ++ ++#define ENV_TLV_TYPE_END 0x00 ++#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS) ++ ++/* ++ * Environment variable flags ++ */ ++ ++#define ENV_FLG_NORMAL 0x00 /* normal read/write */ ++#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */ ++#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */ ++ ++#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */ ++#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */ ++ ++ ++/* ********************************************************************* ++ * _nvram_read(buffer,offset,length) ++ * ++ * Read data from the NVRAM device ++ * ++ * Input parameters: ++ * buffer - destination buffer ++ * offset - offset of data to read ++ * length - number of bytes to read ++ * ++ * Return value: ++ * number of bytes read, or <0 if error occured ++ ********************************************************************* */ ++static int ++_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length) ++{ ++ int i; ++ if (offset > NVRAM_SIZE) ++ return -1; ++ ++ for ( i = 0; i < length; i++) { ++ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i]; ++ } ++ return length; ++} ++ ++ ++static char* ++_strnchr(const char *dest,int c,size_t cnt) ++{ ++ while (*dest && (cnt > 0)) { ++ if (*dest == c) return (char *) dest; ++ dest++; ++ cnt--; ++ } ++ return NULL; ++} ++ ++ ++ ++/* ++ * Core support API: Externally visible. ++ */ ++ ++/* ++ * Get the value of an NVRAM variable ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++ ++char* ++cfe_env_get(unsigned char *nv_buf, char* name) ++{ ++ int size; ++ unsigned char *buffer; ++ unsigned char *ptr; ++ unsigned char *envval; ++ unsigned int reclen; ++ unsigned int rectype; ++ int offset; ++ int flg; ++ ++ size = NVRAM_SIZE; ++ buffer = &_nvdata[0]; ++ ++ ptr = buffer; ++ offset = 0; ++ ++ /* Read the record type and length */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ ++ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) { ++ ++ /* Adjust pointer for TLV type */ ++ rectype = *(ptr); ++ offset++; ++ size--; ++ ++ /* ++ * Read the length. It can be either 1 or 2 bytes ++ * depending on the code ++ */ ++ if (rectype & ENV_LENGTH_8BITS) { ++ /* Read the record type and length - 8 bits */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ reclen = *(ptr); ++ size--; ++ offset++; ++ } ++ else { ++ /* Read the record type and length - 16 bits, MSB first */ ++ if (_nvram_read(nv_buf, ptr,offset,2) != 2) { ++ goto error; ++ } ++ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); ++ size -= 2; ++ offset += 2; ++ } ++ ++ if (reclen > size) ++ break; /* should not happen, bad NVRAM */ ++ ++ switch (rectype) { ++ case ENV_TLV_TYPE_ENV: ++ /* Read the TLV data */ ++ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen) ++ goto error; ++ flg = *ptr++; ++ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1)); ++ if (envval) { ++ *envval++ = '\0'; ++ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr)); ++ _valuestr[(reclen-1)-(envval-ptr)] = '\0'; ++#if 0 ++ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr); ++#endif ++ if(!strcmp(ptr, name)){ ++ return _valuestr; ++ } ++ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name)) ++ return _valuestr; ++ } ++ break; ++ ++ default: ++ /* Unknown TLV type, skip it. */ ++ break; ++ } ++ ++ /* ++ * Advance to next TLV ++ */ ++ ++ size -= (int)reclen; ++ offset += reclen; ++ ++ /* Read the next record type */ ++ ptr = buffer; ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) ++ goto error; ++ } ++ ++error: ++ return NULL; ++ ++} ++ +diff -urN linux.old/arch/mips/bcm947xx/broadcom/linux_osl.c linux.dev/arch/mips/bcm947xx/broadcom/linux_osl.c +--- linux.old/arch/mips/bcm947xx/broadcom/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/linux_osl.c 2005-12-28 16:37:32.834258750 +0100 +@@ -0,0 +1,102 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#define LINUX_OSL ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef mips ++#include ++#endif ++#include ++ ++#define PCI_CFG_RETRY 10 ++ ++#define OS_HANDLE_MAGIC 0x1234abcd ++#define BCM_MEM_FILENAME_LEN 24 ++ ++typedef struct bcm_mem_link { ++ struct bcm_mem_link *prev; ++ struct bcm_mem_link *next; ++ uint size; ++ int line; ++ char file[BCM_MEM_FILENAME_LEN]; ++} bcm_mem_link_t; ++ ++struct os_handle { ++ uint magic; ++ void *pdev; ++ uint malloced; ++ uint failed; ++ bcm_mem_link_t *dbgmem_list; ++}; ++ ++uint32 ++osl_pci_read_config(osl_t *osh, uint offset, uint size) ++{ ++ uint val; ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_read_config_dword(osh->pdev, offset, &val); ++ if (val != 0xffffffff) ++ break; ++ } while (retry--); ++ ++ ++ return (val); ++} ++ ++void ++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++{ ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_write_config_dword(osh->pdev, offset, val); ++ if (offset!=PCI_BAR0_WIN) ++ break; ++ if (osl_pci_read_config(osh,offset,size) == val) ++ break; ++ } while (retry--); ++ ++} ++ ++void ++osl_delay(uint usec) ++{ ++ uint d; ++ ++ while (usec > 0) { ++ d = MIN(usec, 1000); ++ udelay(d); ++ usec -= d; ++ } ++} ++ +diff -urN linux.old/arch/mips/bcm947xx/broadcom/nvram.c linux.dev/arch/mips/bcm947xx/broadcom/nvram.c +--- linux.old/arch/mips/bcm947xx/broadcom/nvram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/nvram.c 2005-12-28 19:30:54.804469750 +0100 +@@ -0,0 +1,192 @@ ++/* ++ * NVRAM variable manipulation (Linux kernel half) ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* In BSS to minimize text size and page aligned so it can be mmap()-ed */ ++static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE))); ++ ++/* Global SB handle */ ++extern void *sbh; ++extern spinlock_t bcm947xx_sbh_lock; ++static int cfe_env; ++ ++extern char *cfe_env_get(char *nv_buf, const char *name); ++ ++ ++/* Convenience */ ++#define sbh_lock bcm947xx_sbh_lock ++#define KB * 1024 ++#define MB * 1024 * 1024 ++ ++/* Probe for NVRAM header */ ++static void __init ++early_nvram_init(void) ++{ ++ struct nvram_header *header; ++ chipcregs_t *cc; ++ struct sflash *info = NULL; ++ int i; ++ uint32 base, off, lim; ++ u32 *src, *dst; ++ ++ cfe_env = 0; ++ if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) { ++ base = KSEG1ADDR(SB_FLASH2); ++ switch (readl(&cc->capabilities) & CAP_FLASH_MASK) { ++ case PFLASH: ++ lim = SB_FLASH2_SZ; ++ break; ++ ++ case SFLASH_ST: ++ case SFLASH_AT: ++ if ((info = sflash_init(cc)) == NULL) ++ return; ++ lim = info->size; ++ break; ++ ++ case FLASH_NONE: ++ default: ++ return; ++ } ++ } else { ++ /* extif assumed, Stop at 4 MB */ ++ base = KSEG1ADDR(SB_FLASH1); ++ lim = SB_FLASH1_SZ; ++ } ++ ++ /* XXX: hack for supporting the CFE environment stuff on WGT634U */ ++ src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); ++ dst = (u32 *) nvram_buf; ++ if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) { ++ printk("early_nvram_init: WGT634U NVRAM found.\n"); ++ ++ for (i = 0; i < 0x1ff0; i++) { ++ if (*src == 0xFFFFFFFF) ++ break; ++ *dst++ = *src++; ++ } ++ cfe_env = 1; ++ return; ++ } ++ ++ off = FLASH_MIN; ++ while (off <= lim) { ++ /* Windowed flash access */ ++ header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ off <<= 1; ++ } ++ ++ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ ++ header = (struct nvram_header *) KSEG1ADDR(base + 4 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ header = (struct nvram_header *) KSEG1ADDR(base + 1 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ return; ++ ++found: ++ src = (u32 *) header; ++ dst = (u32 *) nvram_buf; ++ for (i = 0; i < sizeof(struct nvram_header); i += 4) ++ *dst++ = *src++; ++ for (; i < header->len && i < NVRAM_SPACE; i += 4) ++ *dst++ = ltoh32(*src++); ++} ++ ++/* Early (before mm or mtd) read-only access to NVRAM */ ++char * __init early_nvram_get(const char *name) ++{ ++ char *var, *value, *end, *eq; ++ ++ if (!name) ++ return NULL; ++ ++ /* Too early? */ ++ if (sbh == NULL) ++ return NULL; ++ ++ if (!nvram_buf[0]) ++ early_nvram_init(); ++ ++ if (cfe_env) ++ return cfe_env_get(nvram_buf, name); ++ ++ /* Look for name=value and return value */ ++ var = &nvram_buf[sizeof(struct nvram_header)]; ++ end = nvram_buf + sizeof(nvram_buf) - 2; ++ end[0] = end[1] = '\0'; ++ for (; *var; var = value + strlen(value) + 1) { ++ if (!(eq = strchr(var, '='))) ++ break; ++ value = eq + 1; ++ if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) ++ return value; ++ } ++ ++ return NULL; ++} ++ ++char *nvram_get(const char *name) ++{ ++ char *var, *value, *end, *eq; ++ ++ if (!name) ++ return NULL; ++ ++ if (!nvram_buf[0]) ++ return NULL; ++ ++ /* Look for name=value and return value */ ++ var = &nvram_buf[sizeof(struct nvram_header)]; ++ end = nvram_buf + sizeof(nvram_buf) - 2; ++ end[0] = end[1] = '\0'; ++ for (; *var; var = value + strlen(value) + 1) { ++ if (!(eq = strchr(var, '='))) ++ break; ++ value = eq + 1; ++ if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) ++ return value; ++ } ++ ++ return NULL; ++} ++ ++EXPORT_SYMBOL(nvram_get); +diff -urN linux.old/arch/mips/bcm947xx/broadcom/sbmips.c linux.dev/arch/mips/bcm947xx/broadcom/sbmips.c +--- linux.old/arch/mips/bcm947xx/broadcom/sbmips.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/sbmips.c 2005-12-28 19:19:50.570957750 +0100 +@@ -0,0 +1,1038 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane MIPS core routines ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Returns TRUE if an external UART exists at the given base ++ * register. ++ */ ++static bool ++BCMINITFN(serial_exists)(uint8 *regs) ++{ ++ uint8 save_mcr, status1; ++ ++ save_mcr = R_REG(®s[UART_MCR]); ++ W_REG(®s[UART_MCR], UART_MCR_LOOP | 0x0a); ++ status1 = R_REG(®s[UART_MSR]) & 0xf0; ++ W_REG(®s[UART_MCR], save_mcr); ++ ++ return (status1 == 0x90); ++} ++ ++/* ++ * Initializes UART access. The callback function will be called once ++ * per found UART. ++ */ ++void ++BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) ++{ ++ void *regs; ++ ulong base; ++ uint irq; ++ int i, n; ++ ++ if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) { ++ extifregs_t *eir = (extifregs_t *) regs; ++ sbconfig_t *sb; ++ ++ /* Determine external UART register base */ ++ sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF); ++ base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1))); ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ /* Disable GPIO interrupt initially */ ++ W_REG(&eir->gpiointpolarity, 0); ++ W_REG(&eir->gpiointmask, 0); ++ ++ /* Search for external UARTs */ ++ n = 2; ++ for (i = 0; i < 2; i++) { ++ regs = (void *) REG_MAP(base + (i * 8), 8); ++ if (BCMINIT(serial_exists)(regs)) { ++ /* Set GPIO 1 to be the external UART IRQ */ ++ W_REG(&eir->gpiointmask, 2); ++ if (add) ++ add(regs, irq, 13500000, 0); ++ } ++ } ++ ++ /* Add internal UART if enabled */ ++ if (R_REG(&eir->corecontrol) & CC_UE) ++ if (add) ++ add((void *) &eir->uartdata, irq, sb_clock(sbh), 2); ++ } else if ((regs = sb_setcore(sbh, SB_CC, 0))) { ++ chipcregs_t *cc = (chipcregs_t *) regs; ++ uint32 rev, cap, pll, baud_base, div; ++ ++ /* Determine core revision and capabilities */ ++ rev = sb_corerev(sbh); ++ cap = R_REG(&cc->capabilities); ++ pll = cap & CAP_PLL_MASK; ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ if (pll == PLL_TYPE1) { ++ /* PLL clock */ ++ baud_base = sb_clock_rate(pll, ++ R_REG(&cc->clockcontrol_n), ++ R_REG(&cc->clockcontrol_m2)); ++ div = 1; ++ } else { ++ if (rev >= 11) { ++ /* Fixed ALP clock */ ++ baud_base = 20000000; ++ div = 1; ++ /* Set the override bit so we don't divide it */ ++ W_REG(&cc->corecontrol, CC_UARTCLKO); ++ } else if (rev >= 3) { ++ /* Internal backplane clock */ ++ baud_base = sb_clock(sbh); ++ div = 2; /* Minimum divisor */ ++ W_REG(&cc->clkdiv, ++ ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div)); ++ } else { ++ /* Fixed internal backplane clock */ ++ baud_base = 88000000; ++ div = 48; ++ } ++ ++ /* Clock source depends on strapping if UartClkOverride is unset */ ++ if ((rev > 0) && ++ ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) { ++ if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) { ++ /* Internal divided backplane clock */ ++ baud_base /= div; ++ } else { ++ /* Assume external clock of 1.8432 MHz */ ++ baud_base = 1843200; ++ } ++ } ++ } ++ ++ /* Add internal UARTs */ ++ n = cap & CAP_UARTS_MASK; ++ for (i = 0; i < n; i++) { ++ /* Register offset changed after revision 0 */ ++ if (rev) ++ regs = (void *)((ulong) &cc->uart0data + (i * 256)); ++ else ++ regs = (void *)((ulong) &cc->uart0data + (i * 8)); ++ ++ if (add) ++ add(regs, irq, baud_base, 0); ++ } ++ } ++} ++ ++/* ++ * Initialize jtag master and return handle for ++ * jtag_rwreg. Returns NULL on failure. ++ */ ++void * ++sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap) ++{ ++ void *regs; ++ ++ if ((regs = sb_setcore(sbh, SB_CC, 0)) != NULL) { ++ chipcregs_t *cc = (chipcregs_t *) regs; ++ uint32 tmp; ++ ++ /* ++ * Determine jtagm availability from ++ * core revision and capabilities. ++ */ ++ tmp = sb_corerev(sbh); ++ /* ++ * Corerev 10 has jtagm, but the only chip ++ * with it does not have a mips, and ++ * the layout of the jtagcmd register is ++ * different. We'll only accept >= 11. ++ */ ++ if (tmp < 11) ++ return (NULL); ++ ++ tmp = R_REG(&cc->capabilities); ++ if ((tmp & CAP_JTAGP) == 0) ++ return (NULL); ++ ++ /* Set clock divider if requested */ ++ if (clkd != 0) { ++ tmp = R_REG(&cc->clkdiv); ++ tmp = (tmp & ~CLKD_JTAG) | ++ ((clkd << CLKD_JTAG_SHIFT) & CLKD_JTAG); ++ W_REG(&cc->clkdiv, tmp); ++ } ++ ++ /* Enable jtagm */ ++ tmp = JCTRL_EN | (exttap ? JCTRL_EXT_EN : 0); ++ W_REG(&cc->jtagctrl, tmp); ++ } ++ ++ return (regs); ++} ++ ++void ++sb_jtagm_disable(void *h) ++{ ++ chipcregs_t *cc = (chipcregs_t *)h; ++ ++ W_REG(&cc->jtagctrl, R_REG(&cc->jtagctrl) & ~JCTRL_EN); ++} ++ ++/* ++ * Read/write a jtag register. Assumes a target with ++ * 8 bit IR and 32 bit DR. ++ */ ++#define IRWIDTH 8 ++#define DRWIDTH 32 ++uint32 ++jtag_rwreg(void *h, uint32 ir, uint32 dr) ++{ ++ chipcregs_t *cc = (chipcregs_t *) h; ++ uint32 tmp; ++ ++ W_REG(&cc->jtagir, ir); ++ W_REG(&cc->jtagdr, dr); ++ tmp = JCMD_START | JCMD_ACC_IRDR | ++ ((IRWIDTH - 1) << JCMD_IRW_SHIFT) | ++ (DRWIDTH - 1); ++ W_REG(&cc->jtagcmd, tmp); ++ while (((tmp = R_REG(&cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) { ++ /* OSL_DELAY(1); */ ++ } ++ ++ tmp = R_REG(&cc->jtagdr); ++ return (tmp); ++} ++ ++/* Returns the SB interrupt flag of the current core. */ ++uint32 ++sb_flag(sb_t *sbh) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ regs = sb_coreregs(sbh); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK); ++} ++ ++static const uint32 sbips_int_mask[] = { ++ 0, ++ SBIPS_INT1_MASK, ++ SBIPS_INT2_MASK, ++ SBIPS_INT3_MASK, ++ SBIPS_INT4_MASK ++}; ++ ++static const uint32 sbips_int_shift[] = { ++ 0, ++ 0, ++ SBIPS_INT2_SHIFT, ++ SBIPS_INT3_SHIFT, ++ SBIPS_INT4_SHIFT ++}; ++ ++/* ++ * Returns the MIPS IRQ assignment of the current core. If unassigned, ++ * 0 is returned. ++ */ ++uint ++sb_irq(sb_t *sbh) ++{ ++ uint idx; ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag, sbipsflag; ++ uint irq = 0; ++ ++ flag = sb_flag(sbh); ++ ++ idx = sb_coreidx(sbh); ++ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */ ++ sbipsflag = R_REG(&sb->sbipsflag); ++ for (irq = 1; irq <= 4; irq++) { ++ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag) ++ break; ++ } ++ if (irq == 5) ++ irq = 0; ++ } ++ ++ sb_setcoreidx(sbh, idx); ++ ++ return irq; ++} ++ ++/* Clears the specified MIPS IRQ. */ ++static void ++BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ W_REG(&sb->sbintvec, 0); ++ else ++ OR_REG(&sb->sbipsflag, sbips_int_mask[irq]); ++} ++ ++/* ++ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS ++ * IRQ 0 may be assigned more than once. ++ */ ++static void ++BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag; ++ ++ regs = sb_setcore(sbh, coreid, coreunit); ++ ASSERT(regs); ++ flag = sb_flag(sbh); ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ OR_REG(&sb->sbintvec, 1 << flag); ++ else { ++ flag <<= sbips_int_shift[irq]; ++ ASSERT(!(flag & ~sbips_int_mask[irq])); ++ flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq]; ++ W_REG(&sb->sbipsflag, flag); ++ } ++} ++ ++/* ++ * Initializes clocks and interrupts. SB and NVRAM access must be ++ * initialized prior to calling. ++ */ ++void ++BCMINITFN(sb_mips_init)(sb_t *sbh) ++{ ++ ulong hz, ns, tmp; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ char *value; ++ uint irq; ++ ++ /* Figure out current SB clock speed */ ++ if ((hz = sb_clock(sbh)) == 0) ++ hz = 100000000; ++ ns = 1000000000 / hz; ++ ++ /* Setup external interface timing */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ /* Initialize extif so we can get to the LEDs and external UART */ ++ W_REG(&eir->prog_config, CF_EN); ++ ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++ ++ /* Set programmable interface timing for external uart */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */ ++ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++ } else if ((cc = sb_setcore(sbh, SB_CC, 0))) { ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */ ++ tmp |= CEIL(120, ns); /* W0 = 120nS */ ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { ++ W_REG(&cc->flash_waitcount, tmp); ++ W_REG(&cc->pcmcia_memwait, tmp); ++ } ++ else ++ { ++ if (sb_corerev(sbh) < 9) ++ W_REG(&cc->flash_waitcount, tmp); ++ ++ if ((sb_corerev(sbh) < 9) || ++ ((BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) && BCMINIT(sb_chiprev)(sbh) == 0)) { ++ W_REG(&cc->pcmcia_memwait, tmp); ++ } ++ } ++ } ++ ++ /* Chip specific initialization */ ++ switch (BCMINIT(sb_chip)(sbh)) { ++ case BCM4710_DEVICE_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ BCMINIT(sb_clearirq)(sbh, irq); ++ BCMINIT(sb_setirq)(sbh, 0, SB_CODEC, 0); ++ BCMINIT(sb_setirq)(sbh, 0, SB_EXTIF, 0); ++ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 1); ++ BCMINIT(sb_setirq)(sbh, 3, SB_ILINE20, 0); ++ BCMINIT(sb_setirq)(sbh, 4, SB_PCI, 0); ++ ASSERT(eir); ++ value = BCMINIT(early_nvram_get)("et0phyaddr"); ++ if (value && !strcmp(value, "31")) { ++ /* Enable internal UART */ ++ W_REG(&eir->corecontrol, CC_UE); ++ /* Give USB its own interrupt */ ++ BCMINIT(sb_setirq)(sbh, 1, SB_USB, 0); ++ } else { ++ /* Disable internal UART */ ++ W_REG(&eir->corecontrol, 0); ++ /* Give Ethernet its own interrupt */ ++ BCMINIT(sb_setirq)(sbh, 1, SB_ENET, 0); ++ BCMINIT(sb_setirq)(sbh, 0, SB_USB, 0); ++ } ++ break; ++ case BCM5350_DEVICE_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ BCMINIT(sb_clearirq)(sbh, irq); ++ BCMINIT(sb_setirq)(sbh, 0, SB_CC, 0); ++ BCMINIT(sb_setirq)(sbh, 1, SB_D11, 0); ++ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 0); ++ BCMINIT(sb_setirq)(sbh, 3, SB_PCI, 0); ++ BCMINIT(sb_setirq)(sbh, 4, SB_USB, 0); ++ break; ++ } ++} ++ ++uint32 ++BCMINITFN(sb_mips_clock)(sb_t *sbh) ++{ ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate = 0; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ pll_type = PLL_TYPE1; ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE5) { ++ rate = 200000000; ++ goto out; ++ } ++ else if (pll_type == PLL_TYPE3) { ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) { /* 5365 is also type3 */ ++ rate = 200000000; ++ goto out; ++ } else ++ m = R_REG(&cc->clockcontrol_m2); /* 5350 uses m2 to control mips */ ++ } else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else ++ goto out; ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ rate = 100000000; ++ else ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ ++ if (pll_type == PLL_TYPE6) ++ rate = SB2MIPS_T6(rate); ++ ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return rate; ++} ++ ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) ++ ++static void ++BCMINITFN(handler)(void) ++{ ++ /* Step 11 */ ++ __asm__ ( ++ ".set\tmips32\n\t" ++ "ssnop\n\t" ++ "ssnop\n\t" ++ /* Disable interrupts */ ++ /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */ ++ "mfc0 $15, $12\n\t" ++ /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */ ++ "li $14, -31746\n\t" ++ "and $15, $15, $14\n\t" ++ "mtc0 $15, $12\n\t" ++ "eret\n\t" ++ "nop\n\t" ++ "nop\n\t" ++ ".set\tmips0" ++ ); ++} ++ ++/* The following MUST come right after handler() */ ++static void ++BCMINITFN(afterhandler)(void) ++{ ++} ++ ++/* ++ * Set the MIPS, backplane and PCI clocks as closely as possible. ++ */ ++bool ++BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock) ++{ ++ extifregs_t *eir = NULL; ++ chipcregs_t *cc = NULL; ++ mipsregs_t *mipsr = NULL; ++ volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2; ++ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg; ++ uint32 pll_type, sync_mode; ++ uint ic_size, ic_lsize; ++ uint idx, i; ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 pci25; ++ } n3m_table_t; ++ static n3m_table_t BCMINITDATA(type1_table)[] = { ++ { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */ ++ { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */ ++ { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */ ++ { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */ ++ { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */ ++ { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */ ++ { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */ ++ { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */ ++ { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */ ++ { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */ ++ { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */ ++ { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */ ++ { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */ ++ { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */ ++ { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */ ++ { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */ ++ { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */ ++ { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */ ++ { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */ ++ { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */ ++ }; ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 m2; /* that is the clockcontrol_m2 */ ++ } type3_table_t; ++ static type3_table_t type3_table[] = { /* for 5350, mips clock is always double sb clock */ ++ { 150000000, 0x311, 0x4020005 }, ++ { 200000000, 0x311, 0x4020003 }, ++ }; ++ typedef struct { ++ uint32 mipsclock; ++ uint32 sbclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 m2; ++ uint32 m3; ++ uint32 ratio_cfg; ++ uint32 ratio_parm; ++ } n4m_table_t; ++ ++ static n4m_table_t BCMINITDATA(type2_table)[] = { ++ { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555 }, ++ { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, ++ { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, ++ { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 11, 0x0aaa0555 } ++ }; ++ ++ static n4m_table_t BCMINITDATA(type4_table)[] = { ++ { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, ++ { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8, 0x012a00a9 }, ++ { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, 0x254a14a9 }, ++ { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9, 0x02520129 }, ++ { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, ++ { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9, 0x02520129 }, ++ { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, 0x0aaa0555 } ++ }; ++ ++ static n4m_table_t BCMINITDATA(type7_table)[] = { ++ { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, ++ { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, 0x0aaa0555 }, ++ { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, 0x0aaa0555 } ++ }; ++ ++ ulong start, end, dst; ++ bool ret = FALSE; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ clockcontrol_m2 = NULL; ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ pll_type = PLL_TYPE1; ++ clockcontrol_n = &eir->clockcontrol_n; ++ clockcontrol_sb = &eir->clockcontrol_sb; ++ clockcontrol_pci = &eir->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ if (pll_type == PLL_TYPE6) { ++ clockcontrol_n = NULL; ++ clockcontrol_sb = NULL; ++ clockcontrol_pci = NULL; ++ } else { ++ clockcontrol_n = &cc->clockcontrol_n; ++ clockcontrol_sb = &cc->clockcontrol_sb; ++ clockcontrol_pci = &cc->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } ++ } else ++ goto done; ++ ++ if (pll_type == PLL_TYPE6) { ++ /* Silence compilers */ ++ orig_n = orig_sb = orig_pci = 0; ++ } else { ++ /* Store the current clock register values */ ++ orig_n = R_REG(clockcontrol_n); ++ orig_sb = R_REG(clockcontrol_sb); ++ orig_pci = R_REG(clockcontrol_pci); ++ } ++ ++ if (pll_type == PLL_TYPE1) { ++ /* Keep the current PCI clock if not specified */ ++ if (pciclock == 0) { ++ pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci)); ++ pciclock = (pciclock <= 25000000) ? 25000000 : 33000000; ++ } ++ ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(type1_table)); i++) { ++ ASSERT(BCMINIT(type1_table)[i].mipsclock == ++ sb_clock_rate(pll_type, BCMINIT(type1_table)[i].n, BCMINIT(type1_table)[i].sb)); ++ if (BCMINIT(type1_table)[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(BCMINIT(type1_table)[i].mipsclock <= mipsclock); ++ ++ /* No PLL change */ ++ if ((orig_n == BCMINIT(type1_table)[i].n) && ++ (orig_sb == BCMINIT(type1_table)[i].sb) && ++ (orig_pci == BCMINIT(type1_table)[i].pci33)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, BCMINIT(type1_table)[i].n); ++ W_REG(clockcontrol_sb, BCMINIT(type1_table)[i].sb); ++ if (pciclock == 25000000) ++ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci25); ++ else ++ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci33); ++ ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ ++ while (1); ++ } else if ((pll_type == PLL_TYPE3) && ++ (BCMINIT(sb_chip)(sbh) != BCM5365_DEVICE_ID)) { ++ /* 5350 */ ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ ++ for (i = 0; i < ARRAYSIZE(type3_table); i++) { ++ if (type3_table[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(type3_table[i].mipsclock <= mipsclock); ++ ++ /* No PLL change */ ++ orig_m2 = R_REG(&cc->clockcontrol_m2); ++ if ((orig_n == type3_table[i].n) && ++ (orig_m2 == type3_table[i].m2)) { ++ goto done; ++ } ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, type3_table[i].n); ++ W_REG(clockcontrol_m2, type3_table[i].m2); ++ ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ while (1); ++ } else if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) { ++ n4m_table_t *table = NULL, *te; ++ uint tabsz = 0; ++ ++ ASSERT(cc); ++ ++ orig_mips = R_REG(&cc->clockcontrol_mips); ++ ++ if (pll_type == PLL_TYPE6) { ++ uint32 new_mips = 0; ++ ++ ret = TRUE; ++ if (mipsclock <= SB2MIPS_T6(CC_T6_M1)) ++ new_mips = CC_T6_MMASK; ++ ++ if (orig_mips == new_mips) ++ goto done; ++ ++ W_REG(&cc->clockcontrol_mips, new_mips); ++ goto end_fill; ++ } ++ ++ if (pll_type == PLL_TYPE2) { ++ table = BCMINIT(type2_table); ++ tabsz = ARRAYSIZE(BCMINIT(type2_table)); ++ } else if (pll_type == PLL_TYPE4) { ++ table = BCMINIT(type4_table); ++ tabsz = ARRAYSIZE(BCMINIT(type4_table)); ++ } else if (pll_type == PLL_TYPE7) { ++ table = BCMINIT(type7_table); ++ tabsz = ARRAYSIZE(BCMINIT(type7_table)); ++ } else ++ ASSERT("No table for plltype" == NULL); ++ ++ /* Store the current clock register values */ ++ orig_m2 = R_REG(&cc->clockcontrol_m2); ++ orig_ratio_parm = 0; ++ orig_ratio_cfg = 0; ++ ++ /* Look up current ratio */ ++ for (i = 0; i < tabsz; i++) { ++ if ((orig_n == table[i].n) && ++ (orig_sb == table[i].sb) && ++ (orig_pci == table[i].pci33) && ++ (orig_m2 == table[i].m2) && ++ (orig_mips == table[i].m3)) { ++ orig_ratio_parm = table[i].ratio_parm; ++ orig_ratio_cfg = table[i].ratio_cfg; ++ break; ++ } ++ } ++ ++ /* Search for the closest MIPS clock greater or equal to a preferred value */ ++ for (i = 0; i < tabsz; i++) { ++ ASSERT(table[i].mipsclock == ++ sb_clock_rate(pll_type, table[i].n, table[i].m3)); ++ if ((mipsclock <= table[i].mipsclock) && ++ ((sbclock == 0) || (sbclock <= table[i].sbclock))) ++ break; ++ } ++ if (i == tabsz) { ++ ret = FALSE; ++ goto done; ++ } else { ++ te = &table[i]; ++ ret = TRUE; ++ } ++ ++ /* No PLL change */ ++ if ((orig_n == te->n) && ++ (orig_sb == te->sb) && ++ (orig_pci == te->pci33) && ++ (orig_m2 == te->m2) && ++ (orig_mips == te->m3)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, te->n); ++ W_REG(clockcontrol_sb, te->sb); ++ W_REG(clockcontrol_pci, te->pci33); ++ W_REG(&cc->clockcontrol_m2, te->m2); ++ W_REG(&cc->clockcontrol_mips, te->m3); ++ ++ /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */ ++ if ((pll_type == PLL_TYPE7) && ++ (te->sb != te->m2) && ++ (sb_clock_rate(pll_type, te->n, te->m2) == 120000000)) ++ W_REG(&cc->chipcontrol, R_REG(&cc->chipcontrol) | 0x100); ++ ++ /* No ratio change */ ++ if (orig_ratio_parm == te->ratio_parm) ++ goto end_fill; ++ ++ icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize); ++ ++ /* Preload the code into the cache */ ++ start = ((ulong) &&start_fill) & ~(ic_lsize - 1); ++ end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); ++ while (start < end) { ++ cache_op(start, Fill_I); ++ start += ic_lsize; ++ } ++ ++ /* Copy the handler */ ++ start = (ulong) &BCMINIT(handler); ++ end = (ulong) &BCMINIT(afterhandler); ++ dst = KSEG1ADDR(0x180); ++ for (i = 0; i < (end - start); i += 4) ++ *((ulong *)(dst + i)) = *((ulong *)(start + i)); ++ ++ /* Preload handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += 4) ++ cache_op(dst + i, Fill_I); ++ ++ /* Clear BEV bit */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV); ++ ++ /* Enable interrupts */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE)); ++ ++ /* Enable MIPS timer interrupt */ ++ if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(mipsr = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(mipsr); ++ W_REG(&mipsr->intmask, 1); ++ ++ start_fill: ++ /* step 1, set clock ratios */ ++ MTC0(C0_BROADCOM, 3, te->ratio_parm); ++ MTC0(C0_BROADCOM, 1, te->ratio_cfg); ++ ++ /* step 2: program timer intr */ ++ W_REG(&mipsr->timer, 100); ++ (void) R_REG(&mipsr->timer); ++ ++ /* step 3, switch to async */ ++ sync_mode = MFC0(C0_BROADCOM, 4); ++ MTC0(C0_BROADCOM, 4, 1 << 22); ++ ++ /* step 4, set cfg active */ ++ MTC0(C0_BROADCOM, 2, 0x9); ++ ++ ++ /* steps 5 & 6 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ ++ /* step 7, clear cfg_active */ ++ MTC0(C0_BROADCOM, 2, 0); ++ ++ /* Additional Step: set back to orig sync mode */ ++ MTC0(C0_BROADCOM, 4, sync_mode); ++ ++ /* step 8, fake soft reset */ ++ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4); ++ ++ end_fill: ++ /* step 9 set watchdog timer */ ++ sb_watchdog(sbh, 20); ++ (void) R_REG(&cc->chipid); ++ ++ /* step 11 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "sync\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ while (1); ++ } ++ ++done: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} ++ ++/* ++ * This also must be run from the cache on 47xx ++ * so there are no mips core BIU ops in progress ++ * when the PFC is enabled. ++ */ ++ ++static void ++BCMINITFN(_enable_pfc)(uint32 mode) ++{ ++ /* write range */ ++ *(volatile uint32 *)PFC_CR1 = 0xffff0000; ++ ++ /* enable */ ++ *(volatile uint32 *)PFC_CR0 = mode; ++} ++ ++void ++BCMINITFN(enable_pfc)(uint32 mode) ++{ ++ ulong start, end; ++ int i; ++ ++ /* If auto then choose the correct mode for this ++ platform, currently we only ever select one mode */ ++ if (mode == PFC_AUTO) ++ mode = PFC_INST; ++ ++ /* enable prefetch cache if available */ ++ if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) { ++ start = (ulong) &BCMINIT(_enable_pfc); ++ end = (ulong) &BCMINIT(enable_pfc); ++ ++ /* Preload handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += 4) ++ cache_op(start + i, Fill_I); ++ ++ BCMINIT(_enable_pfc)(mode); ++ } ++} ++ ++/* returns the ncdl value to be programmed into sdram_ncdl for calibration */ ++uint32 ++BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh) ++{ ++ sbmemcregs_t *memc; ++ uint32 ret = 0; ++ uint32 config, rd, wr, misc, dqsg, cd, sm, sd; ++ uint idx, rev; ++ ++ idx = sb_coreidx(sbh); ++ ++ memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0); ++ if (memc == 0) ++ goto out; ++ ++ rev = sb_corerev(sbh); ++ ++ config = R_REG(&memc->config); ++ wr = R_REG(&memc->wrncdlcor); ++ rd = R_REG(&memc->rdncdlcor); ++ misc = R_REG(&memc->miscdlyctl); ++ dqsg = R_REG(&memc->dqsgatencdl); ++ ++ rd &= MEMC_RDNCDLCOR_RD_MASK; ++ wr &= MEMC_WRNCDLCOR_WR_MASK; ++ dqsg &= MEMC_DQSGATENCDL_G_MASK; ++ ++ if (config & MEMC_CONFIG_DDR) { ++ ret = (wr << 16) | (rd << 8) | dqsg; ++ } else { ++ if (rev > 0) ++ cd = rd; ++ else ++ cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD); ++ sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT; ++ sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT; ++ ret = (sm << 16) | (sd << 8) | cd; ++ } ++ ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} ++ +diff -urN linux.old/arch/mips/bcm947xx/broadcom/sbpci.c linux.dev/arch/mips/bcm947xx/broadcom/sbpci.c +--- linux.old/arch/mips/bcm947xx/broadcom/sbpci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/sbpci.c 2005-12-28 16:37:32.854260000 +0100 +@@ -0,0 +1,533 @@ ++/* ++ * Low-Level PCI and SB support for BCM47xx ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Can free sbpci_init() memory after boot */ ++#ifndef linux ++#define __init ++#endif ++ ++/* Emulated configuration space */ ++static pci_config_regs sb_config_regs[SB_MAXCORES]; ++ ++/* Banned cores */ ++static uint16 pci_ban[32] = { 0 }; ++static uint pci_banned = 0; ++ ++/* CardBus mode */ ++static bool cardbus = FALSE; ++ ++/* Disable PCI host core */ ++static bool pci_disabled = FALSE; ++ ++/* ++ * Functions for accessing external PCI configuration space ++ */ ++ ++/* Assume one-hot slot wiring */ ++#define PCI_SLOT_MAX 16 ++ ++static uint32 ++config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off) ++{ ++ uint coreidx; ++ sbpciregs_t *regs; ++ uint32 addr = 0; ++ ++ /* CardBusMode supports only one device */ ++ if (cardbus && dev > 1) ++ return 0; ++ ++ coreidx = sb_coreidx(sbh); ++ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Type 0 transaction */ ++ if (bus == 1) { ++ /* Skip unwired slots */ ++ if (dev < PCI_SLOT_MAX) { ++ /* Slide the PCI window to the appropriate slot */ ++ W_REG(®s->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK)); ++ addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) | ++ (func << 8) | (off & ~3); ++ } ++ } ++ ++ /* Type 1 transaction */ ++ else { ++ W_REG(®s->sbtopci1, SBTOPCI_CFG1); ++ addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ ++ return addr; ++} ++ ++static int ++extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (pci_disabled || ++ !(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ val = 0xffffffff; ++ ++ val >>= 8 * (off & 3); ++ if (len == 4) ++ *((uint32 *) buf) = val; ++ else if (len == 2) ++ *((uint16 *) buf) = (uint16) val; ++ else if (len == 1) ++ *((uint8 *) buf) = (uint8) val; ++ else ++ ret = -1; ++ ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++static int ++extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (pci_disabled || ++ !(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ goto done; ++ ++ if (len == 4) ++ val = *((uint32 *) buf); ++ else if (len == 2) { ++ val &= ~(0xffff << (8 * (off & 3))); ++ val |= *((uint16 *) buf) << (8 * (off & 3)); ++ } else if (len == 1) { ++ val &= ~(0xff << (8 * (off & 3))); ++ val |= *((uint8 *) buf) << (8 * (off & 3)); ++ } else ++ ret = -1; ++ ++ W_REG(reg, val); ++ ++ done: ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++/* ++ * Functions for accessing translated SB configuration space ++ */ ++ ++static int ++sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); ++ ++ if (len == 4) ++ *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); ++ else if (len == 2) ++ *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); ++ else if (len == 1) ++ *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off)); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++static int ++sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint coreidx, n; ++ void *regs; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); ++ ++ /* Emulate BAR sizing */ ++ if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) && ++ len == 4 && *((uint32 *) buf) == ~0) { ++ coreidx = sb_coreidx(sbh); ++ if ((regs = sb_setcoreidx(sbh, dev))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ /* Highest numbered address match register */ ++ n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT; ++ if (off == OFFSETOF(pci_config_regs, base[0])) ++ cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1); ++#if 0 ++ else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1) ++ cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2) ++ cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3) ++ cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1); ++#endif ++ } ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++ } ++ ++ if (len == 4) ++ *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf)); ++ else if (len == 2) ++ *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf)); ++ else if (len == 1) ++ *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++int ++sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_read_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_read_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++int ++sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_write_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_write_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++void ++sbpci_ban(uint16 core) ++{ ++ if (pci_banned < ARRAYSIZE(pci_ban)) ++ pci_ban[pci_banned++] = core; ++} ++ ++static int ++sbpci_init_pci(sb_t *sbh) ++{ ++ uint chip, chiprev, chippkg, host; ++ uint32 boardflags; ++ sbpciregs_t *pci; ++ sbconfig_t *sb; ++ uint32 val; ++ ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); ++ ++ if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) { ++ printf("PCI: no core\n"); ++ pci_disabled = TRUE; ++ return -1; ++ } ++ sb_core_reset(sbh, 0); ++ ++ boardflags = (uint32) getintvar(NULL, "boardflags"); ++ ++ if ((chip == BCM4310_DEVICE_ID) && (chiprev == 0)) ++ pci_disabled = TRUE; ++ ++ /* ++ * The 200-pin BCM4712 package does not bond out PCI. Even when ++ * PCI is bonded out, some boards may leave the pins ++ * floating. ++ */ ++ if (((chip == BCM4712_DEVICE_ID) && ++ ((chippkg == BCM4712SMALL_PKG_ID) || ++ (chippkg == BCM4712MID_PKG_ID))) || ++ (boardflags & BFL_NOPCI)) ++ pci_disabled = TRUE; ++ ++ /* ++ * If the PCI core should not be touched (disabled, not bonded ++ * out, or pins floating), do not even attempt to access core ++ * registers. Otherwise, try to determine if it is in host ++ * mode. ++ */ ++ if (pci_disabled) ++ host = 0; ++ else ++ host = !BUSPROBE(val, &pci->control); ++ ++ if (!host) { ++ /* Disable PCI interrupts in client mode */ ++ sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); ++ W_REG(&sb->sbintvec, 0); ++ ++ /* Disable the PCI bridge in client mode */ ++ sbpci_ban(SB_PCI); ++ printf("PCI: Disabled\n"); ++ } else { ++ /* Reset the external PCI bus and enable the clock */ ++ W_REG(&pci->control, 0x5); /* enable the tristate drivers */ ++ W_REG(&pci->control, 0xd); /* enable the PCI clock */ ++ OSL_DELAY(150); /* delay > 100 us */ ++ W_REG(&pci->control, 0xf); /* deassert PCI reset */ ++ W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */ ++ OSL_DELAY(1); /* delay 1 us */ ++ ++ /* Enable CardBusMode */ ++ cardbus = nvram_match("cardbus", "1"); ++ if (cardbus) { ++ printf("PCI: Enabling CardBus\n"); ++ /* GPIO 1 resets the CardBus device on bcm94710ap */ ++ sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400); ++ } ++ ++ /* 64 MB I/O access window */ ++ W_REG(&pci->sbtopci0, SBTOPCI_IO); ++ /* 64 MB configuration access window */ ++ W_REG(&pci->sbtopci1, SBTOPCI_CFG0); ++ /* 1 GB memory access window */ ++ W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); ++ ++ /* Enable PCI bridge BAR0 prefetch and burst */ ++ val = 6; ++ sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val)); ++ ++ /* Enable PCI interrupts */ ++ W_REG(&pci->intmask, PCI_INTA); ++ } ++ ++ return 0; ++} ++ ++static int ++sbpci_init_cores(sb_t *sbh) ++{ ++ uint chip, chiprev, chippkg, coreidx, i; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ void *regs; ++ char varname[8]; ++ uint wlidx = 0; ++ uint16 vendor, core; ++ uint8 class, subclass, progif; ++ uint32 val; ++ uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK }; ++ uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT }; ++ ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); ++ coreidx = sb_coreidx(sbh); ++ ++ /* Scan the SB bus */ ++ bzero(sb_config_regs, sizeof(sb_config_regs)); ++ for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) { ++ cfg->vendor = 0xffff; ++ if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs))) ++ continue; ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* Read ID register and parse vendor and core */ ++ val = R_REG(&sb->sbidhigh); ++ vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT; ++ core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; ++ progif = 0; ++ ++ /* Check if this core is banned */ ++ for (i = 0; i < pci_banned; i++) ++ if (core == pci_ban[i]) ++ break; ++ if (i < pci_banned) ++ continue; ++ ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ILINE100: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM4610_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++#if 0 ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ break; ++#endif ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ core = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", wlidx); ++ wlidx++; ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; ++ } else { ++ /* 4310 */ ++ core = BCM4310_D11B_ID; ++ } ++ } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; ++ } ++ ++ /* Supported translations */ ++ cfg->vendor = htol16(vendor); ++ cfg->device = htol16(core); ++ cfg->rev_id = chiprev; ++ cfg->prog_if = progif; ++ cfg->sub_class = subclass; ++ cfg->base_class = class; ++ cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0))); ++ cfg->base[1] = 0;//htol32(sb_base(R_REG(&sb->sbadmatch1))); ++ cfg->base[2] = 0;//htol32(sb_base(R_REG(&sb->sbadmatch2))); ++ cfg->base[3] = 0;//htol32(sb_base(R_REG(&sb->sbadmatch3))); ++ cfg->base[4] = 0; ++ cfg->base[5] = 0; ++ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) ++ cfg->header_type = PCI_HEADER_BRIDGE; ++ else ++ cfg->header_type = PCI_HEADER_NORMAL; ++ /* Save core interrupt flag */ ++ cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ /* Default to MIPS shared interrupt 0 */ ++ cfg->int_line = 0; ++ /* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ val = R_REG(&sb->sbipsflag); ++ for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) { ++ if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin) ++ break; ++ } ++ if (cfg->int_line > 4) ++ cfg->int_line = 0; ++ } ++ /* Emulated core */ ++ *((uint32 *) &cfg->sprom_control) = 0xffffffff; ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++} ++ ++int __init ++sbpci_init(sb_t *sbh) ++{ ++ sbpci_init_pci(sbh); ++ sbpci_init_cores(sbh); ++ return 0; ++} ++ +diff -urN linux.old/arch/mips/bcm947xx/broadcom/sbutils.c linux.dev/arch/mips/bcm947xx/broadcom/sbutils.c +--- linux.old/arch/mips/bcm947xx/broadcom/sbutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/sbutils.c 2005-12-28 16:37:32.858260250 +0100 +@@ -0,0 +1,2370 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* debug/trace */ ++#define SB_ERROR(args) ++ ++ ++typedef uint32 (*sb_intrsoff_t)(void *intr_arg); ++typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); ++typedef bool (*sb_intrsenabled_t)(void *intr_arg); ++ ++/* misc sb info needed by some of the routines */ ++typedef struct sb_info { ++ ++ struct sb_pub sb; /* back plane public state(must be first field of sb_info */ ++ ++ void *osh; /* osl os handle */ ++ void *sdh; /* bcmsdh handle */ ++ ++ void *curmap; /* current regs va */ ++ void *regs[SB_MAXCORES]; /* other regs va */ ++ ++ uint curidx; /* current core index */ ++ uint dev_coreid; /* the core provides driver functions */ ++ ++ uint gpioidx; /* gpio control core index */ ++ uint gpioid; /* gpio control coretype */ ++ ++ uint numcores; /* # discovered cores */ ++ uint coreid[SB_MAXCORES]; /* id of each core */ ++ ++ void *intr_arg; /* interrupt callback function arg */ ++ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ ++ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ ++ sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */ ++ ++} sb_info_t; ++ ++/* local prototypes */ ++static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz); ++static void BCMINIT(sb_scan)(sb_info_t *si); ++static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val); ++static uint _sb_coreidx(sb_info_t *si); ++static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit); ++static uint BCMINIT(sb_pcidev2chip)(uint pcidev); ++static uint BCMINIT(sb_chip2numcores)(uint chip); ++static int sb_pci_fixcfg(sb_info_t *si); ++ ++/* delay needed between the mdio control/ mdiodata register data access */ ++#define PR28829_DELAY() OSL_DELAY(10) ++ ++ ++/* global variable to indicate reservation/release of gpio's*/ ++static uint32 sb_gpioreservation = 0; ++ ++#define SB_INFO(sbh) (sb_info_t*)sbh ++#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) ++#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE)) ++#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE)) ++#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) ++#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) ++#define BADIDX (SB_MAXCORES+1) ++#define NOREV -1 ++ ++#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) ++ ++/* sonicsrev */ ++#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) ++#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) ++ ++#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) ++#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) ++#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) ++#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) ++ ++/* ++ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ ++ * after core switching to avoid invalid register accesss inside ISR. ++ */ ++#define INTR_OFF(si, intr_val) \ ++ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } ++#define INTR_RESTORE(si, intr_val) \ ++ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } ++ ++/* dynamic clock control defines */ ++#define LPOMINFREQ 25000 /* low power oscillator min */ ++#define LPOMAXFREQ 43000 /* low power oscillator max */ ++#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ ++#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ ++#define PCIMINFREQ 25000000 /* 25 MHz */ ++#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ ++ ++#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ ++#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ ++ ++#define MIN_DUMPBUFLEN 32 /* debug */ ++ ++/* GPIO Based LED powersave defines */ ++#define DEFAULT_GPIO_ONTIME 10 ++#define DEFAULT_GPIO_OFFTIME 90 ++ ++#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) ++ ++static uint32 ++sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) ++{ ++ uint32 val = R_REG(sbr); ++ ++ return (val); ++} ++ ++static void ++sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) ++{ ++ W_REG(sbr, v); ++} ++ ++/* Using sb_kattach depends on SB_BUS support, either implicit */ ++/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */ ++#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) ++ ++/* global kernel resource */ ++static sb_info_t ksi; ++ ++/* generic kernel variant of sb_attach() */ ++sb_t * ++BCMINITFN(sb_kattach)() ++{ ++ uint32 *regs; ++ ++ if (ksi.curmap == NULL) { ++ uint32 cid; ++ ++ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); ++ cid = R_REG((uint32 *)regs); ++ if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) && ++ ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) && ++ ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) { ++ uint32 *scc, val; ++ ++ scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); ++ val = R_REG(scc); ++ SB_ERROR((" initial scc = 0x%x\n", val)); ++ val |= SCC_SS_XTAL; ++ W_REG(scc, val); ++ } ++ ++ if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, ++ SB_BUS, NULL, NULL, NULL) == NULL) { ++ return NULL; ++ } ++ } ++ ++ return (sb_t *)&ksi; ++} ++#endif ++ ++static sb_info_t * ++BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ uint origidx; ++ chipcregs_t *cc; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ ASSERT(GOODREGS(regs)); ++ ++ bzero((uchar*)si, sizeof (sb_info_t)); ++ ++ si->sb.buscoreidx = si->gpioidx = BADIDX; ++ ++ si->osh = osh; ++ si->curmap = regs; ++ si->sdh = sdh; ++ ++ /* check to see if we are a sb core mimic'ing a pci core */ ++ if (bustype == PCI_BUS) { ++ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) ++ bustype = SB_BUS; ++ else ++ bustype = PCI_BUS; ++ } ++ ++ si->sb.bustype = bustype; ++ if (si->sb.bustype != BUSTYPE(si->sb.bustype)) { ++ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", ++ si->sb.bustype, BUSTYPE(si->sb.bustype))); ++ return NULL; ++ } ++ ++ /* kludge to enable the clock on the 4306 which lacks a slowclock */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) ++ sb_clkctl_xtal(&si->sb, XTAL|PLL, ON); ++ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32)); ++ if (!GOODCOREADDR(w)) ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE); ++ } ++ ++ /* initialize current core index value */ ++ si->curidx = _sb_coreidx(si); ++ ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_doattach: bad core index\n")); ++ return NULL; ++ } ++ ++ /* get sonics backplane revision */ ++ sb = REGS2SB(si->curmap); ++ si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; ++ ++ /* keep and reuse the initial register mapping */ ++ origidx = si->curidx; ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ si->regs[origidx] = regs; ++ ++ /* is core-0 a chipcommon core? */ ++ si->numcores = 1; ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0); ++ if (sb_coreid(&si->sb) != SB_CC) ++ cc = NULL; ++ ++ /* determine chip id and rev */ ++ if (cc) { ++ /* chip common core found! */ ++ si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK; ++ si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; ++ si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ } else { ++ /* no chip common core -- must convert device id to chip id */ ++ if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) { ++ SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid)); ++ sb_setcoreidx(&si->sb, origidx); ++ return NULL; ++ } ++ } ++ ++ /* get chipcommon rev */ ++ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; ++ ++ /* determine numcores */ ++ if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6))) ++ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; ++ else ++ si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip); ++ ++ /* return to original core */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* sanity checks */ ++ ASSERT(si->sb.chip); ++ ++ /* scan for cores */ ++ BCMINIT(sb_scan)(si); ++ ++ /* fixup necessary chip/core configurations */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ if (sb_pci_fixcfg(si)) { ++ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n")); ++ return NULL; ++ } ++ } ++ ++ /* srom_var_init() depends on sb_scan() info */ ++ if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) { ++ SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n")); ++ return (NULL); ++ } ++ ++ if (cc == NULL) { ++ /* ++ * The chip revision number is hardwired into all ++ * of the pci function config rev fields and is ++ * independent from the individual core revision numbers. ++ * For example, the "A0" silicon of each chip is chip rev 0. ++ */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); ++ si->sb.chiprev = w & 0xff; ++ } else ++ si->sb.chiprev = 0; ++ } ++ ++ /* gpio control core is required */ ++ if (!GOODIDX(si->gpioidx)) { ++ SB_ERROR(("sb_doattach: gpio control core not found\n")); ++ return NULL; ++ } ++ ++ /* get boardtype and boardrev */ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ /* do a pci config read to get subsystem id and subvendor id */ ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); ++ si->sb.boardvendor = w & 0xffff; ++ si->sb.boardtype = (w >> 16) & 0xffff; ++ break; ++ ++ case SB_BUS: ++ case JTAG_BUS: ++ si->sb.boardvendor = VENDOR_BROADCOM; ++ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) ++ si->sb.boardtype = 0xffff; ++ break; ++ } ++ ++ if (si->sb.boardtype == 0) { ++ SB_ERROR(("sb_doattach: unknown board type\n")); ++ ASSERT(si->sb.boardtype); ++ } ++ ++ /* setup the GPIO based LED powersave register */ ++ if (si->sb.ccrev >= 16) { ++ w = getintvar(*vars, "gpiotimerval"); ++ if (!w) ++ w = DEFAULT_GPIOTIMERVAL; ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); ++ } ++ ++ ++ return (si); ++} ++ ++uint ++sb_coreid(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++} ++ ++uint ++sb_coreidx(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->curidx); ++} ++ ++/* return current index of core */ ++static uint ++_sb_coreidx(sb_info_t *si) ++{ ++ sbconfig_t *sb; ++ uint32 sbaddr = 0; ++ ++ ASSERT(si); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ sb = REGS2SB(si->curmap); ++ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); ++ break; ++ ++ case PCI_BUS: ++ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); ++ break; ++ ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ sbaddr = (uint32)si->curmap; ++ break; ++#endif /* BCMJTAG */ ++ ++ default: ++ ASSERT(0); ++ } ++ ++ if (!GOODCOREADDR(sbaddr)) ++ return BADIDX; ++ ++ return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); ++} ++ ++uint ++sb_corevendor(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); ++} ++ ++uint ++sb_corerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint sbidh; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ sbidh = R_SBREG(si, &(sb)->sbidhigh); ++ ++ return (SBCOREREV(sbidh)); ++} ++ ++void * ++sb_osh(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return si->osh; ++} ++ ++#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) ++ ++/* set/clear sbtmstatelow core-specific flags */ ++uint32 ++sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTML_ALLOW) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatelow, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW); ++} ++ ++/* set/clear sbtmstatehigh core-specific flags */ ++uint32 ++sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTMH_FL_MASK) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatehigh, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK); ++} ++ ++/* caller needs to take care of core-specific bist hazards */ ++int ++sb_corebist(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ uint32 sblo; ++ uint coreidx; ++ sb_info_t *si; ++ int result = 0; ++ ++ si = SB_INFO(sbh); ++ ++ coreidx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(coreidx)) ++ result = BCME_ERROR; ++ else { ++ sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0); ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE)); ++ ++ SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000); ++ ++ if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF) ++ result = BCME_ERROR; ++ ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo); ++ } ++ ++ return result; ++} ++ ++bool ++sb_iscoreup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); ++} ++ ++/* ++ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, ++ * switch back to the original core, and return the new value. ++ */ ++static uint ++sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ uint origidx; ++ uint32 *r; ++ uint w; ++ uint intr_val = 0; ++ ++ ASSERT(GOODIDX(coreidx)); ++ ASSERT(regoff < SB_CORE_SIZE); ++ ASSERT((val & ~mask) == 0); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ /* switch core */ ++ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); ++ ++ /* mask and set */ ++ if (mask || val) { ++ if (regoff >= SBCONFIGOFF) { ++ w = (R_SBREG(si, r) & ~mask) | val; ++ W_SBREG(si, r, w); ++ } else { ++ w = (R_REG(r) & ~mask) | val; ++ W_REG(r, w); ++ } ++ } ++ ++ /* readback */ ++ if (regoff >= SBCONFIGOFF) ++ w = R_SBREG(si, r); ++ else ++ w = R_REG(r); ++ ++ /* restore core index */ ++ if (origidx != coreidx) ++ sb_setcoreidx(&si->sb, origidx); ++ ++ INTR_RESTORE(si, intr_val); ++ return (w); ++} ++ ++#define DWORD_ALIGN(x) (x & ~(0x03)) ++#define BYTE_POS(x) (x & 0x3) ++#define WORD_POS(x) (x & 0x1) ++ ++#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) ++#define WORD_SHIFT(x) (16 * WORD_POS(x)) ++ ++#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) ++#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) ++ ++#define read_pci_cfg_byte(a) \ ++ (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff) ++ ++#define read_pci_cfg_write(a) \ ++ (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff) ++ ++ ++/* scan the sb enumerated space to identify all cores */ ++static void ++BCMINITFN(sb_scan)(sb_info_t *si) ++{ ++ uint origidx; ++ uint i; ++ bool pci; ++ uint pciidx; ++ uint pcirev; ++ ++ ++ ++ /* numcores should already be set */ ++ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ si->sb.buscorerev = NOREV; ++ si->sb.buscoreidx = BADIDX; ++ ++ si->gpioidx = BADIDX; ++ ++ pci = FALSE; ++ pcirev = NOREV; ++ pciidx = BADIDX; ++ ++ for (i = 0; i < si->numcores; i++) { ++ sb_setcoreidx(&si->sb, i); ++ si->coreid[i] = sb_coreid(&si->sb); ++ ++ if (si->coreid[i] == SB_PCI) { ++ pciidx = i; ++ pcirev = sb_corerev(&si->sb); ++ pci = TRUE; ++ } ++ } ++ if (pci) { ++ si->sb.buscoretype = SB_PCI; ++ si->sb.buscorerev = pcirev; ++ si->sb.buscoreidx = pciidx; ++ } ++ ++ /* ++ * Find the gpio "controlling core" type and index. ++ * Precedence: ++ * - if there's a chip common core - use that ++ * - else if there's a pci core (rev >= 2) - use that ++ * - else there had better be an extif core (4710 only) ++ */ ++ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { ++ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); ++ si->gpioid = SB_CC; ++ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { ++ si->gpioidx = si->sb.buscoreidx; ++ si->gpioid = SB_PCI; ++ } else if (sb_findcoreidx(si, SB_EXTIF, 0)) { ++ si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0); ++ si->gpioid = SB_EXTIF; ++ } else ++ ASSERT(si->gpioidx != BADIDX); ++ ++ /* return to original core index */ ++ sb_setcoreidx(&si->sb, origidx); ++} ++ ++/* may be called with core in reset */ ++void ++sb_detach(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ if (si == NULL) ++ return; ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ for (idx = 0; idx < SB_MAXCORES; idx++) ++ if (si->regs[idx]) { ++ REG_UNMAP(si->regs[idx]); ++ si->regs[idx] = NULL; ++ } ++ ++ if (si != &ksi) ++ MFREE(si->osh, si, sizeof (sb_info_t)); ++} ++ ++/* use pci dev id to determine chip id for chips not having a chipcommon core */ ++static uint ++BCMINITFN(sb_pcidev2chip)(uint pcidev) ++{ ++ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) ++ return (BCM4710_DEVICE_ID); ++ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) ++ return (BCM4402_DEVICE_ID); ++ if (pcidev == BCM4401_ENET_ID) ++ return (BCM4402_DEVICE_ID); ++ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) ++ return (BCM4307_DEVICE_ID); ++ if (pcidev == BCM4301_DEVICE_ID) ++ return (BCM4301_DEVICE_ID); ++ ++ return (0); ++} ++ ++/* convert chip number to number of i/o cores */ ++static uint ++BCMINITFN(sb_chip2numcores)(uint chip) ++{ ++ if (chip == BCM4710_DEVICE_ID) ++ return (9); ++ if (chip == BCM4402_DEVICE_ID) ++ return (3); ++ if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID)) ++ return (5); ++ if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */ ++ return (6); ++ if (chip == BCM4704_DEVICE_ID) ++ return (9); ++ if (chip == BCM5365_DEVICE_ID) ++ return (7); ++ ++ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); ++ ASSERT(0); ++ return (1); ++} ++ ++/* return index of coreid or BADIDX if not found */ ++static uint ++sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit) ++{ ++ uint found; ++ uint i; ++ ++ found = 0; ++ ++ for (i = 0; i < si->numcores; i++) ++ if (si->coreid[i] == coreid) { ++ if (found == coreunit) ++ return (i); ++ found++; ++ } ++ ++ return (BADIDX); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcoreidx(sb_t *sbh, uint coreidx) ++{ ++ sb_info_t *si; ++ uint32 sbaddr; ++ ++ si = SB_INFO(sbh); ++ ++ if (coreidx >= si->numcores) ++ return (NULL); ++ ++ /* ++ * If the user has provided an interrupt mask enabled function, ++ * then assert interrupts are disabled before switching the core. ++ */ ++ ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); ++ ++ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++ ++ case PCI_BUS: ++ /* point bar0 window */ ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); ++ break; ++ ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void *)sbaddr; ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++#endif /* BCMJTAG */ ++ } ++ ++ si->curidx = coreidx; ++ ++ return (si->curmap); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcore(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ idx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(idx)) ++ return (NULL); ++ ++ return (sb_setcoreidx(sbh, idx)); ++} ++ ++/* return chip number */ ++uint ++BCMINITFN(sb_chip)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chip); ++} ++ ++/* return chip revision number */ ++uint ++BCMINITFN(sb_chiprev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chiprev); ++} ++ ++/* return chip common revision number */ ++uint ++BCMINITFN(sb_chipcrev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.ccrev); ++} ++ ++/* return chip package option */ ++uint ++BCMINITFN(sb_chippkg)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chippkg); ++} ++ ++/* return PCI core rev. */ ++uint ++BCMINITFN(sb_pcirev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); ++} ++ ++bool ++BCMINITFN(sb_war16165)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (PCI(si) && (si->sb.buscorerev <= 10)); ++} ++ ++/* return board vendor id */ ++uint ++BCMINITFN(sb_boardvendor)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.boardvendor); ++} ++ ++/* return boardtype */ ++uint ++BCMINITFN(sb_boardtype)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ char *var; ++ ++ si = SB_INFO(sbh); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { ++ /* boardtype format is a hex string */ ++ si->sb.boardtype = getintvar(NULL, "boardtype"); ++ ++ /* backward compatibility for older boardtype string format */ ++ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { ++ if (!strcmp(var, "bcm94710dev")) ++ si->sb.boardtype = BCM94710D_BOARD; ++ else if (!strcmp(var, "bcm94710ap")) ++ si->sb.boardtype = BCM94710AP_BOARD; ++ else if (!strcmp(var, "bu4710")) ++ si->sb.boardtype = BU4710_BOARD; ++ else if (!strcmp(var, "bcm94702mn")) ++ si->sb.boardtype = BCM94702MN_BOARD; ++ else if (!strcmp(var, "bcm94710r1")) ++ si->sb.boardtype = BCM94710R1_BOARD; ++ else if (!strcmp(var, "bcm94710r4")) ++ si->sb.boardtype = BCM94710R4_BOARD; ++ else if (!strcmp(var, "bcm94702cpci")) ++ si->sb.boardtype = BCM94702CPCI_BOARD; ++ else if (!strcmp(var, "bcm95380_rr")) ++ si->sb.boardtype = BCM95380RR_BOARD; ++ } ++ } ++ ++ return (si->sb.boardtype); ++} ++ ++/* return bus type of sbh device */ ++uint ++sb_bus(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.bustype); ++} ++ ++/* return bus core type */ ++uint ++sb_buscoretype(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscoretype); ++} ++ ++/* return bus core revision */ ++uint ++sb_buscorerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscorerev); ++} ++ ++/* return list of found cores */ ++uint ++sb_corelist(sb_t *sbh, uint coreid[]) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); ++ return (si->numcores); ++} ++ ++/* return current register mapping */ ++void * ++sb_coreregs(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ ++ return (si->curmap); ++} ++ ++ ++/* do buffered registers update */ ++void ++sb_commit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ASSERT(GOODIDX(origidx)); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch over to chipcommon core if there is one, else use pci */ ++ if (si->sb.ccrev != NOREV) { ++ chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&ccregs->broadcastaddress, SB_COMMIT); ++ W_REG(&ccregs->broadcastdata, 0x0); ++ } else if (PCI(si)) { ++ sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&pciregs->bcastaddr, SB_COMMIT); ++ W_REG(&pciregs->bcastdata, 0x0); ++ } else ++ ASSERT(0); ++ ++ /* restore core index */ ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++} ++ ++/* reset and re-enable a core */ ++void ++sb_core_reset(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ volatile uint32 dummy; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* ++ * Must do the disable sequence first to work for arbitrary current core state. ++ */ ++ sb_core_disable(sbh, bits); ++ ++ /* ++ * Now do the initialization sequence. ++ */ ++ ++ /* set reset while enabling the clock and forcing them on throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { ++ W_SBREG(si, &sb->sbtmstatehigh, 0); ++ } ++ if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { ++ AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); ++ } ++ ++ /* clear reset and allow it to propagate throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ /* leave clock enabled */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++} ++ ++void ++sb_core_tofixup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || (PCI(si) && (si->sb.buscorerev >= 5)) ) ++ return; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); ++ } else { ++ if (sb_coreid(sbh) == SB_PCI) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ } else { ++ SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ } ++ } ++ ++ sb_commit(sbh); ++} ++ ++/* ++ * Set the initiator timeout for the "master core". ++ * The master core is defined to be the core in control ++ * of the chip and so it issues accesses to non-memory ++ * locations (Because of dma *any* core can access memeory). ++ * ++ * The routine uses the bus to decide who is the master: ++ * SB_BUS => mips ++ * JTAG_BUS => chipc ++ * PCI_BUS => pci ++ * ++ * This routine exists so callers can disable initiator ++ * timeouts so accesses to very slow devices like otp ++ * won't cause an abort. The routine allows arbitrary ++ * settings of the service and request timeouts, though. ++ * ++ * Returns the timeout state before changing it or -1 ++ * on error. ++ */ ++ ++#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) ++ ++uint32 ++sb_set_initiator_to(sb_t *sbh, uint32 to) ++{ ++ sb_info_t *si; ++ uint origidx, idx; ++ uint intr_val = 0; ++ uint32 tmp, ret = 0xffffffff; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ((to & ~TO_MASK) != 0) ++ return ret; ++ ++ /* Figure out the master core */ ++ idx = BADIDX; ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ idx = si->sb.buscoreidx; ++ break; ++ case JTAG_BUS: ++ idx = SB_CC_IDX; ++ break; ++ case SB_BUS: ++ if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX) ++ idx = sb_findcoreidx(si, SB_MIPS, 0); ++ break; ++ default: ++ ASSERT(0); ++ } ++ if (idx == BADIDX) ++ return ret; ++ ++ INTR_OFF(si, intr_val); ++ origidx = sb_coreidx(sbh); ++ ++ sb = REGS2SB(sb_setcoreidx(sbh, idx)); ++ ++ tmp = R_SBREG(si, &sb->sbimconfiglow); ++ ret = tmp & TO_MASK; ++ W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); ++ ++ sb_commit(sbh); ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return ret; ++} ++ ++void ++sb_core_disable(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ volatile uint32 dummy; ++ uint32 rej; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* if core is already in reset, just return */ ++ if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET) ++ return; ++ ++ /* reject value changed between sonics 2.2 and 2.3 */ ++ if (si->sb.sonicsrev == SONICS_2_2) ++ rej = (1 << SBTML_REJ_SHIFT); ++ else ++ rej = (2 << SBTML_REJ_SHIFT); ++ ++ /* if clocks are not enabled, put into reset and return */ ++ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) ++ goto disable; ++ ++ /* set target reject and spin until busy is clear (preserve core-specific bits) */ ++ OR_SBREG(si, &sb->sbtmstatelow, rej); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) { ++ OR_SBREG(si, &sb->sbimstate, SBIM_RJ); ++ dummy = R_SBREG(si, &sb->sbimstate); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); ++ } ++ ++ /* set reset and reject while enabling the clocks */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(10); ++ ++ /* don't forget to clear the initiator reject bit */ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) ++ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); ++ ++disable: ++ /* leave reset and reject asserted */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET)); ++ OSL_DELAY(1); ++} ++ ++/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */ ++void ++sb_watchdog(sb_t *sbh, uint ticks) ++{ ++ sb_info_t *si = SB_INFO(sbh); ++ ++ /* instant NMI */ ++ switch (si->gpioid) { ++ case SB_CC: ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++ break; ++ case SB_EXTIF: ++ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ break; ++ } ++} ++ ++ ++/* ++ * Configure the pci core for pci client (NIC) action ++ * coremask is the bitvec of cores by index to be enabled. ++ */ ++void ++sb_pci_setup(sb_t *sbh, uint coremask) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ sbpciregs_t *pciregs; ++ uint32 sbflag; ++ uint32 w; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ /* if not pci bus, we're done */ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return; ++ ++ ASSERT(PCI(si)); ++ ASSERT(si->sb.buscoreidx != BADIDX); ++ ++ /* get current core index */ ++ idx = si->curidx; ++ ++ /* we interrupt on this backplane flag number */ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ ++ /* switch over to pci core */ ++ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx); ++ sb = REGS2SB(pciregs); ++ ++ /* ++ * Enable sb->pci interrupts. Assume ++ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. ++ */ ++ if ((PCI(si) && ((si->sb.buscorerev) >= 6))) { ++ /* pci config write to set this core bit in PCIIntMask */ ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); ++ w |= (coremask << PCI_SBIM_SHIFT); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); ++ } else { ++ /* set sbintvec bit for our flag number */ ++ OR_SBREG(si, &sb->sbintvec, (1 << sbflag)); ++ } ++ ++ if (PCI(si)) { ++ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); ++ if (si->sb.buscorerev >= 11) ++ OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); ++ if (si->sb.buscorerev < 5) { ++ SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ sb_commit(sbh); ++ } ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++} ++ ++uint32 ++sb_base(uint32 admatch) ++{ ++ uint32 base; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ base = 0; ++ ++ if (type == 0) { ++ base = admatch & SBAM_BASE0_MASK; ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE1_MASK; ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE2_MASK; ++ } ++ ++ return (base); ++} ++ ++uint32 ++sb_size(uint32 admatch) ++{ ++ uint32 size; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ size = 0; ++ ++ if (type == 0) { ++ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); ++ } ++ ++ return (size); ++} ++ ++/* return the core-type instantiation # of the current core */ ++uint ++sb_coreunit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ uint coreid; ++ uint coreunit; ++ uint i; ++ ++ si = SB_INFO(sbh); ++ coreunit = 0; ++ ++ idx = si->curidx; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ coreid = sb_coreid(sbh); ++ ++ /* count the cores of our type */ ++ for (i = 0; i < idx; i++) ++ if (si->coreid[i] == coreid) ++ coreunit++; ++ ++ return (coreunit); ++} ++ ++static INLINE uint32 ++factor6(uint32 x) ++{ ++ switch (x) { ++ case CC_F6_2: return 2; ++ case CC_F6_3: return 3; ++ case CC_F6_4: return 4; ++ case CC_F6_5: return 5; ++ case CC_F6_6: return 6; ++ case CC_F6_7: return 7; ++ default: return 0; ++ } ++} ++ ++/* calculate the speed the SB would run at given a set of clockcontrol values */ ++uint32 ++sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) ++{ ++ uint32 n1, n2, clock, m1, m2, m3, mc; ++ ++ n1 = n & CN_N1_MASK; ++ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; ++ ++ if (pll_type == PLL_TYPE6) { ++ if (m & CC_T6_MMASK) ++ return CC_T6_M1; ++ else ++ return CC_T6_M0; ++ } else if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ n1 = factor6(n1); ++ n2 += CC_F5_BIAS; ++ } else if (pll_type == PLL_TYPE2) { ++ n1 += CC_T2_BIAS; ++ n2 += CC_T2_BIAS; ++ ASSERT((n1 >= 2) && (n1 <= 7)); ++ ASSERT((n2 >= 5) && (n2 <= 23)); ++ } else if (pll_type == PLL_TYPE5) { ++ return (100000000); ++ } else ++ ASSERT(0); ++ /* PLL types 3 and 7 use BASE2 (25Mhz) */ ++ if ((pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE7)) { ++ clock = CC_CLOCK_BASE2 * n1 * n2; ++ } ++ else ++ clock = CC_CLOCK_BASE1 * n1 * n2; ++ ++ if (clock == 0) ++ return 0; ++ ++ m1 = m & CC_M1_MASK; ++ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; ++ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; ++ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ m1 = factor6(m1); ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) ++ m2 += CC_F5_BIAS; ++ else ++ m2 = factor6(m2); ++ m3 = factor6(m3); ++ ++ switch (mc) { ++ case CC_MC_BYPASS: return (clock); ++ case CC_MC_M1: return (clock / m1); ++ case CC_MC_M1M2: return (clock / (m1 * m2)); ++ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); ++ case CC_MC_M1M3: return (clock / (m1 * m3)); ++ default: return (0); ++ } ++ } else { ++ ASSERT(pll_type == PLL_TYPE2); ++ ++ m1 += CC_T2_BIAS; ++ m2 += CC_T2M2_BIAS; ++ m3 += CC_T2_BIAS; ++ ASSERT((m1 >= 2) && (m1 <= 7)); ++ ASSERT((m2 >= 3) && (m2 <= 10)); ++ ASSERT((m3 >= 2) && (m3 <= 7)); ++ ++ if ((mc & CC_T2MC_M1BYP) == 0) ++ clock /= m1; ++ if ((mc & CC_T2MC_M2BYP) == 0) ++ clock /= m2; ++ if ((mc & CC_T2MC_M3BYP) == 0) ++ clock /= m3; ++ ++ return(clock); ++ } ++} ++ ++/* returns the current speed the SB is running at */ ++uint32 ++sb_clock(sb_t *sbh) ++{ ++ sb_info_t *si; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ idx = si->curidx; ++ pll_type = PLL_TYPE1; ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if (pll_type == PLL_TYPE6) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE3) ++ { ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ m = R_REG(&cc->clockcontrol_sb); ++ else ++ m = R_REG(&cc->clockcontrol_m2); ++ } ++ else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else { ++ INTR_RESTORE(si, intr_val); ++ return 0; ++ } ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { ++ rate = 100000000; ++ } ++ else ++ { ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ if (pll_type == PLL_TYPE3) ++ rate = rate / 2; ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ INTR_RESTORE(si, intr_val); ++ ++ return rate; ++} ++ ++/* change logical "focus" to the gpio core for optimized access */ ++void* ++sb_gpiosetcore(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (sb_setcoreidx(sbh, si->gpioidx)); ++} ++ ++/* mask&set gpiocontrol bits */ ++uint32 ++sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiocontrol); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); ++ break; ++ ++ case SB_EXTIF: ++ return (0); ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output enable bits */ ++uint32 ++sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioouten); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioouten); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].outen); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output bits */ ++uint32 ++sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioout); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioout); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].out); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* reserve one gpio */ ++uint32 ++sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ ++ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; ++ } ++ ++ /* already reserved */ ++ if (sb_gpioreservation & gpio_bitmask) ++ return -1; ++ /* set reservation */ ++ sb_gpioreservation |= gpio_bitmask; ++ ++ return sb_gpioreservation; ++} ++ ++/* release one gpio */ ++/* ++ * releasing the gpio doesn't change the current value on the GPIO last write value ++ * persists till some one overwrites it ++*/ ++ ++uint32 ++sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ ++ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; ++ } ++ ++ /* already released */ ++ if (!(sb_gpioreservation & gpio_bitmask)) ++ return -1; ++ ++ /* clear reservation */ ++ sb_gpioreservation &= ~gpio_bitmask; ++ ++ return sb_gpioreservation; ++} ++ ++/* return the current gpioin register value */ ++uint32 ++sb_gpioin(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioin); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioin); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpioin); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); ++} ++ ++/* mask&set gpio interrupt polarity bits */ ++uint32 ++sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt polarity */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointpolarity); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio interrupt mask bits */ ++uint32 ++sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointmask); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt mask */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointmask); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* assign the gpio to an led */ ++uint32 ++sb_gpioled(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ /* gpio led powersave reg */ ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); ++} ++ ++/* mask&set gpio timer val */ ++uint32 ++sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); ++} ++ ++ ++/* return the slow clock source - LPO, XTAL, or PCI */ ++static uint ++sb_slowclk_src(sb_info_t *si) ++{ ++ chipcregs_t *cc; ++ ++ ++ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ ++ if (si->sb.ccrev < 6) { ++ if ((BUSTYPE(si->sb.bustype) == PCI_BUS) ++ && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS)) ++ return (SCC_SS_PCI); ++ else ++ return (SCC_SS_XTAL); ++ } else if (si->sb.ccrev < 10) { ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK); ++ } else /* Insta-clock */ ++ return (SCC_SS_XTAL); ++} ++ ++/* return the ILP (slowclock) min or max frequency */ ++static uint ++sb_slowclk_freq(sb_info_t *si, bool max) ++{ ++ chipcregs_t *cc; ++ uint32 slowclk; ++ uint div; ++ ++ ++ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ ++ /* shouldn't be here unless we've established the chip has dynamic clk control */ ++ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); ++ ++ slowclk = sb_slowclk_src(si); ++ if (si->sb.ccrev < 6) { ++ if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); ++ else ++ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); ++ } else if (si->sb.ccrev < 10) { ++ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ if (slowclk == SCC_SS_LPO) ++ return (max? LPOMAXFREQ : LPOMINFREQ); ++ else if (slowclk == SCC_SS_XTAL) ++ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); ++ else if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); ++ else ++ ASSERT(0); ++ } else { ++ /* Chipc rev 10 is InstaClock */ ++ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; ++ div = 4 * (div + 1); ++ return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); ++ } ++ return (0); ++} ++ ++static void ++sb_clkctl_setdelay(sb_info_t *si, void *chipcregs) ++{ ++ chipcregs_t * cc; ++ uint slowmaxfreq, pll_delay, slowclk; ++ uint pll_on_delay, fref_sel_delay; ++ ++ pll_delay = PLL_DELAY; ++ ++ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay ++ * since the xtal will also be powered down by dynamic clk control logic. ++ */ ++ slowclk = sb_slowclk_src(si); ++ if (slowclk != SCC_SS_XTAL) ++ pll_delay += XTAL_ON_DELAY; ++ ++ /* Starting with 4318 it is ILP that is used for the delays */ ++ slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE); ++ ++ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; ++ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; ++ ++ cc = (chipcregs_t *)chipcregs; ++ W_REG(&cc->pll_on_delay, pll_on_delay); ++ W_REG(&cc->fref_sel_delay, fref_sel_delay); ++} ++ ++int ++sb_pwrctl_slowclk(void *sbh, bool set, uint *div) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint intr_val = 0; ++ uint err = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ ++ if (si->sb.ccrev < 6) ++ return 1; ++ ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return 1; ++ ++ if (set && ((*div % 4) || (*div < 4))) ++ return 2; ++ ++ INTR_OFF(si, intr_val); ++ origidx = si->curidx; ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) { ++ err = 3; ++ goto done; ++ } ++ ++ if (set) { ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT)); ++ sb_clkctl_setdelay(sbh, (void *)cc); ++ } else ++ *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return err; ++} ++ ++/* initialize power control delay registers */ ++void sb_clkctl_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ return; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ /* set all Instaclk chip ILP to 1 MHz */ ++ if (si->sb.ccrev >= 10) ++ SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); ++ ++ sb_clkctl_setdelay(si, (void *)cc); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++} ++void sb_pwrctl_init(sb_t *sbh) ++{ ++sb_clkctl_init(sbh); ++} ++/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ ++uint16 ++sb_clkctl_fast_pwrup_delay(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint slowminfreq; ++ uint16 fpdelay; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ fpdelay = 0; ++ origidx = si->curidx; ++ ++ INTR_OFF(si, intr_val); ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ goto done; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ slowminfreq = sb_slowclk_freq(si, FALSE); ++ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (fpdelay); ++} ++uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh) ++{ ++return sb_clkctl_fast_pwrup_delay(sbh); ++} ++/* turn primary xtal and/or pll off/on */ ++int ++sb_clkctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++ sb_info_t *si; ++ uint32 in, out, outen; ++ ++ si = SB_INFO(sbh); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ ++ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32)); ++ out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); ++ outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32)); ++ ++ /* ++ * Avoid glitching the clock if GPRS is already using it. ++ * We can't actually read the state of the PLLPD so we infer it ++ * by the value of XTAL_PU which *is* readable via gpioin. ++ */ ++ if (on && (in & PCI_CFG_GPIO_XTAL)) ++ return (0); ++ ++ if (what & XTAL) ++ outen |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ outen |= PCI_CFG_GPIO_PLL; ++ ++ if (on) { ++ /* turn primary xtal on */ ++ if (what & XTAL) { ++ out |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); ++ OSL_DELAY(XTAL_ON_DELAY); ++ } ++ ++ /* turn pll on */ ++ if (what & PLL) { ++ out &= ~PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_DELAY(2000); ++ } ++ } else { ++ if (what & XTAL) ++ out &= ~PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); ++ } ++ ++ default: ++ return (-1); ++ } ++ ++ return (0); ++} ++ ++int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++return sb_clkctl_xtal(sbh,what,on); ++} ++ ++/* set dynamic clk control mode (forceslow, forcefast, dynamic) */ ++/* returns true if ignore pll off is set and false if it is not */ ++bool ++sb_clkctl_clk(sb_t *sbh, uint mode) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint32 scc; ++ bool forcefastclk=FALSE; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* chipcommon cores prior to rev6 don't support dynamic clock control */ ++ if (si->sb.ccrev < 6) ++ return (FALSE); ++ ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return (FALSE); ++ ++ INTR_OFF(si, intr_val); ++ ++ origidx = si->curidx; ++ ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ switch (mode) { ++ case CLK_FAST: /* force fast (pll) clock */ ++ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ ++ sb_clkctl_xtal(&si->sb, XTAL, ON); ++ ++ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); ++ break; ++ ++ case CLK_DYNAMIC: /* enable dynamic clock control */ ++ scc = R_REG(&cc->slow_clk_ctl); ++ scc &= ~(SCC_FS | SCC_IP | SCC_XC); ++ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) ++ scc |= SCC_XC; ++ W_REG(&cc->slow_clk_ctl, scc); ++ ++ /* for dynamic control, we have to release our xtal_pu "force on" */ ++ if (scc & SCC_XC) ++ sb_clkctl_xtal(&si->sb, XTAL, OFF); ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ /* Is the h/w forcing the use of the fast clk */ ++ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (forcefastclk); ++} ++ ++bool sb_pwrctl_clk(sb_t *sbh, uint mode) ++{ ++return sb_clkctl_clk(sbh, mode); ++} ++/* register driver interrupt disabling and restoring callback functions */ ++void ++sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ si->intr_arg = intr_arg; ++ si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; ++ si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; ++ si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; ++ /* save current core id. when this function called, the current core ++ * must be the core which provides driver functions(il, et, wl, etc.) ++ */ ++ si->dev_coreid = si->coreid[si->curidx]; ++} ++ ++ ++void ++sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif) ++{ ++ uint vendor, core, unit; ++ uint chip, chippkg; ++ char varname[8]; ++ uint8 class, subclass, progif; ++ ++ vendor = sb_corevendor(sbh); ++ core = sb_coreid(sbh); ++ unit = sb_coreunit(sbh); ++ ++ chip = BCMINIT(sb_chip)(sbh); ++ chippkg = BCMINIT(sb_chippkg)(sbh); ++ ++ progif = 0; ++ ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ core = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", unit); ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; ++ } ++ } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; ++ } ++ ++ *pcivendor = (uint16)vendor; ++ *pcidevice = (uint16)core; ++ *pciclass = class; ++ *pcisubclass = subclass; ++ *pciprogif = progif; ++} ++ ++/* Fix chip's configuration. The current core may be changed upon return */ ++static int ++sb_pci_fixcfg(sb_info_t *si) ++{ ++ uint origidx, pciidx; ++ sbpciregs_t *pciregs; ++ uint16 val16, *reg16; ++ ++ ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS); ++ ++ /* Fix PCI(e) SROM shadow area */ ++ /* save the current index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ if (si->sb.buscoretype == SB_PCI) { ++ pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0); ++ ASSERT(pciregs); ++ reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; ++ } ++ else { ++ ASSERT(0); ++ return -1; ++ } ++ pciidx = sb_coreidx(&si->sb); ++ val16 = R_REG(reg16); ++ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { ++ val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); ++ W_REG(reg16, val16); ++ } ++ ++ /* restore the original index */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL(sb_boardtype); ++EXPORT_SYMBOL(sb_boardvendor); ++EXPORT_SYMBOL(sb_gpiocontrol); ++EXPORT_SYMBOL(sb_gpioin); ++EXPORT_SYMBOL(sb_gpiointmask); ++EXPORT_SYMBOL(sb_gpiointpolarity); ++EXPORT_SYMBOL(sb_gpioled); ++EXPORT_SYMBOL(sb_gpioout); ++EXPORT_SYMBOL(sb_gpioouten); ++EXPORT_SYMBOL(sb_gpiorelease); ++EXPORT_SYMBOL(sb_gpioreserve); ++EXPORT_SYMBOL(sb_gpiosetcore); ++EXPORT_SYMBOL(sb_gpiotimerval); ++EXPORT_SYMBOL(sb_watchdog); +diff -urN linux.old/arch/mips/bcm947xx/broadcom/sflash.c linux.dev/arch/mips/bcm947xx/broadcom/sflash.c +--- linux.old/arch/mips/bcm947xx/broadcom/sflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/broadcom/sflash.c 2005-12-28 16:37:32.870261000 +0100 +@@ -0,0 +1,418 @@ ++/* ++ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Private global state */ ++static struct sflash sflash; ++ ++/* Issue a serial flash command */ ++static INLINE void ++sflash_cmd(chipcregs_t *cc, uint opcode) ++{ ++ W_REG(&cc->flashcontrol, SFLASH_START | opcode); ++ while (R_REG(&cc->flashcontrol) & SFLASH_BUSY); ++} ++ ++/* Initialize serial flash access */ ++struct sflash * ++sflash_init(chipcregs_t *cc) ++{ ++ uint32 id, id2; ++ ++ bzero(&sflash, sizeof(sflash)); ++ ++ sflash.type = R_REG(&cc->capabilities) & CAP_FLASH_MASK; ++ ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Probe for ST chips */ ++ sflash_cmd(cc, SFLASH_ST_DP); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id = R_REG(&cc->flashdata); ++ switch (id) { ++ case 0x11: ++ /* ST M25P20 2 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 4; ++ break; ++ case 0x12: ++ /* ST M25P40 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ break; ++ case 0x13: ++ /* ST M25P80 8 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 16; ++ break; ++ case 0x14: ++ /* ST M25P16 16 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 32; ++ break; ++ case 0x15: ++ /* ST M25P32 32 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 64; ++ break; ++ case 0xbf: ++ W_REG(&cc->flashaddress, 1); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id2 = R_REG(&cc->flashdata); ++ if (id2 == 0x44) { ++ /* SST M25VF80 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ } ++ break; ++ } ++ break; ++ ++ case SFLASH_AT: ++ /* Probe for Atmel chips */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ id = R_REG(&cc->flashdata) & 0x3c; ++ switch (id) { ++ case 0xc: ++ /* Atmel AT45DB011 1Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 512; ++ break; ++ case 0x14: ++ /* Atmel AT45DB021 2Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 1024; ++ break; ++ case 0x1c: ++ /* Atmel AT45DB041 4Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 2048; ++ break; ++ case 0x24: ++ /* Atmel AT45DB081 8Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 4096; ++ break; ++ case 0x2c: ++ /* Atmel AT45DB161 16Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 4096; ++ break; ++ case 0x34: ++ /* Atmel AT45DB321 32Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 8192; ++ break; ++ case 0x3c: ++ /* Atmel AT45DB642 64Mbit Serial Flash */ ++ sflash.blocksize = 1024; ++ sflash.numblocks = 8192; ++ break; ++ } ++ break; ++ } ++ ++ sflash.size = sflash.blocksize * sflash.numblocks; ++ return sflash.size ? &sflash : NULL; ++} ++ ++/* Read len bytes starting at offset into buf. Returns number of bytes read. */ ++int ++sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf) ++{ ++ int cnt; ++ uint32 *from, *to; ++ ++ if (!len) ++ return 0; ++ ++ if ((offset + len) > sflash.size) ++ return -22; ++ ++ if ((len >= 4) && (offset & 3)) ++ cnt = 4 - (offset & 3); ++ else if ((len >= 4) && ((uint32)buf & 3)) ++ cnt = 4 - ((uint32)buf & 3); ++ else ++ cnt = len; ++ ++ from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset); ++ to = (uint32 *)buf; ++ ++ if (cnt < 4) { ++ bcopy(from, to, cnt); ++ return cnt; ++ } ++ ++ while (cnt >= 4) { ++ *to++ = *from++; ++ cnt -= 4; ++ } ++ ++ return (len - cnt); ++} ++ ++/* Poll for command completion. Returns zero when complete. */ ++int ++sflash_poll(chipcregs_t *cc, uint offset) ++{ ++ if (offset >= sflash.size) ++ return -22; ++ ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Check for ST Write In Progress bit */ ++ sflash_cmd(cc, SFLASH_ST_RDSR); ++ return R_REG(&cc->flashdata) & SFLASH_ST_WIP; ++ case SFLASH_AT: ++ /* Check for Atmel Ready bit */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ return !(R_REG(&cc->flashdata) & SFLASH_AT_READY); ++ } ++ ++ return 0; ++} ++ ++/* Write len bytes starting at offset into buf. Returns number of bytes ++ * written. Caller should poll for completion. ++ */ ++int ++sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++{ ++ struct sflash *sfl; ++ int ret = 0; ++ bool is4712b0; ++ uint32 page, byte, mask; ++ ++ if (!len) ++ return 0; ++ ++ if ((offset + len) > sflash.size) ++ return -22; ++ ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ mask = R_REG(&cc->chipid); ++ is4712b0 = (((mask & CID_ID_MASK) == BCM4712_DEVICE_ID) && ++ ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT))); ++ /* Enable writes */ ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ if (is4712b0) { ++ mask = 1 << 14; ++ W_REG(&cc->flashaddress, offset); ++ W_REG(&cc->flashdata, *buf++); ++ /* Set chip select */ ++ OR_REG(&cc->gpioout, mask); ++ /* Issue a page program with the first byte */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ ret = 1; ++ offset++; ++ len--; ++ while (len > 0) { ++ if ((offset & 255) == 0) { ++ /* Page boundary, drop cs and return */ ++ AND_REG(&cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -11; ++ } ++ return ret; ++ } else { ++ /* Write single byte */ ++ sflash_cmd(cc, *buf++); ++ } ++ ret++; ++ offset++; ++ len--; ++ } ++ /* All done, drop cs if needed */ ++ if ((offset & 255) != 1) { ++ /* Drop cs */ ++ AND_REG(&cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -12; ++ } ++ } ++ } else { ++ ret = 1; ++ W_REG(&cc->flashaddress, offset); ++ W_REG(&cc->flashdata, *buf); ++ /* Page program */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ } ++ break; ++ case SFLASH_AT: ++ mask = sfl->blocksize - 1; ++ page = (offset & ~mask) << 1; ++ byte = offset & mask; ++ /* Read main memory page into buffer 1 */ ++ if (byte || len < sfl->blocksize) { ++ W_REG(&cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_LOAD); ++ /* 250 us for AT45DB321B */ ++ SPINWAIT(sflash_poll(cc, offset), 1000); ++ ASSERT(!sflash_poll(cc, offset)); ++ } ++ /* Write into buffer 1 */ ++ for (ret = 0; ret < len && byte < sfl->blocksize; ret++) { ++ W_REG(&cc->flashaddress, byte++); ++ W_REG(&cc->flashdata, *buf++); ++ sflash_cmd(cc, SFLASH_AT_BUF1_WRITE); ++ } ++ /* Write buffer 1 into main memory page */ ++ W_REG(&cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM); ++ break; ++ } ++ ++ return ret; ++} ++ ++/* Erase a region. Returns number of bytes scheduled for erasure. ++ * Caller should poll for completion. ++ */ ++int ++sflash_erase(chipcregs_t *cc, uint offset) ++{ ++ struct sflash *sfl; ++ ++ if (offset >= sflash.size) ++ return -22; ++ ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ W_REG(&cc->flashaddress, offset); ++ sflash_cmd(cc, SFLASH_ST_SE); ++ return sfl->blocksize; ++ case SFLASH_AT: ++ W_REG(&cc->flashaddress, offset << 1); ++ sflash_cmd(cc, SFLASH_AT_PAGE_ERASE); ++ return sfl->blocksize; ++ } ++ ++ return 0; ++} ++ ++/* ++ * writes the appropriate range of flash, a NULL buf simply erases ++ * the region of flash ++ */ ++int ++sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++{ ++ struct sflash *sfl; ++ uchar *block = NULL, *cur_ptr, *blk_ptr; ++ uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder; ++ uint blk_offset, blk_len, copied; ++ int bytes, ret = 0; ++ ++ /* Check address range */ ++ if (len <= 0) ++ return 0; ++ ++ sfl = &sflash; ++ if ((offset + len) > sfl->size) ++ return -1; ++ ++ blocksize = sfl->blocksize; ++ mask = blocksize - 1; ++ ++ /* Allocate a block of mem */ ++ if (!(block = MALLOC(NULL, blocksize))) ++ return -1; ++ ++ while (len) { ++ /* Align offset */ ++ cur_offset = offset & ~mask; ++ cur_length = blocksize; ++ cur_ptr = block; ++ ++ remainder = blocksize - (offset & mask); ++ if (len < remainder) ++ cur_retlen = len; ++ else ++ cur_retlen = remainder; ++ ++ /* buf == NULL means erase only */ ++ if (buf) { ++ /* Copy existing data into holding block if necessary */ ++ if ((offset & mask) || (len < blocksize)) { ++ blk_offset = cur_offset; ++ blk_len = cur_length; ++ blk_ptr = cur_ptr; ++ ++ /* Copy entire block */ ++ while(blk_len) { ++ copied = sflash_read(cc, blk_offset, blk_len, blk_ptr); ++ blk_offset += copied; ++ blk_len -= copied; ++ blk_ptr += copied; ++ } ++ } ++ ++ /* Copy input data into holding block */ ++ memcpy(cur_ptr + (offset & mask), buf, cur_retlen); ++ } ++ ++ /* Erase block */ ++ if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0) ++ goto done; ++ while (sflash_poll(cc, (uint) cur_offset)); ++ ++ /* buf == NULL means erase only */ ++ if (!buf) { ++ offset += cur_retlen; ++ len -= cur_retlen; ++ continue; ++ } ++ ++ /* Write holding block */ ++ while (cur_length > 0) { ++ if ((bytes = sflash_write(cc, ++ (uint) cur_offset, ++ (uint) cur_length, ++ (uchar *) cur_ptr)) < 0) { ++ ret = bytes; ++ goto done; ++ } ++ while (sflash_poll(cc, (uint) cur_offset)); ++ cur_offset += bytes; ++ cur_length -= bytes; ++ cur_ptr += bytes; ++ } ++ ++ offset += cur_retlen; ++ len -= cur_retlen; ++ buf += cur_retlen; ++ } ++ ++ ret = len; ++done: ++ if (block) ++ MFREE(NULL, block, blocksize); ++ return ret; ++} ++ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h +--- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2005-12-28 16:37:32.874261250 +0100 +@@ -0,0 +1,391 @@ ++/* ++ * Broadcom device-specific manifest constants. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _BCMDEVS_H ++#define _BCMDEVS_H ++ ++ ++/* Known PCI vendor Id's */ ++#define VENDOR_EPIGRAM 0xfeda ++#define VENDOR_BROADCOM 0x14e4 ++#define VENDOR_3COM 0x10b7 ++#define VENDOR_NETGEAR 0x1385 ++#define VENDOR_DIAMOND 0x1092 ++#define VENDOR_DELL 0x1028 ++#define VENDOR_HP 0x0e11 ++#define VENDOR_APPLE 0x106b ++ ++/* PCI Device Id's */ ++#define BCM4210_DEVICE_ID 0x1072 /* never used */ ++#define BCM4211_DEVICE_ID 0x4211 ++#define BCM4230_DEVICE_ID 0x1086 /* never used */ ++#define BCM4231_DEVICE_ID 0x4231 ++ ++#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ ++#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ ++#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ ++#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ ++ ++#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ ++#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ ++ ++#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ ++#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ ++ ++#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */ ++#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ ++#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ ++#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ ++#define BCM47XX_USB_ID 0x4715 /* 47xx usb */ ++#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ ++#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ ++#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ ++#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ ++#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ ++#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ ++ ++#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ ++ ++#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */ ++#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */ ++#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */ ++#define BCM4610_ENET_ID 0x4613 /* 4610 enet */ ++#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */ ++#define BCM4610_USB_ID 0x4615 /* 4610 usb */ ++ ++#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */ ++#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ ++#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ ++#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ ++ ++#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */ ++#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */ ++ ++#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */ ++#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */ ++#define BCM4307_ENET_ID 0x4306 /* 4307 enet */ ++#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */ ++ ++#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ ++#define BCM4306_D11G_ID2 0x4325 ++#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ ++#define BCM4306_UART_ID 0x4322 /* 4306 uart */ ++#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ ++#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ ++ ++#define BCM4309_PKG_ID 1 /* 4309 package id */ ++ ++#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ ++#define BCM4303_PKG_ID 2 /* 4303 package id */ ++ ++#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */ ++#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */ ++#define BCM4310_UART_ID 0x4312 /* 4310 uart */ ++#define BCM4310_ENET_ID 0x4313 /* 4310 enet */ ++#define BCM4310_USB_ID 0x4315 /* 4310 usb */ ++ ++#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ ++#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ ++ ++ ++#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */ ++#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ ++ ++#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */ ++ ++#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */ ++#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */ ++ ++#define FPGA_JTAGM_ID 0x4330 /* ??? */ ++ ++/* Address map */ ++#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ ++#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ ++#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ ++#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ ++#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ ++ ++/* Core register space */ ++#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ ++#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ ++#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ ++#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ ++#define BCM4710_REG_USB 0x18004000 /* USB core registers */ ++#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ ++#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ ++#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ ++#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ ++ ++#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ ++#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ ++#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ ++#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ ++#define BCM4710_PROG 0x1f800000 /* Programable interface */ ++#define BCM4710_FLASH 0x1fc00000 /* Flash */ ++ ++#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) ++ ++#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) ++#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) ++ ++#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ ++#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ ++#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ ++#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ ++ ++#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */ ++ ++#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */ ++#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */ ++ ++#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */ ++ ++/* PCMCIA vendor Id's */ ++ ++#define VENDOR_BROADCOM_PCMCIA 0x02d0 ++ ++/* SDIO vendor Id's */ ++#define VENDOR_BROADCOM_SDIO 0x00BF ++ ++ ++/* boardflags */ ++#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */ ++#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */ ++#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */ ++#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */ ++#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */ ++#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */ ++#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */ ++#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */ ++#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */ ++#define BFL_FEM 0x0800 /* This board supports the Front End Module */ ++#define BFL_EXTLNA 0x1000 /* This board has an external LNA */ ++#define BFL_HGPA 0x2000 /* This board has a high gain PA */ ++#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ ++#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ ++ ++/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ ++#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */ ++#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ ++#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ ++#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ ++#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */ ++#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ ++#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ ++#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ ++#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ ++#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ ++ ++/* Bus types */ ++#define SB_BUS 0 /* Silicon Backplane */ ++#define PCI_BUS 1 /* PCI target */ ++#define PCMCIA_BUS 2 /* PCMCIA target */ ++#define SDIO_BUS 3 /* SDIO target */ ++#define JTAG_BUS 4 /* JTAG */ ++ ++/* Allows optimization for single-bus support */ ++#ifdef BCMBUSTYPE ++#define BUSTYPE(bus) (BCMBUSTYPE) ++#else ++#define BUSTYPE(bus) (bus) ++#endif ++ ++/* power control defines */ ++#define PLL_DELAY 150 /* us pll on delay */ ++#define FREF_DELAY 200 /* us fref change delay */ ++#define MIN_SLOW_CLK 32 /* us Slow clock period */ ++#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ ++ ++/* Reference Board Types */ ++ ++#define BU4710_BOARD 0x0400 ++#define VSIM4710_BOARD 0x0401 ++#define QT4710_BOARD 0x0402 ++ ++#define BU4610_BOARD 0x0403 ++#define VSIM4610_BOARD 0x0404 ++ ++#define BU4307_BOARD 0x0405 ++#define BCM94301CB_BOARD 0x0406 ++#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */ ++#define BCM94301MP_BOARD 0x0407 ++#define BCM94307MP_BOARD 0x0408 ++#define BCMAP4307_BOARD 0x0409 ++ ++#define BU4309_BOARD 0x040a ++#define BCM94309CB_BOARD 0x040b ++#define BCM94309MP_BOARD 0x040c ++#define BCM4309AP_BOARD 0x040d ++ ++#define BCM94302MP_BOARD 0x040e ++ ++#define VSIM4310_BOARD 0x040f ++#define BU4711_BOARD 0x0410 ++#define BCM94310U_BOARD 0x0411 ++#define BCM94310AP_BOARD 0x0412 ++#define BCM94310MP_BOARD 0x0414 ++ ++#define BU4306_BOARD 0x0416 ++#define BCM94306CB_BOARD 0x0417 ++#define BCM94306MP_BOARD 0x0418 ++ ++#define BCM94710D_BOARD 0x041a ++#define BCM94710R1_BOARD 0x041b ++#define BCM94710R4_BOARD 0x041c ++#define BCM94710AP_BOARD 0x041d ++ ++ ++#define BU2050_BOARD 0x041f ++ ++ ++#define BCM94309G_BOARD 0x0421 ++ ++#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */ ++ ++#define BU4704_BOARD 0x0423 ++#define BU4702_BOARD 0x0424 ++ ++#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ ++ ++#define BU4317_BOARD 0x0426 ++ ++ ++#define BCM94702MN_BOARD 0x0428 ++ ++/* BCM4702 1U CompactPCI Board */ ++#define BCM94702CPCI_BOARD 0x0429 ++ ++/* BCM4702 with BCM95380 VLAN Router */ ++#define BCM95380RR_BOARD 0x042a ++ ++/* cb4306 with SiGe PA */ ++#define BCM94306CBSG_BOARD 0x042b ++ ++/* mp4301 with 2050 radio */ ++#define BCM94301MPL_BOARD 0x042c ++ ++/* cb4306 with SiGe PA */ ++#define PCSG94306_BOARD 0x042d ++ ++/* bu4704 with sdram */ ++#define BU4704SD_BOARD 0x042e ++ ++/* Dual 11a/11g Router */ ++#define BCM94704AGR_BOARD 0x042f ++ ++/* 11a-only minipci */ ++#define BCM94308MP_BOARD 0x0430 ++ ++ ++ ++/* BCM94317 boards */ ++#define BCM94317CB_BOARD 0x0440 ++#define BCM94317MP_BOARD 0x0441 ++#define BCM94317PCMCIA_BOARD 0x0442 ++#define BCM94317SDIO_BOARD 0x0443 ++ ++#define BU4712_BOARD 0x0444 ++#define BU4712SD_BOARD 0x045d ++#define BU4712L_BOARD 0x045f ++ ++/* BCM4712 boards */ ++#define BCM94712AP_BOARD 0x0445 ++#define BCM94712P_BOARD 0x0446 ++ ++/* BCM4318 boards */ ++#define BU4318_BOARD 0x0447 ++#define CB4318_BOARD 0x0448 ++#define MPG4318_BOARD 0x0449 ++#define MP4318_BOARD 0x044a ++#define SD4318_BOARD 0x044b ++ ++/* BCM63XX boards */ ++#define BCM96338_BOARD 0x6338 ++#define BCM96345_BOARD 0x6345 ++#define BCM96348_BOARD 0x6348 ++ ++/* Another mp4306 with SiGe */ ++#define BCM94306P_BOARD 0x044c ++ ++/* CF-like 4317 modules */ ++#define BCM94317CF_BOARD 0x044d ++ ++/* mp4303 */ ++#define BCM94303MP_BOARD 0x044e ++ ++/* mpsgh4306 */ ++#define BCM94306MPSGH_BOARD 0x044f ++ ++/* BRCM 4306 w/ Front End Modules */ ++#define BCM94306MPM 0x0450 ++#define BCM94306MPL 0x0453 ++ ++/* 4712agr */ ++#define BCM94712AGR_BOARD 0x0451 ++ ++/* The real CF 4317 board */ ++#define CFI4317_BOARD 0x0452 ++ ++/* pcmcia 4303 */ ++#define PC4303_BOARD 0x0454 ++ ++/* 5350K */ ++#define BCM95350K_BOARD 0x0455 ++ ++/* 5350R */ ++#define BCM95350R_BOARD 0x0456 ++ ++/* 4306mplna */ ++#define BCM94306MPLNA_BOARD 0x0457 ++ ++/* 4320 boards */ ++#define BU4320_BOARD 0x0458 ++#define BU4320S_BOARD 0x0459 ++#define BCM94320PH_BOARD 0x045a ++ ++/* 4306mph */ ++#define BCM94306MPH_BOARD 0x045b ++ ++/* 4306pciv */ ++#define BCM94306PCIV_BOARD 0x045c ++ ++#define BU4712SD_BOARD 0x045d ++ ++#define BCM94320PFLSH_BOARD 0x045e ++ ++#define BU4712L_BOARD 0x045f ++#define BCM94712LGR_BOARD 0x0460 ++#define BCM94320R_BOARD 0x0461 ++ ++#define BU5352_BOARD 0x0462 ++ ++#define BCM94318MPGH_BOARD 0x0463 ++ ++ ++#define BCM95352GR_BOARD 0x0467 ++ ++/* bcm95351agr */ ++#define BCM95351AGR_BOARD 0x0470 ++ ++/* # of GPIO pins */ ++#define GPIO_NUMPINS 16 ++ ++#endif /* _BCMDEVS_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h +--- linux.old/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2005-12-28 16:37:32.874261250 +0100 +@@ -0,0 +1,152 @@ ++/* ++ * local version of endian.h - byte order defines ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++*/ ++ ++#ifndef _BCMENDIAN_H_ ++#define _BCMENDIAN_H_ ++ ++#include ++ ++/* Byte swap a 16 bit value */ ++#define BCMSWAP16(val) \ ++ ((uint16)( \ ++ (((uint16)(val) & (uint16)0x00ffU) << 8) | \ ++ (((uint16)(val) & (uint16)0xff00U) >> 8) )) ++ ++/* Byte swap a 32 bit value */ ++#define BCMSWAP32(val) \ ++ ((uint32)( \ ++ (((uint32)(val) & (uint32)0x000000ffUL) << 24) | \ ++ (((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \ ++ (((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \ ++ (((uint32)(val) & (uint32)0xff000000UL) >> 24) )) ++ ++/* 2 Byte swap a 32 bit value */ ++#define BCMSWAP32BY16(val) \ ++ ((uint32)( \ ++ (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \ ++ (((uint32)(val) & (uint32)0xffff0000UL) >> 16) )) ++ ++ ++static INLINE uint16 ++bcmswap16(uint16 val) ++{ ++ return BCMSWAP16(val); ++} ++ ++static INLINE uint32 ++bcmswap32(uint32 val) ++{ ++ return BCMSWAP32(val); ++} ++ ++static INLINE uint32 ++bcmswap32by16(uint32 val) ++{ ++ return BCMSWAP32BY16(val); ++} ++ ++/* buf - start of buffer of shorts to swap */ ++/* len - byte length of buffer */ ++static INLINE void ++bcmswap16_buf(uint16 *buf, uint len) ++{ ++ len = len/2; ++ ++ while(len--){ ++ *buf = bcmswap16(*buf); ++ buf++; ++ } ++} ++ ++#ifndef hton16 ++#ifndef IL_BIGENDIAN ++#define HTON16(i) BCMSWAP16(i) ++#define hton16(i) bcmswap16(i) ++#define hton32(i) bcmswap32(i) ++#define ntoh16(i) bcmswap16(i) ++#define ntoh32(i) bcmswap32(i) ++#define ltoh16(i) (i) ++#define ltoh32(i) (i) ++#define htol16(i) (i) ++#define htol32(i) (i) ++#else ++#define HTON16(i) (i) ++#define hton16(i) (i) ++#define hton32(i) (i) ++#define ntoh16(i) (i) ++#define ntoh32(i) (i) ++#define ltoh16(i) bcmswap16(i) ++#define ltoh32(i) bcmswap32(i) ++#define htol16(i) bcmswap16(i) ++#define htol32(i) bcmswap32(i) ++#endif ++#endif ++ ++#ifndef IL_BIGENDIAN ++#define ltoh16_buf(buf, i) ++#define htol16_buf(buf, i) ++#else ++#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#endif ++ ++/* ++* load 16-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint16 ++ltoh16_ua(uint8 *bytes) ++{ ++ return (bytes[1]<<8)+bytes[0]; ++} ++ ++/* ++* load 32-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint32 ++ltoh32_ua(uint8 *bytes) ++{ ++ return (bytes[3]<<24)+(bytes[2]<<16)+(bytes[1]<<8)+bytes[0]; ++} ++ ++/* ++* load 16-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint16 ++ntoh16_ua(uint8 *bytes) ++{ ++ return (bytes[0]<<8)+bytes[1]; ++} ++ ++/* ++* load 32-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint32 ++ntoh32_ua(uint8 *bytes) ++{ ++ return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3]; ++} ++ ++#define ltoh_ua(ptr) ( \ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \ ++ (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \ ++) ++ ++#define ntoh_ua(ptr) ( \ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \ ++ (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \ ++) ++ ++#endif /* _BCMENDIAN_H_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h +--- linux.old/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2005-12-28 19:28:28.399320000 +0100 +@@ -0,0 +1,95 @@ ++/* ++ * NVRAM variable manipulation ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmnvram_h_ ++#define _bcmnvram_h_ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++#include ++ ++struct nvram_header { ++ uint32 magic; ++ uint32 len; ++ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ ++ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ ++ uint32 config_ncdl; /* ncdl values for memc */ ++}; ++ ++struct nvram_tuple { ++ char *name; ++ char *value; ++ struct nvram_tuple *next; ++}; ++ ++/* ++ * Get the value of an NVRAM variable. The pointer returned may be ++ * invalid after a set. ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++extern char * __init early_nvram_get(const char *name); ++ ++/* ++ * Get the value of an NVRAM variable. The pointer returned may be ++ * invalid after a set. ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++extern char *nvram_get(const char *name); ++ ++/* ++ * Get the value of an NVRAM variable. ++ * @param name name of variable to get ++ * @return value of variable or NUL if undefined ++ */ ++#define nvram_safe_get(name) (BCMINIT(early_nvram_get)(name) ? : "") ++ ++/* ++ * Match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is string equal ++ * to match or FALSE otherwise ++ */ ++static inline int ++nvram_match(char *name, char *match) { ++ const char *value = BCMINIT(early_nvram_get)(name); ++ return (value && !strcmp(value, match)); ++} ++ ++/* ++ * Inversely match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is not string ++ * equal to invmatch or FALSE otherwise ++ */ ++static inline int ++nvram_invmatch(char *name, char *invmatch) { ++ const char *value = BCMINIT(early_nvram_get)(name); ++ return (value && strcmp(value, invmatch)); ++} ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ ++#define NVRAM_VERSION 1 ++#define NVRAM_HEADER_SIZE 20 ++#define NVRAM_SPACE 0x8000 ++ ++#define NVRAM_MAX_VALUE_LEN 255 ++#define NVRAM_MAX_PARAM_LEN 64 ++ ++#endif /* _bcmnvram_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm947xx/include/bcmsrom.h +--- linux.old/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2005-12-28 16:37:32.874261250 +0100 +@@ -0,0 +1,23 @@ ++/* ++ * Misc useful routines to access NIC local SROM/OTP . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmsrom_h_ ++#define _bcmsrom_h_ ++ ++extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, int *count); ++ ++extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++ ++#endif /* _bcmsrom_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bcm947xx/include/bcmutils.h +--- linux.old/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2005-12-28 16:37:32.874261250 +0100 +@@ -0,0 +1,308 @@ ++/* ++ * Misc useful os-independent macros and functions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _bcmutils_h_ ++#define _bcmutils_h_ ++ ++/*** driver-only section ***/ ++#include ++ ++#define _BCM_U 0x01 /* upper */ ++#define _BCM_L 0x02 /* lower */ ++#define _BCM_D 0x04 /* digit */ ++#define _BCM_C 0x08 /* cntrl */ ++#define _BCM_P 0x10 /* punct */ ++#define _BCM_S 0x20 /* white space (space/lf/tab) */ ++#define _BCM_X 0x40 /* hex digit */ ++#define _BCM_SP 0x80 /* hard space (0x20) */ ++ ++#define GPIO_PIN_NOTDEFINED 0x20 ++ ++extern unsigned char bcm_ctype[]; ++#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) ++ ++#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) ++#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) ++#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) ++#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) ++#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) ++#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) ++#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) ++#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) ++#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) ++ ++/* ++ * Spin at most 'us' microseconds while 'exp' is true. ++ * Caller should explicitly test 'exp' when this completes ++ * and take appropriate error action if 'exp' is still true. ++ */ ++#define SPINWAIT(exp, us) { \ ++ uint countdown = (us) + 9; \ ++ while ((exp) && (countdown >= 10)) {\ ++ OSL_DELAY(10); \ ++ countdown -= 10; \ ++ } \ ++} ++ ++/* generic osl packet queue */ ++struct pktq { ++ void *head; /* first packet to dequeue */ ++ void *tail; /* last packet to dequeue */ ++ uint len; /* number of queued packets */ ++ uint maxlen; /* maximum number of queued packets */ ++ bool priority; /* enqueue by packet priority */ ++ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */ ++}; ++#define DEFAULT_QLEN 128 ++ ++#define pktq_len(q) ((q)->len) ++#define pktq_avail(q) ((q)->maxlen - (q)->len) ++#define pktq_head(q) ((q)->head) ++#define pktq_full(q) ((q)->len >= (q)->maxlen) ++#define _pktq_pri(q, pri) ((q)->prio_map[pri]) ++#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0)) ++ ++/* externs */ ++/* packet */ ++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pkttotlen(osl_t *osh, void *); ++extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]); ++extern void pktenq(struct pktq *q, void *p, bool lifo); ++extern void *pktdeq(struct pktq *q); ++extern void *pktdeqtail(struct pktq *q); ++/* string */ ++extern uint bcm_atoi(char *s); ++extern uchar bcm_toupper(uchar c); ++extern ulong bcm_strtoul(char *cp, char **endp, uint base); ++extern char *bcmstrstr(char *haystack, char *needle); ++extern char *bcmstrcat(char *dest, const char *src); ++extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); ++/* ethernet address */ ++extern char *bcm_ether_ntoa(char *ea, char *buf); ++extern int bcm_ether_atoe(char *p, char *ea); ++/* delay */ ++extern void bcm_mdelay(uint ms); ++/* variable access */ ++extern char *getvar(char *vars, char *name); ++extern int getintvar(char *vars, char *name); ++extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); ++#define bcmlog(fmt, a1, a2) ++#define bcmdumplog(buf, size) *buf = '\0' ++#define bcmdumplogent(buf, idx) -1 ++ ++/*** driver/apps-shared section ***/ ++ ++#define BCME_STRLEN 64 ++#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) ++ ++ ++/* ++ * error codes could be added but the defined ones shouldn't be changed/deleted ++ * these error codes are exposed to the user code ++ * when ever a new error code is added to this list ++ * please update errorstring table with the related error string and ++ * update osl files with os specific errorcode map ++*/ ++ ++#define BCME_ERROR -1 /* Error generic */ ++#define BCME_BADARG -2 /* Bad Argument */ ++#define BCME_BADOPTION -3 /* Bad option */ ++#define BCME_NOTUP -4 /* Not up */ ++#define BCME_NOTDOWN -5 /* Not down */ ++#define BCME_NOTAP -6 /* Not AP */ ++#define BCME_NOTSTA -7 /* Not STA */ ++#define BCME_BADKEYIDX -8 /* BAD Key Index */ ++#define BCME_RADIOOFF -9 /* Radio Off */ ++#define BCME_NOTBANDLOCKED -10 /* Not bandlocked */ ++#define BCME_NOCLK -11 /* No Clock*/ ++#define BCME_BADRATESET -12 /* BAD RateSet*/ ++#define BCME_BADBAND -13 /* BAD Band */ ++#define BCME_BUFTOOSHORT -14 /* Buffer too short */ ++#define BCME_BUFTOOLONG -15 /* Buffer too Long */ ++#define BCME_BUSY -16 /* Busy*/ ++#define BCME_NOTASSOCIATED -17 /* Not associated*/ ++#define BCME_BADSSIDLEN -18 /* BAD SSID Len */ ++#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel*/ ++#define BCME_BADCHAN -20 /* BAD Channel */ ++#define BCME_BADADDR -21 /* BAD Address*/ ++#define BCME_NORESOURCE -22 /* No resources*/ ++#define BCME_UNSUPPORTED -23 /* Unsupported*/ ++#define BCME_BADLEN -24 /* Bad Length*/ ++#define BCME_NOTREADY -25 /* Not ready Yet*/ ++#define BCME_EPERM -26 /* Not Permitted */ ++#define BCME_NOMEM -27 /* No Memory */ ++#define BCME_ASSOCIATED -28 /* Associated */ ++#define BCME_RANGE -29 /* Range Error*/ ++#define BCME_NOTFOUND -30 /* Not found */ ++#define BCME_LAST BCME_NOTFOUND ++ ++#ifndef ABS ++#define ABS(a) (((a)<0)?-(a):(a)) ++#endif ++ ++#ifndef MIN ++#define MIN(a, b) (((a)<(b))?(a):(b)) ++#endif ++ ++#ifndef MAX ++#define MAX(a, b) (((a)>(b))?(a):(b)) ++#endif ++ ++#define CEIL(x, y) (((x) + ((y)-1)) / (y)) ++#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) ++#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) ++#define ISPOWEROF2(x) ((((x)-1)&(x))==0) ++#define VALID_MASK(mask) !((mask) & ((mask) + 1)) ++#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) ++#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) ++ ++/* bit map related macros */ ++#ifndef setbit ++#define NBBY 8 /* 8 bits per byte */ ++#define setbit(a,i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) ++#define clrbit(a,i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) ++#define isset(a,i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) ++#define isclr(a,i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) ++#endif ++ ++#define NBITS(type) (sizeof(type) * 8) ++#define NBITVAL(bits) (1 << (bits)) ++#define MAXBITVAL(bits) ((1 << (bits)) - 1) ++ ++/* crc defines */ ++#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ ++#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ ++#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ ++#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ ++#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++ ++/* bcm_format_flags() bit description structure */ ++typedef struct bcm_bit_desc { ++ uint32 bit; ++ char* name; ++} bcm_bit_desc_t; ++ ++/* tag_ID/length/value_buffer tuple */ ++typedef struct bcm_tlv { ++ uint8 id; ++ uint8 len; ++ uint8 data[1]; ++} bcm_tlv_t; ++ ++/* Check that bcm_tlv_t fits into the given buflen */ ++#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) ++ ++/* buffer length for ethernet address from bcm_ether_ntoa() */ ++#define ETHER_ADDR_STR_LEN 18 ++ ++/* unaligned load and store macros */ ++#ifdef IL_BIGENDIAN ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); ++} ++ ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[0] = (v >> 24) & 0xff; ++ a[1] = (v >> 16) & 0xff; ++ a[2] = (v >> 8) & 0xff; ++ a[3] = v & 0xff; ++} ++ ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[0] << 8) | a[1]); ++} ++ ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[0] = (v >> 8) & 0xff; ++ a[1] = v & 0xff; ++} ++ ++#else ++ ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); ++} ++ ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[3] = (v >> 24) & 0xff; ++ a[2] = (v >> 16) & 0xff; ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} ++ ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[1] << 8) | a[0]); ++} ++ ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} ++ ++#endif ++ ++/* externs */ ++/* crc */ ++extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); ++/* format/print */ ++/* IE parsing */ ++extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); ++extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); ++extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); ++ ++/* bcmerror*/ ++extern const char *bcmerrorstr(int bcmerror); ++ ++/* multi-bool data type: set of bools, mbool is true if any is set */ ++typedef uint32 mbool; ++#define mboolset(mb, bit) (mb |= bit) /* set one bool */ ++#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */ ++#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */ ++#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) ++ ++/* power conversion */ ++extern uint16 bcm_qdbm_to_mw(uint8 qdbm); ++extern uint8 bcm_mw_to_qdbm(uint16 mw); ++ ++/* generic datastruct to help dump routines */ ++struct fielddesc { ++ char *nameandfmt; ++ uint32 offset; ++ uint32 len; ++}; ++ ++typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset); ++extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str, char *buf, uint32 bufsize); ++ ++extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); ++ ++#endif /* _bcmutils_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bitfuncs.h linux.dev/arch/mips/bcm947xx/include/bitfuncs.h +--- linux.old/arch/mips/bcm947xx/include/bitfuncs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bitfuncs.h 2005-12-28 16:37:32.874261250 +0100 +@@ -0,0 +1,85 @@ ++/* ++ * bit manipulation utility functions ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _BITFUNCS_H ++#define _BITFUNCS_H ++ ++#include ++ ++/* local prototypes */ ++static INLINE uint32 find_msbit(uint32 x); ++ ++ ++/* ++ * find_msbit: returns index of most significant set bit in x, with index ++ * range defined as 0-31. NOTE: returns zero if input is zero. ++ */ ++ ++#if defined(USE_PENTIUM_BSR) && defined(__GNUC__) ++ ++/* ++ * Implementation for Pentium processors and gcc. Note that this ++ * instruction is actually very slow on some processors (e.g., family 5, ++ * model 2, stepping 12, "Pentium 75 - 200"), so we use the generic ++ * implementation instead. ++ */ ++static INLINE uint32 find_msbit(uint32 x) ++{ ++ uint msbit; ++ __asm__("bsrl %1,%0" ++ :"=r" (msbit) ++ :"r" (x)); ++ return msbit; ++} ++ ++#else ++ ++/* ++ * Generic Implementation ++ */ ++ ++#define DB_POW_MASK16 0xffff0000 ++#define DB_POW_MASK8 0x0000ff00 ++#define DB_POW_MASK4 0x000000f0 ++#define DB_POW_MASK2 0x0000000c ++#define DB_POW_MASK1 0x00000002 ++ ++static INLINE uint32 find_msbit(uint32 x) ++{ ++ uint32 temp_x = x; ++ uint msbit = 0; ++ if (temp_x & DB_POW_MASK16) { ++ temp_x >>= 16; ++ msbit = 16; ++ } ++ if (temp_x & DB_POW_MASK8) { ++ temp_x >>= 8; ++ msbit += 8; ++ } ++ if (temp_x & DB_POW_MASK4) { ++ temp_x >>= 4; ++ msbit += 4; ++ } ++ if (temp_x & DB_POW_MASK2) { ++ temp_x >>= 2; ++ msbit += 2; ++ } ++ if (temp_x & DB_POW_MASK1) { ++ msbit += 1; ++ } ++ return(msbit); ++} ++ ++#endif ++ ++#endif /* _BITFUNCS_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/flash.h linux.dev/arch/mips/bcm947xx/include/flash.h +--- linux.old/arch/mips/bcm947xx/include/flash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/flash.h 2005-12-28 16:37:32.874261250 +0100 +@@ -0,0 +1,188 @@ ++/* ++ * flash.h: Common definitions for flash access. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++/* Types of flashes we know about */ ++typedef enum _flash_type {OLD, BSC, SCS, AMD, SST, SFLASH} flash_type_t; ++ ++/* Commands to write/erase the flases */ ++typedef struct _flash_cmds{ ++ flash_type_t type; ++ bool need_unlock; ++ uint16 pre_erase; ++ uint16 erase_block; ++ uint16 erase_chip; ++ uint16 write_word; ++ uint16 write_buf; ++ uint16 clear_csr; ++ uint16 read_csr; ++ uint16 read_id; ++ uint16 confirm; ++ uint16 read_array; ++} flash_cmds_t; ++ ++#define UNLOCK_CMD_WORDS 2 ++ ++typedef struct _unlock_cmd { ++ uint addr[UNLOCK_CMD_WORDS]; ++ uint16 cmd[UNLOCK_CMD_WORDS]; ++} unlock_cmd_t; ++ ++/* Flash descriptors */ ++typedef struct _flash_desc { ++ uint16 mfgid; /* Manufacturer Id */ ++ uint16 devid; /* Device Id */ ++ uint size; /* Total size in bytes */ ++ uint width; /* Device width in bytes */ ++ flash_type_t type; /* Device type old, S, J */ ++ uint bsize; /* Block size */ ++ uint nb; /* Number of blocks */ ++ uint ff; /* First full block */ ++ uint lf; /* Last full block */ ++ uint nsub; /* Number of subblocks */ ++ uint *subblocks; /* Offsets for subblocks */ ++ char *desc; /* Description */ ++} flash_desc_t; ++ ++ ++#ifdef DECLARE_FLASHES ++flash_cmds_t sflash_cmd_t = ++ { SFLASH, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ ++flash_cmds_t flash_cmds[] = { ++/* type needu preera eraseb erasech write wbuf clcsr rdcsr rdid confrm read */ ++ { BSC, 0, 0x00, 0x20, 0x00, 0x40, 0x00, 0x50, 0x70, 0x90, 0xd0, 0xff }, ++ { SCS, 0, 0x00, 0x20, 0x00, 0x40, 0xe8, 0x50, 0x70, 0x90, 0xd0, 0xff }, ++ { AMD, 1, 0x80, 0x30, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, ++ { SST, 1, 0x80, 0x50, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, ++ { 0 } ++}; ++ ++unlock_cmd_t unlock_cmd_amd = { ++#ifdef MIPSEB ++/* addr: */ { 0x0aa8, 0x0556}, ++#else ++/* addr: */ { 0x0aaa, 0x0554}, ++#endif ++/* data: */ { 0xaa, 0x55} ++}; ++ ++unlock_cmd_t unlock_cmd_sst = { ++#ifdef MIPSEB ++/* addr: */ { 0xaaa8, 0x5556}, ++#else ++/* addr: */ { 0xaaaa, 0x5554}, ++#endif ++/* data: */ { 0xaa, 0x55} ++}; ++ ++#define AMD_CMD 0xaaa ++#define SST_CMD 0xaaaa ++ ++/* intel unlock block cmds */ ++#define INTEL_UNLOCK1 0x60 ++#define INTEL_UNLOCK2 0xD0 ++ ++/* Just eight blocks of 8KB byte each */ ++ ++uint blk8x8k[] = { 0x00000000, ++ 0x00002000, ++ 0x00004000, ++ 0x00006000, ++ 0x00008000, ++ 0x0000a000, ++ 0x0000c000, ++ 0x0000e000, ++ 0x00010000 ++}; ++ ++/* Funky AMD arrangement for 29xx800's */ ++uint amd800[] = { 0x00000000, /* 16KB */ ++ 0x00004000, /* 32KB */ ++ 0x0000c000, /* 8KB */ ++ 0x0000e000, /* 8KB */ ++ 0x00010000, /* 8KB */ ++ 0x00012000, /* 8KB */ ++ 0x00014000, /* 32KB */ ++ 0x0001c000, /* 16KB */ ++ 0x00020000 ++}; ++ ++/* AMD arrangement for 29xx160's */ ++uint amd4112[] = { 0x00000000, /* 32KB */ ++ 0x00008000, /* 8KB */ ++ 0x0000a000, /* 8KB */ ++ 0x0000c000, /* 16KB */ ++ 0x00010000 ++}; ++uint amd2114[] = { 0x00000000, /* 16KB */ ++ 0x00004000, /* 8KB */ ++ 0x00006000, /* 8KB */ ++ 0x00008000, /* 32KB */ ++ 0x00010000 ++}; ++ ++ ++flash_desc_t sflash_desc = ++ { 0, 0, 0, 0, SFLASH, 0, 0, 0, 0, 0, NULL, "SFLASH" }; ++ ++flash_desc_t flashes[] = { ++ { 0x00b0, 0x00d0, 0x0200000, 2, SCS, 0x10000, 32, 0, 31, 0, NULL, "Intel 28F160S3/5 1Mx16" }, ++ { 0x00b0, 0x00d4, 0x0400000, 2, SCS, 0x10000, 64, 0, 63, 0, NULL, "Intel 28F320S3/5 2Mx16" }, ++ { 0x0089, 0x8890, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160B3 1Mx16 TopB" }, ++ { 0x0089, 0x8891, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160B3 1Mx16 BotB" }, ++ { 0x0089, 0x8896, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320B3 2Mx16 TopB" }, ++ { 0x0089, 0x8897, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320B3 2Mx16 BotB" }, ++ { 0x0089, 0x8898, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640B3 4Mx16 TopB" }, ++ { 0x0089, 0x8899, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640B3 4Mx16 BotB" }, ++ { 0x0089, 0x88C2, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160C3 1Mx16 TopB" }, ++ { 0x0089, 0x88C3, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160C3 1Mx16 BotB" }, ++ { 0x0089, 0x88C4, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320C3 2Mx16 TopB" }, ++ { 0x0089, 0x88C5, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320C3 2Mx16 BotB" }, ++ { 0x0089, 0x88CC, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640C3 4Mx16 TopB" }, ++ { 0x0089, 0x88CD, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640C3 4Mx16 BotB" }, ++ { 0x0089, 0x0014, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J5 2Mx16" }, ++ { 0x0089, 0x0015, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J5 4Mx16" }, ++ { 0x0089, 0x0016, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J3 2Mx16" }, ++ { 0x0089, 0x0017, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J3 4Mx16" }, ++ { 0x0089, 0x0018, 0x1000000, 2, SCS, 0x20000, 128, 0, 127, 0, NULL, "Intel 28F128J3 8Mx16" }, ++ { 0x00b0, 0x00e3, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Sharp 28F320BJE 2Mx16 BotB" }, ++ { 0x0001, 0x224a, 0x0100000, 2, AMD, 0x10000, 16, 0, 13, 8, amd800, "AMD 29DL800BT 512Kx16 TopB" }, ++ { 0x0001, 0x22cb, 0x0100000, 2, AMD, 0x10000, 16, 2, 15, 8, amd800, "AMD 29DL800BB 512Kx16 BotB" }, ++ { 0x0001, 0x22c4, 0x0200000, 2, AMD, 0x10000, 32, 0, 30, 4, amd2114, "AMD 29lv160DT 1Mx16 TopB" }, ++ { 0x0001, 0x2249, 0x0200000, 2, AMD, 0x10000, 32, 1, 31, 4, amd4112, "AMD 29lv160DB 1Mx16 BotB" }, ++ { 0x0001, 0x22f6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320DT 2Mx16 TopB" }, ++ { 0x0001, 0x22f9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320DB 2Mx16 BotB" }, ++ { 0x0001, 0x227e, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" }, ++ { 0x0001, 0x2200, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320MB 2Mx16 BotB" }, ++ { 0x0020, 0x22CA, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "ST 29w320DT 2Mx16 TopB" }, ++ { 0x0020, 0x22CB, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "ST 29w320DB 2Mx16 BotB" }, ++ { 0x00C2, 0x00A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, ++ { 0x00C2, 0x00A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, ++ { 0x0004, 0x22F6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MBM29LV320TE 2Mx16 TopB" }, ++ { 0x0004, 0x22F9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MBM29LV320BE 2Mx16 BotB" }, ++ { 0x0098, 0x009A, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "TC58FVT321 2Mx16 TopB" }, ++ { 0x0098, 0x009C, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "TC58FVB321 2Mx16 BotB" }, ++ { 0x00C2, 0x22A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, ++ { 0x00C2, 0x22A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, ++ { 0x00BF, 0x2783, 0x0400000, 2, SST, 0x10000, 64, 0, 63, 0, NULL, "SST39VF320 2Mx16" }, ++ { 0, 0, 0, 0, OLD, 0, 0, 0, 0, 0, NULL, NULL }, ++}; ++ ++#else ++ ++extern flash_cmds_t flash_cmds[]; ++extern unlock_cmd_t unlock_cmd; ++extern flash_desc_t flashes[]; ++ ++#endif +diff -urN linux.old/arch/mips/bcm947xx/include/flashutl.h linux.dev/arch/mips/bcm947xx/include/flashutl.h +--- linux.old/arch/mips/bcm947xx/include/flashutl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/flashutl.h 2005-12-28 16:37:32.878261500 +0100 +@@ -0,0 +1,27 @@ ++/* ++ * BCM47XX FLASH driver interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _flashutl_h_ ++#define _flashutl_h_ ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++int sysFlashInit(char *flash_str); ++int sysFlashRead(uint off, uchar *dst, uint bytes); ++int sysFlashWrite(uint off, uchar *src, uint bytes); ++void nvWrite(unsigned short *data, unsigned int len); ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _flashutl_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm947xx/include/hndmips.h +--- linux.old/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2005-12-28 16:37:32.878261500 +0100 +@@ -0,0 +1,16 @@ ++/* ++ * Alternate include file for HND sbmips.h since CFE also ships with ++ * a sbmips.h. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include "sbmips.h" +diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/bcm947xx/include/linux_osl.h +--- linux.old/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/linux_osl.h 2005-12-28 16:37:32.878261500 +0100 +@@ -0,0 +1,331 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _linux_osl_h_ ++#define _linux_osl_h_ ++ ++#include ++ ++/* use current 2.4.x calling conventions */ ++#include ++ ++/* assert and panic */ ++#ifdef __GNUC__ ++#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) ++#if GCC_VERSION > 30100 ++#define ASSERT(exp) do {} while (0) ++#else ++/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/ ++#define ASSERT(exp) ++#endif ++#endif ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) osl_delay(usec) ++extern void osl_delay(uint usec); ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(osh, offset, size) \ ++ osl_pci_read_config((osh), (offset), (size)) ++#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ ++ osl_pci_write_config((osh), (offset), (size), (val)) ++extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset); ++extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) osl_pci_bus(osh) ++#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) ++extern uint osl_pci_bus(osl_t *osh); ++extern uint osl_pci_slot(osl_t *osh); ++ ++/* OSL initialization */ ++extern osl_t *osl_attach(void *pdev); ++extern void osl_detach(osl_t *osh); ++ ++/* host/bus architecture-specific byte swap */ ++#define BUS_SWAP32(v) (v) ++ ++/* general purpose memory allocation */ ++ ++#define MALLOC(osh, size) kmalloc(size, GFP_ATOMIC) ++#define MFREE(osh, addr, size) kfree(addr); ++ ++#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) ++ ++extern void *osl_malloc(osl_t *osh, uint size); ++extern void osl_mfree(osl_t *osh, void *addr, uint size); ++extern uint osl_malloced(osl_t *osh); ++extern uint osl_malloc_failed(osl_t *osh); ++ ++/* allocate/free shared (dma-able) consistent memory */ ++#define DMA_CONSISTENT_ALIGN PAGE_SIZE ++#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ ++ osl_dma_alloc_consistent((osh), (size), (pap)) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ ++ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) ++extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); ++extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); ++ ++/* map/unmap direction */ ++#define DMA_TX 1 ++#define DMA_RX 2 ++ ++/* register access macros */ ++#if defined(BCMJTAG) ++#include ++#define R_REG(r) bcmjtag_read(NULL, (uint32)(r), sizeof (*(r))) ++#define W_REG(r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r))) ++#endif ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ * Macros expand to calls to functions defined in linux_osl.c . ++ */ ++#ifndef BINOSL ++ ++/* string library, kernel mode */ ++#define printf(fmt, args...) printk(fmt, ## args) ++#include ++#include ++ ++/* register access macros */ ++#if !defined(BCMJTAG) ++#ifndef IL_BIGENDIAN ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ ++ readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#else /* IL_BIGENDIAN */ ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif ++#endif ++ ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++/* bcopy, bcmp, and bzero */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++/* uncached virtual address */ ++#ifdef mips ++#define OSL_UNCACHED(va) KSEG1ADDR((va)) ++#include ++#else ++#define OSL_UNCACHED(va) (va) ++#endif ++ ++/* get processor cycle count */ ++#if defined(mips) ++#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) ++#elif defined(__i386__) ++#define OSL_GETCYCLES(x) rdtscl((x)) ++#else ++#define OSL_GETCYCLES(x) ((x) = 0) ++#endif ++ ++/* dereference an address that may cause a bus exception */ ++#ifdef mips ++#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17)) ++#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module") ++#else ++#define BUSPROBE(val, addr) get_dbe((val), (addr)) ++#include ++#endif ++#else ++#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; }) ++#endif ++ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) ++#define REG_UNMAP(va) iounmap((void *)(va)) ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset((r), '\0', (len)) ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) ++#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) ++#define PKTHEADROOM(osh, skb) (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head)) ++#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) ++#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) ++#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) ++#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) ++#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) ++#define PKTDUP(osh, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC) ++#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum) ++#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x)) ++#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) ++#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) ++#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) ++#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); ++ ++#else /* BINOSL */ ++ ++/* string library */ ++#ifndef LINUX_OSL ++#undef printf ++#define printf(fmt, args...) osl_printf((fmt), ## args) ++#undef sprintf ++#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args) ++#undef strcmp ++#define strcmp(s1, s2) osl_strcmp((s1), (s2)) ++#undef strncmp ++#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) ++#undef strlen ++#define strlen(s) osl_strlen((s)) ++#undef strcpy ++#define strcpy(d, s) osl_strcpy((d), (s)) ++#undef strncpy ++#define strncpy(d, s, n) osl_strncpy((d), (s), (n)) ++#endif ++extern int osl_printf(const char *format, ...); ++extern int osl_sprintf(char *buf, const char *format, ...); ++extern int osl_strcmp(const char *s1, const char *s2); ++extern int osl_strncmp(const char *s1, const char *s2, uint n); ++extern int osl_strlen(const char *s); ++extern char* osl_strcpy(char *d, const char *s); ++extern char* osl_strncpy(char *d, const char *s, uint n); ++ ++/* register access macros */ ++#if !defined(BCMJTAG) ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ ++ osl_readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif ++ ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++extern uint8 osl_readb(volatile uint8 *r); ++extern uint16 osl_readw(volatile uint16 *r); ++extern uint32 osl_readl(volatile uint32 *r); ++extern void osl_writeb(uint8 v, volatile uint8 *r); ++extern void osl_writew(uint16 v, volatile uint16 *r); ++extern void osl_writel(uint32 v, volatile uint32 *r); ++ ++/* bcopy, bcmp, and bzero */ ++extern void bcopy(const void *src, void *dst, int len); ++extern int bcmp(const void *b1, const void *b2, int len); ++extern void bzero(void *b, int len); ++ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) osl_uncached((va)) ++extern void *osl_uncached(void *va); ++ ++/* get processor cycle count */ ++#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) ++extern uint osl_getcycles(void); ++ ++/* dereference an address that may target abort */ ++#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) ++extern int osl_busprobe(uint32 *val, uint32 addr); ++ ++/* map/unmap physical to virtual */ ++#define REG_MAP(pa, size) osl_reg_map((pa), (size)) ++#define REG_UNMAP(va) osl_reg_unmap((va)) ++extern void *osl_reg_map(uint32 pa, uint size); ++extern void osl_reg_unmap(void *va); ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) bzero((r), (len)) ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) ++#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) ++#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) ++#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) ++#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) ++#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x)) ++#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) ++#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) ++#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) ++#define PKTCOOKIE(skb) osl_pktcookie((skb)) ++#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x)) ++#define PKTLINK(skb) osl_pktlink((skb)) ++#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) ++#define PKTPRIO(skb) osl_pktprio((skb)) ++#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); ++extern uchar *osl_pktdata(osl_t *osh, void *skb); ++extern uint osl_pktlen(osl_t *osh, void *skb); ++extern uint osl_pktheadroom(osl_t *osh, void *skb); ++extern uint osl_pkttailroom(osl_t *osh, void *skb); ++extern void *osl_pktnext(osl_t *osh, void *skb); ++extern void osl_pktsetnext(void *skb, void *x); ++extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); ++extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); ++extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); ++extern void *osl_pktdup(osl_t *osh, void *skb); ++extern void *osl_pktcookie(void *skb); ++extern void osl_pktsetcookie(void *skb, void *x); ++extern void *osl_pktlink(void *skb); ++extern void osl_pktsetlink(void *skb, void *x); ++extern uint osl_pktprio(void *skb); ++extern void osl_pktsetprio(void *skb, uint x); ++ ++#endif /* BINOSL */ ++ ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int bcmerror); ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++#endif /* _linux_osl_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bcm947xx/include/linuxver.h +--- linux.old/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2005-12-28 16:37:32.878261500 +0100 +@@ -0,0 +1,389 @@ ++/* ++ * Linux-specific abstractions to gain some independence from linux kernel versions. ++ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _linuxver_h_ ++#define _linuxver_h_ ++ ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) ++/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ ++#ifdef __UNDEF_NO_VERSION__ ++#undef __NO_VERSION__ ++#else ++#define __NO_VERSION__ ++#endif ++#endif ++ ++#if defined(MODULE) && defined(MODVERSIONS) ++#include ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ++#include ++#endif ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ++#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") ++#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) ++#endif ++ ++/* linux/malloc.h is deprecated, use linux/slab.h instead. */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)) ++#include ++#else ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) ++#include ++#else ++#include ++#ifndef work_struct ++#define work_struct tq_struct ++#endif ++#ifndef INIT_WORK ++#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) ++#endif ++#ifndef schedule_work ++#define schedule_work(_work) schedule_task((_work)) ++#endif ++#ifndef flush_scheduled_work ++#define flush_scheduled_work() flush_scheduled_tasks() ++#endif ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* Some distributions have their own 2.6.x compatibility layers */ ++#ifndef IRQ_NONE ++typedef void irqreturn_t; ++#define IRQ_NONE ++#define IRQ_HANDLED ++#define IRQ_RETVAL(x) ++#endif ++#else ++typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); ++#endif ++ ++#ifndef __exit ++#define __exit ++#endif ++#ifndef __devexit ++#define __devexit ++#endif ++#ifndef __devinit ++#define __devinit __init ++#endif ++#ifndef __devinitdata ++#define __devinitdata ++#endif ++#ifndef __devexit_p ++#define __devexit_p(x) x ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) ++ ++#define pci_get_drvdata(dev) (dev)->sysdata ++#define pci_set_drvdata(dev, value) (dev)->sysdata=(value) ++ ++/* ++ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration ++ */ ++ ++struct pci_device_id { ++ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ ++ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ ++ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ ++ unsigned long driver_data; /* Data private to the driver */ ++}; ++ ++struct pci_driver { ++ struct list_head node; ++ char *name; ++ const struct pci_device_id *id_table; /* NULL if wants all devices */ ++ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ ++ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ ++ void (*suspend)(struct pci_dev *dev); /* Device suspended */ ++ void (*resume)(struct pci_dev *dev); /* Device woken up */ ++}; ++ ++#define MODULE_DEVICE_TABLE(type, name) ++#define PCI_ANY_ID (~0) ++ ++/* compatpci.c */ ++#define pci_module_init pci_register_driver ++extern int pci_register_driver(struct pci_driver *drv); ++extern void pci_unregister_driver(struct pci_driver *drv); ++ ++#endif /* PCI registration */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) ++#ifdef MODULE ++#define module_init(x) int init_module(void) { return x(); } ++#define module_exit(x) void cleanup_module(void) { x(); } ++#else ++#define module_init(x) __initcall(x); ++#define module_exit(x) __exitcall(x); ++#endif ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)) ++#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44)) ++#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23)) ++#define pci_enable_device(dev) do { } while (0) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14)) ++#define net_device device ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)) ++ ++/* ++ * DMA mapping ++ * ++ * See linux/Documentation/DMA-mapping.txt ++ */ ++ ++#ifndef PCI_DMA_TODEVICE ++#define PCI_DMA_TODEVICE 1 ++#define PCI_DMA_FROMDEVICE 2 ++#endif ++ ++typedef u32 dma_addr_t; ++ ++/* Pure 2^n version of get_order */ ++static inline int get_order(unsigned long size) ++{ ++ int order; ++ ++ size = (size-1) >> (PAGE_SHIFT-1); ++ order = -1; ++ do { ++ size >>= 1; ++ order++; ++ } while (size); ++ return order; ++} ++ ++static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ++ dma_addr_t *dma_handle) ++{ ++ void *ret; ++ int gfp = GFP_ATOMIC | GFP_DMA; ++ ++ ret = (void *)__get_free_pages(gfp, get_order(size)); ++ ++ if (ret != NULL) { ++ memset(ret, 0, size); ++ *dma_handle = virt_to_bus(ret); ++ } ++ return ret; ++} ++static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, ++ void *vaddr, dma_addr_t dma_handle) ++{ ++ free_pages((unsigned long)vaddr, get_order(size)); ++} ++#ifdef ILSIM ++extern uint pci_map_single(void *dev, void *va, uint size, int direction); ++extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); ++#else ++#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) ++#define pci_unmap_single(cookie, address, size, dir) ++#endif ++ ++#endif /* DMA mapping */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) ++ ++#define dev_kfree_skb_any(a) dev_kfree_skb(a) ++#define netif_down(dev) do { (dev)->start = 0; } while(0) ++ ++/* pcmcia-cs provides its own netdevice compatibility layer */ ++#ifndef _COMPAT_NETDEVICE_H ++ ++/* ++ * SoftNet ++ * ++ * For pre-softnet kernels we need to tell the upper layer not to ++ * re-enter start_xmit() while we are in there. However softnet ++ * guarantees not to enter while we are in there so there is no need ++ * to do the netif_stop_queue() dance unless the transmit queue really ++ * gets stuck. This should also improve performance according to tests ++ * done by Aman Singla. ++ */ ++ ++#define dev_kfree_skb_irq(a) dev_kfree_skb(a) ++#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0) ++#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) ++ ++static inline void netif_start_queue(struct net_device *dev) ++{ ++ dev->tbusy = 0; ++ dev->interrupt = 0; ++ dev->start = 1; ++} ++ ++#define netif_queue_stopped(dev) (dev)->tbusy ++#define netif_running(dev) (dev)->start ++ ++#endif /* _COMPAT_NETDEVICE_H */ ++ ++#define netif_device_attach(dev) netif_start_queue(dev) ++#define netif_device_detach(dev) netif_stop_queue(dev) ++ ++/* 2.4.x renamed bottom halves to tasklets */ ++#define tasklet_struct tq_struct ++static inline void tasklet_schedule(struct tasklet_struct *tasklet) ++{ ++ queue_task(tasklet, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++} ++ ++static inline void tasklet_init(struct tasklet_struct *tasklet, ++ void (*func)(unsigned long), ++ unsigned long data) ++{ ++ tasklet->next = NULL; ++ tasklet->sync = 0; ++ tasklet->routine = (void (*)(void *))func; ++ tasklet->data = (void *)data; ++} ++#define tasklet_kill(tasklet) {do{} while(0);} ++ ++/* 2.4.x introduced del_timer_sync() */ ++#define del_timer_sync(timer) del_timer(timer) ++ ++#else ++ ++#define netif_down(dev) ++ ++#endif /* SoftNet */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) ++ ++/* ++ * Emit code to initialise a tq_struct's routine and data pointers ++ */ ++#define PREPARE_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ (_tq)->routine = _routine; \ ++ (_tq)->data = _data; \ ++ } while (0) ++ ++/* ++ * Emit code to initialise all of a tq_struct ++ */ ++#define INIT_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ INIT_LIST_HEAD(&(_tq)->list); \ ++ (_tq)->sync = 0; \ ++ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ ++ } while (0) ++ ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6)) ++ ++/* Power management related routines */ ++ ++static inline int ++pci_save_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_read_config_dword(dev, i * 4,&buffer[i]); ++ } ++ return 0; ++} ++ ++static inline int ++pci_restore_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_write_config_dword(dev,i * 4, buffer[i]); ++ } ++ /* ++ * otherwise, write the context information we know from bootup. ++ * This works around a problem where warm-booting from Windows ++ * combined with a D3(hot)->D0 transition causes PCI config ++ * header data to be forgotten. ++ */ ++ else { ++ for (i = 0; i < 6; i ++) ++ pci_write_config_dword(dev, ++ PCI_BASE_ADDRESS_0 + (i * 4), ++ pci_resource_start(dev, i)); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ++ } ++ return 0; ++} ++ ++#endif /* PCI power management */ ++ ++/* Old cp0 access macros deprecated in 2.4.19 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)) ++#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) ++#endif ++ ++/* Module refcount handled internally in 2.6.x */ ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do {} while (0) ++#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT ++#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT ++#else ++#define OLD_MOD_INC_USE_COUNT do {} while (0) ++#define OLD_MOD_DEC_USE_COUNT do {} while (0) ++#endif ++ ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) do {} while (0) ++#endif ++ ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(dev) kfree(dev) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* struct packet_type redefined in 2.6.x */ ++#define af_packet_priv data ++#endif ++ ++#endif /* _linuxver_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm947xx/include/mipsinc.h +--- linux.old/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2005-12-28 16:37:32.878261500 +0100 +@@ -0,0 +1,552 @@ ++/* ++ * HND Run Time Environment for standalone MIPS programs. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _MISPINC_H ++#define _MISPINC_H ++ ++ ++/* MIPS defines */ ++ ++#ifdef _LANGUAGE_ASSEMBLY ++ ++/* ++ * Symbolic register names for 32 bit ABI ++ */ ++#define zero $0 /* wired zero */ ++#define AT $1 /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define t0 $8 /* caller saved */ ++#define t1 $9 ++#define t2 $10 ++#define t3 $11 ++#define t4 $12 ++#define t5 $13 ++#define t6 $14 ++#define t7 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel scratch */ ++#define k1 $27 ++#define gp $28 /* global pointer */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* same like fp! */ ++#define ra $31 /* return address */ ++ ++ ++/* ++ * CP0 Registers ++ */ ++ ++#define C0_INX $0 ++#define C0_RAND $1 ++#define C0_TLBLO0 $2 ++#define C0_TLBLO C0_TLBLO0 ++#define C0_TLBLO1 $3 ++#define C0_CTEXT $4 ++#define C0_PGMASK $5 ++#define C0_WIRED $6 ++#define C0_BADVADDR $8 ++#define C0_COUNT $9 ++#define C0_TLBHI $10 ++#define C0_COMPARE $11 ++#define C0_SR $12 ++#define C0_STATUS C0_SR ++#define C0_CAUSE $13 ++#define C0_EPC $14 ++#define C0_PRID $15 ++#define C0_CONFIG $16 ++#define C0_LLADDR $17 ++#define C0_WATCHLO $18 ++#define C0_WATCHHI $19 ++#define C0_XCTEXT $20 ++#define C0_DIAGNOSTIC $22 ++#define C0_BROADCOM C0_DIAGNOSTIC ++#define C0_PERFORMANCE $25 ++#define C0_ECC $26 ++#define C0_CACHEERR $27 ++#define C0_TAGLO $28 ++#define C0_TAGHI $29 ++#define C0_ERREPC $30 ++#define C0_DESAVE $31 ++ ++/* ++ * LEAF - declare leaf routine ++ */ ++#define LEAF(symbol) \ ++ .globl symbol; \ ++ .align 2; \ ++ .type symbol,@function; \ ++ .ent symbol,0; \ ++symbol: .frame sp,0,ra ++ ++/* ++ * END - mark end of function ++ */ ++#define END(function) \ ++ .end function; \ ++ .size function,.-function ++ ++#define _ULCAST_ ++ ++#else ++ ++/* ++ * The following macros are especially useful for __asm__ ++ * inline assembler. ++ */ ++#ifndef __STR ++#define __STR(x) #x ++#endif ++#ifndef STR ++#define STR(x) __STR(x) ++#endif ++ ++#define _ULCAST_ (unsigned long) ++ ++ ++/* ++ * CP0 Registers ++ */ ++ ++#define C0_INX 0 /* CP0: TLB Index */ ++#define C0_RAND 1 /* CP0: TLB Random */ ++#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ ++#define C0_CTEXT 4 /* CP0: Context */ ++#define C0_PGMASK 5 /* CP0: TLB PageMask */ ++#define C0_WIRED 6 /* CP0: TLB Wired */ ++#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ ++#define C0_COUNT 9 /* CP0: Count */ ++#define C0_TLBHI 10 /* CP0: TLB EntryHi */ ++#define C0_COMPARE 11 /* CP0: Compare */ ++#define C0_SR 12 /* CP0: Processor Status */ ++#define C0_STATUS C0_SR /* CP0: Processor Status */ ++#define C0_CAUSE 13 /* CP0: Exception Cause */ ++#define C0_EPC 14 /* CP0: Exception PC */ ++#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ ++#define C0_CONFIG 16 /* CP0: Config */ ++#define C0_LLADDR 17 /* CP0: LLAddr */ ++#define C0_WATCHLO 18 /* CP0: WatchpointLo */ ++#define C0_WATCHHI 19 /* CP0: WatchpointHi */ ++#define C0_XCTEXT 20 /* CP0: XContext */ ++#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ ++#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ ++#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ ++#define C0_ECC 26 /* CP0: ECC */ ++#define C0_CACHEERR 27 /* CP0: CacheErr */ ++#define C0_TAGLO 28 /* CP0: TagLo */ ++#define C0_TAGHI 29 /* CP0: TagHi */ ++#define C0_ERREPC 30 /* CP0: ErrorEPC */ ++#define C0_DESAVE 31 /* CP0: DebugSave */ ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* ++ * Memory segments (32bit kernel mode addresses) ++ */ ++#undef KUSEG ++#undef KSEG0 ++#undef KSEG1 ++#undef KSEG2 ++#undef KSEG3 ++#define KUSEG 0x00000000 ++#define KSEG0 0x80000000 ++#define KSEG1 0xa0000000 ++#define KSEG2 0xc0000000 ++#define KSEG3 0xe0000000 ++#define PHYSADDR_MASK 0x1fffffff ++ ++/* ++ * Map an address to a certain kernel segment ++ */ ++#undef PHYSADDR ++#undef KSEG0ADDR ++#undef KSEG1ADDR ++#undef KSEG2ADDR ++#undef KSEG3ADDR ++ ++#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) ++#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) ++#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) ++#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) ++#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) ++ ++ ++#ifndef Index_Invalidate_I ++/* ++ * Cache Operations ++ */ ++#define Index_Invalidate_I 0x00 ++#define Index_Writeback_Inv_D 0x01 ++#define Index_Invalidate_SI 0x02 ++#define Index_Writeback_Inv_SD 0x03 ++#define Index_Load_Tag_I 0x04 ++#define Index_Load_Tag_D 0x05 ++#define Index_Load_Tag_SI 0x06 ++#define Index_Load_Tag_SD 0x07 ++#define Index_Store_Tag_I 0x08 ++#define Index_Store_Tag_D 0x09 ++#define Index_Store_Tag_SI 0x0A ++#define Index_Store_Tag_SD 0x0B ++#define Create_Dirty_Excl_D 0x0d ++#define Create_Dirty_Excl_SD 0x0f ++#define Hit_Invalidate_I 0x10 ++#define Hit_Invalidate_D 0x11 ++#define Hit_Invalidate_SI 0x12 ++#define Hit_Invalidate_SD 0x13 ++#define Fill_I 0x14 ++#define Hit_Writeback_Inv_D 0x15 ++ /* 0x16 is unused */ ++#define Hit_Writeback_Inv_SD 0x17 ++#define R5K_Page_Invalidate_S 0x17 ++#define Hit_Writeback_I 0x18 ++#define Hit_Writeback_D 0x19 ++ /* 0x1a is unused */ ++#define Hit_Writeback_SD 0x1b ++ /* 0x1c is unused */ ++ /* 0x1e is unused */ ++#define Hit_Set_Virtual_SI 0x1e ++#define Hit_Set_Virtual_SD 0x1f ++#endif ++ ++ ++/* ++ * R4x00 interrupt enable / cause bits ++ */ ++#define IE_SW0 (_ULCAST_(1) << 8) ++#define IE_SW1 (_ULCAST_(1) << 9) ++#define IE_IRQ0 (_ULCAST_(1) << 10) ++#define IE_IRQ1 (_ULCAST_(1) << 11) ++#define IE_IRQ2 (_ULCAST_(1) << 12) ++#define IE_IRQ3 (_ULCAST_(1) << 13) ++#define IE_IRQ4 (_ULCAST_(1) << 14) ++#define IE_IRQ5 (_ULCAST_(1) << 15) ++ ++#ifndef ST0_UM ++/* ++ * Bitfields in the mips32 cp0 status register ++ */ ++#define ST0_IE 0x00000001 ++#define ST0_EXL 0x00000002 ++#define ST0_ERL 0x00000004 ++#define ST0_UM 0x00000010 ++#define ST0_SWINT0 0x00000100 ++#define ST0_SWINT1 0x00000200 ++#define ST0_HWINT0 0x00000400 ++#define ST0_HWINT1 0x00000800 ++#define ST0_HWINT2 0x00001000 ++#define ST0_HWINT3 0x00002000 ++#define ST0_HWINT4 0x00004000 ++#define ST0_HWINT5 0x00008000 ++#define ST0_IM 0x0000ff00 ++#define ST0_NMI 0x00080000 ++#define ST0_SR 0x00100000 ++#define ST0_TS 0x00200000 ++#define ST0_BEV 0x00400000 ++#define ST0_RE 0x02000000 ++#define ST0_RP 0x08000000 ++#define ST0_CU 0xf0000000 ++#define ST0_CU0 0x10000000 ++#define ST0_CU1 0x20000000 ++#define ST0_CU2 0x40000000 ++#define ST0_CU3 0x80000000 ++#endif ++ ++ ++/* ++ * Bitfields in the mips32 cp0 cause register ++ */ ++#define C_EXC 0x0000007c ++#define C_EXC_SHIFT 2 ++#define C_INT 0x0000ff00 ++#define C_INT_SHIFT 8 ++#define C_SW0 (_ULCAST_(1) << 8) ++#define C_SW1 (_ULCAST_(1) << 9) ++#define C_IRQ0 (_ULCAST_(1) << 10) ++#define C_IRQ1 (_ULCAST_(1) << 11) ++#define C_IRQ2 (_ULCAST_(1) << 12) ++#define C_IRQ3 (_ULCAST_(1) << 13) ++#define C_IRQ4 (_ULCAST_(1) << 14) ++#define C_IRQ5 (_ULCAST_(1) << 15) ++#define C_WP 0x00400000 ++#define C_IV 0x00800000 ++#define C_CE 0x30000000 ++#define C_CE_SHIFT 28 ++#define C_BD 0x80000000 ++ ++/* Values in C_EXC */ ++#define EXC_INT 0 ++#define EXC_TLBM 1 ++#define EXC_TLBL 2 ++#define EXC_TLBS 3 ++#define EXC_AEL 4 ++#define EXC_AES 5 ++#define EXC_IBE 6 ++#define EXC_DBE 7 ++#define EXC_SYS 8 ++#define EXC_BPT 9 ++#define EXC_RI 10 ++#define EXC_CU 11 ++#define EXC_OV 12 ++#define EXC_TR 13 ++#define EXC_WATCH 23 ++#define EXC_MCHK 24 ++ ++ ++/* ++ * Bits in the cp0 config register. ++ */ ++#define CONF_CM_CACHABLE_NO_WA 0 ++#define CONF_CM_CACHABLE_WA 1 ++#define CONF_CM_UNCACHED 2 ++#define CONF_CM_CACHABLE_NONCOHERENT 3 ++#define CONF_CM_CACHABLE_CE 4 ++#define CONF_CM_CACHABLE_COW 5 ++#define CONF_CM_CACHABLE_CUW 6 ++#define CONF_CM_CACHABLE_ACCELERATED 7 ++#define CONF_CM_CMASK 7 ++#define CONF_CU (_ULCAST_(1) << 3) ++#define CONF_DB (_ULCAST_(1) << 4) ++#define CONF_IB (_ULCAST_(1) << 5) ++#define CONF_SE (_ULCAST_(1) << 12) ++#define CONF_SC (_ULCAST_(1) << 17) ++#define CONF_AC (_ULCAST_(1) << 23) ++#define CONF_HALT (_ULCAST_(1) << 25) ++ ++ ++/* ++ * Bits in the cp0 config register select 1. ++ */ ++#define CONF1_FP 0x00000001 /* FPU present */ ++#define CONF1_EP 0x00000002 /* EJTAG present */ ++#define CONF1_CA 0x00000004 /* mips16 implemented */ ++#define CONF1_WR 0x00000008 /* Watch registers present */ ++#define CONF1_PC 0x00000010 /* Performance counters present */ ++#define CONF1_DA_SHIFT 7 /* D$ associativity */ ++#define CONF1_DA_MASK 0x00000380 ++#define CONF1_DA_BASE 1 ++#define CONF1_DL_SHIFT 10 /* D$ line size */ ++#define CONF1_DL_MASK 0x00001c00 ++#define CONF1_DL_BASE 2 ++#define CONF1_DS_SHIFT 13 /* D$ sets/way */ ++#define CONF1_DS_MASK 0x0000e000 ++#define CONF1_DS_BASE 64 ++#define CONF1_IA_SHIFT 16 /* I$ associativity */ ++#define CONF1_IA_MASK 0x00070000 ++#define CONF1_IA_BASE 1 ++#define CONF1_IL_SHIFT 19 /* I$ line size */ ++#define CONF1_IL_MASK 0x00380000 ++#define CONF1_IL_BASE 2 ++#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ ++#define CONF1_IS_MASK 0x01c00000 ++#define CONF1_IS_BASE 64 ++#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ ++#define CONF1_MS_SHIFT 25 ++ ++/* PRID register */ ++#define PRID_COPT_MASK 0xff000000 ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++#define PRID_REV_MASK 0x000000ff ++ ++#define PRID_COMP_LEGACY 0x000000 ++#define PRID_COMP_MIPS 0x010000 ++#define PRID_COMP_BROADCOM 0x020000 ++#define PRID_COMP_ALCHEMY 0x030000 ++#define PRID_COMP_SIBYTE 0x040000 ++#define PRID_IMP_BCM4710 0x4000 ++#define PRID_IMP_BCM3302 0x9000 ++#define PRID_IMP_BCM3303 0x9100 ++ ++#define PRID_IMP_UNKNOWN 0xff00 ++ ++#define BCM330X(id) \ ++ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ ++ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) ++ ++/* Bits in C0_BROADCOM */ ++#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ ++#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ ++#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ ++#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ ++ ++/* PreFetch Cache aka Read Ahead Cache */ ++ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ ++ ++/* PFC operations */ ++#define PFC_I 0x00000001 /* Enable PFC use for instructions */ ++#define PFC_D 0x00000002 /* Enable PFC use for data */ ++#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ ++#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ ++#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ ++#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ ++#define PFC_DPF 0x00000040 /* Enable directional prefetching */ ++#define PFC_FLUSH 0x00000100 /* Flush the PFC */ ++#define PFC_BRR 0x40000000 /* Bus error indication */ ++#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ ++ ++/* Handy defaults */ ++#define PFC_DISABLED 0 ++#define PFC_AUTO 0xffffffff /* auto select the default mode */ ++#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) ++#define PFC_INST_NOPF (PFC_I | PFC_CINV) ++#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) ++#define PFC_DATA_NOPF (PFC_D | PFC_CINV) ++#define PFC_I_AND_D (PFC_INST | PFC_DATA) ++#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) ++ ++ ++/* ++ * These are the UART port assignments, expressed as offsets from the base ++ * register. These assignments should hold for any serial port based on ++ * a 8250, 16450, or 16550(A). ++ */ ++ ++#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ ++#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ ++#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ ++#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ ++#define UART_LCR 3 /* Out: Line Control Register */ ++#define UART_MCR 4 /* Out: Modem Control Register */ ++#define UART_LSR 5 /* In: Line Status Register */ ++#define UART_MSR 6 /* In: Modem Status Register */ ++#define UART_SCR 7 /* I/O: Scratch Register */ ++#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ ++#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ ++#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ ++#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ ++#define UART_LSR_RXRDY 0x01 /* Receiver ready */ ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* ++ * Macros to access the system control coprocessor ++ */ ++ ++#define MFC0(source, sel) \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ ++ "move\t%0,$1\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res) \ ++ : \ ++ :"$1"); \ ++ __res; \ ++}) ++ ++#define MTC0(source, sel, value) \ ++do { \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "move\t$1,%z0\n\t" \ ++ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ : \ ++ :"jr" (value) \ ++ :"$1"); \ ++} while (0) ++ ++#define get_c0_count() \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "mfc0\t%0,$9\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res)); \ ++ __res; \ ++}) ++ ++static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; ++ ++ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) ++ lsz = CONF1_IL_BASE << lsz; ++ sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); ++ ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} ++ ++static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; ++ ++ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) ++ lsz = CONF1_DL_BASE << lsz; ++ sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); ++ ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} ++ ++#define cache_op(base, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, (%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++#define cache_unroll4(base, delta, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1,0(%0); \ ++ cache %1,delta(%0); \ ++ cache %1,(2 * delta)(%0); \ ++ cache %1,(3 * delta)(%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++#endif /* !_LANGUAGE_ASSEMBLY */ ++ ++#endif /* _MISPINC_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h +--- linux.old/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/osl.h 2005-12-28 16:37:32.878261500 +0100 +@@ -0,0 +1,42 @@ ++/* ++ * OS Abstraction Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _osl_h_ ++#define _osl_h_ ++ ++/* osl handle type forward declaration */ ++typedef struct os_handle osl_t; ++ ++#if defined(linux) ++#include ++#elif defined(NDIS) ++#include ++#elif defined(_CFE_) ++#include ++#elif defined(_HNDRTE_) ++#include ++#elif defined(_MINOSL_) ++#include ++#elif PMON ++#include ++#elif defined(MACOSX) ++#include ++#else ++#error "Unsupported OSL requested" ++#endif ++ ++/* handy */ ++#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val))) ++#define MAXPRIO 7 /* 0-7 */ ++ ++#endif /* _osl_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm947xx/include/pcicfg.h +--- linux.old/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2005-12-28 16:37:32.882261750 +0100 +@@ -0,0 +1,398 @@ ++/* ++ * pcicfg.h: PCI configuration constants and structures. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _h_pci_ ++#define _h_pci_ ++ ++/* The following inside ifndef's so we don't collide with NTDDK.H */ ++#ifndef PCI_MAX_BUS ++#define PCI_MAX_BUS 0x100 ++#endif ++#ifndef PCI_MAX_DEVICES ++#define PCI_MAX_DEVICES 0x20 ++#endif ++#ifndef PCI_MAX_FUNCTION ++#define PCI_MAX_FUNCTION 0x8 ++#endif ++ ++#ifndef PCI_INVALID_VENDORID ++#define PCI_INVALID_VENDORID 0xffff ++#endif ++#ifndef PCI_INVALID_DEVICEID ++#define PCI_INVALID_DEVICEID 0xffff ++#endif ++ ++ ++/* Convert between bus-slot-function-register and config addresses */ ++ ++#define PCICFG_BUS_SHIFT 16 /* Bus shift */ ++#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ ++#define PCICFG_FUN_SHIFT 8 /* Function shift */ ++#define PCICFG_OFF_SHIFT 0 /* Register shift */ ++ ++#define PCICFG_BUS_MASK 0xff /* Bus mask */ ++#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ ++#define PCICFG_FUN_MASK 7 /* Function mask */ ++#define PCICFG_OFF_MASK 0xff /* Bus mask */ ++ ++#define PCI_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ ++ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ ++ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ ++ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) ++ ++#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) ++#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) ++#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) ++#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) ++ ++/* The actual config space */ ++ ++#define PCI_BAR_MAX 6 ++ ++#define PCI_ROM_BAR 8 ++ ++#define PCR_RSVDA_MAX 2 ++ ++/* pci config status reg has a bit to indicate that capability ptr is present*/ ++ ++#define PCI_CAPPTR_PRESENT 0x0010 ++ ++typedef struct _pci_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long base[PCI_BAR_MAX]; ++ unsigned long cardbus_cis; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long baserom; ++ unsigned long rsvd_a[PCR_RSVDA_MAX]; ++ unsigned char int_line; ++ unsigned char int_pin; ++ unsigned char min_gnt; ++ unsigned char max_lat; ++ unsigned char dev_dep[192]; ++} pci_config_regs; ++ ++#define SZPCR (sizeof (pci_config_regs)) ++#define MINSZPCR 64 /* offsetof (dev_dep[0] */ ++ ++/* A structure for the config registers is nice, but in most ++ * systems the config space is not memory mapped, so we need ++ * filed offsetts. :-( ++ */ ++#define PCI_CFG_VID 0 ++#define PCI_CFG_DID 2 ++#define PCI_CFG_CMD 4 ++#define PCI_CFG_STAT 6 ++#define PCI_CFG_REV 8 ++#define PCI_CFG_PROGIF 9 ++#define PCI_CFG_SUBCL 0xa ++#define PCI_CFG_BASECL 0xb ++#define PCI_CFG_CLSZ 0xc ++#define PCI_CFG_LATTIM 0xd ++#define PCI_CFG_HDR 0xe ++#define PCI_CFG_BIST 0xf ++#define PCI_CFG_BAR0 0x10 ++#define PCI_CFG_BAR1 0x14 ++#define PCI_CFG_BAR2 0x18 ++#define PCI_CFG_BAR3 0x1c ++#define PCI_CFG_BAR4 0x20 ++#define PCI_CFG_BAR5 0x24 ++#define PCI_CFG_CIS 0x28 ++#define PCI_CFG_SVID 0x2c ++#define PCI_CFG_SSID 0x2e ++#define PCI_CFG_ROMBAR 0x30 ++#define PCI_CFG_CAPPTR 0x34 ++#define PCI_CFG_INT 0x3c ++#define PCI_CFG_PIN 0x3d ++#define PCI_CFG_MINGNT 0x3e ++#define PCI_CFG_MAXLAT 0x3f ++ ++/* Classes and subclasses */ ++ ++typedef enum { ++ PCI_CLASS_OLD = 0, ++ PCI_CLASS_DASDI, ++ PCI_CLASS_NET, ++ PCI_CLASS_DISPLAY, ++ PCI_CLASS_MMEDIA, ++ PCI_CLASS_MEMORY, ++ PCI_CLASS_BRIDGE, ++ PCI_CLASS_COMM, ++ PCI_CLASS_BASE, ++ PCI_CLASS_INPUT, ++ PCI_CLASS_DOCK, ++ PCI_CLASS_CPU, ++ PCI_CLASS_SERIAL, ++ PCI_CLASS_INTELLIGENT = 0xe, ++ PCI_CLASS_SATELLITE, ++ PCI_CLASS_CRYPT, ++ PCI_CLASS_DSP, ++ PCI_CLASS_MAX ++} pci_classes; ++ ++typedef enum { ++ PCI_DASDI_SCSI, ++ PCI_DASDI_IDE, ++ PCI_DASDI_FLOPPY, ++ PCI_DASDI_IPI, ++ PCI_DASDI_RAID, ++ PCI_DASDI_OTHER = 0x80 ++} pci_dasdi_subclasses; ++ ++typedef enum { ++ PCI_NET_ETHER, ++ PCI_NET_TOKEN, ++ PCI_NET_FDDI, ++ PCI_NET_ATM, ++ PCI_NET_OTHER = 0x80 ++} pci_net_subclasses; ++ ++typedef enum { ++ PCI_DISPLAY_VGA, ++ PCI_DISPLAY_XGA, ++ PCI_DISPLAY_3D, ++ PCI_DISPLAY_OTHER = 0x80 ++} pci_display_subclasses; ++ ++typedef enum { ++ PCI_MMEDIA_VIDEO, ++ PCI_MMEDIA_AUDIO, ++ PCI_MMEDIA_PHONE, ++ PCI_MEDIA_OTHER = 0x80 ++} pci_mmedia_subclasses; ++ ++typedef enum { ++ PCI_MEMORY_RAM, ++ PCI_MEMORY_FLASH, ++ PCI_MEMORY_OTHER = 0x80 ++} pci_memory_subclasses; ++ ++typedef enum { ++ PCI_BRIDGE_HOST, ++ PCI_BRIDGE_ISA, ++ PCI_BRIDGE_EISA, ++ PCI_BRIDGE_MC, ++ PCI_BRIDGE_PCI, ++ PCI_BRIDGE_PCMCIA, ++ PCI_BRIDGE_NUBUS, ++ PCI_BRIDGE_CARDBUS, ++ PCI_BRIDGE_RACEWAY, ++ PCI_BRIDGE_OTHER = 0x80 ++} pci_bridge_subclasses; ++ ++typedef enum { ++ PCI_COMM_UART, ++ PCI_COMM_PARALLEL, ++ PCI_COMM_MULTIUART, ++ PCI_COMM_MODEM, ++ PCI_COMM_OTHER = 0x80 ++} pci_comm_subclasses; ++ ++typedef enum { ++ PCI_BASE_PIC, ++ PCI_BASE_DMA, ++ PCI_BASE_TIMER, ++ PCI_BASE_RTC, ++ PCI_BASE_PCI_HOTPLUG, ++ PCI_BASE_OTHER = 0x80 ++} pci_base_subclasses; ++ ++typedef enum { ++ PCI_INPUT_KBD, ++ PCI_INPUT_PEN, ++ PCI_INPUT_MOUSE, ++ PCI_INPUT_SCANNER, ++ PCI_INPUT_GAMEPORT, ++ PCI_INPUT_OTHER = 0x80 ++} pci_input_subclasses; ++ ++typedef enum { ++ PCI_DOCK_GENERIC, ++ PCI_DOCK_OTHER = 0x80 ++} pci_dock_subclasses; ++ ++typedef enum { ++ PCI_CPU_386, ++ PCI_CPU_486, ++ PCI_CPU_PENTIUM, ++ PCI_CPU_ALPHA = 0x10, ++ PCI_CPU_POWERPC = 0x20, ++ PCI_CPU_MIPS = 0x30, ++ PCI_CPU_COPROC = 0x40, ++ PCI_CPU_OTHER = 0x80 ++} pci_cpu_subclasses; ++ ++typedef enum { ++ PCI_SERIAL_IEEE1394, ++ PCI_SERIAL_ACCESS, ++ PCI_SERIAL_SSA, ++ PCI_SERIAL_USB, ++ PCI_SERIAL_FIBER, ++ PCI_SERIAL_SMBUS, ++ PCI_SERIAL_OTHER = 0x80 ++} pci_serial_subclasses; ++ ++typedef enum { ++ PCI_INTELLIGENT_I2O, ++} pci_intelligent_subclasses; ++ ++typedef enum { ++ PCI_SATELLITE_TV, ++ PCI_SATELLITE_AUDIO, ++ PCI_SATELLITE_VOICE, ++ PCI_SATELLITE_DATA, ++ PCI_SATELLITE_OTHER = 0x80 ++} pci_satellite_subclasses; ++ ++typedef enum { ++ PCI_CRYPT_NETWORK, ++ PCI_CRYPT_ENTERTAINMENT, ++ PCI_CRYPT_OTHER = 0x80 ++} pci_crypt_subclasses; ++ ++typedef enum { ++ PCI_DSP_DPIO, ++ PCI_DSP_OTHER = 0x80 ++} pci_dsp_subclasses; ++ ++/* Header types */ ++typedef enum { ++ PCI_HEADER_NORMAL, ++ PCI_HEADER_BRIDGE, ++ PCI_HEADER_CARDBUS ++} pci_header_types; ++ ++ ++/* Overlay for a PCI-to-PCI bridge */ ++ ++#define PPB_RSVDA_MAX 2 ++#define PPB_RSVDD_MAX 8 ++ ++typedef struct _ppb_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long rsvd_a[PPB_RSVDA_MAX]; ++ unsigned char prim_bus; ++ unsigned char sec_bus; ++ unsigned char sub_bus; ++ unsigned char sec_lat; ++ unsigned char io_base; ++ unsigned char io_lim; ++ unsigned short sec_status; ++ unsigned short mem_base; ++ unsigned short mem_lim; ++ unsigned short pf_mem_base; ++ unsigned short pf_mem_lim; ++ unsigned long pf_mem_base_hi; ++ unsigned long pf_mem_lim_hi; ++ unsigned short io_base_hi; ++ unsigned short io_lim_hi; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long rsvd_b; ++ unsigned char rsvd_c; ++ unsigned char int_pin; ++ unsigned short bridge_ctrl; ++ unsigned char chip_ctrl; ++ unsigned char diag_ctrl; ++ unsigned short arb_ctrl; ++ unsigned long rsvd_d[PPB_RSVDD_MAX]; ++ unsigned char dev_dep[192]; ++} ppb_config_regs; ++ ++ ++/* PCI CAPABILITY DEFINES */ ++#define PCI_CAP_POWERMGMTCAP_ID 0x01 ++#define PCI_CAP_MSICAP_ID 0x05 ++ ++/* Data structure to define the Message Signalled Interrupt facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_msi { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short msgctrl; ++ unsigned int msgaddr; ++} pciconfig_cap_msi; ++ ++/* Data structure to define the Power managment facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_pwrmgmt { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pme_cap; ++ unsigned short pme_sts_ctrl; ++ unsigned char pme_bridge_ext; ++ unsigned char data; ++} pciconfig_cap_pwrmgmt; ++ ++/* Everything below is BRCM HND proprietary */ ++ ++#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ ++#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ ++#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ ++#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ ++#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ ++#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ ++#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ ++#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */ ++#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address register */ ++#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ ++#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ ++#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ ++ ++#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ ++#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ ++ ++/* PCI_INT_STATUS */ ++#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ ++ ++/* PCI_INT_MASK */ ++#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ ++#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ ++#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ ++ ++/* PCI_SPROM_CONTROL */ ++#define SPROM_BLANK 0x04 /* indicating a blank sprom */ ++#define SPROM_WRITEEN 0x10 /* sprom write enable */ ++#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ ++ ++#define SPROM_SIZE 256 /* sprom size in 16-bit */ ++#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ ++ ++/* PCI_CFG_CMD_STAT */ ++#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ ++ ++#endif +diff -urN linux.old/arch/mips/bcm947xx/include/proto/ethernet.h linux.dev/arch/mips/bcm947xx/include/proto/ethernet.h +--- linux.old/arch/mips/bcm947xx/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/proto/ethernet.h 2005-12-28 16:37:32.882261750 +0100 +@@ -0,0 +1,145 @@ ++/******************************************************************************* ++ * $Id$ ++ * Copyright 2001-2003, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. ++ ******************************************************************************/ ++ ++#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ ++#define _NET_ETHERNET_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include "typedefs.h" ++#endif ++ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#define PACKED ++#endif ++ ++/* ++ * The number of bytes in an ethernet (MAC) address. ++ */ ++#define ETHER_ADDR_LEN 6 ++ ++/* ++ * The number of bytes in the type field. ++ */ ++#define ETHER_TYPE_LEN 2 ++ ++/* ++ * The number of bytes in the trailing CRC field. ++ */ ++#define ETHER_CRC_LEN 4 ++ ++/* ++ * The length of the combined header. ++ */ ++#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) ++ ++/* ++ * The minimum packet length. ++ */ ++#define ETHER_MIN_LEN 64 ++ ++/* ++ * The minimum packet user data length. ++ */ ++#define ETHER_MIN_DATA 46 ++ ++/* ++ * The maximum packet length. ++ */ ++#define ETHER_MAX_LEN 1518 ++ ++/* ++ * The maximum packet user data length. ++ */ ++#define ETHER_MAX_DATA 1500 ++ ++/* ++ * Used to uniquely identify a 802.1q VLAN-tagged header. ++ */ ++#define VLAN_TAG 0x8100 ++ ++/* ++ * Located after dest & src address in ether header. ++ */ ++#define VLAN_FIELDS_OFFSET (ETHER_ADDR_LEN * 2) ++ ++/* ++ * 4 bytes of vlan field info. ++ */ ++#define VLAN_FIELDS_SIZE 4 ++ ++/* location of pri bits in 16-bit vlan fields */ ++#define VLAN_PRI_SHIFT 13 ++ ++/* 3 bits of priority */ ++#define VLAN_PRI_MASK 7 ++ ++/* 802.1X ethertype */ ++#define ETHER_TYPE_802_1X 0x888e ++ ++/* ++ * A macro to validate a length with ++ */ ++#define ETHER_IS_VALID_LEN(foo) \ ++ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) ++ ++ ++#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ ++/* ++ * Structure of a 10Mb/s Ethernet header. ++ */ ++struct ether_header { ++ uint8 ether_dhost[ETHER_ADDR_LEN]; ++ uint8 ether_shost[ETHER_ADDR_LEN]; ++ uint16 ether_type; ++} PACKED ; ++ ++/* ++ * Structure of a 48-bit Ethernet address. ++ */ ++struct ether_addr { ++ uint8 octet[ETHER_ADDR_LEN]; ++} PACKED ; ++#endif ++ ++/* ++ * Takes a pointer, returns true if a 48-bit multicast address ++ * (including broadcast, since it is all ones) ++ */ ++#define ETHER_ISMULTI(ea) (((uint8 *)(ea))[0] & 1) ++ ++/* ++ * Takes a pointer, returns true if a 48-bit broadcast (all ones) ++ */ ++#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ ++ ((uint8 *)(ea))[1] & \ ++ ((uint8 *)(ea))[2] & \ ++ ((uint8 *)(ea))[3] & \ ++ ((uint8 *)(ea))[4] & \ ++ ((uint8 *)(ea))[5]) == 0xff) ++ ++static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; ++ ++/* ++ * Takes a pointer, returns true if a 48-bit null address (all zeros) ++ */ ++#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ ++ ((uint8 *)(ea))[1] | \ ++ ((uint8 *)(ea))[2] | \ ++ ((uint8 *)(ea))[3] | \ ++ ((uint8 *)(ea))[4] | \ ++ ((uint8 *)(ea))[5]) == 0) ++ ++#undef PACKED ++ ++#endif /* _NET_ETHERNET_H_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/s5.h linux.dev/arch/mips/bcm947xx/include/s5.h +--- linux.old/arch/mips/bcm947xx/include/s5.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/s5.h 2005-12-28 16:37:32.882261750 +0100 +@@ -0,0 +1,103 @@ ++#ifndef _S5_H_ ++#define _S5_H_ ++/* ++ * Copyright 2003, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * Broadcom Sentry5 (S5) BCM5365, 53xx, BCM58xx SOC Internal Core ++ * and MIPS3301 (R4K) System Address Space ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation, located in the file ++ * LICENSE. ++ * ++ * $Id: s5.h,v 1.3 2003/06/10 18:54:51 jfd Exp $ ++ * ++ */ ++ ++/* BCM5365 Address map */ ++#define KSEG1ADDR(x) ( (x) | 0xa0000000) ++#define BCM5365_SDRAM 0x00000000 /* 0-128MB Physical SDRAM */ ++#define BCM5365_PCI_MEM 0x08000000 /* Host Mode PCI mem space (64MB) */ ++#define BCM5365_PCI_CFG 0x0c000000 /* Host Mode PCI cfg space (64MB) */ ++#define BCM5365_PCI_DMA 0x40000000 /* Client Mode PCI mem space (1GB)*/ ++#define BCM5365_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define BCM5365_ENUM 0x18000000 /* Beginning of core enum space */ ++ ++/* BCM5365 Core register space */ ++#define BCM5365_REG_CHIPC 0x18000000 /* Chipcommon registers */ ++#define BCM5365_REG_EMAC0 0x18001000 /* Ethernet MAC0 core registers */ ++#define BCM5365_REG_IPSEC 0x18002000 /* BCM582x CryptoCore registers */ ++#define BCM5365_REG_USB 0x18003000 /* USB core registers */ ++#define BCM5365_REG_PCI 0x18004000 /* PCI core registers */ ++#define BCM5365_REG_MIPS33 0x18005000 /* MIPS core registers */ ++#define BCM5365_REG_MEMC 0x18006000 /* MEMC core registers */ ++#define BCM5365_REG_UARTS (BCM5365_REG_CHIPC + 0x300) /* UART regs */ ++#define BCM5365_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++/* COM Ports 1/2 */ ++#define BCM5365_UART (BCM5365_REG_UARTS) ++#define BCM5365_UART_COM2 (BCM5365_REG_UARTS + 0x00000100) ++ ++/* Registers common to MIPS33 Core used in 5365 */ ++#define MIPS33_FLASH_REGION 0x1fc00000 /* Boot FLASH Region */ ++#define MIPS33_EXTIF_REGION 0x1a000000 /* Chipcommon EXTIF region*/ ++#define BCM5365_EXTIF 0x1b000000 /* MISC_CS */ ++#define MIPS33_FLASH_REGION_AUX 0x1c000000 /* FLASH Region 2*/ ++ ++/* Internal Core Sonics Backplane Devices */ ++#define INTERNAL_UART_COM1 BCM5365_UART ++#define INTERNAL_UART_COM2 BCM5365_UART_COM2 ++#define SB_REG_CHIPC BCM5365_REG_CHIPC ++#define SB_REG_ENET0 BCM5365_REG_EMAC0 ++#define SB_REG_IPSEC BCM5365_REG_IPSEC ++#define SB_REG_USB BCM5365_REG_USB ++#define SB_REG_PCI BCM5365_REG_PCI ++#define SB_REG_MIPS BCM5365_REG_MIPS33 ++#define SB_REG_MEMC BCM5365_REG_MEMC ++#define SB_REG_MEMC_OFF 0x6000 ++#define SB_EXTIF_SPACE MIPS33_EXTIF_REGION ++#define SB_FLASH_SPACE MIPS33_FLASH_REGION ++ ++/* ++ * XXX ++ * 5365-specific backplane interrupt flag numbers. This should be done ++ * dynamically instead. ++ */ ++#define SBFLAG_PCI 0 ++#define SBFLAG_ENET0 1 ++#define SBFLAG_ILINE20 2 ++#define SBFLAG_CODEC 3 ++#define SBFLAG_USB 4 ++#define SBFLAG_EXTIF 5 ++#define SBFLAG_ENET1 6 ++ ++/* BCM95365 Local Bus devices */ ++#define BCM95365K_RESET_ADDR BCM5365_EXTIF ++#define BCM95365K_BOARDID_ADDR (BCM5365_EXTIF | 0x4000) ++#define BCM95365K_DOC_ADDR (BCM5365_EXTIF | 0x6000) ++#define BCM95365K_LED_ADDR (BCM5365_EXTIF | 0xc000) ++#define BCM95365K_TOD_REG_BASE (BCM95365K_NVRAM_ADDR | 0x1ff0) ++#define BCM95365K_NVRAM_ADDR (BCM5365_EXTIF | 0xe000) ++#define BCM95365K_NVRAM_SIZE 0x1ff0 /* 8K NVRAM : DS1743/STM48txx*/ ++ ++/* Write to DLR2416 VFD Display character RAM */ ++#define LED_REG(x) \ ++ (*(volatile unsigned char *) (KSEG1ADDR(BCM95365K_LED_ADDR) + (x))) ++ ++#ifdef CONFIG_VSIM ++#define BCM5365_TRACE(trval) do { *((int *)0xa0002ff8) = (trval); \ ++ } while (0) ++#else ++#define BCM5365_TRACE(trval) do { *((unsigned char *)\ ++ KSEG1ADDR(BCM5365K_LED_ADDR)) = (trval); \ ++ *((int *)0xa0002ff8) = (trval); } while (0) ++#endif ++ ++/* BCM9536R Local Bus devices */ ++#define BCM95365R_DOC_ADDR BCM5365_EXTIF ++ ++ ++ ++#endif /*!_S5_H_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm947xx/include/sbchipc.h +--- linux.old/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2005-12-28 16:37:32.882261750 +0100 +@@ -0,0 +1,440 @@ ++/* ++ * SiliconBackplane Chipcommon core hardware definitions. ++ * ++ * The chipcommon core provides chip identification, SB control, ++ * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, ++ * gpio interface, extbus, and support for serial and parallel flashes. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#ifndef _SBCHIPC_H ++#define _SBCHIPC_H ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++typedef volatile struct { ++ uint32 chipid; /* 0x0 */ ++ uint32 capabilities; ++ uint32 corecontrol; /* corerev >= 1 */ ++ uint32 bist; ++ ++ /* OTP */ ++ uint32 otpstatus; /* 0x10, corerev >= 10 */ ++ uint32 otpcontrol; ++ uint32 otpprog; ++ uint32 PAD; ++ ++ /* Interrupt control */ ++ uint32 intstatus; /* 0x20 */ ++ uint32 intmask; ++ uint32 chipcontrol; /* 0x28, rev >= 11 */ ++ uint32 chipstatus; /* 0x2c, rev >= 11 */ ++ ++ /* Jtag Master */ ++ uint32 jtagcmd; /* 0x30, rev >= 10 */ ++ uint32 jtagir; ++ uint32 jtagdr; ++ uint32 jtagctrl; ++ ++ /* serial flash interface registers */ ++ uint32 flashcontrol; /* 0x40 */ ++ uint32 flashaddress; ++ uint32 flashdata; ++ uint32 PAD[1]; ++ ++ /* Silicon backplane configuration broadcast control */ ++ uint32 broadcastaddress; /* 0x50 */ ++ uint32 broadcastdata; ++ uint32 PAD[2]; ++ ++ /* gpio - cleared only by power-on-reset */ ++ uint32 gpioin; /* 0x60 */ ++ uint32 gpioout; ++ uint32 gpioouten; ++ uint32 gpiocontrol; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[2]; ++ ++ /* Watchdog timer */ ++ uint32 watchdog; /* 0x80 */ ++ uint32 PAD[1]; ++ ++ /*GPIO based LED powersave registers corerev >= 16*/ ++ uint32 gpiotimerval; /*0x88 */ ++ uint32 gpiotimeroutmask; ++ ++ /* clock control */ ++ uint32 clockcontrol_n; /* 0x90 */ ++ uint32 clockcontrol_sb; /* aka m0 */ ++ uint32 clockcontrol_pci; /* aka m1 */ ++ uint32 clockcontrol_m2; /* mii/uart/mipsref */ ++ uint32 clockcontrol_mips; /* aka m3 */ ++ uint32 clkdiv; /* corerev >= 3 */ ++ uint32 PAD[2]; ++ ++ /* pll delay registers (corerev >= 4) */ ++ uint32 pll_on_delay; /* 0xb0 */ ++ uint32 fref_sel_delay; ++ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ ++ uint32 PAD[1]; ++ ++ /* Instaclock registers (corerev >= 10) */ ++ uint32 system_clk_ctl; /* 0xc0 */ ++ uint32 clkstatestretch; ++ uint32 PAD[14]; ++ ++ /* ExtBus control registers (corerev >= 3) */ ++ uint32 pcmcia_config; /* 0x100 */ ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ uint32 ide_config; ++ uint32 ide_memwait; ++ uint32 ide_attrwait; ++ uint32 ide_iowait; ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[116]; ++ ++ /* uarts */ ++ uint8 uart0data; /* 0x300 */ ++ uint8 uart0imr; ++ uint8 uart0fcr; ++ uint8 uart0lcr; ++ uint8 uart0mcr; ++ uint8 uart0lsr; ++ uint8 uart0msr; ++ uint8 uart0scratch; ++ uint8 PAD[248]; /* corerev >= 1 */ ++ ++ uint8 uart1data; /* 0x400 */ ++ uint8 uart1imr; ++ uint8 uart1fcr; ++ uint8 uart1lcr; ++ uint8 uart1mcr; ++ uint8 uart1lsr; ++ uint8 uart1msr; ++ uint8 uart1scratch; ++} chipcregs_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#define CC_CHIPID 0 ++#define CC_CAPABILITIES 4 ++#define CC_JTAGCMD 0x30 ++#define CC_JTAGIR 0x34 ++#define CC_JTAGDR 0x38 ++#define CC_JTAGCTRL 0x3c ++#define CC_WATCHDOG 0x80 ++#define CC_CLKC_N 0x90 ++#define CC_CLKC_M0 0x94 ++#define CC_CLKC_M1 0x98 ++#define CC_CLKC_M2 0x9c ++#define CC_CLKC_M3 0xa0 ++#define CC_CLKDIV 0xa4 ++#define CC_SYS_CLK_CTL 0xc0 ++#define CC_OTP 0x800 ++ ++/* chipid */ ++#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ ++#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ ++#define CID_REV_SHIFT 16 /* Chip Revision shift */ ++#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ ++#define CID_PKG_SHIFT 20 /* Package Option shift */ ++#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ ++#define CID_CC_SHIFT 24 ++ ++/* capabilities */ ++#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */ ++#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ ++#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */ ++#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ ++#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */ ++#define CAP_EXTBUS 0x00000040 /* External bus present */ ++#define CAP_FLASH_MASK 0x00000700 /* Type of flash */ ++#define CAP_PLL_MASK 0x00038000 /* Type of PLL */ ++#define CAP_PWR_CTL 0x00040000 /* Power control */ ++#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ ++#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ ++#define CAP_OTPSIZE_BASE 5 /* OTP Size base */ ++#define CAP_JTAGP 0x00400000 /* JTAG Master Present */ ++#define CAP_ROM 0x00800000 /* Internal boot rom active */ ++ ++/* PLL type */ ++#define PLL_NONE 0x00000000 ++#define PLL_TYPE1 0x00010000 /* 48Mhz base, 3 dividers */ ++#define PLL_TYPE2 0x00020000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE3 0x00030000 /* 25Mhz, 2 dividers */ ++#define PLL_TYPE4 0x00008000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE5 0x00018000 /* 25Mhz, 4 dividers */ ++#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ ++#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */ ++ ++/* corecontrol */ ++#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ ++#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ ++ ++/* Fields in the otpstatus register */ ++#define OTPS_PROGFAIL 0x80000000 ++#define OTPS_PROTECT 0x00000007 ++#define OTPS_HW_PROTECT 0x00000001 ++#define OTPS_SW_PROTECT 0x00000002 ++#define OTPS_CID_PROTECT 0x00000004 ++ ++/* Fields in the otpcontrol register */ ++#define OTPC_RECWAIT 0xff000000 ++#define OTPC_PROGWAIT 0x00ffff00 ++#define OTPC_PRW_SHIFT 8 ++#define OTPC_MAXFAIL 0x00000038 ++#define OTPC_VSEL 0x00000006 ++#define OTPC_SELVL 0x00000001 ++ ++/* Fields in otpprog */ ++#define OTPP_COL_MASK 0x000000ff ++#define OTPP_ROW_MASK 0x0000ff00 ++#define OTPP_ROW_SHIFT 8 ++#define OTPP_READERR 0x10000000 ++#define OTPP_VALUE 0x20000000 ++#define OTPP_VALUE_SHIFT 29 ++#define OTPP_READ 0x40000000 ++#define OTPP_START 0x80000000 ++#define OTPP_BUSY 0x80000000 ++ ++/* jtagcmd */ ++#define JCMD_START 0x80000000 ++#define JCMD_BUSY 0x80000000 ++#define JCMD_PAUSE 0x40000000 ++#define JCMD0_ACC_MASK 0x0000f000 ++#define JCMD0_ACC_IRDR 0x00000000 ++#define JCMD0_ACC_DR 0x00001000 ++#define JCMD0_ACC_IR 0x00002000 ++#define JCMD0_ACC_RESET 0x00003000 ++#define JCMD0_ACC_IRPDR 0x00004000 ++#define JCMD0_ACC_PDR 0x00005000 ++#define JCMD0_IRW_MASK 0x00000f00 ++#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ ++#define JCMD_ACC_IRDR 0x00000000 ++#define JCMD_ACC_DR 0x00010000 ++#define JCMD_ACC_IR 0x00020000 ++#define JCMD_ACC_RESET 0x00030000 ++#define JCMD_ACC_IRPDR 0x00040000 ++#define JCMD_ACC_PDR 0x00050000 ++#define JCMD_IRW_MASK 0x00001f00 ++#define JCMD_IRW_SHIFT 8 ++#define JCMD_DRW_MASK 0x0000003f ++ ++/* jtagctrl */ ++#define JCTRL_FORCE_CLK 4 /* Force clock */ ++#define JCTRL_EXT_EN 2 /* Enable external targets */ ++#define JCTRL_EN 1 /* Enable Jtag master */ ++ ++/* Fields in clkdiv */ ++#define CLKD_SFLASH 0x0f000000 ++#define CLKD_SFLASH_SHIFT 24 ++#define CLKD_OTP 0x000f0000 ++#define CLKD_OTP_SHIFT 16 ++#define CLKD_JTAG 0x00000f00 ++#define CLKD_JTAG_SHIFT 8 ++#define CLKD_UART 0x000000ff ++ ++/* intstatus/intmask */ ++#define CI_GPIO 0x00000001 /* gpio intr */ ++#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */ ++#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ ++ ++/* slow_clk_ctl */ ++#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ ++#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ ++#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ ++#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ ++#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ ++#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ ++#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ ++#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */ ++#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */ ++#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ ++#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ ++#define SCC_CD_SHIFT 16 ++ ++/* system_clk_ctl */ ++#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ ++#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ ++#define SYCC_FP 0x00000004 /* ForcePLLOn */ ++#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ ++#define SYCC_HR 0x00000010 /* Force HT */ ++#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4+divisor)) */ ++#define SYCC_CD_SHIFT 16 ++ ++/* gpiotimerval*/ ++#define GPIO_ONTIME_SHIFT 16 ++ ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++#define CN_PLLC_MASK 0xf0000 /* pll control */ ++#define CN_PLLC_SHIFT 16 ++ ++/* clockcontrol_sb/pci/uart */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 ++ ++/* N3M Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 ++ ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++ ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 ++ ++/* Type 2 Clock control magic field values */ ++#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ ++#define CC_T2M2_BIAS 3 /* m2 bias */ ++ ++#define CC_T2MC_M1BYP 1 ++#define CC_T2MC_M2BYP 2 ++#define CC_T2MC_M3BYP 4 ++ ++/* Type 6 Clock control magic field values */ ++#define CC_T6_MMASK 1 /* bits of interest in m */ ++#define CC_T6_M0 120000000 /* sb clock for m = 0 */ ++#define CC_T6_M1 100000000 /* sb clock for m = 1 */ ++#define SB2MIPS_T6(sb) (2 * (sb)) ++ ++/* Common clock base */ ++#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ ++#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLL's */ ++ ++/* Clock control values for 200Mhz in 5350 */ ++#define CLKC_5350_N 0x0311 ++#define CLKC_5350_M 0x04020009 ++ ++/* Flash types in the chipcommon capabilities register */ ++#define FLASH_NONE 0x000 /* No flash */ ++#define SFLASH_ST 0x100 /* ST serial flash */ ++#define SFLASH_AT 0x200 /* Atmel serial flash */ ++#define PFLASH 0x700 /* Parallel flash */ ++ ++/* Bits in the config registers */ ++#define CC_CFG_EN 0x0001 /* Enable */ ++#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ ++#define CC_CFG_EM_ASYNC 0x0002 /* Async/Parallel flash */ ++#define CC_CFG_EM_SYNC 0x0004 /* Synchronous */ ++#define CC_CFG_EM_PCMCIA 0x0008 /* PCMCIA */ ++#define CC_CFG_EM_IDE 0x000a /* IDE */ ++#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ ++#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */ ++#define CC_CFG_CE 0x0080 /* Sync: Clock enable */ ++#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */ ++ ++/* Start/busy bit in flashcontrol */ ++#define SFLASH_START 0x80000000 ++#define SFLASH_BUSY SFLASH_START ++ ++/* flashcontrol opcodes for ST flashes */ ++#define SFLASH_ST_WREN 0x0006 /* Write Enable */ ++#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ ++#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ ++#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ ++#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ ++#define SFLASH_ST_PP 0x0302 /* Page Program */ ++#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ ++#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ ++#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ ++#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ ++ ++/* Status register bits for ST flashes */ ++#define SFLASH_ST_WIP 0x01 /* Write In Progress */ ++#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ ++#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ ++#define SFLASH_ST_BP_SHIFT 2 ++#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ ++ ++/* flashcontrol opcodes for Atmel flashes */ ++#define SFLASH_AT_READ 0x07e8 ++#define SFLASH_AT_PAGE_READ 0x07d2 ++#define SFLASH_AT_BUF1_READ ++#define SFLASH_AT_BUF2_READ ++#define SFLASH_AT_STATUS 0x01d7 ++#define SFLASH_AT_BUF1_WRITE 0x0384 ++#define SFLASH_AT_BUF2_WRITE 0x0387 ++#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 ++#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 ++#define SFLASH_AT_BUF1_PROGRAM 0x0288 ++#define SFLASH_AT_BUF2_PROGRAM 0x0289 ++#define SFLASH_AT_PAGE_ERASE 0x0281 ++#define SFLASH_AT_BLOCK_ERASE 0x0250 ++#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 ++#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 ++#define SFLASH_AT_BUF1_LOAD 0x0253 ++#define SFLASH_AT_BUF2_LOAD 0x0255 ++#define SFLASH_AT_BUF1_COMPARE 0x0260 ++#define SFLASH_AT_BUF2_COMPARE 0x0261 ++#define SFLASH_AT_BUF1_REPROGRAM 0x0258 ++#define SFLASH_AT_BUF2_REPROGRAM 0x0259 ++ ++/* Status register bits for Atmel flashes */ ++#define SFLASH_AT_READY 0x80 ++#define SFLASH_AT_MISMATCH 0x40 ++#define SFLASH_AT_ID_MASK 0x38 ++#define SFLASH_AT_ID_SHIFT 3 ++ ++/* OTP regions */ ++#define OTP_HW_REGION OTPS_HW_PROTECT ++#define OTP_SW_REGION OTPS_SW_PROTECT ++#define OTP_CID_REGION OTPS_CID_PROTECT ++ ++/* OTP regions (Byte offsets from otp size) */ ++#define OTP_SWLIM_OFF (-8) ++#define OTP_CIDBASE_OFF 0 ++#define OTP_CIDLIM_OFF 8 ++ ++/* Predefined OTP words (Word offset from otp size) */ ++#define OTP_BOUNDARY_OFF (-4) ++#define OTP_HWSIGN_OFF (-3) ++#define OTP_SWSIGN_OFF (-2) ++#define OTP_CIDSIGN_OFF (-1) ++ ++#define OTP_CID_OFF 0 ++#define OTP_PKG_OFF 1 ++#define OTP_FID_OFF 2 ++#define OTP_RSV_OFF 3 ++#define OTP_LIM_OFF 4 ++ ++#define OTP_SIGNATURE 0x578a ++#define OTP_MAGIC 0x4e56 ++ ++#endif /* _SBCHIPC_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bcm947xx/include/sbconfig.h +--- linux.old/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2005-12-28 16:37:32.898262750 +0100 +@@ -0,0 +1,342 @@ ++/* ++ * Broadcom SiliconBackplane hardware register definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBCONFIG_H ++#define _SBCONFIG_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* ++ * SiliconBackplane Address Map. ++ * All regions may not exist on all chips. ++ */ ++#define SB_SDRAM_BASE 0x00000000 /* Physical SDRAM */ ++#define SB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ ++#define SB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ ++#define SB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define SB_ENUM_BASE 0x18000000 /* Enumeration space base */ ++#define SB_ENUM_LIM 0x18010000 /* Enumeration space limit */ ++ ++#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ ++#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ ++ ++#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */ ++#define SB_FLASH1 0x1fc00000 /* Flash Region 1 */ ++#define SB_FLASH1_SZ 0x00400000 /* Size of Flash Region 1 */ ++ ++#define SB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ ++#define SB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ ++#define SB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */ ++#define SB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ ++#define SB_EUART (SB_EXTIF_BASE + 0x00800000) ++#define SB_LED (SB_EXTIF_BASE + 0x00900000) ++ ++ ++/* enumeration space related defs */ ++#define SB_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ ++#define SB_MAXCORES ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE) ++#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ ++#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ ++ ++/* mips address */ ++#define SB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++/* ++ * Sonics Configuration Space Registers. ++ */ ++#define SBIPSFLAG 0x08 ++#define SBTPSFLAG 0x18 ++#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ ++#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ ++#define SBADMATCH3 0x60 ++#define SBADMATCH2 0x68 ++#define SBADMATCH1 0x70 ++#define SBIMSTATE 0x90 ++#define SBINTVEC 0x94 ++#define SBTMSTATELOW 0x98 ++#define SBTMSTATEHIGH 0x9c ++#define SBBWA0 0xa0 ++#define SBIMCONFIGLOW 0xa8 ++#define SBIMCONFIGHIGH 0xac ++#define SBADMATCH0 0xb0 ++#define SBTMCONFIGLOW 0xb8 ++#define SBTMCONFIGHIGH 0xbc ++#define SBBCONFIG 0xc0 ++#define SBBSTATE 0xc8 ++#define SBACTCNFG 0xd8 ++#define SBFLAGST 0xe8 ++#define SBIDLOW 0xf8 ++#define SBIDHIGH 0xfc ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++typedef volatile struct _sbconfig { ++ uint32 PAD[2]; ++ uint32 sbipsflag; /* initiator port ocp slave flag */ ++ uint32 PAD[3]; ++ uint32 sbtpsflag; /* target port ocp slave flag */ ++ uint32 PAD[11]; ++ uint32 sbtmerrloga; /* (sonics >= 2.3) */ ++ uint32 PAD; ++ uint32 sbtmerrlog; /* (sonics >= 2.3) */ ++ uint32 PAD[3]; ++ uint32 sbadmatch3; /* address match3 */ ++ uint32 PAD; ++ uint32 sbadmatch2; /* address match2 */ ++ uint32 PAD; ++ uint32 sbadmatch1; /* address match1 */ ++ uint32 PAD[7]; ++ uint32 sbimstate; /* initiator agent state */ ++ uint32 sbintvec; /* interrupt mask */ ++ uint32 sbtmstatelow; /* target state */ ++ uint32 sbtmstatehigh; /* target state */ ++ uint32 sbbwa0; /* bandwidth allocation table0 */ ++ uint32 PAD; ++ uint32 sbimconfiglow; /* initiator configuration */ ++ uint32 sbimconfighigh; /* initiator configuration */ ++ uint32 sbadmatch0; /* address match0 */ ++ uint32 PAD; ++ uint32 sbtmconfiglow; /* target configuration */ ++ uint32 sbtmconfighigh; /* target configuration */ ++ uint32 sbbconfig; /* broadcast configuration */ ++ uint32 PAD; ++ uint32 sbbstate; /* broadcast state */ ++ uint32 PAD[3]; ++ uint32 sbactcnfg; /* activate configuration */ ++ uint32 PAD[3]; ++ uint32 sbflagst; /* current sbflags */ ++ uint32 PAD[3]; ++ uint32 sbidlow; /* identification */ ++ uint32 sbidhigh; /* identification */ ++} sbconfig_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* sbipsflag */ ++#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ ++#define SBIPS_INT1_SHIFT 0 ++#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ ++#define SBIPS_INT2_SHIFT 8 ++#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ ++#define SBIPS_INT3_SHIFT 16 ++#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ ++#define SBIPS_INT4_SHIFT 24 ++ ++/* sbtpsflag */ ++#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ ++#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ ++ ++/* sbtmerrlog */ ++#define SBTMEL_CM 0x00000007 /* command */ ++#define SBTMEL_CI 0x0000ff00 /* connection id */ ++#define SBTMEL_EC 0x0f000000 /* error code */ ++#define SBTMEL_ME 0x80000000 /* multiple error */ ++ ++/* sbimstate */ ++#define SBIM_PC 0xf /* pipecount */ ++#define SBIM_AP_MASK 0x30 /* arbitration policy */ ++#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ ++#define SBIM_AP_TS 0x10 /* use timesliaces only */ ++#define SBIM_AP_TK 0x20 /* use token only */ ++#define SBIM_AP_RSV 0x30 /* reserved */ ++#define SBIM_IBE 0x20000 /* inbanderror */ ++#define SBIM_TO 0x40000 /* timeout */ ++#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ ++#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ ++ ++/* sbtmstatelow */ ++#define SBTML_RESET 0x1 /* reset */ ++#define SBTML_REJ_MASK 0x6 /* reject */ ++#define SBTML_REJ_SHIFT 1 ++#define SBTML_CLK 0x10000 /* clock enable */ ++#define SBTML_FGC 0x20000 /* force gated clocks on */ ++#define SBTML_FL_MASK 0x3ffc0000 /* core-specific flags */ ++#define SBTML_PE 0x40000000 /* pme enable */ ++#define SBTML_BE 0x80000000 /* bist enable */ ++ ++/* sbtmstatehigh */ ++#define SBTMH_SERR 0x1 /* serror */ ++#define SBTMH_INT 0x2 /* interrupt */ ++#define SBTMH_BUSY 0x4 /* busy */ ++#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */ ++#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */ ++#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */ ++#define SBTMH_GCR 0x20000000 /* gated clock request */ ++#define SBTMH_BISTF 0x40000000 /* bist failed */ ++#define SBTMH_BISTD 0x80000000 /* bist done */ ++ ++ ++/* sbbwa0 */ ++#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ ++#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ ++#define SBBWA_TAB1_SHIFT 16 ++ ++/* sbimconfiglow */ ++#define SBIMCL_STO_MASK 0x7 /* service timeout */ ++#define SBIMCL_RTO_MASK 0x70 /* request timeout */ ++#define SBIMCL_RTO_SHIFT 4 ++#define SBIMCL_CID_MASK 0xff0000 /* connection id */ ++#define SBIMCL_CID_SHIFT 16 ++ ++/* sbimconfighigh */ ++#define SBIMCH_IEM_MASK 0xc /* inband error mode */ ++#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ ++#define SBIMCH_TEM_SHIFT 4 ++#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ ++#define SBIMCH_BEM_SHIFT 6 ++ ++/* sbadmatch0 */ ++#define SBAM_TYPE_MASK 0x3 /* address type */ ++#define SBAM_AD64 0x4 /* reserved */ ++#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ ++#define SBAM_ADINT0_SHIFT 3 ++#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ ++#define SBAM_ADINT1_SHIFT 3 ++#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ ++#define SBAM_ADINT2_SHIFT 3 ++#define SBAM_ADEN 0x400 /* enable */ ++#define SBAM_ADNEG 0x800 /* negative decode */ ++#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ ++#define SBAM_BASE0_SHIFT 8 ++#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ ++#define SBAM_BASE1_SHIFT 12 ++#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ ++#define SBAM_BASE2_SHIFT 16 ++ ++/* sbtmconfiglow */ ++#define SBTMCL_CD_MASK 0xff /* clock divide */ ++#define SBTMCL_CO_MASK 0xf800 /* clock offset */ ++#define SBTMCL_CO_SHIFT 11 ++#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ ++#define SBTMCL_IF_SHIFT 18 ++#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ ++#define SBTMCL_IM_SHIFT 24 ++ ++/* sbtmconfighigh */ ++#define SBTMCH_BM_MASK 0x3 /* busy mode */ ++#define SBTMCH_RM_MASK 0x3 /* retry mode */ ++#define SBTMCH_RM_SHIFT 2 ++#define SBTMCH_SM_MASK 0x30 /* stop mode */ ++#define SBTMCH_SM_SHIFT 4 ++#define SBTMCH_EM_MASK 0x300 /* sb error mode */ ++#define SBTMCH_EM_SHIFT 8 ++#define SBTMCH_IM_MASK 0xc00 /* int mode */ ++#define SBTMCH_IM_SHIFT 10 ++ ++/* sbbconfig */ ++#define SBBC_LAT_MASK 0x3 /* sb latency */ ++#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ ++#define SBBC_MAX0_SHIFT 16 ++#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ ++#define SBBC_MAX1_SHIFT 20 ++ ++/* sbbstate */ ++#define SBBS_SRD 0x1 /* st reg disable */ ++#define SBBS_HRD 0x2 /* hold reg disable */ ++ ++/* sbidlow */ ++#define SBIDL_CS_MASK 0x3 /* config space */ ++#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ ++#define SBIDL_AR_SHIFT 3 ++#define SBIDL_SYNCH 0x40 /* sync */ ++#define SBIDL_INIT 0x80 /* initiator */ ++#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ ++#define SBIDL_MINLAT_SHIFT 8 ++#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ ++#define SBIDL_MAXLAT_SHIFT 12 ++#define SBIDL_FIRST 0x10000 /* this initiator is first */ ++#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ ++#define SBIDL_CW_SHIFT 18 ++#define SBIDL_TP_MASK 0xf00000 /* target ports */ ++#define SBIDL_TP_SHIFT 20 ++#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ ++#define SBIDL_IP_SHIFT 24 ++#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ ++#define SBIDL_RV_SHIFT 28 ++#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ ++#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ ++ ++/* sbidhigh */ ++#define SBIDH_RC_MASK 0x000f /* revision code */ ++#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ ++#define SBIDH_RCE_SHIFT 8 ++#define SBCOREREV(sbidh) \ ++ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) ++#define SBIDH_CC_MASK 0x8ff0 /* core code */ ++#define SBIDH_CC_SHIFT 4 ++#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ ++#define SBIDH_VC_SHIFT 16 ++ ++#define SB_COMMIT 0xfd8 /* update buffered registers value */ ++ ++/* vendor codes */ ++#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ ++ ++/* core codes */ ++#define SB_CC 0x800 /* chipcommon core */ ++#define SB_ILINE20 0x801 /* iline20 core */ ++#define SB_SDRAM 0x803 /* sdram core */ ++#define SB_PCI 0x804 /* pci core */ ++#define SB_MIPS 0x805 /* mips core */ ++#define SB_ENET 0x806 /* enet mac core */ ++#define SB_CODEC 0x807 /* v90 codec core */ ++#define SB_USB 0x808 /* usb 1.1 host/device core */ ++#define SB_ADSL 0x809 /* ADSL core */ ++#define SB_ILINE100 0x80a /* iline100 core */ ++#define SB_IPSEC 0x80b /* ipsec core */ ++#define SB_PCMCIA 0x80d /* pcmcia core */ ++#define SB_SOCRAM 0x80e /* internal memory core */ ++#define SB_MEMC 0x80f /* memc sdram core */ ++#define SB_EXTIF 0x811 /* external interface core */ ++#define SB_D11 0x812 /* 802.11 MAC core */ ++#define SB_MIPS33 0x816 /* mips3302 core */ ++#define SB_USB11H 0x817 /* usb 1.1 host core */ ++#define SB_USB11D 0x818 /* usb 1.1 device core */ ++#define SB_USB20H 0x819 /* usb 2.0 host core */ ++#define SB_USB20D 0x81a /* usb 2.0 device core */ ++#define SB_SDIOH 0x81b /* sdio host core */ ++#define SB_ROBO 0x81c /* roboswitch core */ ++#define SB_ATA100 0x81d /* parallel ATA core */ ++#define SB_SATAXOR 0x81e /* serial ATA & XOR DMA core */ ++#define SB_GIGETH 0x81f /* gigabit ethernet core */ ++#define SB_PCIE 0x820 /* pci express core */ ++#define SB_SRAMC 0x822 /* SRAM controller core */ ++#define SB_MINIMAC 0x823 /* MINI MAC/phy core */ ++ ++#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */ ++ ++/* Not really related to Silicon Backplane, but a couple of software ++ * conventions for the use the flash space: ++ */ ++ ++/* Minumum amount of flash we support */ ++#define FLASH_MIN 0x00020000 /* Minimum flash size */ ++ ++/* A boot/binary may have an embedded block that describes its size */ ++#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ ++#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ ++#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ ++#define BISZ_TXTST_IDX 1 /* 1: text start */ ++#define BISZ_TXTEND_IDX 2 /* 2: text start */ ++#define BISZ_DATAST_IDX 3 /* 3: text start */ ++#define BISZ_DATAEND_IDX 4 /* 4: text start */ ++#define BISZ_BSSST_IDX 5 /* 5: text start */ ++#define BISZ_BSSEND_IDX 6 /* 6: text start */ ++#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ ++ ++#endif /* _SBCONFIG_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm947xx/include/sbextif.h +--- linux.old/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2005-12-28 16:37:32.898262750 +0100 +@@ -0,0 +1,242 @@ ++/* ++ * Hardware-specific External Interface I/O core definitions ++ * for the BCM47xx family of SiliconBackplane-based chips. ++ * ++ * The External Interface core supports a total of three external chip selects ++ * supporting external interfaces. One of the external chip selects is ++ * used for Flash, one is used for PCMCIA, and the other may be ++ * programmed to support either a synchronous interface or an ++ * asynchronous interface. The asynchronous interface can be used to ++ * support external devices such as UARTs and the BCM2019 Bluetooth ++ * baseband processor. ++ * The external interface core also contains 2 on-chip 16550 UARTs, clock ++ * frequency control, a watchdog interrupt timer, and a GPIO interface. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBEXTIF_H ++#define _SBEXTIF_H ++ ++/* external interface address space */ ++#define EXTIF_PCMCIA_MEMBASE(x) (x) ++#define EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000) ++#define EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000) ++#define EXTIF_CFGIF_BASE(x) ((x) + 0x800000) ++#define EXTIF_FLASH_BASE(x) ((x) + 0xc00000) ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * The multiple instances of output and output enable registers ++ * are present to allow driver software for multiple cores to control ++ * gpio outputs without needing to share a single register pair. ++ */ ++struct gpiouser { ++ uint32 out; ++ uint32 outen; ++}; ++#define NGPIOUSER 5 ++ ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 extstatus; ++ uint32 PAD[2]; ++ ++ /* pcmcia control registers */ ++ uint32 pcmcia_config; ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ ++ /* programmable interface control registers */ ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ ++ /* flash control registers */ ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[4]; ++ ++ uint32 watchdog; ++ ++ /* clock control */ ++ uint32 clockcontrol_n; ++ uint32 clockcontrol_sb; ++ uint32 clockcontrol_pci; ++ uint32 clockcontrol_mii; ++ uint32 PAD[3]; ++ ++ /* gpio */ ++ uint32 gpioin; ++ struct gpiouser gpio[NGPIOUSER]; ++ uint32 PAD; ++ uint32 ejtagouten; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[153]; ++ ++ uint8 uartdata; ++ uint8 PAD[3]; ++ uint8 uartimer; ++ uint8 PAD[3]; ++ uint8 uartfcr; ++ uint8 PAD[3]; ++ uint8 uartlcr; ++ uint8 PAD[3]; ++ uint8 uartmcr; ++ uint8 PAD[3]; ++ uint8 uartlsr; ++ uint8 PAD[3]; ++ uint8 uartmsr; ++ uint8 PAD[3]; ++ uint8 uartscratch; ++ uint8 PAD[3]; ++} extifregs_t; ++ ++/* corecontrol */ ++#define CC_UE (1 << 0) /* uart enable */ ++ ++/* extstatus */ ++#define ES_EM (1 << 0) /* endian mode (ro) */ ++#define ES_EI (1 << 1) /* external interrupt pin (ro) */ ++#define ES_GI (1 << 2) /* gpio interrupt pin (ro) */ ++ ++/* gpio bit mask */ ++#define GPIO_BIT0 (1 << 0) ++#define GPIO_BIT1 (1 << 1) ++#define GPIO_BIT2 (1 << 2) ++#define GPIO_BIT3 (1 << 3) ++#define GPIO_BIT4 (1 << 4) ++#define GPIO_BIT5 (1 << 5) ++#define GPIO_BIT6 (1 << 6) ++#define GPIO_BIT7 (1 << 7) ++ ++ ++/* pcmcia/prog/flash_config */ ++#define CF_EN (1 << 0) /* enable */ ++#define CF_EM_MASK 0xe /* mode */ ++#define CF_EM_SHIFT 1 ++#define CF_EM_FLASH 0x0 /* flash/asynchronous mode */ ++#define CF_EM_SYNC 0x2 /* synchronous mode */ ++#define CF_EM_PCMCIA 0x4 /* pcmcia mode */ ++#define CF_DS (1 << 4) /* destsize: 0=8bit, 1=16bit */ ++#define CF_BS (1 << 5) /* byteswap */ ++#define CF_CD_MASK 0xc0 /* clock divider */ ++#define CF_CD_SHIFT 6 ++#define CF_CD_DIV2 0x0 /* backplane/2 */ ++#define CF_CD_DIV3 0x40 /* backplane/3 */ ++#define CF_CD_DIV4 0x80 /* backplane/4 */ ++#define CF_CE (1 << 8) /* clock enable */ ++#define CF_SB (1 << 9) /* size/bytestrobe (synch only) */ ++ ++/* pcmcia_memwait */ ++#define PM_W0_MASK 0x3f /* waitcount0 */ ++#define PM_W1_MASK 0x1f00 /* waitcount1 */ ++#define PM_W1_SHIFT 8 ++#define PM_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PM_W2_SHIFT 16 ++#define PM_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PM_W3_SHIFT 24 ++ ++/* pcmcia_attrwait */ ++#define PA_W0_MASK 0x3f /* waitcount0 */ ++#define PA_W1_MASK 0x1f00 /* waitcount1 */ ++#define PA_W1_SHIFT 8 ++#define PA_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PA_W2_SHIFT 16 ++#define PA_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PA_W3_SHIFT 24 ++ ++/* pcmcia_iowait */ ++#define PI_W0_MASK 0x3f /* waitcount0 */ ++#define PI_W1_MASK 0x1f00 /* waitcount1 */ ++#define PI_W1_SHIFT 8 ++#define PI_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PI_W2_SHIFT 16 ++#define PI_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PI_W3_SHIFT 24 ++ ++/* prog_waitcount */ ++#define PW_W0_MASK 0x0000001f /* waitcount0 */ ++#define PW_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PW_W1_SHIFT 8 ++#define PW_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PW_W2_SHIFT 16 ++#define PW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PW_W3_SHIFT 24 ++ ++#define PW_W0 0x0000000c ++#define PW_W1 0x00000a00 ++#define PW_W2 0x00020000 ++#define PW_W3 0x01000000 ++ ++/* flash_waitcount */ ++#define FW_W0_MASK 0x1f /* waitcount0 */ ++#define FW_W1_MASK 0x1f00 /* waitcount1 */ ++#define FW_W1_SHIFT 8 ++#define FW_W2_MASK 0x1f0000 /* waitcount2 */ ++#define FW_W2_SHIFT 16 ++#define FW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define FW_W3_SHIFT 24 ++ ++/* watchdog */ ++#define WATCHDOG_CLOCK 48000000 /* Hz */ ++ ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++ ++/* clockcontrol_sb/pci/mii */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 ++ ++/* Clock control default values */ ++#define CC_DEF_N 0x0009 /* Default values for bcm4710 */ ++#define CC_DEF_100 0x04020011 ++#define CC_DEF_33 0x11030011 ++#define CC_DEF_25 0x11050011 ++ ++/* Clock control values for 125Mhz */ ++#define CC_125_N 0x0802 ++#define CC_125_M 0x04020009 ++#define CC_125_M25 0x11090009 ++#define CC_125_M33 0x11090005 ++ ++/* Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 ++ ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++ ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 ++ ++#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ ++ ++#endif /* _SBEXTIF_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm947xx/include/sbmemc.h +--- linux.old/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h 2005-12-28 16:37:32.902263000 +0100 +@@ -0,0 +1,148 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBMEMC_H ++#define _SBMEMC_H ++ ++#ifdef _LANGUAGE_ASSEMBLY ++ ++#define MEMC_CONTROL 0x00 ++#define MEMC_CONFIG 0x04 ++#define MEMC_REFRESH 0x08 ++#define MEMC_BISTSTAT 0x0c ++#define MEMC_MODEBUF 0x10 ++#define MEMC_BKCLS 0x14 ++#define MEMC_PRIORINV 0x18 ++#define MEMC_DRAMTIM 0x1c ++#define MEMC_INTSTAT 0x20 ++#define MEMC_INTMASK 0x24 ++#define MEMC_INTINFO 0x28 ++#define MEMC_NCDLCTL 0x30 ++#define MEMC_RDNCDLCOR 0x34 ++#define MEMC_WRNCDLCOR 0x38 ++#define MEMC_MISCDLYCTL 0x3c ++#define MEMC_DQSGATENCDL 0x40 ++#define MEMC_SPARE 0x44 ++#define MEMC_TPADDR 0x48 ++#define MEMC_TPDATA 0x4c ++#define MEMC_BARRIER 0x50 ++#define MEMC_CORE 0x54 ++ ++ ++#else ++ ++/* Sonics side: MEMC core registers */ ++typedef volatile struct sbmemcregs { ++ uint32 control; ++ uint32 config; ++ uint32 refresh; ++ uint32 biststat; ++ uint32 modebuf; ++ uint32 bkcls; ++ uint32 priorinv; ++ uint32 dramtim; ++ uint32 intstat; ++ uint32 intmask; ++ uint32 intinfo; ++ uint32 reserved1; ++ uint32 ncdlctl; ++ uint32 rdncdlcor; ++ uint32 wrncdlcor; ++ uint32 miscdlyctl; ++ uint32 dqsgatencdl; ++ uint32 spare; ++ uint32 tpaddr; ++ uint32 tpdata; ++ uint32 barrier; ++ uint32 core; ++} sbmemcregs_t; ++ ++#endif ++ ++/* MEMC Core Init values (OCP ID 0x80f) */ ++ ++/* For sdr: */ ++#define MEMC_SD_CONFIG_INIT 0x00048000 ++#define MEMC_SD_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_SD_DRAMTIM3_INIT 0x000754da ++#define MEMC_SD_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_SD_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */ ++#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b ++#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */ ++#define MEMC_SD_CONTROL_INIT0 0x00000002 ++#define MEMC_SD_CONTROL_INIT1 0x00000008 ++#define MEMC_SD_CONTROL_INIT2 0x00000004 ++#define MEMC_SD_CONTROL_INIT3 0x00000010 ++#define MEMC_SD_CONTROL_INIT4 0x00000001 ++#define MEMC_SD_MODEBUF_INIT 0x00000000 ++#define MEMC_SD_REFRESH_INIT 0x0000840f ++ ++ ++/* This is for SDRM8X8X4 */ ++#define MEMC_SDR_INIT 0x0008 ++#define MEMC_SDR_MODE 0x32 ++#define MEMC_SDR_NCDL 0x00020032 ++#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ ++ ++/* For ddr: */ ++#define MEMC_CONFIG_INIT 0x00048000 ++#define MEMC_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_DRAMTIM25_INIT 0x000754d9 ++#define MEMC_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ ++#define MEMC_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_1_WRNCDLCOR_INIT 0x14500200 ++#define MEMC_DQSGATENCDL_INIT 0x00030000 ++#define MEMC_MISCDLYCTL_INIT 0x21061c1b ++#define MEMC_1_MISCDLYCTL_INIT 0x21021400 ++#define MEMC_NCDLCTL_INIT 0x00002001 ++#define MEMC_CONTROL_INIT0 0x00000002 ++#define MEMC_CONTROL_INIT1 0x00000008 ++#define MEMC_MODEBUF_INIT0 0x00004000 ++#define MEMC_CONTROL_INIT2 0x00000010 ++#define MEMC_MODEBUF_INIT1 0x00000100 ++#define MEMC_CONTROL_INIT3 0x00000010 ++#define MEMC_CONTROL_INIT4 0x00000008 ++#define MEMC_REFRESH_INIT 0x0000840f ++#define MEMC_CONTROL_INIT5 0x00000004 ++#define MEMC_MODEBUF_INIT2 0x00000000 ++#define MEMC_CONTROL_INIT6 0x00000010 ++#define MEMC_CONTROL_INIT7 0x00000001 ++ ++ ++/* This is for DDRM16X16X2 */ ++#define MEMC_DDR_INIT 0x0009 ++#define MEMC_DDR_MODE 0x62 ++#define MEMC_DDR_NCDL 0x0005050a ++#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ ++ ++/* mask for sdr/ddr calibration registers */ ++#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff ++#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff ++#define MEMC_DQSGATENCDL_G_MASK 0x000000ff ++ ++/* masks for miscdlyctl registers */ ++#define MEMC_MISC_SM_MASK 0x30000000 ++#define MEMC_MISC_SM_SHIFT 28 ++#define MEMC_MISC_SD_MASK 0x0f000000 ++#define MEMC_MISC_SD_SHIFT 24 ++ ++/* hw threshhold for calculating wr/rd for sdr memc */ ++#define MEMC_CD_THRESHOLD 128 ++ ++/* Low bit of init register says if memc is ddr or sdr */ ++#define MEMC_CONFIG_DDR 0x00000001 ++ ++#endif /* _SBMEMC_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm947xx/include/sbmips.h +--- linux.old/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbmips.h 2005-12-28 16:37:32.902263000 +0100 +@@ -0,0 +1,62 @@ ++/* ++ * Broadcom SiliconBackplane MIPS definitions ++ * ++ * SB MIPS cores are custom MIPS32 processors with SiliconBackplane ++ * OCP interfaces. The CP0 processor ID is 0x00024000, where bits ++ * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP ++ * interface. The core revision is stored in the SB ID register in SB ++ * configuration space. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBMIPS_H ++#define _SBMIPS_H ++ ++#include ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 PAD[2]; ++ uint32 biststatus; ++ uint32 PAD[4]; ++ uint32 intstatus; ++ uint32 intmask; ++ uint32 timer; ++} mipsregs_t; ++ ++extern uint32 sb_flag(sb_t *sbh); ++extern uint sb_irq(sb_t *sbh); ++ ++extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); ++ ++extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap); ++extern void sb_jtagm_disable(void *h); ++extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr); ++extern void BCMINIT(sb_mips_init)(sb_t *sbh); ++extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh); ++extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); ++extern void BCMINIT(enable_pfc)(uint32 mode); ++extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh); ++ ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _SBMIPS_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h +--- linux.old/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2005-12-28 16:37:32.902263000 +0100 +@@ -0,0 +1,122 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ ++ ++#ifndef _SBPCI_H ++#define _SBPCI_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* Sonics side: PCI core and host control registers */ ++typedef struct sbpciregs { ++ uint32 control; /* PCI control */ ++ uint32 PAD[3]; ++ uint32 arbcontrol; /* PCI arbiter control */ ++ uint32 PAD[3]; ++ uint32 intstatus; /* Interrupt status */ ++ uint32 intmask; /* Interrupt mask */ ++ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ ++ uint32 PAD[9]; ++ uint32 bcastaddr; /* Sonics broadcast address */ ++ uint32 bcastdata; /* Sonics broadcast data */ ++ uint32 PAD[2]; ++ uint32 gpioin; /* ro: gpio input (>=rev2) */ ++ uint32 gpioout; /* rw: gpio output (>=rev2) */ ++ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ ++ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ ++ uint32 PAD[36]; ++ uint32 sbtopci0; /* Sonics to PCI translation 0 */ ++ uint32 sbtopci1; /* Sonics to PCI translation 1 */ ++ uint32 sbtopci2; /* Sonics to PCI translation 2 */ ++ uint32 PAD[445]; ++ uint16 sprom[36]; /* SPROM shadow Area */ ++ uint32 PAD[46]; ++} sbpciregs_t; ++ ++/* PCI control */ ++#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ ++#define PCI_RST 0x02 /* Value driven out to pin */ ++#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ ++#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ ++ ++/* PCI arbiter control */ ++#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ ++#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ ++#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */ ++#define PCI_PARKID_SHIFT 1 ++#define PCI_PARKID_LAST 0 /* Last requestor */ ++#define PCI_PARKID_4710 1 /* 4710 */ ++#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */ ++#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */ ++ ++/* Interrupt status/mask */ ++#define PCI_INTA 0x01 /* PCI INTA# is asserted */ ++#define PCI_INTB 0x02 /* PCI INTB# is asserted */ ++#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ ++#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ ++#define PCI_PME 0x10 /* PCI PME# is asserted */ ++ ++/* (General) PCI/SB mailbox interrupts, two bits per pci function */ ++#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ ++#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ ++#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ ++#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ ++#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ ++#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ ++#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ ++#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ ++ ++/* Sonics broadcast address */ ++#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ ++ ++/* Sonics to PCI translation types */ ++#define SBTOPCI0_MASK 0xfc000000 ++#define SBTOPCI1_MASK 0xfc000000 ++#define SBTOPCI2_MASK 0xc0000000 ++#define SBTOPCI_MEM 0 ++#define SBTOPCI_IO 1 ++#define SBTOPCI_CFG0 2 ++#define SBTOPCI_CFG1 3 ++#define SBTOPCI_PREF 0x4 /* prefetch enable */ ++#define SBTOPCI_BURST 0x8 /* burst enable */ ++#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ ++#define SBTOPCI_RC_READ 0x00 /* memory read */ ++#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ ++#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ ++ ++/* PCI core index in SROM shadow area */ ++#define SRSH_PI_OFFSET 0 /* first word */ ++#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ ++#define SRSH_PI_SHIFT 12 /* bit 15:12 */ ++ ++/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */ ++#define cap_list rsvd_a[0] ++#define bar0_window dev_dep[0x80 - 0x40] ++#define bar1_window dev_dep[0x84 - 0x40] ++#define sprom_control dev_dep[0x88 - 0x40] ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern void sbpci_ban(uint16 core); ++extern int sbpci_init(sb_t *sbh); ++extern void sbpci_check(sb_t *sbh); ++ ++#endif /* !_LANGUAGE_ASSEMBLY */ ++ ++#endif /* _SBPCI_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm947xx/include/sbsdram.h +--- linux.old/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2005-12-28 16:37:32.902263000 +0100 +@@ -0,0 +1,75 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBSDRAM_H ++#define _SBSDRAM_H ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* Sonics side: SDRAM core registers */ ++typedef volatile struct sbsdramregs { ++ uint32 initcontrol; /* Generates external SDRAM initialization sequence */ ++ uint32 config; /* Initializes external SDRAM mode register */ ++ uint32 refresh; /* Controls external SDRAM refresh rate */ ++ uint32 pad1; ++ uint32 pad2; ++} sbsdramregs_t; ++ ++#endif ++ ++/* SDRAM initialization control (initcontrol) register bits */ ++#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */ ++#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */ ++#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */ ++#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */ ++#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */ ++#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */ ++#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */ ++#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */ ++#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */ ++#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */ ++#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */ ++#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */ ++#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */ ++ ++/* SDRAM configuration (config) register bits */ ++#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */ ++#define SDRAM_BURST8 0x0001 /* Use burst of 8 */ ++#define SDRAM_BURST4 0x0002 /* Use burst of 4 */ ++#define SDRAM_BURST2 0x0003 /* Use burst of 2 */ ++#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */ ++#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */ ++ ++/* SDRAM refresh control (refresh) register bits */ ++#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */ ++#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */ ++ ++/* SDRAM Core default Init values (OCP ID 0x803) */ ++#define SDRAM_INIT MEM4MX16X2 ++#define SDRAM_CONFIG SDRAM_BURSTFULL ++#define SDRAM_REFRESH SDRAM_REF(0x40) ++ ++#define MEM1MX16 0x009 /* 2 MB */ ++#define MEM1MX16X2 0x409 /* 4 MB */ ++#define MEM2MX8X2 0x809 /* 4 MB */ ++#define MEM2MX8X4 0xc09 /* 8 MB */ ++#define MEM2MX32 0x439 /* 8 MB */ ++#define MEM4MX16 0x019 /* 8 MB */ ++#define MEM4MX16X2 0x419 /* 16 MB */ ++#define MEM8MX8X2 0x819 /* 16 MB */ ++#define MEM8MX16 0x829 /* 16 MB */ ++#define MEM4MX32 0x429 /* 16 MB */ ++#define MEM8MX8X4 0xc19 /* 32 MB */ ++#define MEM8MX16X2 0xc29 /* 32 MB */ ++ ++#endif /* _SBSDRAM_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h +--- linux.old/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2005-12-28 16:37:32.902263000 +0100 +@@ -0,0 +1,136 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of Broadcom HNBU SiliconBackplane-based chips. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _sbutils_h_ ++#define _sbutils_h_ ++ ++/* ++ * Datastructure to export all chip specific common variables ++ * public (read-only) portion of sbutils handle returned by ++ * sb_attach()/sb_kattach() ++*/ ++ ++struct sb_pub { ++ ++ uint bustype; /* SB_BUS, PCI_BUS */ ++ uint buscoretype; /* SB_PCI, SB_PCMCIA, SB_PCIE*/ ++ uint buscorerev; /* buscore rev */ ++ uint buscoreidx; /* buscore index */ ++ int ccrev; /* chip common core rev */ ++ uint boardtype; /* board type */ ++ uint boardvendor; /* board vendor */ ++ uint chip; /* chip number */ ++ uint chiprev; /* chip revision */ ++ uint chippkg; /* chip package option */ ++ uint sonicsrev; /* sonics backplane rev */ ++}; ++ ++typedef const struct sb_pub sb_t; ++ ++/* ++ * Many of the routines below take an 'sbh' handle as their first arg. ++ * Allocate this by calling sb_attach(). Free it by calling sb_detach(). ++ * At any one time, the sbh is logically focused on one particular sb core ++ * (the "current core"). ++ * Use sb_setcore() or sb_setcoreidx() to change the association to another core. ++ */ ++ ++/* exported externs */ ++extern sb_t * BCMINIT(sb_attach)(uint pcidev, osl_t *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); ++extern sb_t * BCMINIT(sb_kattach)(void); ++extern void sb_detach(sb_t *sbh); ++extern uint BCMINIT(sb_chip)(sb_t *sbh); ++extern uint BCMINIT(sb_chiprev)(sb_t *sbh); ++extern uint BCMINIT(sb_chipcrev)(sb_t *sbh); ++extern uint BCMINIT(sb_chippkg)(sb_t *sbh); ++extern uint BCMINIT(sb_pcirev)(sb_t *sbh); ++extern bool BCMINIT(sb_war16165)(sb_t *sbh); ++extern uint BCMINIT(sb_boardvendor)(sb_t *sbh); ++extern uint BCMINIT(sb_boardtype)(sb_t *sbh); ++extern uint sb_bus(sb_t *sbh); ++extern uint sb_buscoretype(sb_t *sbh); ++extern uint sb_buscorerev(sb_t *sbh); ++extern uint sb_corelist(sb_t *sbh, uint coreid[]); ++extern uint sb_coreid(sb_t *sbh); ++extern uint sb_coreidx(sb_t *sbh); ++extern uint sb_coreunit(sb_t *sbh); ++extern uint sb_corevendor(sb_t *sbh); ++extern uint sb_corerev(sb_t *sbh); ++extern void *sb_osh(sb_t *sbh); ++extern void *sb_coreregs(sb_t *sbh); ++extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val); ++extern bool sb_iscoreup(sb_t *sbh); ++extern void *sb_setcoreidx(sb_t *sbh, uint coreidx); ++extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit); ++extern int sb_corebist(sb_t *sbh, uint coreid, uint coreunit); ++extern void sb_commit(sb_t *sbh); ++extern uint32 sb_base(uint32 admatch); ++extern uint32 sb_size(uint32 admatch); ++extern void sb_core_reset(sb_t *sbh, uint32 bits); ++extern void sb_core_tofixup(sb_t *sbh); ++extern void sb_core_disable(sb_t *sbh, uint32 bits); ++extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m); ++extern uint32 sb_clock(sb_t *sbh); ++extern void sb_pci_setup(sb_t *sbh, uint coremask); ++extern void sb_watchdog(sb_t *sbh, uint ticks); ++extern void *sb_gpiosetcore(sb_t *sbh); ++extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioin(sb_t *sbh); ++extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority); ++extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority); ++ ++extern void sb_clkctl_init(sb_t *sbh); ++extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh); ++extern bool sb_clkctl_clk(sb_t *sbh, uint mode); ++extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on); ++extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, ++ void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg); ++extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to); ++extern void sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif); ++extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val); ++ ++ ++ ++/* ++* Build device path. Path size must be >= SB_DEVPATH_BUFSZ. ++* The returned path is NULL terminated and has trailing '/'. ++* Return 0 on success, nonzero otherwise. ++*/ ++extern int sb_devpath(sb_t *sbh, char *path, int size); ++ ++/* clkctl xtal what flags */ ++#define XTAL 0x1 /* primary crystal oscillator (2050) */ ++#define PLL 0x2 /* main chip pll */ ++ ++/* clkctl clk mode */ ++#define CLK_FAST 0 /* force fast (pll) clock */ ++#define CLK_DYNAMIC 2 /* enable dynamic clock control */ ++ ++ ++/* GPIO usage priorities */ ++#define GPIO_DRV_PRIORITY 0 ++#define GPIO_APP_PRIORITY 1 ++ ++/* device path */ ++#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ ++ ++#endif /* _sbutils_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm947xx/include/sflash.h +--- linux.old/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2005-12-28 16:37:32.902263000 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _sflash_h_ ++#define _sflash_h_ ++ ++#include ++#include ++ ++struct sflash { ++ uint blocksize; /* Block size */ ++ uint numblocks; /* Number of blocks */ ++ uint32 type; /* Type */ ++ uint size; /* Total size in bytes */ ++}; ++ ++/* Utility functions */ ++extern int sflash_poll(chipcregs_t *cc, uint offset); ++extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf); ++extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern int sflash_erase(chipcregs_t *cc, uint offset); ++extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern struct sflash * sflash_init(chipcregs_t *cc); ++ ++#endif /* _sflash_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm947xx/include/trxhdr.h +--- linux.old/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2005-12-28 16:37:32.902263000 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * TRX image file header format. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++ ++#define TRX_MAGIC 0x30524448 /* "HDR0" */ ++#define TRX_VERSION 1 ++#define TRX_MAX_LEN 0x3A0000 ++#define TRX_NO_HEADER 1 /* Do not write TRX header */ ++#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ ++#define TRX_MAX_OFFSET 3 ++ ++struct trx_header { ++ uint32 magic; /* "HDR0" */ ++ uint32 len; /* Length of file including header */ ++ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ ++ uint32 flag_version; /* 0:15 flags, 16:31 version */ ++ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ ++}; ++ ++/* Compatibility */ ++typedef struct trx_header TRXHDR, *PTRXHDR; +diff -urN linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bcm947xx/include/typedefs.h +--- linux.old/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2005-12-28 16:37:32.906263250 +0100 +@@ -0,0 +1,326 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _TYPEDEFS_H_ ++#define _TYPEDEFS_H_ ++ ++ ++/* Define 'SITE_TYPEDEFS' in the compile to include a site specific ++ * typedef file "site_typedefs.h". ++ * ++ * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs" ++ * section of this file makes inferences about the compile environment ++ * based on defined symbols and possibly compiler pragmas. ++ * ++ * Following these two sections is the "Default Typedefs" ++ * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is ++ * defined. This section has a default set of typedefs and a few ++ * proprocessor symbols (TRUE, FALSE, NULL, ...). ++ */ ++ ++#ifdef SITE_TYPEDEFS ++ ++/******************************************************************************* ++ * Site Specific Typedefs ++ *******************************************************************************/ ++ ++#include "site_typedefs.h" ++ ++#else ++ ++/******************************************************************************* ++ * Inferred Typedefs ++ *******************************************************************************/ ++ ++/* Infer the compile environment based on preprocessor symbols and pramas. ++ * Override type definitions as needed, and include configuration dependent ++ * header files to define types. ++ */ ++ ++#ifdef __cplusplus ++ ++#define TYPEDEF_BOOL ++#ifndef FALSE ++#define FALSE false ++#endif ++#ifndef TRUE ++#define TRUE true ++#endif ++ ++#else /* ! __cplusplus */ ++ ++#if defined(_WIN32) ++ ++#define TYPEDEF_BOOL ++typedef unsigned char bool; /* consistent w/BOOL */ ++ ++#endif /* _WIN32 */ ++ ++#endif /* ! __cplusplus */ ++ ++/* use the Windows ULONG_PTR type when compiling for 64 bit */ ++#if defined(_WIN64) ++#include ++#define TYPEDEF_UINTPTR ++typedef ULONG_PTR uintptr; ++#endif ++ ++#ifdef _HNDRTE_ ++typedef long unsigned int size_t; ++#endif ++ ++#ifdef _MSC_VER /* Microsoft C */ ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++typedef signed __int64 int64; ++typedef unsigned __int64 uint64; ++#endif ++ ++#if defined(MACOSX) && defined(KERNEL) ++#define TYPEDEF_BOOL ++#endif ++ ++ ++#if defined(linux) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#define TYPEDEF_ULONG ++#endif ++ ++#if !defined(linux) && !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#endif ++ ++ ++/* Do not support the (u)int64 types with strict ansi for GNU C */ ++#if defined(__GNUC__) && defined(__STRICT_ANSI__) ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++#endif ++ ++/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode ++ * for singned or unsigned */ ++#if defined(__ICL) ++ ++#define TYPEDEF_INT64 ++ ++#if defined(__STDC__) ++#define TYPEDEF_UINT64 ++#endif ++ ++#endif /* __ICL */ ++ ++ ++#if !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) ++ ++/* pick up ushort & uint from standard types.h */ ++#if defined(linux) && defined(__KERNEL__) ++ ++#include /* sys/types.h and linux/types.h are oil and water */ ++ ++#else ++ ++#include ++ ++#endif ++ ++#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ */ ++ ++#if defined(MACOSX) && defined(KERNEL) ++#include ++#endif ++ ++ ++/* use the default typedefs in the next section of this file */ ++#define USE_TYPEDEF_DEFAULTS ++ ++#endif /* SITE_TYPEDEFS */ ++ ++ ++/******************************************************************************* ++ * Default Typedefs ++ *******************************************************************************/ ++ ++#ifdef USE_TYPEDEF_DEFAULTS ++#undef USE_TYPEDEF_DEFAULTS ++ ++#ifndef TYPEDEF_BOOL ++typedef /*@abstract@*/ unsigned char bool; ++#endif ++ ++/*----------------------- define uchar, ushort, uint, ulong ------------------*/ ++ ++#ifndef TYPEDEF_UCHAR ++typedef unsigned char uchar; ++#endif ++ ++#ifndef TYPEDEF_USHORT ++typedef unsigned short ushort; ++#endif ++ ++#ifndef TYPEDEF_UINT ++typedef unsigned int uint; ++#endif ++ ++#ifndef TYPEDEF_ULONG ++typedef unsigned long ulong; ++#endif ++ ++/*----------------------- define [u]int8/16/32/64, uintptr --------------------*/ ++ ++#ifndef TYPEDEF_UINT8 ++typedef unsigned char uint8; ++#endif ++ ++#ifndef TYPEDEF_UINT16 ++typedef unsigned short uint16; ++#endif ++ ++#ifndef TYPEDEF_UINT32 ++typedef unsigned int uint32; ++#endif ++ ++#ifndef TYPEDEF_UINT64 ++typedef unsigned long long uint64; ++#endif ++ ++#ifndef TYPEDEF_UINTPTR ++typedef unsigned int uintptr; ++#endif ++ ++#ifndef TYPEDEF_INT8 ++typedef signed char int8; ++#endif ++ ++#ifndef TYPEDEF_INT16 ++typedef signed short int16; ++#endif ++ ++#ifndef TYPEDEF_INT32 ++typedef signed int int32; ++#endif ++ ++#ifndef TYPEDEF_INT64 ++typedef signed long long int64; ++#endif ++ ++/*----------------------- define float32/64, float_t -----------------------*/ ++ ++#ifndef TYPEDEF_FLOAT32 ++typedef float float32; ++#endif ++ ++#ifndef TYPEDEF_FLOAT64 ++typedef double float64; ++#endif ++ ++/* ++ * abstracted floating point type allows for compile time selection of ++ * single or double precision arithmetic. Compiling with -DFLOAT32 ++ * selects single precision; the default is double precision. ++ */ ++ ++#ifndef TYPEDEF_FLOAT_T ++ ++#if defined(FLOAT32) ++typedef float32 float_t; ++#else /* default to double precision floating point */ ++typedef float64 float_t; ++#endif ++ ++#endif /* TYPEDEF_FLOAT_T */ ++ ++/*----------------------- define macro values -----------------------------*/ ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#ifndef OFF ++#define OFF 0 ++#endif ++ ++#ifndef ON ++#define ON 1 ++#endif ++ ++#define AUTO (-1) ++ ++/* Reclaiming text and data : ++ The following macros specify special linker sections that can be reclaimed ++ after a system is considered 'up'. ++ */ ++#if defined(__GNUC__) && defined(BCMRECLAIM) ++extern bool bcmreclaimed; ++#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data##_ini ++#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn##_ini ++#define BCMINIT(_id) _id##_ini ++#else ++#define BCMINITDATA(_data) _data ++#define BCMINITFN(_fn) _fn ++#define BCMINIT(_id) _id ++#define bcmreclaimed 0 ++#endif ++ ++/*----------------------- define PTRSZ, INLINE ----------------------------*/ ++ ++#ifndef PTRSZ ++#define PTRSZ sizeof (char*) ++#endif ++ ++#ifndef INLINE ++ ++#ifdef _MSC_VER ++ ++#define INLINE __inline ++ ++#elif __GNUC__ ++ ++#define INLINE __inline__ ++ ++#else ++ ++#define INLINE ++ ++#endif /* _MSC_VER */ ++ ++#endif /* INLINE */ ++ ++#undef TYPEDEF_BOOL ++#undef TYPEDEF_UCHAR ++#undef TYPEDEF_USHORT ++#undef TYPEDEF_UINT ++#undef TYPEDEF_ULONG ++#undef TYPEDEF_UINT8 ++#undef TYPEDEF_UINT16 ++#undef TYPEDEF_UINT32 ++#undef TYPEDEF_UINT64 ++#undef TYPEDEF_UINTPTR ++#undef TYPEDEF_INT8 ++#undef TYPEDEF_INT16 ++#undef TYPEDEF_INT32 ++#undef TYPEDEF_INT64 ++#undef TYPEDEF_FLOAT32 ++#undef TYPEDEF_FLOAT64 ++#undef TYPEDEF_FLOAT_T ++ ++#endif /* USE_TYPEDEF_DEFAULTS */ ++ ++#endif /* _TYPEDEFS_H_ */ +diff -urN linux.old/arch/mips/bcm947xx/int-handler.S linux.dev/arch/mips/bcm947xx/int-handler.S +--- linux.old/arch/mips/bcm947xx/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/int-handler.S 2005-12-28 16:37:32.906263250 +0100 +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++ .text ++ .set noreorder ++ .set noat ++ .align 5 ++ ++ NESTED(bcm47xx_irq_handler, PT_SIZE, sp) ++ SAVE_ALL ++ CLI ++ ++ .set at ++ .set noreorder ++ ++ jal bcm47xx_irq_dispatch ++ move a0, sp ++ ++ j ret_from_irq ++ nop ++ ++ END(bcm47xx_irq_handler) +diff -urN linux.old/arch/mips/bcm947xx/irq.c linux.dev/arch/mips/bcm947xx/irq.c +--- linux.old/arch/mips/bcm947xx/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/irq.c 2005-12-28 16:37:32.906263250 +0100 +@@ -0,0 +1,67 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++extern asmlinkage void bcm47xx_irq_handler(void); ++ ++void bcm47xx_irq_dispatch(struct pt_regs *regs) ++{ ++ u32 cause; ++ ++ cause = read_c0_cause() & read_c0_status() & CAUSEF_IP; ++ ++ clear_c0_status(cause); ++ ++ if (cause & CAUSEF_IP7) ++ do_IRQ(7, regs); ++ if (cause & CAUSEF_IP2) ++ do_IRQ(2, regs); ++ if (cause & CAUSEF_IP3) ++ do_IRQ(3, regs); ++ if (cause & CAUSEF_IP4) ++ do_IRQ(4, regs); ++ if (cause & CAUSEF_IP5) ++ do_IRQ(5, regs); ++ if (cause & CAUSEF_IP6) ++ do_IRQ(6, regs); ++} ++ ++void __init arch_init_irq(void) ++{ ++ set_except_vector(0, bcm47xx_irq_handler); ++ mips_cpu_irq_init(0); ++} +diff -urN linux.old/arch/mips/bcm947xx/pci.c linux.dev/arch/mips/bcm947xx/pci.c +--- linux.old/arch/mips/bcm947xx/pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/pci.c 2005-12-28 16:37:32.906263250 +0100 +@@ -0,0 +1,215 @@ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern sb_t *sbh; ++extern spinlock_t sbh_lock; ++ ++ ++static int ++sb_pci_read_config(struct pci_bus *bus, unsigned int devfn, ++ int reg, int size, u32 *val) ++{ ++ int ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, val, size); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sb_pci_write_config(struct pci_bus *bus, unsigned int devfn, ++ int reg, int size, u32 val) ++{ ++ int ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, &val, size); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++ ++static struct pci_ops sb_pci_ops = { ++ .read = sb_pci_read_config, ++ .write = sb_pci_write_config, ++}; ++ ++static struct resource sb_pci_mem_resource = { ++ .name = "SB PCI Memory resources", ++ .start = SB_ENUM_BASE, ++ .end = SB_ENUM_LIM - 1, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct resource sb_pci_io_resource = { ++ .name = "SB PCI I/O resources", ++ .start = 0x000, ++ .end = 0x0FF, ++ .flags = IORESOURCE_IO, ++}; ++ ++static struct pci_controller bcm47xx_sb_pci_controller = { ++ .pci_ops = &sb_pci_ops, ++ .mem_resource = &sb_pci_mem_resource, ++ .io_resource = &sb_pci_io_resource, ++}; ++ ++static struct resource ext_pci_mem_resource = { ++ .name = "Ext PCI Memory resources", ++ .start = 0x40000000, ++ .end = 0x7fffffff, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct resource ext_pci_io_resource = { ++ .name = "Ext PCI I/O resources", ++ .start = 0x100, ++ .end = 0x1FF, ++ .flags = IORESOURCE_IO, ++}; ++ ++static struct pci_controller bcm47xx_ext_pci_controller = { ++ .pci_ops = &sb_pci_ops, ++ .io_resource = &ext_pci_io_resource, ++ .mem_resource = &ext_pci_mem_resource, ++ .mem_offset = 0x24000000, ++}; ++ ++void bcm47xx_pci_init(void) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ sbpci_init(sbh); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000)); ++ ++ register_pci_controller(&bcm47xx_sb_pci_controller); ++ register_pci_controller(&bcm47xx_ext_pci_controller); ++} ++ ++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ u8 irq; ++ ++ if (dev->bus->number == 1) ++ return 2; ++ ++ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); ++ return irq + 2; ++} ++ ++u32 pci_iobase = 0x100; ++u32 pci_membase = SB_PCI_DMA; ++ ++static void bcm47xx_fixup_device(struct pci_dev *d) ++{ ++ struct resource *res; ++ int pos, size; ++ u32 *base; ++ ++ if (d->bus->number == 0) ++ return; ++ ++ printk("PCI: Fixing up device %s\n", pci_name(d)); ++ ++ /* Fix up resource bases */ ++ for (pos = 0; pos < 6; pos++) { ++ res = &d->resource[pos]; ++ base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase); ++ if (res->end) { ++ size = res->end - res->start + 1; ++ if (*base & (size - 1)) ++ *base = (*base + size) & ~(size - 1); ++ res->start = *base; ++ res->end = res->start + size - 1; ++ *base += size; ++ pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); ++ } ++ /* Fix up PCI bridge BAR0 only */ ++ if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0) ++ break; ++ } ++ /* Fix up interrupt lines */ ++ if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL)) ++ d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq; ++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); ++} ++ ++ ++static void bcm47xx_fixup_bridge(struct pci_dev *dev) ++{ ++ if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0) ++ return; ++ ++ printk("PCI: fixing up bridge\n"); ++ ++ /* Enable PCI bridge bus mastering and memory space */ ++ pci_set_master(dev); ++ pcibios_enable_device(dev, ~0); ++ ++ /* Enable PCI bridge BAR1 prefetch and burst */ ++ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3); ++} ++ ++/* Do platform specific device initialization at pci_enable_device() time */ ++int pcibios_plat_dev_init(struct pci_dev *dev) ++{ ++ uint coreidx; ++ unsigned long flags; ++ ++ bcm47xx_fixup_device(dev); ++ ++ /* These cores come out of reset enabled */ ++ if ((dev->bus->number != 0) || ++ (dev->device == SB_MIPS) || ++ (dev->device == SB_MIPS33) || ++ (dev->device == SB_EXTIF) || ++ (dev->device == SB_CC)) ++ return 0; ++ ++ /* Do a core reset */ ++ spin_lock_irqsave(&sbh_lock, flags); ++ coreidx = sb_coreidx(sbh); ++ if (sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)) && (sb_coreid(sbh) == SB_USB)) { ++ /* ++ * The USB core requires a special bit to be set during core ++ * reset to enable host (OHCI) mode. Resetting the SB core in ++ * pcibios_enable_device() is a hack for compatibility with ++ * vanilla usb-ohci so that it does not have to know about ++ * SB. A driver that wants to use the USB core in device mode ++ * should know about SB and should reset the bit back to 0 ++ * after calling pcibios_enable_device(). ++ */ ++ sb_core_disable(sbh, sb_coreflags(sbh, 0, 0)); ++ sb_core_reset(sbh, 1 << 29); ++ } else { ++ sb_core_reset(sbh, 0); ++ } ++ sb_setcoreidx(sbh, coreidx); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ return 0; ++} ++ ++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge); +diff -urN linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c +--- linux.old/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/prom.c 2005-12-28 16:37:32.906263250 +0100 +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++const char *get_system_type(void) ++{ ++ return "Broadcom BCM47xx"; ++} ++ ++void __init prom_init(void) ++{ ++ unsigned long mem; ++ ++ mips_machgroup = MACH_GROUP_BRCM; ++ mips_machtype = MACH_BCM47XX; ++ ++ /* Figure out memory size by finding aliases */ ++ for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { ++ if (*(unsigned long *)((unsigned long)(prom_init) + mem) == ++ *(unsigned long *)(prom_init)) ++ break; ++ } ++ ++ add_memory_region(0, mem, BOOT_MEM_RAM); ++} ++ ++unsigned long __init prom_free_prom_memory(void) ++{ ++ return 0; ++} +diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c +--- linux.old/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/setup.c 2005-12-28 19:29:25.870911750 +0100 +@@ -0,0 +1,157 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * Copyright (C) 2005 Waldemar Brodkorb ++ * Copyright (C) 2005 Felix Fietkau ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern void bcm47xx_pci_init(void); ++extern void bcm47xx_time_init(void); ++extern void bcm47xx_timer_setup(struct irqaction *irq); ++void *sbh; ++spinlock_t sbh_lock = SPIN_LOCK_UNLOCKED; ++int boardflags; ++ ++static int ser_line = 0; ++ ++typedef struct { ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++} serial_port; ++ ++static serial_port ports[4]; ++static int num_ports = 0; ++ ++static void ++serial_add(void *regs, uint irq, uint baud_base, uint reg_shift) ++{ ++ ports[num_ports].regs = regs; ++ ports[num_ports].irq = irq; ++ ports[num_ports].baud_base = baud_base; ++ ports[num_ports].reg_shift = reg_shift; ++ num_ports++; ++} ++ ++static void ++do_serial_add(serial_port *port) ++{ ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++ struct uart_port s; ++ ++ regs = port->regs; ++ irq = port->irq; ++ baud_base = port->baud_base; ++ reg_shift = port->reg_shift; ++ ++ memset(&s, 0, sizeof(s)); ++ ++ s.line = ser_line++; ++ s.membase = regs; ++ s.irq = irq + 2; ++ s.uartclk = baud_base; ++ s.flags = ASYNC_BOOT_AUTOCONF; ++ s.iotype = SERIAL_IO_MEM; ++ s.regshift = reg_shift; ++ ++ if (early_serial_setup(&s) != 0) { ++ printk(KERN_ERR "Serial setup failed!\n"); ++ } ++} ++ ++static void bcm47xx_machine_restart(char *command) ++{ ++ printk("Please stand by while rebooting the system...\n"); ++ ++ /* Set the watchdog timer to reset immediately */ ++ local_irq_disable(); ++ sb_watchdog(sbh, 1); ++ while (1); ++} ++ ++static void bcm47xx_machine_halt(void) ++{ ++ /* Disable interrupts and watchdog and spin forever */ ++ local_irq_disable(); ++ sb_watchdog(sbh, 0); ++ while (1); ++} ++ ++void __init plat_setup(void) ++{ ++ char *s; ++ int i; ++ ++ sbh = (void *) sb_kattach(); ++ sb_mips_init(sbh); ++ ++ bcm47xx_pci_init(); ++ ++ sb_serial_init(sbh, serial_add); ++ boardflags = getintvar(NULL, "boardflags"); ++ ++ /* reverse serial ports if the nvram variable kernel_args starts with console=ttyS1 */ ++ s = early_nvram_get("kernel_args"); ++ if (!s) s = ""; ++ if (!strncmp(s, "console=ttyS1", 13)) { ++ for (i = num_ports; i; i--) ++ do_serial_add(&ports[i - 1]); ++ } else { ++ for (i = 0; i < num_ports; i++) ++ do_serial_add(&ports[i]); ++ } ++ ++ _machine_restart = bcm47xx_machine_restart; ++ _machine_halt = bcm47xx_machine_halt; ++ _machine_power_off = bcm47xx_machine_halt; ++ ++ board_time_init = bcm47xx_time_init; ++ board_timer_setup = bcm47xx_timer_setup; ++} ++ ++EXPORT_SYMBOL(sbh); ++EXPORT_SYMBOL(sbh_lock); ++EXPORT_SYMBOL(boardflags); +diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c +--- linux.old/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/time.c 2005-12-28 16:37:32.906263250 +0100 +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void __init ++bcm47xx_time_init(void) ++{ ++ unsigned int hz; ++ ++ /* ++ * Use deterministic values for initial counter interrupt ++ * so that calibrate delay avoids encountering a counter wrap. ++ */ ++ write_c0_count(0); ++ write_c0_compare(0xffff); ++ ++ hz = 200 * 1000 * 1000; ++ ++ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ ++ mips_hpt_frequency = hz / 2; ++ ++} ++ ++void __init ++bcm47xx_timer_setup(struct irqaction *irq) ++{ ++ /* Enable the timer interrupt */ ++ setup_irq(7, irq); ++} +diff -urN linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu-probe.c +--- linux.old/arch/mips/kernel/cpu-probe.c 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/arch/mips/kernel/cpu-probe.c 2005-12-28 16:37:32.934265000 +0100 +@@ -656,6 +656,28 @@ + } + + ++static inline void cpu_probe_broadcom(struct cpuinfo_mips *c) ++{ ++ decode_config1(c); ++ switch (c->processor_id & 0xff00) { ++ case PRID_IMP_BCM3302: ++ c->cputype = CPU_BCM3302; ++ c->isa_level = MIPS_CPU_ISA_M32; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER; ++ break; ++ case PRID_IMP_BCM4710: ++ c->cputype = CPU_BCM4710; ++ c->isa_level = MIPS_CPU_ISA_M32; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER; ++ break; ++ default: ++ c->cputype = CPU_UNKNOWN; ++ break; ++ } ++} ++ + __init void cpu_probe(void) + { + struct cpuinfo_mips *c = ¤t_cpu_data; +@@ -678,6 +700,9 @@ + case PRID_COMP_SIBYTE: + cpu_probe_sibyte(c); + break; ++ case PRID_COMP_BROADCOM: ++ cpu_probe_broadcom(c); ++ break; + case PRID_COMP_SANDCRAFT: + cpu_probe_sandcraft(c); + break; +diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S +--- linux.old/arch/mips/kernel/head.S 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/arch/mips/kernel/head.S 2005-12-28 16:37:32.934265000 +0100 +@@ -107,6 +107,14 @@ + #endif + .endm + ++#ifdef CONFIG_BCM4710 ++#undef eret ++#define eret nop; nop; eret ++#endif ++ ++ j kernel_entry ++ nop ++ + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. +diff -urN linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c +--- linux.old/arch/mips/kernel/proc.c 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/arch/mips/kernel/proc.c 2005-12-28 16:37:32.946265750 +0100 +@@ -82,6 +82,8 @@ + [CPU_VR4181] = "NEC VR4181", + [CPU_VR4181A] = "NEC VR4181A", + [CPU_SR71000] = "Sandcraft SR71000", ++ [CPU_BCM3302] = "Broadcom BCM3302", ++ [CPU_BCM4710] = "Broadcom BCM4710", + [CPU_PR4450] = "Philips PR4450", + }; + +diff -urN linux.old/arch/mips/mm/tlbex.c linux.dev/arch/mips/mm/tlbex.c +--- linux.old/arch/mips/mm/tlbex.c 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/arch/mips/mm/tlbex.c 2005-12-28 16:37:32.970267250 +0100 +@@ -858,6 +858,8 @@ + case CPU_4KSC: + case CPU_20KC: + case CPU_25KF: ++ case CPU_BCM3302: ++ case CPU_BCM4710: + tlbw(p); + break; + +diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h +--- linux.old/include/asm-mips/bootinfo.h 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/include/asm-mips/bootinfo.h 2005-12-28 16:37:32.970267250 +0100 +@@ -218,6 +218,12 @@ + #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ + #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ + ++/* ++ * Valid machtype for group Broadcom ++ */ ++#define MACH_GROUP_BRCM 23 /* Broadcom */ ++#define MACH_BCM47XX 1 /* Broadcom BCM47xx */ ++ + #define CL_SIZE COMMAND_LINE_SIZE + + const char *get_system_type(void); +diff -urN linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h +--- linux.old/include/asm-mips/cpu.h 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/include/asm-mips/cpu.h 2005-12-28 16:37:32.974267500 +0100 +@@ -102,6 +102,13 @@ + #define PRID_IMP_SR71000 0x0400 + + /* ++ * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM ++ */ ++ ++#define PRID_IMP_BCM4710 0x4000 ++#define PRID_IMP_BCM3302 0x9000 ++ ++/* + * Definitions for 7:0 on legacy processors + */ + +@@ -196,7 +203,9 @@ + #define CPU_34K 60 + #define CPU_PR4450 61 + #define CPU_SB1A 62 +-#define CPU_LAST 62 ++#define CPU_BCM3302 63 ++#define CPU_BCM4710 64 ++#define CPU_LAST 64 + + /* + * ISA Level encodings +diff -urN linux.old/include/linux/init.h linux.dev/include/linux/init.h +--- linux.old/include/linux/init.h 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/include/linux/init.h 2005-12-28 16:37:32.982268000 +0100 +@@ -86,6 +86,8 @@ + static initcall_t __initcall_##fn __attribute_used__ \ + __attribute__((__section__(".initcall" level ".init"))) = fn + ++#define early_initcall(fn) __define_initcall(".early1",fn) ++ + #define core_initcall(fn) __define_initcall("1",fn) + #define postcore_initcall(fn) __define_initcall("2",fn) + #define arch_initcall(fn) __define_initcall("3",fn) +diff -urN linux.old/include/linux/pci_ids.h linux.dev/include/linux/pci_ids.h +--- linux.old/include/linux/pci_ids.h 2005-12-19 01:36:54.000000000 +0100 ++++ linux.dev/include/linux/pci_ids.h 2005-12-28 16:37:32.994268750 +0100 +@@ -1836,6 +1836,7 @@ + #define PCI_DEVICE_ID_TIGON3_5901_2 0x170e + #define PCI_DEVICE_ID_BCM4401 0x4401 + #define PCI_DEVICE_ID_BCM4401B0 0x4402 ++#define PCI_DEVICE_ID_BCM4713 0x4713 + + #define PCI_VENDOR_ID_TOPIC 0x151f + #define PCI_DEVICE_ID_TOPIC_TP560 0x0000 diff --git a/openwrt/target/linux/brcm-2.6/patches/002-flash-map.patch b/openwrt/target/linux/brcm-2.6/patches/002-flash-map.patch new file mode 100644 index 0000000000..b8aeafa602 --- /dev/null +++ b/openwrt/target/linux/brcm-2.6/patches/002-flash-map.patch @@ -0,0 +1,347 @@ +diff -Nur linux-2.6.15-rc5/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.15-rc5-flash/drivers/mtd/maps/bcm47xx-flash.c +--- linux-2.6.15-rc5/drivers/mtd/maps/bcm47xx-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15-rc5-flash/drivers/mtd/maps/bcm47xx-flash.c 2005-12-19 00:33:31.276241000 +0100 +@@ -0,0 +1,316 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * Copyright (C) 2005 Waldemar Brodkorb ++ * ++ * original functions for finding root filesystem from Mike Baker ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * Copyright 2001-2003, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Flash mapping for BCM947XX boards ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_MTD_PARTITIONS ++#include ++#endif ++#include ++ ++#include ++ ++#define WINDOW_ADDR 0x1c000000 ++#define WINDOW_SIZE (0x400000*2) ++#define BUSWIDTH 2 ++ ++static struct mtd_info *bcm947xx_mtd; ++ ++static void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++#define MIPS_MEMCPY_ALIGN 4 ++ map_word ret; ++ ssize_t transfer; ++ ssize_t done = 0; ++ if ((len >= MIPS_MEMCPY_ALIGN) && (!(from & (MIPS_MEMCPY_ALIGN - 1))) && (!(((unsigned int)to & (MIPS_MEMCPY_ALIGN - 1))))) { ++ done = len & ~(MIPS_MEMCPY_ALIGN - 1); ++ memcpy_fromio(to, map->virt + from, done); ++ } ++ while (done < len) { ++ ret = map->read(map, from + done); ++ transfer = len - done; ++ if (transfer > map->bankwidth) ++ transfer = map->bankwidth; ++ memcpy((void *)((unsigned long)to + done), &ret.x[0], transfer); ++ done += transfer; ++ } ++} ++ ++static struct map_info bcm947xx_map = { ++ name: "Physically mapped flash", ++ size: WINDOW_SIZE, ++ bankwidth: BUSWIDTH, ++ phys: WINDOW_ADDR, ++}; ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ ++static struct mtd_partition bcm947xx_parts[] = { ++ { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, ++ { name: "linux", offset: 0, size: 0, }, ++ { name: "rootfs", offset: 0, size: 0, }, ++ { name: "nvram", offset: 0, size: 0, }, ++ { name: "OpenWrt", offset: 0, size: 0, }, ++ { name: NULL, }, ++}; ++ ++static int __init ++find_cfe_size(struct mtd_info *mtd, size_t size) ++{ ++ struct trx_header *trx; ++ unsigned char buf[512]; ++ int off; ++ size_t len; ++ int cfe_size_flag; ++ ++ trx = (struct trx_header *) buf; ++ ++ cfe_size_flag=0; ++ ++ for (off = (256*1024); off < size; off += mtd->erasesize) { ++ memset(buf, 0xe5, sizeof(buf)); ++ ++ /* ++ * Read into buffer ++ */ ++ if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || ++ len != sizeof(buf)) ++ continue; ++ ++ /* found a TRX header */ ++ if (le32_to_cpu(trx->magic) == TRX_MAGIC) { ++ goto done; ++ } ++ cfe_size_flag += 1; ++ } ++ ++ printk(KERN_NOTICE ++ "%s: Couldn't find bootloader size\n", ++ mtd->name); ++ return -1; ++ ++ done: ++ printk(KERN_NOTICE "bootloader size flag: %d\n", cfe_size_flag); ++ return cfe_size_flag; ++ ++} ++ ++static int __init ++find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) ++{ ++ struct trx_header *trx; ++ unsigned char buf[512]; ++ int off; ++ size_t len; ++ ++ trx = (struct trx_header *) buf; ++ ++ for (off = (256*1024); off < size; off += mtd->erasesize) { ++ memset(buf, 0xe5, sizeof(buf)); ++ ++ /* ++ * Read into buffer ++ */ ++ if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || ++ len != sizeof(buf)) ++ continue; ++ ++ /* found a TRX header */ ++ if (le32_to_cpu(trx->magic) == TRX_MAGIC) { ++ part->offset = le32_to_cpu(trx->offsets[2]) ? : ++ le32_to_cpu(trx->offsets[1]); ++ part->size = le32_to_cpu(trx->len); ++ ++ part->size -= part->offset; ++ part->offset += off; ++ ++ goto done; ++ } ++ } ++ ++ printk(KERN_NOTICE ++ "%s: Couldn't find root filesystem\n", ++ mtd->name); ++ return -1; ++ ++ done: ++ return part->size; ++} ++ ++struct mtd_partition * __init ++init_mtd_partitions(struct mtd_info *mtd, size_t size) ++{ ++ ++ int cfe_size_flag; ++ ++ /* if cfe_size_flag=0, cfe size is 256 kb, else 384 kb */ ++ cfe_size_flag = find_cfe_size(mtd, size); ++ ++ /* boot loader */ ++ bcm947xx_parts[0].offset = 0; ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[0].size = 1024*256; ++ } else { ++ /* netgear wgt634u has 384 kb bootloader */ ++ bcm947xx_parts[0].size = 1024*384; ++ } ++ ++ /* nvram */ ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[3].offset = size - mtd->erasesize; ++ } else { ++ /* nvram (old 128kb config partition on netgear wgt634u) */ ++ bcm947xx_parts[3].offset = bcm947xx_parts[0].size; ++ } ++ bcm947xx_parts[3].size = mtd->erasesize; ++ ++ /* linux (kernel and rootfs) */ ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[1].offset = bcm947xx_parts[0].size; ++ bcm947xx_parts[1].size = bcm947xx_parts[3].offset - ++ bcm947xx_parts[1].offset; ++ } else { ++ /* do not count the elf loader, which is on one block */ ++ bcm947xx_parts[1].offset = bcm947xx_parts[0].size + ++ bcm947xx_parts[3].size + mtd->erasesize; ++ bcm947xx_parts[1].size = size - ++ bcm947xx_parts[0].size - ++ (2*bcm947xx_parts[3].size) - ++ mtd->erasesize; ++ } ++ ++ /* find and size rootfs */ ++ if (find_root(mtd,size,&bcm947xx_parts[2])==0) { ++ /* entirely jffs2 */ ++ bcm947xx_parts[4].name = NULL; ++ bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset - ++ bcm947xx_parts[3].size; ++ } else { ++ /* legacy setup */ ++ /* calculate leftover flash, and assign it to the jffs2 partition */ ++ if (cfe_size_flag == 0) { ++ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + ++ bcm947xx_parts[2].size; ++ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) { ++ bcm947xx_parts[4].offset += mtd->erasesize - ++ (bcm947xx_parts[4].offset % mtd->erasesize); ++ } ++ bcm947xx_parts[4].size = bcm947xx_parts[3].offset - ++ bcm947xx_parts[4].offset; ++ } else { ++ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + ++ bcm947xx_parts[2].size; ++ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) { ++ bcm947xx_parts[4].offset += mtd->erasesize - ++ (bcm947xx_parts[4].offset % mtd->erasesize); ++ } ++ bcm947xx_parts[4].size = size - bcm947xx_parts[3].size - ++ bcm947xx_parts[4].offset; ++ } ++ } ++ ++ return bcm947xx_parts; ++} ++#endif ++ ++int __init init_bcm947xx_map(void) ++{ ++ size_t size; ++ int ret = 0; ++#ifdef CONFIG_MTD_PARTITIONS ++ struct mtd_partition *parts; ++ int i; ++#endif ++ ++ bcm947xx_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ ++ if (!bcm947xx_map.virt) { ++ printk("Failed to ioremap\n"); ++ return -EIO; ++ } ++ simple_map_init(&bcm947xx_map); ++ ++ bcm947xx_map.copy_from = bcm947xx_map_copy_from; ++ ++ if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) { ++ printk("Failed to do_map_probe\n"); ++ iounmap((void *)bcm947xx_map.virt); ++ return -ENXIO; ++ } ++ ++ bcm947xx_mtd->owner = THIS_MODULE; ++ ++ size = bcm947xx_mtd->size; ++ ++ printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR); ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ parts = init_mtd_partitions(bcm947xx_mtd, size); ++ for (i = 0; parts[i].name; i++); ++ ret = add_mtd_partitions(bcm947xx_mtd, parts, i); ++ if (ret) { ++ printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); ++ goto fail; ++ } ++#endif ++ return 0; ++ ++ fail: ++ if (bcm947xx_mtd) ++ map_destroy(bcm947xx_mtd); ++ if (bcm947xx_map.virt) ++ iounmap((void *)bcm947xx_map.virt); ++ bcm947xx_map.virt = 0; ++ return ret; ++} ++ ++void __exit cleanup_bcm947xx_map(void) ++{ ++#ifdef CONFIG_MTD_PARTITIONS ++ del_mtd_partitions(bcm947xx_mtd); ++#endif ++ map_destroy(bcm947xx_mtd); ++ iounmap((void *)bcm947xx_map.virt); ++} ++ ++module_init(init_bcm947xx_map); ++module_exit(cleanup_bcm947xx_map); +diff -Nur linux-2.6.15-rc5/drivers/mtd/maps/Kconfig linux-2.6.15-rc5-flash/drivers/mtd/maps/Kconfig +--- linux-2.6.15-rc5/drivers/mtd/maps/Kconfig 2005-12-04 06:10:42.000000000 +0100 ++++ linux-2.6.15-rc5-flash/drivers/mtd/maps/Kconfig 2005-12-18 19:36:11.555087000 +0100 +@@ -299,6 +299,12 @@ + Mapping for the Flaga digital module. If you don't have one, ignore + this setting. + ++config MTD_BCM47XX ++ tristate "BCM47xx flash device" ++ depends on MIPS && MTD_CFI && BCM947XX ++ help ++ Support for the flash chips on the BCM947xx board. ++ + config MTD_BEECH + tristate "CFI Flash device mapped on IBM 405LP Beech" + depends on MTD_CFI && BEECH +diff -Nur linux-2.6.15-rc5/drivers/mtd/maps/Makefile linux-2.6.15-rc5-flash/drivers/mtd/maps/Makefile +--- linux-2.6.15-rc5/drivers/mtd/maps/Makefile 2005-12-04 06:10:42.000000000 +0100 ++++ linux-2.6.15-rc5-flash/drivers/mtd/maps/Makefile 2005-12-18 19:36:11.555087000 +0100 +@@ -31,6 +31,7 @@ + obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o + obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o + obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o ++obj-$(CONFIG_MTD_BCM47XX) += bcm47xx-flash.o + obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o + obj-$(CONFIG_MTD_IPAQ) += ipaq-flash.o + obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o diff --git a/openwrt/target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch b/openwrt/target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch new file mode 100644 index 0000000000..76e90584d9 --- /dev/null +++ b/openwrt/target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch @@ -0,0 +1,316 @@ +diff -urN linux.old/arch/mips/kernel/genex.S linux.dev/arch/mips/kernel/genex.S +--- linux.old/arch/mips/kernel/genex.S 2005-12-04 06:10:42.000000000 +0100 ++++ linux.dev/arch/mips/kernel/genex.S 2005-12-18 05:30:48.564937750 +0100 +@@ -72,6 +72,10 @@ + .set push + .set mips3 + .set noat ++#ifdef CONFIG_BCM4710 ++ nop ++ nop ++#endif + mfc0 k1, CP0_CAUSE + li k0, 31<<2 + andi k1, k1, 0x7c +diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c +--- linux.old/arch/mips/mm/c-r4k.c 2005-12-04 06:10:42.000000000 +0100 ++++ linux.dev/arch/mips/mm/c-r4k.c 2005-12-18 06:08:19.112437750 +0100 +@@ -14,6 +14,12 @@ + #include + #include + ++#ifdef CONFIG_BCM4710 ++#include "../bcm947xx/include/typedefs.h" ++#include "../bcm947xx/include/sbconfig.h" ++#include ++#endif ++ + #include + #include + #include +@@ -29,6 +35,9 @@ + #include + #include /* for run_uncached() */ + ++/* For enabling BCM4710 cache workarounds */ ++int bcm4710 = 0; ++ + /* + * Must die. + */ +@@ -73,7 +82,9 @@ + { + unsigned long dc_lsize = cpu_dcache_line_size(); + +- if (dc_lsize == 16) ++ if (bcm4710) ++ r4k_blast_dcache_page = blast_dcache_page; ++ else if (dc_lsize == 16) + r4k_blast_dcache_page = blast_dcache16_page; + else if (dc_lsize == 32) + r4k_blast_dcache_page = r4k_blast_dcache_page_dc32; +@@ -85,7 +96,9 @@ + { + unsigned long dc_lsize = cpu_dcache_line_size(); + +- if (dc_lsize == 16) ++ if (bcm4710) ++ r4k_blast_dcache_page_indexed = blast_dcache_page_indexed; ++ else if (dc_lsize == 16) + r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed; + else if (dc_lsize == 32) + r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed; +@@ -97,7 +110,9 @@ + { + unsigned long dc_lsize = cpu_dcache_line_size(); + +- if (dc_lsize == 16) ++ if (bcm4710) ++ r4k_blast_dcache = blast_dcache; ++ else if (dc_lsize == 16) + r4k_blast_dcache = blast_dcache16; + else if (dc_lsize == 32) + r4k_blast_dcache = blast_dcache32; +@@ -486,6 +501,9 @@ + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + ++ BCM4710_PROTECTED_FILL_TLB(addr); ++ BCM4710_PROTECTED_FILL_TLB(aend); ++ + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); +@@ -657,6 +675,10 @@ + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); ++ ++ BCM4710_FILL_TLB(a); ++ BCM4710_FILL_TLB(end); ++ + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) +@@ -702,6 +724,10 @@ + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); ++ ++ BCM4710_FILL_TLB(a); ++ BCM4710_FILL_TLB(end); ++ + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) +@@ -727,6 +753,8 @@ + unsigned long addr = (unsigned long) arg; + + R4600_HIT_CACHEOP_WAR_IMPL; ++ BCM4710_PROTECTED_FILL_TLB(addr); ++ BCM4710_PROTECTED_FILL_TLB(addr + 4); + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + if (!cpu_icache_snoops_remote_store) + protected_writeback_scache_line(addr & ~(sc_lsize - 1)); +@@ -1202,6 +1230,16 @@ + static inline void coherency_setup(void) + { + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); ++#if defined(CONFIG_BCM4310) || defined(CONFIG_BCM4704) || defined(CONFIG_BCM5365) ++ if (BCM330X(current_cpu_data.processor_id)) { ++ __u32 cm = read_c0_diag(); ++ /* Enable icache */ ++ cm |= (1 << 31); ++ /* Enable dcache */ ++ cm |= (1 << 30); ++ write_c0_diag(cm); ++ } ++#endif + + /* + * c0_status.cu=0 specifies that updates by the sc instruction use +@@ -1231,6 +1269,15 @@ + + /* Default cache error handler for R4000 and R5000 family */ + set_uncached_handler (0x100, &except_vec2_generic, 0x80); ++ ++ /* Check if special workarounds are required */ ++#ifdef CONFIG_BCM4710 ++ if (current_cpu_data.cputype == CPU_BCM4710 && (current_cpu_data.processor_id & 0xff) == 0) { ++ printk("Enabling BCM4710A0 cache workarounds.\n"); ++ bcm4710 = 1; ++ } else ++#endif ++ bcm4710 = 0; + + probe_pcache(); + setup_scache(); +diff -urN linux.old/arch/mips/mm/tlbex.c linux.dev/arch/mips/mm/tlbex.c +--- linux.old/arch/mips/mm/tlbex.c 2005-12-15 12:57:27.945158000 +0100 ++++ linux.dev/arch/mips/mm/tlbex.c 2005-12-18 06:06:17.916863500 +0100 +@@ -28,6 +28,10 @@ + + /* #define DEBUG_TLB */ + ++#ifdef CONFIG_BCM4710 ++extern int bcm4710; ++#endif ++ + static __init int __attribute__((unused)) r45k_bvahwbug(void) + { + /* XXX: We should probe for the presence of this bug, but we don't. */ +@@ -1152,6 +1156,12 @@ + memset(relocs, 0, sizeof(relocs)); + memset(final_handler, 0, sizeof(final_handler)); + ++#ifdef CONFIG_BCM4710 ++ if (bcm4710) { ++ i_nop(&p); ++ } ++#endif ++ + /* + * create the plain linear handler + */ +diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h +--- linux.old/include/asm-mips/r4kcache.h 2005-12-17 22:39:19.281320000 +0100 ++++ linux.dev/include/asm-mips/r4kcache.h 2005-12-18 05:22:06.020280750 +0100 +@@ -15,6 +15,18 @@ + #include + #include + ++#ifdef CONFIG_BCM4710 ++#define BCM4710_DUMMY_RREG() (((sbconfig_t *)(KSEG1ADDR(SB_ENUM_BASE + SBCONFIGOFF)))->sbimstate) ++ ++#define BCM4710_FILL_TLB(addr) (*(volatile unsigned long *)(addr)) ++#define BCM4710_PROTECTED_FILL_TLB(addr) ({ unsigned long x; get_dbe(x, (volatile unsigned long *)(addr)); }) ++#else ++#define BCM4710_DUMMY_RREG() ++ ++#define BCM4710_FILL_TLB(addr) ++#define BCM4710_PROTECTED_FILL_TLB(addr) ++#endif ++ + /* + * This macro return a properly sign-extended address suitable as base address + * for indexed cache operations. Two issues here: +@@ -45,6 +57,7 @@ + + static inline void flush_dcache_line_indexed(unsigned long addr) + { ++ BCM4710_DUMMY_RREG(); + cache_op(Index_Writeback_Inv_D, addr); + } + +@@ -60,11 +73,13 @@ + + static inline void flush_dcache_line(unsigned long addr) + { ++ BCM4710_DUMMY_RREG(); + cache_op(Hit_Writeback_Inv_D, addr); + } + + static inline void invalidate_dcache_line(unsigned long addr) + { ++ BCM4710_DUMMY_RREG(); + cache_op(Hit_Invalidate_D, addr); + } + +@@ -104,6 +119,7 @@ + */ + static inline void protected_writeback_dcache_line(unsigned long addr) + { ++ BCM4710_DUMMY_RREG(); + __asm__ __volatile__( + " .set push \n" + " .set noreorder \n" +@@ -166,6 +182,49 @@ + : "r" (base), \ + "i" (op)); + ++static inline void blast_dcache(void) ++{ ++ unsigned long start = KSEG0; ++ unsigned long dcache_size = current_cpu_data.dcache.waysize * current_cpu_data.dcache.ways; ++ unsigned long end = (start + dcache_size); ++ ++ do { ++ BCM4710_DUMMY_RREG(); ++ cache_op(Index_Writeback_Inv_D, start); ++ start += current_cpu_data.dcache.linesz; ++ } while(start < end); ++} ++ ++static inline void blast_dcache_page(unsigned long page) ++{ ++ unsigned long start = page; ++ unsigned long end = start + PAGE_SIZE; ++ ++ BCM4710_FILL_TLB(start); ++ do { ++ BCM4710_DUMMY_RREG(); ++ cache_op(Hit_Writeback_Inv_D, start); ++ start += current_cpu_data.dcache.linesz; ++ } while(start < end); ++} ++ ++static inline void blast_dcache_page_indexed(unsigned long page) ++{ ++ unsigned long start = page; ++ unsigned long end = start + PAGE_SIZE; ++ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; ++ unsigned long ws_end = current_cpu_data.dcache.ways << ++ current_cpu_data.dcache.waybit; ++ unsigned long ws, addr; ++ for (ws = 0; ws < ws_end; ws += ws_inc) { ++ start = page + ws; ++ for (addr = start; addr < end; addr += current_cpu_data.dcache.linesz) { ++ BCM4710_DUMMY_RREG(); ++ cache_op(Index_Writeback_Inv_D, addr); ++ } ++ } ++} ++ + static inline void blast_dcache16(void) + { + unsigned long start = INDEX_BASE; +@@ -213,7 +272,8 @@ + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; +- ++ ++ BCM4710_FILL_TLB(start); + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Invalidate_I); +@@ -357,6 +417,7 @@ + current_cpu_data.icache.waybit; + unsigned long ws, addr; + ++ BCM4710_FILL_TLB(start); + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); +@@ -471,6 +532,7 @@ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + ++ BCM4710_FILL_TLB(start); + do { + cache64_unroll32(start,Hit_Invalidate_I); + start += 0x800; +diff -urN linux.old/include/asm-mips/stackframe.h linux.dev/include/asm-mips/stackframe.h +--- linux.old/include/asm-mips/stackframe.h 2005-12-04 06:10:42.000000000 +0100 ++++ linux.dev/include/asm-mips/stackframe.h 2005-12-18 05:33:02.405302250 +0100 +@@ -285,6 +285,10 @@ + .macro RESTORE_SP_AND_RET + LONG_L sp, PT_R29(sp) + .set mips3 ++#ifdef CONFIG_BCM4710 ++ nop ++ nop ++#endif + eret + .set mips0 + .endm diff --git a/openwrt/target/linux/generic-2.4/README b/openwrt/target/linux/generic-2.4/README new file mode 100644 index 0000000000..15d95232d7 --- /dev/null +++ b/openwrt/target/linux/generic-2.4/README @@ -0,0 +1,98 @@ +Description of kernel patches: + + +generic/ + Generic patches for vanilla Linux kernel + +000-linux_mips.patch + This is the diff between vanilla linux-2.4.32 and linux-mips.org kernel + (CVS tag 2_4_32-rc1 used). The kernel source from linux-mips.org CVS repository has + newer drivers and code then vanilla linux-2.4.32 especially for the mips architecture. + +001-squashfs.patch + Support for the squashfs filesystem. It has better compression ratio then cramfs. + +002-squashfs_lzma.patch + LZMA Addon patch from Oleg I. Vdovikin for the squashfs filesystem. + Even better compression ratio. + +003-jffs2_compression.patch + Compression for jffs2 filesystem. + +004-exec_pagesize.patch + +005-mtd_flashtypes.patch + Additional mtd drivers for flash chips + +100-ebtables.patch + Filtering packets on ethernet layer. See http://ebtables.sf.net + +101-netfilter_ipp2p.patch + Netfilter ipp2p match module (matches traffic of most P2P networks) + +102-netfilter_layer7.patch + +103-netfilter_nat_pptp.patch + NAT support for PPTP and GRE + +104-netfilter_maxconn.patch + +105-netfilter_TTL.patch + Netfilter target for manipulating the TTL of IP packets + +106-mppe_mppc.patch + Microsoft PPP Encryption/Compression + +107-cifs.patch + CIFS (Common Internet File System) module. + +108-optional_aout_support.patch + +109-ipsec_nat_traversal.patch + Openswan patch for allowing IPSec through NAT + +110-netdev_random_core.patch + Support for gathering entropy from network devices for /dev/random + +200-i4l.patch + +201-hfc_usb_backport.patch + +202-pl2303_backport.patch + +203-hfsplus_fix.patch + +204-net_b44.patch + Support for the BCM47xx chipset in the b44 driver + +206-gcc_3.4_fixes.patch + mips specific gcc 3.4 fixes + +207-gcc_4.0_fixes.patch + gcc 4.0 fixes + + +brcm/ + Broadcom specific patches + +001-bcm47xx.patch + This is the broadcom specific code from asus (1941) GPL source tarball. + There are many small patches included, so it works with linux 2.4.32 kernel. + The original code is based on Linux 2.4.20. + +002-wl_fix.patch + The driver for the wireless lan chip on brcm47xx based routers is binary only. + This means it depends on older data structures in the kernel. We backported some + of the changes or changed some of the data structures to work with the binary modul. + This is a really bad hack, but without source code, there is no better chance to get + the driver working with newer kernels. + +003-bcm47xx_cache_fixes.patch + + +ar7/ + TI AR7 specific patches + +000-ar7_support.patch + +001-flash_map.patch diff --git a/openwrt/target/linux/generic-2.4/modules.mk b/openwrt/target/linux/generic-2.4/modules.mk new file mode 100644 index 0000000000..6aea74203b --- /dev/null +++ b/openwrt/target/linux/generic-2.4/modules.mk @@ -0,0 +1,325 @@ +include ../netfilter.mk + +# Networking + +$(eval $(call KMOD_template,ATM,atm,\ + $(MODULES_DIR)/kernel/net/atm/atm.o \ + $(MODULES_DIR)/kernel/net/atm/br2684.o \ +,CONFIG_ATM,,50,atm)) + +$(eval $(call KMOD_template,GRE,gre,\ + $(MODULES_DIR)/kernel/net/ipv4/ip_gre.o \ +,CONFIG_NET_IPGRE)) + +$(eval $(call KMOD_template,IMQ,imq,\ + $(MODULES_DIR)/kernel/net/*/netfilter/*IMQ*.o \ + $(MODULES_DIR)/kernel/drivers/net/imq.o \ +)) + +$(eval $(call KMOD_template,IPV6,ipv6,\ + $(MODULES_DIR)/kernel/net/ipv6/ipv6.o \ +,CONFIG_IPV6,,20,ipv6)) + +$(eval $(call KMOD_template,PPP,ppp,\ + $(MODULES_DIR)/kernel/drivers/net/ppp_async.o \ + $(MODULES_DIR)/kernel/drivers/net/ppp_generic.o \ + $(MODULES_DIR)/kernel/drivers/net/slhc.o \ + $(MODULES_DIR)/kernel/drivers/net/pppox.o \ +,CONFIG_PPP)) + +$(eval $(call KMOD_template,MPPE,mppe,\ + $(MODULES_DIR)/kernel/drivers/net/ppp_mppe_mppc.o \ +,CONFIG_PPP_MPPE_MPPC)) + +$(eval $(call KMOD_template,PPPOATM,pppoatm,\ + $(MODULES_DIR)/kernel/net/atm/pppoatm.o \ +,CONFIG_PPPOATM)) + +$(eval $(call KMOD_template,PPPOE,pppoe,\ + $(MODULES_DIR)/kernel/drivers/net/pppoe.o \ +,CONFIG_PPPOE)) + +ifneq ($(wildcard $(MODULES_DIR)/kernel/net/sched/*.o),) +CONFIG_SCHED:=m +endif +$(eval $(call KMOD_template,SCHED,sched,\ + $(MODULES_DIR)/kernel/net/sched/*.o \ +,CONFIG_SCHED)) + +$(eval $(call KMOD_template,TUN,tun,\ + $(MODULES_DIR)/kernel/drivers/net/tun.o \ +,CONFIG_TUN,,20,tun)) + +$(eval $(call KMOD_template,RING,ring,\ + $(MODULES_DIR)/kernel/net/ring/ring.o \ +,CONFIG_RING,,20,ring)) + + +# Filtering / Firewalling + +$(eval $(call KMOD_template,ARPTABLES,arptables,\ + $(MODULES_DIR)/kernel/net/ipv4/netfilter/arp*.o \ +,CONFIG_IP_NF_ARPTABLES)) + +$(eval $(call KMOD_template,EBTABLES,ebtables,\ + $(MODULES_DIR)/kernel/net/bridge/netfilter/*.o \ +,CONFIG_BRIDGE_NF_EBTABLES)) + +# metapackage for compatibility ... +$(eval $(call KMOD_template,IPTABLES_EXTRA,iptables-extra,\ +,,kmod-ipt-conntrack kmod-ipt-extra kmod-ipt-filter kmod-ipt-ipopt kmod-ipt-ipsec kmod-ipt-nat kmod-ipt-nat-extra kmod-ipt-queue kmod-ipt-ulogd)) + +$(eval $(call KMOD_template,IPT_CONNTRACK,ipt-conntrack,\ + $(foreach mod,$(IPT_CONNTRACK-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IPT_EXTRA,ipt-extra,\ + $(foreach mod,$(IPT_EXTRA-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IPT_FILTER,ipt-filter,\ + $(foreach mod,$(IPT_FILTER-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IPT_IPOPT,ipt-ipopt,\ + $(foreach mod,$(IPT_IPOPT-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IPT_IPSEC,ipt-ipsec,\ + $(foreach mod,$(IPT_IPSEC-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IPT_NAT,ipt-nat,\ + $(foreach mod,$(IPT_NAT-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IPT_NAT_EXTRA,ipt-nat-extra,\ + $(foreach mod,$(IPT_NAT_EXTRA-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +,,,40,$(IPT_NAT_EXTRA-m))) + +$(eval $(call KMOD_template,IPT_QUEUE,ipt-queue,\ + $(foreach mod,$(IPT_QUEUE-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IPT_ULOG,ipt-ulog,\ + $(foreach mod,$(IPT_ULOG-m),$(MODULES_DIR)/kernel/net/ipv4/netfilter/$(mod).o) \ +)) + +$(eval $(call KMOD_template,IP6TABLES,ip6tables,\ + $(MODULES_DIR)/kernel/net/ipv6/netfilter/ip*.o \ +,CONFIG_IP6_NF_IPTABLES,kmod-ipv6)) + + +# Block devices + +$(eval $(call KMOD_template,IDE,ide,\ + $(MODULES_DIR)/kernel/drivers/ide/*.o \ + $(MODULES_DIR)/kernel/drivers/ide/*/*.o \ +,CONFIG_IDE)) + +$(eval $(call KMOD_template,LOOP,loop,\ + $(MODULES_DIR)/kernel/drivers/block/loop.o \ +,CONFIG_BLK_DEV_LOOP,,20,loop)) + +$(eval $(call KMOD_template,NBD,nbd,\ + $(MODULES_DIR)/kernel/drivers/block/nbd.o \ +,CONFIG_BLK_DEV_NBD,,20,nbd)) + + +# Crypto + +ifneq ($(wildcard $(MODULES_DIR)/kernel/crypto/*.o),) +CONFIG_CRYPTO:=m +endif +$(eval $(call KMOD_template,CRYPTO,crypto,\ + $(MODULES_DIR)/kernel/crypto/*.o \ +,CONFIG_CRYPTO)) + + +# Filesystems + +$(eval $(call KMOD_template,FS_CIFS,fs-cifs,\ + $(MODULES_DIR)/kernel/fs/cifs/cifs.o \ +,CONFIG_CIFS,,30,cifs)) + +$(eval $(call KMOD_template,FS_EXT2,fs-ext2,\ + $(MODULES_DIR)/kernel/fs/ext2/*.o \ +,CONFIG_EXT2_FS,,30,ext2)) + +$(eval $(call KMOD_template,FS_EXT3,fs-ext3,\ + $(MODULES_DIR)/kernel/fs/ext3/*.o \ + $(MODULES_DIR)/kernel/fs/jbd/*.o \ +,CONFIG_EXT3_FS,,30,jbd ext3)) + +$(eval $(call KMOD_template,FS_HFSPLUS,fs-hfsplus,\ + $(MODULES_DIR)/kernel/fs/hfsplus/*.o \ +,CONFIG_HFSPLUS_FS,,30,hfsplus)) + +$(eval $(call KMOD_template,FS_NFS,fs-nfs,\ + $(MODULES_DIR)/kernel/fs/lockd/*.o \ + $(MODULES_DIR)/kernel/fs/nfs/*.o \ + $(MODULES_DIR)/kernel/net/sunrpc/*.o \ +,CONFIG_NFS_FS,,30,sunrpc lockd nfs)) + +$(eval $(call KMOD_template,FS_VFAT,fs-vfat,\ + $(MODULES_DIR)/kernel/fs/vfat/vfat.o \ + $(MODULES_DIR)/kernel/fs/fat/fat.o \ +,CONFIG_VFAT_FS,,30,fat vfat)) + +$(eval $(call KMOD_template,FS_XFS,fs-xfs,\ + $(MODULES_DIR)/kernel/fs/xfs/*.o \ +,CONFIG_XFS_FS,,30,xfs)) + + +# Multimedia + +$(eval $(call KMOD_template,PWC,pwc,\ + $(MODULES_DIR)/kernel/drivers/usb/pwc.o \ +,CONFIG_USB_PWC,kmod-videodev,63,pwc)) + +$(eval $(call KMOD_template,SOUNDCORE,soundcore,\ + $(MODULES_DIR)/kernel/drivers/sound/soundcore.o \ +,CONFIG_SOUND,,30,soundcore)) + +$(eval $(call KMOD_template,VIDEODEV,videodev,\ + $(MODULES_DIR)/kernel/drivers/media/video/videodev.o \ +,CONFIG_VIDEO_DEV,,62,videodev)) + + +# Network devices + +$(eval $(call KMOD_template,NET_3C59X,net-3c59x,\ + $(MODULES_DIR)/kernel/drivers/net/3c59x.o \ +,CONFIG_VORTEX,,10,3c59x)) + +$(eval $(call KMOD_template,NET_8139TOO,net-8139too,\ + $(MODULES_DIR)/kernel/drivers/net/8139too.o \ + $(MODULES_DIR)/kernel/drivers/net/mii.o \ +,CONFIG_8139TOO,,10,mii 8139too)) + +$(eval $(call KMOD_template,NET_AIRO,net-airo,\ + $(MODULES_DIR)/kernel/drivers/net/wireless/airo.o \ +,CONFIG_AIRO,,10,airo)) + +$(eval $(call KMOD_template,NET_B44,net-b44,\ + $(MODULES_DIR)/kernel/drivers/net/b44.o \ +,CONFIG_B44,,10,b44)) + +$(eval $(call KMOD_template,NET_E100,net-e100,\ + $(MODULES_DIR)/kernel/drivers/net/e100.o \ +,CONFIG_E100,,10,e100)) + +$(eval $(call KMOD_template,NET_HERMES,net-hermes,\ + $(MODULES_DIR)/kernel/drivers/net/wireless/hermes.o \ + $(MODULES_DIR)/kernel/drivers/net/wireless/orinoco.o \ +,CONFIG_HERMES,,10,hermes orinoco)) + +$(eval $(call KMOD_template,NET_HERMES_PCI,net-hermes-pci,\ + $(MODULES_DIR)/kernel/drivers/net/wireless/orinoco_pci.o \ +,CONFIG_PCI_HERMES,kmod-net-hermes,11,orinoco_pci)) + +$(eval $(call KMOD_template,NET_HERMES_PCI,net-hermes-plx,\ + $(MODULES_DIR)/kernel/drivers/net/wireless/orinoco_plx.o \ +,CONFIG_PLX_HERMES,kmod-net-hermes,11,orinoco_plx)) + +$(eval $(call KMOD_template,NET_NATSEMI,net-natsemi,\ + $(MODULES_DIR)/kernel/drivers/net/natsemi.o \ +,CONFIG_NATSEMI,,10,natsemi)) + +$(eval $(call KMOD_template,NET_PRISM54,net-prism54,\ + $(MODULES_DIR)/kernel/drivers/net/wireless/prism54/prism54.o \ +,CONFIG_PRISM54,,10,prism54)) + + +# PCMCIA/CardBus + +$(eval $(call KMOD_template,PCMCIA_CORE,pcmcia-core,\ + $(MODULES_DIR)/kernel/drivers/pcmcia/pcmcia_core.o \ + $(MODULES_DIR)/kernel/drivers/pcmcia/yenta_socket.o \ + $(MODULES_DIR)/kernel/drivers/pcmcia/ds.o \ +,CONFIG_PCMCIA,,50,pcmcia_core yenta_socket ds)) + +$(eval $(call KMOD_template,PCMCIA_SERIAL,pcmcia-serial,\ + $(MODULES_DIR)/kernel/drivers/char/pcmcia/serial_cs.o \ +,CONFIG_PCMCIA_SERIAL_CS,kmod-pcmcia-core,51,serial_cs)) + + +# USB + +$(eval $(call KMOD_template,USB,usb-core,\ + $(MODULES_DIR)/kernel/drivers/usb/usbcore.o \ +,CONFIG_USB,,50,usbcore)) + +$(eval $(call KMOD_template,USB_OHCI,usb-ohci,\ + $(MODULES_DIR)/kernel/drivers/usb/host/usb-ohci.o \ +,CONFIG_USB_OHCI,kmod-usb-core,60,usb-ohci)) + +$(eval $(call KMOD_template,USB_UHCI,usb-uhci,\ + $(MODULES_DIR)/kernel/drivers/usb/host/uhci.o \ +,CONFIG_USB_UHCI_ALT,kmod-usb-core,60,uhci)) + +$(eval $(call KMOD_template,USB2,usb2,\ + $(MODULES_DIR)/kernel/drivers/usb/host/ehci-hcd.o \ +,CONFIG_USB_EHCI_HCD,kmod-usb-core,60,ehci-hcd)) + +$(eval $(call KMOD_template,USB_ACM,usb-acm,\ + $(MODULES_DIR)/kernel/drivers/usb/acm.o \ +,CONFIG_USB_ACM)) + +$(eval $(call KMOD_template,USB_AUDIO,usb-audio,\ + $(MODULES_DIR)/kernel/drivers/usb/audio.o \ +,CONFIG_USB_AUDIO,kmod-soundcore kmod-usb-core,61,audio)) + +$(eval $(call KMOD_template,USB_PRINTER,usb-printer,\ + $(MODULES_DIR)/kernel/drivers/usb/printer.o \ +,CONFIG_USB_PRINTER,kmod-usb-core,60,printer)) + +$(eval $(call KMOD_template,USB_SERIAL,usb-serial,\ + $(MODULES_DIR)/kernel/drivers/usb/serial/usbserial.o \ +,CONFIG_USB_SERIAL,kmod-usb-core,60,usbserial)) + +$(eval $(call KMOD_template,USB_SERIAL_BELKIN,usb-serial-belkin,\ + $(MODULES_DIR)/kernel/drivers/usb/serial/belkin_sa.o \ +,CONFIG_USB_SERIAL_BELKIN,kmod-usb-serial,61,belkin_sa)) + +$(eval $(call KMOD_template,USB_SERIAL_FTDI,usb-serial-ftdi,\ + $(MODULES_DIR)/kernel/drivers/usb/serial/ftdi_sio.o \ +,CONFIG_USB_SERIAL_FTDI_SIO,kmod-usb-serial,61,ftdi_sio)) + +$(eval $(call KMOD_template,USB_SERIAL_MCT_U232,usb-serial-mct-u232,\ + $(MODULES_DIR)/kernel/drivers/usb/serial/mct_u232.o \ +,CONFIG_USB_SERIAL_MCT_U232,kmod-usb-serial,61,mct_u232)) + +$(eval $(call KMOD_template,USB_SERIAL_PL2303,usb-serial-pl2303,\ + $(MODULES_DIR)/kernel/drivers/usb/serial/pl2303.o \ +,CONFIG_USB_SERIAL_PL2303,kmod-usb-serial,61,pl2303)) + +$(eval $(call KMOD_template,USB_SERIAL_VISOR,usb-serial-visor,\ + $(MODULES_DIR)/kernel/drivers/usb/serial/visor.o \ +,CONFIG_USB_SERIAL_VISOR,kmod-usb-serial,61,visor)) + +$(eval $(call KMOD_template,USB_STORAGE,usb-storage,\ + $(MODULES_DIR)/kernel/drivers/scsi/*.o \ + $(MODULES_DIR)/kernel/drivers/usb/storage/*.o \ +,CONFIG_USB_STORAGE,kmod-usb-core,60,scsi_mod sd_mod usb-storage)) + + +# Misc. devices + +$(eval $(call KMOD_template,AX25,ax25,\ + $(MODULES_DIR)/kernel/net/ax25/ax25.o \ + $(MODULES_DIR)/kernel/drivers/net/hamradio/mkiss.o \ +,CONFIG_AX25,,90,ax25 mkiss)) + +$(eval $(call KMOD_template,BLUETOOTH,bluetooth,\ + $(MODULES_DIR)/kernel/net/bluetooth/*.o \ + $(MODULES_DIR)/kernel/net/bluetooth/rfcomm/*.o \ + $(MODULES_DIR)/kernel/drivers/bluetooth/*.o \ +,CONFIG_BLUEZ)) + +$(eval $(call KMOD_template,SOFTDOG,softdog,\ + $(MODULES_DIR)/kernel/drivers/char/softdog.o \ +,CONFIG_SOFT_WATCHDOG,,95,softdog)) + + + diff --git a/openwrt/target/linux/generic-2.4/patches/000-linux_mips.patch b/openwrt/target/linux/generic-2.4/patches/000-linux_mips.patch new file mode 100644 index 0000000000..7fae1eefc6 --- /dev/null +++ b/openwrt/target/linux/generic-2.4/patches/000-linux_mips.patch @@ -0,0 +1,27968 @@ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/au1xxx_irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/au1xxx_irqmap.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/au1xxx_irqmap.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/au1xxx_irqmap.c 2005-01-30 09:01:27.000000000 +0100 +@@ -172,14 +172,14 @@ + { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0}, +- { AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +- { AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, ++ { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0}, + { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, +@@ -200,14 +200,14 @@ + { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0}, +- { AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +- { AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, +- { AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, ++ { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, ++ { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0}, + { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 }, + { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/cputable.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/cputable.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/cputable.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/cputable.c 2005-01-30 09:01:27.000000000 +0100 +@@ -39,7 +39,8 @@ + { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 }, + { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 }, + { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 }, +- { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 }, ++ { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 }, ++ { 0xffffffff, 0x04030201, "Au1200 AC", 0, 0 }, + { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 }, + }; + +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/dbdma.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/dbdma.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/dbdma.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/dbdma.c 2005-02-08 07:28:37.000000000 +0100 +@@ -41,6 +41,8 @@ + #include + #include + ++#include ++ + #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) + + /* +@@ -60,37 +62,10 @@ + */ + #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1)) + +-static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; +-static int dbdma_initialized; ++static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; ++static int dbdma_initialized=0; + static void au1xxx_dbdma_init(void); + +-typedef struct dbdma_device_table { +- u32 dev_id; +- u32 dev_flags; +- u32 dev_tsize; +- u32 dev_devwidth; +- u32 dev_physaddr; /* If FIFO */ +- u32 dev_intlevel; +- u32 dev_intpolarity; +-} dbdev_tab_t; +- +-typedef struct dbdma_chan_config { +- u32 chan_flags; +- u32 chan_index; +- dbdev_tab_t *chan_src; +- dbdev_tab_t *chan_dest; +- au1x_dma_chan_t *chan_ptr; +- au1x_ddma_desc_t *chan_desc_base; +- au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr; +- void *chan_callparam; +- void (*chan_callback)(int, void *, struct pt_regs *); +-} chan_tab_t; +- +-#define DEV_FLAGS_INUSE (1 << 0) +-#define DEV_FLAGS_ANYUSE (1 << 1) +-#define DEV_FLAGS_OUT (1 << 2) +-#define DEV_FLAGS_IN (1 << 3) +- + static dbdev_tab_t dbdev_tab[] = { + #ifdef CONFIG_SOC_AU1550 + /* UARTS */ +@@ -156,13 +131,13 @@ + { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + +- { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, ++ { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, ++ { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, ++ { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, ++ { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 }, + +- { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, ++ { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, ++ { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, + + { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, + { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, +@@ -172,9 +147,9 @@ + { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 }, + { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + +- { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, ++ { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, ++ { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, ++ { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, + { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + + { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +@@ -183,6 +158,24 @@ + + { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, ++ ++ /* Provide 16 user definable device types */ ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, + }; + + #define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t)) +@@ -202,6 +195,30 @@ + return NULL; + } + ++u32 ++au1xxx_ddma_add_device(dbdev_tab_t *dev) ++{ ++ u32 ret = 0; ++ dbdev_tab_t *p=NULL; ++ static u16 new_id=0x1000; ++ ++ p = find_dbdev_id(0); ++ if ( NULL != p ) ++ { ++ memcpy(p, dev, sizeof(dbdev_tab_t)); ++ p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id); ++ ret = p->dev_id; ++ new_id++; ++#if 0 ++ printk("add_device: id:%x flags:%x padd:%x\n", ++ p->dev_id, p->dev_flags, p->dev_physaddr ); ++#endif ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(au1xxx_ddma_add_device); ++ + /* Allocate a channel and return a non-zero descriptor if successful. + */ + u32 +@@ -214,7 +231,7 @@ + int i; + dbdev_tab_t *stp, *dtp; + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + + /* We do the intialization on the first channel allocation. + * We have to wait because of the interrupt handler initialization +@@ -224,9 +241,6 @@ + au1xxx_dbdma_init(); + dbdma_initialized = 1; + +- if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS)) +- return 0; +- + if ((stp = find_dbdev_id(srcid)) == NULL) return 0; + if ((dtp = find_dbdev_id(destid)) == NULL) return 0; + +@@ -268,9 +282,9 @@ + /* If kmalloc fails, it is caught below same + * as a channel not available. + */ +- ctp = (chan_tab_t *)kmalloc(sizeof(chan_tab_t), GFP_KERNEL); ++ ctp = (chan_tab_t *) ++ kmalloc(sizeof(chan_tab_t), GFP_KERNEL); + chan_tab_ptr[i] = ctp; +- ctp->chan_index = chan = i; + break; + } + } +@@ -278,10 +292,11 @@ + + if (ctp != NULL) { + memset(ctp, 0, sizeof(chan_tab_t)); ++ ctp->chan_index = chan = i; + dcp = DDMA_CHANNEL_BASE; + dcp += (0x0100 * chan); + ctp->chan_ptr = (au1x_dma_chan_t *)dcp; +- cp = (volatile au1x_dma_chan_t *)dcp; ++ cp = (au1x_dma_chan_t *)dcp; + ctp->chan_src = stp; + ctp->chan_dest = dtp; + ctp->chan_callback = callback; +@@ -298,6 +313,9 @@ + i |= DDMA_CFG_DED; + if (dtp->dev_intpolarity) + i |= DDMA_CFG_DP; ++ if ((stp->dev_flags & DEV_FLAGS_SYNC) || ++ (dtp->dev_flags & DEV_FLAGS_SYNC)) ++ i |= DDMA_CFG_SYNC; + cp->ddma_cfg = i; + au_sync(); + +@@ -308,14 +326,14 @@ + rv = (u32)(&chan_tab_ptr[chan]); + } + else { +- /* Release devices. +- */ ++ /* Release devices */ + stp->dev_flags &= ~DEV_FLAGS_INUSE; + dtp->dev_flags &= ~DEV_FLAGS_INUSE; + } + } + return rv; + } ++EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); + + /* Set the device width if source or destination is a FIFO. + * Should be 8, 16, or 32 bits. +@@ -343,6 +361,7 @@ + + return rv; + } ++EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth); + + /* Allocate a descriptor ring, initializing as much as possible. + */ +@@ -369,7 +388,8 @@ + * and if we try that first we are likely to not waste larger + * slabs of memory. + */ +- desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL); ++ desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), ++ GFP_KERNEL|GFP_DMA); + if (desc_base == 0) + return 0; + +@@ -380,7 +400,7 @@ + kfree((const void *)desc_base); + i = entries * sizeof(au1x_ddma_desc_t); + i += (sizeof(au1x_ddma_desc_t) - 1); +- if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0) ++ if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0) + return 0; + + desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t)); +@@ -460,9 +480,14 @@ + /* If source input is fifo, set static address. + */ + if (stp->dev_flags & DEV_FLAGS_IN) { +- src0 = stp->dev_physaddr; +- src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC); ++ if ( stp->dev_flags & DEV_FLAGS_BURSTABLE ) ++ src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST); ++ else ++ src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC); ++ + } ++ if (stp->dev_physaddr) ++ src0 = stp->dev_physaddr; + + /* Set up dest1. For now, assume no stride and increment. + * A channel attribute update can change this later. +@@ -486,10 +511,18 @@ + /* If destination output is fifo, set static address. + */ + if (dtp->dev_flags & DEV_FLAGS_OUT) { +- dest0 = dtp->dev_physaddr; ++ if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE ) ++ dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST); ++ else + dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC); + } ++ if (dtp->dev_physaddr) ++ dest0 = dtp->dev_physaddr; + ++#if 0 ++ printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", ++ dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 ); ++#endif + for (i=0; idscr_cmd0 = cmd0; + dp->dscr_cmd1 = cmd1; +@@ -498,6 +531,7 @@ + dp->dscr_dest0 = dest0; + dp->dscr_dest1 = dest1; + dp->dscr_stat = 0; ++ dp->sw_context = dp->sw_status = 0; + dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1)); + dp++; + } +@@ -510,13 +544,14 @@ + + return (u32)(ctp->chan_desc_base); + } ++EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); + + /* Put a source buffer into the DMA ring. + * This updates the source pointer and byte count. Normally used + * for memory to fifo transfers. + */ + u32 +-au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes) ++_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) + { + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; +@@ -543,24 +578,40 @@ + */ + dp->dscr_source0 = virt_to_phys(buf); + dp->dscr_cmd1 = nbytes; +- dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ +- ctp->chan_ptr->ddma_dbell = 0xffffffff; /* Make it go */ +- ++ /* Check flags */ ++ if (flags & DDMA_FLAGS_IE) ++ dp->dscr_cmd0 |= DSCR_CMD0_IE; ++ if (flags & DDMA_FLAGS_NOIE) ++ dp->dscr_cmd0 &= ~DSCR_CMD0_IE; + /* Get next descriptor pointer. + */ + ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); + ++ /* ++ * There is an errata on the Au1200/Au1550 parts that could result ++ * in "stale" data being DMA'd. It has to do with the snoop logic on ++ * the dache eviction buffer. NONCOHERENT_IO is on by default for ++ * these parts. If it is fixedin the future, these dma_cache_inv will ++ * just be nothing more than empty macros. See io.h. ++ * */ ++ dma_cache_wback_inv(buf,nbytes); ++ dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ ++ au_sync(); ++ dma_cache_wback_inv(dp, sizeof(dp)); ++ ctp->chan_ptr->ddma_dbell = 0; ++ + /* return something not zero. + */ + return nbytes; + } ++EXPORT_SYMBOL(_au1xxx_dbdma_put_source); + + /* Put a destination buffer into the DMA ring. + * This updates the destination pointer and byte count. Normally used + * to place an empty buffer into the ring for fifo to memory transfers. + */ + u32 +-au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes) ++_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) + { + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; +@@ -582,11 +633,33 @@ + if (dp->dscr_cmd0 & DSCR_CMD0_V) + return 0; + +- /* Load up buffer address and byte count. +- */ ++ /* Load up buffer address and byte count */ ++ ++ /* Check flags */ ++ if (flags & DDMA_FLAGS_IE) ++ dp->dscr_cmd0 |= DSCR_CMD0_IE; ++ if (flags & DDMA_FLAGS_NOIE) ++ dp->dscr_cmd0 &= ~DSCR_CMD0_IE; ++ + dp->dscr_dest0 = virt_to_phys(buf); + dp->dscr_cmd1 = nbytes; ++#if 0 ++ printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", ++ dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0, ++ dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 ); ++#endif ++ /* ++ * There is an errata on the Au1200/Au1550 parts that could result in ++ * "stale" data being DMA'd. It has to do with the snoop logic on the ++ * dache eviction buffer. NONCOHERENT_IO is on by default for these ++ * parts. If it is fixedin the future, these dma_cache_inv will just ++ * be nothing more than empty macros. See io.h. ++ * */ ++ dma_cache_inv(buf,nbytes); + dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ ++ au_sync(); ++ dma_cache_wback_inv(dp, sizeof(dp)); ++ ctp->chan_ptr->ddma_dbell = 0; + + /* Get next descriptor pointer. + */ +@@ -596,6 +669,7 @@ + */ + return nbytes; + } ++EXPORT_SYMBOL(_au1xxx_dbdma_put_dest); + + /* Get a destination buffer into the DMA ring. + * Normally used to get a full buffer from the ring during fifo +@@ -645,7 +719,7 @@ + au1xxx_dbdma_stop(u32 chanid) + { + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + int halt_timeout = 0; + + ctp = *((chan_tab_t **)chanid); +@@ -665,6 +739,7 @@ + cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); + au_sync(); + } ++EXPORT_SYMBOL(au1xxx_dbdma_stop); + + /* Start using the current descriptor pointer. If the dbdma encounters + * a not valid descriptor, it will stop. In this case, we can just +@@ -674,17 +749,17 @@ + au1xxx_dbdma_start(u32 chanid) + { + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + + ctp = *((chan_tab_t **)chanid); +- + cp = ctp->chan_ptr; + cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); + cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ + au_sync(); +- cp->ddma_dbell = 0xffffffff; /* Make it go */ ++ cp->ddma_dbell = 0; + au_sync(); + } ++EXPORT_SYMBOL(au1xxx_dbdma_start); + + void + au1xxx_dbdma_reset(u32 chanid) +@@ -703,15 +778,21 @@ + + do { + dp->dscr_cmd0 &= ~DSCR_CMD0_V; ++ /* reset our SW status -- this is used to determine ++ * if a descriptor is in use by upper level SW. Since ++ * posting can reset 'V' bit. ++ */ ++ dp->sw_status = 0; + dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); + } while (dp != ctp->chan_desc_base); + } ++EXPORT_SYMBOL(au1xxx_dbdma_reset); + + u32 + au1xxx_get_dma_residue(u32 chanid) + { + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + u32 rv; + + ctp = *((chan_tab_t **)chanid); +@@ -746,15 +827,16 @@ + + kfree(ctp); + } ++EXPORT_SYMBOL(au1xxx_dbdma_chan_free); + + static void + dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) + { +- u32 intstat; ++ u32 intstat, flags; + u32 chan_index; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + + intstat = dbdma_gptr->ddma_intstat; + au_sync(); +@@ -773,18 +855,26 @@ + (ctp->chan_callback)(irq, ctp->chan_callparam, regs); + + ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); +- + } + +-static void +-au1xxx_dbdma_init(void) ++static void au1xxx_dbdma_init(void) + { ++ int irq_nr; ++ + dbdma_gptr->ddma_config = 0; + dbdma_gptr->ddma_throttle = 0; + dbdma_gptr->ddma_inten = 0xffff; + au_sync(); + +- if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT, ++#if defined(CONFIG_SOC_AU1550) ++ irq_nr = AU1550_DDMA_INT; ++#elif defined(CONFIG_SOC_AU1200) ++ irq_nr = AU1200_DDMA_INT; ++#else ++ #error Unknown Au1x00 SOC ++#endif ++ ++ if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT, + "Au1xxx dbdma", (void *)dbdma_gptr)) + printk("Can't get 1550 dbdma irq"); + } +@@ -795,7 +885,8 @@ + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; + dbdev_tab_t *stp, *dtp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; ++ u32 i = 0; + + ctp = *((chan_tab_t **)chanid); + stp = ctp->chan_src; +@@ -820,15 +911,64 @@ + dp = ctp->chan_desc_base; + + do { +- printk("dp %08x, cmd0 %08x, cmd1 %08x\n", +- (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); +- printk("src0 %08x, src1 %08x, dest0 %08x\n", +- dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0); +- printk("dest1 %08x, stat %08x, nxtptr %08x\n", +- dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr); ++ printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n", ++ i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); ++ printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n", ++ dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1); ++ printk("stat %08x, nxtptr %08x\n", ++ dp->dscr_stat, dp->dscr_nxtptr); + dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); + } while (dp != ctp->chan_desc_base); + } + ++/* Put a descriptor into the DMA ring. ++ * This updates the source/destination pointers and byte count. ++ */ ++u32 ++au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ) ++{ ++ chan_tab_t *ctp; ++ au1x_ddma_desc_t *dp; ++ u32 nbytes=0; ++ ++ /* I guess we could check this to be within the ++ * range of the table...... ++ */ ++ ctp = *((chan_tab_t **)chanid); ++ ++ /* We should have multiple callers for a particular channel, ++ * an interrupt doesn't affect this pointer nor the descriptor, ++ * so no locking should be needed. ++ */ ++ dp = ctp->put_ptr; ++ ++ /* If the descriptor is valid, we are way ahead of the DMA ++ * engine, so just return an error condition. ++ */ ++ if (dp->dscr_cmd0 & DSCR_CMD0_V) ++ return 0; ++ ++ /* Load up buffer addresses and byte count. ++ */ ++ dp->dscr_dest0 = dscr->dscr_dest0; ++ dp->dscr_source0 = dscr->dscr_source0; ++ dp->dscr_dest1 = dscr->dscr_dest1; ++ dp->dscr_source1 = dscr->dscr_source1; ++ dp->dscr_cmd1 = dscr->dscr_cmd1; ++ nbytes = dscr->dscr_cmd1; ++ /* Allow the caller to specifiy if an interrupt is generated */ ++ dp->dscr_cmd0 &= ~DSCR_CMD0_IE; ++ dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V; ++ ctp->chan_ptr->ddma_dbell = 0; ++ ++ /* Get next descriptor pointer. ++ */ ++ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); ++ ++ /* return something not zero. ++ */ ++ return nbytes; ++} ++ + #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ + +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/gpio.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/gpio.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/gpio.c 2005-01-30 09:01:27.000000000 +0100 +@@ -0,0 +1,118 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++ ++#define gpio1 sys ++#if !defined(CONFIG_SOC_AU1000) ++static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE; ++ ++#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 ++ ++int au1xxx_gpio2_read(int signal) ++{ ++ signal -= 200; ++/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */ ++ return ((gpio2->pinstate >> signal) & 0x01); ++} ++ ++void au1xxx_gpio2_write(int signal, int value) ++{ ++ signal -= 200; ++ ++ gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) | ++ (value << signal); ++} ++ ++void au1xxx_gpio2_tristate(int signal) ++{ ++ signal -= 200; ++ gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */ ++} ++#endif ++ ++int au1xxx_gpio1_read(int signal) ++{ ++/* gpio1->trioutclr |= (0x01 << signal); */ ++ return ((gpio1->pinstaterd >> signal) & 0x01); ++} ++ ++void au1xxx_gpio1_write(int signal, int value) ++{ ++ if(value) ++ gpio1->outputset = (0x01 << signal); ++ else ++ gpio1->outputclr = (0x01 << signal); /* Output a Zero */ ++} ++ ++void au1xxx_gpio1_tristate(int signal) ++{ ++ gpio1->trioutclr = (0x01 << signal); /* Tristate signal */ ++} ++ ++ ++int au1xxx_gpio_read(int signal) ++{ ++ if(signal >= 200) ++#if defined(CONFIG_SOC_AU1000) ++ return 0; ++#else ++ return au1xxx_gpio2_read(signal); ++#endif ++ else ++ return au1xxx_gpio1_read(signal); ++} ++ ++void au1xxx_gpio_write(int signal, int value) ++{ ++ if(signal >= 200) ++#if defined(CONFIG_SOC_AU1000) ++ ; ++#else ++ au1xxx_gpio2_write(signal, value); ++#endif ++ else ++ au1xxx_gpio1_write(signal, value); ++} ++ ++void au1xxx_gpio_tristate(int signal) ++{ ++ if(signal >= 200) ++#if defined(CONFIG_SOC_AU1000) ++ ; ++#else ++ au1xxx_gpio2_tristate(signal); ++#endif ++ else ++ au1xxx_gpio1_tristate(signal); ++} ++ ++void au1xxx_gpio1_set_inputs(void) ++{ ++ gpio1->pininputen = 0; ++} ++ ++EXPORT_SYMBOL(au1xxx_gpio1_set_inputs); ++EXPORT_SYMBOL(au1xxx_gpio_tristate); ++EXPORT_SYMBOL(au1xxx_gpio_write); ++EXPORT_SYMBOL(au1xxx_gpio_read); +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/irq.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/irq.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/irq.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/irq.c 2005-03-13 08:56:57.000000000 +0100 +@@ -303,8 +303,30 @@ + }; + + #ifdef CONFIG_PM +-void startup_match20_interrupt(void) ++void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *)) + { ++ static struct irqaction action; ++ /* This is a big problem.... since we didn't use request_irq ++ when kernel/irq.c calls probe_irq_xxx this interrupt will ++ be probed for usage. This will end up disabling the device :( ++ ++ Give it a bogus "action" pointer -- this will keep it from ++ getting auto-probed! ++ ++ By setting the status to match that of request_irq() we ++ can avoid it. --cgray ++ */ ++ action.dev_id = handler; ++ action.flags = 0; ++ action.mask = 0; ++ action.name = "Au1xxx TOY"; ++ action.handler = handler; ++ action.next = NULL; ++ ++ irq_desc[AU1000_TOY_MATCH2_INT].action = &action; ++ irq_desc[AU1000_TOY_MATCH2_INT].status ++ &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); ++ + local_enable_irq(AU1000_TOY_MATCH2_INT); + } + #endif +@@ -508,6 +530,7 @@ + + if (!intc0_req0) return; + ++#ifdef AU1000_USB_DEV_REQ_INT + /* + * Because of the tight timing of SETUP token to reply + * transactions, the USB devices-side packet complete +@@ -518,6 +541,7 @@ + do_IRQ(AU1000_USB_DEV_REQ_INT, regs); + return; + } ++#endif + + irq = au_ffs(intc0_req0) - 1; + intc0_req0 &= ~(1<bus->number; + unsigned int dev_fn = dev->devfn; +@@ -170,7 +171,6 @@ + unsigned long offset, status; + unsigned long cfg_base; + unsigned long flags; +- int error = PCIBIOS_SUCCESSFUL; + unsigned long entryLo0, entryLo1; + + if (device > 19) { +@@ -205,9 +205,8 @@ + last_entryLo0 = last_entryLo1 = 0xffffffff; + } + +- /* Since the Au1xxx doesn't do the idsel timing exactly to spec, +- * many board vendors implement their own off-chip idsel, so call +- * it now. If it doesn't succeed, may as well bail out at this point. ++ /* Allow board vendors to implement their own off-chip idsel. ++ * If it doesn't succeed, may as well bail out at this point. + */ + if (board_pci_idsel) { + if (board_pci_idsel(device, 1) == 0) { +@@ -271,8 +270,11 @@ + } + + local_irq_restore(flags); +- return error; ++#else ++ /* Fake out Config space access with no responder */ ++ *data = 0xFFFFFFFF; + #endif ++ return error; + } + #endif + +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/power.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/power.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/power.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/power.c 2005-04-07 02:37:19.000000000 +0200 +@@ -50,7 +50,6 @@ + + static void calibrate_delay(void); + +-extern void set_au1x00_speed(unsigned int new_freq); + extern unsigned int get_au1x00_speed(void); + extern unsigned long get_au1x00_uart_baud_base(void); + extern void set_au1x00_uart_baud_base(unsigned long new_baud_base); +@@ -116,6 +115,7 @@ + sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); + sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); + ++#ifndef CONFIG_SOC_AU1200 + /* Shutdown USB host/device. + */ + sleep_usbhost_enable = au_readl(USB_HOST_CONFIG); +@@ -127,6 +127,7 @@ + + sleep_usbdev_enable = au_readl(USBD_ENABLE); + au_writel(0, USBD_ENABLE); au_sync(); ++#endif + + /* Save interrupt controller state. + */ +@@ -212,14 +213,12 @@ + int au_sleep(void) + { + unsigned long wakeup, flags; +- extern void save_and_sleep(void); ++ extern unsigned int save_and_sleep(void); + + spin_lock_irqsave(&pm_lock,flags); + + save_core_regs(); + +- flush_cache_all(); +- + /** The code below is all system dependent and we should probably + ** have a function call out of here to set this up. You need + ** to configure the GPIO or timer interrupts that will bring +@@ -227,27 +226,26 @@ + ** For testing, the TOY counter wakeup is useful. + **/ + +-#if 0 ++#if 1 + au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD); + + /* gpio 6 can cause a wake up event */ + wakeup = au_readl(SYS_WAKEMSK); + wakeup &= ~(1 << 8); /* turn off match20 wakeup */ +- wakeup |= 1 << 6; /* turn on gpio 6 wakeup */ ++ wakeup = 1 << 5; /* turn on gpio 6 wakeup */ + #else +- /* For testing, allow match20 to wake us up. +- */ ++ /* For testing, allow match20 to wake us up. */ + #ifdef SLEEP_TEST_TIMEOUT + wakeup_counter0_set(sleep_ticks); + #endif + wakeup = 1 << 8; /* turn on match20 wakeup */ + wakeup = 0; + #endif +- au_writel(1, SYS_WAKESRC); /* clear cause */ ++ au_writel(0, SYS_WAKESRC); /* clear cause */ + au_sync(); + au_writel(wakeup, SYS_WAKEMSK); + au_sync(); +- ++ DPRINTK("Entering sleep!\n"); + save_and_sleep(); + + /* after a wakeup, the cpu vectors back to 0x1fc00000 so +@@ -255,6 +253,7 @@ + */ + restore_core_regs(); + spin_unlock_irqrestore(&pm_lock, flags); ++ DPRINTK("Leaving sleep!\n"); + return 0; + } + +@@ -285,7 +284,6 @@ + + if (retval) + return retval; +- + au_sleep(); + retval = pm_send_all(PM_RESUME, (void *) 0); + } +@@ -296,7 +294,6 @@ + void *buffer, size_t * len) + { + int retval = 0; +- void au1k_wait(void); + + if (!write) { + *len = 0; +@@ -305,119 +302,9 @@ + if (retval) + return retval; + suspend_mode = 1; +- au1k_wait(); +- retval = pm_send_all(PM_RESUME, (void *) 0); +- } +- return retval; +-} + +- +-static int pm_do_freq(ctl_table * ctl, int write, struct file *file, +- void *buffer, size_t * len) +-{ +- int retval = 0, i; +- unsigned long val, pll; +-#define TMPBUFLEN 64 +-#define MAX_CPU_FREQ 396 +- char buf[TMPBUFLEN], *p; +- unsigned long flags, intc0_mask, intc1_mask; +- unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk, +- old_refresh; +- unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh; +- +- spin_lock_irqsave(&pm_lock, flags); +- if (!write) { +- *len = 0; +- } else { +- /* Parse the new frequency */ +- if (*len > TMPBUFLEN - 1) { +- spin_unlock_irqrestore(&pm_lock, flags); +- return -EFAULT; +- } +- if (copy_from_user(buf, buffer, *len)) { +- spin_unlock_irqrestore(&pm_lock, flags); +- return -EFAULT; +- } +- buf[*len] = 0; +- p = buf; +- val = simple_strtoul(p, &p, 0); +- if (val > MAX_CPU_FREQ) { +- spin_unlock_irqrestore(&pm_lock, flags); +- return -EFAULT; +- } +- +- pll = val / 12; +- if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */ +- /* revisit this for higher speed cpus */ +- spin_unlock_irqrestore(&pm_lock, flags); +- return -EFAULT; +- } +- +- old_baud_base = get_au1x00_uart_baud_base(); +- old_cpu_freq = get_au1x00_speed(); +- +- new_cpu_freq = pll * 12 * 1000000; +- new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); +- set_au1x00_speed(new_cpu_freq); +- set_au1x00_uart_baud_base(new_baud_base); +- +- old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff; +- new_refresh = +- ((old_refresh * new_cpu_freq) / +- old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff); +- +- au_writel(pll, SYS_CPUPLL); +- au_sync_delay(1); +- au_writel(new_refresh, MEM_SDREFCFG); +- au_sync_delay(1); +- +- for (i = 0; i < 4; i++) { +- if (au_readl +- (UART_BASE + UART_MOD_CNTRL + +- i * 0x00100000) == 3) { +- old_clk = +- au_readl(UART_BASE + UART_CLK + +- i * 0x00100000); +- // baud_rate = baud_base/clk +- baud_rate = old_baud_base / old_clk; +- /* we won't get an exact baud rate and the error +- * could be significant enough that our new +- * calculation will result in a clock that will +- * give us a baud rate that's too far off from +- * what we really want. +- */ +- if (baud_rate > 100000) +- baud_rate = 115200; +- else if (baud_rate > 50000) +- baud_rate = 57600; +- else if (baud_rate > 30000) +- baud_rate = 38400; +- else if (baud_rate > 17000) +- baud_rate = 19200; +- else +- (baud_rate = 9600); +- // new_clk = new_baud_base/baud_rate +- new_clk = new_baud_base / baud_rate; +- au_writel(new_clk, +- UART_BASE + UART_CLK + +- i * 0x00100000); +- au_sync_delay(10); +- } +- } ++ retval = pm_send_all(PM_RESUME, (void *) 0); + } +- +- +- /* We don't want _any_ interrupts other than +- * match20. Otherwise our calibrate_delay() +- * calculation will be off, potentially a lot. +- */ +- intc0_mask = save_local_and_disable(0); +- intc1_mask = save_local_and_disable(1); +- local_enable_irq(AU1000_TOY_MATCH2_INT); +- spin_unlock_irqrestore(&pm_lock, flags); +- calibrate_delay(); +- restore_local_and_enable(0, intc0_mask); +- restore_local_and_enable(1, intc1_mask); + return retval; + } + +@@ -425,7 +312,6 @@ + static struct ctl_table pm_table[] = { + {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend}, + {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep}, +- {CTL_ACPI, "freq", NULL, 0, 0600, NULL, &pm_do_freq}, + {0} + }; + +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/reset.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/reset.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/reset.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/reset.c 2005-03-19 08:17:51.000000000 +0100 +@@ -37,8 +37,6 @@ + #include + #include + +-extern int au_sleep(void); +- + void au1000_restart(char *command) + { + /* Set all integrated peripherals to disabled states */ +@@ -144,6 +142,26 @@ + au_writel(0x00, 0xb1900064); /* sys_auxpll */ + au_writel(0x00, 0xb1900100); /* sys_pininputen */ + break; ++ case 0x04000000: /* Au1200 */ ++ au_writel(0x00, 0xb400300c); /* ddma */ ++ au_writel(0x00, 0xb1a00004); /* psc 0 */ ++ au_writel(0x00, 0xb1b00004); /* psc 1 */ ++ au_writel(0x00d02000, 0xb4020004); /* ehci, ohci, udc, otg */ ++ au_writel(0x00, 0xb5000004); /* lcd */ ++ au_writel(0x00, 0xb060000c); /* sd0 */ ++ au_writel(0x00, 0xb068000c); /* sd1 */ ++ au_writel(0x00, 0xb1100100); /* swcnt */ ++ au_writel(0x00, 0xb0300000); /* aes */ ++ au_writel(0x00, 0xb4004000); /* cim */ ++ au_writel(0x00, 0xb1100100); /* uart0_enable */ ++ au_writel(0x00, 0xb1200100); /* uart1_enable */ ++ au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ ++ au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ ++ au_writel(0x00, 0xb1900028); /* sys_clksrc */ ++ au_writel(0x10, 0xb1900060); /* sys_cpupll */ ++ au_writel(0x00, 0xb1900064); /* sys_auxpll */ ++ au_writel(0x00, 0xb1900100); /* sys_pininputen */ ++ break; + + default: + break; +@@ -163,32 +181,23 @@ + + void au1000_halt(void) + { +-#if defined(CONFIG_MIPS_PB1550) +- /* power off system */ +- printk("\n** Powering off Pb1550\n"); +- au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C); +- au_sync(); +- while(1); /* should not get here */ +-#endif +- printk(KERN_NOTICE "\n** You can safely turn off the power\n"); +-#ifdef CONFIG_MIPS_MIRAGE +- au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT); +-#endif +-#ifdef CONFIG_PM +- au_sleep(); +- +- /* should not get here */ +- printk(KERN_ERR "Unable to put cpu in sleep mode\n"); +- while(1); +-#else +- while (1) ++ /* Use WAIT in a low-power infinite spin loop */ ++ while (1) { + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +-#endif ++ } + } + + void au1000_power_off(void) + { ++ extern void board_power_off (void); ++ ++ printk(KERN_NOTICE "\n** You can safely turn off the power\n"); ++ ++ /* Give board a chance to power-off */ ++ board_power_off(); ++ ++ /* If board can't power-off, spin forever */ + au1000_halt(); + } +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/setup.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/setup.c 2005-01-30 09:01:27.000000000 +0100 +@@ -174,6 +174,40 @@ + initrd_end = (unsigned long)&__rd_end; + #endif + ++#if defined(CONFIG_SOC_AU1200) ++#ifdef CONFIG_USB_EHCI_HCD ++ if ((argptr = strstr(argptr, "usb_ehci=")) == NULL) { ++ char usb_args[80]; ++ argptr = prom_getcmdline(); ++ memset(usb_args, 0, sizeof(usb_args)); ++ sprintf(usb_args, " usb_ehci=base:0x%x,len:0x%x,irq:%d", ++ USB_EHCI_BASE, USB_EHCI_LEN, AU1000_USB_HOST_INT); ++ strcat(argptr, usb_args); ++ } ++#ifdef CONFIG_USB_AMD5536UDC ++ /* enable EHC + OHC + UDC clocks, memory and bus mastering */ ++/* au_writel( 0x00DF207F, USB_MSR_BASE + 4); */ ++ au_writel( 0xC0DF207F, USB_MSR_BASE + 4); // incl. prefetch ++#else ++ /* enable EHC + OHC clocks, memory and bus mastering */ ++/* au_writel( 0x00DB200F, USB_MSR_BASE + 4); */ ++ au_writel( 0xC0DB200F, USB_MSR_BASE + 4); /* incl. prefetch */ ++#endif ++ udelay(1000); ++ ++#else /* CONFIG_USB_EHCI_HCD */ ++ ++#ifdef CONFIG_USB_AMD5536UDC ++#ifndef CONFIG_USB_OHCI ++ /* enable UDC clocks, memory and bus mastering */ ++/* au_writel( 0x00DC2070, USB_MSR_BASE + 4); */ ++ au_writel( 0xC0DC2070, USB_MSR_BASE + 4); // incl. prefetch ++ udelay(1000); ++#endif ++#endif ++#endif /* CONFIG_USB_EHCI_HCD */ ++#endif /* CONFIG_SOC_AU1200 */ ++ + #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + #ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { +@@ -187,19 +221,38 @@ + #endif + + #ifdef CONFIG_USB_OHCI +- // enable host controller and wait for reset done ++#if defined(CONFIG_SOC_AU1200) ++#ifndef CONFIG_USB_EHCI_HCD ++#ifdef CONFIG_USB_AMD5536UDC ++ /* enable OHC + UDC clocks, memory and bus mastering */ ++/* au_writel( 0x00DD2073, USB_MSR_BASE + 4); */ ++ au_writel( 0xC0DD2073, USB_MSR_BASE + 4); // incl. prefetch ++#else ++ /* enable OHC clocks, memory and bus mastering */ ++ au_writel( 0x00D12003, USB_MSR_BASE + 4); ++#endif ++ udelay(1000); ++printk("DEBUG: Reading Au1200 USB2 reg 0x%x\n", au_readl(USB_MSR_BASE + 4)); ++#endif ++#else ++ /* Au1000, Au1500, Au1100, Au1550 */ ++ /* enable host controller and wait for reset done */ + au_writel(0x08, USB_HOST_CONFIG); + udelay(1000); + au_writel(0x0E, USB_HOST_CONFIG); + udelay(1000); +- au_readl(USB_HOST_CONFIG); // throw away first read ++ au_readl(USB_HOST_CONFIG); /* throw away first read */ + while (!(au_readl(USB_HOST_CONFIG) & 0x10)) + au_readl(USB_HOST_CONFIG); ++#endif /* CONFIG_SOC_AU1200 */ + #endif +-#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) ++#else ++ ++#endif /* defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) */ ++ + + #ifdef CONFIG_FB +- // Needed if PCI video card in use ++ /* Needed if PCI video card in use */ + conswitchp = &dummy_con; + #endif + +@@ -209,8 +262,7 @@ + #endif + + #ifdef CONFIG_BLK_DEV_IDE +- /* Board setup takes precedence for unique devices. +- */ ++ /* Board setup takes precedence for unique devices. */ + if ((ide_ops == NULL) || (ide_ops == &no_ide_ops)) + ide_ops = &std_ide_ops; + #endif +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/sleeper.S linux-2.4.32-rc1.mips/arch/mips/au1000/common/sleeper.S +--- linux-2.4.32-rc1/arch/mips/au1000/common/sleeper.S 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/sleeper.S 2005-01-30 09:01:27.000000000 +0100 +@@ -15,17 +15,48 @@ + #include + #include + #include ++#include ++ ++/* ++ * Note: This file is *not* conditional on CONFIG_PM since Alchemy sleep ++ * need not be tied to any particular power management scheme. ++ */ ++ ++ .extern ___flush_cache_all + + .text +- .set macro +- .set noat + .align 5 + +-/* Save all of the processor general registers and go to sleep. +- * A wakeup condition will get us back here to restore the registers. ++/* ++ * Save the processor general registers and go to sleep. A wakeup ++ * condition will get us back here to restore the registers. + */ +-LEAF(save_and_sleep) + ++/* still need to fix alignment issues here */ ++save_and_sleep_frmsz = 48 ++NESTED(save_and_sleep, save_and_sleep_frmsz, ra) ++ .set noreorder ++ .set nomacro ++ .set noat ++ subu sp, save_and_sleep_frmsz ++ sw ra, save_and_sleep_frmsz-4(sp) ++ sw s0, save_and_sleep_frmsz-8(sp) ++ sw s1, save_and_sleep_frmsz-12(sp) ++ sw s2, save_and_sleep_frmsz-16(sp) ++ sw s3, save_and_sleep_frmsz-20(sp) ++ sw s4, save_and_sleep_frmsz-24(sp) ++ sw s5, save_and_sleep_frmsz-28(sp) ++ sw s6, save_and_sleep_frmsz-32(sp) ++ sw s7, save_and_sleep_frmsz-36(sp) ++ sw s8, save_and_sleep_frmsz-40(sp) ++ sw gp, save_and_sleep_frmsz-44(sp) ++ ++ /* We only need to save the registers that the calling function ++ * hasn't saved for us. 0 is always zero. 8 - 15, 24 and 25 are ++ * temporaries and can be used without saving. 26 and 27 are reserved ++ * for interrupt/trap handling and expected to change. 29 is the ++ * stack pointer which is handled as a special case here. ++ */ + subu sp, PT_SIZE + sw $1, PT_R1(sp) + sw $2, PT_R2(sp) +@@ -34,14 +65,6 @@ + sw $5, PT_R5(sp) + sw $6, PT_R6(sp) + sw $7, PT_R7(sp) +- sw $8, PT_R8(sp) +- sw $9, PT_R9(sp) +- sw $10, PT_R10(sp) +- sw $11, PT_R11(sp) +- sw $12, PT_R12(sp) +- sw $13, PT_R13(sp) +- sw $14, PT_R14(sp) +- sw $15, PT_R15(sp) + sw $16, PT_R16(sp) + sw $17, PT_R17(sp) + sw $18, PT_R18(sp) +@@ -50,32 +73,47 @@ + sw $21, PT_R21(sp) + sw $22, PT_R22(sp) + sw $23, PT_R23(sp) +- sw $24, PT_R24(sp) +- sw $25, PT_R25(sp) +- sw $26, PT_R26(sp) +- sw $27, PT_R27(sp) + sw $28, PT_R28(sp) +- sw $29, PT_R29(sp) + sw $30, PT_R30(sp) + sw $31, PT_R31(sp) ++#define PT_C0STATUS PT_LO ++#define PT_CONTEXT PT_HI ++#define PT_PAGEMASK PT_EPC ++#define PT_CONFIG PT_BVADDR + mfc0 k0, CP0_STATUS +- sw k0, 0x20(sp) ++ sw k0, PT_C0STATUS(sp) // 0x20 + mfc0 k0, CP0_CONTEXT +- sw k0, 0x1c(sp) ++ sw k0, PT_CONTEXT(sp) // 0x1c + mfc0 k0, CP0_PAGEMASK +- sw k0, 0x18(sp) ++ sw k0, PT_PAGEMASK(sp) // 0x18 + mfc0 k0, CP0_CONFIG +- sw k0, 0x14(sp) ++ sw k0, PT_CONFIG(sp) // 0x14 ++ ++ .set macro ++ .set at ++ ++ li t0, SYS_SLPPWR ++ sw zero, 0(t0) /* Get the processor ready to sleep */ ++ sync + + /* Now set up the scratch registers so the boot rom will + * return to this point upon wakeup. ++ * sys_scratch0 : SP ++ * sys_scratch1 : RA ++ */ ++ li t0, SYS_SCRATCH0 ++ li t1, SYS_SCRATCH1 ++ sw sp, 0(t0) ++ la k0, resume_from_sleep ++ sw k0, 0(t1) ++ ++/* ++ * Flush DCACHE to make sure context is in memory + */ +- la k0, 1f +- lui k1, 0xb190 +- ori k1, 0x18 +- sw sp, 0(k1) +- ori k1, 0x1c +- sw k0, 0(k1) ++ la t1,___flush_cache_all /* _flush_cache_all is a function pointer */ ++ lw t0,0(t1) ++ jal t0 ++ nop + + /* Put SDRAM into self refresh. Preload instructions into cache, + * issue a precharge, then auto refresh, then sleep commands to it. +@@ -88,30 +126,65 @@ + cache 0x14, 96(t0) + .set mips0 + ++ /* Put SDRAM to sleep */ + sdsleep: +- lui k0, 0xb400 +- sw zero, 0x001c(k0) /* Precharge */ +- sw zero, 0x0020(k0) /* Auto refresh */ +- sw zero, 0x0030(k0) /* SDRAM sleep */ ++ li a0, MEM_PHYS_ADDR ++ or a0, a0, 0xA0000000 ++#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1500) ++ lw k0, MEM_SDMODE0(a0) ++ sw zero, MEM_SDPRECMD(a0) /* Precharge */ ++ sw zero, MEM_SDAUTOREF(a0) /* Auto Refresh */ ++ sw zero, MEM_SDSLEEP(a0) /* Sleep */ + sync +- +- lui k1, 0xb190 +- sw zero, 0x0078(k1) /* get ready to sleep */ ++#endif ++#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) ++ sw zero, MEM_SDPRECMD(a0) /* Precharge */ ++ sw zero, MEM_SDSREF(a0) ++ ++ #lw t0, MEM_SDSTAT(a0) ++ #and t0, t0, 0x01000000 ++ li t0, 0x01000000 ++refresh_not_set: ++ lw t1, MEM_SDSTAT(a0) ++ and t2, t1, t0 ++ beq zero, t2, refresh_not_set ++ nop ++ ++ li t0, ~0x30000000 ++ lw t1, MEM_SDCONFIGA(a0) ++ and t1, t0, t1 ++ sw t1, MEM_SDCONFIGA(a0) + sync +- sw zero, 0x007c(k1) /* Put processor to sleep */ ++#endif ++ ++ li t0, SYS_SLEEP ++ sw zero, 0(t0) /* Put processor to sleep */ + sync ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ + + /* This is where we return upon wakeup. + * Reload all of the registers and return. + */ +-1: nop +- lw k0, 0x20(sp) ++resume_from_sleep: ++ nop ++ .set nomacro ++ .set noat ++ ++ lw k0, PT_C0STATUS(sp) // 0x20 + mtc0 k0, CP0_STATUS +- lw k0, 0x1c(sp) ++ lw k0, PT_CONTEXT(sp) // 0x1c + mtc0 k0, CP0_CONTEXT +- lw k0, 0x18(sp) ++ lw k0, PT_PAGEMASK(sp) // 0x18 + mtc0 k0, CP0_PAGEMASK +- lw k0, 0x14(sp) ++ lw k0, PT_CONFIG(sp) // 0x14 + mtc0 k0, CP0_CONFIG + lw $1, PT_R1(sp) + lw $2, PT_R2(sp) +@@ -120,14 +193,6 @@ + lw $5, PT_R5(sp) + lw $6, PT_R6(sp) + lw $7, PT_R7(sp) +- lw $8, PT_R8(sp) +- lw $9, PT_R9(sp) +- lw $10, PT_R10(sp) +- lw $11, PT_R11(sp) +- lw $12, PT_R12(sp) +- lw $13, PT_R13(sp) +- lw $14, PT_R14(sp) +- lw $15, PT_R15(sp) + lw $16, PT_R16(sp) + lw $17, PT_R17(sp) + lw $18, PT_R18(sp) +@@ -136,15 +201,36 @@ + lw $21, PT_R21(sp) + lw $22, PT_R22(sp) + lw $23, PT_R23(sp) +- lw $24, PT_R24(sp) +- lw $25, PT_R25(sp) +- lw $26, PT_R26(sp) +- lw $27, PT_R27(sp) + lw $28, PT_R28(sp) +- lw $29, PT_R29(sp) + lw $30, PT_R30(sp) + lw $31, PT_R31(sp) ++ ++ .set macro ++ .set at ++ ++ /* clear the wake source, but save it as the return value of the function */ ++ li t0, SYS_WAKESRC ++ lw v0, 0(t0) ++ sw v0, PT_R2(sp) ++ sw zero, 0(t0) ++ + addiu sp, PT_SIZE + ++ lw gp, save_and_sleep_frmsz-44(sp) ++ lw s8, save_and_sleep_frmsz-40(sp) ++ lw s7, save_and_sleep_frmsz-36(sp) ++ lw s6, save_and_sleep_frmsz-32(sp) ++ lw s5, save_and_sleep_frmsz-28(sp) ++ lw s4, save_and_sleep_frmsz-24(sp) ++ lw s3, save_and_sleep_frmsz-20(sp) ++ lw s2, save_and_sleep_frmsz-16(sp) ++ lw s1, save_and_sleep_frmsz-12(sp) ++ lw s0, save_and_sleep_frmsz-8(sp) ++ lw ra, save_and_sleep_frmsz-4(sp) ++ ++ addu sp, save_and_sleep_frmsz + jr ra ++ nop ++ .set reorder + END(save_and_sleep) ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/time.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/time.c +--- linux-2.4.32-rc1/arch/mips/au1000/common/time.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/time.c 2005-04-08 10:33:17.000000000 +0200 +@@ -50,7 +50,6 @@ + #include + #include + +-extern void startup_match20_interrupt(void); + extern void do_softirq(void); + extern volatile unsigned long wall_jiffies; + unsigned long missed_heart_beats = 0; +@@ -59,14 +58,14 @@ + static unsigned long r4k_cur; /* What counter should be at next timer irq */ + extern rwlock_t xtime_lock; + int no_au1xxx_32khz; +-void (*au1k_wait_ptr)(void); ++extern int allow_au1k_wait; /* default off for CP0 Counter */ + + /* Cycle counter value at the previous timer interrupt.. */ + static unsigned int timerhi = 0, timerlo = 0; + + #ifdef CONFIG_PM + #define MATCH20_INC 328 +-extern void startup_match20_interrupt(void); ++extern void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *)); + static unsigned long last_pc0, last_match20; + #endif + +@@ -385,7 +384,6 @@ + { + unsigned int est_freq; + extern unsigned long (*do_gettimeoffset)(void); +- extern void au1k_wait(void); + + printk("calculating r4koff... "); + r4k_offset = cal_r4koff(); +@@ -437,9 +435,6 @@ + au_writel(0, SYS_TOYWRITE); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + +- au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); +- au_writel(~0, SYS_WAKESRC); +- au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + + /* setup match20 to interrupt once every 10ms */ +@@ -447,13 +442,13 @@ + au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); +- startup_match20_interrupt(); ++ startup_match20_interrupt(counter0_irq); + + do_gettimeoffset = do_fast_pm_gettimeoffset; + + /* We can use the real 'wait' instruction. + */ +- au1k_wait_ptr = au1k_wait; ++ allow_au1k_wait = 1; + } + + #else +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/db1x00/board_setup.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -46,10 +46,22 @@ + #include + #include + +-extern struct rtc_ops no_rtc_ops; ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) && defined(CONFIG_MIPS_DB1550) ++#include ++extern struct ide_ops *ide_ops; ++extern struct ide_ops au1xxx_ide_ops; ++extern u32 au1xxx_ide_virtbase; ++extern u64 au1xxx_ide_physbase; ++extern int au1xxx_ide_irq; ++ ++/* Ddma */ ++chan_tab_t *ide_read_ch, *ide_write_ch; ++u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma ++ ++dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }; ++#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */ + +-/* not correct for db1550 */ +-static BCSR * const bcsr = (BCSR *)0xAE000000; ++extern struct rtc_ops no_rtc_ops; + + void board_reset (void) + { +@@ -57,6 +69,13 @@ + au_writel(0x00000000, 0xAE00001C); + } + ++void board_power_off (void) ++{ ++#ifdef CONFIG_MIPS_MIRAGE ++ au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT); ++#endif ++} ++ + void __init board_setup(void) + { + u32 pin_func; +@@ -108,8 +127,42 @@ + au_writel(0x02000200, GPIO2_OUTPUT); + #endif + ++#if defined(CONFIG_AU1XXX_SMC91111) ++#define CPLD_CONTROL (0xAF00000C) ++ { ++ extern uint32_t au1xxx_smc91111_base; ++ extern unsigned int au1xxx_smc91111_irq; ++ extern int au1xxx_smc91111_nowait; ++ ++ au1xxx_smc91111_base = 0xAC000300; ++ au1xxx_smc91111_irq = AU1000_GPIO_8; ++ au1xxx_smc91111_nowait = 1; ++ ++ /* set up the Static Bus timing - only 396Mhz */ ++ bcsr->resets |= 0x7; ++ au_writel(0x00010003, MEM_STCFG0); ++ au_writel(0x000c00c0, MEM_STCFG2); ++ au_writel(0x85E1900D, MEM_STTIME2); ++ } ++#endif /* end CONFIG_SMC91111 */ + au_sync(); + ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) && defined(CONFIG_MIPS_DB1550) ++ /* ++ * Iniz IDE parameters ++ */ ++ ide_ops = &au1xxx_ide_ops; ++ au1xxx_ide_irq = DAUGHTER_CARD_IRQ; ++ au1xxx_ide_physbase = AU1XXX_ATA_PHYS_ADDR; ++ au1xxx_ide_virtbase = KSEG1ADDR(AU1XXX_ATA_PHYS_ADDR); ++ ++ /* ++ * change PIO or PIO+Ddma ++ * check the GPIO-6 pin condition. db1550:s6_dot ++ */ ++ switch4ddma = (au_readl(SYS_PINSTATERD) & (1 << 6)) ? 1 : 0; ++#endif ++ + #ifdef CONFIG_MIPS_DB1000 + printk("AMD Alchemy Au1000/Db1000 Board\n"); + #endif +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/irqmap.c +--- linux-2.4.32-rc1/arch/mips/au1000/db1x00/irqmap.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/irqmap.c 2005-01-30 09:06:19.000000000 +0100 +@@ -53,6 +53,7 @@ + #ifdef CONFIG_MIPS_DB1550 + { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ# + { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ# ++ { AU1000_GPIO_8, INTC_INT_LOW_LEVEL, 0 }, // Daughtercard IRQ# + #else + { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 Fully_Interted# + { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 STSCHG# +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/Makefile +--- linux-2.4.32-rc1/arch/mips/au1000/db1x00/Makefile 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/Makefile 2005-01-30 09:06:19.000000000 +0100 +@@ -17,4 +17,11 @@ + obj-y := init.o board_setup.o irqmap.o + obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o + ++ifdef CONFIG_MIPS_DB1100 ++ifdef CONFIG_MMC ++obj-y += mmc_support.o ++export-objs += mmc_support.o ++endif ++endif ++ + include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/mmc_support.c linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/mmc_support.c +--- linux-2.4.32-rc1/arch/mips/au1000/db1x00/mmc_support.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/mmc_support.c 2005-01-30 09:07:01.000000000 +0100 +@@ -0,0 +1,126 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * ++ * MMC support routines for DB1100. ++ * ++ * ++ * Copyright (c) 2003-2004 Embedded Edge, LLC. ++ * Author: Embedded Edge, LLC. ++ * Contact: dan@embeddededge.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* SD/MMC controller support functions */ ++ ++/* ++ * Detect card. ++ */ ++void mmc_card_inserted(int _n_, int *_res_) ++{ ++ u32 gpios = au_readl(SYS_PINSTATERD); ++ u32 emptybit = (_n_) ? (1<<20) : (1<<19); ++ *_res_ = ((gpios & emptybit) == 0); ++} ++ ++/* ++ * Check card write protection. ++ */ ++void mmc_card_writable(int _n_, int *_res_) ++{ ++ BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ unsigned long mmc_wp, board_specific; ++ ++ if (_n_) { ++ mmc_wp = BCSR_BOARD_SD1_WP; ++ } else { ++ mmc_wp = BCSR_BOARD_SD0_WP; ++ } ++ ++ board_specific = au_readl((unsigned long)(&bcsr->specific)); ++ ++ if (!(board_specific & mmc_wp)) {/* low means card writable */ ++ *_res_ = 1; ++ } else { ++ *_res_ = 0; ++ } ++} ++ ++/* ++ * Apply power to card slot. ++ */ ++void mmc_power_on(int _n_) ++{ ++ BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ unsigned long mmc_pwr, board_specific; ++ ++ if (_n_) { ++ mmc_pwr = BCSR_BOARD_SD1_PWR; ++ } else { ++ mmc_pwr = BCSR_BOARD_SD0_PWR; ++ } ++ ++ board_specific = au_readl((unsigned long)(&bcsr->specific)); ++ board_specific |= mmc_pwr; ++ ++ au_writel(board_specific, (int)(&bcsr->specific)); ++ au_sync_delay(1); ++} ++ ++/* ++ * Remove power from card slot. ++ */ ++void mmc_power_off(int _n_) ++{ ++ BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ unsigned long mmc_pwr, board_specific; ++ ++ if (_n_) { ++ mmc_pwr = BCSR_BOARD_SD1_PWR; ++ } else { ++ mmc_pwr = BCSR_BOARD_SD0_PWR; ++ } ++ ++ board_specific = au_readl((unsigned long)(&bcsr->specific)); ++ board_specific &= ~mmc_pwr; ++ ++ au_writel(board_specific, (int)(&bcsr->specific)); ++ au_sync_delay(1); ++} ++ ++EXPORT_SYMBOL(mmc_card_inserted); ++EXPORT_SYMBOL(mmc_card_writable); ++EXPORT_SYMBOL(mmc_power_on); ++EXPORT_SYMBOL(mmc_power_off); ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/au1200_ibutton.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/au1200_ibutton.c +--- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/au1200_ibutton.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/au1200_ibutton.c 2005-02-03 07:35:29.000000000 +0100 +@@ -0,0 +1,270 @@ ++/* ---------------------------------------------------------------------- ++ * mtwilson_keys.c ++ * ++ * Copyright (C) 2003 Intrinsyc Software Inc. ++ * ++ * Intel Personal Media Player buttons ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * May 02, 2003 : Initial version [FB] ++ * ++ ------------------------------------------------------------------------*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_VERSION "V1.0" ++#define DRIVER_AUTHOR "FIC" ++#define DRIVER_DESC "FIC Travis Media Player Button Driver" ++#define DRIVER_NAME "Au1200Button" ++ ++#define BUTTON_MAIN (1<<1) ++#define BUTTON_SELECT (1<<6) ++#define BUTTON_GUIDE (1<<12) ++#define BUTTON_DOWN (1<<17) ++#define BUTTON_LEFT (1<<19) ++#define BUTTON_RIGHT (1<<26) ++#define BUTTON_UP (1<<28) ++ ++#define BUTTON_MASK (\ ++ BUTTON_MAIN \ ++ | BUTTON_SELECT \ ++ | BUTTON_GUIDE \ ++ | BUTTON_DOWN \ ++ | BUTTON_LEFT \ ++ | BUTTON_RIGHT \ ++ | BUTTON_UP \ ++ ) ++ ++#define BUTTON_INVERT (\ ++ BUTTON_MAIN \ ++ | 0 \ ++ | BUTTON_GUIDE \ ++ | 0 \ ++ | 0 \ ++ | 0 \ ++ | 0 \ ++ ) ++ ++char button_map[32]={0,KEY_S,0,0,0,0,KEY_ENTER,0,0,0,0,0,KEY_G,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0}; ++//char button_map[32]={0,0,0,0,0,0,KEY_ENTER,0,0,0,0,0,KEY_G,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0}; ++ ++//char button_map[32]={0,KEY_TAB,0,0,0,0,KEY_M,0,0,0,0,0,KEY_S,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0}; ++//char button_map[32]={0,0,0,0,0,0,KEY_M,0,0,0,0,0,KEY_S,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0}; ++ ++#define BUTTON_COUNT (sizeof (button_map) / sizeof (button_map[0])) ++ ++struct input_dev dev; ++struct timeval cur_tv; ++ ++static unsigned int old_tv_usec = 0; ++ ++static unsigned int read_button_state(void) ++{ ++ unsigned int state; ++ ++ state = au_readl(SYS_PINSTATERD) & BUTTON_MASK; /* get gpio status */ ++ ++ state ^= BUTTON_INVERT; /* invert main & guide button */ ++ ++ /* printk("au1200_ibutton.c: button state [0x%X]\r\n",state); */ ++ return state; ++} ++ ++//This function returns 0 if the allowed microseconds have elapsed since the last call to ths function, otherwise it returns 1 to indicate a bounce condition ++static unsigned int bounce() ++{ ++ ++ unsigned int elapsed_time; ++ ++ do_gettimeofday (&cur_tv); ++ ++ if (!old_tv_usec) { ++ old_tv_usec = cur_tv.tv_usec; ++ return 0; ++ } ++ ++ if(cur_tv.tv_usec > old_tv_usec) { ++ /* If there hasn't been rollover */ ++ elapsed_time = ((cur_tv.tv_usec - old_tv_usec)); ++ } ++ else { ++ /* Accounting for rollover */ ++ elapsed_time = ((1000000 - old_tv_usec + cur_tv.tv_usec)); ++ } ++ ++ if (elapsed_time > 250000) { ++ old_tv_usec = 0; /* reset the bounce time */ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* button interrupt handler */ ++static void button_interrupt(int irq, void *dev, struct pt_regs *regs) ++{ ++ ++ unsigned int i,bit_mask, key_choice; ++ u32 button_state; ++ ++ /* Report state to upper level */ ++ ++ button_state = read_button_state() & BUTTON_MASK; /* get new gpio status */ ++ ++ /* Return if this is a repeated (bouncing) event */ ++ if(bounce()) ++ return; ++ ++ /* we want to make keystrokes */ ++ for( i=0; i< BUTTON_COUNT; i++) { ++ bit_mask = 1< ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#if defined(CONFIG_MIPS_FICMMP) ++ #define DOCK_GPIO 215 ++#else ++ #error Unsupported Au1xxx Platform ++#endif ++ ++#define MAKE_FLAG 0x20 ++ ++#undef DEBUG ++ ++#define DEBUG 0 ++//#define DEBUG 1 ++ ++#if DEBUG ++#define DPRINTK(format, args...) printk(__FUNCTION__ ": " format, ## args) ++#else ++#define DPRINTK(format, args...) do { } while (0) ++#endif ++ ++/* Please note that this driver is based on a timer and is not interrupt ++ * driven. If you are going to make use of this driver, you will need to have ++ * your application open the dock listing from the /dev directory first. ++ */ ++ ++struct au1xxx_dock { ++ struct fasync_struct *fasync; ++ wait_queue_head_t read_wait; ++ int open_count; ++ unsigned int debounce; ++ unsigned int current; ++ unsigned int last; ++}; ++ ++static struct au1xxx_dock dock_info; ++ ++ ++static void dock_timer_periodic(void *data); ++ ++static struct tq_struct dock_task = { ++ routine: dock_timer_periodic, ++ data: NULL ++}; ++ ++static int cleanup_flag = 0; ++static DECLARE_WAIT_QUEUE_HEAD(cleanup_wait_queue); ++ ++ ++static unsigned int read_dock_state(void) ++{ ++ u32 state; ++ ++ state = au1xxx_gpio_read(DOCK_GPIO); ++ ++ /* printk( "Current Dock State: %d\n", state ); */ ++ ++ return state; ++} ++ ++ ++static void dock_timer_periodic(void *data) ++{ ++ struct au1xxx_dock *dock = (struct au1xxx_dock *)data; ++ unsigned long dock_state; ++ ++ /* If cleanup wants us to die */ ++ if (cleanup_flag) { ++ /* now cleanup_module can return */ ++ wake_up(&cleanup_wait_queue); ++ } else { ++ /* put ourselves back in the task queue */ ++ queue_task(&dock_task, &tq_timer); ++ } ++ ++ /* read current dock */ ++ dock_state = read_dock_state(); ++ ++ /* if dock states hasn't changed */ ++ /* save time and be done. */ ++ if (dock_state == dock->current) { ++ return; ++ } ++ ++ if (dock_state == dock->debounce) { ++ dock->current = dock_state; ++ } else { ++ dock->debounce = dock_state; ++ } ++ if (dock->current != dock->last) { ++ if (waitqueue_active(&dock->read_wait)) { ++ wake_up_interruptible(&dock->read_wait); ++ } ++ } ++} ++ ++ ++static ssize_t au1xxx_dock_read(struct file *filp, char *buffer, size_t count, loff_t *ppos) ++{ ++ struct au1xxx_dock *dock = filp->private_data; ++ char event[3]; ++ int last; ++ int cur; ++ int err; ++ ++try_again: ++ ++ while (dock->current == dock->last) { ++ if (filp->f_flags & O_NONBLOCK) { ++ return -EAGAIN; ++ } ++ interruptible_sleep_on(&dock->read_wait); ++ if (signal_pending(current)) { ++ return -ERESTARTSYS; ++ } ++ } ++ ++ cur = dock->current; ++ last = dock->last; ++ ++ if(cur != last) ++ { ++ event[0] = cur ? 'D' : 'U'; ++ event[1] = '\r'; ++ event[2] = '\n'; ++ } ++ else ++ goto try_again; ++ ++ dock->last = cur; ++ err = copy_to_user(buffer, &event, 3); ++ if (err) { ++ return err; ++ } ++ ++ return 3; ++} ++ ++ ++static int au1xxx_dock_open(struct inode *inode, struct file *filp) ++{ ++ struct au1xxx_dock *dock = &dock_info; ++ ++ MOD_INC_USE_COUNT; ++ ++ filp->private_data = dock; ++ ++ if (dock->open_count++ == 0) { ++ dock_task.data = dock; ++ cleanup_flag = 0; ++ queue_task(&dock_task, &tq_timer); ++ } ++ ++ return 0; ++} ++ ++ ++static unsigned int au1xxx_dock_poll(struct file *filp, poll_table *wait) ++{ ++ struct au1xxx_dock *dock = filp->private_data; ++ int ret = 0; ++ ++ DPRINTK("start\n"); ++ poll_wait(filp, &dock->read_wait, wait); ++ if (dock->current != dock->last) { ++ ret = POLLIN | POLLRDNORM; ++ } ++ return ret; ++} ++ ++ ++static int au1xxx_dock_release(struct inode *inode, struct file *filp) ++{ ++ struct au1xxx_dock *dock = filp->private_data; ++ ++ DPRINTK("start\n"); ++ ++ if (--dock->open_count == 0) { ++ cleanup_flag = 1; ++ sleep_on(&cleanup_wait_queue); ++ } ++ MOD_DEC_USE_COUNT; ++ ++ return 0; ++} ++ ++ ++ ++static struct file_operations au1xxx_dock_fops = { ++ owner: THIS_MODULE, ++ read: au1xxx_dock_read, ++ poll: au1xxx_dock_poll, ++ open: au1xxx_dock_open, ++ release: au1xxx_dock_release, ++}; ++ ++/* ++ * The au1xxx dock is a misc device: ++ * Major 10 char ++ * Minor 22 /dev/dock ++ * ++ * This is /dev/misc/dock if devfs is used. ++ */ ++ ++static struct miscdevice au1xxx_dock_dev = { ++ minor: 23, ++ name: "dock", ++ fops: &au1xxx_dock_fops, ++}; ++ ++static int __init au1xxx_dock_init(void) ++{ ++ struct au1xxx_dock *dock = &dock_info; ++ int ret; ++ ++ DPRINTK("Initializing dock driver\n"); ++ dock->open_count = 0; ++ cleanup_flag = 0; ++ init_waitqueue_head(&dock->read_wait); ++ ++ ++ /* yamon configures GPIO pins for the dock ++ * no initialization needed ++ */ ++ ++ ret = misc_register(&au1xxx_dock_dev); ++ ++ DPRINTK("dock driver fully initialized.\n"); ++ ++ return ret; ++} ++ ++ ++static void __exit au1xxx_dock_exit(void) ++{ ++ DPRINTK("unloading dock driver\n"); ++ misc_deregister(&au1xxx_dock_dev); ++} ++ ++ ++module_init(au1xxx_dock_init); ++module_exit(au1xxx_dock_exit); +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/board_setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -0,0 +1,226 @@ ++/* ++ * ++ * BRIEF MODULE DESCRIPTION ++ * Alchemy Pb1200 board setup. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern struct rtc_ops no_rtc_ops; ++ ++/* value currently in the board configuration register */ ++u16 ficmmp_config = 0; ++ ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) ++extern struct ide_ops *ide_ops; ++extern struct ide_ops au1xxx_ide_ops; ++extern u32 au1xxx_ide_virtbase; ++extern u64 au1xxx_ide_physbase; ++extern int au1xxx_ide_irq; ++ ++u32 led_base_addr; ++/* Ddma */ ++chan_tab_t *ide_read_ch, *ide_write_ch; ++u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma ++ ++dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }; ++#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */ ++ ++void board_reset (void) ++{ ++ au_writel(0, 0xAD80001C); ++} ++ ++void board_power_off (void) ++{ ++} ++ ++void __init board_setup(void) ++{ ++ char *argptr = NULL; ++ u32 pin_func; ++ rtc_ops = &no_rtc_ops; ++ ++ ficmmp_config_init(); //Initialize FIC control register ++ ++#if 0 ++ /* Enable PSC1 SYNC for AC97. Normaly done in audio driver, ++ * but it is board specific code, so put it here. ++ */ ++ pin_func = au_readl(SYS_PINFUNC); ++ au_sync(); ++ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1; ++ au_writel(pin_func, SYS_PINFUNC); ++ ++ au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ ++ au_sync(); ++#endif ++ ++#if defined( CONFIG_I2C_ALGO_AU1550 ) ++ { ++ u32 freq0, clksrc; ++ ++ /* Select SMBUS in CPLD */ ++ /* bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); */ ++ ++ pin_func = au_readl(SYS_PINFUNC); ++ au_sync(); ++ pin_func &= ~(3<<17 | 1<<4); ++ /* Set GPIOs correctly */ ++ pin_func |= 2<<17; ++ au_writel(pin_func, SYS_PINFUNC); ++ au_sync(); ++ ++ /* The i2c driver depends on 50Mhz clock */ ++ freq0 = au_readl(SYS_FREQCTRL0); ++ au_sync(); ++ freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1); ++ freq0 |= (3<resets bit 12: 0=SMB 1=SPI ++ */ ++#if defined(CONFIG_AU1550_PSC_SPI) && defined(CONFIG_I2C_ALGO_AU1550) ++ #error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\ ++ Refer to Pb1200 documentation. ++#elif defined( CONFIG_AU1550_PSC_SPI ) ++ //bcsr->resets |= BCSR_RESETS_PCS0MUX; ++#elif defined( CONFIG_I2C_ALGO_AU1550 ) ++ //bcsr->resets &= (~BCSR_RESETS_PCS0MUX); ++#endif ++ au_sync(); ++ ++ printk("FIC Multimedia Player Board\n"); ++ au1xxx_gpio_tristate(5); ++ printk("B1900100: %X\n", *((volatile u32*)0xB1900100)); ++ printk("B190002C: %X\n", *((volatile u32*)0xB190002C)); ++} ++ ++int ++board_au1200fb_panel (void) ++{ ++ au1xxx_gpio_tristate(6); ++ ++ if (au1xxx_gpio_read(12) == 0) ++ return 9; /* FS453_640x480 (Composite/S-Video) */ ++ else ++ return 7; /* Sharp 320x240 TFT */ ++} ++ ++int ++board_au1200fb_panel_init (void) ++{ ++ /*Enable data buffers*/ ++ ficmmp_config_clear(FICMMP_CONFIG_LCMDATAOUT); ++ /*Take LCD out of reset*/ ++ ficmmp_config_set(FICMMP_CONFIG_LCMPWREN | FICMMP_CONFIG_LCMEN); ++ return 0; ++} ++ ++int ++board_au1200fb_panel_shutdown (void) ++{ ++ /*Disable data buffers*/ ++ ficmmp_config_set(FICMMP_CONFIG_LCMDATAOUT); ++ /*Put LCD in reset, remove power*/ ++ ficmmp_config_clear(FICMMP_CONFIG_LCMEN | FICMMP_CONFIG_LCMPWREN); ++ return 0; ++} ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/init.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/init.c +--- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/init.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/init.c 2005-01-30 09:01:27.000000000 +0100 +@@ -0,0 +1,76 @@ ++/* ++ * ++ * BRIEF MODULE DESCRIPTION ++ * PB1200 board setup ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int prom_argc; ++char **prom_argv, **prom_envp; ++extern void __init prom_init_cmdline(void); ++extern char *prom_getenv(char *envname); ++ ++const char *get_system_type(void) ++{ ++ return "FIC Multimedia Player (Au1200)"; ++} ++ ++u32 mae_memsize = 0; ++ ++int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) ++{ ++ unsigned char *memsize_str; ++ unsigned long memsize; ++ ++ prom_argc = argc; ++ prom_argv = argv; ++ prom_envp = envp; ++ ++ mips_machgroup = MACH_GROUP_ALCHEMY; ++ mips_machtype = MACH_PB1000; /* set the platform # */ ++ prom_init_cmdline(); ++ ++ memsize_str = prom_getenv("memsize"); ++ if (!memsize_str) { ++ memsize = 0x08000000; ++ } else { ++ memsize = simple_strtol(memsize_str, NULL, 0); ++ } ++ ++ /* reserved 32MB for MAE driver */ ++ memsize -= (32 * 1024 * 1024); ++ add_memory_region(0, memsize, BOOT_MEM_RAM); ++ mae_memsize = memsize; /* for drivers/char/au1xxx_mae.c */ ++ return 0; ++} ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/irqmap.c +--- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/irqmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/irqmap.c 2005-01-30 09:01:27.000000000 +0100 +@@ -0,0 +1,61 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * Au1xxx irq map table ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++au1xxx_irq_map_t au1xxx_irq_map[] = { ++ { FICMMP_IDE_INT, INTC_INT_HIGH_LEVEL, 0 }, ++ { AU1XXX_SMC91111_IRQ, INTC_INT_HIGH_LEVEL, 0 }, ++ { AU1000_GPIO_1 , INTC_INT_FALL_EDGE, 0 }, // main button ++ { AU1000_GPIO_6 , INTC_INT_RISE_EDGE, 0 }, // select button ++ { AU1000_GPIO_12, INTC_INT_FALL_EDGE, 0 }, // guide button ++ { AU1000_GPIO_17, INTC_INT_RISE_EDGE, 0 }, // down button ++ { AU1000_GPIO_19, INTC_INT_RISE_EDGE, 0 }, // left button ++ { AU1000_GPIO_26, INTC_INT_RISE_EDGE, 0 }, // right button ++ { AU1000_GPIO_28, INTC_INT_RISE_EDGE, 0 }, // up button ++}; ++ ++int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/Makefile +--- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/Makefile 2005-01-30 09:01:27.000000000 +0100 +@@ -0,0 +1,25 @@ ++# ++# Copyright 2000 MontaVista Software Inc. ++# Author: MontaVista Software, Inc. ++# ppopov@mvista.com or source@mvista.com ++# ++# Makefile for the Alchemy Semiconductor FIC board. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++ ++USE_STANDARD_AS_RULE := true ++ ++O_TARGET := ficmmp.o ++ ++obj-y := init.o board_setup.o irqmap.o au1200_ibutton.o au1xxx_dock.o ++ ++ifdef CONFIG_MMC ++obj-y += mmc_support.o ++export-objs +=mmc_support.o ++endif ++ ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/board_setup.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -51,12 +51,19 @@ + { + } + ++void board_power_off (void) ++{ ++} ++ + void __init board_setup(void) + { + u32 pin_func; + + rtc_ops = &no_rtc_ops; + ++ /* Set GPIO14 high to make CD/DAT1 high for MMC to work */ ++ au_writel(1<<14, SYS_OUTPUTSET); ++ + #ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/buttons.c linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/buttons.c +--- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/buttons.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/buttons.c 2005-02-11 22:09:55.000000000 +0100 +@@ -0,0 +1,308 @@ ++/* ++ * Copyright (C) 2003 Metrowerks, All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define BUTTON_SELECT (1<<1) ++#define BUTTON_1 (1<<2) ++#define BUTTON_2 (1<<3) ++#define BUTTON_ONOFF (1<<6) ++#define BUTTON_3 (1<<7) ++#define BUTTON_4 (1<<8) ++#define BUTTON_LEFT (1<<9) ++#define BUTTON_DOWN (1<<10) ++#define BUTTON_RIGHT (1<<11) ++#define BUTTON_UP (1<<12) ++ ++#define BUTTON_MASK (\ ++ BUTTON_SELECT \ ++ | BUTTON_1 \ ++ | BUTTON_2 \ ++ | BUTTON_ONOFF \ ++ | BUTTON_3 \ ++ | BUTTON_4 \ ++ | BUTTON_LEFT \ ++ | BUTTON_DOWN \ ++ | BUTTON_RIGHT \ ++ | BUTTON_UP \ ++ ) ++ ++#define BUTTON_INVERT (\ ++ BUTTON_SELECT \ ++ | BUTTON_1 \ ++ | BUTTON_2 \ ++ | BUTTON_3 \ ++ | BUTTON_4 \ ++ | BUTTON_LEFT \ ++ | BUTTON_DOWN \ ++ | BUTTON_RIGHT \ ++ | BUTTON_UP \ ++ ) ++ ++ ++ ++#define MAKE_FLAG 0x20 ++ ++#undef DEBUG ++ ++#define DEBUG 0 ++//#define DEBUG 1 ++ ++#if DEBUG ++#define DPRINTK(format, args...) printk(__FUNCTION__ ": " format, ## args) ++#else ++#define DPRINTK(format, args...) do { } while (0) ++#endif ++ ++/* Please note that this driver is based on a timer and is not interrupt ++ * driven. If you are going to make use of this driver, you will need to have ++ * your application open the buttons listing from the /dev directory first. ++ */ ++ ++struct hydrogen3_buttons { ++ struct fasync_struct *fasync; ++ wait_queue_head_t read_wait; ++ int open_count; ++ unsigned int debounce; ++ unsigned int current; ++ unsigned int last; ++}; ++ ++static struct hydrogen3_buttons buttons_info; ++ ++ ++static void button_timer_periodic(void *data); ++ ++static struct tq_struct button_task = { ++ routine: button_timer_periodic, ++ data: NULL ++}; ++ ++static int cleanup_flag = 0; ++static DECLARE_WAIT_QUEUE_HEAD(cleanup_wait_queue); ++ ++ ++static unsigned int read_button_state(void) ++{ ++ unsigned long state; ++ ++ state = inl(SYS_PINSTATERD) & BUTTON_MASK; ++ state ^= BUTTON_INVERT; ++ ++ DPRINTK( "Current Button State: %d\n", state ); ++ ++ return state; ++} ++ ++ ++static void button_timer_periodic(void *data) ++{ ++ struct hydrogen3_buttons *buttons = (struct hydrogen3_buttons *)data; ++ unsigned long button_state; ++ ++ // If cleanup wants us to die ++ if (cleanup_flag) { ++ wake_up(&cleanup_wait_queue); // now cleanup_module can return ++ } else { ++ queue_task(&button_task, &tq_timer); // put ourselves back in the task queue ++ } ++ ++ // read current buttons ++ button_state = read_button_state(); ++ ++ // if no buttons are down and nothing to do then ++ // save time and be done. ++ if ((button_state == 0) && (buttons->current == 0)) { ++ return; ++ } ++ ++ if (button_state == buttons->debounce) { ++ buttons->current = button_state; ++ } else { ++ buttons->debounce = button_state; ++ } ++// printk("0x%04x\n", button_state); ++ if (buttons->current != buttons->last) { ++ if (waitqueue_active(&buttons->read_wait)) { ++ wake_up_interruptible(&buttons->read_wait); ++ } ++ } ++} ++ ++ ++static ssize_t hydrogen3_buttons_read(struct file *filp, char *buffer, size_t count, loff_t *ppos) ++{ ++ struct hydrogen3_buttons *buttons = filp->private_data; ++ char events[16]; ++ int index; ++ int last; ++ int cur; ++ int bit; ++ int bit_mask; ++ int err; ++ ++ DPRINTK("start\n"); ++ ++try_again: ++ ++ while (buttons->current == buttons->last) { ++ if (filp->f_flags & O_NONBLOCK) { ++ return -EAGAIN; ++ } ++ interruptible_sleep_on(&buttons->read_wait); ++ if (signal_pending(current)) { ++ return -ERESTARTSYS; ++ } ++ } ++ ++ cur = buttons->current; ++ last = buttons->last; ++ ++ index = 0; ++ bit_mask = 1; ++ for (bit = 0; (bit < 16) && count; bit++) { ++ if ((cur ^ last) & bit_mask) { ++ if (cur & bit_mask) { ++ events[index] = (bit | MAKE_FLAG) + 'A'; ++ last |= bit_mask; ++ } else { ++ events[index] = bit + 'A'; ++ last &= ~bit_mask; ++ } ++ index++; ++ count--; ++ } ++ bit_mask <<= 1; ++ } ++ buttons->last = last; ++ ++ if (index == 0) { ++ goto try_again; ++ } ++ ++ err = copy_to_user(buffer, events, index); ++ if (err) { ++ return err; ++ } ++ ++ return index; ++} ++ ++ ++static int hydrogen3_buttons_open(struct inode *inode, struct file *filp) ++{ ++ struct hydrogen3_buttons *buttons = &buttons_info; ++ ++ DPRINTK("start\n"); ++ MOD_INC_USE_COUNT; ++ ++ filp->private_data = buttons; ++ ++ if (buttons->open_count++ == 0) { ++ button_task.data = buttons; ++ cleanup_flag = 0; ++ queue_task(&button_task, &tq_timer); ++ } ++ ++ return 0; ++} ++ ++ ++static unsigned int hydrogen3_buttons_poll(struct file *filp, poll_table *wait) ++{ ++ struct hydrogen3_buttons *buttons = filp->private_data; ++ int ret = 0; ++ ++ DPRINTK("start\n"); ++ poll_wait(filp, &buttons->read_wait, wait); ++ if (buttons->current != buttons->last) { ++ ret = POLLIN | POLLRDNORM; ++ } ++ return ret; ++} ++ ++ ++static int hydrogen3_buttons_release(struct inode *inode, struct file *filp) ++{ ++ struct hydrogen3_buttons *buttons = filp->private_data; ++ ++ DPRINTK("start\n"); ++ ++ if (--buttons->open_count == 0) { ++ cleanup_flag = 1; ++ sleep_on(&cleanup_wait_queue); ++ } ++ MOD_DEC_USE_COUNT; ++ ++ return 0; ++} ++ ++ ++ ++static struct file_operations hydrogen3_buttons_fops = { ++ owner: THIS_MODULE, ++ read: hydrogen3_buttons_read, ++ poll: hydrogen3_buttons_poll, ++ open: hydrogen3_buttons_open, ++ release: hydrogen3_buttons_release, ++}; ++ ++/* ++ * The hydrogen3 buttons is a misc device: ++ * Major 10 char ++ * Minor 22 /dev/buttons ++ * ++ * This is /dev/misc/buttons if devfs is used. ++ */ ++ ++static struct miscdevice hydrogen3_buttons_dev = { ++ minor: 22, ++ name: "buttons", ++ fops: &hydrogen3_buttons_fops, ++}; ++ ++static int __init hydrogen3_buttons_init(void) ++{ ++ struct hydrogen3_buttons *buttons = &buttons_info; ++ int ret; ++ ++ DPRINTK("Initializing buttons driver\n"); ++ buttons->open_count = 0; ++ cleanup_flag = 0; ++ init_waitqueue_head(&buttons->read_wait); ++ ++ ++ // yamon configures GPIO pins for the buttons ++ // no initialization needed ++ ++ ret = misc_register(&hydrogen3_buttons_dev); ++ ++ DPRINTK("Buttons driver fully initialized.\n"); ++ ++ return ret; ++} ++ ++ ++static void __exit hydrogen3_buttons_exit(void) ++{ ++ DPRINTK("unloading buttons driver\n"); ++ misc_deregister(&hydrogen3_buttons_dev); ++} ++ ++ ++module_init(hydrogen3_buttons_init); ++module_exit(hydrogen3_buttons_exit); +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/Makefile +--- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/Makefile 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/Makefile 2005-02-11 22:09:55.000000000 +0100 +@@ -14,6 +14,11 @@ + + O_TARGET := hydrogen3.o + +-obj-y := init.o board_setup.o irqmap.o ++obj-y := init.o board_setup.o irqmap.o buttons.o ++ ++ifdef CONFIG_MMC ++obj-y += mmc_support.o ++export-objs +=mmc_support.o ++endif + + include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/mmc_support.c linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/mmc_support.c +--- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/mmc_support.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/mmc_support.c 2005-02-02 05:27:06.000000000 +0100 +@@ -0,0 +1,89 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * ++ * MMC support routines for Hydrogen3. ++ * ++ * ++ * Copyright (c) 2003-2004 Embedded Edge, LLC. ++ * Author: Embedded Edge, LLC. ++ * Contact: dan@embeddededge.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define GPIO_17_WP 0x20000 ++ ++/* SD/MMC controller support functions */ ++ ++/* ++ * Detect card. ++ */ ++void mmc_card_inserted(int _n_, int *_res_) ++{ ++ u32 gpios = au_readl(SYS_PINSTATERD); ++ u32 emptybit = (1<<16); ++ *_res_ = ((gpios & emptybit) == 0); ++} ++ ++/* ++ * Check card write protection. ++ */ ++void mmc_card_writable(int _n_, int *_res_) ++{ ++ unsigned long mmc_wp, board_specific; ++ board_specific = au_readl(SYS_OUTPUTSET); ++ mmc_wp=GPIO_17_WP; ++ if (!(board_specific & mmc_wp)) {/* low means card writable */ ++ *_res_ = 1; ++ } else { ++ *_res_ = 0; ++ } ++} ++/* ++ * Apply power to card slot. ++ */ ++void mmc_power_on(int _n_) ++{ ++} ++ ++/* ++ * Remove power from card slot. ++ */ ++void mmc_power_off(int _n_) ++{ ++} ++ ++EXPORT_SYMBOL(mmc_card_inserted); ++EXPORT_SYMBOL(mmc_card_writable); ++EXPORT_SYMBOL(mmc_power_on); ++EXPORT_SYMBOL(mmc_power_off); ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/mtx-1/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/mtx-1/board_setup.c 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/board_setup.c 2004-11-26 09:37:16.000000000 +0100 +@@ -48,6 +48,12 @@ + + extern struct rtc_ops no_rtc_ops; + ++void board_reset (void) ++{ ++ /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ ++ au_writel(0x00000000, 0xAE00001C); ++} ++ + void __init board_setup(void) + { + rtc_ops = &no_rtc_ops; +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/mtx-1/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/irqmap.c +--- linux-2.4.32-rc1/arch/mips/au1000/mtx-1/irqmap.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/irqmap.c 2004-11-26 09:37:16.000000000 +0100 +@@ -72,10 +72,10 @@ + * A B C D + */ + { +- {INTA, INTB, INTC, INTD}, /* IDSEL 0 */ +- {INTA, INTB, INTC, INTD}, /* IDSEL 1 */ +- {INTA, INTB, INTC, INTD}, /* IDSEL 2 */ +- {INTA, INTB, INTC, INTD}, /* IDSEL 3 */ ++ {INTA, INTB, INTX, INTX}, /* IDSEL 0 */ ++ {INTB, INTA, INTX, INTX}, /* IDSEL 1 */ ++ {INTC, INTD, INTX, INTX}, /* IDSEL 2 */ ++ {INTD, INTC, INTX, INTX}, /* IDSEL 3 */ + }; + const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1000/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1000/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1000/board_setup.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1000/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -58,6 +58,10 @@ + { + } + ++void board_power_off (void) ++{ ++} ++ + void __init board_setup(void) + { + u32 pin_func, static_cfg0; +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1100/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1100/board_setup.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -62,6 +62,10 @@ + au_writel(0x00000000, 0xAE00001C); + } + ++void board_power_off (void) ++{ ++} ++ + void __init board_setup(void) + { + u32 pin_func; +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1100/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/Makefile +--- linux-2.4.32-rc1/arch/mips/au1000/pb1100/Makefile 2003-08-25 13:44:39.000000000 +0200 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/Makefile 2005-01-30 09:10:29.000000000 +0100 +@@ -16,4 +16,10 @@ + + obj-y := init.o board_setup.o irqmap.o + ++ ++ifdef CONFIG_MMC ++obj-y += mmc_support.o ++export-objs += mmc_support.o ++endif ++ + include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1100/mmc_support.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/mmc_support.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1100/mmc_support.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/mmc_support.c 2005-01-30 09:10:29.000000000 +0100 +@@ -0,0 +1,126 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * ++ * MMC support routines for PB1100. ++ * ++ * ++ * Copyright (c) 2003-2004 Embedded Edge, LLC. ++ * Author: Embedded Edge, LLC. ++ * Contact: dan@embeddededge.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* SD/MMC controller support functions */ ++ ++/* ++ * Detect card. ++ */ ++void mmc_card_inserted(int _n_, int *_res_) ++{ ++ u32 gpios = au_readl(SYS_PINSTATERD); ++ u32 emptybit = (_n_) ? (1<<15) : (1<<14); ++ *_res_ = ((gpios & emptybit) == 0); ++} ++ ++/* ++ * Check card write protection. ++ */ ++void mmc_card_writable(int _n_, int *_res_) ++{ ++ BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ unsigned long mmc_wp, board_specific; ++ ++ if (_n_) { ++ mmc_wp = BCSR_PCMCIA_SD1_WP; ++ } else { ++ mmc_wp = BCSR_PCMCIA_SD0_WP; ++ } ++ ++ board_specific = au_readl((unsigned long)(&bcsr->pcmcia)); ++ ++ if (!(board_specific & mmc_wp)) {/* low means card writable */ ++ *_res_ = 1; ++ } else { ++ *_res_ = 0; ++ } ++} ++ ++/* ++ * Apply power to card slot. ++ */ ++void mmc_power_on(int _n_) ++{ ++ BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ unsigned long mmc_pwr, board_specific; ++ ++ if (_n_) { ++ mmc_pwr = BCSR_PCMCIA_SD1_PWR; ++ } else { ++ mmc_pwr = BCSR_PCMCIA_SD0_PWR; ++ } ++ ++ board_specific = au_readl((unsigned long)(&bcsr->pcmcia)); ++ board_specific |= mmc_pwr; ++ ++ au_writel(board_specific, (int)(&bcsr->pcmcia)); ++ au_sync_delay(1); ++} ++ ++/* ++ * Remove power from card slot. ++ */ ++void mmc_power_off(int _n_) ++{ ++ BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ unsigned long mmc_pwr, board_specific; ++ ++ if (_n_) { ++ mmc_pwr = BCSR_PCMCIA_SD1_PWR; ++ } else { ++ mmc_pwr = BCSR_PCMCIA_SD0_PWR; ++ } ++ ++ board_specific = au_readl((unsigned long)(&bcsr->pcmcia)); ++ board_specific &= ~mmc_pwr; ++ ++ au_writel(board_specific, (int)(&bcsr->pcmcia)); ++ au_sync_delay(1); ++} ++ ++EXPORT_SYMBOL(mmc_card_inserted); ++EXPORT_SYMBOL(mmc_card_writable); ++EXPORT_SYMBOL(mmc_power_on); ++EXPORT_SYMBOL(mmc_power_off); ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1200/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1200/board_setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -0,0 +1,221 @@ ++/* ++ * ++ * BRIEF MODULE DESCRIPTION ++ * Alchemy Pb1200 board setup. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_MIPS_PB1200 ++#include ++#endif ++ ++#ifdef CONFIG_MIPS_DB1200 ++#include ++#define PB1200_ETH_INT DB1200_ETH_INT ++#define PB1200_IDE_INT DB1200_IDE_INT ++#endif ++ ++extern struct rtc_ops no_rtc_ops; ++ ++extern void _board_init_irq(void); ++extern void (*board_init_irq)(void); ++ ++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX ++extern struct ide_ops *ide_ops; ++extern struct ide_ops au1xxx_ide_ops; ++extern u32 au1xxx_ide_virtbase; ++extern u64 au1xxx_ide_physbase; ++extern int au1xxx_ide_irq; ++ ++u32 led_base_addr; ++/* Ddma */ ++chan_tab_t *ide_read_ch, *ide_write_ch; ++u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma ++ ++dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }; ++#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */ ++ ++void board_reset (void) ++{ ++ bcsr->resets = 0; ++} ++ ++void board_power_off (void) ++{ ++ bcsr->resets = 0xC000; ++} ++ ++void __init board_setup(void) ++{ ++ char *argptr = NULL; ++ u32 pin_func; ++ rtc_ops = &no_rtc_ops; ++ ++#if 0 ++ /* Enable PSC1 SYNC for AC97. Normaly done in audio driver, ++ * but it is board specific code, so put it here. ++ */ ++ pin_func = au_readl(SYS_PINFUNC); ++ au_sync(); ++ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1; ++ au_writel(pin_func, SYS_PINFUNC); ++ ++ au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ ++ au_sync(); ++#endif ++ ++#if defined( CONFIG_I2C_ALGO_AU1550 ) ++ { ++ u32 freq0, clksrc; ++ ++ /* Select SMBUS in CPLD */ ++ bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); ++ ++ pin_func = au_readl(SYS_PINFUNC); ++ au_sync(); ++ pin_func &= ~(3<<17 | 1<<4); ++ /* Set GPIOs correctly */ ++ pin_func |= 2<<17; ++ au_writel(pin_func, SYS_PINFUNC); ++ au_sync(); ++ ++ /* The i2c driver depends on 50Mhz clock */ ++ freq0 = au_readl(SYS_FREQCTRL0); ++ au_sync(); ++ freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1); ++ freq0 |= (3<resets bit 12: 0=SMB 1=SPI ++ */ ++#if defined(CONFIG_AU1550_PSC_SPI) && defined(CONFIG_I2C_ALGO_AU1550) ++ #error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\ ++ Refer to Pb1200/Db1200 documentation. ++#elif defined( CONFIG_AU1550_PSC_SPI ) ++ bcsr->resets |= BCSR_RESETS_PCS0MUX; ++#elif defined( CONFIG_I2C_ALGO_AU1550 ) ++ bcsr->resets &= (~BCSR_RESETS_PCS0MUX); ++#endif ++ au_sync(); ++ ++#ifdef CONFIG_MIPS_PB1200 ++ printk("AMD Alchemy Pb1200 Board\n"); ++#endif ++#ifdef CONFIG_MIPS_DB1200 ++ printk("AMD Alchemy Db1200 Board\n"); ++#endif ++ ++ /* Setup Pb1200 External Interrupt Controller */ ++ { ++ extern void (*board_init_irq)(void); ++ extern void _board_init_irq(void); ++ board_init_irq = _board_init_irq; ++ } ++} ++ ++int ++board_au1200fb_panel (void) ++{ ++ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ int p; ++ ++ p = bcsr->switches; ++ p >>= 8; ++ p &= 0x0F; ++ return p; ++} ++ ++int ++board_au1200fb_panel_init (void) ++{ ++ /* Apply power */ ++ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ bcsr->board |= (BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL); ++ return 0; ++} ++ ++int ++board_au1200fb_panel_shutdown (void) ++{ ++ /* Remove power */ ++ BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++ bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL); ++ return 0; ++} ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1200/init.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/init.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1200/init.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/init.c 2005-01-30 09:01:28.000000000 +0100 +@@ -0,0 +1,72 @@ ++/* ++ * ++ * BRIEF MODULE DESCRIPTION ++ * PB1200 board setup ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int prom_argc; ++char **prom_argv, **prom_envp; ++extern void __init prom_init_cmdline(void); ++extern char *prom_getenv(char *envname); ++ ++const char *get_system_type(void) ++{ ++ return "AMD Alchemy Au1200/Pb1200"; ++} ++ ++u32 mae_memsize = 0; ++ ++int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) ++{ ++ unsigned char *memsize_str; ++ unsigned long memsize; ++ ++ prom_argc = argc; ++ prom_argv = argv; ++ prom_envp = envp; ++ ++ mips_machgroup = MACH_GROUP_ALCHEMY; ++ mips_machtype = MACH_PB1000; /* set the platform # */ ++ prom_init_cmdline(); ++ ++ memsize_str = prom_getenv("memsize"); ++ if (!memsize_str) { ++ memsize = 0x08000000; ++ } else { ++ memsize = simple_strtol(memsize_str, NULL, 0); ++ } ++ add_memory_region(0, memsize, BOOT_MEM_RAM); ++ return 0; ++} ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1200/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/irqmap.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1200/irqmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/irqmap.c 2005-01-30 09:01:28.000000000 +0100 +@@ -0,0 +1,180 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * Au1xxx irq map table ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_MIPS_PB1200 ++#include ++#endif ++ ++#ifdef CONFIG_MIPS_DB1200 ++#include ++#define PB1200_INT_BEGIN DB1200_INT_BEGIN ++#define PB1200_INT_END DB1200_INT_END ++#endif ++ ++au1xxx_irq_map_t au1xxx_irq_map[] = { ++ { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade ++}; ++ ++int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); ++ ++/* ++ * Support for External interrupts on the PbAu1200 Development platform. ++ */ ++static volatile int pb1200_cascade_en=0; ++ ++void pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs) ++{ ++ unsigned short bisr = bcsr->int_status; ++ int extirq_nr = 0; ++ ++ /* Clear all the edge interrupts. This has no effect on level */ ++ bcsr->int_status = bisr; ++ for( ; bisr; bisr &= (bisr-1) ) ++ { ++ extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr); ++ /* Ack and dispatch IRQ */ ++ do_IRQ(extirq_nr,regs); ++ } ++} ++ ++inline void pb1200_enable_irq(unsigned int irq_nr) ++{ ++ bcsr->intset_mask = 1<<(irq_nr - PB1200_INT_BEGIN); ++ bcsr->intset = 1<<(irq_nr - PB1200_INT_BEGIN); ++} ++ ++inline void pb1200_disable_irq(unsigned int irq_nr) ++{ ++ bcsr->intclr_mask = 1<<(irq_nr - PB1200_INT_BEGIN); ++ bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN); ++} ++ ++static unsigned int pb1200_startup_irq( unsigned int irq_nr ) ++{ ++ if (++pb1200_cascade_en == 1) ++ { ++ request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, ++ 0, "Pb1200 Cascade", &pb1200_cascade_handler ); ++#ifdef CONFIG_MIPS_PB1200 ++ /* We have a problem with CPLD rev3. Enable a workaround */ ++ if( ((bcsr->whoami & BCSR_WHOAMI_CPLD)>>4) <= 3) ++ { ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n"); ++ printk("updated to latest revision. This software will not\n"); ++ printk("work on anything less than CPLD rev4\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ printk("\nWARNING!!!\n"); ++ while(1); ++ } ++#endif ++ } ++ pb1200_enable_irq(irq_nr); ++ return 0; ++} ++ ++static void pb1200_shutdown_irq( unsigned int irq_nr ) ++{ ++ pb1200_disable_irq(irq_nr); ++ if (--pb1200_cascade_en == 0) ++ { ++ free_irq(AU1000_GPIO_7,&pb1200_cascade_handler ); ++ } ++ return; ++} ++ ++static inline void pb1200_mask_and_ack_irq(unsigned int irq_nr) ++{ ++ pb1200_disable_irq( irq_nr ); ++} ++ ++static void pb1200_end_irq(unsigned int irq_nr) ++{ ++ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { ++ pb1200_enable_irq(irq_nr); ++ } ++} ++ ++static struct hw_interrupt_type external_irq_type = ++{ ++#ifdef CONFIG_MIPS_PB1200 ++ "Pb1200 Ext", ++#endif ++#ifdef CONFIG_MIPS_DB1200 ++ "Db1200 Ext", ++#endif ++ pb1200_startup_irq, ++ pb1200_shutdown_irq, ++ pb1200_enable_irq, ++ pb1200_disable_irq, ++ pb1200_mask_and_ack_irq, ++ pb1200_end_irq, ++ NULL ++}; ++ ++void _board_init_irq(void) ++{ ++ int irq_nr; ++ ++ for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++) ++ { ++ irq_desc[irq_nr].handler = &external_irq_type; ++ pb1200_disable_irq(irq_nr); ++ } ++ ++ /* GPIO_7 can not be hooked here, so it is hooked upon first ++ request of any source attached to the cascade */ ++} ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1200/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/Makefile +--- linux-2.4.32-rc1/arch/mips/au1000/pb1200/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/Makefile 2005-01-30 09:01:27.000000000 +0100 +@@ -0,0 +1,25 @@ ++# ++# Copyright 2000 MontaVista Software Inc. ++# Author: MontaVista Software, Inc. ++# ppopov@mvista.com or source@mvista.com ++# ++# Makefile for the Alchemy Semiconductor PB1000 board. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++ ++USE_STANDARD_AS_RULE := true ++ ++O_TARGET := pb1200.o ++ ++obj-y := init.o board_setup.o irqmap.o ++ ++ifdef CONFIG_MMC ++obj-y += mmc_support.o ++export-objs +=mmc_support.o ++endif ++ ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1200/mmc_support.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/mmc_support.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1200/mmc_support.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1200/mmc_support.c 2005-01-30 09:01:28.000000000 +0100 +@@ -0,0 +1,141 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * ++ * MMC support routines for PB1200. ++ * ++ * ++ * Copyright (c) 2003-2004 Embedded Edge, LLC. ++ * Author: Embedded Edge, LLC. ++ * Contact: dan@embeddededge.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifdef CONFIG_MIPS_PB1200 ++#include ++#endif ++ ++#ifdef CONFIG_MIPS_DB1200 ++/* NOTE: DB1200 only has SD0 pinned out and usable */ ++#include ++#endif ++ ++/* SD/MMC controller support functions */ ++ ++/* ++ * Detect card. ++ */ ++void mmc_card_inserted(int socket, int *result) ++{ ++ u16 mask; ++ ++ if (socket) ++#ifdef CONFIG_MIPS_DB1200 ++ mask = 0; ++#else ++ mask = BCSR_INT_SD1INSERT; ++#endif ++ else ++ mask = BCSR_INT_SD0INSERT; ++ ++ *result = ((bcsr->sig_status & mask) != 0); ++} ++ ++/* ++ * Check card write protection. ++ */ ++void mmc_card_writable(int socket, int *result) ++{ ++ u16 mask; ++ ++ if (socket) ++#ifdef CONFIG_MIPS_DB1200 ++ mask = 0; ++#else ++ mask = BCSR_STATUS_SD1WP; ++#endif ++ else ++ mask = BCSR_STATUS_SD0WP; ++ ++ /* low means card writable */ ++ if (!(bcsr->status & mask)) { ++ *result = 1; ++ } else { ++ *result = 0; ++ } ++} ++ ++/* ++ * Apply power to card slot. ++ */ ++void mmc_power_on(int socket) ++{ ++ u16 mask; ++ ++ if (socket) ++#ifdef CONFIG_MIPS_DB1200 ++ mask = 0; ++#else ++ mask = BCSR_BOARD_SD1PWR; ++#endif ++ else ++ mask = BCSR_BOARD_SD0PWR; ++ ++ bcsr->board |= mask; ++ au_sync_delay(1); ++} ++ ++/* ++ * Remove power from card slot. ++ */ ++void mmc_power_off(int socket) ++{ ++ u16 mask; ++ ++ if (socket) ++#ifdef CONFIG_MIPS_DB1200 ++ mask = 0; ++#else ++ mask = BCSR_BOARD_SD1PWR; ++#endif ++ else ++ mask = BCSR_BOARD_SD0PWR; ++ ++ bcsr->board &= ~mask; ++ au_sync_delay(1); ++} ++ ++EXPORT_SYMBOL(mmc_card_inserted); ++EXPORT_SYMBOL(mmc_card_writable); ++EXPORT_SYMBOL(mmc_power_on); ++EXPORT_SYMBOL(mmc_power_off); ++ +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1500/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1500/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1500/board_setup.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1500/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -62,6 +62,10 @@ + au_writel(0x00000000, 0xAE00001C); + } + ++void board_power_off (void) ++{ ++} ++ + void __init board_setup(void) + { + u32 pin_func; +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1550/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1550/board_setup.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1550/board_setup.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1550/board_setup.c 2005-03-19 08:17:51.000000000 +0100 +@@ -48,12 +48,31 @@ + + extern struct rtc_ops no_rtc_ops; + ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) ++extern struct ide_ops *ide_ops; ++extern struct ide_ops au1xxx_ide_ops; ++extern u32 au1xxx_ide_virtbase; ++extern u64 au1xxx_ide_physbase; ++extern unsigned int au1xxx_ide_irq; ++ ++u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma ++#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */ ++ + void board_reset (void) + { + /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ + au_writew(au_readw(0xAF00001C) & ~(1<<15), 0xAF00001C); + } + ++void board_power_off (void) ++{ ++ /* power off system */ ++ printk("\n** Powering off Pb1550\n"); ++ au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C); ++ au_sync(); ++ while(1); /* should not get here */ ++} ++ + void __init board_setup(void) + { + u32 pin_func; +@@ -78,5 +97,36 @@ + au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ + au_sync(); + ++#if defined(CONFIG_AU1XXX_SMC91111) ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) ++#error "Resource conflict occured. Disable either Ethernet or IDE daughter card." ++#else ++#define CPLD_CONTROL (0xAF00000C) ++ { ++ /* set up the Static Bus timing */ ++ /* only 396Mhz */ ++ /* reset the DC */ ++ au_writew(au_readw(CPLD_CONTROL) | 0x0f, CPLD_CONTROL); ++ au_writel(0x00010003, MEM_STCFG0); ++ au_writel(0x000c00c0, MEM_STCFG2); ++ au_writel(0x85E1900D, MEM_STTIME2); ++ } ++#endif ++#endif /* end CONFIG_SMC91111 */ ++ ++#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) ++ /* ++ * Iniz IDE parameters ++ */ ++ ide_ops = &au1xxx_ide_ops; ++ au1xxx_ide_irq = DAUGHTER_CARD_IRQ;; ++ au1xxx_ide_physbase = AU1XXX_ATA_PHYS_ADDR; ++ au1xxx_ide_virtbase = KSEG1ADDR(AU1XXX_ATA_PHYS_ADDR); ++ /* ++ * change PIO or PIO+Ddma ++ * check the GPIO-6 pin condition. pb1550:s15_dot ++ */ ++ switch4ddma = (au_readl(SYS_PINSTATERD) & (1 << 6)) ? 1 : 0; ++#endif + printk("AMD Alchemy Pb1550 Board\n"); + } +diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1550/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1550/irqmap.c +--- linux-2.4.32-rc1/arch/mips/au1000/pb1550/irqmap.c 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1550/irqmap.c 2005-01-30 09:01:28.000000000 +0100 +@@ -50,6 +50,9 @@ + au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, ++#ifdef CONFIG_AU1XXX_SMC91111 ++ { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, ++#endif + }; + + int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); +diff -Nur linux-2.4.32-rc1/arch/mips/config-shared.in linux-2.4.32-rc1.mips/arch/mips/config-shared.in +--- linux-2.4.32-rc1/arch/mips/config-shared.in 2005-01-19 15:09:27.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/config-shared.in 2005-01-30 09:01:26.000000000 +0100 +@@ -21,16 +21,19 @@ + comment 'Machine selection' + dep_bool 'Support for Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 $CONFIG_EXPERIMENTAL + dep_bool 'Support for Alchemy Bosporus board' CONFIG_MIPS_BOSPORUS $CONFIG_MIPS32 ++dep_bool 'Support for FIC Multimedia Player board' CONFIG_MIPS_FICMMP $CONFIG_MIPS32 + dep_bool 'Support for Alchemy Mirage board' CONFIG_MIPS_MIRAGE $CONFIG_MIPS32 + dep_bool 'Support for Alchemy Db1000 board' CONFIG_MIPS_DB1000 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy Db1100 board' CONFIG_MIPS_DB1100 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy Db1500 board' CONFIG_MIPS_DB1500 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy Db1550 board' CONFIG_MIPS_DB1550 $CONFIG_MIPS32 ++dep_bool 'Support for Alchemy Db1200 board' CONFIG_MIPS_DB1200 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32 +-dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32 + dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32 ++dep_bool 'Support for Alchemy PB1200 board' CONFIG_MIPS_PB1200 $CONFIG_MIPS32 ++dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32 + dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32 + dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32 + dep_bool 'Support for Cogent CSB250 board' CONFIG_COGENT_CSB250 $CONFIG_MIPS32 +@@ -249,6 +252,12 @@ + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_NONCOHERENT_IO y + fi ++if [ "$CONFIG_MIPS_FICMMP" = "y" ]; then ++ define_bool CONFIG_SOC_AU1X00 y ++ define_bool CONFIG_SOC_AU1200 y ++ define_bool CONFIG_NONCOHERENT_IO y ++ define_bool CONFIG_PC_KEYB y ++fi + if [ "$CONFIG_MIPS_BOSPORUS" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y +@@ -263,6 +272,12 @@ + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y + fi ++if [ "$CONFIG_MIPS_PB1500" = "y" ]; then ++ define_bool CONFIG_SOC_AU1X00 y ++ define_bool CONFIG_SOC_AU1500 y ++ define_bool CONFIG_NONCOHERENT_IO y ++ define_bool CONFIG_PC_KEYB y ++fi + if [ "$CONFIG_MIPS_PB1100" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1100 y +@@ -271,9 +286,15 @@ + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y + fi +-if [ "$CONFIG_MIPS_PB1500" = "y" ]; then ++if [ "$CONFIG_MIPS_PB1550" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y +- define_bool CONFIG_SOC_AU1500 y ++ define_bool CONFIG_SOC_AU1550 y ++ define_bool CONFIG_NONCOHERENT_IO n ++ define_bool CONFIG_PC_KEYB y ++fi ++if [ "$CONFIG_MIPS_PB1200" = "y" ]; then ++ define_bool CONFIG_SOC_AU1X00 y ++ define_bool CONFIG_SOC_AU1200 y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + fi +@@ -290,18 +311,24 @@ + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + fi ++if [ "$CONFIG_MIPS_DB1100" = "y" ]; then ++ define_bool CONFIG_SOC_AU1X00 y ++ define_bool CONFIG_SOC_AU1100 y ++ define_bool CONFIG_NONCOHERENT_IO y ++ define_bool CONFIG_PC_KEYB y ++ define_bool CONFIG_SWAP_IO_SPACE y ++fi + if [ "$CONFIG_MIPS_DB1550" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1550 y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + fi +-if [ "$CONFIG_MIPS_DB1100" = "y" ]; then ++if [ "$CONFIG_MIPS_DB1200" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y +- define_bool CONFIG_SOC_AU1100 y ++ define_bool CONFIG_SOC_AU1200 y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y +- define_bool CONFIG_SWAP_IO_SPACE y + fi + if [ "$CONFIG_MIPS_HYDROGEN3" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y +@@ -327,12 +354,6 @@ + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + fi +-if [ "$CONFIG_MIPS_PB1550" = "y" ]; then +- define_bool CONFIG_SOC_AU1X00 y +- define_bool CONFIG_SOC_AU1550 y +- define_bool CONFIG_NONCOHERENT_IO n +- define_bool CONFIG_PC_KEYB y +-fi + if [ "$CONFIG_MIPS_COBALT" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y + define_bool CONFIG_COBALT_LCD y +@@ -729,6 +750,13 @@ + "$CONFIG_MIPS_PB1000" = "y" -o \ + "$CONFIG_MIPS_PB1100" = "y" -o \ + "$CONFIG_MIPS_PB1500" = "y" -o \ ++ "$CONFIG_MIPS_PB1550" = "y" -o \ ++ "$CONFIG_MIPS_PB1200" = "y" -o \ ++ "$CONFIG_MIPS_DB1000" = "y" -o \ ++ "$CONFIG_MIPS_DB1100" = "y" -o \ ++ "$CONFIG_MIPS_DB1500" = "y" -o \ ++ "$CONFIG_MIPS_DB1550" = "y" -o \ ++ "$CONFIG_MIPS_DB1200" = "y" -o \ + "$CONFIG_NEC_OSPREY" = "y" -o \ + "$CONFIG_NEC_EAGLE" = "y" -o \ + "$CONFIG_NINO" = "y" -o \ +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig linux-2.4.32-rc1.mips/arch/mips/defconfig +--- linux-2.4.32-rc1/arch/mips/defconfig 2005-01-19 15:09:27.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -235,11 +235,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -319,9 +314,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -465,7 +462,6 @@ + # CONFIG_SERIAL is not set + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-atlas linux-2.4.32-rc1.mips/arch/mips/defconfig-atlas +--- linux-2.4.32-rc1/arch/mips/defconfig-atlas 2005-01-19 15:09:27.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-atlas 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -235,11 +235,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -317,9 +312,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -528,7 +525,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-bosporus linux-2.4.32-rc1.mips/arch/mips/defconfig-bosporus +--- linux-2.4.32-rc1/arch/mips/defconfig-bosporus 2005-01-19 15:09:27.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-bosporus 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -208,9 +208,7 @@ + CONFIG_MTD_BOSPORUS=y + # 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 +@@ -229,7 +227,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -373,11 +370,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -457,9 +449,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -681,7 +675,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-capcella linux-2.4.32-rc1.mips/arch/mips/defconfig-capcella +--- linux-2.4.32-rc1/arch/mips/defconfig-capcella 2005-01-19 15:09:27.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-capcella 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -228,11 +228,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -472,7 +467,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-cobalt linux-2.4.32-rc1.mips/arch/mips/defconfig-cobalt +--- linux-2.4.32-rc1/arch/mips/defconfig-cobalt 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-cobalt 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -222,11 +222,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -505,7 +500,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=16 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-csb250 linux-2.4.32-rc1.mips/arch/mips/defconfig-csb250 +--- linux-2.4.32-rc1/arch/mips/defconfig-csb250 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-csb250 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 is not set ++# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set + CONFIG_COGENT_CSB250=y +@@ -268,11 +268,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -556,7 +551,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-db1000 linux-2.4.32-rc1.mips/arch/mips/defconfig-db1000 +--- linux-2.4.32-rc1/arch/mips/defconfig-db1000 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-db1000 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -214,11 +214,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set +-CONFIG_MTD_DB1X00=y +-CONFIG_MTD_DB1X00_BOOT=y +-CONFIG_MTD_DB1X00_USER=y + # 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 +@@ -237,7 +233,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -342,11 +337,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -636,7 +626,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-db1100 linux-2.4.32-rc1.mips/arch/mips/defconfig-db1100 +--- linux-2.4.32-rc1/arch/mips/defconfig-db1100 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-db1100 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -214,11 +214,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set +-CONFIG_MTD_DB1X00=y +-# CONFIG_MTD_DB1X00_BOOT is not set +-CONFIG_MTD_DB1X00_USER=y + # 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 +@@ -237,7 +233,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -342,11 +337,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -636,7 +626,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +@@ -884,6 +873,7 @@ + # CONFIG_FB_PM2 is not set + # CONFIG_FB_PM3 is not set + # CONFIG_FB_CYBER2000 is not set ++CONFIG_FB_AU1100=y + # CONFIG_FB_MATROX is not set + # CONFIG_FB_ATY is not set + # CONFIG_FB_RADEON is not set +@@ -895,7 +885,6 @@ + # CONFIG_FB_VOODOO1 is not set + # CONFIG_FB_TRIDENT is not set + # CONFIG_FB_E1356 is not set +-CONFIG_FB_AU1100=y + # CONFIG_FB_IT8181 is not set + # CONFIG_FB_VIRTUAL is not set + CONFIG_FBCON_ADVANCED=y +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-db1200 linux-2.4.32-rc1.mips/arch/mips/defconfig-db1200 +--- linux-2.4.32-rc1/arch/mips/defconfig-db1200 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-db1200 2005-03-18 13:13:21.000000000 +0100 +@@ -0,0 +1,1032 @@ ++# ++# Automatically generated make config: 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_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_PB1000 is not set ++# CONFIG_MIPS_PB1100 is not set ++# CONFIG_MIPS_PB1500 is not set ++# CONFIG_MIPS_PB1550 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_MIPS_AU1000 is not set ++ ++# ++# CPU selection ++# ++CONFIG_CPU_MIPS32=y ++# CONFIG_CPU_MIPS64 is not set ++# CONFIG_CPU_R3000 is not set ++# CONFIG_CPU_TX39XX is not set ++# CONFIG_CPU_VR41XX is not set ++# 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_HAS_PREFETCH=y ++# CONFIG_VTAG_ICACHE is not set ++CONFIG_64BIT_PHYS_ADDR=y ++# CONFIG_CPU_ADVANCED is not set ++CONFIG_CPU_HAS_LLSC=y ++# 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=y ++# CONFIG_BUILD_ELF64 is not set ++CONFIG_NET=y ++CONFIG_PCI=y ++CONFIG_PCI_NEW=y ++CONFIG_PCI_AUTO=y ++# CONFIG_PCI_NAMES is not set ++# CONFIG_ISA is not set ++# CONFIG_TC is not set ++# CONFIG_MCA is not set ++# CONFIG_SBUS is not set ++CONFIG_HOTPLUG=y ++ ++# ++# PCMCIA/CardBus support ++# ++CONFIG_PCMCIA=m ++# CONFIG_CARDBUS is not set ++# CONFIG_TCIC is not set ++# CONFIG_I82092 is not set ++# CONFIG_I82365 is not set ++ ++# ++# PCI Hotplug Support ++# ++# CONFIG_HOTPLUG_PCI is not set ++# CONFIG_HOTPLUG_PCI_COMPAQ is not set ++# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set ++# CONFIG_HOTPLUG_PCI_SHPC is not set ++# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set ++# CONFIG_HOTPLUG_PCI_PCIE is not set ++# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE 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_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=y ++CONFIG_CMDLINE="mem=96M" ++ ++# ++# Memory Technology Devices (MTD) ++# ++# CONFIG_MTD is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT 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=y ++# CONFIG_BLK_DEV_NBD is not set ++# 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 is not set ++# CONFIG_NETLINK_DEV is not set ++CONFIG_NETFILTER=y ++# CONFIG_NETFILTER_DEBUG is not set ++CONFIG_FILTER=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE 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 is not set ++# CONFIG_IP_NF_QUEUE is not set ++# CONFIG_IP_NF_IPTABLES is not set ++# CONFIG_IP_NF_ARPTABLES is not set ++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set ++# CONFIG_IP_NF_COMPAT_IPFWADM is not set ++ ++# ++# IP: Virtual Server Configuration ++# ++# CONFIG_IP_VS is not set ++# CONFIG_IPV6 is not set ++# CONFIG_KHTTPD is not set ++ ++# ++# SCTP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_SCTP is not set ++# CONFIG_ATM is not set ++# CONFIG_VLAN_8021Q is not set ++ ++# ++# ++# ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_DECNET is not set ++# CONFIG_BRIDGE is not set ++# 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 is not set ++# CONFIG_NET_FASTROUTE is not set ++# CONFIG_NET_HW_FLOWCONTROL is not set ++ ++# ++# QoS and/or fair queueing ++# ++# CONFIG_NET_SCHED is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++ ++# ++# 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=y ++ ++# ++# IDE, ATA and ATAPI Block devices ++# ++CONFIG_BLK_DEV_IDE=y ++ ++# ++# Please see Documentation/ide.txt for help/info on IDE drives ++# ++# 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=y ++CONFIG_IDEDISK_MULTI_MODE=y ++CONFIG_IDEDISK_STROKE=y ++CONFIG_BLK_DEV_IDECS=m ++# 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 ++ ++# ++# IDE chipset support/bugfixes ++# ++# CONFIG_BLK_DEV_CMD640 is not set ++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set ++# CONFIG_BLK_DEV_ISAPNP is not set ++# CONFIG_BLK_DEV_IDEPCI 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=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++CONFIG_SD_EXTRA_DEVS=40 ++CONFIG_CHR_DEV_ST=y ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++CONFIG_SR_EXTRA_DEVS=2 ++# CONFIG_CHR_DEV_SG is not set ++ ++# ++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs ++# ++# CONFIG_SCSI_DEBUG_QUEUES is not set ++# CONFIG_SCSI_MULTI_LUN is not set ++CONFIG_SCSI_CONSTANTS=y ++# CONFIG_SCSI_LOGGING is not set ++ ++# ++# SCSI low-level drivers ++# ++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set ++# CONFIG_SCSI_7000FASST is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_AHA152X is not set ++# CONFIG_SCSI_AHA1542 is not set ++# CONFIG_SCSI_AHA1740 is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC79XX is not set ++# CONFIG_SCSI_AIC7XXX_OLD is not set ++# CONFIG_SCSI_DPT_I2O is not set ++# CONFIG_SCSI_ADVANSYS is not set ++# CONFIG_SCSI_IN2000 is not set ++# CONFIG_SCSI_AM53C974 is not set ++# CONFIG_SCSI_MEGARAID is not set ++# CONFIG_SCSI_MEGARAID2 is not set ++# CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set ++# CONFIG_SCSI_SATA_SVW is not set ++# CONFIG_SCSI_ATA_PIIX is not set ++# CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set ++# CONFIG_SCSI_SATA_PROMISE is not set ++# CONFIG_SCSI_SATA_SX4 is not set ++# CONFIG_SCSI_SATA_SIL is not set ++# CONFIG_SCSI_SATA_SIS is not set ++# CONFIG_SCSI_SATA_ULI is not set ++# CONFIG_SCSI_SATA_VIA is not set ++# CONFIG_SCSI_SATA_VITESSE is not set ++# CONFIG_SCSI_BUSLOGIC is not set ++# CONFIG_SCSI_CPQFCTS is not set ++# CONFIG_SCSI_DMX3191D is not set ++# CONFIG_SCSI_DTC3280 is not set ++# CONFIG_SCSI_EATA is not set ++# CONFIG_SCSI_EATA_DMA is not set ++# CONFIG_SCSI_EATA_PIO is not set ++# CONFIG_SCSI_FUTURE_DOMAIN is not set ++# CONFIG_SCSI_GDTH is not set ++# CONFIG_SCSI_GENERIC_NCR5380 is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_NCR53C406A is not set ++# CONFIG_SCSI_NCR53C7xx is not set ++# CONFIG_SCSI_SYM53C8XX_2 is not set ++# CONFIG_SCSI_NCR53C8XX is not set ++# CONFIG_SCSI_SYM53C8XX is not set ++# CONFIG_SCSI_PAS16 is not set ++# CONFIG_SCSI_PCI2000 is not set ++# CONFIG_SCSI_PCI2220I is not set ++# CONFIG_SCSI_PSI240I is not set ++# CONFIG_SCSI_QLOGIC_FAS is not set ++# CONFIG_SCSI_QLOGIC_ISP is not set ++# CONFIG_SCSI_QLOGIC_FC is not set ++# CONFIG_SCSI_QLOGIC_1280 is not set ++# CONFIG_SCSI_SIM710 is not set ++# CONFIG_SCSI_SYM53C416 is not set ++# CONFIG_SCSI_DC390T is not set ++# CONFIG_SCSI_T128 is not set ++# CONFIG_SCSI_U14_34F is not set ++# CONFIG_SCSI_NSP32 is not set ++# CONFIG_SCSI_DEBUG is not set ++ ++# ++# PCMCIA SCSI adapter support ++# ++# CONFIG_SCSI_PCMCIA 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 ++ ++# ++# IEEE 1394 (FireWire) support (EXPERIMENTAL) ++# ++# CONFIG_IEEE1394 is not set ++ ++# ++# I2O device support ++# ++# CONFIG_I2O is not set ++# CONFIG_I2O_PCI is not set ++# CONFIG_I2O_BLOCK is not set ++# CONFIG_I2O_LAN is not set ++# CONFIG_I2O_SCSI is not set ++# CONFIG_I2O_PROC 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_TUN is not set ++# CONFIG_ETHERTAP is not set ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++CONFIG_NET_ETHERNET=y ++# CONFIG_SUNLANCE is not set ++# CONFIG_HAPPYMEAL 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_HP100 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 is not set ++# CONFIG_SLIP is not set ++ ++# ++# Wireless LAN (non-hamradio) ++# ++# CONFIG_NET_RADIO is not set ++ ++# ++# Token Ring devices ++# ++# CONFIG_TR is not set ++# CONFIG_NET_FC is not set ++# CONFIG_RCPCI is not set ++# CONFIG_SHAPER is not set ++ ++# ++# Wan interfaces ++# ++# CONFIG_WAN is not set ++ ++# ++# PCMCIA network device support ++# ++# CONFIG_NET_PCMCIA is not set ++ ++# ++# Amateur Radio support ++# ++# CONFIG_HAMRADIO is not set ++ ++# ++# IrDA (infrared) support ++# ++# CONFIG_IRDA is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Input core support ++# ++CONFIG_INPUT=y ++CONFIG_INPUT_KEYBDEV=y ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_UINPUT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++# CONFIG_VT_CONSOLE is not set ++# CONFIG_SERIAL is not set ++# CONFIG_SERIAL_EXTENDED is not set ++CONFIG_SERIAL_NONSTANDARD=y ++# CONFIG_COMPUTONE is not set ++# CONFIG_ROCKETPORT is not set ++# CONFIG_CYCLADES is not set ++# CONFIG_DIGIEPCA is not set ++# CONFIG_DIGI is not set ++# CONFIG_ESPSERIAL is not set ++# CONFIG_MOXA_INTELLIO is not set ++# CONFIG_MOXA_SMARTIO is not set ++# CONFIG_ISI is not set ++# CONFIG_SYNCLINK is not set ++# CONFIG_SYNCLINKMP is not set ++# CONFIG_N_HDLC is not set ++# CONFIG_RISCOM8 is not set ++# CONFIG_SPECIALIX is not set ++# CONFIG_SX is not set ++# CONFIG_RIO is not set ++# CONFIG_STALDRV is not set ++# CONFIG_SERIAL_TX3912 is not set ++# CONFIG_SERIAL_TX3912_CONSOLE is not set ++# CONFIG_SERIAL_TXX9 is not set ++# CONFIG_SERIAL_TXX9_CONSOLE is not set ++# CONFIG_TXX927_SERIAL is not set ++CONFIG_UNIX98_PTYS=y ++CONFIG_UNIX98_PTY_COUNT=256 ++ ++# ++# 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_INPUT_NS558 is not set ++# CONFIG_INPUT_LIGHTNING is not set ++# CONFIG_INPUT_PCIGAME is not set ++# CONFIG_INPUT_CS461X is not set ++# CONFIG_INPUT_EMU10K1 is not set ++# CONFIG_INPUT_SERIO is not set ++# CONFIG_INPUT_SERPORT is not set ++ ++# ++# Joysticks ++# ++# CONFIG_INPUT_ANALOG is not set ++# CONFIG_INPUT_A3D is not set ++# CONFIG_INPUT_ADI is not set ++# CONFIG_INPUT_COBRA is not set ++# CONFIG_INPUT_GF2K is not set ++# CONFIG_INPUT_GRIP is not set ++# CONFIG_INPUT_INTERACT is not set ++# CONFIG_INPUT_TMDC is not set ++# CONFIG_INPUT_SIDEWINDER is not set ++# CONFIG_INPUT_IFORCE_USB is not set ++# CONFIG_INPUT_IFORCE_232 is not set ++# CONFIG_INPUT_WARRIOR is not set ++# CONFIG_INPUT_MAGELLAN is not set ++# CONFIG_INPUT_SPACEORB is not set ++# CONFIG_INPUT_SPACEBALL is not set ++# CONFIG_INPUT_STINGER is not set ++# CONFIG_INPUT_DB9 is not set ++# CONFIG_INPUT_GAMECON is not set ++# CONFIG_INPUT_TURBOGRAFX 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 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 ++ ++# ++# PCMCIA character devices ++# ++# CONFIG_PCMCIA_SERIAL_CS is not set ++# CONFIG_SYNCLINK_CS is not set ++ ++# ++# File systems ++# ++# CONFIG_QUOTA is not set ++# CONFIG_QFMT_V2 is not set ++CONFIG_AUTOFS_FS=y ++# 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 is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BEFS_DEBUG is not set ++# CONFIG_BFS_FS is not set ++CONFIG_EXT3_FS=y ++CONFIG_JBD=y ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++# CONFIG_UMSDOS_FS is not set ++CONFIG_VFAT_FS=y ++# CONFIG_EFS_FS is not set ++# CONFIG_JFFS_FS is not set ++# CONFIG_JFFS2_FS is not set ++# CONFIG_CRAMFS is not set ++CONFIG_TMPFS=y ++CONFIG_RAMFS=y ++# CONFIG_ISO9660_FS is not set ++# CONFIG_JOLIET is not set ++# 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 is not set ++# CONFIG_DEVFS_MOUNT is not set ++# 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=y ++# 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 is not set ++# 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=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_DIRECTIO is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFSD is not set ++# CONFIG_NFSD_V3 is not set ++# CONFIG_NFSD_TCP is not set ++CONFIG_SUNRPC=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=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 is not set ++CONFIG_MSDOS_PARTITION=y ++# 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 is not set ++ ++# ++# Console drivers ++# ++# CONFIG_VGA_CONSOLE is not set ++# CONFIG_MDA_CONSOLE is not set ++ ++# ++# Frame-buffer support ++# ++CONFIG_FB=y ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FB_RIVA is not set ++# CONFIG_FB_CLGEN is not set ++# CONFIG_FB_PM2 is not set ++# CONFIG_FB_PM3 is not set ++# CONFIG_FB_CYBER2000 is not set ++# CONFIG_FB_MATROX is not set ++# CONFIG_FB_ATY is not set ++# CONFIG_FB_RADEON is not set ++# CONFIG_FB_ATY128 is not set ++# CONFIG_FB_INTEL is not set ++# CONFIG_FB_SIS is not set ++# CONFIG_FB_NEOMAGIC is not set ++# CONFIG_FB_3DFX is not set ++# CONFIG_FB_VOODOO1 is not set ++# CONFIG_FB_TRIDENT is not set ++# CONFIG_FB_E1356 is not set ++# CONFIG_FB_IT8181 is not set ++# CONFIG_FB_VIRTUAL is not set ++CONFIG_FBCON_ADVANCED=y ++# CONFIG_FBCON_MFB is not set ++# CONFIG_FBCON_CFB2 is not set ++# CONFIG_FBCON_CFB4 is not set ++# CONFIG_FBCON_CFB8 is not set ++CONFIG_FBCON_CFB16=y ++# CONFIG_FBCON_CFB24 is not set ++CONFIG_FBCON_CFB32=y ++# CONFIG_FBCON_AFB is not set ++# CONFIG_FBCON_ILBM is not set ++# CONFIG_FBCON_IPLAN2P2 is not set ++# CONFIG_FBCON_IPLAN2P4 is not set ++# CONFIG_FBCON_IPLAN2P8 is not set ++# CONFIG_FBCON_MAC is not set ++# CONFIG_FBCON_VGA_PLANES is not set ++# CONFIG_FBCON_VGA is not set ++# CONFIG_FBCON_HGA is not set ++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set ++CONFIG_FBCON_FONTS=y ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++# CONFIG_FONT_SUN8x16 is not set ++# CONFIG_FONT_SUN12x22 is not set ++# CONFIG_FONT_6x11 is not set ++# CONFIG_FONT_PEARL_8x8 is not set ++# CONFIG_FONT_ACORN_8x8 is not set ++ ++# ++# Sound ++# ++CONFIG_SOUND=y ++# 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=y ++# CONFIG_USB_DEBUG is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEVICEFS=y ++# CONFIG_USB_BANDWIDTH is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_UHCI is not set ++# CONFIG_USB_UHCI_ALT is not set ++CONFIG_USB_OHCI=y ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_AUDIO is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_BLUETOOTH is not set ++# CONFIG_USB_MIDI is not set ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_DPCM is not set ++# CONFIG_USB_STORAGE_HP8200e is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++ ++# ++# USB Human Interface Devices (HID) ++# ++CONFIG_USB_HID=y ++CONFIG_USB_HIDINPUT=y ++CONFIG_USB_HIDDEV=y ++# CONFIG_USB_AIPTEK is not set ++# CONFIG_USB_WACOM is not set ++# CONFIG_USB_KBTAB is not set ++# CONFIG_USB_POWERMATE is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_DC2XX is not set ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_SCANNER is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USB_HPUSBSCSI is not set ++ ++# ++# USB Multimedia devices ++# ++ ++# ++# Video4Linux support is needed for USB Multimedia device support ++# ++ ++# ++# USB Network adaptors ++# ++# CONFIG_USB_PEGASUS is not set ++# CONFIG_USB_RTL8150 is not set ++# CONFIG_USB_KAWETH is not set ++# CONFIG_USB_CATC is not set ++# CONFIG_USB_CDCETHER is not set ++# CONFIG_USB_USBNET is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_USS720 is not set ++ ++# ++# USB Serial Converter support ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_AUERSWALD is not set ++# CONFIG_USB_TIGL is not set ++# CONFIG_USB_BRLVGER is not set ++# CONFIG_USB_LCD is not set ++ ++# ++# Support for USB gadgets ++# ++# CONFIG_USB_GADGET is not set ++ ++# ++# Bluetooth support ++# ++# CONFIG_BLUEZ 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 is not set ++# CONFIG_MIPS_UNCACHED is not set ++CONFIG_LOG_BUF_SHIFT=0 ++ ++# ++# Cryptographic options ++# ++# CONFIG_CRYPTO is not set ++ ++# ++# Library routines ++# ++# CONFIG_CRC32 is not set ++CONFIG_ZLIB_INFLATE=m ++CONFIG_ZLIB_DEFLATE=m ++# CONFIG_FW_LOADER is not set +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-db1500 linux-2.4.32-rc1.mips/arch/mips/defconfig-db1500 +--- linux-2.4.32-rc1/arch/mips/defconfig-db1500 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-db1500 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -267,11 +267,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -555,7 +550,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-db1550 linux-2.4.32-rc1.mips/arch/mips/defconfig-db1550 +--- linux-2.4.32-rc1/arch/mips/defconfig-db1550 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-db1550 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -213,11 +213,9 @@ + # 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=y + CONFIG_MTD_PB1550_BOOT=y + CONFIG_MTD_PB1550_USER=y +-# 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 +@@ -236,7 +234,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -343,11 +340,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -633,7 +625,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ddb5476 linux-2.4.32-rc1.mips/arch/mips/defconfig-ddb5476 +--- linux-2.4.32-rc1/arch/mips/defconfig-ddb5476 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ddb5476 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -226,11 +226,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -517,7 +512,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ddb5477 linux-2.4.32-rc1.mips/arch/mips/defconfig-ddb5477 +--- linux-2.4.32-rc1/arch/mips/defconfig-ddb5477 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ddb5477 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -226,11 +226,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -434,7 +429,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-decstation linux-2.4.32-rc1.mips/arch/mips/defconfig-decstation +--- linux-2.4.32-rc1/arch/mips/defconfig-decstation 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-decstation 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -223,11 +223,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -306,9 +301,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -477,7 +474,6 @@ + CONFIG_SERIAL_DEC_CONSOLE=y + CONFIG_DZ=y + CONFIG_ZS=y +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-e55 linux-2.4.32-rc1.mips/arch/mips/defconfig-e55 +--- linux-2.4.32-rc1/arch/mips/defconfig-e55 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-e55 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -222,11 +222,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -426,7 +421,6 @@ + # CONFIG_SERIAL_MULTIPORT is not set + # CONFIG_HUB6 is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-eagle linux-2.4.32-rc1.mips/arch/mips/defconfig-eagle +--- linux-2.4.32-rc1/arch/mips/defconfig-eagle 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-eagle 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -208,8 +208,8 @@ + # Mapping drivers for chip access + # + CONFIG_MTD_PHYSMAP=y +-CONFIG_MTD_PHYSMAP_START=1c000000 +-CONFIG_MTD_PHYSMAP_LEN=2000000 ++CONFIG_MTD_PHYSMAP_START=0x1c000000 ++CONFIG_MTD_PHYSMAP_LEN=0x2000000 + CONFIG_MTD_PHYSMAP_BUSWIDTH=4 + # CONFIG_MTD_PB1000 is not set + # CONFIG_MTD_PB1500 is not set +@@ -217,9 +217,7 @@ + # 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 +@@ -238,7 +236,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -327,11 +324,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -587,7 +579,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ev64120 linux-2.4.32-rc1.mips/arch/mips/defconfig-ev64120 +--- linux-2.4.32-rc1/arch/mips/defconfig-ev64120 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ev64120 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -230,11 +230,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -443,7 +438,6 @@ + # CONFIG_SERIAL_CONSOLE is not set + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ev96100 linux-2.4.32-rc1.mips/arch/mips/defconfig-ev96100 +--- linux-2.4.32-rc1/arch/mips/defconfig-ev96100 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ev96100 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -232,11 +232,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -441,7 +436,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ficmmp linux-2.4.32-rc1.mips/arch/mips/defconfig-ficmmp +--- linux-2.4.32-rc1/arch/mips/defconfig-ficmmp 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ficmmp 2005-03-18 13:13:21.000000000 +0100 +@@ -0,0 +1,862 @@ ++# ++# Automatically generated make config: 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_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_PB1000 is not set ++# CONFIG_MIPS_PB1100 is not set ++# CONFIG_MIPS_PB1500 is not set ++# CONFIG_MIPS_PB1550 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_MIPS_AU1000 is not set ++ ++# ++# CPU selection ++# ++CONFIG_CPU_MIPS32=y ++# CONFIG_CPU_MIPS64 is not set ++# CONFIG_CPU_R3000 is not set ++# CONFIG_CPU_TX39XX is not set ++# CONFIG_CPU_VR41XX is not set ++# 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_HAS_PREFETCH=y ++# CONFIG_VTAG_ICACHE is not set ++CONFIG_64BIT_PHYS_ADDR=y ++# CONFIG_CPU_ADVANCED is not set ++CONFIG_CPU_HAS_LLSC=y ++# 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=y ++# CONFIG_BUILD_ELF64 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_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=y ++CONFIG_CMDLINE="ide3=dma mem=96M root=/dev/hda2 rootflags=data=journal" ++ ++# ++# Memory Technology Devices (MTD) ++# ++# CONFIG_MTD is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT 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=y ++# CONFIG_BLK_DEV_NBD is not set ++# 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 is not set ++# CONFIG_NETLINK_DEV is not set ++CONFIG_NETFILTER=y ++# CONFIG_NETFILTER_DEBUG is not set ++CONFIG_FILTER=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_IP_ADVANCED_ROUTER is not set ++# CONFIG_IP_PNP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE 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 is not set ++# CONFIG_IP_NF_QUEUE is not set ++# CONFIG_IP_NF_IPTABLES is not set ++# CONFIG_IP_NF_ARPTABLES is not set ++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set ++# CONFIG_IP_NF_COMPAT_IPFWADM is not set ++ ++# ++# IP: Virtual Server Configuration ++# ++# CONFIG_IP_VS is not set ++# CONFIG_IPV6 is not set ++# CONFIG_KHTTPD is not set ++ ++# ++# SCTP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_SCTP is not set ++# CONFIG_ATM is not set ++# CONFIG_VLAN_8021Q is not set ++ ++# ++# ++# ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_DECNET is not set ++# CONFIG_BRIDGE is not set ++# 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 is not set ++# CONFIG_NET_FASTROUTE is not set ++# CONFIG_NET_HW_FLOWCONTROL is not set ++ ++# ++# QoS and/or fair queueing ++# ++# CONFIG_NET_SCHED is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++ ++# ++# 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=y ++ ++# ++# IDE, ATA and ATAPI Block devices ++# ++CONFIG_BLK_DEV_IDE=y ++ ++# ++# Please see Documentation/ide.txt for help/info on IDE drives ++# ++CONFIG_BLK_DEV_HD_IDE=y ++CONFIG_BLK_DEV_HD=y ++# CONFIG_BLK_DEV_IDE_SATA is not set ++CONFIG_BLK_DEV_IDEDISK=y ++CONFIG_IDEDISK_MULTI_MODE=y ++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 ++ ++# ++# IDE chipset support/bugfixes ++# ++# 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=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++CONFIG_SD_EXTRA_DEVS=40 ++CONFIG_CHR_DEV_ST=y ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++CONFIG_SR_EXTRA_DEVS=2 ++# CONFIG_CHR_DEV_SG is not set ++ ++# ++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs ++# ++# CONFIG_SCSI_DEBUG_QUEUES is not set ++# CONFIG_SCSI_MULTI_LUN is not set ++CONFIG_SCSI_CONSTANTS=y ++# CONFIG_SCSI_LOGGING is not set ++ ++# ++# SCSI low-level drivers ++# ++# CONFIG_SCSI_7000FASST is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_AHA152X is not set ++# CONFIG_SCSI_AHA1542 is not set ++# CONFIG_SCSI_AHA1740 is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC79XX is not set ++# CONFIG_SCSI_AIC7XXX_OLD is not set ++# CONFIG_SCSI_DPT_I2O is not set ++# CONFIG_SCSI_ADVANSYS is not set ++# CONFIG_SCSI_IN2000 is not set ++# CONFIG_SCSI_AM53C974 is not set ++# CONFIG_SCSI_MEGARAID is not set ++# CONFIG_SCSI_MEGARAID2 is not set ++# CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set ++# CONFIG_SCSI_SATA_SVW is not set ++# CONFIG_SCSI_ATA_PIIX is not set ++# CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set ++# CONFIG_SCSI_SATA_PROMISE is not set ++# CONFIG_SCSI_SATA_SX4 is not set ++# CONFIG_SCSI_SATA_SIL is not set ++# CONFIG_SCSI_SATA_SIS is not set ++# CONFIG_SCSI_SATA_ULI is not set ++# CONFIG_SCSI_SATA_VIA is not set ++# CONFIG_SCSI_SATA_VITESSE is not set ++# CONFIG_SCSI_BUSLOGIC is not set ++# CONFIG_SCSI_DMX3191D is not set ++# CONFIG_SCSI_DTC3280 is not set ++# CONFIG_SCSI_EATA is not set ++# CONFIG_SCSI_EATA_DMA is not set ++# CONFIG_SCSI_EATA_PIO is not set ++# CONFIG_SCSI_FUTURE_DOMAIN is not set ++# CONFIG_SCSI_GDTH is not set ++# CONFIG_SCSI_GENERIC_NCR5380 is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_NCR53C406A is not set ++# CONFIG_SCSI_NCR53C7xx is not set ++# CONFIG_SCSI_PAS16 is not set ++# CONFIG_SCSI_PCI2000 is not set ++# CONFIG_SCSI_PCI2220I is not set ++# CONFIG_SCSI_PSI240I is not set ++# CONFIG_SCSI_QLOGIC_FAS is not set ++# CONFIG_SCSI_SIM710 is not set ++# CONFIG_SCSI_SYM53C416 is not set ++# CONFIG_SCSI_T128 is not set ++# CONFIG_SCSI_U14_34F is not set ++# CONFIG_SCSI_NSP32 is not set ++# CONFIG_SCSI_DEBUG 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_TUN is not set ++# CONFIG_ETHERTAP is not set ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++CONFIG_NET_ETHERNET=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 is not set ++# CONFIG_SLIP is not set ++ ++# ++# Wireless LAN (non-hamradio) ++# ++# CONFIG_NET_RADIO is not set ++ ++# ++# Token Ring devices ++# ++# CONFIG_TR is not set ++# CONFIG_NET_FC is not set ++# CONFIG_RCPCI is not set ++# CONFIG_SHAPER is not set ++ ++# ++# Wan interfaces ++# ++# CONFIG_WAN is not set ++ ++# ++# Amateur Radio support ++# ++# CONFIG_HAMRADIO is not set ++ ++# ++# IrDA (infrared) support ++# ++# CONFIG_IRDA is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Input core support ++# ++CONFIG_INPUT=y ++CONFIG_INPUT_KEYBDEV=y ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_UINPUT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_VT_CONSOLE=y ++# CONFIG_SERIAL is not set ++# CONFIG_SERIAL_EXTENDED is not set ++CONFIG_SERIAL_NONSTANDARD=y ++# CONFIG_COMPUTONE is not set ++# CONFIG_ROCKETPORT is not set ++# CONFIG_CYCLADES is not set ++# CONFIG_DIGIEPCA is not set ++# CONFIG_DIGI is not set ++# CONFIG_ESPSERIAL is not set ++# CONFIG_MOXA_INTELLIO is not set ++# CONFIG_MOXA_SMARTIO is not set ++# CONFIG_ISI is not set ++# CONFIG_SYNCLINK is not set ++# CONFIG_SYNCLINKMP is not set ++# CONFIG_N_HDLC is not set ++# CONFIG_RISCOM8 is not set ++# CONFIG_SPECIALIX is not set ++# CONFIG_SX is not set ++# CONFIG_RIO is not set ++# CONFIG_STALDRV is not set ++# CONFIG_SERIAL_TX3912 is not set ++# CONFIG_SERIAL_TX3912_CONSOLE is not set ++# CONFIG_SERIAL_TXX9 is not set ++# CONFIG_SERIAL_TXX9_CONSOLE is not set ++# CONFIG_TXX927_SERIAL is not set ++CONFIG_UNIX98_PTYS=y ++CONFIG_UNIX98_PTY_COUNT=256 ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++# CONFIG_I2C_ALGOBIT is not set ++# CONFIG_SCx200_ACB is not set ++# CONFIG_I2C_ALGOPCF is not set ++# CONFIG_I2C_CHARDEV is not set ++# CONFIG_I2C_PROC is not set ++ ++# ++# Mice ++# ++# CONFIG_BUSMOUSE is not set ++# CONFIG_MOUSE is not set ++ ++# ++# Joysticks ++# ++# CONFIG_INPUT_GAMEPORT is not set ++# CONFIG_INPUT_NS558 is not set ++# CONFIG_INPUT_LIGHTNING is not set ++# CONFIG_INPUT_PCIGAME is not set ++# CONFIG_INPUT_CS461X is not set ++# CONFIG_INPUT_EMU10K1 is not set ++# CONFIG_INPUT_SERIO is not set ++# CONFIG_INPUT_SERPORT is not set ++ ++# ++# Joysticks ++# ++# CONFIG_INPUT_ANALOG is not set ++# CONFIG_INPUT_A3D is not set ++# CONFIG_INPUT_ADI is not set ++# CONFIG_INPUT_COBRA is not set ++# CONFIG_INPUT_GF2K is not set ++# CONFIG_INPUT_GRIP is not set ++# CONFIG_INPUT_INTERACT is not set ++# CONFIG_INPUT_TMDC is not set ++# CONFIG_INPUT_SIDEWINDER is not set ++# CONFIG_INPUT_IFORCE_USB is not set ++# CONFIG_INPUT_IFORCE_232 is not set ++# CONFIG_INPUT_WARRIOR is not set ++# CONFIG_INPUT_MAGELLAN is not set ++# CONFIG_INPUT_SPACEORB is not set ++# CONFIG_INPUT_SPACEBALL is not set ++# CONFIG_INPUT_STINGER is not set ++# CONFIG_INPUT_DB9 is not set ++# CONFIG_INPUT_GAMECON is not set ++# CONFIG_INPUT_TURBOGRAFX 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 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=y ++# 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 is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BEFS_DEBUG is not set ++# CONFIG_BFS_FS is not set ++CONFIG_EXT3_FS=y ++CONFIG_JBD=y ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++# CONFIG_UMSDOS_FS is not set ++CONFIG_VFAT_FS=y ++# CONFIG_EFS_FS is not set ++# CONFIG_JFFS_FS is not set ++# CONFIG_JFFS2_FS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_TMPFS is not set ++CONFIG_RAMFS=y ++# CONFIG_ISO9660_FS is not set ++# CONFIG_JOLIET is not set ++# 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 is not set ++# CONFIG_DEVFS_MOUNT is not set ++# 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=y ++# 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 is not set ++# 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 is not set ++# CONFIG_NFS_V3 is not set ++# 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 is not set ++# CONFIG_LOCKD is not set ++# 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 is not set ++CONFIG_MSDOS_PARTITION=y ++# 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 is not set ++ ++# ++# Console drivers ++# ++# CONFIG_VGA_CONSOLE is not set ++# CONFIG_MDA_CONSOLE is not set ++ ++# ++# Frame-buffer support ++# ++CONFIG_FB=y ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FB_CYBER2000 is not set ++# CONFIG_FB_VIRTUAL is not set ++CONFIG_FBCON_ADVANCED=y ++# CONFIG_FBCON_MFB is not set ++# CONFIG_FBCON_CFB2 is not set ++# CONFIG_FBCON_CFB4 is not set ++# CONFIG_FBCON_CFB8 is not set ++CONFIG_FBCON_CFB16=y ++# CONFIG_FBCON_CFB24 is not set ++# CONFIG_FBCON_CFB32 is not set ++# CONFIG_FBCON_AFB is not set ++# CONFIG_FBCON_ILBM is not set ++# CONFIG_FBCON_IPLAN2P2 is not set ++# CONFIG_FBCON_IPLAN2P4 is not set ++# CONFIG_FBCON_IPLAN2P8 is not set ++# CONFIG_FBCON_MAC is not set ++# CONFIG_FBCON_VGA_PLANES is not set ++# CONFIG_FBCON_VGA is not set ++# CONFIG_FBCON_HGA is not set ++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set ++CONFIG_FBCON_FONTS=y ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++# CONFIG_FONT_SUN8x16 is not set ++# CONFIG_FONT_SUN12x22 is not set ++# CONFIG_FONT_6x11 is not set ++# CONFIG_FONT_PEARL_8x8 is not set ++# CONFIG_FONT_ACORN_8x8 is not set ++ ++# ++# Sound ++# ++CONFIG_SOUND=y ++# 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 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 is not set ++# CONFIG_MIPS_UNCACHED is not set ++CONFIG_LOG_BUF_SHIFT=0 ++ ++# ++# Cryptographic options ++# ++# CONFIG_CRYPTO is not set ++ ++# ++# Library routines ++# ++# CONFIG_CRC32 is not set ++CONFIG_ZLIB_INFLATE=m ++CONFIG_ZLIB_DEFLATE=m +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-hp-lj linux-2.4.32-rc1.mips/arch/mips/defconfig-hp-lj +--- linux-2.4.32-rc1/arch/mips/defconfig-hp-lj 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-hp-lj 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -184,8 +184,8 @@ + # Mapping drivers for chip access + # + CONFIG_MTD_PHYSMAP=y +-CONFIG_MTD_PHYSMAP_START=10040000 +-CONFIG_MTD_PHYSMAP_LEN=00fc0000 ++CONFIG_MTD_PHYSMAP_START=0x10040000 ++CONFIG_MTD_PHYSMAP_LEN=0x00fc0000 + CONFIG_MTD_PHYSMAP_BUSWIDTH=4 + # CONFIG_MTD_PB1000 is not set + # CONFIG_MTD_PB1500 is not set +@@ -193,9 +193,7 @@ + # 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 +@@ -214,7 +212,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -304,11 +301,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -604,7 +596,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_UNIX98_PTYS is not set + + # +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-hydrogen3 linux-2.4.32-rc1.mips/arch/mips/defconfig-hydrogen3 +--- linux-2.4.32-rc1/arch/mips/defconfig-hydrogen3 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-hydrogen3 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-CONFIG_MIPS_HYDROGEN3=y + # CONFIG_MIPS_PB1550 is not set ++CONFIG_MIPS_HYDROGEN3=y + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set + # CONFIG_COGENT_CSB250 is not set +@@ -214,9 +214,7 @@ + # 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=y + # CONFIG_MTD_MIRAGE is not set + # CONFIG_MTD_CSTM_MIPS_IXX is not set + # CONFIG_MTD_OCELOT is not set +@@ -235,7 +233,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -340,11 +337,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -590,7 +582,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-CONFIG_MIPS_HYDROGEN3_BUTTONS=y + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +@@ -838,6 +829,7 @@ + # CONFIG_FB_PM2 is not set + # CONFIG_FB_PM3 is not set + # CONFIG_FB_CYBER2000 is not set ++CONFIG_FB_AU1100=y + # CONFIG_FB_MATROX is not set + # CONFIG_FB_ATY is not set + # CONFIG_FB_RADEON is not set +@@ -849,7 +841,6 @@ + # CONFIG_FB_VOODOO1 is not set + # CONFIG_FB_TRIDENT is not set + # CONFIG_FB_E1356 is not set +-CONFIG_FB_AU1100=y + # CONFIG_FB_IT8181 is not set + # CONFIG_FB_VIRTUAL is not set + CONFIG_FBCON_ADVANCED=y +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ip22 linux-2.4.32-rc1.mips/arch/mips/defconfig-ip22 +--- linux-2.4.32-rc1/arch/mips/defconfig-ip22 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ip22 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -235,11 +235,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -319,9 +314,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -465,7 +462,6 @@ + # CONFIG_SERIAL is not set + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-it8172 linux-2.4.32-rc1.mips/arch/mips/defconfig-it8172 +--- linux-2.4.32-rc1/arch/mips/defconfig-it8172 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-it8172 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -186,8 +186,8 @@ + # Mapping drivers for chip access + # + CONFIG_MTD_PHYSMAP=y +-CONFIG_MTD_PHYSMAP_START=8000000 +-CONFIG_MTD_PHYSMAP_LEN=2000000 ++CONFIG_MTD_PHYSMAP_START=0x8000000 ++CONFIG_MTD_PHYSMAP_LEN=0x2000000 + CONFIG_MTD_PHYSMAP_BUSWIDTH=4 + # CONFIG_MTD_PB1000 is not set + # CONFIG_MTD_PB1500 is not set +@@ -195,9 +195,7 @@ + # 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 +@@ -216,7 +214,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -304,11 +301,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -592,7 +584,6 @@ + CONFIG_PC_KEYB=y + # CONFIG_IT8172_SCR0 is not set + # CONFIG_IT8172_SCR1 is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ivr linux-2.4.32-rc1.mips/arch/mips/defconfig-ivr +--- linux-2.4.32-rc1/arch/mips/defconfig-ivr 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ivr 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -226,11 +226,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -516,7 +511,6 @@ + CONFIG_QTRONIX_KEYBOARD=y + CONFIG_IT8172_CIR=y + # CONFIG_IT8172_SCR0 is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-jmr3927 linux-2.4.32-rc1.mips/arch/mips/defconfig-jmr3927 +--- linux-2.4.32-rc1/arch/mips/defconfig-jmr3927 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-jmr3927 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -225,11 +225,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -454,7 +449,6 @@ + # CONFIG_SERIAL_TXX9_CONSOLE is not set + CONFIG_TXX927_SERIAL=y + CONFIG_TXX927_SERIAL_CONSOLE=y +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_UNIX98_PTYS is not set + + # +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-lasat linux-2.4.32-rc1.mips/arch/mips/defconfig-lasat +--- linux-2.4.32-rc1/arch/mips/defconfig-lasat 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-lasat 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -198,9 +198,7 @@ + # 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 +@@ -219,7 +217,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -303,11 +300,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -584,7 +576,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-malta linux-2.4.32-rc1.mips/arch/mips/defconfig-malta +--- linux-2.4.32-rc1/arch/mips/defconfig-malta 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-malta 2005-04-19 14:19:34.000000000 +0200 +@@ -22,16 +22,19 @@ + # + # 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_MIPS_HYDROGEN3 is not set + # 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 +@@ -237,11 +240,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -273,8 +271,83 @@ + # + # ATA/IDE/MFM/RLL support + # +-# CONFIG_IDE is not set ++CONFIG_IDE=y ++ ++# ++# IDE, ATA and ATAPI Block devices ++# ++CONFIG_BLK_DEV_IDE=y ++ ++# ++# Please see Documentation/ide.txt for help/info on IDE drives ++# ++# 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=y ++# CONFIG_IDEDISK_MULTI_MODE is not set ++# CONFIG_IDEDISK_STROKE is not set ++# CONFIG_BLK_DEV_IDECS is not set ++# CONFIG_BLK_DEV_DELKIN is not set ++CONFIG_BLK_DEV_IDECD=y ++CONFIG_BLK_DEV_IDETAPE=y ++CONFIG_BLK_DEV_IDEFLOPPY=y ++CONFIG_BLK_DEV_IDESCSI=y ++# CONFIG_IDE_TASK_IOCTL is not set ++ ++# ++# IDE chipset support/bugfixes ++# ++# CONFIG_BLK_DEV_CMD640 is not set ++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set ++# CONFIG_BLK_DEV_ISAPNP is not set ++CONFIG_BLK_DEV_IDEPCI=y ++CONFIG_BLK_DEV_GENERIC=y ++CONFIG_IDEPCI_SHARE_IRQ=y ++CONFIG_BLK_DEV_IDEDMA_PCI=y ++# CONFIG_BLK_DEV_OFFBOARD is not set ++CONFIG_BLK_DEV_IDEDMA_FORCED=y ++CONFIG_IDEDMA_PCI_AUTO=y ++# CONFIG_IDEDMA_ONLYDISK is not set ++CONFIG_BLK_DEV_IDEDMA=y ++# CONFIG_IDEDMA_PCI_WIP is not set ++# CONFIG_BLK_DEV_ADMA100 is not set ++# CONFIG_BLK_DEV_AEC62XX is not set ++# CONFIG_BLK_DEV_ALI15X3 is not set ++# CONFIG_WDC_ALI15X3 is not set ++# CONFIG_BLK_DEV_AMD74XX is not set ++# CONFIG_AMD74XX_OVERRIDE is not set ++# CONFIG_BLK_DEV_ATIIXP is not set ++# CONFIG_BLK_DEV_CMD64X is not set ++# CONFIG_BLK_DEV_TRIFLEX is not set ++# CONFIG_BLK_DEV_CY82C693 is not set ++# CONFIG_BLK_DEV_CS5530 is not set ++# CONFIG_BLK_DEV_HPT34X is not set ++# CONFIG_HPT34X_AUTODMA is not set ++# CONFIG_BLK_DEV_HPT366 is not set ++CONFIG_BLK_DEV_PIIX=y ++# CONFIG_BLK_DEV_NS87415 is not set ++# CONFIG_BLK_DEV_OPTI621 is not set ++# CONFIG_BLK_DEV_PDC202XX_OLD is not set ++# CONFIG_PDC202XX_BURST is not set ++# CONFIG_BLK_DEV_PDC202XX_NEW is not set ++# CONFIG_BLK_DEV_RZ1000 is not set ++# CONFIG_BLK_DEV_SC1200 is not set ++# CONFIG_BLK_DEV_SVWKS is not set ++# CONFIG_BLK_DEV_SIIMAGE is not set ++# CONFIG_BLK_DEV_SIS5513 is not set ++# CONFIG_BLK_DEV_SLC90E66 is not set ++# CONFIG_BLK_DEV_TRM290 is not set ++# CONFIG_BLK_DEV_VIA82CXXX is not set ++# CONFIG_IDE_CHIPSETS is not set ++CONFIG_IDEDMA_AUTO=y ++# CONFIG_IDEDMA_IVB 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 +@@ -319,9 +392,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -524,7 +599,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-mirage linux-2.4.32-rc1.mips/arch/mips/defconfig-mirage +--- linux-2.4.32-rc1/arch/mips/defconfig-mirage 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-mirage 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -209,9 +209,7 @@ + # 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=y + # CONFIG_MTD_CSTM_MIPS_IXX is not set + # CONFIG_MTD_OCELOT is not set +@@ -230,7 +228,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -335,11 +332,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -560,7 +552,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-mpc30x linux-2.4.32-rc1.mips/arch/mips/defconfig-mpc30x +--- linux-2.4.32-rc1/arch/mips/defconfig-mpc30x 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-mpc30x 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -228,11 +228,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -400,7 +395,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-mtx-1 linux-2.4.32-rc1.mips/arch/mips/defconfig-mtx-1 +--- linux-2.4.32-rc1/arch/mips/defconfig-mtx-1 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-mtx-1 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 is not set ++# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_XXS1500 is not set + CONFIG_MIPS_MTX1=y + # CONFIG_COGENT_CSB250 is not set +@@ -193,9 +193,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + CONFIG_MTD_MTX1=y +-# 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 +@@ -214,7 +212,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -371,11 +368,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + CONFIG_BRIDGE=m + # CONFIG_X25 is not set +@@ -479,9 +471,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -700,7 +694,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-nino linux-2.4.32-rc1.mips/arch/mips/defconfig-nino +--- linux-2.4.32-rc1/arch/mips/defconfig-nino 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-nino 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -226,11 +226,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -339,7 +334,6 @@ + # CONFIG_SERIAL_TXX9 is not set + # CONFIG_SERIAL_TXX9_CONSOLE is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_UNIX98_PTYS is not set + + # +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ocelot linux-2.4.32-rc1.mips/arch/mips/defconfig-ocelot +--- linux-2.4.32-rc1/arch/mips/defconfig-ocelot 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ocelot 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -194,9 +194,7 @@ + # 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=y +@@ -215,7 +213,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + CONFIG_MTD_DOC2000=y + # CONFIG_MTD_DOC2001 is not set + CONFIG_MTD_DOCPROBE=y +@@ -307,11 +304,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -513,7 +505,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-osprey linux-2.4.32-rc1.mips/arch/mips/defconfig-osprey +--- linux-2.4.32-rc1/arch/mips/defconfig-osprey 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-osprey 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -227,11 +227,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -388,7 +383,6 @@ + # CONFIG_SERIAL_MULTIPORT is not set + # CONFIG_HUB6 is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-pb1000 linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1000 +--- linux-2.4.32-rc1/arch/mips/defconfig-pb1000 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1000 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + CONFIG_MIPS_PB1000=y + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -215,9 +215,7 @@ + # 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 +@@ -236,7 +234,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -324,11 +321,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -622,7 +614,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +@@ -707,7 +698,7 @@ + # + # CONFIG_PCMCIA_SERIAL_CS is not set + # CONFIG_SYNCLINK_CS is not set +-CONFIG_AU1X00_GPIO=m ++CONFIG_AU1X00_GPIO=y + # CONFIG_TS_AU1X00_ADS7846 is not set + + # +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-pb1100 linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1100 +--- linux-2.4.32-rc1/arch/mips/defconfig-pb1100 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1100 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + CONFIG_MIPS_PB1100=y + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -198,9 +198,7 @@ + # CONFIG_MTD_MTX1 is not set + CONFIG_MTD_PB1500_BOOT=y + CONFIG_MTD_PB1500_USER=y +-# 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 +@@ -219,7 +217,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -324,11 +321,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -613,7 +605,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +@@ -859,6 +850,7 @@ + # CONFIG_FB_PM2 is not set + # CONFIG_FB_PM3 is not set + # CONFIG_FB_CYBER2000 is not set ++CONFIG_FB_AU1100=y + # CONFIG_FB_MATROX is not set + # CONFIG_FB_ATY is not set + # CONFIG_FB_RADEON is not set +@@ -870,7 +862,6 @@ + # CONFIG_FB_VOODOO1 is not set + # CONFIG_FB_TRIDENT is not set + # CONFIG_FB_E1356 is not set +-CONFIG_FB_AU1100=y + # CONFIG_FB_IT8181 is not set + # CONFIG_FB_VIRTUAL is not set + CONFIG_FBCON_ADVANCED=y +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-pb1200 linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1200 +--- linux-2.4.32-rc1/arch/mips/defconfig-pb1200 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1200 2005-03-18 13:13:21.000000000 +0100 +@@ -0,0 +1,1060 @@ ++# ++# Automatically generated make config: 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_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_PB1000 is not set ++# CONFIG_MIPS_PB1100 is not set ++# CONFIG_MIPS_PB1500 is not set ++# CONFIG_MIPS_PB1550 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_SOC_AU1X00=y ++CONFIG_SOC_AU1200=y ++CONFIG_NONCOHERENT_IO=y ++CONFIG_PC_KEYB=y ++# CONFIG_MIPS_AU1000 is not set ++ ++# ++# CPU selection ++# ++CONFIG_CPU_MIPS32=y ++# CONFIG_CPU_MIPS64 is not set ++# CONFIG_CPU_R3000 is not set ++# CONFIG_CPU_TX39XX is not set ++# CONFIG_CPU_VR41XX is not set ++# 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_HAS_PREFETCH=y ++# CONFIG_VTAG_ICACHE is not set ++CONFIG_64BIT_PHYS_ADDR=y ++# CONFIG_CPU_ADVANCED is not set ++CONFIG_CPU_HAS_LLSC=y ++# 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=y ++# CONFIG_BUILD_ELF64 is not set ++CONFIG_NET=y ++CONFIG_PCI=y ++CONFIG_PCI_NEW=y ++CONFIG_PCI_AUTO=y ++# CONFIG_PCI_NAMES is not set ++# CONFIG_ISA is not set ++# CONFIG_TC is not set ++# CONFIG_MCA is not set ++# CONFIG_SBUS is not set ++CONFIG_HOTPLUG=y ++ ++# ++# PCMCIA/CardBus support ++# ++CONFIG_PCMCIA=m ++# CONFIG_CARDBUS is not set ++# CONFIG_TCIC is not set ++# CONFIG_I82092 is not set ++# CONFIG_I82365 is not set ++CONFIG_PCMCIA_AU1X00=m ++ ++# ++# PCI Hotplug Support ++# ++# CONFIG_HOTPLUG_PCI is not set ++# CONFIG_HOTPLUG_PCI_COMPAQ is not set ++# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set ++# CONFIG_HOTPLUG_PCI_SHPC is not set ++# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set ++# CONFIG_HOTPLUG_PCI_PCIE is not set ++# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE 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_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=y ++CONFIG_CMDLINE="mem=96M" ++# CONFIG_PM is not set ++ ++# ++# Memory Technology Devices (MTD) ++# ++# CONFIG_MTD is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT 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=y ++# CONFIG_BLK_DEV_NBD is not set ++# 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 is not set ++# CONFIG_NETLINK_DEV is not set ++CONFIG_NETFILTER=y ++# CONFIG_NETFILTER_DEBUG is not set ++CONFIG_FILTER=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++CONFIG_IP_PNP_BOOTP=y ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE 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 is not set ++# CONFIG_IP_NF_QUEUE is not set ++# CONFIG_IP_NF_IPTABLES is not set ++# CONFIG_IP_NF_ARPTABLES is not set ++# CONFIG_IP_NF_COMPAT_IPCHAINS is not set ++# CONFIG_IP_NF_COMPAT_IPFWADM is not set ++ ++# ++# IP: Virtual Server Configuration ++# ++# CONFIG_IP_VS is not set ++# CONFIG_IPV6 is not set ++# CONFIG_KHTTPD is not set ++ ++# ++# SCTP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_SCTP is not set ++# CONFIG_ATM is not set ++# CONFIG_VLAN_8021Q is not set ++ ++# ++# ++# ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_DECNET is not set ++# CONFIG_BRIDGE is not set ++# 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 is not set ++# CONFIG_NET_FASTROUTE is not set ++# CONFIG_NET_HW_FLOWCONTROL is not set ++ ++# ++# QoS and/or fair queueing ++# ++# CONFIG_NET_SCHED is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++ ++# ++# 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=y ++ ++# ++# IDE, ATA and ATAPI Block devices ++# ++CONFIG_BLK_DEV_IDE=y ++ ++# ++# Please see Documentation/ide.txt for help/info on IDE drives ++# ++# 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=y ++CONFIG_IDEDISK_MULTI_MODE=y ++CONFIG_IDEDISK_STROKE=y ++CONFIG_BLK_DEV_IDECS=m ++# 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 ++ ++# ++# IDE chipset support/bugfixes ++# ++# CONFIG_BLK_DEV_CMD640 is not set ++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set ++# CONFIG_BLK_DEV_ISAPNP is not set ++# CONFIG_BLK_DEV_IDEPCI 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=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++CONFIG_SD_EXTRA_DEVS=40 ++CONFIG_CHR_DEV_ST=y ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++CONFIG_SR_EXTRA_DEVS=2 ++# CONFIG_CHR_DEV_SG is not set ++ ++# ++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs ++# ++# CONFIG_SCSI_DEBUG_QUEUES is not set ++# CONFIG_SCSI_MULTI_LUN is not set ++CONFIG_SCSI_CONSTANTS=y ++# CONFIG_SCSI_LOGGING is not set ++ ++# ++# SCSI low-level drivers ++# ++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set ++# CONFIG_SCSI_7000FASST is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_AHA152X is not set ++# CONFIG_SCSI_AHA1542 is not set ++# CONFIG_SCSI_AHA1740 is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC79XX is not set ++# CONFIG_SCSI_AIC7XXX_OLD is not set ++# CONFIG_SCSI_DPT_I2O is not set ++# CONFIG_SCSI_ADVANSYS is not set ++# CONFIG_SCSI_IN2000 is not set ++# CONFIG_SCSI_AM53C974 is not set ++# CONFIG_SCSI_MEGARAID is not set ++# CONFIG_SCSI_MEGARAID2 is not set ++# CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set ++# CONFIG_SCSI_SATA_SVW is not set ++# CONFIG_SCSI_ATA_PIIX is not set ++# CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set ++# CONFIG_SCSI_SATA_PROMISE is not set ++# CONFIG_SCSI_SATA_SX4 is not set ++# CONFIG_SCSI_SATA_SIL is not set ++# CONFIG_SCSI_SATA_SIS is not set ++# CONFIG_SCSI_SATA_ULI is not set ++# CONFIG_SCSI_SATA_VIA is not set ++# CONFIG_SCSI_SATA_VITESSE is not set ++# CONFIG_SCSI_BUSLOGIC is not set ++# CONFIG_SCSI_CPQFCTS is not set ++# CONFIG_SCSI_DMX3191D is not set ++# CONFIG_SCSI_DTC3280 is not set ++# CONFIG_SCSI_EATA is not set ++# CONFIG_SCSI_EATA_DMA is not set ++# CONFIG_SCSI_EATA_PIO is not set ++# CONFIG_SCSI_FUTURE_DOMAIN is not set ++# CONFIG_SCSI_GDTH is not set ++# CONFIG_SCSI_GENERIC_NCR5380 is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_NCR53C406A is not set ++# CONFIG_SCSI_NCR53C7xx is not set ++# CONFIG_SCSI_SYM53C8XX_2 is not set ++# CONFIG_SCSI_NCR53C8XX is not set ++# CONFIG_SCSI_SYM53C8XX is not set ++# CONFIG_SCSI_PAS16 is not set ++# CONFIG_SCSI_PCI2000 is not set ++# CONFIG_SCSI_PCI2220I is not set ++# CONFIG_SCSI_PSI240I is not set ++# CONFIG_SCSI_QLOGIC_FAS is not set ++# CONFIG_SCSI_QLOGIC_ISP is not set ++# CONFIG_SCSI_QLOGIC_FC is not set ++# CONFIG_SCSI_QLOGIC_1280 is not set ++# CONFIG_SCSI_SIM710 is not set ++# CONFIG_SCSI_SYM53C416 is not set ++# CONFIG_SCSI_DC390T is not set ++# CONFIG_SCSI_T128 is not set ++# CONFIG_SCSI_U14_34F is not set ++# CONFIG_SCSI_NSP32 is not set ++# CONFIG_SCSI_DEBUG is not set ++ ++# ++# PCMCIA SCSI adapter support ++# ++# CONFIG_SCSI_PCMCIA 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 ++ ++# ++# IEEE 1394 (FireWire) support (EXPERIMENTAL) ++# ++# CONFIG_IEEE1394 is not set ++ ++# ++# I2O device support ++# ++# CONFIG_I2O is not set ++# CONFIG_I2O_PCI is not set ++# CONFIG_I2O_BLOCK is not set ++# CONFIG_I2O_LAN is not set ++# CONFIG_I2O_SCSI is not set ++# CONFIG_I2O_PROC 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_TUN is not set ++# CONFIG_ETHERTAP is not set ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++CONFIG_NET_ETHERNET=y ++# CONFIG_MIPS_AU1X00_ENET is not set ++# CONFIG_SUNLANCE is not set ++# CONFIG_HAPPYMEAL 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_HP100 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=y ++# CONFIG_PPP_FILTER is not set ++CONFIG_PPP_ASYNC=m ++# CONFIG_PPP_SYNC_TTY is not set ++CONFIG_PPP_DEFLATE=m ++# CONFIG_PPP_BSDCOMP is not set ++CONFIG_PPPOE=m ++# CONFIG_SLIP is not set ++ ++# ++# Wireless LAN (non-hamradio) ++# ++# CONFIG_NET_RADIO is not set ++ ++# ++# Token Ring devices ++# ++# CONFIG_TR is not set ++# CONFIG_NET_FC is not set ++# CONFIG_RCPCI is not set ++# CONFIG_SHAPER is not set ++ ++# ++# Wan interfaces ++# ++# CONFIG_WAN is not set ++ ++# ++# PCMCIA network device support ++# ++# CONFIG_NET_PCMCIA is not set ++ ++# ++# Amateur Radio support ++# ++# CONFIG_HAMRADIO is not set ++ ++# ++# IrDA (infrared) support ++# ++# CONFIG_IRDA is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Input core support ++# ++CONFIG_INPUT=y ++CONFIG_INPUT_KEYBDEV=y ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_UINPUT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++# CONFIG_VT_CONSOLE is not set ++# CONFIG_SERIAL is not set ++# CONFIG_SERIAL_EXTENDED is not set ++CONFIG_SERIAL_NONSTANDARD=y ++# CONFIG_COMPUTONE is not set ++# CONFIG_ROCKETPORT is not set ++# CONFIG_CYCLADES is not set ++# CONFIG_DIGIEPCA is not set ++# CONFIG_DIGI is not set ++# CONFIG_ESPSERIAL is not set ++# CONFIG_MOXA_INTELLIO is not set ++# CONFIG_MOXA_SMARTIO is not set ++# CONFIG_ISI is not set ++# CONFIG_SYNCLINK is not set ++# CONFIG_SYNCLINKMP is not set ++# CONFIG_N_HDLC is not set ++# CONFIG_RISCOM8 is not set ++# CONFIG_SPECIALIX is not set ++# CONFIG_SX is not set ++# CONFIG_RIO is not set ++# CONFIG_STALDRV is not set ++# CONFIG_SERIAL_TX3912 is not set ++# CONFIG_SERIAL_TX3912_CONSOLE is not set ++# CONFIG_SERIAL_TXX9 is not set ++# CONFIG_SERIAL_TXX9_CONSOLE is not set ++CONFIG_AU1X00_UART=y ++CONFIG_AU1X00_SERIAL_CONSOLE=y ++# CONFIG_AU1X00_USB_TTY is not set ++# CONFIG_AU1X00_USB_RAW is not set ++# CONFIG_TXX927_SERIAL is not set ++CONFIG_UNIX98_PTYS=y ++CONFIG_UNIX98_PTY_COUNT=256 ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++# CONFIG_I2C_ALGOBIT is not set ++# CONFIG_SCx200_ACB is not set ++# CONFIG_I2C_ALGOPCF is not set ++# CONFIG_I2C_CHARDEV is not set ++CONFIG_I2C_PROC=y ++ ++# ++# Mice ++# ++# CONFIG_BUSMOUSE is not set ++# CONFIG_MOUSE is not set ++ ++# ++# Joysticks ++# ++# CONFIG_INPUT_GAMEPORT is not set ++# CONFIG_INPUT_NS558 is not set ++# CONFIG_INPUT_LIGHTNING is not set ++# CONFIG_INPUT_PCIGAME is not set ++# CONFIG_INPUT_CS461X is not set ++# CONFIG_INPUT_EMU10K1 is not set ++# CONFIG_INPUT_SERIO is not set ++# CONFIG_INPUT_SERPORT is not set ++ ++# ++# Joysticks ++# ++# CONFIG_INPUT_ANALOG is not set ++# CONFIG_INPUT_A3D is not set ++# CONFIG_INPUT_ADI is not set ++# CONFIG_INPUT_COBRA is not set ++# CONFIG_INPUT_GF2K is not set ++# CONFIG_INPUT_GRIP is not set ++# CONFIG_INPUT_INTERACT is not set ++# CONFIG_INPUT_TMDC is not set ++# CONFIG_INPUT_SIDEWINDER is not set ++# CONFIG_INPUT_IFORCE_USB is not set ++# CONFIG_INPUT_IFORCE_232 is not set ++# CONFIG_INPUT_WARRIOR is not set ++# CONFIG_INPUT_MAGELLAN is not set ++# CONFIG_INPUT_SPACEORB is not set ++# CONFIG_INPUT_SPACEBALL is not set ++# CONFIG_INPUT_STINGER is not set ++# CONFIG_INPUT_DB9 is not set ++# CONFIG_INPUT_GAMECON is not set ++# CONFIG_INPUT_TURBOGRAFX 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 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 ++ ++# ++# PCMCIA character devices ++# ++# CONFIG_PCMCIA_SERIAL_CS is not set ++# CONFIG_SYNCLINK_CS is not set ++# CONFIG_AU1X00_GPIO is not set ++# CONFIG_TS_AU1X00_ADS7846 is not set ++ ++# ++# File systems ++# ++# CONFIG_QUOTA is not set ++# CONFIG_QFMT_V2 is not set ++CONFIG_AUTOFS_FS=y ++# 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 is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BEFS_DEBUG is not set ++# CONFIG_BFS_FS is not set ++CONFIG_EXT3_FS=y ++CONFIG_JBD=y ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++# CONFIG_UMSDOS_FS is not set ++CONFIG_VFAT_FS=y ++# CONFIG_EFS_FS is not set ++# CONFIG_JFFS_FS is not set ++# CONFIG_JFFS2_FS is not set ++# CONFIG_CRAMFS is not set ++CONFIG_TMPFS=y ++CONFIG_RAMFS=y ++# CONFIG_ISO9660_FS is not set ++# CONFIG_JOLIET is not set ++# 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 is not set ++# CONFIG_DEVFS_MOUNT is not set ++# 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=y ++# 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 is not set ++# 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=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_DIRECTIO is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFSD is not set ++# CONFIG_NFSD_V3 is not set ++# CONFIG_NFSD_TCP is not set ++CONFIG_SUNRPC=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=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 is not set ++CONFIG_MSDOS_PARTITION=y ++# 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 is not set ++ ++# ++# Console drivers ++# ++# CONFIG_VGA_CONSOLE is not set ++# CONFIG_MDA_CONSOLE is not set ++ ++# ++# Frame-buffer support ++# ++CONFIG_FB=y ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FB_RIVA is not set ++# CONFIG_FB_CLGEN is not set ++# CONFIG_FB_PM2 is not set ++# CONFIG_FB_PM3 is not set ++# CONFIG_FB_CYBER2000 is not set ++# CONFIG_FB_MATROX is not set ++# CONFIG_FB_ATY is not set ++# CONFIG_FB_RADEON is not set ++# CONFIG_FB_ATY128 is not set ++# CONFIG_FB_INTEL is not set ++# CONFIG_FB_SIS is not set ++# CONFIG_FB_NEOMAGIC is not set ++# CONFIG_FB_3DFX is not set ++# CONFIG_FB_VOODOO1 is not set ++# CONFIG_FB_TRIDENT is not set ++# CONFIG_FB_E1356 is not set ++# CONFIG_FB_IT8181 is not set ++# CONFIG_FB_VIRTUAL is not set ++CONFIG_FBCON_ADVANCED=y ++# CONFIG_FBCON_MFB is not set ++# CONFIG_FBCON_CFB2 is not set ++# CONFIG_FBCON_CFB4 is not set ++# CONFIG_FBCON_CFB8 is not set ++CONFIG_FBCON_CFB16=y ++# CONFIG_FBCON_CFB24 is not set ++CONFIG_FBCON_CFB32=y ++# CONFIG_FBCON_AFB is not set ++# CONFIG_FBCON_ILBM is not set ++# CONFIG_FBCON_IPLAN2P2 is not set ++# CONFIG_FBCON_IPLAN2P4 is not set ++# CONFIG_FBCON_IPLAN2P8 is not set ++# CONFIG_FBCON_MAC is not set ++# CONFIG_FBCON_VGA_PLANES is not set ++# CONFIG_FBCON_VGA is not set ++# CONFIG_FBCON_HGA is not set ++# CONFIG_FBCON_FONTWIDTH8_ONLY is not set ++CONFIG_FBCON_FONTS=y ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++# CONFIG_FONT_SUN8x16 is not set ++# CONFIG_FONT_SUN12x22 is not set ++# CONFIG_FONT_6x11 is not set ++# CONFIG_FONT_PEARL_8x8 is not set ++# CONFIG_FONT_ACORN_8x8 is not set ++ ++# ++# Sound ++# ++CONFIG_SOUND=y ++# 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_AU1X00 is not set ++CONFIG_SOUND_AU1550_PSC=y ++# CONFIG_SOUND_AU1550_I2S 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=y ++# CONFIG_USB_DEBUG is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEVICEFS=y ++# CONFIG_USB_BANDWIDTH is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_UHCI is not set ++# CONFIG_USB_UHCI_ALT is not set ++CONFIG_USB_OHCI=y ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_AUDIO is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_BLUETOOTH is not set ++# CONFIG_USB_MIDI is not set ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_DPCM is not set ++# CONFIG_USB_STORAGE_HP8200e is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++ ++# ++# USB Human Interface Devices (HID) ++# ++CONFIG_USB_HID=y ++CONFIG_USB_HIDINPUT=y ++CONFIG_USB_HIDDEV=y ++# CONFIG_USB_AIPTEK is not set ++# CONFIG_USB_WACOM is not set ++# CONFIG_USB_KBTAB is not set ++# CONFIG_USB_POWERMATE is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_DC2XX is not set ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_SCANNER is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USB_HPUSBSCSI is not set ++ ++# ++# USB Multimedia devices ++# ++ ++# ++# Video4Linux support is needed for USB Multimedia device support ++# ++ ++# ++# USB Network adaptors ++# ++# CONFIG_USB_PEGASUS is not set ++# CONFIG_USB_RTL8150 is not set ++# CONFIG_USB_KAWETH is not set ++# CONFIG_USB_CATC is not set ++# CONFIG_USB_CDCETHER is not set ++# CONFIG_USB_USBNET is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_USS720 is not set ++ ++# ++# USB Serial Converter support ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_AUERSWALD is not set ++# CONFIG_USB_TIGL is not set ++# CONFIG_USB_BRLVGER is not set ++# CONFIG_USB_LCD is not set ++ ++# ++# Support for USB gadgets ++# ++# CONFIG_USB_GADGET is not set ++ ++# ++# Bluetooth support ++# ++# CONFIG_BLUEZ 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 is not set ++# CONFIG_MIPS_UNCACHED is not set ++CONFIG_LOG_BUF_SHIFT=0 ++ ++# ++# Cryptographic options ++# ++# CONFIG_CRYPTO is not set ++ ++# ++# Library routines ++# ++# CONFIG_CRC32 is not set ++CONFIG_ZLIB_INFLATE=m ++CONFIG_ZLIB_DEFLATE=m ++# CONFIG_FW_LOADER is not set +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-pb1500 linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1500 +--- linux-2.4.32-rc1/arch/mips/defconfig-pb1500 2005-01-19 15:09:28.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1500 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + CONFIG_MIPS_PB1500=y +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -215,9 +215,7 @@ + # CONFIG_MTD_MTX1 is not set + CONFIG_MTD_PB1500_BOOT=y + # CONFIG_MTD_PB1500_USER 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 +@@ -236,7 +234,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -341,11 +338,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -675,7 +667,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-pb1550 linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1550 +--- linux-2.4.32-rc1/arch/mips/defconfig-pb1550 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-pb1550 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + CONFIG_MIPS_PB1550=y ++# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set + # CONFIG_COGENT_CSB250 is not set +@@ -213,11 +213,9 @@ + # 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=y + CONFIG_MTD_PB1550_BOOT=y + CONFIG_MTD_PB1550_USER=y +-# 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 +@@ -236,7 +234,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -343,11 +340,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -633,7 +625,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-rbtx4927 linux-2.4.32-rc1.mips/arch/mips/defconfig-rbtx4927 +--- linux-2.4.32-rc1/arch/mips/defconfig-rbtx4927 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-rbtx4927 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -223,11 +223,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -466,7 +461,6 @@ + CONFIG_SERIAL_TXX9=y + CONFIG_SERIAL_TXX9_CONSOLE=y + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_UNIX98_PTYS is not set + + # +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-rm200 linux-2.4.32-rc1.mips/arch/mips/defconfig-rm200 +--- linux-2.4.32-rc1/arch/mips/defconfig-rm200 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-rm200 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -229,11 +229,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -340,7 +335,6 @@ + # CONFIG_SERIAL is not set + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-sb1250-swarm linux-2.4.32-rc1.mips/arch/mips/defconfig-sb1250-swarm +--- linux-2.4.32-rc1/arch/mips/defconfig-sb1250-swarm 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-sb1250-swarm 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -90,6 +90,7 @@ + # CONFIG_SIBYTE_TBPROF is not set + CONFIG_SIBYTE_GENBUS_IDE=y + CONFIG_SMP_CAPABLE=y ++CONFIG_MIPS_RTC=y + # CONFIG_SNI_RM200_PCI is not set + # CONFIG_TANBAC_TB0226 is not set + # CONFIG_TANBAC_TB0229 is not set +@@ -253,11 +254,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -469,7 +465,6 @@ + CONFIG_SIBYTE_SB1250_DUART=y + CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y + CONFIG_SERIAL_CONSOLE=y +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-sead linux-2.4.32-rc1.mips/arch/mips/defconfig-sead +--- linux-2.4.32-rc1/arch/mips/defconfig-sead 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-sead 2005-03-18 13:13:21.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -244,7 +244,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_UNIX98_PTYS is not set + + # +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-stretch linux-2.4.32-rc1.mips/arch/mips/defconfig-stretch +--- linux-2.4.32-rc1/arch/mips/defconfig-stretch 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-stretch 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -240,11 +240,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -324,9 +319,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -516,7 +513,6 @@ + # CONFIG_SERIAL_TXX9 is not set + # CONFIG_SERIAL_TXX9_CONSOLE is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-tb0226 linux-2.4.32-rc1.mips/arch/mips/defconfig-tb0226 +--- linux-2.4.32-rc1/arch/mips/defconfig-tb0226 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-tb0226 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -228,11 +228,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -312,9 +307,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -518,7 +515,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-tb0229 linux-2.4.32-rc1.mips/arch/mips/defconfig-tb0229 +--- linux-2.4.32-rc1/arch/mips/defconfig-tb0229 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-tb0229 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -230,11 +230,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -445,7 +440,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-ti1500 linux-2.4.32-rc1.mips/arch/mips/defconfig-ti1500 +--- linux-2.4.32-rc1/arch/mips/defconfig-ti1500 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-ti1500 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 is not set ++# CONFIG_MIPS_HYDROGEN3 is not set + CONFIG_MIPS_XXS1500=y + # CONFIG_MIPS_MTX1 is not set + # CONFIG_COGENT_CSB250 is not set +@@ -213,9 +213,7 @@ + # CONFIG_MTD_BOSPORUS is not set + CONFIG_MTD_XXS1500=y + # 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 +@@ -234,7 +232,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -339,11 +336,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -600,7 +592,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-workpad linux-2.4.32-rc1.mips/arch/mips/defconfig-workpad +--- linux-2.4.32-rc1/arch/mips/defconfig-workpad 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-workpad 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -222,11 +222,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -426,7 +421,6 @@ + # CONFIG_SERIAL_MULTIPORT is not set + # CONFIG_HUB6 is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_VR41XX_KIU is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-xxs1500 linux-2.4.32-rc1.mips/arch/mips/defconfig-xxs1500 +--- linux-2.4.32-rc1/arch/mips/defconfig-xxs1500 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-xxs1500 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 is not set ++# CONFIG_MIPS_HYDROGEN3 is not set + CONFIG_MIPS_XXS1500=y + # CONFIG_MIPS_MTX1 is not set + # CONFIG_COGENT_CSB250 is not set +@@ -213,9 +213,7 @@ + # CONFIG_MTD_BOSPORUS is not set + CONFIG_MTD_XXS1500=y + # 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 +@@ -234,7 +232,6 @@ + # + # Disk-On-Chip Device Drivers + # +-# CONFIG_MTD_DOC1000 is not set + # CONFIG_MTD_DOC2000 is not set + # CONFIG_MTD_DOC2001 is not set + # CONFIG_MTD_DOCPROBE is not set +@@ -339,11 +336,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -671,7 +663,6 @@ + # CONFIG_AU1X00_USB_TTY is not set + # CONFIG_AU1X00_USB_RAW is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/defconfig-yosemite linux-2.4.32-rc1.mips/arch/mips/defconfig-yosemite +--- linux-2.4.32-rc1/arch/mips/defconfig-yosemite 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/defconfig-yosemite 2005-03-18 13:13:21.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -227,11 +227,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -310,9 +305,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -477,7 +474,6 @@ + # CONFIG_SERIAL_TXX9 is not set + # CONFIG_SERIAL_TXX9_CONSOLE is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips/kernel/cpu-probe.c linux-2.4.32-rc1.mips/arch/mips/kernel/cpu-probe.c +--- linux-2.4.32-rc1/arch/mips/kernel/cpu-probe.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/kernel/cpu-probe.c 2005-05-25 15:33:22.000000000 +0200 +@@ -34,21 +34,16 @@ + ".set\tmips0"); + } + +-/* The Au1xxx wait is available only if we run CONFIG_PM and +- * the timer setup found we had a 32KHz counter available. +- * There are still problems with functions that may call au1k_wait +- * directly, but that will be discovered pretty quickly. +- */ +-extern void (*au1k_wait_ptr)(void); +-void au1k_wait(void) ++/* The Au1xxx wait is available only if using 32khz counter or ++ * external timer source, but specifically not CP0 Counter. */ ++int allow_au1k_wait; ++ ++static void au1k_wait(void) + { +-#ifdef CONFIG_PM +- unsigned long addr; + /* using the wait instruction makes CP0 counter unusable */ +- __asm__("la %0,au1k_wait\n\t" +- ".set mips3\n\t" +- "cache 0x14,0(%0)\n\t" +- "cache 0x14,32(%0)\n\t" ++ __asm__(".set mips3\n\t" ++ "cache 0x14, 0(%0)\n\t" ++ "cache 0x14, 32(%0)\n\t" + "sync\n\t" + "nop\n\t" + "wait\n\t" +@@ -57,11 +52,7 @@ + "nop\n\t" + "nop\n\t" + ".set mips0\n\t" +- : : "r" (addr)); +-#else +- __asm__("nop\n\t" +- "nop"); +-#endif ++ : : "r" (au1k_wait)); + } + + static inline void check_wait(void) +@@ -100,20 +91,17 @@ + cpu_wait = r4k_wait; + printk(" available.\n"); + break; +-#ifdef CONFIG_PM + case CPU_AU1000: + case CPU_AU1100: + case CPU_AU1500: + case CPU_AU1550: +- if (au1k_wait_ptr != NULL) { +- cpu_wait = au1k_wait_ptr; ++ case CPU_AU1200: ++ if (allow_au1k_wait) { ++ cpu_wait = au1k_wait; + printk(" available.\n"); +- } +- else { ++ } else + printk(" unavailable.\n"); +- } + break; +-#endif + default: + printk(" unavailable.\n"); + break; +diff -Nur linux-2.4.32-rc1/arch/mips/kernel/head.S linux-2.4.32-rc1.mips/arch/mips/kernel/head.S +--- linux-2.4.32-rc1/arch/mips/kernel/head.S 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/kernel/head.S 2004-11-22 14:38:23.000000000 +0100 +@@ -43,9 +43,9 @@ + + /* Cache Error */ + LEAF(except_vec2_generic) ++ .set push + .set noreorder + .set noat +- .set mips0 + /* + * This is a very bad place to be. Our cache error + * detection has triggered. If we have write-back data +@@ -64,10 +64,9 @@ + + j cache_parity_error + nop ++ .set pop + END(except_vec2_generic) + +- .set at +- + /* + * Special interrupt vector for embedded MIPS. This is a + * dedicated interrupt vector which reduces interrupt processing +@@ -76,8 +75,11 @@ + * size! + */ + NESTED(except_vec4, 0, sp) ++ .set push ++ .set noreorder + 1: j 1b /* Dummy, will be replaced */ + nop ++ .set pop + END(except_vec4) + + /* +@@ -87,8 +89,11 @@ + * unconditional jump to this vector. + */ + NESTED(except_vec_ejtag_debug, 0, sp) ++ .set push ++ .set noreorder + j ejtag_debug_handler + nop ++ .set pop + END(except_vec_ejtag_debug) + + __FINIT +@@ -97,6 +102,7 @@ + * EJTAG debug exception handler. + */ + NESTED(ejtag_debug_handler, PT_SIZE, sp) ++ .set push + .set noat + .set noreorder + mtc0 k0, CP0_DESAVE +@@ -120,7 +126,7 @@ + deret + .set mips0 + nop +- .set at ++ .set pop + END(ejtag_debug_handler) + + __INIT +@@ -132,13 +138,17 @@ + * unconditional jump to this vector. + */ + NESTED(except_vec_nmi, 0, sp) ++ .set push ++ .set noreorder + j nmi_handler + nop ++ .set pop + END(except_vec_nmi) + + __FINIT + + NESTED(nmi_handler, PT_SIZE, sp) ++ .set push + .set noat + .set noreorder + .set mips3 +@@ -147,8 +157,7 @@ + move a0, sp + RESTORE_ALL + eret +- .set at +- .set mips0 ++ .set pop + END(nmi_handler) + + __INIT +@@ -157,7 +166,20 @@ + * Kernel entry point + */ + NESTED(kernel_entry, 16, sp) ++ .set push ++ /* ++ * For the moment disable interrupts and mark the kernel mode. ++ * A full initialization of the CPU's status register is done ++ * later in per_cpu_trap_init(). ++ */ ++ mfc0 t0, CP0_STATUS ++ or t0, ST0_CU0|0x1f ++ xor t0, 0x1f ++ mtc0 t0, CP0_STATUS ++ + .set noreorder ++ sll zero,3 # ehb ++ .set reorder + + /* + * The firmware/bootloader passes argc/argp/envp +@@ -170,8 +192,8 @@ + la t1, (_end - 4) + 1: + addiu t0, 4 ++ sw zero, (t0) + bne t0, t1, 1b +- sw zero, (t0) + + /* + * Stack for kernel and init, current variable +@@ -182,7 +204,7 @@ + sw t0, kernelsp + + jal init_arch +- nop ++ .set pop + END(kernel_entry) + + +@@ -193,17 +215,26 @@ + * function after setting up the stack and gp registers. + */ + LEAF(smp_bootstrap) +- .set push +- .set noreorder +- mtc0 zero, CP0_WIRED +- CLI ++ .set push ++ /* ++ * For the moment disable interrupts and bootstrap exception ++ * vectors and mark the kernel mode. A full initialization of ++ * the CPU's status register is done later in ++ * per_cpu_trap_init(). ++ */ + mfc0 t0, CP0_STATUS +- li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_UX) +- and t0, t1 +- or t0, (ST0_CU0); ++ or t0, ST0_CU0|ST0_BEV|0x1f ++ xor t0, ST0_BEV|0x1f ++ mtc0 t0, CP0_STATUS ++ ++ .set noreorder ++ sll zero,3 # ehb ++ .set reorder ++ ++ mtc0 zero, CP0_WIRED ++ + jal start_secondary +- mtc0 t0, CP0_STATUS +- .set pop ++ .set pop + END(smp_bootstrap) + #endif + +diff -Nur linux-2.4.32-rc1/arch/mips/kernel/process.c linux-2.4.32-rc1.mips/arch/mips/kernel/process.c +--- linux-2.4.32-rc1/arch/mips/kernel/process.c 2003-08-25 13:44:40.000000000 +0200 ++++ linux-2.4.32-rc1.mips/arch/mips/kernel/process.c 2005-04-14 12:41:44.000000000 +0200 +@@ -128,6 +128,26 @@ + return 1; + } + ++void dump_regs(elf_greg_t *gp, struct pt_regs *regs) ++{ ++ int i; ++ ++ for (i = 0; i < EF_REG0; i++) ++ gp[i] = 0; ++ gp[EF_REG0] = 0; ++ for (i = 1; i <= 31; i++) ++ gp[EF_REG0 + i] = regs->regs[i]; ++ gp[EF_REG26] = 0; ++ gp[EF_REG27] = 0; ++ gp[EF_LO] = regs->lo; ++ gp[EF_HI] = regs->hi; ++ gp[EF_CP0_EPC] = regs->cp0_epc; ++ gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr; ++ gp[EF_CP0_STATUS] = regs->cp0_status; ++ gp[EF_CP0_CAUSE] = regs->cp0_cause; ++ gp[EF_UNUSED0] = 0; ++} ++ + /* + * Create a kernel thread + */ +diff -Nur linux-2.4.32-rc1/arch/mips/kernel/scall_o32.S linux-2.4.32-rc1.mips/arch/mips/kernel/scall_o32.S +--- linux-2.4.32-rc1/arch/mips/kernel/scall_o32.S 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/kernel/scall_o32.S 2005-02-07 22:21:53.000000000 +0100 +@@ -121,15 +121,14 @@ + + trace_a_syscall: + SAVE_STATIC +- sw t2, PT_R1(sp) ++ move s0, t2 + jal syscall_trace +- lw t2, PT_R1(sp) + + lw a0, PT_R4(sp) # Restore argument registers + lw a1, PT_R5(sp) + lw a2, PT_R6(sp) + lw a3, PT_R7(sp) +- jalr t2 ++ jalr s0 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 +diff -Nur linux-2.4.32-rc1/arch/mips/kernel/setup.c linux-2.4.32-rc1.mips/arch/mips/kernel/setup.c +--- linux-2.4.32-rc1/arch/mips/kernel/setup.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/kernel/setup.c 2005-01-13 22:15:57.000000000 +0100 +@@ -5,7 +5,7 @@ + * + * Copyright (C) 1995 Linus Torvalds + * Copyright (C) 1995 Waldorf Electronics +- * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Ralf Baechle ++ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 01, 05 Ralf Baechle + * Copyright (C) 1996 Stoned Elipot + * Copyright (C) 2000, 2001, 2002 Maciej W. Rozycki + */ +@@ -71,6 +71,8 @@ + extern struct rtc_ops no_rtc_ops; + struct rtc_ops *rtc_ops; + ++EXPORT_SYMBOL(rtc_ops); ++ + #ifdef CONFIG_PC_KEYB + struct kbd_ops *kbd_ops; + #endif +@@ -132,10 +134,6 @@ + */ + load_mmu(); + +- /* Disable coprocessors and set FPU for 16/32 FPR register model */ +- clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); +- set_c0_status(ST0_CU0); +- + start_kernel(); + } + +diff -Nur linux-2.4.32-rc1/arch/mips/kernel/traps.c linux-2.4.32-rc1.mips/arch/mips/kernel/traps.c +--- linux-2.4.32-rc1/arch/mips/kernel/traps.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/kernel/traps.c 2005-04-12 22:25:34.000000000 +0200 +@@ -452,9 +452,10 @@ + } + ll_task = current; + ++ compute_return_epc(regs); ++ + regs->regs[(opcode & RT) >> 16] = value; + +- compute_return_epc(regs); + return; + + sig: +@@ -485,8 +486,8 @@ + goto sig; + } + if (ll_bit == 0 || ll_task != current) { +- regs->regs[reg] = 0; + compute_return_epc(regs); ++ regs->regs[reg] = 0; + return; + } + +@@ -495,9 +496,9 @@ + goto sig; + } + ++ compute_return_epc(regs); + regs->regs[reg] = 1; + +- compute_return_epc(regs); + return; + + sig: +@@ -887,12 +888,18 @@ + void __init per_cpu_trap_init(void) + { + unsigned int cpu = smp_processor_id(); ++ unsigned int status_set = ST0_CU0; + +- /* Some firmware leaves the BEV flag set, clear it. */ +- clear_c0_status(ST0_CU3|ST0_CU2|ST0_CU1|ST0_BEV|ST0_KX|ST0_SX|ST0_UX); +- ++ /* ++ * Disable coprocessors and 64-bit addressing and set FPU for ++ * the 16/32 FPR register model. Reset the BEV flag that some ++ * firmware may have left set and the TS bit (for IP27). Set ++ * XX for ISA IV code to work. ++ */ + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) +- set_c0_status(ST0_XX); ++ status_set |= ST0_XX; ++ change_c0_status(ST0_CU|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, ++ status_set); + + /* + * Some MIPS CPUs have a dedicated interrupt vector which reduces the +@@ -902,7 +909,7 @@ + set_c0_cause(CAUSEF_IV); + + cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; +- write_c0_context(cpu << 23); ++ TLBMISS_HANDLER_SETUP(); + + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; +@@ -918,8 +925,6 @@ + extern char except_vec4; + unsigned long i; + +- per_cpu_trap_init(); +- + /* Copy the generic exception handler code to it's final destination. */ + memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); + +@@ -1020,10 +1025,5 @@ + + flush_icache_range(KSEG0, KSEG0 + 0x400); + +- atomic_inc(&init_mm.mm_count); /* XXX UP? */ +- current->active_mm = &init_mm; +- +- /* XXX Must be done for all CPUs */ +- current_cpu_data.asid_cache = ASID_FIRST_VERSION; +- TLBMISS_HANDLER_SETUP(); ++ per_cpu_trap_init(); + } +diff -Nur linux-2.4.32-rc1/arch/mips/lib/rtc-no.c linux-2.4.32-rc1.mips/arch/mips/lib/rtc-no.c +--- linux-2.4.32-rc1/arch/mips/lib/rtc-no.c 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/lib/rtc-no.c 2005-01-13 22:15:57.000000000 +0100 +@@ -6,10 +6,9 @@ + * Stub RTC routines to keep Linux from crashing on machine which don't + * have a RTC chip. + * +- * Copyright (C) 1998, 2001 by Ralf Baechle ++ * Copyright (C) 1998, 2001, 2005 by Ralf Baechle + */ + #include +-#include + #include + + static unsigned int shouldnt_happen(void) +@@ -29,5 +28,3 @@ + .rtc_write_data = (void *) &shouldnt_happen, + .rtc_bcd_mode = (void *) &shouldnt_happen + }; +- +-EXPORT_SYMBOL(rtc_ops); +diff -Nur linux-2.4.32-rc1/arch/mips/lib/rtc-std.c linux-2.4.32-rc1.mips/arch/mips/lib/rtc-std.c +--- linux-2.4.32-rc1/arch/mips/lib/rtc-std.c 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/lib/rtc-std.c 2005-01-13 22:15:57.000000000 +0100 +@@ -5,9 +5,8 @@ + * + * RTC routines for PC style attached Dallas chip. + * +- * Copyright (C) 1998, 2001 by Ralf Baechle ++ * Copyright (C) 1998, 2001, 05 by Ralf Baechle + */ +-#include + #include + #include + +@@ -33,5 +32,3 @@ + &std_rtc_write_data, + &std_rtc_bcd_mode + }; +- +-EXPORT_SYMBOL(rtc_ops); +diff -Nur linux-2.4.32-rc1/arch/mips/Makefile linux-2.4.32-rc1.mips/arch/mips/Makefile +--- linux-2.4.32-rc1/arch/mips/Makefile 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/Makefile 2005-01-30 09:01:26.000000000 +0100 +@@ -211,7 +211,7 @@ + endif + + # +-# Au1000 (Alchemy Semi PB1000) eval board ++# Au1x AMD Alchemy eval boards + # + ifdef CONFIG_MIPS_PB1000 + LIBS += arch/mips/au1000/pb1000/pb1000.o \ +@@ -220,9 +220,6 @@ + LOADADDR := 0x80100000 + endif + +-# +-# Au1100 (Alchemy Semi PB1100) eval board +-# + ifdef CONFIG_MIPS_PB1100 + LIBS += arch/mips/au1000/pb1100/pb1100.o \ + arch/mips/au1000/common/au1000.o +@@ -230,9 +227,6 @@ + LOADADDR += 0x80100000 + endif + +-# +-# Au1500 (Alchemy Semi PB1500) eval board +-# + ifdef CONFIG_MIPS_PB1500 + LIBS += arch/mips/au1000/pb1500/pb1500.o \ + arch/mips/au1000/common/au1000.o +@@ -240,9 +234,6 @@ + LOADADDR := 0x80100000 + endif + +-# +-# Au1x00 (AMD/Alchemy) eval boards +-# + ifdef CONFIG_MIPS_DB1000 + LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +@@ -313,6 +304,27 @@ + LOADADDR += 0x80100000 + endif + ++ifdef CONFIG_MIPS_PB1200 ++LIBS += arch/mips/au1000/pb1200/pb1200.o \ ++ arch/mips/au1000/common/au1000.o ++SUBDIRS += arch/mips/au1000/pb1200 arch/mips/au1000/common ++LOADADDR += 0x80100000 ++endif ++ ++ifdef CONFIG_MIPS_DB1200 ++LIBS += arch/mips/au1000/pb1200/pb1200.o \ ++ arch/mips/au1000/common/au1000.o ++SUBDIRS += arch/mips/au1000/pb1200 arch/mips/au1000/common ++LOADADDR += 0x80100000 ++endif ++ ++ifdef CONFIG_MIPS_FICMMP ++LIBS += arch/mips/au1000/ficmmp/ficmmp.o \ ++ arch/mips/au1000/common/au1000.o ++SUBDIRS += arch/mips/au1000/ficmmp arch/mips/au1000/common ++LOADADDR += 0x80100000 ++endif ++ + + # + # Cogent CSB250 +diff -Nur linux-2.4.32-rc1/arch/mips/mm/cerr-sb1.c linux-2.4.32-rc1.mips/arch/mips/mm/cerr-sb1.c +--- linux-2.4.32-rc1/arch/mips/mm/cerr-sb1.c 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/mm/cerr-sb1.c 2004-12-13 18:37:23.000000000 +0100 +@@ -252,14 +252,14 @@ + + /* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ + static const uint64_t mask_72_64[8] = { +- 0x0738C808099264FFL, +- 0x38C808099264FF07L, +- 0xC808099264FF0738L, +- 0x08099264FF0738C8L, +- 0x099264FF0738C808L, +- 0x9264FF0738C80809L, +- 0x64FF0738C8080992L, +- 0xFF0738C808099264L ++ 0x0738C808099264FFULL, ++ 0x38C808099264FF07ULL, ++ 0xC808099264FF0738ULL, ++ 0x08099264FF0738C8ULL, ++ 0x099264FF0738C808ULL, ++ 0x9264FF0738C80809ULL, ++ 0x64FF0738C8080992ULL, ++ 0xFF0738C808099264ULL + }; + + /* Calculate the parity on a range of bits */ +@@ -331,9 +331,9 @@ + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } +- va = (taglo & 0xC0000FFFFFFFE000) | addr; ++ va = (taglo & 0xC0000FFFFFFFE000ULL) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) +- va |= 0x3FFFF00000000000; ++ va |= 0x3FFFF00000000000ULL; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; +@@ -474,7 +474,7 @@ + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; +- pa = (taglo & 0xFFFFFFE000) | addr; ++ pa = (taglo & 0xFFFFFFE000ULL) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", +diff -Nur linux-2.4.32-rc1/arch/mips/mm/c-r4k.c linux-2.4.32-rc1.mips/arch/mips/mm/c-r4k.c +--- linux-2.4.32-rc1/arch/mips/mm/c-r4k.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/mm/c-r4k.c 2005-02-06 22:55:42.000000000 +0100 +@@ -867,9 +867,16 @@ + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ +- if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000) +- if (c->dcache.waysize > PAGE_SIZE) +- c->dcache.flags |= MIPS_CACHE_ALIASES; ++ switch (c->cputype) { ++ case CPU_R10000: ++ case CPU_R12000: ++ break; ++ case CPU_24K: ++ if (!(read_c0_config7() & (1 << 16))) ++ default: ++ if (c->dcache.waysize > PAGE_SIZE) ++ c->dcache.flags |= MIPS_CACHE_ALIASES; ++ } + + switch (c->cputype) { + case CPU_20KC: +@@ -1069,9 +1076,6 @@ + probe_pcache(); + setup_scache(); + +- if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) +- c->dcache.flags |= MIPS_CACHE_ALIASES; +- + r4k_blast_dcache_page_setup(); + r4k_blast_dcache_page_indexed_setup(); + r4k_blast_dcache_setup(); +diff -Nur linux-2.4.32-rc1/arch/mips/mm/tlbex-mips32.S linux-2.4.32-rc1.mips/arch/mips/mm/tlbex-mips32.S +--- linux-2.4.32-rc1/arch/mips/mm/tlbex-mips32.S 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/mm/tlbex-mips32.S 2004-11-29 00:33:15.000000000 +0100 +@@ -196,7 +196,7 @@ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ +- STI; \ ++ KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ +diff -Nur linux-2.4.32-rc1/arch/mips/mm/tlbex-r4k.S linux-2.4.32-rc1.mips/arch/mips/mm/tlbex-r4k.S +--- linux-2.4.32-rc1/arch/mips/mm/tlbex-r4k.S 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/mm/tlbex-r4k.S 2005-06-06 16:46:22.000000000 +0200 +@@ -184,13 +184,10 @@ + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it +- b 1f +- rm9000_tlb_hazard ++ mtc0_tlbw_hazard + tlbwr # write random tlb entry +-1: +- nop +- rm9000_tlb_hazard +- eret # return from trap ++ tlbw_eret_hazard ++ eret + END(except_vec0_r4000) + + /* TLB refill, EXL == 0, R4600 version */ +@@ -468,13 +465,9 @@ + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1, k0) +- rm9000_tlb_hazard +- nop +- b 1f +- tlbwi +-1: +- nop +- rm9000_tlb_hazard ++ mtc0_tlbw_hazard ++ tlbwi ++ tlbw_eret_hazard + .set mips3 + eret + .set mips0 +@@ -496,13 +489,9 @@ + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1, k0) +- rm9000_tlb_hazard +- nop +- b 1f +- tlbwi +-1: +- nop +- rm9000_tlb_hazard ++ mtc0_tlbw_hazard ++ tlbwi ++ tlbw_eret_hazard + .set mips3 + eret + .set mips0 +@@ -529,13 +518,9 @@ + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1, k0) +- rm9000_tlb_hazard +- nop +- b 1f +- tlbwi +-1: +- rm9000_tlb_hazard +- nop ++ mtc0_tlbw_hazard ++ tlbwi ++ tlbw_eret_hazard + .set mips3 + eret + .set mips0 +diff -Nur linux-2.4.32-rc1/arch/mips/mm/tlb-r4k.c linux-2.4.32-rc1.mips/arch/mips/mm/tlb-r4k.c +--- linux-2.4.32-rc1/arch/mips/mm/tlb-r4k.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips/mm/tlb-r4k.c 2004-11-25 23:18:38.000000000 +0100 +@@ -3,17 +3,12 @@ + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * +- * r4xx0.c: R4000 processor variant specific MMU/Cache routines. +- * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org +- * +- * To do: +- * +- * - this code is a overbloated pig +- * - many of the bug workarounds are not efficient at all, but at +- * least they are functional ... ++ * Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + */ ++#include + #include + #include + #include +@@ -25,9 +20,6 @@ + #include + #include + +-#undef DEBUG_TLB +-#undef DEBUG_TLBUPDATE +- + extern char except_vec0_nevada, except_vec0_r4000, except_vec0_r4600; + + /* CP0 hazard avoidance. */ +@@ -41,33 +33,23 @@ + unsigned long old_ctx; + int entry; + +-#ifdef DEBUG_TLB +- printk("[tlball]"); +-#endif +- + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); +- BARRIER; + + entry = read_c0_wired(); + + /* Blast 'em all away. */ + while (entry < current_cpu_data.tlbsize) { +- /* +- * Make sure all entries differ. If they're not different +- * MIPS32 will take revenge ... +- */ + write_c0_entryhi(KSEG0 + entry*0x2000); + write_c0_index(entry); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); +- BARRIER; + entry++; + } +- BARRIER; ++ tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); + } +@@ -76,12 +58,8 @@ + { + int cpu = smp_processor_id(); + +- if (cpu_context(cpu, mm) != 0) { +-#ifdef DEBUG_TLB +- printk("[tlbmm<%d>]", cpu_context(cpu, mm)); +-#endif ++ if (cpu_context(cpu, mm) != 0) + drop_mmu_context(mm,cpu); +- } + } + + void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, +@@ -93,10 +71,6 @@ + unsigned long flags; + int size; + +-#ifdef DEBUG_TLB +- printk("[tlbrange<%02x,%08lx,%08lx>]", +- cpu_asid(cpu, mm), start, end); +-#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; +@@ -112,7 +86,7 @@ + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + idx = read_c0_index(); +@@ -122,10 +96,10 @@ + continue; + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0 + idx*0x2000); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); +- BARRIER; + } ++ tlbw_use_hazard(); + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); +@@ -138,34 +112,30 @@ + { + int cpu = smp_processor_id(); + +- if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { ++ if (cpu_context(cpu, vma->vm_mm) != 0) { + unsigned long flags; +- int oldpid, newpid, idx; ++ unsigned long oldpid, newpid, idx; + +-#ifdef DEBUG_TLB +- printk("[tlbpage<%d,%08lx>]", cpu_context(cpu, vma->vm_mm), +- page); +-#endif + newpid = cpu_asid(cpu, vma->vm_mm); + page &= (PAGE_MASK << 1); + local_irq_save(flags); + oldpid = read_c0_entryhi(); + write_c0_entryhi(page | newpid); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); +- if(idx < 0) ++ if (idx < 0) + goto finish; + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); ++ tlbw_use_hazard(); + + finish: +- BARRIER; + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +@@ -185,7 +155,7 @@ + + local_irq_save(flags); + write_c0_entryhi(page); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + idx = read_c0_index(); +@@ -194,18 +164,19 @@ + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); ++ tlbw_use_hazard(); + } +- BARRIER; + write_c0_entryhi(oldpid); ++ + local_irq_restore(flags); + } + + EXPORT_SYMBOL(local_flush_tlb_one); + +-/* We will need multiple versions of update_mmu_cache(), one that just +- * updates the TLB with the new pte(s), and another which also checks +- * for the R4k "end of page" hardware bug and does the needy. ++/* ++ * Updates the TLB with the new pte(s). + */ + void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) + { +@@ -223,25 +194,16 @@ + + pid = read_c0_entryhi() & ASID_MASK; + +-#ifdef DEBUG_TLB +- if ((pid != cpu_asid(cpu, vma->vm_mm)) || +- (cpu_context(vma->vm_mm) == 0)) { +- printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d " +- "tlbpid=%d\n", (int) (cpu_asid(cpu, vma->vm_mm)), pid); +- } +-#endif +- + local_irq_save(flags); + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | pid); + pgdp = pgd_offset(vma->vm_mm, address); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset(pmdp, address); +- BARRIER; + #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) + write_c0_entrylo0(ptep->pte_high); + ptep++; +@@ -251,15 +213,13 @@ + write_c0_entrylo1(pte_val(*ptep) >> 6); + #endif + write_c0_entryhi(address | pid); +- BARRIER; +- if (idx < 0) { ++ mtc0_tlbw_hazard(); ++ if (idx < 0) + tlb_write_random(); +- } else { ++ else + tlb_write_indexed(); +- } +- BARRIER; ++ tlbw_use_hazard(); + write_c0_entryhi(pid); +- BARRIER; + local_irq_restore(flags); + } + +@@ -279,24 +239,26 @@ + asid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(address | asid); + pgdp = pgd_offset(vma->vm_mm, address); ++ mtc0_tlbw_hazard(); + tlb_probe(); ++ BARRIER; + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset(pmdp, address); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); +- BARRIER; ++ mtc0_tlbw_hazard(); + if (idx < 0) + tlb_write_random(); + else + tlb_write_indexed(); +- BARRIER; ++ tlbw_use_hazard(); + local_irq_restore(flags); + } + #endif + + void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, +- unsigned long entryhi, unsigned long pagemask) ++ unsigned long entryhi, unsigned long pagemask) + { + unsigned long flags; + unsigned long wired; +@@ -315,9 +277,9 @@ + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); +- BARRIER; ++ tlbw_use_hazard(); + + write_c0_entryhi(old_ctx); + BARRIER; +@@ -355,17 +317,15 @@ + } + + write_c0_index(temp_tlb_entry); +- BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); +- BARRIER; ++ tlbw_use_hazard(); + + write_c0_entryhi(old_ctx); +- BARRIER; + write_c0_pagemask(old_pagemask); + out: + local_irq_restore(flags); +@@ -375,7 +335,7 @@ + static void __init probe_tlb(unsigned long config) + { + struct cpuinfo_mips *c = ¤t_cpu_data; +- unsigned int reg; ++ unsigned int config1; + + /* + * If this isn't a MIPS32 / MIPS64 compliant CPU. Config 1 register +@@ -385,16 +345,16 @@ + if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) + return; + +- reg = read_c0_config1(); ++ config1 = read_c0_config1(); + if (!((config >> 7) & 3)) + panic("No TLB present"); + +- c->tlbsize = ((reg >> 25) & 0x3f) + 1; ++ c->tlbsize = ((config1 >> 25) & 0x3f) + 1; + } + + void __init r4k_tlb_init(void) + { +- u32 config = read_c0_config(); ++ unsigned int config = read_c0_config(); + + /* + * You should never change this register: +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig linux-2.4.32-rc1.mips/arch/mips64/defconfig +--- linux-2.4.32-rc1/arch/mips64/defconfig 2005-01-19 15:09:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig 2005-03-18 13:13:23.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -470,9 +470,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -658,7 +660,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-atlas linux-2.4.32-rc1.mips/arch/mips64/defconfig-atlas +--- linux-2.4.32-rc1/arch/mips64/defconfig-atlas 2005-01-19 15:09:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-atlas 2005-03-18 13:13:23.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -232,11 +232,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -314,9 +309,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -474,7 +471,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-decstation linux-2.4.32-rc1.mips/arch/mips64/defconfig-decstation +--- linux-2.4.32-rc1/arch/mips64/defconfig-decstation 2005-01-19 15:09:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-decstation 2005-03-18 13:13:23.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -224,11 +224,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -307,9 +302,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -477,7 +474,6 @@ + CONFIG_SERIAL_DEC_CONSOLE=y + # CONFIG_DZ is not set + CONFIG_ZS=y +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-ip22 linux-2.4.32-rc1.mips/arch/mips64/defconfig-ip22 +--- linux-2.4.32-rc1/arch/mips64/defconfig-ip22 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-ip22 2005-03-18 13:13:23.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -235,11 +235,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -319,9 +314,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -488,7 +485,6 @@ + # CONFIG_SERIAL_TXX9_CONSOLE is not set + # CONFIG_TXX927_SERIAL is not set + CONFIG_IP22_SERIAL=y +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-ip27 linux-2.4.32-rc1.mips/arch/mips64/defconfig-ip27 +--- linux-2.4.32-rc1/arch/mips64/defconfig-ip27 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-ip27 2005-03-18 13:13:23.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -470,9 +470,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -658,7 +660,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-jaguar linux-2.4.32-rc1.mips/arch/mips64/defconfig-jaguar +--- linux-2.4.32-rc1/arch/mips64/defconfig-jaguar 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-jaguar 2005-03-18 13:13:23.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -227,11 +227,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -403,7 +398,6 @@ + # CONFIG_SERIAL_TXX9 is not set + # CONFIG_SERIAL_TXX9_CONSOLE is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-malta linux-2.4.32-rc1.mips/arch/mips64/defconfig-malta +--- linux-2.4.32-rc1/arch/mips64/defconfig-malta 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-malta 2005-04-19 14:19:34.000000000 +0200 +@@ -22,16 +22,19 @@ + # + # 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_MIPS_HYDROGEN3 is not set + # 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 +@@ -146,9 +149,9 @@ + CONFIG_BINFMT_ELF=y + CONFIG_MIPS32_COMPAT=y + CONFIG_MIPS32_O32=y +-# CONFIG_MIPS32_N32 is not set ++CONFIG_MIPS32_N32=y + CONFIG_BINFMT_ELF32=y +-# CONFIG_BINFMT_MISC is not set ++CONFIG_BINFMT_MISC=y + # CONFIG_OOM_KILLER is not set + # CONFIG_CMDLINE_BOOL is not set + +@@ -235,11 +238,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -271,8 +269,83 @@ + # + # ATA/IDE/MFM/RLL support + # +-# CONFIG_IDE is not set ++CONFIG_IDE=y ++ ++# ++# IDE, ATA and ATAPI Block devices ++# ++CONFIG_BLK_DEV_IDE=y ++ ++# ++# Please see Documentation/ide.txt for help/info on IDE drives ++# ++# 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=y ++# CONFIG_IDEDISK_MULTI_MODE is not set ++# CONFIG_IDEDISK_STROKE is not set ++# CONFIG_BLK_DEV_IDECS is not set ++# CONFIG_BLK_DEV_DELKIN is not set ++CONFIG_BLK_DEV_IDECD=y ++CONFIG_BLK_DEV_IDETAPE=y ++CONFIG_BLK_DEV_IDEFLOPPY=y ++# CONFIG_BLK_DEV_IDESCSI is not set ++# CONFIG_IDE_TASK_IOCTL is not set ++ ++# ++# IDE chipset support/bugfixes ++# ++# CONFIG_BLK_DEV_CMD640 is not set ++# CONFIG_BLK_DEV_CMD640_ENHANCED is not set ++# CONFIG_BLK_DEV_ISAPNP is not set ++CONFIG_BLK_DEV_IDEPCI=y ++CONFIG_BLK_DEV_GENERIC=y ++CONFIG_IDEPCI_SHARE_IRQ=y ++CONFIG_BLK_DEV_IDEDMA_PCI=y ++# CONFIG_BLK_DEV_OFFBOARD is not set ++CONFIG_BLK_DEV_IDEDMA_FORCED=y ++CONFIG_IDEDMA_PCI_AUTO=y ++# CONFIG_IDEDMA_ONLYDISK is not set ++CONFIG_BLK_DEV_IDEDMA=y ++# CONFIG_IDEDMA_PCI_WIP is not set ++# CONFIG_BLK_DEV_ADMA100 is not set ++# CONFIG_BLK_DEV_AEC62XX is not set ++# CONFIG_BLK_DEV_ALI15X3 is not set ++# CONFIG_WDC_ALI15X3 is not set ++# CONFIG_BLK_DEV_AMD74XX is not set ++# CONFIG_AMD74XX_OVERRIDE is not set ++# CONFIG_BLK_DEV_ATIIXP is not set ++# CONFIG_BLK_DEV_CMD64X is not set ++# CONFIG_BLK_DEV_TRIFLEX is not set ++# CONFIG_BLK_DEV_CY82C693 is not set ++# CONFIG_BLK_DEV_CS5530 is not set ++# CONFIG_BLK_DEV_HPT34X is not set ++# CONFIG_HPT34X_AUTODMA is not set ++# CONFIG_BLK_DEV_HPT366 is not set ++CONFIG_BLK_DEV_PIIX=y ++# CONFIG_BLK_DEV_NS87415 is not set ++# CONFIG_BLK_DEV_OPTI621 is not set ++# CONFIG_BLK_DEV_PDC202XX_OLD is not set ++# CONFIG_PDC202XX_BURST is not set ++# CONFIG_BLK_DEV_PDC202XX_NEW is not set ++# CONFIG_BLK_DEV_RZ1000 is not set ++# CONFIG_BLK_DEV_SC1200 is not set ++# CONFIG_BLK_DEV_SVWKS is not set ++# CONFIG_BLK_DEV_SIIMAGE is not set ++# CONFIG_BLK_DEV_SIS5513 is not set ++# CONFIG_BLK_DEV_SLC90E66 is not set ++# CONFIG_BLK_DEV_TRM290 is not set ++# CONFIG_BLK_DEV_VIA82CXXX is not set ++# CONFIG_IDE_CHIPSETS is not set ++CONFIG_IDEDMA_AUTO=y ++# CONFIG_IDEDMA_IVB 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 +@@ -317,9 +390,11 @@ + # CONFIG_SCSI_MEGARAID is not set + # CONFIG_SCSI_MEGARAID2 is not set + # CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_AHCI is not set + # CONFIG_SCSI_SATA_SVW is not set + # CONFIG_SCSI_ATA_PIIX is not set + # CONFIG_SCSI_SATA_NV is not set ++# CONFIG_SCSI_SATA_QSTOR is not set + # CONFIG_SCSI_SATA_PROMISE is not set + # CONFIG_SCSI_SATA_SX4 is not set + # CONFIG_SCSI_SATA_SIL is not set +@@ -477,7 +552,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-ocelotc linux-2.4.32-rc1.mips/arch/mips64/defconfig-ocelotc +--- linux-2.4.32-rc1/arch/mips64/defconfig-ocelotc 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-ocelotc 2005-03-18 13:13:23.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -231,11 +231,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -453,7 +448,6 @@ + # CONFIG_SERIAL_TXX9 is not set + # CONFIG_SERIAL_TXX9_CONSOLE is not set + # CONFIG_TXX927_SERIAL is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-sb1250-swarm linux-2.4.32-rc1.mips/arch/mips64/defconfig-sb1250-swarm +--- linux-2.4.32-rc1/arch/mips64/defconfig-sb1250-swarm 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-sb1250-swarm 2005-03-18 13:13:23.000000000 +0100 +@@ -30,8 +30,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -90,6 +90,7 @@ + # CONFIG_SIBYTE_TBPROF is not set + CONFIG_SIBYTE_GENBUS_IDE=y + CONFIG_SMP_CAPABLE=y ++CONFIG_MIPS_RTC=y + # CONFIG_SNI_RM200_PCI is not set + # CONFIG_TANBAC_TB0226 is not set + # CONFIG_TANBAC_TB0229 is not set +@@ -253,11 +254,6 @@ + # + # CONFIG_IPX is not set + # CONFIG_ATALK is not set +- +-# +-# Appletalk devices +-# +-# CONFIG_DEV_APPLETALK is not set + # CONFIG_DECNET is not set + # CONFIG_BRIDGE is not set + # CONFIG_X25 is not set +@@ -432,7 +428,6 @@ + CONFIG_SIBYTE_SB1250_DUART=y + CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y + CONFIG_SERIAL_CONSOLE=y +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + CONFIG_UNIX98_PTYS=y + CONFIG_UNIX98_PTY_COUNT=256 + +diff -Nur linux-2.4.32-rc1/arch/mips64/defconfig-sead linux-2.4.32-rc1.mips/arch/mips64/defconfig-sead +--- linux-2.4.32-rc1/arch/mips64/defconfig-sead 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/defconfig-sead 2005-03-18 13:13:23.000000000 +0100 +@@ -28,8 +28,8 @@ + # CONFIG_MIPS_PB1000 is not set + # CONFIG_MIPS_PB1100 is not set + # CONFIG_MIPS_PB1500 is not set +-# CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 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 +@@ -242,7 +242,6 @@ + CONFIG_SERIAL_CONSOLE=y + # CONFIG_SERIAL_EXTENDED is not set + # CONFIG_SERIAL_NONSTANDARD is not set +-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set + # CONFIG_UNIX98_PTYS is not set + + # +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/binfmt_elfn32.c linux-2.4.32-rc1.mips/arch/mips64/kernel/binfmt_elfn32.c +--- linux-2.4.32-rc1/arch/mips64/kernel/binfmt_elfn32.c 2003-08-25 13:44:40.000000000 +0200 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/binfmt_elfn32.c 2005-01-26 03:40:47.000000000 +0100 +@@ -116,4 +116,7 @@ + #undef MODULE_DESCRIPTION + #undef MODULE_AUTHOR + ++#undef TASK_SIZE ++#define TASK_SIZE TASK_SIZE32 ++ + #include "../../../fs/binfmt_elf.c" +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/binfmt_elfo32.c linux-2.4.32-rc1.mips/arch/mips64/kernel/binfmt_elfo32.c +--- linux-2.4.32-rc1/arch/mips64/kernel/binfmt_elfo32.c 2003-08-25 13:44:40.000000000 +0200 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/binfmt_elfo32.c 2005-01-26 03:40:47.000000000 +0100 +@@ -137,4 +137,7 @@ + #undef MODULE_DESCRIPTION + #undef MODULE_AUTHOR + ++#undef TASK_SIZE ++#define TASK_SIZE TASK_SIZE32 ++ + #include "../../../fs/binfmt_elf.c" +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/head.S linux-2.4.32-rc1.mips/arch/mips64/kernel/head.S +--- linux-2.4.32-rc1/arch/mips64/kernel/head.S 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/head.S 2004-11-22 14:38:26.000000000 +0100 +@@ -91,6 +91,21 @@ + __INIT + + NESTED(kernel_entry, 16, sp) # kernel entry point ++ .set push ++ /* ++ * For the moment disable interrupts, mark the kernel mode and ++ * set ST0_KX so that the CPU does not spit fire when using ++ * 64-bit addresses. A full initialization of the CPU's status ++ * register is done later in per_cpu_trap_init(). ++ */ ++ mfc0 t0, CP0_STATUS ++ or t0, ST0_CU0|ST0_KX|0x1f ++ xor t0, 0x1f ++ mtc0 t0, CP0_STATUS ++ ++ .set noreorder ++ sll zero,3 # ehb ++ .set reorder + + ori sp, 0xf # align stack on 16 byte. + xori sp, 0xf +@@ -103,8 +118,6 @@ + + ARC64_TWIDDLE_PC + +- CLI # disable interrupts +- + /* + * The firmware/bootloader passes argc/argp/envp + * to us as arguments. But clear bss first because +@@ -125,6 +138,7 @@ + dsubu sp, 4*SZREG # init stack pointer + + j init_arch ++ .set pop + END(kernel_entry) + + #ifdef CONFIG_SMP +@@ -133,6 +147,23 @@ + * function after setting up the stack and gp registers. + */ + NESTED(smp_bootstrap, 16, sp) ++ .set push ++ /* ++ * For the moment disable interrupts and bootstrap exception ++ * vectors, mark the kernel mode and set ST0_KX so that the CPU ++ * does not spit fire when using 64-bit addresses. A full ++ * initialization of the CPU's status register is done later in ++ * per_cpu_trap_init(). ++ */ ++ mfc0 t0, CP0_STATUS ++ or t0, ST0_CU0|ST0_BEV|ST0_KX|0x1f ++ xor t0, ST0_BEV|0x1f ++ mtc0 t0, CP0_STATUS ++ ++ .set noreorder ++ sll zero,3 # ehb ++ .set reorder ++ + #ifdef CONFIG_SGI_IP27 + GET_NASID_ASM t1 + dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ +@@ -146,19 +177,8 @@ + ARC64_TWIDDLE_PC + #endif /* CONFIG_SGI_IP27 */ + +- CLI +- +- /* +- * For the moment set ST0_KU so the CPU will not spit fire when +- * executing 64-bit instructions. The full initialization of the +- * CPU's status register is done later in per_cpu_trap_init(). +- */ +- mfc0 t0, CP0_STATUS +- or t0, ST0_KX +- mtc0 t0, CP0_STATUS +- + jal start_secondary # XXX: IP27: cboot +- ++ .set pop + END(smp_bootstrap) + #endif /* CONFIG_SMP */ + +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/ioctl32.c linux-2.4.32-rc1.mips/arch/mips64/kernel/ioctl32.c +--- linux-2.4.32-rc1/arch/mips64/kernel/ioctl32.c 2005-01-19 15:09:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/ioctl32.c 2005-01-26 03:36:17.000000000 +0100 +@@ -2352,7 +2352,7 @@ + IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout), + IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE), + IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI), +- IOCTL32_DEFAULT(AUTOFS_IOC_PROTSUBVER), ++ IOCTL32_DEFAULT(AUTOFS_IOC_PROTOSUBVER), + IOCTL32_DEFAULT(AUTOFS_IOC_ASKREGHOST), + IOCTL32_DEFAULT(AUTOFS_IOC_TOGGLEREGHOST), + IOCTL32_DEFAULT(AUTOFS_IOC_ASKUMOUNT), +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/linux32.c linux-2.4.32-rc1.mips/arch/mips64/kernel/linux32.c +--- linux-2.4.32-rc1/arch/mips64/kernel/linux32.c 2005-04-04 03:42:19.000000000 +0200 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/linux32.c 2005-04-22 15:01:00.000000000 +0200 +@@ -1101,6 +1101,7 @@ + * specially as they have atomicity guarantees and can handle + * iovec's natively + */ ++ inode = file->f_dentry->d_inode; + if (inode->i_sock) { + int err; + err = sock_readv_writev(type, inode, file, iov, count, tot_len); +@@ -1187,72 +1188,19 @@ + lseek back to original location. They fail just like lseek does on + non-seekable files. */ + +-asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf, +- size_t count, u32 unused, u64 a4, u64 a5) ++asmlinkage ssize_t sys32_pread(unsigned int fd, char *buf, ++ size_t count, u32 unused, u64 a4, u64 a5) + { +- ssize_t ret; +- struct file * file; +- ssize_t (*read)(struct file *, char *, size_t, loff_t *); +- loff_t pos; +- +- ret = -EBADF; +- file = fget(fd); +- if (!file) +- goto bad_file; +- if (!(file->f_mode & FMODE_READ)) +- goto out; +- pos = merge_64(a4, a5); +- ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode, +- file, pos, count); +- if (ret) +- goto out; +- ret = -EINVAL; +- if (!file->f_op || !(read = file->f_op->read)) +- goto out; +- if (pos < 0) +- goto out; +- ret = read(file, buf, count, &pos); +- if (ret > 0) +- dnotify_parent(file->f_dentry, DN_ACCESS); +-out: +- fput(file); +-bad_file: +- return ret; ++ return sys_pread(fd, buf, count, merge_64(a4, a5)); + } + + asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf, + size_t count, u32 unused, u64 a4, u64 a5) + { +- ssize_t ret; +- struct file * file; +- ssize_t (*write)(struct file *, const char *, size_t, loff_t *); +- loff_t pos; ++ return sys_pwrite(fd, buf, count, merge_64(a4, a5)); ++} + +- ret = -EBADF; +- file = fget(fd); +- if (!file) +- goto bad_file; +- if (!(file->f_mode & FMODE_WRITE)) +- goto out; +- pos = merge_64(a4, a5); +- ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode, +- file, pos, count); +- if (ret) +- goto out; +- ret = -EINVAL; +- if (!file->f_op || !(write = file->f_op->write)) +- goto out; +- if (pos < 0) +- goto out; + +- ret = write(file, buf, count, &pos); +- if (ret > 0) +- dnotify_parent(file->f_dentry, DN_MODIFY); +-out: +- fput(file); +-bad_file: +- return ret; +-} + /* + * Ooo, nasty. We need here to frob 32-bit unsigned longs to + * 64-bit unsigned longs. +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/process.c linux-2.4.32-rc1.mips/arch/mips64/kernel/process.c +--- linux-2.4.32-rc1/arch/mips64/kernel/process.c 2003-08-25 13:44:40.000000000 +0200 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/process.c 2005-04-14 12:41:44.000000000 +0200 +@@ -125,6 +125,25 @@ + return 1; + } + ++void dump_regs(elf_greg_t *gp, struct pt_regs *regs) ++{ ++ int i; ++ ++ for (i = 0; i < EF_REG0; i++) ++ gp[i] = 0; ++ gp[EF_REG0] = 0; ++ for (i = 1; i <= 31; i++) ++ gp[EF_REG0 + i] = regs->regs[i]; ++ gp[EF_REG26] = 0; ++ gp[EF_REG27] = 0; ++ gp[EF_LO] = regs->lo; ++ gp[EF_HI] = regs->hi; ++ gp[EF_CP0_EPC] = regs->cp0_epc; ++ gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr; ++ gp[EF_CP0_STATUS] = regs->cp0_status; ++ gp[EF_CP0_CAUSE] = regs->cp0_cause; ++} ++ + /* + * Create a kernel thread + */ +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/scall_64.S linux-2.4.32-rc1.mips/arch/mips64/kernel/scall_64.S +--- linux-2.4.32-rc1/arch/mips64/kernel/scall_64.S 2005-01-19 15:09:32.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/scall_64.S 2005-02-07 22:21:54.000000000 +0100 +@@ -102,15 +102,14 @@ + + trace_a_syscall: + SAVE_STATIC +- sd t2,PT_R1(sp) ++ move s0, t2 + jal syscall_trace +- ld t2,PT_R1(sp) + + ld a0, PT_R4(sp) # Restore argument registers + ld a1, PT_R5(sp) + ld a2, PT_R6(sp) + ld a3, PT_R7(sp) +- jalr t2 ++ jalr s0 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/scall_n32.S linux-2.4.32-rc1.mips/arch/mips64/kernel/scall_n32.S +--- linux-2.4.32-rc1/arch/mips64/kernel/scall_n32.S 2005-01-19 15:09:32.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/scall_n32.S 2005-02-07 22:21:54.000000000 +0100 +@@ -106,15 +106,14 @@ + + trace_a_syscall: + SAVE_STATIC +- sd t2,PT_R1(sp) ++ move s0, t2 + jal syscall_trace +- ld t2,PT_R1(sp) + + ld a0, PT_R4(sp) # Restore argument registers + ld a1, PT_R5(sp) + ld a2, PT_R6(sp) + ld a3, PT_R7(sp) +- jalr t2 ++ jalr s0 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/scall_o32.S linux-2.4.32-rc1.mips/arch/mips64/kernel/scall_o32.S +--- linux-2.4.32-rc1/arch/mips64/kernel/scall_o32.S 2005-01-19 15:09:32.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/scall_o32.S 2005-02-14 04:52:57.000000000 +0100 +@@ -118,9 +118,8 @@ + sd a6, PT_R10(sp) + sd a7, PT_R11(sp) + +- sd t2,PT_R1(sp) ++ move s0, t2 + jal syscall_trace +- ld t2,PT_R1(sp) + + ld a0, PT_R4(sp) # Restore argument registers + ld a1, PT_R5(sp) +@@ -129,7 +128,7 @@ + ld a4, PT_R8(sp) + ld a5, PT_R9(sp) + +- jalr t2 ++ jalr s0 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 +@@ -576,6 +575,8 @@ + sys_call_table: + syscalltable + ++ .purgem sys ++ + .macro sys function, nargs + .byte \nargs + .endm +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/setup.c linux-2.4.32-rc1.mips/arch/mips64/kernel/setup.c +--- linux-2.4.32-rc1/arch/mips64/kernel/setup.c 2005-01-19 15:09:32.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/setup.c 2004-11-22 14:38:26.000000000 +0100 +@@ -129,14 +129,6 @@ + */ + load_mmu(); + +- /* +- * On IP27, I am seeing the TS bit set when the kernel is loaded. +- * Maybe because the kernel is in ckseg0 and not xkphys? Clear it +- * anyway ... +- */ +- clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); +- set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); +- + start_kernel(); + } + +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/signal_n32.c linux-2.4.32-rc1.mips/arch/mips64/kernel/signal_n32.c +--- linux-2.4.32-rc1/arch/mips64/kernel/signal_n32.c 2005-01-19 15:09:33.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/signal_n32.c 2005-02-07 22:10:53.000000000 +0100 +@@ -68,7 +68,7 @@ + }; + + extern asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc); +-extern int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc); ++extern int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc); + + asmlinkage void sysn32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) + { +diff -Nur linux-2.4.32-rc1/arch/mips64/kernel/traps.c linux-2.4.32-rc1.mips/arch/mips64/kernel/traps.c +--- linux-2.4.32-rc1/arch/mips64/kernel/traps.c 2005-01-19 15:09:33.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/kernel/traps.c 2005-04-12 22:25:34.000000000 +0200 +@@ -462,9 +462,10 @@ + } + ll_task = current; + ++ compute_return_epc(regs); ++ + regs->regs[(opcode & RT) >> 16] = value; + +- compute_return_epc(regs); + return; + + sig: +@@ -495,8 +496,8 @@ + goto sig; + } + if (ll_bit == 0 || ll_task != current) { +- regs->regs[reg] = 0; + compute_return_epc(regs); ++ regs->regs[reg] = 0; + return; + } + +@@ -505,9 +506,9 @@ + goto sig; + } + ++ compute_return_epc(regs); + regs->regs[reg] = 1; + +- compute_return_epc(regs); + return; + + sig: +@@ -809,13 +810,18 @@ + void __init per_cpu_trap_init(void) + { + unsigned int cpu = smp_processor_id(); ++ unsigned int status_set = ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX; + +- /* Some firmware leaves the BEV flag set, clear it. */ +- clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); +- set_c0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX); +- ++ /* ++ * Disable coprocessors, enable 64-bit addressing and set FPU ++ * for the 32/32 FPR register model. Reset the BEV flag that ++ * some firmware may have left set and the TS bit (for IP27). ++ * Set XX for ISA IV code to work. ++ */ + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) +- set_c0_status(ST0_XX); ++ status_set |= ST0_XX; ++ change_c0_status(ST0_CU|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, ++ status_set); + + /* + * Some MIPS CPUs have a dedicated interrupt vector which reduces the +@@ -825,13 +831,11 @@ + set_c0_cause(CAUSEF_IV); + + cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; +- write_c0_context(((long)(&pgd_current[cpu])) << 23); +- write_c0_wired(0); ++ TLBMISS_HANDLER_SETUP(); + + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; +- if (current->mm) +- BUG(); ++ BUG_ON(current->mm); + enter_lazy_tlb(&init_mm, current, cpu); + } + +@@ -842,8 +846,6 @@ + extern char except_vec4; + unsigned long i; + +- per_cpu_trap_init(); +- + /* Copy the generic exception handlers to their final destination. */ + memcpy((void *) KSEG0 , &except_vec0_generic, 0x80); + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); +@@ -933,6 +935,5 @@ + + flush_icache_range(KSEG0, KSEG0 + 0x400); + +- atomic_inc(&init_mm.mm_count); /* XXX UP? */ +- current->active_mm = &init_mm; ++ per_cpu_trap_init(); + } +diff -Nur linux-2.4.32-rc1/arch/mips64/mm/cerr-sb1.c linux-2.4.32-rc1.mips/arch/mips64/mm/cerr-sb1.c +--- linux-2.4.32-rc1/arch/mips64/mm/cerr-sb1.c 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/mm/cerr-sb1.c 2004-12-13 18:37:26.000000000 +0100 +@@ -252,14 +252,14 @@ + + /* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ + static const uint64_t mask_72_64[8] = { +- 0x0738C808099264FFL, +- 0x38C808099264FF07L, +- 0xC808099264FF0738L, +- 0x08099264FF0738C8L, +- 0x099264FF0738C808L, +- 0x9264FF0738C80809L, +- 0x64FF0738C8080992L, +- 0xFF0738C808099264L ++ 0x0738C808099264FFULL, ++ 0x38C808099264FF07ULL, ++ 0xC808099264FF0738ULL, ++ 0x08099264FF0738C8ULL, ++ 0x099264FF0738C808ULL, ++ 0x9264FF0738C80809ULL, ++ 0x64FF0738C8080992ULL, ++ 0xFF0738C808099264ULL + }; + + /* Calculate the parity on a range of bits */ +@@ -331,9 +331,9 @@ + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } +- va = (taglo & 0xC0000FFFFFFFE000) | addr; ++ va = (taglo & 0xC0000FFFFFFFE000ULL) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) +- va |= 0x3FFFF00000000000; ++ va |= 0x3FFFF00000000000ULL; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; +@@ -474,7 +474,7 @@ + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; +- pa = (taglo & 0xFFFFFFE000) | addr; ++ pa = (taglo & 0xFFFFFFE000ULL) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", +diff -Nur linux-2.4.32-rc1/arch/mips64/mm/c-r4k.c linux-2.4.32-rc1.mips/arch/mips64/mm/c-r4k.c +--- linux-2.4.32-rc1/arch/mips64/mm/c-r4k.c 2005-01-19 15:09:33.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/mm/c-r4k.c 2005-02-06 22:55:42.000000000 +0100 +@@ -867,9 +867,16 @@ + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ +- if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000) +- if (c->dcache.waysize > PAGE_SIZE) +- c->dcache.flags |= MIPS_CACHE_ALIASES; ++ switch (c->cputype) { ++ case CPU_R10000: ++ case CPU_R12000: ++ break; ++ case CPU_24K: ++ if (!(read_c0_config7() & (1 << 16))) ++ default: ++ if (c->dcache.waysize > PAGE_SIZE) ++ c->dcache.flags |= MIPS_CACHE_ALIASES; ++ } + + switch (c->cputype) { + case CPU_20KC: +@@ -1070,9 +1077,6 @@ + setup_scache(); + coherency_setup(); + +- if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) +- c->dcache.flags |= MIPS_CACHE_ALIASES; +- + r4k_blast_dcache_page_setup(); + r4k_blast_dcache_page_indexed_setup(); + r4k_blast_dcache_setup(); +diff -Nur linux-2.4.32-rc1/arch/mips64/mm/tlbex-r4k.S linux-2.4.32-rc1.mips/arch/mips64/mm/tlbex-r4k.S +--- linux-2.4.32-rc1/arch/mips64/mm/tlbex-r4k.S 2004-02-18 14:36:30.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/mm/tlbex-r4k.S 2005-06-06 16:46:22.000000000 +0200 +@@ -125,6 +125,33 @@ + nop + END(except_vec1_r4k) + ++ __FINIT ++ ++ .align 5 ++LEAF(handle_vec1_r4k) ++ .set noat ++ LOAD_PTE2 k1 k0 9f ++ ld k0, 0(k1) # get even pte ++ ld k1, 8(k1) # get odd pte ++ PTE_RELOAD k0 k1 ++ mtc0_tlbw_hazard ++ tlbwr ++ tlbw_eret_hazard ++ eret ++ ++9: # handle the vmalloc range ++ LOAD_KPTE2 k1 k0 invalid_vmalloc_address ++ ld k0, 0(k1) # get even pte ++ ld k1, 8(k1) # get odd pte ++ PTE_RELOAD k0 k1 ++ mtc0_tlbw_hazard ++ tlbwr ++ tlbw_eret_hazard ++ eret ++END(handle_vec1_r4k) ++ ++ __INIT ++ + LEAF(except_vec1_sb1) + #if BCM1250_M3_WAR + dmfc0 k0, CP0_BADVADDR +@@ -134,28 +161,24 @@ + bnez k0, 1f + #endif + .set noat +- dla k0, handle_vec1_r4k ++ dla k0, handle_vec1_sb1 + jr k0 + nop + + 1: eret +- nop + END(except_vec1_sb1) + + __FINIT + + .align 5 +-LEAF(handle_vec1_r4k) ++LEAF(handle_vec1_sb1) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 +- rm9000_tlb_hazard +- b 1f +- tlbwr +-1: nop +- rm9000_tlb_hazard ++ mtc0_tlbw_hazard ++ tlbwr + eret + + 9: # handle the vmalloc range +@@ -163,13 +186,10 @@ + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 +- rm9000_tlb_hazard +- b 1f +- tlbwr +-1: nop +- rm9000_tlb_hazard ++ mtc0_tlbw_hazard ++ tlbwr + eret +-END(handle_vec1_r4k) ++END(handle_vec1_sb1) + + + __INIT +@@ -195,10 +215,8 @@ + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 +- rm9000_tlb_hazard +- nop ++ mtc0_tlbw_hazard + tlbwr +- rm9000_tlb_hazard + eret + + 9: # handle the vmalloc range +@@ -206,10 +224,8 @@ + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 +- rm9000_tlb_hazard +- nop ++ mtc0_tlbw_hazard + tlbwr +- rm9000_tlb_hazard + eret + END(handle_vec1_r10k) + +diff -Nur linux-2.4.32-rc1/arch/mips64/mm/tlb-r4k.c linux-2.4.32-rc1.mips/arch/mips64/mm/tlb-r4k.c +--- linux-2.4.32-rc1/arch/mips64/mm/tlb-r4k.c 2005-01-19 15:09:33.000000000 +0100 ++++ linux-2.4.32-rc1.mips/arch/mips64/mm/tlb-r4k.c 2004-11-25 23:18:38.000000000 +0100 +@@ -1,24 +1,12 @@ + /* +- * Carsten Langgaard, carstenl@mips.com +- * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. +- * +- * This program is free software; you can distribute it and/or modify it +- * under the terms of the GNU General Public License (Version 2) as +- * published by the Free Software Foundation. +- * +- * This program is distributed in the hope it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive + * for more details. + * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +- * +- * MIPS64 CPU variant specific MMU routines. +- * These routine are not optimized in any way, they are done in a generic way +- * so they can be used on all MIPS64 compliant CPUs, and also done in an +- * attempt not to break anything for the R4xx0 style CPUs. ++ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) ++ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org ++ * Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + */ + #include + #include +@@ -30,9 +18,6 @@ + #include + #include + +-#undef DEBUG_TLB +-#undef DEBUG_TLBUPDATE +- + extern void except_vec1_r4k(void); + + /* CP0 hazard avoidance. */ +@@ -46,31 +31,23 @@ + unsigned long old_ctx; + int entry; + +-#ifdef DEBUG_TLB +- printk("[tlball]"); +-#endif +- + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi(); +- write_c0_entryhi(XKPHYS); + write_c0_entrylo0(0); + write_c0_entrylo1(0); +- BARRIER; + + entry = read_c0_wired(); + + /* Blast 'em all away. */ +- while(entry < current_cpu_data.tlbsize) { +- /* Make sure all entries differ. */ +- write_c0_entryhi(XKPHYS+entry*0x2000); ++ while (entry < current_cpu_data.tlbsize) { ++ write_c0_entryhi(XKPHYS + entry*0x2000); + write_c0_index(entry); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); +- BARRIER; + entry++; + } +- BARRIER; ++ tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); + } +@@ -79,12 +56,8 @@ + { + int cpu = smp_processor_id(); + +- if (cpu_context(cpu, mm) != 0) { +-#ifdef DEBUG_TLB +- printk("[tlbmm<%d>]", mm->context); +-#endif ++ if (cpu_context(cpu, mm) != 0) + drop_mmu_context(mm,cpu); +- } + } + + void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, +@@ -96,10 +69,6 @@ + unsigned long flags; + int size; + +-#ifdef DEBUG_TLB +- printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & ASID_MASK), +- start, end); +-#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; +@@ -110,25 +79,25 @@ + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); +- while(start < end) { ++ while (start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); +- if(idx < 0) ++ if (idx < 0) + continue; + /* Make sure all entries differ. */ + write_c0_entryhi(XKPHYS+idx*0x2000); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); +- BARRIER; + } ++ tlbw_use_hazard(); + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); +@@ -145,28 +114,26 @@ + unsigned long flags; + unsigned long oldpid, newpid, idx; + +-#ifdef DEBUG_TLB +- printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); +-#endif + newpid = cpu_asid(cpu, vma->vm_mm); + page &= (PAGE_MASK << 1); + local_irq_save(flags); + oldpid = read_c0_entryhi(); + write_c0_entryhi(page | newpid); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); +- if(idx < 0) ++ if (idx < 0) + goto finish; + /* Make sure all entries differ. */ + write_c0_entryhi(XKPHYS+idx*0x2000); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); ++ tlbw_use_hazard(); ++ + finish: +- BARRIER; + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +@@ -186,7 +153,7 @@ + + local_irq_save(flags); + write_c0_entryhi(page); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + idx = read_c0_index(); +@@ -195,10 +162,12 @@ + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); ++ tlbw_use_hazard(); + } +- BARRIER; + write_c0_entryhi(oldpid); ++ + local_irq_restore(flags); + } + +@@ -208,7 +177,6 @@ + void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) + { + unsigned long flags; +- unsigned int asid; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; +@@ -222,70 +190,58 @@ + + pid = read_c0_entryhi() & ASID_MASK; + +-#ifdef DEBUG_TLB +- if ((pid != (cpu_asid(smp_processor_id(), vma->vm_mm))) || +- (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) { +- printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d" +- "tlbpid=%d\n", (int) (cpu_context(smp_processor_id(), +- vma->vm_mm) & ASID_MASK), pid); +- } +-#endif +- + local_irq_save(flags); + address &= (PAGE_MASK << 1); +- write_c0_entryhi(address | (pid)); ++ write_c0_entryhi(address | pid); + pgdp = pgd_offset(vma->vm_mm, address); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_probe(); + BARRIER; + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset(pmdp, address); +- BARRIER; + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); +- write_c0_entryhi(address | (pid)); +- BARRIER; +- if(idx < 0) { ++ write_c0_entryhi(address | pid); ++ mtc0_tlbw_hazard(); ++ if (idx < 0) + tlb_write_random(); +- } else { ++ else + tlb_write_indexed(); +- } +- BARRIER; ++ tlbw_use_hazard(); + write_c0_entryhi(pid); +- BARRIER; + local_irq_restore(flags); + } + +-void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, +- unsigned long entryhi, unsigned long pagemask) ++void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, ++ unsigned long entryhi, unsigned long pagemask) + { +- unsigned long flags; +- unsigned long wired; +- unsigned long old_pagemask; +- unsigned long old_ctx; +- +- local_irq_save(flags); +- /* Save old context and create impossible VPN2 value */ +- old_ctx = (read_c0_entryhi() & ASID_MASK); +- old_pagemask = read_c0_pagemask(); +- wired = read_c0_wired(); +- write_c0_wired(wired + 1); +- write_c0_index(wired); +- BARRIER; +- write_c0_pagemask(pagemask); +- write_c0_entryhi(entryhi); +- write_c0_entrylo0(entrylo0); +- write_c0_entrylo1(entrylo1); +- BARRIER; +- tlb_write_indexed(); +- BARRIER; +- +- write_c0_entryhi(old_ctx); +- BARRIER; +- write_c0_pagemask(old_pagemask); +- local_flush_tlb_all(); +- local_irq_restore(flags); ++ unsigned long flags; ++ unsigned long wired; ++ unsigned long old_pagemask; ++ unsigned long old_ctx; ++ ++ local_irq_save(flags); ++ /* Save old context and create impossible VPN2 value */ ++ old_ctx = read_c0_entryhi() & ASID_MASK; ++ old_pagemask = read_c0_pagemask(); ++ wired = read_c0_wired(); ++ write_c0_wired(wired + 1); ++ write_c0_index(wired); ++ BARRIER; ++ write_c0_pagemask(pagemask); ++ write_c0_entryhi(entryhi); ++ write_c0_entrylo0(entrylo0); ++ write_c0_entrylo1(entrylo1); ++ mtc0_tlbw_hazard(); ++ tlb_write_indexed(); ++ tlbw_use_hazard(); ++ ++ write_c0_entryhi(old_ctx); ++ BARRIER; ++ write_c0_pagemask(old_pagemask); ++ local_flush_tlb_all(); ++ local_irq_restore(flags); + } + + /* +@@ -317,17 +273,15 @@ + } + + write_c0_index(temp_tlb_entry); +- BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); +- BARRIER; ++ mtc0_tlbw_hazard(); + tlb_write_indexed(); +- BARRIER; ++ tlbw_use_hazard(); + + write_c0_entryhi(old_ctx); +- BARRIER; + write_c0_pagemask(old_pagemask); + out: + local_irq_restore(flags); +@@ -348,15 +302,23 @@ + return; + + config1 = read_c0_config1(); +- if (!((config1 >> 7) & 3)) +- panic("No MMU present"); ++ if (!((config >> 7) & 3)) ++ panic("No TLB present"); + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; + } + + void __init r4k_tlb_init(void) + { +- unsigned long config = read_c0_config(); ++ unsigned int config = read_c0_config(); ++ ++ /* ++ * You should never change this register: ++ * - On R4600 1.7 the tlbp never hits for pages smaller than ++ * the value in the c0_pagemask register. ++ * - The entire mm handling assumes the c0_pagemask register to ++ * be set for 4kb pages. ++ */ + probe_tlb(config); + write_c0_pagemask(PM_DEFAULT_MASK); + write_c0_wired(0); +diff -Nur linux-2.4.32-rc1/drivers/char/au1000_gpio.c linux-2.4.32-rc1.mips/drivers/char/au1000_gpio.c +--- linux-2.4.32-rc1/drivers/char/au1000_gpio.c 2003-08-25 13:44:41.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/au1000_gpio.c 2003-12-20 14:18:51.000000000 +0100 +@@ -246,7 +246,7 @@ + + static struct miscdevice au1000gpio_miscdev = + { +- GPIO_MINOR, ++ MISC_DYNAMIC_MINOR, + "au1000_gpio", + &au1000gpio_fops + }; +diff -Nur linux-2.4.32-rc1/drivers/char/au1550_psc_spi.c linux-2.4.32-rc1.mips/drivers/char/au1550_psc_spi.c +--- linux-2.4.32-rc1/drivers/char/au1550_psc_spi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/au1550_psc_spi.c 2005-02-11 21:37:24.000000000 +0100 +@@ -0,0 +1,466 @@ ++/* ++ * Driver for Alchemy Au1550 SPI on the PSC. ++ * ++ * Copyright 2004 Embedded Edge, LLC. ++ * dan@embeddededge.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_MIPS_PB1550 ++#include ++#endif ++ ++#ifdef CONFIG_MIPS_DB1550 ++#include ++#endif ++ ++#ifdef CONFIG_MIPS_PB1200 ++#include ++#endif ++ ++/* This is just a simple programmed I/O SPI interface on the PSC of the 1550. ++ * We support open, close, write, and ioctl. The SPI is a full duplex ++ * interface, you can't read without writing. So, the write system call ++ * copies the bytes out to the SPI, and whatever is returned is placed ++ * in the same buffer. Kinda weird, maybe we'll change it, but for now ++ * it works OK. ++ * I didn't implement any DMA yet, and it's a debate about the necessity. ++ * The SPI clocks are usually quite fast, so data is sent/received as ++ * quickly as you can stuff the FIFO. The overhead of DMA and interrupts ++ * are usually far greater than the data transfer itself. If, however, ++ * we find applications that move large amounts of data, we may choose ++ * use the overhead of buffering and DMA to do the work. ++ */ ++ ++/* The maximum clock rate specified in the manual is 2mHz. ++*/ ++#define MAX_BAUD_RATE (2 * 1000000) ++#define PSC_INTCLK_RATE (32 * 1000000) ++ ++static int inuse; ++ ++/* We have to know what the user requested for the data length ++ * so we know how to stuff the fifo. The FIFO is 32 bits wide, ++ * and we have to load it with the bits to go in a single transfer. ++ */ ++static uint spi_datalen; ++ ++static int ++au1550spi_master_done( int ms ) ++{ ++ int timeout=ms; ++ volatile psc_spi_t *sp; ++ ++ sp = (volatile psc_spi_t *)SPI_PSC_BASE; ++ ++ /* Loop until MD is set or timeout has expired */ ++ while(!(sp->psc_spievent & PSC_SPIEVNT_MD) && timeout--) udelay(1000); ++ ++ if ( !timeout ) ++ return 0; ++ else ++ sp->psc_spievent |= PSC_SPIEVNT_MD; ++ ++ return 1; ++} ++ ++static int ++au1550spi_open(struct inode *inode, struct file *file) ++{ ++ if (inuse) ++ return -EBUSY; ++ ++ inuse = 1; ++ ++ MOD_INC_USE_COUNT; ++ ++ return 0; ++} ++ ++static ssize_t ++au1550spi_write(struct file *fp, const char *bp, size_t count, loff_t *ppos) ++{ ++ int bytelen, i; ++ size_t rcount, retval; ++ unsigned char sb, *rp, *wp; ++ uint fifoword, pcr, stat; ++ volatile psc_spi_t *sp; ++ ++ /* Get the number of bytes per transfer. ++ */ ++ bytelen = ((spi_datalen - 1) / 8) + 1; ++ ++ /* User needs to send us multiple of this count. ++ */ ++ if ((count % bytelen) != 0) ++ return -EINVAL; ++ ++ rp = wp = (unsigned char *)bp; ++ retval = rcount = count; ++ ++ /* Reset the FIFO. ++ */ ++ sp = (volatile psc_spi_t *)SPI_PSC_BASE; ++ sp->psc_spipcr = (PSC_SPIPCR_RC | PSC_SPIPCR_TC); ++ au_sync(); ++ do { ++ pcr = sp->psc_spipcr; ++ au_sync(); ++ } while (pcr != 0); ++ ++ /* Prime the transmit FIFO. ++ */ ++ while (count > 0) { ++ fifoword = 0; ++ for (i=0; ipsc_spitxrx = fifoword; ++ au_sync(); ++ stat = sp->psc_spistat; ++ au_sync(); ++ if (stat & PSC_SPISTAT_TF) ++ break; ++ } ++ ++ /* Start the transfer. ++ */ ++ sp->psc_spipcr = PSC_SPIPCR_MS; ++ au_sync(); ++ ++ /* Now, just keep the transmit fifo full and empty the receive. ++ */ ++ while (count > 0) { ++ stat = sp->psc_spistat; ++ au_sync(); ++ while ((stat & PSC_SPISTAT_RE) == 0) { ++ fifoword = sp->psc_spitxrx; ++ au_sync(); ++ for (i=0; i>= 8; ++ rp++; ++ } ++ rcount -= bytelen; ++ stat = sp->psc_spistat; ++ au_sync(); ++ } ++ if ((stat & PSC_SPISTAT_TF) == 0) { ++ fifoword = 0; ++ for (i=0; ipsc_spitxrx = fifoword; ++ au_sync(); ++ } ++ } ++ ++ /* All of the bytes for transmit have been written. Hang ++ * out waiting for any residual bytes that are yet to be ++ * read from the fifo. ++ */ ++ while (rcount > 0) { ++ stat = sp->psc_spistat; ++ au_sync(); ++ if ((stat & PSC_SPISTAT_RE) == 0) { ++ fifoword = sp->psc_spitxrx; ++ au_sync(); ++ for (i=0; i>= 8; ++ rp++; ++ } ++ rcount -= bytelen; ++ } ++ } ++ ++ /* Wait for MasterDone event. 30ms timeout */ ++ if (!au1550spi_master_done(30) ) retval = -EFAULT; ++ return retval; ++} ++ ++static int ++au1550spi_release(struct inode *inode, struct file *file) ++{ ++ MOD_DEC_USE_COUNT; ++ ++ inuse = 0; ++ ++ return 0; ++} ++ ++/* Set the baud rate closest to the request, then return the actual ++ * value we are using. ++ */ ++static uint ++set_baud_rate(uint baud) ++{ ++ uint rate, tmpclk, brg, ctl, stat; ++ volatile psc_spi_t *sp; ++ ++ /* For starters, the input clock is divided by two. ++ */ ++ tmpclk = PSC_INTCLK_RATE/2; ++ ++ rate = tmpclk / baud; ++ ++ /* The dividers work as follows: ++ * baud = tmpclk / (2 * (brg + 1)) ++ */ ++ brg = (rate/2) - 1; ++ ++ /* Test BRG to ensure it will fit into the 6 bits allocated. ++ */ ++ ++ /* Make sure the device is disabled while we make the change. ++ */ ++ sp = (volatile psc_spi_t *)SPI_PSC_BASE; ++ ctl = sp->psc_spicfg; ++ au_sync(); ++ sp->psc_spicfg = ctl & ~PSC_SPICFG_DE_ENABLE; ++ au_sync(); ++ ctl = PSC_SPICFG_CLR_BAUD(ctl); ++ ctl |= PSC_SPICFG_SET_BAUD(brg); ++ sp->psc_spicfg = ctl; ++ au_sync(); ++ ++ /* If the device was running prior to getting here, wait for ++ * it to restart. ++ */ ++ if (ctl & PSC_SPICFG_DE_ENABLE) { ++ do { ++ stat = sp->psc_spistat; ++ au_sync(); ++ } while ((stat & PSC_SPISTAT_DR) == 0); ++ } ++ ++ /* Return the actual value. ++ */ ++ rate = tmpclk / (2 * (brg + 1)); ++ ++ return(rate); ++} ++ ++static uint ++set_word_len(uint len) ++{ ++ uint ctl, stat; ++ volatile psc_spi_t *sp; ++ ++ if ((len < 4) || (len > 24)) ++ return -EINVAL; ++ ++ /* Make sure the device is disabled while we make the change. ++ */ ++ sp = (volatile psc_spi_t *)SPI_PSC_BASE; ++ ctl = sp->psc_spicfg; ++ au_sync(); ++ sp->psc_spicfg = ctl & ~PSC_SPICFG_DE_ENABLE; ++ au_sync(); ++ ctl = PSC_SPICFG_CLR_LEN(ctl); ++ ctl |= PSC_SPICFG_SET_LEN(len); ++ sp->psc_spicfg = ctl; ++ au_sync(); ++ ++ /* If the device was running prior to getting here, wait for ++ * it to restart. ++ */ ++ if (ctl & PSC_SPICFG_DE_ENABLE) { ++ do { ++ stat = sp->psc_spistat; ++ au_sync(); ++ } while ((stat & PSC_SPISTAT_DR) == 0); ++ } ++ ++ return 0; ++} ++ ++static int ++au1550spi_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ int status; ++ u32 val; ++ ++ status = 0; ++ ++ switch(cmd) { ++ case AU1550SPI_WORD_LEN: ++ status = set_word_len(arg); ++ break; ++ ++ case AU1550SPI_SET_BAUD: ++ if (get_user(val, (u32 *)arg)) ++ return -EFAULT; ++ ++ val = set_baud_rate(val); ++ if (put_user(val, (u32 *)arg)) ++ return -EFAULT; ++ break; ++ ++ default: ++ status = -ENOIOCTLCMD; ++ ++ } ++ ++ return status; ++} ++ ++ ++static struct file_operations au1550spi_fops = ++{ ++ owner: THIS_MODULE, ++ write: au1550spi_write, ++ ioctl: au1550spi_ioctl, ++ open: au1550spi_open, ++ release: au1550spi_release, ++}; ++ ++ ++static struct miscdevice au1550spi_miscdev = ++{ ++ MISC_DYNAMIC_MINOR, ++ "au1550_spi", ++ &au1550spi_fops ++}; ++ ++ ++int __init ++au1550spi_init(void) ++{ ++ uint clk, rate, stat; ++ volatile psc_spi_t *sp; ++ ++ /* Wire up Freq3 as a clock for the SPI. The PSC does ++ * factor of 2 divisor, so run a higher rate so we can ++ * get some granularity to the clock speeds. ++ * We can't do this in board set up because the frequency ++ * is computed too late. ++ */ ++ rate = get_au1x00_speed(); ++ rate /= PSC_INTCLK_RATE; ++ ++ /* The FRDIV in the frequency control is (FRDIV + 1) * 2 ++ */ ++ rate /=2; ++ rate--; ++ clk = au_readl(SYS_FREQCTRL1); ++ au_sync(); ++ clk &= ~SYS_FC_FRDIV3_MASK; ++ clk |= (rate << SYS_FC_FRDIV3_BIT); ++ clk |= SYS_FC_FE3; ++ au_writel(clk, SYS_FREQCTRL1); ++ au_sync(); ++ ++ /* Set up the clock source routing to get Freq3 to PSC0_intclk. ++ */ ++ clk = au_readl(SYS_CLKSRC); ++ au_sync(); ++ clk &= ~0x03e0; ++ clk |= (5 << 7); ++ au_writel(clk, SYS_CLKSRC); ++ au_sync(); ++ ++ /* Set up GPIO pin function to drive PSC0_SYNC1, which is ++ * the SPI Select. ++ */ ++ clk = au_readl(SYS_PINFUNC); ++ au_sync(); ++ clk |= 1; ++ au_writel(clk, SYS_PINFUNC); ++ au_sync(); ++ ++ /* Now, set up the PSC for SPI PIO mode. ++ */ ++ sp = (volatile psc_spi_t *)SPI_PSC_BASE; ++ sp->psc_ctrl = PSC_CTRL_DISABLE; ++ au_sync(); ++ sp->psc_sel = PSC_SEL_PS_SPIMODE; ++ sp->psc_spicfg = 0; ++ au_sync(); ++ sp->psc_ctrl = PSC_CTRL_ENABLE; ++ au_sync(); ++ do { ++ stat = sp->psc_spistat; ++ au_sync(); ++ } while ((stat & PSC_SPISTAT_SR) == 0); ++ ++ sp->psc_spicfg = (PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8 | ++ PSC_SPICFG_DD_DISABLE | PSC_SPICFG_MO); ++ sp->psc_spicfg |= PSC_SPICFG_SET_LEN(8); ++ spi_datalen = 8; ++ sp->psc_spimsk = PSC_SPIMSK_ALLMASK; ++ au_sync(); ++ ++ set_baud_rate(1000000); ++ ++ sp->psc_spicfg |= PSC_SPICFG_DE_ENABLE; ++ do { ++ stat = sp->psc_spistat; ++ au_sync(); ++ } while ((stat & PSC_SPISTAT_DR) == 0); ++ ++ misc_register(&au1550spi_miscdev); ++ printk("Au1550 SPI driver\n"); ++ return 0; ++} ++ ++ ++void __exit ++au1550spi_exit(void) ++{ ++ misc_deregister(&au1550spi_miscdev); ++} ++ ++ ++module_init(au1550spi_init); ++module_exit(au1550spi_exit); +diff -Nur linux-2.4.32-rc1/drivers/char/Config.in linux-2.4.32-rc1.mips/drivers/char/Config.in +--- linux-2.4.32-rc1/drivers/char/Config.in 2004-08-08 01:26:04.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/Config.in 2005-02-11 22:09:56.000000000 +0100 +@@ -313,14 +313,11 @@ + if [ "$CONFIG_OBSOLETE" = "y" -a "$CONFIG_ALPHA_BOOK1" = "y" ]; then + bool 'Tadpole ANA H8 Support (OBSOLETE)' CONFIG_H8 + fi +-if [ "$CONFIG_MIPS" = "y" -a "$CONFIG_NEW_TIME_C" = "y" ]; then +- tristate 'Generic MIPS RTC Support' CONFIG_MIPS_RTC +-fi + if [ "$CONFIG_SGI_IP22" = "y" ]; then +- bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286 ++ tristate 'Dallas DS1286 RTC support' CONFIG_DS1286 + fi + if [ "$CONFIG_SGI_IP27" = "y" ]; then +- bool 'SGI M48T35 RTC support' CONFIG_SGI_IP27_RTC ++ tristate 'SGI M48T35 RTC support' CONFIG_SGI_IP27_RTC + fi + if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then + tristate 'Dallas DS1742 RTC support' CONFIG_DS1742 +@@ -383,6 +380,11 @@ + source drivers/char/drm/Config.in + fi + fi ++ ++if [ "$CONFIG_X86" = "y" ]; then ++ tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE ++fi ++ + endmenu + + if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then +@@ -391,6 +393,7 @@ + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + tristate ' Alchemy Au1x00 GPIO device support' CONFIG_AU1X00_GPIO + tristate ' Au1000/ADS7846 touchscreen support' CONFIG_TS_AU1X00_ADS7846 ++ #tristate ' Alchemy Au1550 PSC SPI support' CONFIG_AU1550_PSC_SPI + fi + if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then + tristate ' ITE GPIO' CONFIG_ITE_GPIO +diff -Nur linux-2.4.32-rc1/drivers/char/decserial.c linux-2.4.32-rc1.mips/drivers/char/decserial.c +--- linux-2.4.32-rc1/drivers/char/decserial.c 2003-08-25 13:44:41.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/decserial.c 2004-09-28 02:53:01.000000000 +0200 +@@ -3,95 +3,105 @@ + * choose the right serial device at boot time + * + * triemer 6-SEP-1998 +- * sercons.c is designed to allow the three different kinds ++ * sercons.c is designed to allow the three different kinds + * of serial devices under the decstation world to co-exist +- * in the same kernel. The idea here is to abstract ++ * in the same kernel. The idea here is to abstract + * the pieces of the drivers that are common to this file + * so that they do not clash at compile time and runtime. + * + * HK 16-SEP-1998 v0.002 + * removed the PROM console as this is not a real serial + * device. Added support for PROM console in drivers/char/tty_io.c +- * instead. Although it may work to enable more than one ++ * instead. Although it may work to enable more than one + * console device I strongly recommend to use only one. ++ * ++ * Copyright (C) 2004 Maciej W. Rozycki + */ + + #include ++#include + #include ++ + #include ++#include ++ ++extern int register_zs_hook(unsigned int channel, ++ struct dec_serial_hook *hook); ++extern int unregister_zs_hook(unsigned int channel); ++ ++extern int register_dz_hook(unsigned int channel, ++ struct dec_serial_hook *hook); ++extern int unregister_dz_hook(unsigned int channel); + ++int register_dec_serial_hook(unsigned int channel, ++ struct dec_serial_hook *hook) ++{ + #ifdef CONFIG_ZS +-extern int zs_init(void); ++ if (IOASIC) ++ return register_zs_hook(channel, hook); + #endif +- + #ifdef CONFIG_DZ +-extern int dz_init(void); ++ if (!IOASIC) ++ return register_dz_hook(channel, hook); + #endif ++ return 0; ++} + +-#ifdef CONFIG_SERIAL_DEC_CONSOLE +- ++int unregister_dec_serial_hook(unsigned int channel) ++{ + #ifdef CONFIG_ZS +-extern void zs_serial_console_init(void); ++ if (IOASIC) ++ return unregister_zs_hook(channel); + #endif +- + #ifdef CONFIG_DZ +-extern void dz_serial_console_init(void); +-#endif +- ++ if (!IOASIC) ++ return unregister_dz_hook(channel); + #endif ++ return 0; ++} + +-/* rs_init - starts up the serial interface - +- handle normal case of starting up the serial interface */ + +-#ifdef CONFIG_SERIAL_DEC ++extern int zs_init(void); ++extern int dz_init(void); + ++/* ++ * rs_init - starts up the serial interface - ++ * handle normal case of starting up the serial interface ++ */ + int __init rs_init(void) + { +- +-#if defined(CONFIG_ZS) && defined(CONFIG_DZ) +- if (IOASIC) +- return zs_init(); +- else +- return dz_init(); +-#else +- + #ifdef CONFIG_ZS +- return zs_init(); ++ if (IOASIC) ++ return zs_init(); + #endif +- + #ifdef CONFIG_DZ +- return dz_init(); +-#endif +- ++ if (!IOASIC) ++ return dz_init(); + #endif ++ return -ENXIO; + } + + __initcall(rs_init); + +-#endif + + #ifdef CONFIG_SERIAL_DEC_CONSOLE + +-/* dec_serial_console_init handles the special case of starting +- * up the console on the serial port ++extern void zs_serial_console_init(void); ++extern void dz_serial_console_init(void); ++ ++/* ++ * dec_serial_console_init handles the special case of starting ++ * up the console on the serial port + */ + void __init dec_serial_console_init(void) + { +-#if defined(CONFIG_ZS) && defined(CONFIG_DZ) +- if (IOASIC) +- zs_serial_console_init(); +- else +- dz_serial_console_init(); +-#else +- + #ifdef CONFIG_ZS +- zs_serial_console_init(); ++ if (IOASIC) ++ zs_serial_console_init(); + #endif +- + #ifdef CONFIG_DZ +- dz_serial_console_init(); +-#endif +- ++ if (!IOASIC) ++ dz_serial_console_init(); + #endif + } + +diff -Nur linux-2.4.32-rc1/drivers/char/ds1286.c linux-2.4.32-rc1.mips/drivers/char/ds1286.c +--- linux-2.4.32-rc1/drivers/char/ds1286.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/ds1286.c 2004-01-10 06:21:39.000000000 +0100 +@@ -1,6 +1,10 @@ + /* + * DS1286 Real Time Clock interface for Linux + * ++ * Copyright (C) 2003 TimeSys Corp. ++ * S. James Hill (James.Hill@timesys.com) ++ * (sjhill@realitydiluted.com) ++ * + * Copyright (C) 1998, 1999, 2000 Ralf Baechle + * + * Based on code written by Paul Gortmaker. +@@ -29,6 +33,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -95,6 +100,12 @@ + return -EIO; + } + ++void rtc_ds1286_wait(void) ++{ ++ unsigned char sec = CMOS_READ(RTC_SECONDS); ++ while (sec == CMOS_READ(RTC_SECONDS)); ++} ++ + static int ds1286_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) + { +@@ -249,23 +260,22 @@ + { + spin_lock_irq(&ds1286_lock); + +- if (ds1286_status & RTC_IS_OPEN) +- goto out_busy; ++ if (ds1286_status & RTC_IS_OPEN) { ++ spin_unlock_irq(&ds1286_lock); ++ return -EBUSY; ++ } + + ds1286_status |= RTC_IS_OPEN; + +- spin_lock_irq(&ds1286_lock); ++ spin_unlock_irq(&ds1286_lock); + return 0; +- +-out_busy: +- spin_lock_irq(&ds1286_lock); +- return -EBUSY; + } + + static int ds1286_release(struct inode *inode, struct file *file) + { ++ spin_lock_irq(&ds1286_lock); + ds1286_status &= ~RTC_IS_OPEN; +- ++ spin_unlock_irq(&ds1286_lock); + return 0; + } + +@@ -276,32 +286,6 @@ + return 0; + } + +-/* +- * The various file operations we support. +- */ +- +-static struct file_operations ds1286_fops = { +- .llseek = no_llseek, +- .read = ds1286_read, +- .poll = ds1286_poll, +- .ioctl = ds1286_ioctl, +- .open = ds1286_open, +- .release = ds1286_release, +-}; +- +-static struct miscdevice ds1286_dev= +-{ +- .minor = RTC_MINOR, +- .name = "rtc", +- .fops = &ds1286_fops, +-}; +- +-int __init ds1286_init(void) +-{ +- printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); +- return misc_register(&ds1286_dev); +-} +- + static char *days[] = { + "***", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; +@@ -528,3 +512,38 @@ + BCD_TO_BIN(alm_tm->tm_hour); + alm_tm->tm_sec = 0; + } ++ ++static struct file_operations ds1286_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .read = ds1286_read, ++ .poll = ds1286_poll, ++ .ioctl = ds1286_ioctl, ++ .open = ds1286_open, ++ .release = ds1286_release, ++}; ++ ++static struct miscdevice ds1286_dev = ++{ ++ .minor = RTC_MINOR, ++ .name = "rtc", ++ .fops = &ds1286_fops, ++}; ++ ++static int __init ds1286_init(void) ++{ ++ printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); ++ return misc_register(&ds1286_dev); ++} ++ ++static void __exit ds1286_exit(void) ++{ ++ misc_deregister(&ds1286_dev); ++} ++ ++module_init(ds1286_init); ++module_exit(ds1286_exit); ++EXPORT_NO_SYMBOLS; ++ ++MODULE_AUTHOR("Ralf Baechle"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/char/ds1742.c linux-2.4.32-rc1.mips/drivers/char/ds1742.c +--- linux-2.4.32-rc1/drivers/char/ds1742.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/ds1742.c 2004-01-09 20:27:16.000000000 +0100 +@@ -142,6 +142,7 @@ + CMOS_WRITE(RTC_WRITE, RTC_CONTROL); + + /* convert */ ++ memset(&tm, 0, sizeof(struct rtc_time)); + to_tm(t, &tm); + + /* check each field one by one */ +@@ -216,6 +217,7 @@ + unsigned long curr_time; + + curr_time = rtc_ds1742_get_time(); ++ memset(&tm, 0, sizeof(struct rtc_time)); + to_tm(curr_time, &tm); + + p = buf; +@@ -251,8 +253,8 @@ + + void rtc_ds1742_wait(void) + { +- while (CMOS_READ(RTC_SECONDS) & 1); +- while (!(CMOS_READ(RTC_SECONDS) & 1)); ++ unsigned char sec = CMOS_READ(RTC_SECONDS); ++ while (sec == CMOS_READ(RTC_SECONDS)); + } + + static int ds1742_ioctl(struct inode *inode, struct file *file, +@@ -264,6 +266,7 @@ + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + curr_time = rtc_ds1742_get_time(); ++ memset(&rtc_tm, 0, sizeof(struct rtc_time)); + to_tm(curr_time, &rtc_tm); + rtc_tm.tm_year -= 1900; + return copy_to_user((void *) arg, &rtc_tm, sizeof(rtc_tm)) ? +diff -Nur linux-2.4.32-rc1/drivers/char/dummy_keyb.c linux-2.4.32-rc1.mips/drivers/char/dummy_keyb.c +--- linux-2.4.32-rc1/drivers/char/dummy_keyb.c 2003-08-25 13:44:41.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/dummy_keyb.c 2004-01-09 09:53:08.000000000 +0100 +@@ -140,3 +140,7 @@ + { + printk("Dummy keyboard driver installed.\n"); + } ++#ifdef CONFIG_MAGIC_SYSRQ ++unsigned char kbd_sysrq_key; ++unsigned char kbd_sysrq_xlate[128]; ++#endif +diff -Nur linux-2.4.32-rc1/drivers/char/dz.c linux-2.4.32-rc1.mips/drivers/char/dz.c +--- linux-2.4.32-rc1/drivers/char/dz.c 2005-01-19 15:09:44.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/dz.c 2004-12-27 05:13:42.000000000 +0100 +@@ -1,11 +1,13 @@ + /* +- * dz.c: Serial port driver for DECStations equiped ++ * dz.c: Serial port driver for DECstations equipped + * with the DZ chipset. + * + * Copyright (C) 1998 Olivier A. D. Lebaillif + * + * Email: olivier.lebaillif@ifrsys.com + * ++ * Copyright (C) 2004 Maciej W. Rozycki ++ * + * [31-AUG-98] triemer + * Changed IRQ to use Harald's dec internals interrupts.h + * removed base_addr code - moving address assignment to setup.c +@@ -24,6 +26,7 @@ + #undef DEBUG_DZ + + #include ++#include + #include + #include + #include +@@ -54,33 +57,56 @@ + #include + #include + +-#define CONSOLE_LINE (3) /* for definition of struct console */ ++#ifdef CONFIG_MAGIC_SYSRQ ++#include ++#endif + + #include "dz.h" + +-#define DZ_INTR_DEBUG 1 +- + DECLARE_TASK_QUEUE(tq_serial); + +-static struct dz_serial *lines[4]; +-static unsigned char tmp_buffer[256]; ++static struct dz_serial multi[DZ_NB_PORT]; /* Four serial lines in the DZ chip */ ++static struct tty_driver serial_driver, callout_driver; ++ ++static struct tty_struct *serial_table[DZ_NB_PORT]; ++static struct termios *serial_termios[DZ_NB_PORT]; ++static struct termios *serial_termios_locked[DZ_NB_PORT]; ++ ++static int serial_refcount; + +-#ifdef DEBUG_DZ + /* +- * debugging code to send out chars via prom ++ * tmp_buf is used as a temporary buffer by serial_write. We need to ++ * lock it in case the copy_from_user blocks while swapping in a page, ++ * and some other program tries to do a serial write at the same time. ++ * Since the lock will only come under contention when the system is ++ * swapping and available memory is low, it makes sense to share one ++ * buffer across all the serial ports, since it significantly saves ++ * memory if large numbers of serial ports are open. + */ +-static void debug_console(const char *s, int count) +-{ +- unsigned i; ++static unsigned char *tmp_buf; ++static DECLARE_MUTEX(tmp_buf_sem); + +- for (i = 0; i < count; i++) { +- if (*s == 10) +- prom_printf("%c", 13); +- prom_printf("%c", *s++); +- } +-} ++static char *dz_name __initdata = "DECstation DZ serial driver version "; ++static char *dz_version __initdata = "1.03"; ++ ++static struct dz_serial *lines[DZ_NB_PORT]; ++static unsigned char tmp_buffer[256]; ++ ++#ifdef CONFIG_SERIAL_DEC_CONSOLE ++static struct console dz_sercons; ++#endif ++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ ++ !defined(MODULE) ++static unsigned long break_pressed; /* break, really ... */ + #endif + ++static void change_speed (struct dz_serial *); ++ ++static int baud_table[] = { ++ 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, ++ 9600, 0 ++}; ++ + /* + * ------------------------------------------------------------ + * dz_in () and dz_out () +@@ -94,15 +120,16 @@ + { + volatile unsigned short *addr = + (volatile unsigned short *) (info->port + offset); ++ + return *addr; + } + + static inline void dz_out(struct dz_serial *info, unsigned offset, + unsigned short value) + { +- + volatile unsigned short *addr = + (volatile unsigned short *) (info->port + offset); ++ + *addr = value; + } + +@@ -143,25 +170,24 @@ + + tmp |= mask; /* set the TX flag */ + dz_out(info, DZ_TCR, tmp); +- + } + + /* + * ------------------------------------------------------------ +- * Here starts the interrupt handling routines. All of the +- * following subroutines are declared as inline and are folded +- * into dz_interrupt. They were separated out for readability's +- * sake. + * +- * Note: rs_interrupt() is a "fast" interrupt, which means that it ++ * Here starts the interrupt handling routines. All of the following ++ * subroutines are declared as inline and are folded into ++ * dz_interrupt(). They were separated out for readability's sake. ++ * ++ * Note: dz_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify +- * rs_interrupt() should try to keep the interrupt handler as fast as ++ * dz_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer dz.c + * +- * and look at the resulting assemble code in serial.s. ++ * and look at the resulting assemble code in dz.s. + * + * ------------------------------------------------------------ + */ +@@ -188,101 +214,97 @@ + * This routine deals with inputs from any lines. + * ------------------------------------------------------------ + */ +-static inline void receive_chars(struct dz_serial *info_in) ++static inline void receive_chars(struct dz_serial *info_in, ++ struct pt_regs *regs) + { +- + struct dz_serial *info; +- struct tty_struct *tty = 0; ++ struct tty_struct *tty; + struct async_icount *icount; +- int ignore = 0; +- unsigned short status, tmp; +- unsigned char ch; +- +- /* this code is going to be a problem... +- the call to tty_flip_buffer is going to need +- to be rethought... +- */ +- do { +- status = dz_in(info_in, DZ_RBUF); +- info = lines[LINE(status)]; ++ int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; ++ unsigned short status; ++ unsigned char ch, flag; ++ int i; + +- /* punt so we don't get duplicate characters */ +- if (!(status & DZ_DVAL)) +- goto ignore_char; +- +- ch = UCHAR(status); /* grab the char */ +- +-#if 0 +- if (info->is_console) { +- if (ch == 0) +- return; /* it's a break ... */ +- } +-#endif ++ while ((status = dz_in(info_in, DZ_RBUF)) & DZ_DVAL) { ++ info = lines[LINE(status)]; ++ tty = info->tty; /* point to the proper dev */ + +- tty = info->tty; /* now tty points to the proper dev */ +- icount = &info->icount; ++ ch = UCHAR(status); /* grab the char */ + +- if (!tty) +- break; +- if (tty->flip.count >= TTY_FLIPBUF_SIZE) +- break; ++ if (!tty && (!info->hook || !info->hook->rx_char)) ++ continue; + +- *tty->flip.char_buf_ptr = ch; +- *tty->flip.flag_buf_ptr = 0; ++ icount = &info->icount; + icount->rx++; + +- /* keep track of the statistics */ +- if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) { +- if (status & DZ_PERR) /* parity error */ +- icount->parity++; +- else if (status & DZ_FERR) /* frame error */ +- icount->frame++; +- if (status & DZ_OERR) /* overrun error */ +- icount->overrun++; +- +- /* check to see if we should ignore the character +- and mask off conditions that should be ignored ++ flag = 0; ++ if (status & DZ_FERR) { /* frame error */ ++ /* ++ * There is no separate BREAK status bit, so ++ * treat framing errors as BREAKs for Magic SysRq ++ * and SAK; normally, otherwise. + */ +- +- if (status & info->ignore_status_mask) { +- if (++ignore > 100) +- break; +- goto ignore_char; ++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ ++ !defined(MODULE) ++ if (info->line == dz_sercons.index) { ++ if (!break_pressed) ++ break_pressed = jiffies; ++ continue; + } +- /* mask off the error conditions we want to ignore */ +- tmp = status & info->read_status_mask; +- +- if (tmp & DZ_PERR) { +- *tty->flip.flag_buf_ptr = TTY_PARITY; +-#ifdef DEBUG_DZ +- debug_console("PERR\n", 5); +-#endif +- } else if (tmp & DZ_FERR) { +- *tty->flip.flag_buf_ptr = TTY_FRAME; +-#ifdef DEBUG_DZ +- debug_console("FERR\n", 5); + #endif ++ flag = TTY_BREAK; ++ if (info->flags & DZ_SAK) ++ do_SAK(tty); ++ else ++ flag = TTY_FRAME; ++ } else if (status & DZ_OERR) /* overrun error */ ++ flag = TTY_OVERRUN; ++ else if (status & DZ_PERR) /* parity error */ ++ flag = TTY_PARITY; ++ ++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ ++ !defined(MODULE) ++ if (break_pressed && info->line == dz_sercons.index) { ++ if (time_before(jiffies, break_pressed + HZ * 5)) { ++ handle_sysrq(ch, regs, NULL, NULL); ++ break_pressed = 0; ++ continue; + } +- if (tmp & DZ_OERR) { +-#ifdef DEBUG_DZ +- debug_console("OERR\n", 5); ++ break_pressed = 0; ++ } + #endif +- if (tty->flip.count < TTY_FLIPBUF_SIZE) { +- tty->flip.count++; +- tty->flip.flag_buf_ptr++; +- tty->flip.char_buf_ptr++; +- *tty->flip.flag_buf_ptr = TTY_OVERRUN; +- } +- } ++ ++ if (info->hook && info->hook->rx_char) { ++ (*info->hook->rx_char)(ch, flag); ++ return; + } +- tty->flip.flag_buf_ptr++; +- tty->flip.char_buf_ptr++; +- tty->flip.count++; +- ignore_char: +- } while (status & DZ_DVAL); + +- if (tty) +- tty_flip_buffer_push(tty); ++ /* keep track of the statistics */ ++ switch (flag) { ++ case TTY_FRAME: ++ icount->frame++; ++ break; ++ case TTY_PARITY: ++ icount->parity++; ++ break; ++ case TTY_OVERRUN: ++ icount->overrun++; ++ break; ++ case TTY_BREAK: ++ icount->brk++; ++ break; ++ default: ++ break; ++ } ++ ++ if ((status & info->ignore_status_mask) == 0) { ++ tty_insert_flip_char(tty, ch, flag); ++ lines_rx[LINE(status)] = 1; ++ } ++ } ++ for (i = 0; i < DZ_NB_PORT; i++) ++ if (lines_rx[i]) ++ tty_flip_buffer_push(lines[i]->tty); + } + + /* +@@ -292,20 +314,34 @@ + * This routine deals with outputs to any lines. + * ------------------------------------------------------------ + */ +-static inline void transmit_chars(struct dz_serial *info) ++static inline void transmit_chars(struct dz_serial *info_in) + { ++ struct dz_serial *info; ++ unsigned short status; + unsigned char tmp; + ++ status = dz_in(info_in, DZ_CSR); ++ info = lines[LINE(status)]; + ++ if (info->hook || !info->tty) { ++ unsigned short mask, tmp; + +- if (info->x_char) { /* XON/XOFF chars */ ++ mask = 1 << info->line; ++ tmp = dz_in(info, DZ_TCR); /* read the TX flag */ ++ tmp &= ~mask; /* clear the TX flag */ ++ dz_out(info, DZ_TCR, tmp); ++ return; ++ } ++ ++ if (info->x_char) { /* XON/XOFF chars */ + dz_out(info, DZ_TDR, info->x_char); + info->icount.tx++; + info->x_char = 0; + return; + } + /* if nothing to do or stopped or hardware stopped */ +- if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped) { ++ if (info->xmit_cnt <= 0 || ++ info->tty->stopped || info->tty->hw_stopped) { + dz_stop(info->tty); + return; + } +@@ -359,15 +395,14 @@ + */ + static void dz_interrupt(int irq, void *dev, struct pt_regs *regs) + { +- struct dz_serial *info; ++ struct dz_serial *info = (struct dz_serial *)dev; + unsigned short status; + + /* get the reason why we just got an irq */ +- status = dz_in((struct dz_serial *) dev, DZ_CSR); +- info = lines[LINE(status)]; /* re-arrange info the proper port */ ++ status = dz_in(info, DZ_CSR); + + if (status & DZ_RDONE) +- receive_chars(info); /* the receive function */ ++ receive_chars(info, regs); + + if (status & DZ_TRDY) + transmit_chars(info); +@@ -514,7 +549,7 @@ + + + info->cflags &= ~DZ_CREAD; /* turn off receive enable flag */ +- dz_out(info, DZ_LPR, info->cflags); ++ dz_out(info, DZ_LPR, info->cflags | info->line); + + if (info->xmit_buf) { /* free Tx buffer */ + free_page((unsigned long) info->xmit_buf); +@@ -545,18 +580,21 @@ + { + unsigned long flags; + unsigned cflag; +- int baud; ++ int baud, i; + +- if (!info->tty || !info->tty->termios) +- return; ++ if (!info->hook) { ++ if (!info->tty || !info->tty->termios) ++ return; ++ cflag = info->tty->termios->c_cflag; ++ } else { ++ cflag = info->hook->cflags; ++ } + + save_flags(flags); + cli(); + + info->cflags = info->line; + +- cflag = info->tty->termios->c_cflag; +- + switch (cflag & CSIZE) { + case CS5: + info->cflags |= DZ_CS5; +@@ -579,7 +617,16 @@ + if (cflag & PARODD) + info->cflags |= DZ_PARODD; + +- baud = tty_get_baud_rate(info->tty); ++ i = cflag & CBAUD; ++ if (i & CBAUDEX) { ++ i &= ~CBAUDEX; ++ if (!info->hook) ++ info->tty->termios->c_cflag &= ~CBAUDEX; ++ else ++ info->hook->cflags &= ~CBAUDEX; ++ } ++ baud = baud_table[i]; ++ + switch (baud) { + case 50: + info->cflags |= DZ_B50; +@@ -629,16 +676,16 @@ + } + + info->cflags |= DZ_RXENAB; +- dz_out(info, DZ_LPR, info->cflags); ++ dz_out(info, DZ_LPR, info->cflags | info->line); + + /* setup accept flag */ + info->read_status_mask = DZ_OERR; +- if (I_INPCK(info->tty)) ++ if (info->tty && I_INPCK(info->tty)) + info->read_status_mask |= (DZ_FERR | DZ_PERR); + + /* characters to ignore */ + info->ignore_status_mask = 0; +- if (I_IGNPAR(info->tty)) ++ if (info->tty && I_IGNPAR(info->tty)) + info->ignore_status_mask |= (DZ_FERR | DZ_PERR); + + restore_flags(flags); +@@ -694,7 +741,7 @@ + + down(&tmp_buf_sem); + while (1) { +- c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); ++ c = min(count, min(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + +@@ -707,7 +754,7 @@ + save_flags(flags); + cli(); + +- c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); ++ c = min(c, min(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE - 1)); + info->xmit_cnt += c; +@@ -727,7 +774,7 @@ + save_flags(flags); + cli(); + +- c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); ++ c = min(count, min(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; +@@ -845,7 +892,7 @@ + + /* + * ------------------------------------------------------------ +- * rs_ioctl () and friends ++ * dz_ioctl () and friends + * ------------------------------------------------------------ + */ + static int get_serial_info(struct dz_serial *info, +@@ -958,6 +1005,9 @@ + struct dz_serial *info = (struct dz_serial *) tty->driver_data; + int retval; + ++ if (info->hook) ++ return -ENODEV; ++ + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && + (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { +@@ -1252,19 +1302,14 @@ + int retval, line; + + line = MINOR(tty->device) - tty->driver.minor_start; +- +- /* The dz lines for the mouse/keyboard must be +- * opened using their respective drivers. +- */ + if ((line < 0) || (line >= DZ_NB_PORT)) + return -ENODEV; ++ info = lines[line]; + +- if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE)) ++ if (info->hook) + return -ENODEV; + +- info = lines[line]; + info->count++; +- + tty->driver_data = info; + info->tty = tty; + +@@ -1285,14 +1330,21 @@ + else + *tty->termios = info->callout_termios; + change_speed(info); +- + } ++#ifdef CONFIG_SERIAL_DEC_CONSOLE ++ if (dz_sercons.cflag && dz_sercons.index == line) { ++ tty->termios->c_cflag = dz_sercons.cflag; ++ dz_sercons.cflag = 0; ++ change_speed(info); ++ } ++#endif ++ + info->session = current->session; + info->pgrp = current->pgrp; + return 0; + } + +-static void show_serial_version(void) ++static void __init show_serial_version(void) + { + printk("%s%s\n", dz_name, dz_version); + } +@@ -1300,7 +1352,6 @@ + int __init dz_init(void) + { + int i; +- long flags; + struct dz_serial *info; + + /* Setup base handler, and timer table. */ +@@ -1311,9 +1362,9 @@ + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + #if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) +- serial_driver.name = "ttyS"; +-#else + serial_driver.name = "tts/%d"; ++#else ++ serial_driver.name = "ttyS"; + #endif + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64; +@@ -1352,9 +1403,9 @@ + */ + callout_driver = serial_driver; + #if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) +- callout_driver.name = "cua"; +-#else + callout_driver.name = "cua/%d"; ++#else ++ callout_driver.name = "cua"; + #endif + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; +@@ -1363,25 +1414,27 @@ + panic("Couldn't register serial driver"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver"); +- save_flags(flags); +- cli(); + + for (i = 0; i < DZ_NB_PORT; i++) { + info = &multi[i]; + lines[i] = info; +- info->magic = SERIAL_MAGIC; +- ++ info->tty = 0; ++ info->x_char = 0; + if (mips_machtype == MACH_DS23100 || + mips_machtype == MACH_DS5100) + info->port = (unsigned long) KN01_DZ11_BASE; + else + info->port = (unsigned long) KN02_DZ11_BASE; +- + info->line = i; +- info->tty = 0; ++ ++ if (info->hook && info->hook->init_info) { ++ (*info->hook->init_info)(info); ++ continue; ++ } ++ ++ info->magic = SERIAL_MAGIC; + info->close_delay = 50; + info->closing_wait = 3000; +- info->x_char = 0; + info->event = 0; + info->count = 0; + info->blocked_open = 0; +@@ -1393,25 +1446,16 @@ + info->normal_termios = serial_driver.init_termios; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); +- +- /* +- * If we are pointing to address zero then punt - not correctly +- * set up in setup.c to handle this. +- */ +- if (!info->port) +- return 0; +- +- printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line, +- info->port, dec_interrupt[DEC_IRQ_DZ11]); +- ++ printk("ttyS%02d at 0x%08x (irq = %d) is a DC7085 DZ\n", ++ info->line, info->port, dec_interrupt[DEC_IRQ_DZ11]); + tty_register_devfs(&serial_driver, 0, +- serial_driver.minor_start + info->line); ++ serial_driver.minor_start + info->line); + tty_register_devfs(&callout_driver, 0, +- callout_driver.minor_start + info->line); ++ callout_driver.minor_start + info->line); + } + +- /* reset the chip */ + #ifndef CONFIG_SERIAL_DEC_CONSOLE ++ /* reset the chip */ + dz_out(info, DZ_CSR, DZ_CLR); + while (dz_in(info, DZ_CSR) & DZ_CLR); + iob(); +@@ -1420,43 +1464,104 @@ + dz_out(info, DZ_CSR, DZ_MSE); + #endif + +- /* order matters here... the trick is that flags +- is updated... in request_irq - to immediatedly obliterate +- it is unwise. */ +- restore_flags(flags); +- +- + if (request_irq(dec_interrupt[DEC_IRQ_DZ11], dz_interrupt, +- SA_INTERRUPT, "DZ", lines[0])) ++ 0, "DZ", lines[0])) + panic("Unable to register DZ interrupt"); + ++ for (i = 0; i < DZ_NB_PORT; i++) ++ if (lines[i]->hook) { ++ startup(lines[i]); ++ if (lines[i]->hook->init_channel) ++ (*lines[i]->hook->init_channel)(lines[i]); ++ } ++ + return 0; + } + +-#ifdef CONFIG_SERIAL_DEC_CONSOLE +-static void dz_console_put_char(unsigned char ch) ++/* ++ * polling I/O routines ++ */ ++static int dz_poll_tx_char(void *handle, unsigned char ch) + { + unsigned long flags; +- int loops = 2500; +- unsigned short tmp = ch; +- /* this code sends stuff out to serial device - spinning its +- wheels and waiting. */ ++ struct dz_serial *info = handle; ++ unsigned short csr, tcr, trdy, mask; ++ int loops = 10000; ++ int ret; + +- /* force the issue - point it at lines[3] */ +- dz_console = &multi[CONSOLE_LINE]; ++ local_irq_save(flags); ++ csr = dz_in(info, DZ_CSR); ++ dz_out(info, DZ_CSR, csr & ~DZ_TIE); ++ tcr = dz_in(info, DZ_TCR); ++ tcr |= 1 << info->line; ++ mask = tcr; ++ dz_out(info, DZ_TCR, mask); ++ iob(); ++ local_irq_restore(flags); + +- save_flags(flags); +- cli(); ++ while (loops--) { ++ trdy = dz_in(info, DZ_CSR); ++ if (!(trdy & DZ_TRDY)) ++ continue; ++ trdy = (trdy & DZ_TLINE) >> 8; ++ if (trdy == info->line) ++ break; ++ mask &= ~(1 << trdy); ++ dz_out(info, DZ_TCR, mask); ++ iob(); ++ udelay(2); ++ } + ++ if (loops) { ++ dz_out(info, DZ_TDR, ch); ++ ret = 0; ++ } else ++ ret = -EAGAIN; + +- /* spin our wheels */ +- while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--); ++ dz_out(info, DZ_TCR, tcr); ++ dz_out(info, DZ_CSR, csr); + +- /* Actually transmit the character. */ +- dz_out(dz_console, DZ_TDR, tmp); ++ return ret; ++} + +- restore_flags(flags); ++static int dz_poll_rx_char(void *handle) ++{ ++ return -ENODEV; ++} ++ ++int register_dz_hook(unsigned int channel, struct dec_serial_hook *hook) ++{ ++ struct dz_serial *info = multi + channel; ++ ++ if (info->hook) { ++ printk("%s: line %d has already a hook registered\n", ++ __FUNCTION__, channel); ++ ++ return 0; ++ } else { ++ hook->poll_rx_char = dz_poll_rx_char; ++ hook->poll_tx_char = dz_poll_tx_char; ++ info->hook = hook; ++ ++ return 1; ++ } ++} ++ ++int unregister_dz_hook(unsigned int channel) ++{ ++ struct dz_serial *info = &multi[channel]; ++ ++ if (info->hook) { ++ info->hook = NULL; ++ return 1; ++ } else { ++ printk("%s: trying to unregister hook on line %d," ++ " but none is registered\n", __FUNCTION__, channel); ++ return 0; ++ } + } ++ ++#ifdef CONFIG_SERIAL_DEC_CONSOLE + /* + * ------------------------------------------------------------------- + * dz_console_print () +@@ -1465,17 +1570,19 @@ + * The console must be locked when we get here. + * ------------------------------------------------------------------- + */ +-static void dz_console_print(struct console *cons, ++static void dz_console_print(struct console *co, + const char *str, + unsigned int count) + { ++ struct dz_serial *info = multi + co->index; ++ + #ifdef DEBUG_DZ + prom_printf((char *) str); + #endif + while (count--) { + if (*str == '\n') +- dz_console_put_char('\r'); +- dz_console_put_char(*str++); ++ dz_poll_tx_char(info, '\r'); ++ dz_poll_tx_char(info, *str++); + } + } + +@@ -1486,12 +1593,12 @@ + + static int __init dz_console_setup(struct console *co, char *options) + { ++ struct dz_serial *info = multi + co->index; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + char *s; +- unsigned short mask, tmp; + + if (options) { + baud = simple_strtoul(options, NULL, 10); +@@ -1542,44 +1649,31 @@ + } + co->cflag = cflag; + +- /* TOFIX: force to console line */ +- dz_console = &multi[CONSOLE_LINE]; + if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) +- dz_console->port = KN01_DZ11_BASE; ++ info->port = KN01_DZ11_BASE; + else +- dz_console->port = KN02_DZ11_BASE; +- dz_console->line = CONSOLE_LINE; ++ info->port = KN02_DZ11_BASE; ++ info->line = co->index; + +- dz_out(dz_console, DZ_CSR, DZ_CLR); +- while ((tmp = dz_in(dz_console, DZ_CSR)) & DZ_CLR); ++ dz_out(info, DZ_CSR, DZ_CLR); ++ while (dz_in(info, DZ_CSR) & DZ_CLR); + + /* enable scanning */ +- dz_out(dz_console, DZ_CSR, DZ_MSE); ++ dz_out(info, DZ_CSR, DZ_MSE); + + /* Set up flags... */ +- dz_console->cflags = 0; +- dz_console->cflags |= DZ_B9600; +- dz_console->cflags |= DZ_CS8; +- dz_console->cflags |= DZ_PARENB; +- dz_out(dz_console, DZ_LPR, dz_console->cflags); +- +- mask = 1 << dz_console->line; +- tmp = dz_in(dz_console, DZ_TCR); /* read the TX flag */ +- if (!(tmp & mask)) { +- tmp |= mask; /* set the TX flag */ +- dz_out(dz_console, DZ_TCR, tmp); +- } ++ dz_out(info, DZ_LPR, cflag | info->line); ++ + return 0; + } + +-static struct console dz_sercons = +-{ +- .name = "ttyS", +- .write = dz_console_print, +- .device = dz_console_device, +- .setup = dz_console_setup, +- .flags = CON_CONSDEV | CON_PRINTBUFFER, +- .index = CONSOLE_LINE, ++static struct console dz_sercons = { ++ .name = "ttyS", ++ .write = dz_console_print, ++ .device = dz_console_device, ++ .setup = dz_console_setup, ++ .flags = CON_PRINTBUFFER, ++ .index = -1, + }; + + void __init dz_serial_console_init(void) +diff -Nur linux-2.4.32-rc1/drivers/char/dz.h linux-2.4.32-rc1.mips/drivers/char/dz.h +--- linux-2.4.32-rc1/drivers/char/dz.h 2002-08-03 02:39:43.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/dz.h 2004-09-28 02:53:01.000000000 +0200 +@@ -10,6 +10,8 @@ + #ifndef DZ_SERIAL_H + #define DZ_SERIAL_H + ++#include ++ + #define SERIAL_MAGIC 0x5301 + + /* +@@ -17,6 +19,7 @@ + */ + #define DZ_TRDY 0x8000 /* Transmitter empty */ + #define DZ_TIE 0x4000 /* Transmitter Interrupt Enable */ ++#define DZ_TLINE 0x0300 /* Transmitter Line Number */ + #define DZ_RDONE 0x0080 /* Receiver data ready */ + #define DZ_RIE 0x0040 /* Receive Interrupt Enable */ + #define DZ_MSE 0x0020 /* Master Scan Enable */ +@@ -37,19 +40,30 @@ + #define UCHAR(x) (unsigned char)(x & DZ_RBUF_MASK) + + /* +- * Definitions for the Transmit Register. ++ * Definitions for the Transmit Control Register. + */ + #define DZ_LINE_KEYBOARD 0x0001 + #define DZ_LINE_MOUSE 0x0002 + #define DZ_LINE_MODEM 0x0004 + #define DZ_LINE_PRINTER 0x0008 + ++#define DZ_MODEM_RTS 0x0800 /* RTS for the modem line (2) */ + #define DZ_MODEM_DTR 0x0400 /* DTR for the modem line (2) */ ++#define DZ_PRINT_RTS 0x0200 /* RTS for the printer line (3) */ ++#define DZ_PRINT_DTR 0x0100 /* DTR for the printer line (3) */ ++#define DZ_LNENB 0x000f /* Transmitter Line Enable */ + + /* + * Definitions for the Modem Status Register. + */ ++#define DZ_MODEM_RI 0x0800 /* RI for the modem line (2) */ ++#define DZ_MODEM_CD 0x0400 /* CD for the modem line (2) */ + #define DZ_MODEM_DSR 0x0200 /* DSR for the modem line (2) */ ++#define DZ_MODEM_CTS 0x0100 /* CTS for the modem line (2) */ ++#define DZ_PRINT_RI 0x0008 /* RI for the printer line (2) */ ++#define DZ_PRINT_CD 0x0004 /* CD for the printer line (2) */ ++#define DZ_PRINT_DSR 0x0002 /* DSR for the printer line (2) */ ++#define DZ_PRINT_CTS 0x0001 /* CTS for the printer line (2) */ + + /* + * Definitions for the Transmit Data Register. +@@ -115,9 +129,6 @@ + + #define DZ_EVENT_WRITE_WAKEUP 0 + +-#ifndef MIN +-#define MIN(a,b) ((a) < (b) ? (a) : (b)) +- + #define DZ_INITIALIZED 0x80000000 /* Serial port was initialized */ + #define DZ_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ + #define DZ_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ +@@ -129,6 +140,7 @@ + #define DZ_CLOSING_WAIT_INF 0 + #define DZ_CLOSING_WAIT_NONE 65535 + ++#define DZ_SAK 0x0004 /* Secure Attention Key (Orange book) */ + #define DZ_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ + #define DZ_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ + #define DZ_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ +@@ -166,79 +178,9 @@ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + ++ struct dec_serial_hook *hook; /* Hook on this channel. */ + unsigned char is_console; /* flag indicating a serial console */ + unsigned char is_initialized; + }; + +-static struct dz_serial multi[DZ_NB_PORT]; /* Four serial lines in the DZ chip */ +-static struct dz_serial *dz_console; +-static struct tty_driver serial_driver, callout_driver; +- +-static struct tty_struct *serial_table[DZ_NB_PORT]; +-static struct termios *serial_termios[DZ_NB_PORT]; +-static struct termios *serial_termios_locked[DZ_NB_PORT]; +- +-static int serial_refcount; +- +-/* +- * tmp_buf is used as a temporary buffer by serial_write. We need to +- * lock it in case the copy_from_user blocks while swapping in a page, +- * and some other program tries to do a serial write at the same time. +- * Since the lock will only come under contention when the system is +- * swapping and available memory is low, it makes sense to share one +- * buffer across all the serial ports, since it significantly saves +- * memory if large numbers of serial ports are open. +- */ +-static unsigned char *tmp_buf; +-static DECLARE_MUTEX(tmp_buf_sem); +- +-static char *dz_name = "DECstation DZ serial driver version "; +-static char *dz_version = "1.02"; +- +-static inline unsigned short dz_in (struct dz_serial *, unsigned); +-static inline void dz_out (struct dz_serial *, unsigned, unsigned short); +- +-static inline void dz_sched_event (struct dz_serial *, int); +-static inline void receive_chars (struct dz_serial *); +-static inline void transmit_chars (struct dz_serial *); +-static inline void check_modem_status (struct dz_serial *); +- +-static void dz_stop (struct tty_struct *); +-static void dz_start (struct tty_struct *); +-static void dz_interrupt (int, void *, struct pt_regs *); +-static void do_serial_bh (void); +-static void do_softint (void *); +-static void do_serial_hangup (void *); +-static void change_speed (struct dz_serial *); +-static void dz_flush_chars (struct tty_struct *); +-static void dz_console_print (struct console *, const char *, unsigned int); +-static void dz_flush_buffer (struct tty_struct *); +-static void dz_throttle (struct tty_struct *); +-static void dz_unthrottle (struct tty_struct *); +-static void dz_send_xchar (struct tty_struct *, char); +-static void shutdown (struct dz_serial *); +-static void send_break (struct dz_serial *, int); +-static void dz_set_termios (struct tty_struct *, struct termios *); +-static void dz_close (struct tty_struct *, struct file *); +-static void dz_hangup (struct tty_struct *); +-static void show_serial_version (void); +- +-static int dz_write (struct tty_struct *, int, const unsigned char *, int); +-static int dz_write_room (struct tty_struct *); +-static int dz_chars_in_buffer (struct tty_struct *); +-static int startup (struct dz_serial *); +-static int get_serial_info (struct dz_serial *, struct serial_struct *); +-static int set_serial_info (struct dz_serial *, struct serial_struct *); +-static int get_lsr_info (struct dz_serial *, unsigned int *); +-static int dz_ioctl (struct tty_struct *, struct file *, unsigned int, unsigned long); +-static int block_til_ready (struct tty_struct *, struct file *, struct dz_serial *); +-static int dz_open (struct tty_struct *, struct file *); +- +-#ifdef MODULE +-int init_module (void) +-void cleanup_module (void) +-#endif +- +-#endif +- + #endif /* DZ_SERIAL_H */ +diff -Nur linux-2.4.32-rc1/drivers/char/ibm_workpad_keymap.map linux-2.4.32-rc1.mips/drivers/char/ibm_workpad_keymap.map +--- linux-2.4.32-rc1/drivers/char/ibm_workpad_keymap.map 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/ibm_workpad_keymap.map 2003-12-20 15:20:44.000000000 +0100 +@@ -0,0 +1,343 @@ ++# Keymap for IBM Workpad z50 ++# US Mapping ++# ++# by Michael Klar ++# ++# This is a great big mess on account of how the Caps Lock key is handled as ++# LeftShift-RightShift. Right shift key had to be broken out, so don't use ++# use this map file as a basis for other keyboards that don't do the same ++# thing with Caps Lock. ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++ ++keymaps 0-2,4-5,8,12,32-33,36-37 ++strings as usual ++ ++keycode 0 = F1 F11 Console_13 ++ shiftr keycode 0 = F11 ++ shift shiftr keycode 0 = F11 ++ control keycode 0 = F1 ++ alt keycode 0 = Console_1 ++ control alt keycode 0 = Console_1 ++keycode 1 = F3 F13 Console_15 ++ shiftr keycode 1 = F13 ++ shift shiftr keycode 1 = F13 ++ control keycode 1 = F3 ++ alt keycode 1 = Console_3 ++ control alt keycode 1 = Console_3 ++keycode 2 = F5 F15 Console_17 ++ shiftr keycode 2 = F15 ++ shift shiftr keycode 2 = F15 ++ control keycode 2 = F5 ++ alt keycode 2 = Console_5 ++ control alt keycode 2 = Console_5 ++keycode 3 = F7 F17 Console_19 ++ shiftr keycode 3 = F17 ++ shift shiftr keycode 3 = F17 ++ control keycode 3 = F7 ++ alt keycode 3 = Console_7 ++ control alt keycode 3 = Console_7 ++keycode 4 = F9 F19 Console_21 ++ shiftr keycode 4 = F19 ++ shift shiftr keycode 4 = F19 ++ control keycode 4 = F9 ++ alt keycode 4 = Console_9 ++ control alt keycode 4 = Console_9 ++#keycode 5 is contrast down ++#keycode 6 is contrast up ++keycode 7 = F11 F11 Console_23 ++ shiftr keycode 7 = F11 ++ shift shiftr keycode 7 = F11 ++ control keycode 7 = F11 ++ alt keycode 7 = Console_11 ++ control alt keycode 7 = Console_11 ++keycode 8 = F2 F12 Console_14 ++ shiftr keycode 8 = F12 ++ shift shiftr keycode 8 = F12 ++ control keycode 8 = F2 ++ alt keycode 8 = Console_2 ++ control alt keycode 8 = Console_2 ++keycode 9 = F4 F14 Console_16 ++ shiftr keycode 9 = F14 ++ shift shiftr keycode 9 = F14 ++ control keycode 9 = F4 ++ alt keycode 9 = Console_4 ++ control alt keycode 9 = Console_4 ++keycode 10 = F6 F16 Console_18 ++ shiftr keycode 10 = F16 ++ shift shiftr keycode 10 = F16 ++ control keycode 10 = F6 ++ alt keycode 10 = Console_6 ++ control alt keycode 10 = Console_6 ++keycode 11 = F8 F18 Console_20 ++ shiftr keycode 11 = F18 ++ shift shiftr keycode 11 = F18 ++ control keycode 11 = F8 ++ alt keycode 11 = Console_8 ++ control alt keycode 11 = Console_8 ++keycode 12 = F10 F20 Console_22 ++ shiftr keycode 12 = F20 ++ shift shiftr keycode 12 = F20 ++ control keycode 12 = F10 ++ alt keycode 12 = Console_10 ++ control alt keycode 12 = Console_10 ++#keycode 13 is brightness down ++#keycode 14 is brightness up ++keycode 15 = F12 F12 Console_24 ++ shiftr keycode 15 = F12 ++ shift shiftr keycode 15 = F12 ++ control keycode 15 = F12 ++ alt keycode 15 = Console_12 ++ control alt keycode 15 = Console_12 ++keycode 16 = apostrophe quotedbl ++ shiftr keycode 16 = quotedbl ++ shift shiftr keycode 16 = quotedbl ++ control keycode 16 = Control_g ++ alt keycode 16 = Meta_apostrophe ++keycode 17 = bracketleft braceleft ++ shiftr keycode 17 = braceleft ++ shift shiftr keycode 17 = braceleft ++ control keycode 17 = Escape ++ alt keycode 17 = Meta_bracketleft ++keycode 18 = minus underscore backslash ++ shiftr keycode 18 = underscore ++ shift shiftr keycode 18 = underscore ++ control keycode 18 = Control_underscore ++ shift control keycode 18 = Control_underscore ++ shiftr control keycode 18 = Control_underscore ++ shift shiftr control keycode 18 = Control_underscore ++ alt keycode 18 = Meta_minus ++keycode 19 = zero parenright braceright ++ shiftr keycode 19 = parenright ++ shift shiftr keycode 19 = parenright ++ alt keycode 19 = Meta_zero ++keycode 20 = p ++ shiftr keycode 20 = +P ++ shift shiftr keycode 20 = +p ++keycode 21 = semicolon colon ++ shiftr keycode 21 = colon ++ shift shiftr keycode 21 = colon ++ alt keycode 21 = Meta_semicolon ++keycode 22 = Up Scroll_Backward ++ shiftr keycode 22 = Scroll_Backward ++ shift shiftr keycode 22 = Scroll_Backward ++ alt keycode 22 = Prior ++keycode 23 = slash question ++ shiftr keycode 23 = question ++ shift shiftr keycode 23 = question ++ control keycode 23 = Delete ++ alt keycode 23 = Meta_slash ++ ++keycode 27 = nine parenleft bracketright ++ shiftr keycode 27 = parenleft ++ shift shiftr keycode 27 = parenleft ++ alt keycode 27 = Meta_nine ++keycode 28 = o ++ shiftr keycode 28 = +O ++ shift shiftr keycode 28 = +o ++keycode 29 = l ++ shiftr keycode 29 = +L ++ shift shiftr keycode 29 = +l ++keycode 30 = period greater ++ shiftr keycode 30 = greater ++ shift shiftr keycode 30 = greater ++ control keycode 30 = Compose ++ alt keycode 30 = Meta_period ++ ++keycode 32 = Left Decr_Console ++ shiftr keycode 32 = Decr_Console ++ shift shiftr keycode 32 = Decr_Console ++ alt keycode 32 = Home ++keycode 33 = bracketright braceright asciitilde ++ shiftr keycode 33 = braceright ++ shift shiftr keycode 33 = braceright ++ control keycode 33 = Control_bracketright ++ alt keycode 33 = Meta_bracketright ++keycode 34 = equal plus ++ shiftr keycode 34 = plus ++ shift shiftr keycode 34 = plus ++ alt keycode 34 = Meta_equal ++keycode 35 = eight asterisk bracketleft ++ shiftr keycode 35 = asterisk ++ shift shiftr keycode 35 = asterisk ++ control keycode 35 = Delete ++ alt keycode 35 = Meta_eight ++keycode 36 = i ++ shiftr keycode 36 = +I ++ shift shiftr keycode 36 = +i ++keycode 37 = k ++ shiftr keycode 37 = +K ++ shift shiftr keycode 37 = +k ++keycode 38 = comma less ++ shiftr keycode 38 = less ++ shift shiftr keycode 38 = less ++ alt keycode 38 = Meta_comma ++ ++keycode 40 = h ++ shiftr keycode 40 = +H ++ shift shiftr keycode 40 = +h ++keycode 41 = y ++ shiftr keycode 41 = +Y ++ shift shiftr keycode 41 = +y ++keycode 42 = six asciicircum ++ shiftr keycode 42 = asciicircum ++ shift shiftr keycode 42 = asciicircum ++ control keycode 42 = Control_asciicircum ++ alt keycode 42 = Meta_six ++keycode 43 = seven ampersand braceleft ++ shiftr keycode 43 = ampersand ++ shift shiftr keycode 43 = ampersand ++ control keycode 43 = Control_underscore ++ alt keycode 43 = Meta_seven ++keycode 44 = u ++ shiftr keycode 44 = +U ++ shift shiftr keycode 44 = +u ++keycode 45 = j ++ shiftr keycode 45 = +J ++ shift shiftr keycode 45 = +j ++keycode 46 = m ++ shiftr keycode 46 = +M ++ shift shiftr keycode 46 = +m ++keycode 47 = n ++ shiftr keycode 47 = +N ++ shift shiftr keycode 47 = +n ++ ++# This is the "Backspace" key: ++keycode 49 = Delete Delete ++ shiftr keycode 49 = Delete ++ shift shiftr keycode 49 = Delete ++ control keycode 49 = BackSpace ++ alt keycode 49 = Meta_Delete ++keycode 50 = Num_Lock ++ shift keycode 50 = Bare_Num_Lock ++ shiftr keycode 50 = Bare_Num_Lock ++ shift shiftr keycode 50 = Bare_Num_Lock ++# This is the "Delete" key: ++keycode 51 = Remove ++ control alt keycode 51 = Boot ++ ++keycode 53 = backslash bar ++ shiftr keycode 53 = bar ++ shift shiftr keycode 53 = bar ++ control keycode 53 = Control_backslash ++ alt keycode 53 = Meta_backslash ++keycode 54 = Return ++ alt keycode 54 = Meta_Control_m ++keycode 55 = space space ++ shiftr keycode 55 = space ++ shift shiftr keycode 55 = space ++ control keycode 55 = nul ++ alt keycode 55 = Meta_space ++keycode 56 = g ++ shiftr keycode 56 = +G ++ shift shiftr keycode 56 = +g ++keycode 57 = t ++ shiftr keycode 57 = +T ++ shift shiftr keycode 57 = +t ++keycode 58 = five percent ++ shiftr keycode 58 = percent ++ shift shiftr keycode 58 = percent ++ control keycode 58 = Control_bracketright ++ alt keycode 58 = Meta_five ++keycode 59 = four dollar dollar ++ shiftr keycode 59 = dollar ++ shift shiftr keycode 59 = dollar ++ control keycode 59 = Control_backslash ++ alt keycode 59 = Meta_four ++keycode 60 = r ++ shiftr keycode 60 = +R ++ shift shiftr keycode 60 = +r ++keycode 61 = f ++ shiftr keycode 61 = +F ++ shift shiftr keycode 61 = +f ++ altgr keycode 61 = Hex_F ++keycode 62 = v ++ shiftr keycode 62 = +V ++ shift shiftr keycode 62 = +v ++keycode 63 = b ++ shiftr keycode 63 = +B ++ shift shiftr keycode 63 = +b ++ altgr keycode 63 = Hex_B ++ ++keycode 67 = three numbersign ++ shiftr keycode 67 = numbersign ++ shift shiftr keycode 67 = numbersign ++ control keycode 67 = Escape ++ alt keycode 67 = Meta_three ++keycode 68 = e ++ shiftr keycode 68 = +E ++ shift shiftr keycode 68 = +e ++ altgr keycode 68 = Hex_E ++keycode 69 = d ++ shiftr keycode 69 = +D ++ shift shiftr keycode 69 = +d ++ altgr keycode 69 = Hex_D ++keycode 70 = c ++ shiftr keycode 70 = +C ++ shift shiftr keycode 70 = +c ++ altgr keycode 70 = Hex_C ++keycode 71 = Right Incr_Console ++ shiftr keycode 71 = Incr_Console ++ shift shiftr keycode 71 = Incr_Console ++ alt keycode 71 = End ++ ++keycode 75 = two at at ++ shiftr keycode 75 = at ++ shift shiftr keycode 75 = at ++ control keycode 75 = nul ++ shift control keycode 75 = nul ++ shiftr control keycode 75 = nul ++ shift shiftr control keycode 75 = nul ++ alt keycode 75 = Meta_two ++keycode 76 = w ++ shiftr keycode 76 = +W ++ shift shiftr keycode 76 = +w ++keycode 77 = s ++ shiftr keycode 77 = +S ++ shift shiftr keycode 77 = +s ++keycode 78 = x ++ shiftr keycode 78 = +X ++ shift shiftr keycode 78 = +x ++keycode 79 = Down Scroll_Forward ++ shiftr keycode 79 = Scroll_Forward ++ shift shiftr keycode 79 = Scroll_Forward ++ alt keycode 79 = Next ++keycode 80 = Escape Escape ++ shiftr keycode 80 = Escape ++ shift shiftr keycode 80 = Escape ++ alt keycode 80 = Meta_Escape ++keycode 81 = Tab Tab ++ shiftr keycode 81 = Tab ++ shift shiftr keycode 81 = Tab ++ alt keycode 81 = Meta_Tab ++keycode 82 = grave asciitilde ++ shiftr keycode 82 = asciitilde ++ shift shiftr keycode 82 = asciitilde ++ control keycode 82 = nul ++ alt keycode 82 = Meta_grave ++keycode 83 = one exclam ++ shiftr keycode 83 = exclam ++ shift shiftr keycode 83 = exclam ++ alt keycode 83 = Meta_one ++keycode 84 = q ++ shiftr keycode 84 = +Q ++ shift shiftr keycode 84 = +q ++keycode 85 = a ++ shiftr keycode 85 = +A ++ shift shiftr keycode 85 = +a ++ altgr keycode 85 = Hex_A ++keycode 86 = z ++ shiftr keycode 86 = +Z ++ shift shiftr keycode 86 = +z ++ ++# This is the windows key: ++keycode 88 = Decr_Console ++keycode 89 = Shift ++keycode 90 = Control ++keycode 91 = Control ++keycode 92 = Alt ++keycode 93 = AltGr ++keycode 94 = ShiftR ++ shift keycode 94 = Caps_Lock +diff -Nur linux-2.4.32-rc1/drivers/char/indydog.c linux-2.4.32-rc1.mips/drivers/char/indydog.c +--- linux-2.4.32-rc1/drivers/char/indydog.c 2003-08-25 13:44:41.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/indydog.c 2004-06-22 17:32:07.000000000 +0200 +@@ -1,5 +1,5 @@ + /* +- * IndyDog 0.2 A Hardware Watchdog Device for SGI IP22 ++ * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22 + * + * (c) Copyright 2002 Guido Guenther , All Rights Reserved. + * +@@ -7,10 +7,10 @@ + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. +- * ++ * + * based on softdog.c by Alan Cox + */ +- ++ + #include + #include + #include +@@ -19,13 +19,12 @@ + #include + #include + #include +-#include + #include + #include + #include + +-static unsigned long indydog_alive; +-static int expect_close = 0; ++#define PFX "indydog: " ++static int indydog_alive; + + #ifdef CONFIG_WATCHDOG_NOWAYOUT + static int nowayout = 1; +@@ -33,10 +32,30 @@ + static int nowayout = 0; + #endif + ++#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ ++ + MODULE_PARM(nowayout,"i"); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); + +-static inline void indydog_ping(void) ++static void indydog_start(void) ++{ ++ u32 mc_ctrl0 = sgimc->cpuctrl0; ++ ++ mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; ++ sgimc->cpuctrl0 = mc_ctrl0; ++} ++ ++static void indydog_stop(void) ++{ ++ u32 mc_ctrl0 = sgimc->cpuctrl0; ++ ++ mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; ++ sgimc->cpuctrl0 = mc_ctrl0; ++ ++ printk(KERN_INFO PFX "Stopped watchdog timer.\n"); ++} ++ ++static void indydog_ping(void) + { + sgimc->watchdogt = 0; + } +@@ -46,18 +65,14 @@ + */ + static int indydog_open(struct inode *inode, struct file *file) + { +- u32 mc_ctrl0; +- +- if (test_and_set_bit(0,&indydog_alive)) ++ if (indydog_alive) + return -EBUSY; + +- if (nowayout) { ++ if (nowayout) + MOD_INC_USE_COUNT; +- } + + /* Activate timer */ +- mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; +- sgimc->cpuctrl0 = mc_ctrl0; ++ indydog_start(); + indydog_ping(); + + indydog_alive = 1; +@@ -69,63 +84,48 @@ + static int indydog_release(struct inode *inode, struct file *file) + { + /* Shut off the timer. +- * Lock it in if it's a module and we set nowayout. */ +- lock_kernel(); +- if (expect_close) { +- u32 mc_ctrl0 = sgimc->cpuctrl0; ++ * Lock it in if it's a module and we defined ...NOWAYOUT */ ++ if (!nowayout) { ++ u32 mc_ctrl0 = sgimc->cpuctrl0; + mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; + printk(KERN_INFO "Stopped watchdog timer.\n"); +- } else +- printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); +- clear_bit(0, &indydog_alive); +- unlock_kernel(); ++ } ++ indydog_alive = 0; + + return 0; + } + + static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) + { +- /* Can't seek (pwrite) on this device */ ++ /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; + +- /* +- * Refresh the timer. +- */ ++ /* Refresh the timer. */ + if (len) { +- if (!nowayout) { +- size_t i; +- +- /* In case it was set long ago */ +- expect_close = 0; +- +- for (i = 0; i != len; i++) { +- char c; +- if (get_user(c, data + i)) +- return -EFAULT; +- if (c == 'V') +- expect_close = 1; +- } +- } + indydog_ping(); +- return 1; + } +- return 0; ++ return len; + } + + static int indydog_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) + { ++ int options, retval = -EINVAL; + static struct watchdog_info ident = { +- options: WDIOF_MAGICCLOSE, +- identity: "Hardware Watchdog for SGI IP22", ++ .options = WDIOF_KEEPALIVEPING | ++ WDIOF_MAGICCLOSE, ++ .firmware_version = 0, ++ .identity = "Hardware Watchdog for SGI IP22", + }; ++ + switch (cmd) { + default: + return -ENOIOCTLCMD; + case WDIOC_GETSUPPORT: +- if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) ++ if (copy_to_user((struct watchdog_info *)arg, ++ &ident, sizeof(ident))) + return -EFAULT; + return 0; + case WDIOC_GETSTATUS: +@@ -134,31 +134,53 @@ + case WDIOC_KEEPALIVE: + indydog_ping(); + return 0; ++ case WDIOC_GETTIMEOUT: ++ return put_user(WATCHDOG_TIMEOUT,(int *)arg); ++ case WDIOC_SETOPTIONS: ++ { ++ if (get_user(options, (int *)arg)) ++ return -EFAULT; ++ ++ if (options & WDIOS_DISABLECARD) { ++ indydog_stop(); ++ retval = 0; ++ } ++ ++ if (options & WDIOS_ENABLECARD) { ++ indydog_start(); ++ retval = 0; ++ } ++ ++ return retval; ++ } + } + } + + static struct file_operations indydog_fops = { +- owner: THIS_MODULE, +- write: indydog_write, +- ioctl: indydog_ioctl, +- open: indydog_open, +- release: indydog_release, ++ .owner = THIS_MODULE, ++ .write = indydog_write, ++ .ioctl = indydog_ioctl, ++ .open = indydog_open, ++ .release = indydog_release, + }; + + static struct miscdevice indydog_miscdev = { +- minor: WATCHDOG_MINOR, +- name: "watchdog", +- fops: &indydog_fops, ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &indydog_fops, + }; + +-static const char banner[] __initdata = KERN_INFO "Hardware Watchdog Timer for SGI IP22: 0.2\n"; ++static char banner[] __initdata = ++ KERN_INFO PFX "Hardware Watchdog Timer for SGI IP22: 0.3\n"; + + static int __init watchdog_init(void) + { + int ret = misc_register(&indydog_miscdev); +- +- if (ret) ++ if (ret) { ++ printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", ++ WATCHDOG_MINOR, ret); + return ret; ++ } + + printk(banner); + +@@ -172,4 +194,7 @@ + + module_init(watchdog_init); + module_exit(watchdog_exit); ++ ++MODULE_AUTHOR("Guido Guenther "); ++MODULE_DESCRIPTION("Hardware Watchdog Device for SGI IP22"); + MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/char/ip27-rtc.c linux-2.4.32-rc1.mips/drivers/char/ip27-rtc.c +--- linux-2.4.32-rc1/drivers/char/ip27-rtc.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/ip27-rtc.c 2004-04-06 03:35:30.000000000 +0200 +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); +@@ -209,11 +210,8 @@ + + static int __init rtc_init(void) + { +- nasid_t nid; +- +- nid = get_nasid(); + rtc = (struct m48t35_rtc *) +- (KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); ++ (KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base + IOC3_BYTEBUS_DEV0); + + printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); + if (misc_register(&rtc_dev)) { +@@ -325,3 +323,7 @@ + + rtc_tm->tm_mon--; + } ++ ++MODULE_AUTHOR("Ralf Baechle "); ++MODULE_DESCRIPTION("SGI IP27 M48T35 RTC driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/char/Makefile linux-2.4.32-rc1.mips/drivers/char/Makefile +--- linux-2.4.32-rc1/drivers/char/Makefile 2004-08-08 01:26:04.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/Makefile 2005-02-11 22:09:56.000000000 +0100 +@@ -48,7 +48,12 @@ + KEYBD = + endif + ifeq ($(CONFIG_VR41XX_KIU),y) +- KEYMAP = ++ ifeq ($(CONFIG_IBM_WORKPAD),y) ++ KEYMAP = ibm_workpad_keymap.o ++ endif ++ ifeq ($(CONFIG_VICTOR_MPC30X),y) ++ KEYMAP = victor_mpc30x_keymap.o ++ endif + KEYBD = vr41xx_keyb.o + endif + endif +@@ -251,7 +256,6 @@ + obj-$(CONFIG_RTC) += rtc.o + obj-$(CONFIG_GEN_RTC) += genrtc.o + obj-$(CONFIG_EFI_RTC) += efirtc.o +-obj-$(CONFIG_SGI_DS1286) += ds1286.o + obj-$(CONFIG_MIPS_RTC) += mips_rtc.o + obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o + ifeq ($(CONFIG_PPC),) +@@ -259,6 +263,7 @@ + endif + obj-$(CONFIG_TOSHIBA) += toshiba.o + obj-$(CONFIG_I8K) += i8k.o ++obj-$(CONFIG_DS1286) += ds1286.o + obj-$(CONFIG_DS1620) += ds1620.o + obj-$(CONFIG_DS1742) += ds1742.o + obj-$(CONFIG_INTEL_RNG) += i810_rng.o +@@ -269,6 +274,7 @@ + + obj-$(CONFIG_ITE_GPIO) += ite_gpio.o + obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o ++obj-$(CONFIG_AU1550_PSC_SPI) += au1550_psc_spi.o + obj-$(CONFIG_AU1X00_USB_TTY) += au1000_usbtty.o + obj-$(CONFIG_AU1X00_USB_RAW) += au1000_usbraw.o + obj-$(CONFIG_COBALT_LCD) += lcd.o +@@ -353,3 +359,9 @@ + + qtronixmap.c: qtronixmap.map + set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ ++ ++ibm_workpad_keymap.c: ibm_workpad_keymap.map ++ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ ++ ++victor_mpc30x_keymap.c: victor_mpc30x_keymap.map ++ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@ +diff -Nur linux-2.4.32-rc1/drivers/char/mips_rtc.c linux-2.4.32-rc1.mips/drivers/char/mips_rtc.c +--- linux-2.4.32-rc1/drivers/char/mips_rtc.c 2004-01-05 14:53:56.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/mips_rtc.c 2004-06-28 14:54:53.000000000 +0200 +@@ -53,14 +53,6 @@ + #include + #include + #include +- +-/* +- * Check machine +- */ +-#if !defined(CONFIG_MIPS) || !defined(CONFIG_NEW_TIME_C) +-#error "This driver is for MIPS machines with CONFIG_NEW_TIME_C defined" +-#endif +- + #include + + static unsigned long rtc_status = 0; /* bitmapped status byte. */ +diff -Nur linux-2.4.32-rc1/drivers/char/sb1250_duart.c linux-2.4.32-rc1.mips/drivers/char/sb1250_duart.c +--- linux-2.4.32-rc1/drivers/char/sb1250_duart.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/sb1250_duart.c 2004-09-17 01:25:44.000000000 +0200 +@@ -328,10 +328,11 @@ + if (c <= 0) break; + + if (from_user) { ++ spin_unlock_irqrestore(&us->outp_lock, flags); + if (copy_from_user(us->outp_buf + us->outp_tail, buf, c)) { +- spin_unlock_irqrestore(&us->outp_lock, flags); + return -EFAULT; + } ++ spin_lock_irqsave(&us->outp_lock, flags); + } else { + memcpy(us->outp_buf + us->outp_tail, buf, c); + } +@@ -498,9 +499,31 @@ + duart_set_cflag(us->line, tty->termios->c_cflag); + } + ++static int get_serial_info(uart_state_t *us, struct serial_struct * retinfo) { ++ ++ struct serial_struct tmp; ++ ++ memset(&tmp, 0, sizeof(tmp)); ++ ++ tmp.type=PORT_SB1250; ++ tmp.line=us->line; ++ tmp.port=A_DUART_CHANREG(tmp.line,0); ++ tmp.irq=K_INT_UART_0 + tmp.line; ++ tmp.xmit_fifo_size=16; /* fixed by hw */ ++ tmp.baud_base=5000000; ++ tmp.io_type=SERIAL_IO_MEM; ++ ++ if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) ++ return -EFAULT; ++ ++ return 0; ++} ++ + static int duart_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) + { ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ + /* if (serial_paranoia_check(info, tty->device, "rs_ioctl")) + return -ENODEV;*/ + switch (cmd) { +@@ -517,7 +540,7 @@ + printk("Ignoring TIOCMSET\n"); + break; + case TIOCGSERIAL: +- printk("Ignoring TIOCGSERIAL\n"); ++ return get_serial_info(us,(struct serial_struct *) arg); + break; + case TIOCSSERIAL: + printk("Ignoring TIOCSSERIAL\n"); +diff -Nur linux-2.4.32-rc1/drivers/char/serial.c linux-2.4.32-rc1.mips/drivers/char/serial.c +--- linux-2.4.32-rc1/drivers/char/serial.c 2005-10-24 11:33:29.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/char/serial.c 2005-09-23 22:41:22.000000000 +0200 +@@ -62,6 +62,12 @@ + * Robert Schwebel , + * Juergen Beisert , + * Theodore Ts'o ++ * ++ * 10/00: Added suport for MIPS Atlas board. ++ * 11/00: Hooks for serial kernel debug port support added. ++ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, ++ * carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + */ + + static char *serial_version = "5.05c"; +@@ -413,6 +419,22 @@ + return 0; + } + ++#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD) ++ ++#include ++ ++static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) ++{ ++ return (*(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) & 0xff); ++} ++ ++static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) ++{ ++ *(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) = value; ++} ++ ++#else ++ + static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) + { + switch (info->io_type) { +@@ -447,6 +469,8 @@ + outb(value, info->port+offset); + } + } ++#endif ++ + + /* + * We used to support using pause I/O for certain machines. We +diff -Nur linux-2.4.32-rc1/drivers/char/victor_mpc30x_keymap.map linux-2.4.32-rc1.mips/drivers/char/victor_mpc30x_keymap.map +--- linux-2.4.32-rc1/drivers/char/victor_mpc30x_keymap.map 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/victor_mpc30x_keymap.map 2004-02-05 18:04:42.000000000 +0100 +@@ -0,0 +1,102 @@ ++# Victor Interlink MP-C303/304 keyboard keymap ++# ++# Copyright (C) 2003 Yoichi Yuasa ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++keymaps 0-1,4-5,8-9,12 ++alt_is_meta ++strings as usual ++compose as usual for "iso-8859-1" ++ ++# First line ++keycode 89 = Escape ++keycode 9 = Delete ++ ++# 2nd line ++keycode 73 = one exclam ++keycode 18 = two quotedbl ++keycode 92 = three numbersign ++ control keycode 92 = Escape ++keycode 53 = four dollar ++ control keycode 53 = Control_backslash ++keycode 21 = five percent ++ control keycode 21 = Control_bracketright ++keycode 50 = six ampersand ++ control keycode 50 = Control_underscore ++keycode 48 = seven apostrophe ++keycode 51 = eight parenleft ++keycode 16 = nine parenright ++keycode 80 = zero asciitilde ++ control keycode 80 = nul ++keycode 49 = minus equal ++keycode 30 = asciicircum asciitilde ++ control keycode 30 = Control_asciicircum ++keycode 5 = backslash bar ++ control keycode 5 = Control_backslash ++keycode 13 = BackSpace ++# 3rd line ++keycode 57 = Tab ++keycode 74 = q ++keycode 26 = w ++keycode 81 = e ++keycode 29 = r ++keycode 37 = t ++keycode 45 = y ++keycode 72 = u ++keycode 24 = i ++keycode 32 = o ++keycode 41 = p ++keycode 1 = at grave ++ control keycode 1 = nul ++keycode 54 = bracketleft braceleft ++keycode 63 = Return ++ alt keycode 63 = Meta_Control_m ++# 4th line ++keycode 23 = Caps_Lock ++keycode 34 = a ++keycode 66 = s ++keycode 52 = d ++keycode 20 = f ++keycode 84 = g ++keycode 67 = h ++keycode 64 = j ++keycode 17 = k ++keycode 83 = l ++keycode 22 = semicolon plus ++keycode 61 = colon asterisk ++ control keycode 61 = Control_g ++keycode 65 = bracketright braceright ++ control keycode 65 = Control_bracketright ++# 5th line ++keycode 91 = Shift ++keycode 76 = z ++keycode 68 = x ++keycode 28 = c ++keycode 36 = v ++keycode 44 = b ++keycode 19 = n ++keycode 27 = m ++keycode 35 = comma less ++keycode 3 = period greater ++ control keycode 3 = Compose ++keycode 38 = slash question ++ control keycode 38 = Delete ++ shift control keycode 38 = Delete ++keycode 6 = backslash underscore ++ control keycode 6 = Control_backslash ++keycode 55 = Up ++ alt keycode 55 = PageUp ++keycode 14 = Shift ++# 6th line ++keycode 56 = Control ++keycode 42 = Alt ++keycode 33 = space ++ control keycode 33 = nul ++keycode 7 = Left ++ alt keycode 7 = Home ++keycode 31 = Down ++ alt keycode 31 = PageDown ++keycode 47 = Right ++ alt keycode 47 = End +diff -Nur linux-2.4.32-rc1/drivers/char/vr41xx_keyb.c linux-2.4.32-rc1.mips/drivers/char/vr41xx_keyb.c +--- linux-2.4.32-rc1/drivers/char/vr41xx_keyb.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/char/vr41xx_keyb.c 2004-02-17 13:08:55.000000000 +0100 +@@ -308,7 +308,7 @@ + if (found != 0) { + kiu_base = VRC4173_KIU_OFFSET; + mkiuintreg = VRC4173_MKIUINTREG_OFFSET; +- vrc4173_clock_supply(VRC4173_KIU_CLOCK); ++ vrc4173_supply_clock(VRC4173_KIU_CLOCK); + } + } + #endif +@@ -325,7 +325,7 @@ + + if (current_cpu_data.cputype == CPU_VR4111 || + current_cpu_data.cputype == CPU_VR4121) +- vr41xx_clock_supply(KIU_CLOCK); ++ vr41xx_supply_clock(KIU_CLOCK); + + kiu_writew(KIURST_KIURST, KIURST); + +diff -Nur linux-2.4.32-rc1/drivers/i2c/Config.in linux-2.4.32-rc1.mips/drivers/i2c/Config.in +--- linux-2.4.32-rc1/drivers/i2c/Config.in 2004-04-14 15:05:29.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/i2c/Config.in 2005-02-11 20:49:04.000000000 +0100 +@@ -57,6 +57,10 @@ + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate 'I2C SGI interfaces' CONFIG_I2C_ALGO_SGI $CONFIG_I2C + fi ++ ++ if [ "$CONFIG_SOC_AU1550" = "y" -o "$CONFIG_SOC_AU1200" ]; then ++ dep_tristate 'Au1550/Au1200 SMBus interface' CONFIG_I2C_ALGO_AU1550 $CONFIG_I2C ++ fi + + # This is needed for automatic patch generation: sensors code starts here + # This is needed for automatic patch generation: sensors code ends here +diff -Nur linux-2.4.32-rc1/drivers/i2c/i2c-algo-au1550.c linux-2.4.32-rc1.mips/drivers/i2c/i2c-algo-au1550.c +--- linux-2.4.32-rc1/drivers/i2c/i2c-algo-au1550.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/i2c/i2c-algo-au1550.c 2005-02-11 20:49:04.000000000 +0100 +@@ -0,0 +1,340 @@ ++/* ++ * i2c-algo-au1550.c: SMBus (i2c) driver algorithms for Alchemy PSC interface ++ * Copyright (C) 2004 Embedded Edge, LLC ++ * ++ * The documentation describes this as an SMBus controller, but it doesn't ++ * understand any of the SMBus protocol in hardware. It's really an I2C ++ * controller that could emulate most of the SMBus in software. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++static int ++wait_xfer_done(struct i2c_algo_au1550_data *adap) ++{ ++ u32 stat; ++ int i; ++ volatile psc_smb_t *sp; ++ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ ++ /* Wait for Tx FIFO Underflow. ++ */ ++ for (i = 0; i < adap->xfer_timeout; i++) { ++ stat = sp->psc_smbevnt; ++ au_sync(); ++ if ((stat & PSC_SMBEVNT_TU) != 0) { ++ /* Clear it. */ ++ sp->psc_smbevnt = PSC_SMBEVNT_TU; ++ au_sync(); ++ return 0; ++ } ++ udelay(1); ++ } ++ ++ return -ETIMEDOUT; ++} ++ ++static int ++wait_ack(struct i2c_algo_au1550_data *adap) ++{ ++ u32 stat; ++ volatile psc_smb_t *sp; ++ ++ if (wait_xfer_done(adap)) ++ return -ETIMEDOUT; ++ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ ++ stat = sp->psc_smbevnt; ++ au_sync(); ++ ++ if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0) ++ return -ETIMEDOUT; ++ ++ return 0; ++} ++ ++static int ++wait_master_done(struct i2c_algo_au1550_data *adap) ++{ ++ u32 stat; ++ int i; ++ volatile psc_smb_t *sp; ++ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ ++ /* Wait for Master Done. ++ */ ++ for (i = 0; i < adap->xfer_timeout; i++) { ++ stat = sp->psc_smbevnt; ++ au_sync(); ++ if ((stat & PSC_SMBEVNT_MD) != 0) ++ return 0; ++ udelay(1); ++ } ++ ++ return -ETIMEDOUT; ++} ++ ++static int ++do_address(struct i2c_algo_au1550_data *adap, unsigned int addr, int rd) ++{ ++ volatile psc_smb_t *sp; ++ u32 stat; ++ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ ++ /* Reset the FIFOs, clear events. ++ */ ++ sp->psc_smbpcr = PSC_SMBPCR_DC; ++ sp->psc_smbevnt = PSC_SMBEVNT_ALLCLR; ++ au_sync(); ++ do { ++ stat = sp->psc_smbpcr; ++ au_sync(); ++ } while ((stat & PSC_SMBPCR_DC) != 0); ++ ++ /* Write out the i2c chip address and specify operation ++ */ ++ addr <<= 1; ++ if (rd) ++ addr |= 1; ++ ++ /* Put byte into fifo, start up master. ++ */ ++ sp->psc_smbtxrx = addr; ++ au_sync(); ++ sp->psc_smbpcr = PSC_SMBPCR_MS; ++ au_sync(); ++ if (wait_ack(adap)) ++ return -EIO; ++ return 0; ++} ++ ++static u32 ++wait_for_rx_byte(struct i2c_algo_au1550_data *adap, u32 *ret_data) ++{ ++ int j; ++ u32 data, stat; ++ volatile psc_smb_t *sp; ++ ++ if (wait_xfer_done(adap)) ++ return -EIO; ++ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ ++ j = adap->xfer_timeout * 100; ++ do { ++ j--; ++ if (j <= 0) ++ return -EIO; ++ ++ stat = sp->psc_smbstat; ++ au_sync(); ++ if ((stat & PSC_SMBSTAT_RE) == 0) ++ j = 0; ++ else ++ udelay(1); ++ } while (j > 0); ++ data = sp->psc_smbtxrx; ++ au_sync(); ++ *ret_data = data; ++ ++ return 0; ++} ++ ++static int ++i2c_read(struct i2c_algo_au1550_data *adap, unsigned char *buf, ++ unsigned int len) ++{ ++ int i; ++ u32 data; ++ volatile psc_smb_t *sp; ++ ++ if (len == 0) ++ return 0; ++ ++ /* A read is performed by stuffing the transmit fifo with ++ * zero bytes for timing, waiting for bytes to appear in the ++ * receive fifo, then reading the bytes. ++ */ ++ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ ++ i = 0; ++ while (i < (len-1)) { ++ sp->psc_smbtxrx = 0; ++ au_sync(); ++ if (wait_for_rx_byte(adap, &data)) ++ return -EIO; ++ ++ buf[i] = data; ++ i++; ++ } ++ ++ /* The last byte has to indicate transfer done. ++ */ ++ sp->psc_smbtxrx = PSC_SMBTXRX_STP; ++ au_sync(); ++ if (wait_master_done(adap)) ++ return -EIO; ++ ++ data = sp->psc_smbtxrx; ++ au_sync(); ++ buf[i] = data; ++ return 0; ++} ++ ++static int ++i2c_write(struct i2c_algo_au1550_data *adap, unsigned char *buf, ++ unsigned int len) ++{ ++ int i; ++ u32 data; ++ volatile psc_smb_t *sp; ++ ++ if (len == 0) ++ return 0; ++ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ ++ i = 0; ++ while (i < (len-1)) { ++ data = buf[i]; ++ sp->psc_smbtxrx = data; ++ au_sync(); ++ if (wait_ack(adap)) ++ return -EIO; ++ i++; ++ } ++ ++ /* The last byte has to indicate transfer done. ++ */ ++ data = buf[i]; ++ data |= PSC_SMBTXRX_STP; ++ sp->psc_smbtxrx = data; ++ au_sync(); ++ if (wait_master_done(adap)) ++ return -EIO; ++ return 0; ++} ++ ++static int ++au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) ++{ ++ struct i2c_algo_au1550_data *adap = i2c_adap->algo_data; ++ struct i2c_msg *p; ++ int i, err = 0; ++ ++ for (i = 0; !err && i < num; i++) { ++ p = &msgs[i]; ++ err = do_address(adap, p->addr, p->flags & I2C_M_RD); ++ if (err || !p->len) ++ continue; ++ if (p->flags & I2C_M_RD) ++ err = i2c_read(adap, p->buf, p->len); ++ else ++ err = i2c_write(adap, p->buf, p->len); ++ } ++ ++ /* Return the number of messages processed, or the error code. ++ */ ++ if (err == 0) ++ err = num; ++ return err; ++} ++ ++static u32 ++au1550_func(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C; ++} ++ ++static struct i2c_algorithm au1550_algo = { ++ .name = "Au1550 algorithm", ++ .id = I2C_ALGO_AU1550, ++ .master_xfer = au1550_xfer, ++ .functionality = au1550_func, ++}; ++ ++/* ++ * registering functions to load algorithms at runtime ++ * Prior to calling us, the 50MHz clock frequency and routing ++ * must have been set up for the PSC indicated by the adapter. ++ */ ++int ++i2c_au1550_add_bus(struct i2c_adapter *i2c_adap) ++{ ++ struct i2c_algo_au1550_data *adap = i2c_adap->algo_data; ++ volatile psc_smb_t *sp; ++ u32 stat; ++ ++ i2c_adap->algo = &au1550_algo; ++ ++ /* Now, set up the PSC for SMBus PIO mode. ++ */ ++ sp = (volatile psc_smb_t *)(adap->psc_base); ++ sp->psc_ctrl = PSC_CTRL_DISABLE; ++ au_sync(); ++ sp->psc_sel = PSC_SEL_PS_SMBUSMODE; ++ sp->psc_smbcfg = 0; ++ au_sync(); ++ sp->psc_ctrl = PSC_CTRL_ENABLE; ++ au_sync(); ++ do { ++ stat = sp->psc_smbstat; ++ au_sync(); ++ } while ((stat & PSC_SMBSTAT_SR) == 0); ++ ++ sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | ++ PSC_SMBCFG_DD_DISABLE); ++ ++ /* Divide by 8 to get a 6.25 MHz clock. The later protocol ++ * timings are based on this clock. ++ */ ++ sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV2); ++ sp->psc_smbmsk = PSC_SMBMSK_ALLMASK; ++ au_sync(); ++ ++ /* Set the protocol timer values. See Table 71 in the ++ * Au1550 Data Book for standard timing values. ++ */ ++ sp->psc_smbtmr = PSC_SMBTMR_SET_TH(2) | PSC_SMBTMR_SET_PS(15) | \ ++ PSC_SMBTMR_SET_PU(11) | PSC_SMBTMR_SET_SH(11) | \ ++ PSC_SMBTMR_SET_SU(11) | PSC_SMBTMR_SET_CL(15) | \ ++ PSC_SMBTMR_SET_CH(11); ++ au_sync(); ++ ++ sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE; ++ do { ++ stat = sp->psc_smbstat; ++ au_sync(); ++ } while ((stat & PSC_SMBSTAT_DR) == 0); ++ ++ return i2c_add_adapter(i2c_adap); ++} ++ ++ ++int ++i2c_au1550_del_bus(struct i2c_adapter *adap) ++{ ++ return i2c_del_adapter(adap); ++} ++ ++EXPORT_SYMBOL(i2c_au1550_add_bus); ++EXPORT_SYMBOL(i2c_au1550_del_bus); ++ ++MODULE_AUTHOR("Dan Malek "); ++MODULE_DESCRIPTION("SMBus Au1550 algorithm"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/i2c/i2c-au1550.c linux-2.4.32-rc1.mips/drivers/i2c/i2c-au1550.c +--- linux-2.4.32-rc1/drivers/i2c/i2c-au1550.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/i2c/i2c-au1550.c 2005-02-11 20:49:04.000000000 +0100 +@@ -0,0 +1,154 @@ ++/* ++ * i2c-au1550.c: SMBus (i2c) adapter for Alchemy PSC interface ++ * Copyright (C) 2004 Embedded Edge, LLC ++ * ++ * This is just a skeleton adapter to use with the Au1550 PSC ++ * algorithm. It was developed for the Pb1550, but will work with ++ * any Au1550 board that has a similar PSC configuration. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#if defined( CONFIG_MIPS_PB1550 ) ++ #include ++#endif ++#if defined( CONFIG_MIPS_PB1200 ) ++ #include ++#endif ++#if defined( CONFIG_MIPS_DB1200 ) ++ #include ++#endif ++#if defined( CONFIG_MIPS_FICMMP ) ++ #include ++#endif ++ ++#include ++#include ++ ++ ++ ++static int ++pb1550_reg(struct i2c_client *client) ++{ ++ return 0; ++} ++ ++static int ++pb1550_unreg(struct i2c_client *client) ++{ ++ return 0; ++} ++ ++static void ++pb1550_inc_use(struct i2c_adapter *adap) ++{ ++#ifdef MODULE ++ MOD_INC_USE_COUNT; ++#endif ++} ++ ++static void ++pb1550_dec_use(struct i2c_adapter *adap) ++{ ++#ifdef MODULE ++ MOD_DEC_USE_COUNT; ++#endif ++} ++ ++static struct i2c_algo_au1550_data pb1550_i2c_info = { ++ SMBUS_PSC_BASE, 200, 200 ++}; ++ ++static struct i2c_adapter pb1550_board_adapter = { ++ name: "pb1550 adapter", ++ id: I2C_HW_AU1550_PSC, ++ algo: NULL, ++ algo_data: &pb1550_i2c_info, ++ inc_use: pb1550_inc_use, ++ dec_use: pb1550_dec_use, ++ client_register: pb1550_reg, ++ client_unregister: pb1550_unreg, ++ client_count: 0, ++}; ++ ++int __init ++i2c_pb1550_init(void) ++{ ++ /* This is where we would set up a 50MHz clock source ++ * and routing. On the Pb1550, the SMBus is PSC2, which ++ * uses a shared clock with USB. This has been already ++ * configured by Yamon as a 48MHz clock, close enough ++ * for our work. ++ */ ++ if (i2c_au1550_add_bus(&pb1550_board_adapter) < 0) ++ return -ENODEV; ++ ++ return 0; ++} ++ ++/* BIG hack to support the control interface on the Wolfson WM8731 ++ * audio codec on the Pb1550 board. We get an address and two data ++ * bytes to write, create an i2c message, and send it across the ++ * i2c transfer function. We do this here because we have access to ++ * the i2c adapter structure. ++ */ ++static struct i2c_msg wm_i2c_msg; /* We don't want this stuff on the stack */ ++static u8 i2cbuf[2]; ++ ++int ++pb1550_wm_codec_write(u8 addr, u8 reg, u8 val) ++{ ++ wm_i2c_msg.addr = addr; ++ wm_i2c_msg.flags = 0; ++ wm_i2c_msg.buf = i2cbuf; ++ wm_i2c_msg.len = 2; ++ i2cbuf[0] = reg; ++ i2cbuf[1] = val; ++ ++ return pb1550_board_adapter.algo->master_xfer(&pb1550_board_adapter, &wm_i2c_msg, 1); ++} ++ ++/* the next function is needed by DVB driver. */ ++int pb1550_i2c_xfer(struct i2c_msg msgs[], int num) ++{ ++ return pb1550_board_adapter.algo->master_xfer(&pb1550_board_adapter, msgs, num); ++} ++ ++EXPORT_SYMBOL(pb1550_wm_codec_write); ++EXPORT_SYMBOL(pb1550_i2c_xfer); ++ ++MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); ++MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550"); ++MODULE_LICENSE("GPL"); ++ ++int ++init_module(void) ++{ ++ return i2c_pb1550_init(); ++} ++ ++void ++cleanup_module(void) ++{ ++ i2c_au1550_del_bus(&pb1550_board_adapter); ++} +diff -Nur linux-2.4.32-rc1/drivers/i2c/i2c-core.c linux-2.4.32-rc1.mips/drivers/i2c/i2c-core.c +--- linux-2.4.32-rc1/drivers/i2c/i2c-core.c 2005-06-01 02:56:56.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/i2c/i2c-core.c 2005-05-23 14:12:30.000000000 +0200 +@@ -1280,6 +1280,9 @@ + #ifdef CONFIG_I2C_MAX1617 + extern int i2c_max1617_init(void); + #endif ++#ifdef CONFIG_I2C_ALGO_AU1550 ++ extern int i2c_pb1550_init(void); ++#endif + + #ifdef CONFIG_I2C_PROC + extern int sensors_init(void); +@@ -1335,6 +1338,10 @@ + i2c_max1617_init(); + #endif + ++#ifdef CONFIG_I2C_ALGO_AU1550 ++ i2c_pb1550_init(); ++#endif ++ + /* -------------- proc interface ---- */ + #ifdef CONFIG_I2C_PROC + sensors_init(); +diff -Nur linux-2.4.32-rc1/drivers/i2c/Makefile linux-2.4.32-rc1.mips/drivers/i2c/Makefile +--- linux-2.4.32-rc1/drivers/i2c/Makefile 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/i2c/Makefile 2005-02-11 20:49:04.000000000 +0100 +@@ -6,7 +6,7 @@ + + export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \ + i2c-algo-ite.o i2c-algo-sibyte.o i2c-algo-sgi.o \ +- i2c-proc.o ++ i2c-algo-au1550.o i2c-proc.o i2c-au1550.o + + obj-$(CONFIG_I2C) += i2c-core.o + obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o +@@ -25,6 +25,7 @@ + obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o i2c-sibyte.o + obj-$(CONFIG_I2C_MAX1617) += i2c-max1617.o + obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o ++obj-$(CONFIG_I2C_ALGO_AU1550) += i2c-algo-au1550.o i2c-au1550.o + + # This is needed for automatic patch generation: sensors code starts here + # This is needed for automatic patch generation: sensors code ends here +diff -Nur linux-2.4.32-rc1/drivers/media/video/indycam.c linux-2.4.32-rc1.mips/drivers/media/video/indycam.c +--- linux-2.4.32-rc1/drivers/media/video/indycam.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/media/video/indycam.c 2004-12-09 21:32:05.000000000 +0100 +@@ -50,13 +50,14 @@ + 0x80, /* INDYCAM_GAMMA */ + }; + +- int err = 0; + struct indycam *camera; + struct i2c_client *client; ++ int err = 0; + + client = kmalloc(sizeof(*client), GFP_KERNEL); +- if (!client) ++ if (!client) + return -ENOMEM; ++ + camera = kmalloc(sizeof(*camera), GFP_KERNEL); + if (!camera) { + err = -ENOMEM; +@@ -67,7 +68,7 @@ + client->adapter = adap; + client->addr = addr; + client->driver = &i2c_driver_indycam; +- strcpy(client->name, "IndyCam client"); ++ strcpy(client->name, "IndyCam client"); + camera->client = client; + + err = i2c_attach_client(client); +@@ -75,18 +76,18 @@ + goto out_free_camera; + + camera->version = i2c_smbus_read_byte_data(client, INDYCAM_VERSION); +- if (camera->version != CAMERA_VERSION_INDY && +- camera->version != CAMERA_VERSION_MOOSE) { ++ if ((camera->version != CAMERA_VERSION_INDY) && ++ (camera->version != CAMERA_VERSION_MOOSE)) { + err = -ENODEV; + goto out_detach_client; + } +- printk(KERN_INFO "Indycam v%d.%d detected.\n", ++ printk(KERN_INFO "IndyCam v%d.%d detected.\n", + INDYCAM_VERSION_MAJOR(camera->version), + INDYCAM_VERSION_MINOR(camera->version)); + + err = i2c_master_send(client, initseq, sizeof(initseq)); + if (err) +- printk(KERN_INFO "IndyCam initalization failed\n"); ++ printk(KERN_ERR "IndyCam initalization failed.\n"); + + MOD_INC_USE_COUNT; + return 0; +diff -Nur linux-2.4.32-rc1/drivers/media/video/vino.c linux-2.4.32-rc1.mips/drivers/media/video/vino.c +--- linux-2.4.32-rc1/drivers/media/video/vino.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/media/video/vino.c 2004-12-10 05:02:54.000000000 +0100 +@@ -5,6 +5,8 @@ + * License version 2 as published by the Free Software Foundation. + * + * Copyright (C) 2003 Ladislav Michl ++ * Copyright (C) 2004 Mikael Nousiainen ++ * + */ + + #include +@@ -37,13 +39,23 @@ + #define DEBUG(x...) + #endif + ++/* Channels (who could have guessed) */ ++#define VINO_CHAN_NONE 0 ++#define VINO_CHAN_A 1 ++#define VINO_CHAN_B 2 ++ + /* VINO video size */ + #define VINO_PAL_WIDTH 768 + #define VINO_PAL_HEIGHT 576 + #define VINO_NTSC_WIDTH 646 + #define VINO_NTSC_HEIGHT 486 + +-/* set this to some sensible values. note: VINO_MIN_WIDTH has to be 8*x */ ++/* Minimum value for Y-clipping (for smaller values the images ++ * will be corrupted) */ ++#define VINO_MIN_Y_CLIPPING 2 ++ ++/* Set these to some sensible values. ++ * Note: the picture width has to be divisible by 8 */ + #define VINO_MIN_WIDTH 32 + #define VINO_MIN_HEIGHT 32 + +@@ -64,9 +76,7 @@ + + struct vino_device { + struct video_device vdev; +-#define VINO_CHAN_A 1 +-#define VINO_CHAN_B 2 +- int chan; ++ int chan; /* VINO_CHAN_NONE, VINO_CHAN_A or VINO_CHAN_B */ + int alpha; + /* clipping... */ + unsigned int left, right, top, bottom; +@@ -106,7 +116,7 @@ + + struct vino_client { + struct i2c_client *driver; +- int owner; ++ int owner; /* VINO_CHAN_NONE, VINO_CHAN_A or VINO_CHAN_B */ + }; + + struct vino_video { +@@ -362,6 +372,7 @@ + static int dma_setup(struct vino_device *v) + { + u32 ctrl, intr; ++ int ofs; + struct sgi_vino_channel *ch; + + ch = (v->chan == VINO_CHAN_A) ? &vino->a : &vino->b; +@@ -377,14 +388,24 @@ + ch->line_size = v->line_size - 8; + /* set the alpha register */ + ch->alpha = v->alpha; +- /* set cliping registers */ +- ch->clip_start = VINO_CLIP_ODD(v->top) | VINO_CLIP_EVEN(v->top+1) | ++ /* Set the clipping registers, this is the constant source of fun :) ++ * Y clipping start has to be >= 2 and end has to be start + height/2 ++ * The values of top and bottom are even so dividing is not a problem ++ * ++ * The docs say that clipping values for the even field should be ++ * odd_end + something_to_skip_vertical_blanking + some_lines and ++ * even_start + height/2, though the image is good this way also ++ * ++ * TODO: for analog sources (SAA7191), the clipping values are a bit ++ * different and that case isn't yet handled ++ */ ++ ofs = VINO_MIN_Y_CLIPPING; /* Should depend on input source */ ++ ch->clip_start = VINO_CLIP_ODD(ofs + v->top / 2) | ++ VINO_CLIP_EVEN(ofs + v->top / 2 + 1) | + VINO_CLIP_X(v->left); +- ch->clip_end = VINO_CLIP_ODD(v->bottom) | VINO_CLIP_EVEN(v->bottom+1) | ++ ch->clip_end = VINO_CLIP_ODD(ofs + v->bottom / 2 - 1) | ++ VINO_CLIP_EVEN(ofs + v->bottom / 2) | + VINO_CLIP_X(v->right); +- /* FIXME: end-of-field bug workaround +- VINO_CLIP_X(VINO_PAL_WIDTH); +- */ + /* init the frame rate and norm (full frame rate only for now...) */ + ch->frame_rate = VINO_FRAMERT_RT(0x1fff) | + (get_capture_norm(v) == VIDEO_MODE_PAL ? +@@ -510,6 +531,7 @@ + static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) + { + u32 intr, ctrl; ++ int a_eof, b_eof; + + spin_lock(&Vino->vino_lock); + ctrl = vino->control; +@@ -525,12 +547,14 @@ + vino->control = ctrl; + clear_eod(&Vino->chB); + } ++ a_eof = intr & VINO_INTSTAT_A_EOF; ++ b_eof = intr & VINO_INTSTAT_B_EOF; + vino->intr_status = ~intr; + spin_unlock(&Vino->vino_lock); +- /* FIXME: For now we are assuming that interrupt means that frame is +- * done. That's not true, but we can live with such brokeness for +- * a while ;-) */ +- field_done(&Vino->chA); ++ if (a_eof) ++ field_done(&Vino->chA); ++ if (b_eof) ++ field_done(&Vino->chB); + } + + static int vino_grab(struct vino_device *v, int frame) +diff -Nur linux-2.4.32-rc1/drivers/mtd/devices/docprobe.c linux-2.4.32-rc1.mips/drivers/mtd/devices/docprobe.c +--- linux-2.4.32-rc1/drivers/mtd/devices/docprobe.c 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/mtd/devices/docprobe.c 2003-06-16 01:42:21.000000000 +0200 +@@ -89,10 +89,10 @@ + 0xe4000000, + #elif defined(CONFIG_MOMENCO_OCELOT) + 0x2f000000, +- 0xff000000, ++ 0xff000000, + #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) +- 0xff000000, +-##else ++ 0xff000000, ++#else + #warning Unknown architecture for DiskOnChip. No default probe locations defined + #endif + 0 }; +diff -Nur linux-2.4.32-rc1/drivers/mtd/devices/ms02-nv.c linux-2.4.32-rc1.mips/drivers/mtd/devices/ms02-nv.c +--- linux-2.4.32-rc1/drivers/mtd/devices/ms02-nv.c 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/mtd/devices/ms02-nv.c 2004-07-30 12:22:40.000000000 +0200 +@@ -1,10 +1,10 @@ + /* +- * Copyright (c) 2001 Maciej W. Rozycki ++ * Copyright (c) 2001 Maciej W. Rozycki + * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version +- * 2 of the License, or (at your option) any later version. ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. + * + * $Id: ms02-nv.c,v 1.2 2003/01/24 14:05:17 dwmw2 Exp $ + */ +@@ -29,18 +29,18 @@ + + + static char version[] __initdata = +- "ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n"; ++ "ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n"; + +-MODULE_AUTHOR("Maciej W. Rozycki "); ++MODULE_AUTHOR("Maciej W. Rozycki "); + MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver"); + MODULE_LICENSE("GPL"); + + + /* + * Addresses we probe for an MS02-NV at. Modules may be located +- * at any 8MB boundary within a 0MB up to 112MB range or at any 32MB +- * boundary within a 0MB up to 448MB range. We don't support a module +- * at 0MB, though. ++ * at any 8MiB boundary within a 0MiB up to 112MiB range or at any 32MiB ++ * boundary within a 0MiB up to 448MiB range. We don't support a module ++ * at 0MiB, though. + */ + static ulong ms02nv_addrs[] __initdata = { + 0x07000000, 0x06800000, 0x06000000, 0x05800000, 0x05000000, +@@ -130,7 +130,7 @@ + + int ret = -ENODEV; + +- /* The module decodes 8MB of address space. */ ++ /* The module decodes 8MiB of address space. */ + mod_res = kmalloc(sizeof(*mod_res), GFP_KERNEL); + if (!mod_res) + return -ENOMEM; +@@ -233,7 +233,7 @@ + goto err_out_csr_res; + } + +- printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMB.\n", ++ printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMiB.\n", + mtd->index, ms02nv_name, addr, size >> 20); + + mp->next = root_ms02nv_mtd; +@@ -293,12 +293,12 @@ + + switch (mips_machtype) { + case MACH_DS5000_200: +- csr = (volatile u32 *)KN02_CSR_ADDR; ++ csr = (volatile u32 *)KN02_CSR_BASE; + if (*csr & KN02_CSR_BNK32M) + stride = 2; + break; + case MACH_DS5000_2X0: +- case MACH_DS5000: ++ case MACH_DS5900: + csr = (volatile u32 *)KN03_MCR_BASE; + if (*csr & KN03_MCR_BNK32M) + stride = 2; +diff -Nur linux-2.4.32-rc1/drivers/mtd/devices/ms02-nv.h linux-2.4.32-rc1.mips/drivers/mtd/devices/ms02-nv.h +--- linux-2.4.32-rc1/drivers/mtd/devices/ms02-nv.h 2002-11-29 00:53:13.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/mtd/devices/ms02-nv.h 2004-07-30 12:22:40.000000000 +0200 +@@ -1,32 +1,96 @@ + /* +- * Copyright (c) 2001 Maciej W. Rozycki ++ * Copyright (c) 2001, 2003 Maciej W. Rozycki + * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version +- * 2 of the License, or (at your option) any later version. ++ * DEC MS02-NV (54-20948-01) battery backed-up NVRAM module for ++ * DECstation/DECsystem 5000/2x0 and DECsystem 5900 and 5900/260 ++ * systems. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * $Id: ms02-nv.h,v 1.3 2003/08/19 09:25:36 dwmw2 Exp $ + */ + + #include + #include + ++/* ++ * Addresses are decoded as follows: ++ * ++ * 0x000000 - 0x3fffff SRAM ++ * 0x400000 - 0x7fffff CSR ++ * ++ * Within the SRAM area the following ranges are forced by the system ++ * firmware: ++ * ++ * 0x000000 - 0x0003ff diagnostic area, destroyed upon a reboot ++ * 0x000400 - ENDofRAM storage area, available to operating systems ++ * ++ * but we can't really use the available area right from 0x000400 as ++ * the first word is used by the firmware as a status flag passed ++ * from an operating system. If anything but the valid data magic ++ * ID value is found, the firmware considers the SRAM clean, i.e. ++ * containing no valid data, and disables the battery resulting in ++ * data being erased as soon as power is switched off. So the choice ++ * for the start address of the user-available is 0x001000 which is ++ * nicely page aligned. The area between 0x000404 and 0x000fff may ++ * be used by the driver for own needs. ++ * ++ * The diagnostic area defines two status words to be read by an ++ * operating system, a magic ID to distinguish a MS02-NV board from ++ * anything else and a status information providing results of tests ++ * as well as the size of SRAM available, which can be 1MiB or 2MiB ++ * (that's what the firmware handles; no idea if 2MiB modules ever ++ * existed). ++ * ++ * The firmware only handles the MS02-NV board if installed in the ++ * last (15th) slot, so for any other location the status information ++ * stored in the SRAM cannot be relied upon. But from the hardware ++ * point of view there is no problem using up to 14 such boards in a ++ * system -- only the 1st slot needs to be filled with a DRAM module. ++ * The MS02-NV board is ECC-protected, like other MS02 memory boards. ++ * ++ * The state of the battery as provided by the CSR is reflected on ++ * the two onboard LEDs. When facing the battery side of the board, ++ * with the LEDs at the top left and the battery at the bottom right ++ * (i.e. looking from the back side of the system box), their meaning ++ * is as follows (the system has to be powered on): ++ * ++ * left LED battery disable status: lit = enabled ++ * right LED battery condition status: lit = OK ++ */ ++ + /* MS02-NV iomem register offsets. */ + #define MS02NV_CSR 0x400000 /* control & status register */ + ++/* MS02-NV CSR status bits. */ ++#define MS02NV_CSR_BATT_OK 0x01 /* battery OK */ ++#define MS02NV_CSR_BATT_OFF 0x02 /* battery disabled */ ++ ++ + /* MS02-NV memory offsets. */ + #define MS02NV_DIAG 0x0003f8 /* diagnostic status */ + #define MS02NV_MAGIC 0x0003fc /* MS02-NV magic ID */ +-#define MS02NV_RAM 0x000400 /* general-purpose RAM start */ ++#define MS02NV_VALID 0x000400 /* valid data magic ID */ ++#define MS02NV_RAM 0x001000 /* user-exposed RAM start */ + +-/* MS02-NV diagnostic status constants. */ +-#define MS02NV_DIAG_SIZE_MASK 0xf0 /* RAM size mask */ +-#define MS02NV_DIAG_SIZE_SHIFT 0x10 /* RAM size shift (left) */ ++/* MS02-NV diagnostic status bits. */ ++#define MS02NV_DIAG_TEST 0x01 /* SRAM test done (?) */ ++#define MS02NV_DIAG_RO 0x02 /* SRAM r/o test done */ ++#define MS02NV_DIAG_RW 0x04 /* SRAM r/w test done */ ++#define MS02NV_DIAG_FAIL 0x08 /* SRAM test failed */ ++#define MS02NV_DIAG_SIZE_MASK 0xf0 /* SRAM size mask */ ++#define MS02NV_DIAG_SIZE_SHIFT 0x10 /* SRAM size shift (left) */ + + /* MS02-NV general constants. */ + #define MS02NV_ID 0x03021966 /* MS02-NV magic ID value */ ++#define MS02NV_VALID_ID 0xbd100248 /* valid data magic ID value */ + #define MS02NV_SLOT_SIZE 0x800000 /* size of the address space + decoded by the module */ + ++ + typedef volatile u32 ms02nv_uint; + + struct ms02nv_private { +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/Config.in linux-2.4.32-rc1.mips/drivers/mtd/maps/Config.in +--- linux-2.4.32-rc1/drivers/mtd/maps/Config.in 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/Config.in 2004-02-26 01:46:35.000000000 +0100 +@@ -51,11 +51,26 @@ + dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000 + dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500 + dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100 ++ dep_tristate ' Bosporus MTD support' CONFIG_MTD_BOSPORUS $CONFIG_MIPS_BOSPORUS ++ dep_tristate ' XXS1500 boot flash device' CONFIG_MTD_XXS1500 $CONFIG_MIPS_XXS1500 ++ dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1 + if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" \ + -o "$CONFIG_MTD_PB1100" = "y" -o "$CONFIG_MTD_PB1100" = "m" ]; then + bool ' Pb[15]00 boot flash device' CONFIG_MTD_PB1500_BOOT + bool ' Pb[15]00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER + fi ++ tristate ' Db1x00 MTD support' CONFIG_MTD_DB1X00 ++ if [ "$CONFIG_MTD_DB1X00" = "y" -o "$CONFIG_MTD_DB1X00" = "m" ]; then ++ bool ' Db1x00 boot flash device' CONFIG_MTD_DB1X00_BOOT ++ bool ' Db1x00 user flash device (2nd bank)' CONFIG_MTD_DB1X00_USER ++ fi ++ tristate ' Pb1550 MTD support' CONFIG_MTD_PB1550 ++ if [ "$CONFIG_MTD_PB1550" = "y" -o "$CONFIG_MTD_PB1550" = "m" ]; then ++ bool ' Pb1550 Boot Flash' CONFIG_MTD_PB1550_BOOT ++ bool ' Pb1550 User Parameter Flash' CONFIG_MTD_PB1550_USER ++ fi ++ dep_tristate ' Hydrogen 3 MTD support' CONFIG_MTD_HYDROGEN3 $CONFIG_MIPS_HYDROGEN3 ++ dep_tristate ' Mirage MTD support' CONFIG_MTD_MIRAGE $CONFIG_MIPS_MIRAGE + dep_tristate ' Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS + if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then + hex ' Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000 +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/db1x00-flash.c linux-2.4.32-rc1.mips/drivers/mtd/maps/db1x00-flash.c +--- linux-2.4.32-rc1/drivers/mtd/maps/db1x00-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/db1x00-flash.c 2005-02-03 07:35:29.000000000 +0100 +@@ -0,0 +1,283 @@ ++/* ++ * Flash memory access on Alchemy Db1xxx boards ++ * ++ * (C) 2003 Pete Popov ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifdef DEBUG_RW ++#define DBG(x...) printk(x) ++#else ++#define DBG(x...) ++#endif ++ ++static unsigned long window_addr; ++static unsigned long window_size; ++static unsigned long flash_size; ++ ++__u8 physmap_read8(struct map_info *map, unsigned long ofs) ++{ ++ __u8 ret; ++ ret = __raw_readb(map->map_priv_1 + ofs); ++ DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u16 physmap_read16(struct map_info *map, unsigned long ofs) ++{ ++ __u16 ret; ++ ret = __raw_readw(map->map_priv_1 + ofs); ++ DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u32 physmap_read32(struct map_info *map, unsigned long ofs) ++{ ++ __u32 ret; ++ ret = __raw_readl(map->map_priv_1 + ofs); ++ DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++} ++ ++void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++static struct map_info db1x00_map = { ++ name: "Db1x00 flash", ++ read8: physmap_read8, ++ read16: physmap_read16, ++ read32: physmap_read32, ++ copy_from: physmap_copy_from, ++ write8: physmap_write8, ++ write16: physmap_write16, ++ write32: physmap_write32, ++ copy_to: physmap_copy_to, ++}; ++ ++static unsigned char flash_buswidth = 4; ++ ++/* ++ * The Db1x boards support different flash densities. We setup ++ * the mtd_partition structures below for default of 64Mbit ++ * flash densities, and override the partitions sizes, if ++ * necessary, after we check the board status register. ++ */ ++ ++#ifdef DB1X00_BOTH_BANKS ++/* both banks will be used. Combine the first bank and the first ++ * part of the second bank together into a single jffs/jffs2 ++ * partition. ++ */ ++static struct mtd_partition db1x00_partitions[] = { ++ { ++ name: "User FS", ++ size: 0x1c00000, ++ offset: 0x0000000 ++ },{ ++ name: "yamon", ++ size: 0x0100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "raw kernel", ++ size: (0x300000-0x40000), /* last 256KB is yamon env */ ++ offset: MTDPART_OFS_APPEND, ++ } ++}; ++#elif defined(DB1X00_BOOT_ONLY) ++static struct mtd_partition db1x00_partitions[] = { ++ { ++ name: "User FS", ++ size: 0x00c00000, ++ offset: 0x0000000 ++ },{ ++ name: "yamon", ++ size: 0x0100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "raw kernel", ++ size: (0x300000-0x40000), /* last 256KB is yamon env */ ++ offset: MTDPART_OFS_APPEND, ++ } ++}; ++#elif defined(DB1X00_USER_ONLY) ++static struct mtd_partition db1x00_partitions[] = { ++ { ++ name: "User FS", ++ size: 0x0e00000, ++ offset: 0x0000000 ++ },{ ++ name: "raw kernel", ++ size: MTDPART_SIZ_FULL, ++ offset: MTDPART_OFS_APPEND, ++ } ++}; ++#else ++#error MTD_DB1X00 define combo error /* should never happen */ ++#endif ++ ++ ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++ ++static struct mtd_partition *parsed_parts; ++static struct mtd_info *mymtd; ++ ++/* ++ * Probe the flash density and setup window address and size ++ * based on user CONFIG options. There are times when we don't ++ * want the MTD driver to be probing the boot or user flash, ++ * so having the option to enable only one bank is important. ++ */ ++int setup_flash_params() ++{ ++ switch ((bcsr->status >> 14) & 0x3) { ++ case 0: /* 64Mbit devices */ ++ flash_size = 0x800000; /* 8MB per part */ ++#if defined(DB1X00_BOTH_BANKS) ++ window_addr = 0x1E000000; ++ window_size = 0x2000000; ++#elif defined(DB1X00_BOOT_ONLY) ++ window_addr = 0x1F000000; ++ window_size = 0x1000000; ++#else /* USER ONLY */ ++ window_addr = 0x1E000000; ++ window_size = 0x1000000; ++#endif ++ break; ++ case 1: ++ /* 128 Mbit devices */ ++ flash_size = 0x1000000; /* 16MB per part */ ++#if defined(DB1X00_BOTH_BANKS) ++ window_addr = 0x1C000000; ++ window_size = 0x4000000; ++ /* USERFS from 0x1C00 0000 to 0x1FC0 0000 */ ++ db1x00_partitions[0].size = 0x3C00000; ++#elif defined(DB1X00_BOOT_ONLY) ++ window_addr = 0x1E000000; ++ window_size = 0x2000000; ++ /* USERFS from 0x1E00 0000 to 0x1FC0 0000 */ ++ db1x00_partitions[0].size = 0x1C00000; ++#else /* USER ONLY */ ++ window_addr = 0x1C000000; ++ window_size = 0x2000000; ++ /* USERFS from 0x1C00 0000 to 0x1DE00000 */ ++ db1x00_partitions[0].size = 0x1DE0000; ++#endif ++ break; ++ case 2: ++ /* 256 Mbit devices */ ++ flash_size = 0x4000000; /* 64MB per part */ ++#if defined(DB1X00_BOTH_BANKS) ++ return 1; ++#elif defined(DB1X00_BOOT_ONLY) ++ /* Boot ROM flash bank only; no user bank */ ++ window_addr = 0x1C000000; ++ window_size = 0x4000000; ++ /* USERFS from 0x1C00 0000 to 0x1FC00000 */ ++ db1x00_partitions[0].size = 0x3C00000; ++#else /* USER ONLY */ ++ return 1; ++#endif ++ break; ++ default: ++ return 1; ++ } ++ return 0; ++} ++ ++int __init db1x00_mtd_init(void) ++{ ++ struct mtd_partition *parts; ++ int nb_parts = 0; ++ char *part_type; ++ ++ /* Default flash buswidth */ ++ db1x00_map.buswidth = flash_buswidth; ++ ++ if (setup_flash_params()) ++ return -ENXIO; ++ ++ /* ++ * Static partition definition selection ++ */ ++ part_type = "static"; ++ parts = db1x00_partitions; ++ nb_parts = NB_OF(db1x00_partitions); ++ db1x00_map.size = window_size; ++ ++ /* ++ * Now let's probe for the actual flash. Do it here since ++ * specific machine settings might have been set above. ++ */ ++ printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n", ++ db1x00_map.buswidth*8); ++ db1x00_map.map_priv_1 = ++ (unsigned long)ioremap(window_addr, window_size); ++ mymtd = do_map_probe("cfi_probe", &db1x00_map); ++ if (!mymtd) return -ENXIO; ++ mymtd->module = THIS_MODULE; ++ ++ add_mtd_partitions(mymtd, parts, nb_parts); ++ return 0; ++} ++ ++static void __exit db1x00_mtd_cleanup(void) ++{ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ if (parsed_parts) ++ kfree(parsed_parts); ++ } ++} ++ ++module_init(db1x00_mtd_init); ++module_exit(db1x00_mtd_cleanup); ++ ++MODULE_AUTHOR("Pete Popov"); ++MODULE_DESCRIPTION("Db1x00 mtd map driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/hydrogen3-flash.c linux-2.4.32-rc1.mips/drivers/mtd/maps/hydrogen3-flash.c +--- linux-2.4.32-rc1/drivers/mtd/maps/hydrogen3-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/hydrogen3-flash.c 2004-01-10 23:40:18.000000000 +0100 +@@ -0,0 +1,189 @@ ++/* ++ * Flash memory access on Alchemy HydrogenIII boards ++ * ++ * (C) 2003 Pete Popov ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef DEBUG_RW ++#define DBG(x...) printk(x) ++#else ++#define DBG(x...) ++#endif ++ ++#define WINDOW_ADDR 0x1E000000 ++#define WINDOW_SIZE 0x02000000 ++ ++ ++__u8 physmap_read8(struct map_info *map, unsigned long ofs) ++{ ++ __u8 ret; ++ ret = __raw_readb(map->map_priv_1 + ofs); ++ DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u16 physmap_read16(struct map_info *map, unsigned long ofs) ++{ ++ __u16 ret; ++ ret = __raw_readw(map->map_priv_1 + ofs); ++ DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u32 physmap_read32(struct map_info *map, unsigned long ofs) ++{ ++ __u32 ret; ++ ret = __raw_readl(map->map_priv_1 + ofs); ++ DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++} ++ ++void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++static struct map_info hydrogen3_map = { ++ name: "HydrogenIII flash", ++ read8: physmap_read8, ++ read16: physmap_read16, ++ read32: physmap_read32, ++ copy_from: physmap_copy_from, ++ write8: physmap_write8, ++ write16: physmap_write16, ++ write32: physmap_write32, ++ copy_to: physmap_copy_to, ++}; ++ ++static unsigned char flash_buswidth = 4; ++ ++/* MTDPART_OFS_APPEND is vastly preferred to any attempt at statically lining ++ * up the offsets. */ ++static struct mtd_partition hydrogen3_partitions[] = { ++ { ++ name: "User FS", ++ size: 0x1c00000, ++ offset: 0x0000000 ++ },{ ++ name: "yamon", ++ size: 0x0100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "raw kernel", ++ size: 0x02c0000, ++ offset: MTDPART_OFS_APPEND ++ } ++}; ++ ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++ ++static struct mtd_partition *parsed_parts; ++static struct mtd_info *mymtd; ++ ++int __init hydrogen3_mtd_init(void) ++{ ++ struct mtd_partition *parts; ++ int nb_parts = 0; ++ char *part_type; ++ ++ /* Default flash buswidth */ ++ hydrogen3_map.buswidth = flash_buswidth; ++ ++ /* ++ * Static partition definition selection ++ */ ++ part_type = "static"; ++ parts = hydrogen3_partitions; ++ nb_parts = NB_OF(hydrogen3_partitions); ++ hydrogen3_map.size = WINDOW_SIZE; ++ ++ /* ++ * Now let's probe for the actual flash. Do it here since ++ * specific machine settings might have been set above. ++ */ ++ printk(KERN_NOTICE "HydrogenIII flash: probing %d-bit flash bus\n", ++ hydrogen3_map.buswidth*8); ++ hydrogen3_map.map_priv_1 = ++ (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ mymtd = do_map_probe("cfi_probe", &hydrogen3_map); ++ if (!mymtd) return -ENXIO; ++ mymtd->module = THIS_MODULE; ++ ++ add_mtd_partitions(mymtd, parts, nb_parts); ++ return 0; ++} ++ ++static void __exit hydrogen3_mtd_cleanup(void) ++{ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ if (parsed_parts) ++ kfree(parsed_parts); ++ } ++} ++ ++/*#ifndef MODULE ++ ++static int __init _bootflashonly(char *str) ++{ ++ bootflashonly = simple_strtol(str, NULL, 0); ++ return 1; ++} ++ ++ ++__setup("bootflashonly=", _bootflashonly); ++ ++#endif*/ ++ ++ ++module_init(hydrogen3_mtd_init); ++module_exit(hydrogen3_mtd_cleanup); ++ ++MODULE_PARM(bootflashonly, "i"); ++MODULE_PARM_DESC(bootflashonly, "1=use \"boot flash only\""); ++MODULE_AUTHOR("Pete Popov"); ++MODULE_DESCRIPTION("HydrogenIII mtd map driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/lasat.c linux-2.4.32-rc1.mips/drivers/mtd/maps/lasat.c +--- linux-2.4.32-rc1/drivers/mtd/maps/lasat.c 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/lasat.c 2003-08-18 04:59:02.000000000 +0200 +@@ -1,15 +1,6 @@ + /* + * Flash device on lasat 100 and 200 boards + * +- * Presumably (C) 2002 Brian Murphy or whoever he +- * works for. +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License version +- * 2 as published by the Free Software Foundation. +- * +- * $Id: lasat.c,v 1.1 2003/01/24 14:26:38 dwmw2 Exp $ +- * + */ + + #include +@@ -21,7 +12,6 @@ + #include + #include + #include +-#include + + static struct mtd_info *mymtd; + +@@ -69,30 +59,33 @@ + } + + static struct map_info sp_map = { +- .name = "SP flash", +- .buswidth = 4, +- .read8 = sp_read8, +- .read16 = sp_read16, +- .read32 = sp_read32, +- .copy_from = sp_copy_from, +- .write8 = sp_write8, +- .write16 = sp_write16, +- .write32 = sp_write32, +- .copy_to = sp_copy_to ++ name: "SP flash", ++ buswidth: 4, ++ read8: sp_read8, ++ read16: sp_read16, ++ read32: sp_read32, ++ copy_from: sp_copy_from, ++ write8: sp_write8, ++ write16: sp_write16, ++ write32: sp_write32, ++ copy_to: sp_copy_to + }; + + static struct mtd_partition partition_info[LASAT_MTD_LAST]; +-static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"}; ++static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Config", "Filesystem"}; + + static int __init init_sp(void) + { + int i; ++ int nparts = 0; + /* this does not play well with the old flash code which + * protects and uprotects the flash when necessary */ + printk(KERN_NOTICE "Unprotecting flash\n"); + *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; + +- sp_map.map_priv_1 = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER); ++ sp_map.map_priv_1 = ioremap_nocache( ++ lasat_flash_partition_start(LASAT_MTD_BOOTLOADER), ++ lasat_board_info.li_flash_size); + sp_map.size = lasat_board_info.li_flash_size; + + printk(KERN_NOTICE "sp flash device: %lx at %lx\n", +@@ -109,12 +102,15 @@ + + for (i=0; i < LASAT_MTD_LAST; i++) { + size = lasat_flash_partition_size(i); +- partition_info[i].size = size; +- partition_info[i].offset = offset; +- offset += size; ++ if (size != 0) { ++ nparts++; ++ partition_info[i].size = size; ++ partition_info[i].offset = offset; ++ offset += size; ++ } + } + +- add_mtd_partitions( mymtd, partition_info, LASAT_MTD_LAST ); ++ add_mtd_partitions( mymtd, partition_info, nparts ); + return 0; + } + +@@ -124,11 +120,11 @@ + static void __exit cleanup_sp(void) + { + if (mymtd) { +- del_mtd_partitions(mymtd); +- map_destroy(mymtd); ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); + } + if (sp_map.map_priv_1) { +- sp_map.map_priv_1 = 0; ++ sp_map.map_priv_1 = 0; + } + } + +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/Makefile linux-2.4.32-rc1.mips/drivers/mtd/maps/Makefile +--- linux-2.4.32-rc1/drivers/mtd/maps/Makefile 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/Makefile 2004-02-26 01:46:35.000000000 +0100 +@@ -52,7 +52,13 @@ + obj-$(CONFIG_MTD_PB1000) += pb1xxx-flash.o + obj-$(CONFIG_MTD_PB1100) += pb1xxx-flash.o + obj-$(CONFIG_MTD_PB1500) += pb1xxx-flash.o ++obj-$(CONFIG_MTD_XXS1500) += xxs1500.o ++obj-$(CONFIG_MTD_MTX1) += mtx-1.o + obj-$(CONFIG_MTD_LASAT) += lasat.o ++obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o ++obj-$(CONFIG_MTD_PB1550) += pb1550-flash.o ++obj-$(CONFIG_MTD_HYDROGEN3) += hydrogen3-flash.o ++obj-$(CONFIG_MTD_BOSPORUS) += pb1xxx-flash.o + obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o + obj-$(CONFIG_MTD_EDB7312) += edb7312.o + obj-$(CONFIG_MTD_IMPA7) += impa7.o +@@ -61,5 +67,6 @@ + obj-$(CONFIG_MTD_UCLINUX) += uclinux.o + obj-$(CONFIG_MTD_NETtel) += nettel.o + obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o ++obj-$(CONFIG_MTD_MIRAGE) += mirage-flash.o + + include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/mirage-flash.c linux-2.4.32-rc1.mips/drivers/mtd/maps/mirage-flash.c +--- linux-2.4.32-rc1/drivers/mtd/maps/mirage-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/mirage-flash.c 2003-12-22 04:37:22.000000000 +0100 +@@ -0,0 +1,194 @@ ++/* ++ * Flash memory access on AMD Mirage board. ++ * ++ * (C) 2003 Embedded Edge ++ * based on mirage-flash.c: ++ * (C) 2003 Pete Popov ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++//#include ++ ++#ifdef DEBUG_RW ++#define DBG(x...) printk(x) ++#else ++#define DBG(x...) ++#endif ++ ++static unsigned long window_addr; ++static unsigned long window_size; ++static unsigned long flash_size; ++ ++__u8 physmap_read8(struct map_info *map, unsigned long ofs) ++{ ++ __u8 ret; ++ ret = __raw_readb(map->map_priv_1 + ofs); ++ DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u16 physmap_read16(struct map_info *map, unsigned long ofs) ++{ ++ __u16 ret; ++ ret = __raw_readw(map->map_priv_1 + ofs); ++ DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u32 physmap_read32(struct map_info *map, unsigned long ofs) ++{ ++ __u32 ret; ++ ret = __raw_readl(map->map_priv_1 + ofs); ++ DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++} ++ ++void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++static struct map_info mirage_map = { ++ name: "Mirage flash", ++ read8: physmap_read8, ++ read16: physmap_read16, ++ read32: physmap_read32, ++ copy_from: physmap_copy_from, ++ write8: physmap_write8, ++ write16: physmap_write16, ++ write32: physmap_write32, ++ copy_to: physmap_copy_to, ++}; ++ ++static unsigned char flash_buswidth = 4; ++ ++static struct mtd_partition mirage_partitions[] = { ++ { ++ name: "User FS", ++ size: 0x1c00000, ++ offset: 0x0000000 ++ },{ ++ name: "yamon", ++ size: 0x0100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "raw kernel", ++ size: (0x300000-0x40000), /* last 256KB is yamon env */ ++ offset: MTDPART_OFS_APPEND, ++ } ++}; ++ ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++ ++static struct mtd_partition *parsed_parts; ++static struct mtd_info *mymtd; ++ ++/* ++ * Probe the flash density and setup window address and size ++ * based on user CONFIG options. There are times when we don't ++ * want the MTD driver to be probing the boot or user flash, ++ * so having the option to enable only one bank is important. ++ */ ++int setup_flash_params() ++{ ++ flash_size = 0x4000000; /* 64MB per part */ ++ /* Boot ROM flash bank only; no user bank */ ++ window_addr = 0x1C000000; ++ window_size = 0x4000000; ++ /* USERFS from 0x1C00 0000 to 0x1FC00000 */ ++ mirage_partitions[0].size = 0x3C00000; ++ return 0; ++} ++ ++int __init mirage_mtd_init(void) ++{ ++ struct mtd_partition *parts; ++ int nb_parts = 0; ++ char *part_type; ++ ++ /* Default flash buswidth */ ++ mirage_map.buswidth = flash_buswidth; ++ ++ if (setup_flash_params()) ++ return -ENXIO; ++ ++ /* ++ * Static partition definition selection ++ */ ++ part_type = "static"; ++ parts = mirage_partitions; ++ nb_parts = NB_OF(mirage_partitions); ++ mirage_map.size = window_size; ++ ++ /* ++ * Now let's probe for the actual flash. Do it here since ++ * specific machine settings might have been set above. ++ */ ++ printk(KERN_NOTICE "Mirage flash: probing %d-bit flash bus\n", ++ mirage_map.buswidth*8); ++ mirage_map.map_priv_1 = ++ (unsigned long)ioremap(window_addr, window_size); ++ mymtd = do_map_probe("cfi_probe", &mirage_map); ++ if (!mymtd) return -ENXIO; ++ mymtd->module = THIS_MODULE; ++ ++ add_mtd_partitions(mymtd, parts, nb_parts); ++ return 0; ++} ++ ++static void __exit mirage_mtd_cleanup(void) ++{ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ if (parsed_parts) ++ kfree(parsed_parts); ++ } ++} ++ ++module_init(mirage_mtd_init); ++module_exit(mirage_mtd_cleanup); ++ ++MODULE_AUTHOR("Embedded Edge"); ++MODULE_DESCRIPTION("Mirage mtd map driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/mtx-1.c linux-2.4.32-rc1.mips/drivers/mtd/maps/mtx-1.c +--- linux-2.4.32-rc1/drivers/mtd/maps/mtx-1.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/mtx-1.c 2003-06-27 02:04:35.000000000 +0200 +@@ -0,0 +1,181 @@ ++/* ++ * Flash memory access on 4G Systems MTX-1 board ++ * ++ * (C) 2003 Pete Popov ++ * Bruno Randolf ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef DEBUG_RW ++#define DBG(x...) printk(x) ++#else ++#define DBG(x...) ++#endif ++ ++#ifdef CONFIG_MIPS_MTX1 ++#define WINDOW_ADDR 0x1E000000 ++#define WINDOW_SIZE 0x2000000 ++#endif ++ ++__u8 physmap_read8(struct map_info *map, unsigned long ofs) ++{ ++ __u8 ret; ++ ret = __raw_readb(map->map_priv_1 + ofs); ++ DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u16 physmap_read16(struct map_info *map, unsigned long ofs) ++{ ++ __u16 ret; ++ ret = __raw_readw(map->map_priv_1 + ofs); ++ DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u32 physmap_read32(struct map_info *map, unsigned long ofs) ++{ ++ __u32 ret; ++ ret = __raw_readl(map->map_priv_1 + ofs); ++ DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++} ++ ++void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++ ++ ++static struct map_info mtx1_map = { ++ name: "MTX-1 flash", ++ read8: physmap_read8, ++ read16: physmap_read16, ++ read32: physmap_read32, ++ copy_from: physmap_copy_from, ++ write8: physmap_write8, ++ write16: physmap_write16, ++ write32: physmap_write32, ++ copy_to: physmap_copy_to, ++}; ++ ++ ++static unsigned long flash_size = 0x01000000; ++static unsigned char flash_buswidth = 4; ++static struct mtd_partition mtx1_partitions[] = { ++ { ++ name: "user fs", ++ size: 0x1c00000, ++ offset: 0, ++ },{ ++ name: "yamon", ++ size: 0x0100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "raw kernel", ++ size: 0x02c0000, ++ offset: MTDPART_OFS_APPEND, ++ },{ ++ name: "yamon env vars", ++ size: 0x0040000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ } ++}; ++ ++ ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++ ++static struct mtd_partition *parsed_parts; ++static struct mtd_info *mymtd; ++ ++int __init mtx1_mtd_init(void) ++{ ++ struct mtd_partition *parts; ++ int nb_parts = 0; ++ char *part_type; ++ ++ /* Default flash buswidth */ ++ mtx1_map.buswidth = flash_buswidth; ++ ++ /* ++ * Static partition definition selection ++ */ ++ part_type = "static"; ++ parts = mtx1_partitions; ++ nb_parts = NB_OF(mtx1_partitions); ++ mtx1_map.size = flash_size; ++ ++ /* ++ * Now let's probe for the actual flash. Do it here since ++ * specific machine settings might have been set above. ++ */ ++ printk(KERN_NOTICE "MTX-1 flash: probing %d-bit flash bus\n", ++ mtx1_map.buswidth*8); ++ mtx1_map.map_priv_1 = ++ (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ mymtd = do_map_probe("cfi_probe", &mtx1_map); ++ if (!mymtd) return -ENXIO; ++ mymtd->module = THIS_MODULE; ++ ++ add_mtd_partitions(mymtd, parts, nb_parts); ++ return 0; ++} ++ ++static void __exit mtx1_mtd_cleanup(void) ++{ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ if (parsed_parts) ++ kfree(parsed_parts); ++ } ++} ++ ++module_init(mtx1_mtd_init); ++module_exit(mtx1_mtd_cleanup); ++ ++MODULE_AUTHOR("Pete Popov"); ++MODULE_DESCRIPTION("MTX-1 CFI map driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/pb1550-flash.c linux-2.4.32-rc1.mips/drivers/mtd/maps/pb1550-flash.c +--- linux-2.4.32-rc1/drivers/mtd/maps/pb1550-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/pb1550-flash.c 2004-02-26 01:48:48.000000000 +0100 +@@ -0,0 +1,270 @@ ++/* ++ * Flash memory access on Alchemy Pb1550 board ++ * ++ * (C) 2004 Embedded Edge, LLC, based on pb1550-flash.c: ++ * (C) 2003 Pete Popov ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifdef DEBUG_RW ++#define DBG(x...) printk(x) ++#else ++#define DBG(x...) ++#endif ++ ++static unsigned long window_addr; ++static unsigned long window_size; ++ ++__u8 physmap_read8(struct map_info *map, unsigned long ofs) ++{ ++ __u8 ret; ++ ret = __raw_readb(map->map_priv_1 + ofs); ++ DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u16 physmap_read16(struct map_info *map, unsigned long ofs) ++{ ++ __u16 ret; ++ ret = __raw_readw(map->map_priv_1 + ofs); ++ DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u32 physmap_read32(struct map_info *map, unsigned long ofs) ++{ ++ __u32 ret; ++ ret = __raw_readl(map->map_priv_1 + ofs); ++ DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++} ++ ++void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++static struct map_info pb1550_map = { ++ name: "Pb1550 flash", ++ read8: physmap_read8, ++ read16: physmap_read16, ++ read32: physmap_read32, ++ copy_from: physmap_copy_from, ++ write8: physmap_write8, ++ write16: physmap_write16, ++ write32: physmap_write32, ++ copy_to: physmap_copy_to, ++}; ++ ++static unsigned char flash_buswidth = 4; ++ ++/* ++ * Support only 64MB NOR Flash parts ++ */ ++ ++#ifdef PB1550_BOTH_BANKS ++/* both banks will be used. Combine the first bank and the first ++ * part of the second bank together into a single jffs/jffs2 ++ * partition. ++ */ ++static struct mtd_partition pb1550_partitions[] = { ++ /* assume boot[2:0]:swap is '0000' or '1000', which translates to: ++ * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash ++ * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash ++ */ ++ { ++ name: "User FS", ++ size: (0x1FC00000 - 0x18000000), ++ offset: 0x0000000 ++ },{ ++ name: "yamon", ++ size: 0x0100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "raw kernel", ++ size: (0x300000 - 0x40000), /* last 256KB is yamon env */ ++ offset: MTDPART_OFS_APPEND, ++ } ++}; ++#elif defined(PB1550_BOOT_ONLY) ++static struct mtd_partition pb1550_partitions[] = { ++ /* assume boot[2:0]:swap is '0000' or '1000', which translates to: ++ * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash ++ */ ++ { ++ name: "User FS", ++ size: 0x03c00000, ++ offset: 0x0000000 ++ },{ ++ name: "yamon", ++ size: 0x0100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "raw kernel", ++ size: (0x300000-0x40000), /* last 256KB is yamon env */ ++ offset: MTDPART_OFS_APPEND, ++ } ++}; ++#elif defined(PB1550_USER_ONLY) ++static struct mtd_partition pb1550_partitions[] = { ++ /* assume boot[2:0]:swap is '0000' or '1000', which translates to: ++ * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash ++ */ ++ { ++ name: "User FS", ++ size: (0x4000000 - 0x200000), /* reserve 2MB for raw kernel */ ++ offset: 0x0000000 ++ },{ ++ name: "raw kernel", ++ size: MTDPART_SIZ_FULL, ++ offset: MTDPART_OFS_APPEND, ++ } ++}; ++#else ++#error MTD_PB1550 define combo error /* should never happen */ ++#endif ++ ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++ ++static struct mtd_partition *parsed_parts; ++static struct mtd_info *mymtd; ++ ++/* ++ * Probe the flash density and setup window address and size ++ * based on user CONFIG options. There are times when we don't ++ * want the MTD driver to be probing the boot or user flash, ++ * so having the option to enable only one bank is important. ++ */ ++int setup_flash_params() ++{ ++ u16 boot_swapboot; ++ boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | ++ ((bcsr->status >> 6) & 0x1); ++ printk("Pb1550 MTD: boot:swap %d\n", boot_swapboot); ++ ++ switch (boot_swapboot) { ++ case 0: /* 512Mbit devices, both enabled */ ++ case 1: ++ case 8: ++ case 9: ++#if defined(PB1550_BOTH_BANKS) ++ window_addr = 0x18000000; ++ window_size = 0x8000000; ++#elif defined(PB1550_BOOT_ONLY) ++ window_addr = 0x1C000000; ++ window_size = 0x4000000; ++#else /* USER ONLY */ ++ window_addr = 0x1E000000; ++ window_size = 0x1000000; ++#endif ++ break; ++ case 0xC: ++ case 0xD: ++ case 0xE: ++ case 0xF: ++ /* 64 MB Boot NOR Flash is disabled */ ++ /* and the start address is moved to 0x0C00000 */ ++ window_addr = 0x0C000000; ++ window_size = 0x4000000; ++ default: ++ printk("Pb1550 MTD: unsupported boot:swap setting\n"); ++ return 1; ++ } ++ return 0; ++} ++ ++int __init pb1550_mtd_init(void) ++{ ++ struct mtd_partition *parts; ++ int nb_parts = 0; ++ char *part_type; ++ ++ /* Default flash buswidth */ ++ pb1550_map.buswidth = flash_buswidth; ++ ++ if (setup_flash_params()) ++ return -ENXIO; ++ ++ /* ++ * Static partition definition selection ++ */ ++ part_type = "static"; ++ parts = pb1550_partitions; ++ nb_parts = NB_OF(pb1550_partitions); ++ pb1550_map.size = window_size; ++ ++ /* ++ * Now let's probe for the actual flash. Do it here since ++ * specific machine settings might have been set above. ++ */ ++ printk(KERN_NOTICE "Pb1550 flash: probing %d-bit flash bus\n", ++ pb1550_map.buswidth*8); ++ pb1550_map.map_priv_1 = ++ (unsigned long)ioremap(window_addr, window_size); ++ mymtd = do_map_probe("cfi_probe", &pb1550_map); ++ if (!mymtd) return -ENXIO; ++ mymtd->module = THIS_MODULE; ++ ++ add_mtd_partitions(mymtd, parts, nb_parts); ++ return 0; ++} ++ ++static void __exit pb1550_mtd_cleanup(void) ++{ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ if (parsed_parts) ++ kfree(parsed_parts); ++ } ++} ++ ++module_init(pb1550_mtd_init); ++module_exit(pb1550_mtd_cleanup); ++ ++MODULE_AUTHOR("Embedded Edge, LLC"); ++MODULE_DESCRIPTION("Pb1550 mtd map driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/pb1xxx-flash.c linux-2.4.32-rc1.mips/drivers/mtd/maps/pb1xxx-flash.c +--- linux-2.4.32-rc1/drivers/mtd/maps/pb1xxx-flash.c 2003-06-13 16:51:34.000000000 +0200 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/pb1xxx-flash.c 2003-05-19 08:27:22.000000000 +0200 +@@ -192,6 +192,34 @@ + #else + #error MTD_PB1500 define combo error /* should never happen */ + #endif ++#elif defined(CONFIG_MTD_BOSPORUS) ++static unsigned char flash_buswidth = 2; ++static unsigned long flash_size = 0x02000000; ++#define WINDOW_ADDR 0x1F000000 ++#define WINDOW_SIZE 0x2000000 ++static struct mtd_partition pb1xxx_partitions[] = { ++ { ++ name: "User FS", ++ size: 0x00400000, ++ offset: 0x00000000, ++ },{ ++ name: "Yamon-2", ++ size: 0x00100000, ++ offset: 0x00400000, ++ },{ ++ name: "Root FS", ++ size: 0x00700000, ++ offset: 0x00500000, ++ },{ ++ name: "Yamon-1", ++ size: 0x00100000, ++ offset: 0x00C00000, ++ },{ ++ name: "Kernel", ++ size: 0x00300000, ++ offset: 0x00D00000, ++ } ++}; + #else + #error Unsupported board + #endif +diff -Nur linux-2.4.32-rc1/drivers/mtd/maps/xxs1500.c linux-2.4.32-rc1.mips/drivers/mtd/maps/xxs1500.c +--- linux-2.4.32-rc1/drivers/mtd/maps/xxs1500.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/mtd/maps/xxs1500.c 2003-08-02 04:06:01.000000000 +0200 +@@ -0,0 +1,186 @@ ++/* ++ * Flash memory access on MyCable XXS1500 board ++ * ++ * (C) 2003 Pete Popov ++ * ++ * $Id: xxs1500.c,v 1.1.2.1 2003/06/13 21:15:46 ppopov Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef DEBUG_RW ++#define DBG(x...) printk(x) ++#else ++#define DBG(x...) ++#endif ++ ++#ifdef CONFIG_MIPS_XXS1500 ++#define WINDOW_ADDR 0x1F000000 ++#define WINDOW_SIZE 0x1000000 ++#endif ++ ++__u8 physmap_read8(struct map_info *map, unsigned long ofs) ++{ ++ __u8 ret; ++ ret = __raw_readb(map->map_priv_1 + ofs); ++ DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u16 physmap_read16(struct map_info *map, unsigned long ofs) ++{ ++ __u16 ret; ++ ret = __raw_readw(map->map_priv_1 + ofs); ++ DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++__u32 physmap_read32(struct map_info *map, unsigned long ofs) ++{ ++ __u32 ret; ++ ret = __raw_readl(map->map_priv_1 + ofs); ++ DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); ++ return ret; ++} ++ ++void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); ++ memcpy_fromio(to, map->map_priv_1 + from, len); ++} ++ ++void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) ++{ ++ DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) ++{ ++ DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); ++ memcpy_toio(map->map_priv_1 + to, from, len); ++} ++ ++ ++ ++static struct map_info xxs1500_map = { ++ name: "XXS1500 flash", ++ read8: physmap_read8, ++ read16: physmap_read16, ++ read32: physmap_read32, ++ copy_from: physmap_copy_from, ++ write8: physmap_write8, ++ write16: physmap_write16, ++ write32: physmap_write32, ++ copy_to: physmap_copy_to, ++}; ++ ++ ++static unsigned long flash_size = 0x00800000; ++static unsigned char flash_buswidth = 4; ++static struct mtd_partition xxs1500_partitions[] = { ++ { ++ name: "kernel image", ++ size: 0x00200000, ++ offset: 0, ++ },{ ++ name: "user fs 0", ++ size: (0x00C00000-0x200000), ++ offset: MTDPART_OFS_APPEND, ++ },{ ++ name: "yamon", ++ size: 0x00100000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ },{ ++ name: "user fs 1", ++ size: 0x2c0000, ++ offset: MTDPART_OFS_APPEND, ++ },{ ++ name: "yamon env vars", ++ size: 0x040000, ++ offset: MTDPART_OFS_APPEND, ++ mask_flags: MTD_WRITEABLE ++ } ++}; ++ ++ ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++ ++static struct mtd_partition *parsed_parts; ++static struct mtd_info *mymtd; ++ ++int __init xxs1500_mtd_init(void) ++{ ++ struct mtd_partition *parts; ++ int nb_parts = 0; ++ char *part_type; ++ ++ /* Default flash buswidth */ ++ xxs1500_map.buswidth = flash_buswidth; ++ ++ /* ++ * Static partition definition selection ++ */ ++ part_type = "static"; ++ parts = xxs1500_partitions; ++ nb_parts = NB_OF(xxs1500_partitions); ++ xxs1500_map.size = flash_size; ++ ++ /* ++ * Now let's probe for the actual flash. Do it here since ++ * specific machine settings might have been set above. ++ */ ++ printk(KERN_NOTICE "XXS1500 flash: probing %d-bit flash bus\n", ++ xxs1500_map.buswidth*8); ++ xxs1500_map.map_priv_1 = ++ (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ mymtd = do_map_probe("cfi_probe", &xxs1500_map); ++ if (!mymtd) return -ENXIO; ++ mymtd->module = THIS_MODULE; ++ ++ add_mtd_partitions(mymtd, parts, nb_parts); ++ return 0; ++} ++ ++static void __exit xxs1500_mtd_cleanup(void) ++{ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ if (parsed_parts) ++ kfree(parsed_parts); ++ } ++} ++ ++module_init(xxs1500_mtd_init); ++module_exit(xxs1500_mtd_cleanup); ++ ++MODULE_AUTHOR("Pete Popov"); ++MODULE_DESCRIPTION("XXS1500 CFI map driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/net/defxx.c linux-2.4.32-rc1.mips/drivers/net/defxx.c +--- linux-2.4.32-rc1/drivers/net/defxx.c 2004-11-17 12:54:21.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/net/defxx.c 2004-11-19 01:28:39.000000000 +0100 +@@ -10,24 +10,18 @@ + * + * Abstract: + * A Linux device driver supporting the Digital Equipment Corporation +- * FDDI EISA and PCI controller families. Supported adapters include: ++ * FDDI TURBOchannel, EISA and PCI controller families. Supported ++ * adapters include: + * +- * DEC FDDIcontroller/EISA (DEFEA) +- * DEC FDDIcontroller/PCI (DEFPA) ++ * DEC FDDIcontroller/TURBOchannel (DEFTA) ++ * DEC FDDIcontroller/EISA (DEFEA) ++ * DEC FDDIcontroller/PCI (DEFPA) + * +- * Maintainers: +- * LVS Lawrence V. Stefani +- * +- * Contact: +- * The author may be reached at: ++ * The original author: ++ * LVS Lawrence V. Stefani + * +- * Inet: stefani@lkg.dec.com +- * (NOTE! this address no longer works -jgarzik) +- * +- * Mail: Digital Equipment Corporation +- * 550 King Street +- * M/S: LKG1-3/M07 +- * Littleton, MA 01460 ++ * Maintainers: ++ * macro Maciej W. Rozycki + * + * Credits: + * I'd like to thank Patricia Cross for helping me get started with +@@ -197,16 +191,16 @@ + * Sep 2000 tjeerd Fix leak on unload, cosmetic code cleanup + * Feb 2001 Skb allocation fixes + * Feb 2001 davej PCI enable cleanups. ++ * 04 Aug 2003 macro Converted to the DMA API. ++ * 14 Aug 2004 macro Fix device names reported. ++ * 26 Sep 2004 macro TURBOchannel support. + */ + + /* Include files */ + + #include +- + #include +-#include + #include +-#include + #include + #include + #include +@@ -215,19 +209,33 @@ + #include + #include + #include ++#include ++#include ++ + #include + #include + #include + +-#include +-#include ++#ifdef CONFIG_TC ++#include ++#else ++static int search_tc_card(const char *name) { return -ENODEV; } ++static void claim_tc_card(int slot) { } ++static void release_tc_card(int slot) { } ++static unsigned long get_tc_base_addr(int slot) { return 0; } ++static unsigned long get_tc_irq_nr(int slot) { return -1; } ++#endif + + #include "defxx.h" + +-/* Version information string - should be updated prior to each new release!!! */ ++/* Version information string should be updated prior to each new release! */ ++#define DRV_NAME "defxx" ++#define DRV_VERSION "v1.07T" ++#define DRV_RELDATE "2004/09/26" + + static char version[] __devinitdata = +- "defxx.c:v1.05e 2001/02/03 Lawrence V. Stefani and others\n"; ++ DRV_NAME ": " DRV_VERSION " " DRV_RELDATE ++ " Lawrence V. Stefani and others\n"; + + #define DYNAMIC_BUFFERS 1 + +@@ -243,7 +251,7 @@ + static void dfx_bus_init(struct net_device *dev); + static void dfx_bus_config_check(DFX_board_t *bp); + +-static int dfx_driver_init(struct net_device *dev); ++static int dfx_driver_init(struct net_device *dev, const char *print_name); + static int dfx_adap_init(DFX_board_t *bp, int get_buffers); + + static int dfx_open(struct net_device *dev); +@@ -337,48 +345,84 @@ + int offset, + u8 data + ) ++{ ++ if (bp->bus_type == DFX_BUS_TYPE_TC) ++ { ++ volatile u8 *addr = (void *)(bp->base_addr + offset); + ++ *addr = data; ++ mb(); ++ } ++ else + { + u16 port = bp->base_addr + offset; + + outb(data, port); + } ++} + + static inline void dfx_port_read_byte( + DFX_board_t *bp, + int offset, + u8 *data + ) ++{ ++ if (bp->bus_type == DFX_BUS_TYPE_TC) ++ { ++ volatile u8 *addr = (void *)(bp->base_addr + offset); + ++ mb(); ++ *data = *addr; ++ } ++ else + { + u16 port = bp->base_addr + offset; + + *data = inb(port); + } ++} + + static inline void dfx_port_write_long( + DFX_board_t *bp, + int offset, + u32 data + ) ++{ ++ if (bp->bus_type == DFX_BUS_TYPE_TC) ++ { ++ volatile u32 *addr = (void *)(bp->base_addr + offset); + ++ *addr = data; ++ mb(); ++ } ++ else + { + u16 port = bp->base_addr + offset; + + outl(data, port); + } ++} + + static inline void dfx_port_read_long( + DFX_board_t *bp, + int offset, + u32 *data + ) ++{ ++ if (bp->bus_type == DFX_BUS_TYPE_TC) ++ { ++ volatile u32 *addr = (void *)(bp->base_addr + offset); + ++ mb(); ++ *data = *addr; ++ } ++ else + { + u16 port = bp->base_addr + offset; + + *data = inl(port); + } ++} + + + /* +@@ -393,8 +437,9 @@ + * Condition code + * + * Arguments: +- * pdev - pointer to pci device information (NULL for EISA) +- * ioaddr - pointer to port (NULL for PCI) ++ * pdev - pointer to pci device information (NULL for EISA or TURBOchannel) ++ * bus_type - bus type (one of DFX_BUS_TYPE_*) ++ * handle - bus-specific data: slot (TC), pointer to port (EISA), NULL (PCI) + * + * Functional Description: + * +@@ -410,54 +455,68 @@ + * initialized and the board resources are read and stored in + * the device structure. + */ +-static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr) ++static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, u32 bus_type, long handle) + { ++ static int version_disp; ++ char *print_name = DRV_NAME; + struct net_device *dev; + DFX_board_t *bp; /* board pointer */ ++ long ioaddr; /* pointer to port */ ++ unsigned long len; /* resource length */ ++ int alloc_size; /* total buffer size used */ + int err; + +-#ifndef MODULE +- static int version_disp; +- +- if (!version_disp) /* display version info if adapter is found */ +- { ++ if (!version_disp) { /* display version info if adapter is found */ + version_disp = 1; /* set display flag to TRUE so that */ + printk(version); /* we only display this string ONCE */ + } +-#endif + +- /* +- * init_fddidev() allocates a device structure with private data, clears the device structure and private data, +- * and calls fddi_setup() and register_netdev(). Not much left to do for us here. +- */ +- dev = init_fddidev(NULL, sizeof(*bp)); ++ if (pdev != NULL) ++ print_name = pdev->slot_name; ++ ++ dev = alloc_fddidev(sizeof(*bp)); + if (!dev) { +- printk (KERN_ERR "defxx: unable to allocate fddidev, aborting\n"); ++ printk(KERN_ERR "%s: unable to allocate fddidev, aborting\n", ++ print_name); + return -ENOMEM; + } + + /* Enable PCI device. */ +- if (pdev != NULL) { ++ if (bus_type == DFX_BUS_TYPE_PCI) { + err = pci_enable_device (pdev); + if (err) goto err_out; + ioaddr = pci_resource_start (pdev, 1); + } + + SET_MODULE_OWNER(dev); ++ SET_NETDEV_DEV(dev, &pdev->dev); + + bp = dev->priv; + +- if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, dev->name)) { +- printk (KERN_ERR "%s: Cannot reserve I/O resource 0x%x @ 0x%lx, aborting\n", +- dev->name, PFI_K_CSR_IO_LEN, ioaddr); ++ if (bus_type == DFX_BUS_TYPE_TC) { ++ /* TURBOchannel board */ ++ bp->slot = handle; ++ claim_tc_card(bp->slot); ++ ioaddr = get_tc_base_addr(handle) + PI_TC_K_CSR_OFFSET; ++ len = PI_TC_K_CSR_LEN; ++ } else if (bus_type == DFX_BUS_TYPE_EISA) { ++ /* EISA board */ ++ ioaddr = handle; ++ len = PI_ESIC_K_CSR_IO_LEN; ++ } else ++ /* PCI board */ ++ len = PFI_K_CSR_IO_LEN; ++ dev->base_addr = ioaddr; /* save port (I/O) base address */ ++ ++ if (!request_region(ioaddr, len, print_name)) { ++ printk(KERN_ERR "%s: Cannot reserve I/O resource " ++ "0x%lx @ 0x%lx, aborting\n", print_name, len, ioaddr); + err = -EBUSY; + goto err_out; + } + + /* Initialize new device structure */ + +- dev->base_addr = ioaddr; /* save port (I/O) base address */ +- + dev->get_stats = dfx_ctl_get_stats; + dev->open = dfx_open; + dev->stop = dfx_close; +@@ -465,37 +524,54 @@ + dev->set_multicast_list = dfx_ctl_set_multicast_list; + dev->set_mac_address = dfx_ctl_set_mac_address; + +- if (pdev == NULL) { +- /* EISA board */ +- bp->bus_type = DFX_BUS_TYPE_EISA; ++ bp->bus_type = bus_type; ++ if (bus_type == DFX_BUS_TYPE_TC || bus_type == DFX_BUS_TYPE_EISA) { ++ /* TURBOchannel or EISA board */ + bp->next = root_dfx_eisa_dev; + root_dfx_eisa_dev = dev; + } else { + /* PCI board */ +- bp->bus_type = DFX_BUS_TYPE_PCI; + bp->pci_dev = pdev; + pci_set_drvdata (pdev, dev); + pci_set_master (pdev); + } + +- if (dfx_driver_init(dev) != DFX_K_SUCCESS) { ++ ++ if (dfx_driver_init(dev, print_name) != DFX_K_SUCCESS) { + err = -ENODEV; + goto err_out_region; + } + ++ err = register_netdev(dev); ++ if (err) ++ goto err_out_kfree; ++ ++ printk("%s: registered as %s\n", print_name, dev->name); + return 0; + ++err_out_kfree: ++ alloc_size = sizeof(PI_DESCR_BLOCK) + ++ PI_CMD_REQ_K_SIZE_MAX + PI_CMD_RSP_K_SIZE_MAX + ++#ifndef DYNAMIC_BUFFERS ++ (bp->rcv_bufs_to_post * PI_RCV_DATA_K_SIZE_MAX) + ++#endif ++ sizeof(PI_CONSUMER_BLOCK) + ++ (PI_ALIGN_K_DESC_BLK - 1); ++ if (bp->kmalloced) ++ pci_free_consistent(pdev, alloc_size, ++ bp->kmalloced, bp->kmalloced_dma); + err_out_region: +- release_region(ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN); ++ release_region(ioaddr, len); + err_out: +- unregister_netdev(dev); +- kfree(dev); ++ if (bp->bus_type == DFX_BUS_TYPE_TC) ++ release_tc_card(bp->slot); ++ free_netdev(dev); + return err; + } + + static int __devinit dfx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + { +- return dfx_init_one_pci_or_eisa(pdev, 0); ++ return dfx_init_one_pci_or_eisa(pdev, DFX_BUS_TYPE_PCI, 0); + } + + static int __init dfx_eisa_init(void) +@@ -507,6 +583,7 @@ + + DBG_printk("In dfx_eisa_init...\n"); + ++#ifdef CONFIG_EISA + /* Scan for FDDI EISA controllers */ + + for (i=0; i < DFX_MAX_EISA_SLOTS; i++) /* only scan for up to 16 EISA slots */ +@@ -517,9 +594,27 @@ + { + port = (i << 12); /* recalc base addr */ + +- if (dfx_init_one_pci_or_eisa(NULL, port) == 0) rc = 0; ++ if (dfx_init_one_pci_or_eisa(NULL, DFX_BUS_TYPE_EISA, port) == 0) rc = 0; + } + } ++#endif ++ return rc; ++} ++ ++static int __init dfx_tc_init(void) ++{ ++ int rc = -ENODEV; ++ int slot; /* TC slot number */ ++ ++ DBG_printk("In dfx_tc_init...\n"); ++ ++ /* Scan for FDDI TC controllers */ ++ while ((slot = search_tc_card("PMAF-F")) >= 0) { ++ if (dfx_init_one_pci_or_eisa(NULL, DFX_BUS_TYPE_TC, slot) == 0) ++ rc = 0; ++ else ++ break; ++ } + return rc; + } + +@@ -583,8 +678,9 @@ + + /* Initialize adapter based on bus type */ + +- if (bp->bus_type == DFX_BUS_TYPE_EISA) +- { ++ if (bp->bus_type == DFX_BUS_TYPE_TC) { ++ dev->irq = get_tc_irq_nr(bp->slot); ++ } else if (bp->bus_type == DFX_BUS_TYPE_EISA) { + /* Get the interrupt level from the ESIC chip */ + + dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &val); +@@ -766,6 +862,7 @@ + * + * Arguments: + * dev - pointer to device information ++ * print_name - printable device name + * + * Functional Description: + * This function allocates additional resources such as the host memory +@@ -780,20 +877,21 @@ + * or read adapter MAC address + * + * Assumptions: +- * Memory allocated from kmalloc() call is physically contiguous, locked +- * memory whose physical address equals its virtual address. ++ * Memory allocated from pci_alloc_consistent() call is physically ++ * contiguous, locked memory. + * + * Side Effects: + * Adapter is reset and should be in DMA_UNAVAILABLE state before + * returning from this routine. + */ + +-static int __devinit dfx_driver_init(struct net_device *dev) ++static int __devinit dfx_driver_init(struct net_device *dev, ++ const char *print_name) + { + DFX_board_t *bp = dev->priv; + int alloc_size; /* total buffer size needed */ + char *top_v, *curr_v; /* virtual addrs into memory block */ +- u32 top_p, curr_p; /* physical addrs into memory block */ ++ dma_addr_t top_p, curr_p; /* physical addrs into memory block */ + u32 data; /* host data register value */ + + DBG_printk("In dfx_driver_init...\n"); +@@ -837,26 +935,20 @@ + + /* Read the factory MAC address from the adapter then save it */ + +- if (dfx_hw_port_ctrl_req(bp, +- PI_PCTRL_M_MLA, +- PI_PDATA_A_MLA_K_LO, +- 0, +- &data) != DFX_K_SUCCESS) +- { +- printk("%s: Could not read adapter factory MAC address!\n", dev->name); ++ if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_LO, 0, ++ &data) != DFX_K_SUCCESS) { ++ printk("%s: Could not read adapter factory MAC address!\n", ++ print_name); + return(DFX_K_FAILURE); +- } ++ } + memcpy(&bp->factory_mac_addr[0], &data, sizeof(u32)); + +- if (dfx_hw_port_ctrl_req(bp, +- PI_PCTRL_M_MLA, +- PI_PDATA_A_MLA_K_HI, +- 0, +- &data) != DFX_K_SUCCESS) +- { +- printk("%s: Could not read adapter factory MAC address!\n", dev->name); ++ if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_HI, 0, ++ &data) != DFX_K_SUCCESS) { ++ printk("%s: Could not read adapter factory MAC address!\n", ++ print_name); + return(DFX_K_FAILURE); +- } ++ } + memcpy(&bp->factory_mac_addr[4], &data, sizeof(u16)); + + /* +@@ -867,28 +959,27 @@ + */ + + memcpy(dev->dev_addr, bp->factory_mac_addr, FDDI_K_ALEN); +- if (bp->bus_type == DFX_BUS_TYPE_EISA) +- printk("%s: DEFEA at I/O addr = 0x%lX, IRQ = %d, Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", +- dev->name, +- dev->base_addr, +- dev->irq, +- dev->dev_addr[0], +- dev->dev_addr[1], +- dev->dev_addr[2], +- dev->dev_addr[3], +- dev->dev_addr[4], +- dev->dev_addr[5]); ++ if (bp->bus_type == DFX_BUS_TYPE_TC) ++ printk("%s: DEFTA at addr = 0x%lX, IRQ = %d, " ++ "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", ++ print_name, dev->base_addr, dev->irq, ++ dev->dev_addr[0], dev->dev_addr[1], ++ dev->dev_addr[2], dev->dev_addr[3], ++ dev->dev_addr[4], dev->dev_addr[5]); ++ else if (bp->bus_type == DFX_BUS_TYPE_EISA) ++ printk("%s: DEFEA at I/O addr = 0x%lX, IRQ = %d, " ++ "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", ++ print_name, dev->base_addr, dev->irq, ++ dev->dev_addr[0], dev->dev_addr[1], ++ dev->dev_addr[2], dev->dev_addr[3], ++ dev->dev_addr[4], dev->dev_addr[5]); + else +- printk("%s: DEFPA at I/O addr = 0x%lX, IRQ = %d, Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", +- dev->name, +- dev->base_addr, +- dev->irq, +- dev->dev_addr[0], +- dev->dev_addr[1], +- dev->dev_addr[2], +- dev->dev_addr[3], +- dev->dev_addr[4], +- dev->dev_addr[5]); ++ printk("%s: DEFPA at I/O addr = 0x%lX, IRQ = %d, " ++ "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", ++ print_name, dev->base_addr, dev->irq, ++ dev->dev_addr[0], dev->dev_addr[1], ++ dev->dev_addr[2], dev->dev_addr[3], ++ dev->dev_addr[4], dev->dev_addr[5]); + + /* + * Get memory for descriptor block, consumer block, and other buffers +@@ -903,14 +994,15 @@ + #endif + sizeof(PI_CONSUMER_BLOCK) + + (PI_ALIGN_K_DESC_BLK - 1); +- bp->kmalloced = top_v = (char *) kmalloc(alloc_size, GFP_KERNEL); +- if (top_v == NULL) +- { +- printk("%s: Could not allocate memory for host buffers and structures!\n", dev->name); ++ bp->kmalloced = top_v = pci_alloc_consistent(bp->pci_dev, alloc_size, ++ &bp->kmalloced_dma); ++ if (top_v == NULL) { ++ printk("%s: Could not allocate memory for host buffers " ++ "and structures!\n", print_name); + return(DFX_K_FAILURE); +- } ++ } + memset(top_v, 0, alloc_size); /* zero out memory before continuing */ +- top_p = virt_to_bus(top_v); /* get physical address of buffer */ ++ top_p = bp->kmalloced_dma; /* get physical address of buffer */ + + /* + * To guarantee the 8K alignment required for the descriptor block, 8K - 1 +@@ -924,7 +1016,7 @@ + * for allocating the needed memory. + */ + +- curr_p = (u32) (ALIGN(top_p, PI_ALIGN_K_DESC_BLK)); ++ curr_p = ALIGN(top_p, PI_ALIGN_K_DESC_BLK); + curr_v = top_v + (curr_p - top_p); + + /* Reserve space for descriptor block */ +@@ -965,14 +1057,20 @@ + + /* Display virtual and physical addresses if debug driver */ + +- DBG_printk("%s: Descriptor block virt = %0lX, phys = %0X\n", dev->name, (long)bp->descr_block_virt, bp->descr_block_phys); +- DBG_printk("%s: Command Request buffer virt = %0lX, phys = %0X\n", dev->name, (long)bp->cmd_req_virt, bp->cmd_req_phys); +- DBG_printk("%s: Command Response buffer virt = %0lX, phys = %0X\n", dev->name, (long)bp->cmd_rsp_virt, bp->cmd_rsp_phys); +- DBG_printk("%s: Receive buffer block virt = %0lX, phys = %0X\n", dev->name, (long)bp->rcv_block_virt, bp->rcv_block_phys); +- DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n", dev->name, (long)bp->cons_block_virt, bp->cons_block_phys); ++ DBG_printk("%s: Descriptor block virt = %0lX, phys = %0X\n", ++ print_name, ++ (long)bp->descr_block_virt, bp->descr_block_phys); ++ DBG_printk("%s: Command Request buffer virt = %0lX, phys = %0X\n", ++ print_name, (long)bp->cmd_req_virt, bp->cmd_req_phys); ++ DBG_printk("%s: Command Response buffer virt = %0lX, phys = %0X\n", ++ print_name, (long)bp->cmd_rsp_virt, bp->cmd_rsp_phys); ++ DBG_printk("%s: Receive buffer block virt = %0lX, phys = %0X\n", ++ print_name, (long)bp->rcv_block_virt, bp->rcv_block_phys); ++ DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n", ++ print_name, (long)bp->cons_block_virt, bp->cons_block_phys); + + return(DFX_K_SUCCESS); +- } ++} + + + /* +@@ -1218,7 +1316,9 @@ + + /* Register IRQ - support shared interrupts by passing device ptr */ + +- ret = request_irq(dev->irq, (void *)dfx_interrupt, SA_SHIRQ, dev->name, dev); ++ ret = request_irq(dev->irq, (void *)dfx_interrupt, ++ (bp->bus_type == DFX_BUS_TYPE_TC) ? 0 : SA_SHIRQ, ++ dev->name, dev); + if (ret) { + printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq); + return ret; +@@ -1737,7 +1837,7 @@ + dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, + (PFI_MODE_M_PDQ_INT_ENB + PFI_MODE_M_DMA_ENB)); + } +- else ++ else if (bp->bus_type == DFX_BUS_TYPE_EISA) + { + /* Disable interrupts at the ESIC */ + +@@ -1755,6 +1855,13 @@ + tmp |= PI_CONFIG_STAT_0_M_INT_ENB; + dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp); + } ++ else { ++ /* TC doesn't share interrupts so no need to disable them */ ++ ++ /* Call interrupt service routine for this adapter */ ++ ++ dfx_int_common(dev); ++ } + + spin_unlock(&bp->lock); + } +@@ -2663,12 +2770,12 @@ + + static void my_skb_align(struct sk_buff *skb, int n) + { +- u32 x=(u32)skb->data; /* We only want the low bits .. */ +- u32 v; ++ unsigned long x = (unsigned long)skb->data; ++ unsigned long v; + +- v=(x+n-1)&~(n-1); /* Where we want to be */ ++ v = ALIGN(x, n); /* Where we want to be */ + +- skb_reserve(skb, v-x); ++ skb_reserve(skb, v - x); + } + + +@@ -2745,7 +2852,10 @@ + */ + + my_skb_align(newskb, 128); +- bp->descr_block_virt->rcv_data[i+j].long_1 = virt_to_bus(newskb->data); ++ bp->descr_block_virt->rcv_data[i + j].long_1 = ++ (u32)pci_map_single(bp->pci_dev, newskb->data, ++ NEW_SKB_SIZE, ++ PCI_DMA_FROMDEVICE); + /* + * p_rcv_buff_va is only used inside the + * kernel so we put the skb pointer here. +@@ -2859,9 +2969,17 @@ + + my_skb_align(newskb, 128); + skb = (struct sk_buff *)bp->p_rcv_buff_va[entry]; ++ pci_unmap_single(bp->pci_dev, ++ bp->descr_block_virt->rcv_data[entry].long_1, ++ NEW_SKB_SIZE, ++ PCI_DMA_FROMDEVICE); + skb_reserve(skb, RCV_BUFF_K_PADDING); + bp->p_rcv_buff_va[entry] = (char *)newskb; +- bp->descr_block_virt->rcv_data[entry].long_1 = virt_to_bus(newskb->data); ++ bp->descr_block_virt->rcv_data[entry].long_1 = ++ (u32)pci_map_single(bp->pci_dev, ++ newskb->data, ++ NEW_SKB_SIZE, ++ PCI_DMA_FROMDEVICE); + } else + skb = NULL; + } else +@@ -2934,7 +3052,7 @@ + * is contained in a single physically contiguous buffer + * in which the virtual address of the start of packet + * (skb->data) can be converted to a physical address +- * by using virt_to_bus(). ++ * by using pci_map_single(). + * + * Since the adapter architecture requires a three byte + * packet request header to prepend the start of packet, +@@ -3082,12 +3200,13 @@ + * skb->data. + * 6. The physical address of the start of packet + * can be determined from the virtual address +- * by using virt_to_bus() and is only 32-bits ++ * by using pci_map_single() and is only 32-bits + * wide. + */ + + p_xmt_descr->long_0 = (u32) (PI_XMT_DESCR_M_SOP | PI_XMT_DESCR_M_EOP | ((skb->len) << PI_XMT_DESCR_V_SEG_LEN)); +- p_xmt_descr->long_1 = (u32) virt_to_bus(skb->data); ++ p_xmt_descr->long_1 = (u32)pci_map_single(bp->pci_dev, skb->data, ++ skb->len, PCI_DMA_TODEVICE); + + /* + * Verify that descriptor is actually available +@@ -3171,6 +3290,7 @@ + { + XMT_DRIVER_DESCR *p_xmt_drv_descr; /* ptr to transmit driver descriptor */ + PI_TYPE_2_CONSUMER *p_type_2_cons; /* ptr to rcv/xmt consumer block register */ ++ u8 comp; /* local transmit completion index */ + int freed = 0; /* buffers freed */ + + /* Service all consumed transmit frames */ +@@ -3188,7 +3308,11 @@ + bp->xmt_total_bytes += p_xmt_drv_descr->p_skb->len; + + /* Return skb to operating system */ +- ++ comp = bp->rcv_xmt_reg.index.xmt_comp; ++ pci_unmap_single(bp->pci_dev, ++ bp->descr_block_virt->xmt_data[comp].long_1, ++ p_xmt_drv_descr->p_skb->len, ++ PCI_DMA_TODEVICE); + dev_kfree_skb_irq(p_xmt_drv_descr->p_skb); + + /* +@@ -3297,6 +3421,7 @@ + { + u32 prod_cons; /* rcv/xmt consumer block longword */ + XMT_DRIVER_DESCR *p_xmt_drv_descr; /* ptr to transmit driver descriptor */ ++ u8 comp; /* local transmit completion index */ + + /* Flush all outstanding transmit frames */ + +@@ -3307,7 +3432,11 @@ + p_xmt_drv_descr = &(bp->xmt_drv_descr_blk[bp->rcv_xmt_reg.index.xmt_comp]); + + /* Return skb to operating system */ +- ++ comp = bp->rcv_xmt_reg.index.xmt_comp; ++ pci_unmap_single(bp->pci_dev, ++ bp->descr_block_virt->xmt_data[comp].long_1, ++ p_xmt_drv_descr->p_skb->len, ++ PCI_DMA_TODEVICE); + dev_kfree_skb(p_xmt_drv_descr->p_skb); + + /* Increment transmit error counter */ +@@ -3337,12 +3466,36 @@ + + static void __devexit dfx_remove_one_pci_or_eisa(struct pci_dev *pdev, struct net_device *dev) + { +- DFX_board_t *bp = dev->priv; ++ DFX_board_t *bp = dev->priv; ++ unsigned long len; /* resource length */ ++ int alloc_size; /* total buffer size used */ + ++ if (bp->bus_type == DFX_BUS_TYPE_TC) { ++ /* TURBOchannel board */ ++ len = PI_TC_K_CSR_LEN; ++ } else if (bp->bus_type == DFX_BUS_TYPE_EISA) { ++ /* EISA board */ ++ len = PI_ESIC_K_CSR_IO_LEN; ++ } else { ++ len = PFI_K_CSR_IO_LEN; ++ } + unregister_netdev(dev); +- release_region(dev->base_addr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN ); +- if (bp->kmalloced) kfree(bp->kmalloced); +- kfree(dev); ++ release_region(dev->base_addr, len); ++ ++ if (bp->bus_type == DFX_BUS_TYPE_TC) ++ release_tc_card(bp->slot); ++ ++ alloc_size = sizeof(PI_DESCR_BLOCK) + ++ PI_CMD_REQ_K_SIZE_MAX + PI_CMD_RSP_K_SIZE_MAX + ++#ifndef DYNAMIC_BUFFERS ++ (bp->rcv_bufs_to_post * PI_RCV_DATA_K_SIZE_MAX) + ++#endif ++ sizeof(PI_CONSUMER_BLOCK) + ++ (PI_ALIGN_K_DESC_BLK - 1); ++ if (bp->kmalloced) ++ pci_free_consistent(pdev, alloc_size, bp->kmalloced, ++ bp->kmalloced_dma); ++ free_netdev(dev); + } + + static void __devexit dfx_remove_one (struct pci_dev *pdev) +@@ -3353,21 +3506,22 @@ + pci_set_drvdata(pdev, NULL); + } + +-static struct pci_device_id dfx_pci_tbl[] __devinitdata = { ++static struct pci_device_id dfx_pci_tbl[] = { + { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_FDDI, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, } + }; + MODULE_DEVICE_TABLE(pci, dfx_pci_tbl); + + static struct pci_driver dfx_driver = { +- name: "defxx", +- probe: dfx_init_one, +- remove: __devexit_p(dfx_remove_one), +- id_table: dfx_pci_tbl, ++ .name = "defxx", ++ .probe = dfx_init_one, ++ .remove = __devexit_p(dfx_remove_one), ++ .id_table = dfx_pci_tbl, + }; + + static int dfx_have_pci; + static int dfx_have_eisa; ++static int dfx_have_tc; + + + static void __exit dfx_eisa_cleanup(void) +@@ -3388,12 +3542,7 @@ + + static int __init dfx_init(void) + { +- int rc_pci, rc_eisa; +- +-/* when a module, this is printed whether or not devices are found in probe */ +-#ifdef MODULE +- printk(version); +-#endif ++ int rc_pci, rc_eisa, rc_tc; + + rc_pci = pci_module_init(&dfx_driver); + if (rc_pci >= 0) dfx_have_pci = 1; +@@ -3401,20 +3550,27 @@ + rc_eisa = dfx_eisa_init(); + if (rc_eisa >= 0) dfx_have_eisa = 1; + +- return ((rc_eisa < 0) ? 0 : rc_eisa) + ((rc_pci < 0) ? 0 : rc_pci); ++ rc_tc = dfx_tc_init(); ++ if (rc_tc >= 0) dfx_have_tc = 1; ++ ++ return ((rc_tc < 0) ? 0 : rc_tc) + ++ ((rc_eisa < 0) ? 0 : rc_eisa) + ++ ((rc_pci < 0) ? 0 : rc_pci); + } + + static void __exit dfx_cleanup(void) + { + if (dfx_have_pci) + pci_unregister_driver(&dfx_driver); +- if (dfx_have_eisa) ++ if (dfx_have_eisa || dfx_have_tc) + dfx_eisa_cleanup(); +- + } + + module_init(dfx_init); + module_exit(dfx_cleanup); ++MODULE_AUTHOR("Lawrence V. Stefani"); ++MODULE_DESCRIPTION("DEC FDDIcontroller EISA/PCI (DEFEA/DEFPA) driver " ++ DRV_VERSION " " DRV_RELDATE); + MODULE_LICENSE("GPL"); + + +diff -Nur linux-2.4.32-rc1/drivers/net/defxx.h linux-2.4.32-rc1.mips/drivers/net/defxx.h +--- linux-2.4.32-rc1/drivers/net/defxx.h 2001-02-13 22:15:05.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/net/defxx.h 2004-10-03 20:06:48.000000000 +0200 +@@ -12,17 +12,11 @@ + * Contains all definitions specified by port specification and required + * by the defxx.c driver. + * +- * Maintainers: +- * LVS Lawrence V. Stefani +- * +- * Contact: +- * The author may be reached at: ++ * The original author: ++ * LVS Lawrence V. Stefani + * +- * Inet: stefani@lkg.dec.com +- * Mail: Digital Equipment Corporation +- * 550 King Street +- * M/S: LKG1-3/M07 +- * Littleton, MA 01460 ++ * Maintainers: ++ * macro Maciej W. Rozycki + * + * Modification History: + * Date Name Description +@@ -30,6 +24,7 @@ + * 09-Sep-96 LVS Added group_prom field. Moved read/write I/O + * macros to DEFXX.C. + * 12-Sep-96 LVS Removed packet request header pointers. ++ * 04 Aug 2003 macro Converted to the DMA API. + */ + + #ifndef _DEFXX_H_ +@@ -1467,6 +1462,11 @@ + + #endif /* #ifndef BIG_ENDIAN */ + ++/* Define TC PDQ CSR offset and length */ ++ ++#define PI_TC_K_CSR_OFFSET 0x100000 ++#define PI_TC_K_CSR_LEN 0x80 /* 128 bytes */ ++ + /* Define EISA controller register offsets */ + + #define PI_ESIC_K_BURST_HOLDOFF 0x040 +@@ -1634,6 +1634,7 @@ + + #define DFX_BUS_TYPE_PCI 0 /* type code for DEC FDDIcontroller/PCI */ + #define DFX_BUS_TYPE_EISA 1 /* type code for DEC FDDIcontroller/EISA */ ++#define DFX_BUS_TYPE_TC 2 /* type code for DEC FDDIcontroller/TURBOchannel */ + + #define DFX_FC_PRH2_PRH1_PRH0 0x54003820 /* Packet Request Header bytes + FC */ + #define DFX_PRH0_BYTE 0x20 /* Packet Request Header byte 0 */ +@@ -1704,17 +1705,19 @@ + { + /* Keep virtual and physical pointers to locked, physically contiguous memory */ + +- char *kmalloced; /* kfree this on unload */ ++ char *kmalloced; /* pci_free_consistent this on unload */ ++ dma_addr_t kmalloced_dma; ++ /* DMA handle for the above */ + PI_DESCR_BLOCK *descr_block_virt; /* PDQ descriptor block virt address */ +- u32 descr_block_phys; /* PDQ descriptor block phys address */ ++ dma_addr_t descr_block_phys; /* PDQ descriptor block phys address */ + PI_DMA_CMD_REQ *cmd_req_virt; /* Command request buffer virt address */ +- u32 cmd_req_phys; /* Command request buffer phys address */ ++ dma_addr_t cmd_req_phys; /* Command request buffer phys address */ + PI_DMA_CMD_RSP *cmd_rsp_virt; /* Command response buffer virt address */ +- u32 cmd_rsp_phys; /* Command response buffer phys address */ ++ dma_addr_t cmd_rsp_phys; /* Command response buffer phys address */ + char *rcv_block_virt; /* LLC host receive queue buf blk virt */ +- u32 rcv_block_phys; /* LLC host receive queue buf blk phys */ ++ dma_addr_t rcv_block_phys; /* LLC host receive queue buf blk phys */ + PI_CONSUMER_BLOCK *cons_block_virt; /* PDQ consumer block virt address */ +- u32 cons_block_phys; /* PDQ consumer block phys address */ ++ dma_addr_t cons_block_phys; /* PDQ consumer block phys address */ + + /* Keep local copies of Type 1 and Type 2 register data */ + +@@ -1758,8 +1761,9 @@ + + struct net_device *dev; /* pointer to device structure */ + struct net_device *next; +- u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */ +- u16 base_addr; /* base I/O address (same as dev->base_addr) */ ++ u32 bus_type; /* bus type (0 == PCI, 1 == EISA, 2 == TC) */ ++ long base_addr; /* base I/O address (same as dev->base_addr) */ ++ int slot; /* TC slot number */ + struct pci_dev * pci_dev; + u32 full_duplex_enb; /* FDDI Full Duplex enable (1 == on, 2 == off) */ + u32 req_ttrt; /* requested TTRT value (in 80ns units) */ +diff -Nur linux-2.4.32-rc1/drivers/net/hamradio/hdlcdrv.c linux-2.4.32-rc1.mips/drivers/net/hamradio/hdlcdrv.c +--- linux-2.4.32-rc1/drivers/net/hamradio/hdlcdrv.c 2002-02-25 20:37:59.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/net/hamradio/hdlcdrv.c 2004-05-04 14:04:27.000000000 +0200 +@@ -587,6 +587,8 @@ + return -EINVAL; + s = (struct hdlcdrv_state *)dev->priv; + ++ netif_stop_queue(dev); ++ + if (s->ops && s->ops->close) + i = s->ops->close(dev); + if (s->skb) +diff -Nur linux-2.4.32-rc1/drivers/net/irda/au1k_ir.c linux-2.4.32-rc1.mips/drivers/net/irda/au1k_ir.c +--- linux-2.4.32-rc1/drivers/net/irda/au1k_ir.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/net/irda/au1k_ir.c 2005-02-03 07:35:29.000000000 +0100 +@@ -81,10 +81,6 @@ + + #define RUN_AT(x) (jiffies + (x)) + +-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) +-static BCSR * const bcsr = (BCSR *)0xAE000000; +-#endif +- + static spinlock_t ir_lock = SPIN_LOCK_UNLOCKED; + + /* +diff -Nur linux-2.4.32-rc1/drivers/net/sgiseeq.c linux-2.4.32-rc1.mips/drivers/net/sgiseeq.c +--- linux-2.4.32-rc1/drivers/net/sgiseeq.c 2005-01-19 15:09:56.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/net/sgiseeq.c 2005-09-23 16:35:27.000000000 +0200 +@@ -24,16 +24,16 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include + + #include "sgiseeq.h" + +-static char *version = "sgiseeq.c: David S. Miller (dm@engr.sgi.com)\n"; +- + static char *sgiseeqstr = "SGI Seeq8003"; + + /* +@@ -113,9 +113,9 @@ + + static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) + { +- hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ; ++ hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ; + udelay(20); +- hregs->rx_reset = 0; ++ hregs->reset = 0; + } + + static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs, +@@ -238,7 +238,6 @@ + + #define TSTAT_INIT_SEEQ (SEEQ_TCMD_IPT|SEEQ_TCMD_I16|SEEQ_TCMD_IC|SEEQ_TCMD_IUF) + #define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2) +-#define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ) + + static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp, + struct sgiseeq_regs *sregs) +@@ -260,8 +259,6 @@ + sregs->tstat = TSTAT_INIT_SEEQ; + } + +- hregs->rx_dconfig |= RDMACFG_INIT; +- + hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[0]); + hregs->tx_ndptr = PHYSADDR(&sp->srings.tx_desc[0]); + +@@ -432,7 +429,7 @@ + spin_lock(&sp->tx_lock); + + /* Ack the IRQ and set software state. */ +- hregs->rx_reset = HPC3_ERXRST_CLRIRQ; ++ hregs->reset = HPC3_ERST_CLRIRQ; + + /* Always check for received packets. */ + sgiseeq_rx(dev, sp, hregs, sregs); +@@ -616,7 +613,7 @@ + + #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) + +-int sgiseeq_init(struct hpc3_regs* regs, int irq) ++int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) + { + struct net_device *dev; + struct sgiseeq_private *sp; +@@ -629,7 +626,7 @@ + goto err_out; + } + /* Make private data page aligned */ +- sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); ++ sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); + if (!sp) { + printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n"); + err = -ENOMEM; +@@ -644,7 +641,9 @@ + + #define EADDR_NVOFS 250 + for (i = 0; i < 3; i++) { +- unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); ++ unsigned short tmp = has_eeprom ? ++ ip22_eeprom_read(&hpcregs->eeprom, EADDR_NVOFS / 2+i) : ++ ip22_nvram_read(EADDR_NVOFS / 2+i); + + dev->dev_addr[2 * i] = tmp >> 8; + dev->dev_addr[2 * i + 1] = tmp & 0xff; +@@ -654,8 +653,8 @@ + gpriv = sp; + gdev = dev; + #endif +- sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0]; +- sp->hregs = &hpc3c0->ethregs; ++ sp->sregs = (struct sgiseeq_regs *) &hpcregs->eth_ext[0]; ++ sp->hregs = &hpcregs->ethregs; + sp->name = sgiseeqstr; + sp->mode = SEEQ_RCMD_RBCAST; + +@@ -672,6 +671,11 @@ + setup_rx_ring(sp->srings.rx_desc, SEEQ_RX_BUFFERS); + setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS); + ++ /* Setup PIO and DMA transfer timing */ ++ sp->hregs->pconfig = 0x161; ++ sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP | ++ HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026; ++ + /* Reset the chip. */ + hpc3_eth_reset(sp->hregs); + +@@ -699,7 +703,7 @@ + goto err_out_free_irq; + } + +- printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name); ++ printk(KERN_INFO "%s: %s ", dev->name, sgiseeqstr); + for (i = 0; i < 6; i++) + printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + +@@ -721,10 +725,22 @@ + + static int __init sgiseeq_probe(void) + { +- printk(version); ++ unsigned int tmp, ret1, ret2 = 0; + + /* On board adapter on 1st HPC is always present */ +- return sgiseeq_init(hpc3c0, SGI_ENET_IRQ); ++ ret1 = sgiseeq_init(hpc3c0, SGI_ENET_IRQ, 0); ++ /* Let's see if second HPC is there */ ++ if (!(ip22_is_fullhouse()) && ++ get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]) == 0) { ++ sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | ++ SGIMC_GIOPAR_EXP164 | ++ SGIMC_GIOPAR_HPC264; ++ hpc3c1->pbus_piocfg[0][0] = 0x3ffff; ++ /* interrupt/config register on Challenge S Mezz board */ ++ hpc3c1->pbus_extregs[0][0] = 0x30; ++ ret2 = sgiseeq_init(hpc3c1, SGI_GIO_0_IRQ, 1); ++ } ++ return (ret1 & ret2) ? ret1 : 0; + } + + static void __exit sgiseeq_exit(void) +@@ -747,4 +763,6 @@ + module_init(sgiseeq_probe); + module_exit(sgiseeq_exit); + ++MODULE_DESCRIPTION("SGI Seeq 8003 driver"); ++MODULE_AUTHOR("David S. Miller"); + MODULE_LICENSE("GPL"); +diff -Nur linux-2.4.32-rc1/drivers/pci/pci.c linux-2.4.32-rc1.mips/drivers/pci/pci.c +--- linux-2.4.32-rc1/drivers/pci/pci.c 2004-11-17 12:54:21.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/pci/pci.c 2004-11-19 01:28:41.000000000 +0100 +@@ -1281,11 +1281,17 @@ + { + unsigned int buses; + unsigned short cr; ++ unsigned short bctl; + struct pci_bus *child; + int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); + + pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); + DBG("Scanning behind PCI bridge %s, config %06x, pass %d\n", dev->slot_name, buses & 0xffffff, pass); ++ /* Disable MasterAbortMode during probing to avoid reporting ++ of bus errors (in some architectures) */ ++ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl); ++ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ++ bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); + if ((buses & 0xffff00) && !pcibios_assign_all_busses()) { + /* + * Bus already configured by firmware, process it in the first +@@ -1351,6 +1357,7 @@ + pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); + pci_write_config_word(dev, PCI_COMMAND, cr); + } ++ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl); + sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); + return max; + } +diff -Nur linux-2.4.32-rc1/drivers/pcmcia/au1000_db1x00.c linux-2.4.32-rc1.mips/drivers/pcmcia/au1000_db1x00.c +--- linux-2.4.32-rc1/drivers/pcmcia/au1000_db1x00.c 2005-01-19 15:09:57.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/pcmcia/au1000_db1x00.c 2005-02-03 07:35:30.000000000 +0100 +@@ -1,6 +1,6 @@ + /* + * +- * Alchemy Semi Db1x00 boards specific pcmcia routines. ++ * AMD Alchemy DUAL-SLOT Db1x00 boards' specific pcmcia routines. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. +@@ -54,9 +54,20 @@ + #include + #include + ++#if defined(CONFIG_MIPS_PB1200) ++#include ++#elif defined(CONFIG_MIPS_DB1200) ++#include ++#else + #include ++#endif + +-static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; ++#define PCMCIA_MAX_SOCK 1 ++#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) ++ ++/* VPP/VCC */ ++#define SET_VCC_VPP(VCC, VPP, SLOT)\ ++ ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) + + static int db1x00_pcmcia_init(struct pcmcia_init *init) + { +@@ -76,7 +87,7 @@ + db1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) + { + u32 inserted; +- unsigned char vs; ++ u16 vs; + + if(sock > PCMCIA_MAX_SOCK) return -1; + +@@ -87,11 +98,11 @@ + + if (sock == 0) { + vs = bcsr->status & 0x3; +- inserted = !(bcsr->status & (1<<4)); ++ inserted = BOARD_CARD_INSERTED(0); + } + else { + vs = (bcsr->status & 0xC)>>2; +- inserted = !(bcsr->status & (1<<5)); ++ inserted = BOARD_CARD_INSERTED(1); + } + + DEBUG(KERN_DEBUG "db1x00 socket %d: inserted %d, vs %d\n", +@@ -144,16 +155,9 @@ + if(info->sock > PCMCIA_MAX_SOCK) return -1; + + if(info->sock == 0) +-#ifdef CONFIG_MIPS_DB1550 +- info->irq = AU1000_GPIO_3; ++ info->irq = BOARD_PC0_INT; + else +- info->irq = AU1000_GPIO_5; +-#else +- info->irq = AU1000_GPIO_2; +- else +- info->irq = AU1000_GPIO_5; +-#endif +- ++ info->irq = BOARD_PC1_INT; + return 0; + } + +diff -Nur linux-2.4.32-rc1/drivers/pcmcia/Config.in linux-2.4.32-rc1.mips/drivers/pcmcia/Config.in +--- linux-2.4.32-rc1/drivers/pcmcia/Config.in 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/pcmcia/Config.in 2004-02-22 06:21:34.000000000 +0100 +@@ -30,16 +30,14 @@ + dep_tristate ' M8xx support' CONFIG_PCMCIA_M8XX $CONFIG_PCMCIA + fi + if [ "$CONFIG_SOC_AU1X00" = "y" ]; then +- dep_tristate ' Au1x00 PCMCIA support' CONFIG_PCMCIA_AU1X00 $CONFIG_PCMCIA +- if [ "$CONFIG_PCMCIA_AU1X00" != "n" ]; then +- bool ' Pb1x00 board support' CONFIG_PCMCIA_PB1X00 +- bool ' Db1x00 board support' CONFIG_PCMCIA_DB1X00 +- bool ' XXS1500 board support' CONFIG_PCMCIA_XXS1500 +- fi ++ dep_tristate ' Au1x00 PCMCIA support' CONFIG_PCMCIA_AU1X00 $CONFIG_PCMCIA + fi + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + dep_bool ' SiByte PCMCIA support' CONFIG_PCMCIA_SIBYTE $CONFIG_PCMCIA $CONFIG_BLK_DEV_IDE_SIBYTE + fi ++ if [ "$CONFIG_VRC4171" = "y" -o "$CONFIG_VRC4171" = "m" ]; then ++ dep_tristate ' NEC VRC4171 Card Controllers support' CONFIG_PCMCIA_VRC4171 $CONFIG_PCMCIA ++ fi + if [ "$CONFIG_VRC4173" = "y" -o "$CONFIG_VRC4173" = "m" ]; then + dep_tristate ' NEC VRC4173 CARDU support' CONFIG_PCMCIA_VRC4173 $CONFIG_PCMCIA + fi +diff -Nur linux-2.4.32-rc1/drivers/pcmcia/Makefile linux-2.4.32-rc1.mips/drivers/pcmcia/Makefile +--- linux-2.4.32-rc1/drivers/pcmcia/Makefile 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/pcmcia/Makefile 2005-02-03 07:35:30.000000000 +0100 +@@ -61,9 +61,18 @@ + + obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o + au1000_ss-objs-y := au1000_generic.o +-au1000_ss-objs-$(CONFIG_PCMCIA_PB1X00) += au1000_pb1x00.o +-au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o +-au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o ++au1000_ss-objs-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_PB1550) += au1000_pb1550.o ++au1000_ss-objs-$(CONFIG_MIPS_PB1200) += au1000_db1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o ++au1000_ss-objs-$(CONFIG_MIPS_HYDROGEN3) += au1000_hydrogen3.o ++au1000_ss-objs-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o + + obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o + obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o +@@ -89,6 +98,7 @@ + sa1100_cs-objs-$(CONFIG_SA1100_XP860) += sa1100_xp860.o sa1111_generic.o + sa1100_cs-objs-$(CONFIG_SA1100_YOPY) += sa1100_yopy.o + ++obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o + obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o + + include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32-rc1/drivers/pcmcia/vrc4171_card.c linux-2.4.32-rc1.mips/drivers/pcmcia/vrc4171_card.c +--- linux-2.4.32-rc1/drivers/pcmcia/vrc4171_card.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/pcmcia/vrc4171_card.c 2004-01-19 16:54:58.000000000 +0100 +@@ -0,0 +1,886 @@ ++/* ++ * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services. ++ * ++ * Copyright (C) 2003 Yoichi Yuasa ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#include "i82365.h" ++ ++MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services"); ++MODULE_AUTHOR("Yoichi Yuasa "); ++MODULE_LICENSE("GPL"); ++ ++#define CARD_MAX_SLOTS 2 ++#define CARD_SLOTA 0 ++#define CARD_SLOTB 1 ++#define CARD_SLOTB_OFFSET 0x40 ++ ++#define CARD_MEM_START 0x10000000 ++#define CARD_MEM_END 0x13ffffff ++#define CARD_MAX_MEM_OFFSET 0x3ffffff ++#define CARD_MAX_MEM_SPEED 1000 ++ ++#define CARD_CONTROLLER_INDEX 0x03e0 ++#define CARD_CONTROLLER_DATA 0x03e1 ++#define CARD_CONTROLLER_SIZE 2 ++ /* Power register */ ++ #define VPP_GET_VCC 0x01 ++ #define POWER_ENABLE 0x10 ++ #define CARD_VOLTAGE_SENSE 0x1f ++ #define VCC_3VORXV_CAPABLE 0x00 ++ #define VCC_XV_ONLY 0x01 ++ #define VCC_3V_CAPABLE 0x02 ++ #define VCC_5V_ONLY 0x03 ++ #define CARD_VOLTAGE_SELECT 0x2f ++ #define VCC_3V 0x01 ++ #define VCC_5V 0x00 ++ #define VCC_XV 0x02 ++ #define VCC_STATUS_3V 0x02 ++ #define VCC_STATUS_5V 0x01 ++ #define VCC_STATUS_XV 0x03 ++ #define GLOBAL_CONTROL 0x1e ++ #define EXWRBK 0x04 ++ #define IRQPM_EN 0x08 ++ #define CLRPMIRQ 0x10 ++ ++#define IO_MAX_MAPS 2 ++#define MEM_MAX_MAPS 5 ++ ++enum { ++ SLOTB_PROBE = 0, ++ SLOTB_NOPROBE_IO, ++ SLOTB_NOPROBE_MEM, ++ SLOTB_NOPROBE_ALL ++}; ++ ++typedef struct vrc4171_socket { ++ int noprobe; ++ void (*handler)(void *, unsigned int); ++ void *info; ++ socket_cap_t cap; ++ spinlock_t event_lock; ++ uint16_t events; ++ struct socket_info_t *pcmcia_socket; ++ struct tq_struct tq_task; ++ char name[24]; ++ int csc_irq; ++ int io_irq; ++} vrc4171_socket_t; ++ ++static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS]; ++static int vrc4171_slotb = SLOTB_IS_NONE; ++static unsigned int vrc4171_irq; ++static uint16_t vrc4171_irq_mask = 0xdeb8; ++ ++extern struct socket_info_t *pcmcia_register_socket(int slot, ++ struct pccard_operations *vtable, ++ int use_bus_pm); ++extern void pcmcia_unregister_socket(struct socket_info_t *s); ++ ++static inline uint8_t exca_read_byte(int slot, uint8_t index) ++{ ++ if (slot == CARD_SLOTB) ++ index += CARD_SLOTB_OFFSET; ++ ++ outb(index, CARD_CONTROLLER_INDEX); ++ return inb(CARD_CONTROLLER_DATA); ++} ++ ++static inline uint16_t exca_read_word(int slot, uint8_t index) ++{ ++ uint16_t data; ++ ++ if (slot == CARD_SLOTB) ++ index += CARD_SLOTB_OFFSET; ++ ++ outb(index++, CARD_CONTROLLER_INDEX); ++ data = inb(CARD_CONTROLLER_DATA); ++ ++ outb(index, CARD_CONTROLLER_INDEX); ++ data |= ((uint16_t)inb(CARD_CONTROLLER_DATA)) << 8; ++ ++ return data; ++} ++ ++static inline uint8_t exca_write_byte(int slot, uint8_t index, uint8_t data) ++{ ++ if (slot == CARD_SLOTB) ++ index += CARD_SLOTB_OFFSET; ++ ++ outb(index, CARD_CONTROLLER_INDEX); ++ outb(data, CARD_CONTROLLER_DATA); ++ ++ return data; ++} ++ ++static inline uint16_t exca_write_word(int slot, uint8_t index, uint16_t data) ++{ ++ if (slot == CARD_SLOTB) ++ index += CARD_SLOTB_OFFSET; ++ ++ outb(index++, CARD_CONTROLLER_INDEX); ++ outb(data, CARD_CONTROLLER_DATA); ++ ++ outb(index, CARD_CONTROLLER_INDEX); ++ outb((uint8_t)(data >> 8), CARD_CONTROLLER_DATA); ++ ++ return data; ++} ++ ++static inline int search_nonuse_irq(void) ++{ ++ int i; ++ ++ for (i = 0; i < 16; i++) { ++ if (vrc4171_irq_mask & (1 << i)) { ++ vrc4171_irq_mask &= ~(1 << i); ++ return i; ++ } ++ } ++ ++ return -1; ++} ++ ++static int pccard_init(unsigned int slot) ++{ ++ vrc4171_socket_t *socket = &vrc4171_sockets[slot]; ++ ++ socket->cap.features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS; ++ socket->cap.irq_mask = 0; ++ socket->cap.pci_irq = vrc4171_irq; ++ socket->cap.map_size = 0x1000; ++ socket->events = 0; ++ spin_lock_init(socket->event_lock); ++ socket->csc_irq = search_nonuse_irq(); ++ socket->io_irq = search_nonuse_irq(); ++ ++ return 0; ++} ++ ++static int pccard_suspend(unsigned int slot) ++{ ++ return -EINVAL; ++} ++ ++static int pccard_register_callback(unsigned int slot, ++ void (*handler)(void *, unsigned int), ++ void *info) ++{ ++ vrc4171_socket_t *socket; ++ ++ if (slot >= CARD_MAX_SLOTS) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ ++ socket->handler = handler; ++ socket->info = info; ++ ++ if (handler) ++ MOD_INC_USE_COUNT; ++ else ++ MOD_DEC_USE_COUNT; ++ ++ return 0; ++} ++ ++static int pccard_inquire_socket(unsigned int slot, socket_cap_t *cap) ++{ ++ vrc4171_socket_t *socket; ++ ++ if (slot >= CARD_MAX_SLOTS || cap == NULL) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ ++ *cap = socket->cap; ++ ++ return 0; ++} ++ ++static int pccard_get_status(unsigned int slot, u_int *value) ++{ ++ uint8_t status, sense; ++ u_int val = 0; ++ ++ if (slot >= CARD_MAX_SLOTS || value == NULL) ++ return -EINVAL; ++ ++ status = exca_read_byte(slot, I365_STATUS); ++ if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) { ++ if (status & I365_CS_STSCHG) ++ val |= SS_STSCHG; ++ } else { ++ if (!(status & I365_CS_BVD1)) ++ val |= SS_BATDEAD; ++ else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1) ++ val |= SS_BATWARN; ++ } ++ if ((status & I365_CS_DETECT) == I365_CS_DETECT) ++ val |= SS_DETECT; ++ if (status & I365_CS_WRPROT) ++ val |= SS_WRPROT; ++ if (status & I365_CS_READY) ++ val |= SS_READY; ++ if (status & I365_CS_POWERON) ++ val |= SS_POWERON; ++ ++ sense = exca_read_byte(slot, CARD_VOLTAGE_SENSE); ++ switch (sense) { ++ case VCC_3VORXV_CAPABLE: ++ val |= SS_3VCARD | SS_XVCARD; ++ break; ++ case VCC_XV_ONLY: ++ val |= SS_XVCARD; ++ break; ++ case VCC_3V_CAPABLE: ++ val |= SS_3VCARD; ++ break; ++ default: ++ /* 5V only */ ++ break; ++ } ++ ++ *value = val; ++ ++ return 0; ++} ++ ++static inline u_char get_Vcc_value(uint8_t voltage) ++{ ++ switch (voltage) { ++ case VCC_STATUS_3V: ++ return 33; ++ case VCC_STATUS_5V: ++ return 50; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static inline u_char get_Vpp_value(uint8_t power, u_char Vcc) ++{ ++ if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02) ++ return Vcc; ++ ++ return 0; ++} ++ ++static int pccard_get_socket(unsigned int slot, socket_state_t *state) ++{ ++ vrc4171_socket_t *socket; ++ uint8_t power, voltage, control, cscint; ++ ++ if (slot >= CARD_MAX_SLOTS || state == NULL) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ ++ power = exca_read_byte(slot, I365_POWER); ++ voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT); ++ ++ state->Vcc = get_Vcc_value(voltage); ++ state->Vpp = get_Vpp_value(power, state->Vcc); ++ ++ state->flags = 0; ++ if (power & POWER_ENABLE) ++ state->flags |= SS_PWR_AUTO; ++ if (power & I365_PWR_OUT) ++ state->flags |= SS_OUTPUT_ENA; ++ ++ control = exca_read_byte(slot, I365_INTCTL); ++ if (control & I365_PC_IOCARD) ++ state->flags |= SS_IOCARD; ++ if (!(control & I365_PC_RESET)) ++ state->flags |= SS_RESET; ++ ++ cscint = exca_read_byte(slot, I365_CSCINT); ++ state->csc_mask = 0; ++ if (state->flags & SS_IOCARD) { ++ if (cscint & I365_CSC_STSCHG) ++ state->flags |= SS_STSCHG; ++ } else { ++ if (cscint & I365_CSC_BVD1) ++ state->csc_mask |= SS_BATDEAD; ++ if (cscint & I365_CSC_BVD2) ++ state->csc_mask |= SS_BATWARN; ++ } ++ if (cscint & I365_CSC_READY) ++ state->csc_mask |= SS_READY; ++ if (cscint & I365_CSC_DETECT) ++ state->csc_mask |= SS_DETECT; ++ ++ return 0; ++} ++ ++static inline uint8_t set_Vcc_value(u_char Vcc) ++{ ++ switch (Vcc) { ++ case 33: ++ return VCC_3V; ++ case 50: ++ return VCC_5V; ++ } ++ ++ /* Small voltage is chosen for safety. */ ++ return VCC_3V; ++} ++ ++static int pccard_set_socket(unsigned int slot, socket_state_t *state) ++{ ++ vrc4171_socket_t *socket; ++ uint8_t voltage, power, control, cscint; ++ ++ if (slot >= CARD_MAX_SLOTS || ++ (state->Vpp != state->Vcc && state->Vpp != 0) || ++ (state->Vcc != 50 && state->Vcc != 33 && state->Vcc != 0)) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ ++ spin_lock_irq(&socket->event_lock); ++ ++ voltage = set_Vcc_value(state->Vcc); ++ exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage); ++ ++ power = POWER_ENABLE; ++ if (state->Vpp == state->Vcc) ++ power |= VPP_GET_VCC; ++ if (state->flags & SS_OUTPUT_ENA) ++ power |= I365_PWR_OUT; ++ exca_write_byte(slot, I365_POWER, power); ++ ++ control = 0; ++ if (state->io_irq != 0) ++ control |= socket->io_irq; ++ if (state->flags & SS_IOCARD) ++ control |= I365_PC_IOCARD; ++ if (state->flags & SS_RESET) ++ control &= ~I365_PC_RESET; ++ else ++ control |= I365_PC_RESET; ++ exca_write_byte(slot, I365_INTCTL, control); ++ ++ cscint = 0; ++ exca_write_byte(slot, I365_CSCINT, cscint); ++ exca_read_byte(slot, I365_CSC); /* clear CardStatus change */ ++ if (state->csc_mask != 0) ++ cscint |= socket->csc_irq << 8; ++ if (state->flags & SS_IOCARD) { ++ if (state->csc_mask & SS_STSCHG) ++ cscint |= I365_CSC_STSCHG; ++ } else { ++ if (state->csc_mask & SS_BATDEAD) ++ cscint |= I365_CSC_BVD1; ++ if (state->csc_mask & SS_BATWARN) ++ cscint |= I365_CSC_BVD2; ++ } ++ if (state->csc_mask & SS_READY) ++ cscint |= I365_CSC_READY; ++ if (state->csc_mask & SS_DETECT) ++ cscint |= I365_CSC_DETECT; ++ exca_write_byte(slot, I365_CSCINT, cscint); ++ ++ spin_unlock_irq(&socket->event_lock); ++ ++ return 0; ++} ++ ++static int pccard_get_io_map(unsigned int slot, struct pccard_io_map *io) ++{ ++ vrc4171_socket_t *socket; ++ uint8_t ioctl, addrwin; ++ u_char map; ++ ++ if (slot >= CARD_MAX_SLOTS || io == NULL || ++ io->map >= IO_MAX_MAPS) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ map = io->map; ++ ++ io->start = exca_read_word(slot, I365_IO(map)+I365_W_START); ++ io->stop = exca_read_word(slot, I365_IO(map)+I365_W_STOP); ++ ++ ioctl = exca_read_byte(slot, I365_IOCTL); ++ if (io->flags & I365_IOCTL_WAIT(map)) ++ io->speed = 1; ++ else ++ io->speed = 0; ++ ++ io->flags = 0; ++ if (ioctl & I365_IOCTL_16BIT(map)) ++ io->flags |= MAP_16BIT; ++ if (ioctl & I365_IOCTL_IOCS16(map)) ++ io->flags |= MAP_AUTOSZ; ++ if (ioctl & I365_IOCTL_0WS(map)) ++ io->flags |= MAP_0WS; ++ ++ addrwin = exca_read_byte(slot, I365_ADDRWIN); ++ if (addrwin & I365_ENA_IO(map)) ++ io->flags |= MAP_ACTIVE; ++ ++ return 0; ++} ++ ++static int pccard_set_io_map(unsigned int slot, struct pccard_io_map *io) ++{ ++ vrc4171_socket_t *socket; ++ uint8_t ioctl, addrwin; ++ u_char map; ++ ++ if (slot >= CARD_MAX_SLOTS || ++ io == NULL || io->map >= IO_MAX_MAPS || ++ io->start > 0xffff || io->stop > 0xffff || io->start > io->stop) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ map = io->map; ++ ++ addrwin = exca_read_byte(slot, I365_ADDRWIN); ++ if (addrwin & I365_ENA_IO(map)) { ++ addrwin &= ~I365_ENA_IO(map); ++ exca_write_byte(slot, I365_ADDRWIN, addrwin); ++ } ++ ++ exca_write_word(slot, I365_IO(map)+I365_W_START, io->start); ++ exca_write_word(slot, I365_IO(map)+I365_W_STOP, io->stop); ++ ++ ioctl = 0; ++ if (io->speed > 0) ++ ioctl |= I365_IOCTL_WAIT(map); ++ if (io->flags & MAP_16BIT) ++ ioctl |= I365_IOCTL_16BIT(map); ++ if (io->flags & MAP_AUTOSZ) ++ ioctl |= I365_IOCTL_IOCS16(map); ++ if (io->flags & MAP_0WS) ++ ioctl |= I365_IOCTL_0WS(map); ++ exca_write_byte(slot, I365_IOCTL, ioctl); ++ ++ if (io->flags & MAP_ACTIVE) { ++ addrwin |= I365_ENA_IO(map); ++ exca_write_byte(slot, I365_ADDRWIN, addrwin); ++ } ++ ++ return 0; ++} ++ ++static int pccard_get_mem_map(unsigned int slot, struct pccard_mem_map *mem) ++{ ++ vrc4171_socket_t *socket; ++ uint8_t addrwin; ++ u_long start, stop; ++ u_int offset; ++ u_char map; ++ ++ if (slot >= CARD_MAX_SLOTS || mem == NULL || mem->map >= MEM_MAX_MAPS) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ map = mem->map; ++ ++ mem->flags = 0; ++ mem->speed = 0; ++ ++ addrwin = exca_read_byte(slot, I365_ADDRWIN); ++ if (addrwin & I365_ENA_MEM(map)) ++ mem->flags |= MAP_ACTIVE; ++ ++ start = exca_read_word(slot, I365_MEM(map)+I365_W_START); ++ if (start & I365_MEM_16BIT) ++ mem->flags |= MAP_16BIT; ++ mem->sys_start = (start & 0x3fffUL) << 12; ++ ++ stop = exca_read_word(slot, I365_MEM(map)+I365_W_STOP); ++ if (start & I365_MEM_WS0) ++ mem->speed += 1; ++ if (start & I365_MEM_WS1) ++ mem->speed += 2; ++ mem->sys_stop = ((stop & 0x3fffUL) << 12) + 0xfffUL; ++ ++ offset = exca_read_word(slot, I365_MEM(map)+I365_W_OFF); ++ if (offset & I365_MEM_REG) ++ mem->flags |= MAP_ATTRIB; ++ if (offset & I365_MEM_WRPROT) ++ mem->flags |= MAP_WRPROT; ++ mem->card_start = (offset & 0x3fffUL) << 12; ++ ++ mem->sys_start += CARD_MEM_START; ++ mem->sys_stop += CARD_MEM_START; ++ ++ return 0; ++} ++ ++static int pccard_set_mem_map(unsigned int slot, struct pccard_mem_map *mem) ++{ ++ vrc4171_socket_t *socket; ++ uint16_t start, stop, offset; ++ uint8_t addrwin; ++ u_char map; ++ ++ if (slot >= CARD_MAX_SLOTS || ++ mem == NULL || mem->map >= MEM_MAX_MAPS || ++ mem->sys_start < CARD_MEM_START || mem->sys_start > CARD_MEM_END || ++ mem->sys_stop < CARD_MEM_START || mem->sys_stop > CARD_MEM_END || ++ mem->sys_start > mem->sys_stop || ++ mem->card_start > CARD_MAX_MEM_OFFSET || ++ mem->speed > CARD_MAX_MEM_SPEED) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ map = mem->map; ++ ++ addrwin = exca_read_byte(slot, I365_ADDRWIN); ++ if (addrwin & I365_ENA_MEM(map)) { ++ addrwin &= ~I365_ENA_MEM(map); ++ exca_write_byte(slot, I365_ADDRWIN, addrwin); ++ } ++ ++ start = (mem->sys_start >> 12) & 0x3fff; ++ if (mem->flags & MAP_16BIT) ++ start |= I365_MEM_16BIT; ++ exca_write_word(slot, I365_MEM(map)+I365_W_START, start); ++ ++ stop = (mem->sys_stop >> 12) & 0x3fff; ++ switch (mem->speed) { ++ case 0: ++ break; ++ case 1: ++ stop |= I365_MEM_WS0; ++ break; ++ case 2: ++ stop |= I365_MEM_WS1; ++ break; ++ default: ++ stop |= I365_MEM_WS0 | I365_MEM_WS1; ++ break; ++ } ++ exca_write_word(slot, I365_MEM(map)+I365_W_STOP, stop); ++ ++ offset = (mem->card_start >> 12) & 0x3fff; ++ if (mem->flags & MAP_ATTRIB) ++ offset |= I365_MEM_REG; ++ if (mem->flags & MAP_WRPROT) ++ offset |= I365_MEM_WRPROT; ++ exca_write_word(slot, I365_MEM(map)+I365_W_OFF, offset); ++ ++ if (mem->flags & MAP_ACTIVE) { ++ addrwin |= I365_ENA_MEM(map); ++ exca_write_byte(slot, I365_ADDRWIN, addrwin); ++ } ++ ++ return 0; ++} ++ ++static void pccard_proc_setup(unsigned int slot, struct proc_dir_entry *base) ++{ ++} ++ ++static struct pccard_operations vrc4171_pccard_operations = { ++ .init = pccard_init, ++ .suspend = pccard_suspend, ++ .register_callback = pccard_register_callback, ++ .inquire_socket = pccard_inquire_socket, ++ .get_status = pccard_get_status, ++ .get_socket = pccard_get_socket, ++ .set_socket = pccard_set_socket, ++ .get_io_map = pccard_get_io_map, ++ .set_io_map = pccard_set_io_map, ++ .get_mem_map = pccard_get_mem_map, ++ .set_mem_map = pccard_set_mem_map, ++ .proc_setup = pccard_proc_setup, ++}; ++ ++static void pccard_bh(void *data) ++{ ++ vrc4171_socket_t *socket = (vrc4171_socket_t *)data; ++ uint16_t events; ++ ++ spin_lock_irq(&socket->event_lock); ++ events = socket->events; ++ socket->events = 0; ++ spin_unlock_irq(&socket->event_lock); ++ ++ if (socket->handler) ++ socket->handler(socket->info, events); ++} ++ ++static inline uint16_t get_events(int slot) ++{ ++ uint16_t events = 0; ++ uint8_t status, csc; ++ ++ status = exca_read_byte(slot, I365_STATUS); ++ csc = exca_read_byte(slot, I365_CSC); ++ ++ if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) { ++ if ((csc & I365_CSC_STSCHG) && (status & I365_CS_STSCHG)) ++ events |= SS_STSCHG; ++ } else { ++ if (csc & (I365_CSC_BVD1 | I365_CSC_BVD2)) { ++ if (!(status & I365_CS_BVD1)) ++ events |= SS_BATDEAD; ++ else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1) ++ events |= SS_BATWARN; ++ } ++ } ++ if ((csc & I365_CSC_READY) && (status & I365_CS_READY)) ++ events |= SS_READY; ++ if ((csc & I365_CSC_DETECT) && ((status & I365_CS_DETECT) == I365_CS_DETECT)) ++ events |= SS_DETECT; ++ ++ return events; ++} ++ ++static void pccard_status_change(int slot, vrc4171_socket_t *socket) ++{ ++ uint16_t events; ++ ++ socket->tq_task.routine = pccard_bh; ++ socket->tq_task.data = socket; ++ ++ events = get_events(slot); ++ if (events) { ++ spin_lock(&socket->event_lock); ++ socket->events |= events; ++ spin_unlock(&socket->event_lock); ++ schedule_task(&socket->tq_task); ++ } ++} ++ ++static void pccard_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ vrc4171_socket_t *socket; ++ uint16_t status; ++ ++ status = vrc4171_get_irq_status(); ++ if (status & IRQ_A) { ++ socket = &vrc4171_sockets[CARD_SLOTA]; ++ if (socket->noprobe == SLOTB_PROBE) { ++ if (status & (1 << socket->csc_irq)) ++ pccard_status_change(CARD_SLOTA, socket); ++ } ++ } ++ ++ if (status & IRQ_B) { ++ socket = &vrc4171_sockets[CARD_SLOTB]; ++ if (socket->noprobe == SLOTB_PROBE) { ++ if (status & (1 << socket->csc_irq)) ++ pccard_status_change(CARD_SLOTB, socket); ++ } ++ } ++} ++ ++static inline void reserve_using_irq(int slot) ++{ ++ unsigned int irq; ++ ++ irq = exca_read_byte(slot, I365_INTCTL); ++ irq &= 0x0f; ++ vrc4171_irq_mask &= ~(1 << irq); ++ ++ irq = exca_read_byte(slot, I365_CSCINT); ++ irq = (irq & 0xf0) >> 4; ++ vrc4171_irq_mask &= ~(1 << irq); ++} ++ ++static int __devinit vrc4171_add_socket(int slot) ++{ ++ vrc4171_socket_t *socket; ++ ++ if (slot >= CARD_MAX_SLOTS) ++ return -EINVAL; ++ ++ socket = &vrc4171_sockets[slot]; ++ if (socket->noprobe != SLOTB_PROBE) { ++ uint8_t addrwin; ++ ++ switch (socket->noprobe) { ++ case SLOTB_NOPROBE_MEM: ++ addrwin = exca_read_byte(slot, I365_ADDRWIN); ++ addrwin &= 0x1f; ++ exca_write_byte(slot, I365_ADDRWIN, addrwin); ++ break; ++ case SLOTB_NOPROBE_IO: ++ addrwin = exca_read_byte(slot, I365_ADDRWIN); ++ addrwin &= 0xc0; ++ exca_write_byte(slot, I365_ADDRWIN, addrwin); ++ break; ++ default: ++ break; ++ } ++ ++ reserve_using_irq(slot); ++ ++ return 0; ++ } ++ ++ sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot); ++ ++ socket->pcmcia_socket = pcmcia_register_socket(slot, &vrc4171_pccard_operations, 1); ++ if (socket->pcmcia_socket == NULL) ++ return -ENOMEM; ++ ++ exca_write_byte(slot, I365_ADDRWIN, 0); ++ ++ exca_write_byte(slot, GLOBAL_CONTROL, 0); ++ ++ return 0; ++} ++ ++static void vrc4171_remove_socket(int slot) ++{ ++ vrc4171_socket_t *socket; ++ ++ if (slot >= CARD_MAX_SLOTS) ++ return; ++ ++ socket = &vrc4171_sockets[slot]; ++ ++ if (socket->pcmcia_socket != NULL) { ++ pcmcia_unregister_socket(socket->pcmcia_socket); ++ socket->pcmcia_socket = NULL; ++ } ++} ++ ++static int __devinit vrc4171_card_setup(char *options) ++{ ++ if (options == NULL || *options == '\0') ++ return 0; ++ ++ if (strncmp(options, "irq:", 4) == 0) { ++ int irq; ++ options += 4; ++ irq = simple_strtoul(options, &options, 0); ++ if (irq >= 0 && irq < NR_IRQS) ++ vrc4171_irq = irq; ++ ++ if (*options != ',') ++ return 0; ++ options++; ++ } ++ ++ if (strncmp(options, "slota:", 6) == 0) { ++ options += 6; ++ if (*options != '\0') { ++ if (strncmp(options, "noprobe", 7) == 0) { ++ vrc4171_sockets[CARD_SLOTA].noprobe = 1; ++ options += 7; ++ } ++ ++ if (*options != ',') ++ return 0; ++ options++; ++ } else ++ return 0; ++ ++ } ++ ++ if (strncmp(options, "slotb:", 6) == 0) { ++ options += 6; ++ if (*options != '\0') { ++ if (strncmp(options, "pccard", 6) == 0) { ++ vrc4171_slotb = SLOTB_IS_PCCARD; ++ options += 6; ++ } else if (strncmp(options, "cf", 2) == 0) { ++ vrc4171_slotb = SLOTB_IS_CF; ++ options += 2; ++ } else if (strncmp(options, "flashrom", 8) == 0) { ++ vrc4171_slotb = SLOTB_IS_FLASHROM; ++ options += 8; ++ } else if (strncmp(options, "none", 4) == 0) { ++ vrc4171_slotb = SLOTB_IS_NONE; ++ options += 4; ++ } ++ ++ if (*options != ',') ++ return 0; ++ options++; ++ ++ if ( strncmp(options, "memnoprobe", 10) == 0) ++ vrc4171_sockets[CARD_SLOTB].noprobe = SLOTB_NOPROBE_MEM; ++ if ( strncmp(options, "ionoprobe", 9) == 0) ++ vrc4171_sockets[CARD_SLOTB].noprobe = SLOTB_NOPROBE_IO; ++ if ( strncmp(options, "noprobe", 7) == 0) ++ vrc4171_sockets[CARD_SLOTB].noprobe = SLOTB_NOPROBE_ALL; ++ } ++ } ++ ++ return 0; ++} ++ ++__setup("vrc4171_card=", vrc4171_card_setup); ++ ++static int __devinit vrc4171_card_init(void) ++{ ++ int retval, slot; ++ ++ vrc4171_set_multifunction_pin(vrc4171_slotb); ++ ++ if (request_region(CARD_CONTROLLER_INDEX, CARD_CONTROLLER_SIZE, ++ "NEC VRC4171 Card Controller") == NULL) ++ return -EBUSY; ++ ++ for (slot = 0; slot < CARD_MAX_SLOTS; slot++) { ++ if (slot == CARD_SLOTB && vrc4171_slotb == SLOTB_IS_NONE) ++ break; ++ ++ retval = vrc4171_add_socket(slot); ++ if (retval != 0) ++ return retval; ++ } ++ ++ retval = request_irq(vrc4171_irq, pccard_interrupt, SA_SHIRQ, ++ "NEC VRC4171 Card Controller", vrc4171_sockets); ++ if (retval < 0) { ++ for (slot = 0; slot < CARD_MAX_SLOTS; slot++) ++ vrc4171_remove_socket(slot); ++ ++ return retval; ++ } ++ ++ printk(KERN_INFO "NEC VRC4171 Card Controller, connected to IRQ %d\n", vrc4171_irq); ++ ++ return 0; ++} ++ ++static void __devexit vrc4171_card_exit(void) ++{ ++ int slot; ++ ++ for (slot = 0; slot < CARD_MAX_SLOTS; slot++) ++ vrc4171_remove_socket(slot); ++ ++ release_region(CARD_CONTROLLER_INDEX, CARD_CONTROLLER_SIZE); ++} ++ ++module_init(vrc4171_card_init); ++module_exit(vrc4171_card_exit); +diff -Nur linux-2.4.32-rc1/drivers/scsi/NCR53C9x.h linux-2.4.32-rc1.mips/drivers/scsi/NCR53C9x.h +--- linux-2.4.32-rc1/drivers/scsi/NCR53C9x.h 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/scsi/NCR53C9x.h 2003-12-15 19:19:51.000000000 +0100 +@@ -144,12 +144,7 @@ + + #ifndef MULTIPLE_PAD_SIZES + +-#ifdef CONFIG_CPU_HAS_WB +-#include +-#define esp_write(__reg, __val) do{(__reg) = (__val); wbflush();} while(0) +-#else +-#define esp_write(__reg, __val) ((__reg) = (__val)) +-#endif ++#define esp_write(__reg, __val) do{(__reg) = (__val); iob();} while(0) + #define esp_read(__reg) (__reg) + + struct ESP_regs { +diff -Nur linux-2.4.32-rc1/drivers/sound/au1550_i2s.c linux-2.4.32-rc1.mips/drivers/sound/au1550_i2s.c +--- linux-2.4.32-rc1/drivers/sound/au1550_i2s.c 2005-01-19 15:10:04.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/sound/au1550_i2s.c 2005-02-08 08:07:50.000000000 +0100 +@@ -41,6 +41,7 @@ + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ ++ + #include + #include + #include +@@ -62,7 +63,45 @@ + #include + #include + #include ++ ++#if defined(CONFIG_SOC_AU1550) + #include ++#endif ++ ++#if defined(CONFIG_MIPS_PB1200) ++#define WM8731 ++#define WM_MODE_USB ++#include ++#endif ++ ++#if defined(CONFIG_MIPS_FICMMP) ++#define WM8721 ++#define WM_MODE_NORMAL ++#include ++#endif ++ ++ ++#define WM_VOLUME_MIN 47 ++#define WM_VOLUME_SCALE 80 ++ ++#if defined(WM8731) ++ /* OSS interface to the wm i2s.. */ ++ #define CODEC_NAME "Wolfson WM8731 I2S" ++ #define WM_I2S_STEREO_MASK (SOUND_MASK_PCM | SOUND_MASK_LINE) ++ #define WM_I2S_SUPPORTED_MASK (WM_I2S_STEREO_MASK | SOUND_MASK_MIC) ++ #define WM_I2S_RECORD_MASK (SOUND_MASK_MIC | SOUND_MASK_LINE1 | SOUND_MASK_LINE) ++#elif defined(WM8721) ++ #define CODEC_NAME "Wolfson WM8721 I2S" ++ #define WM_I2S_STEREO_MASK (SOUND_MASK_PCM) ++ #define WM_I2S_SUPPORTED_MASK (WM_I2S_STEREO_MASK) ++ #define WM_I2S_RECORD_MASK (0) ++#endif ++ ++ ++#define supported_mixer(FOO) ((FOO >= 0) && \ ++ (FOO < SOUND_MIXER_NRDEVICES) && \ ++ WM_I2S_SUPPORTED_MASK & (1< + #include + +@@ -98,13 +137,51 @@ + * 0 = no VRA, 1 = use VRA if codec supports it + * The framework is here, but we currently force no VRA. + */ ++#if defined(CONFIG_MIPS_PB1200) | defined(CONFIG_MIPS_PB1550) + static int vra = 0; ++#elif defined(CONFIG_MIPS_FICMMP) ++static int vra = 1; ++#endif ++ ++#define WM_REG_L_HEADPHONE_OUT 0x02 ++#define WM_REG_R_HEADPHONE_OUT 0x03 ++#define WM_REG_ANALOGUE_AUDIO_PATH_CTRL 0x04 ++#define WM_REG_DIGITAL_AUDIO_PATH_CTRL 0x05 ++#define WM_REG_POWER_DOWN_CTRL 0x06 ++#define WM_REG_DIGITAL_AUDIO_IF 0x07 ++#define WM_REG_SAMPLING_CONTROL 0x08 ++#define WM_REG_ACTIVE_CTRL 0x09 ++#define WM_REG_RESET 0x0F ++#define WM_SC_SR_96000 (0x7<<2) ++#define WM_SC_SR_88200 (0xF<<2) ++#define WM_SC_SR_48000 (0x0<<2) ++#define WM_SC_SR_44100 (0x8<<2) ++#define WM_SC_SR_32000 (0x6<<2) ++#define WM_SC_SR_8018 (0x9<<2) ++#define WM_SC_SR_8000 (0x1<<2) ++#define WM_SC_MODE_USB 1 ++#define WM_SC_MODE_NORMAL 0 ++#define WM_SC_BOSR_250FS (0<<1) ++#define WM_SC_BOSR_272FS (1<<1) ++#define WM_SC_BOSR_256FS (0<<1) ++#define WM_SC_BOSR_128FS (0<<1) ++#define WM_SC_BOSR_384FS (1<<1) ++#define WM_SC_BOSR_192FS (1<<1) ++ ++#define WS_64FS 31 ++#define WS_96FS 47 ++#define WS_128FS 63 ++#define WS_192FS 95 ++ ++#define MIN_Q_COUNT 2 ++ + MODULE_PARM(vra, "i"); + MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); + + static struct au1550_state { + /* soundcore stuff */ + int dev_audio; ++ int dev_mixer; + + spinlock_t lock; + struct semaphore open_sem; +@@ -114,6 +191,11 @@ + int no_vra; + volatile psc_i2s_t *psc_addr; + ++ int level_line; ++ int level_mic; ++ int level_left; ++ int level_right; ++ + struct dmabuf { + u32 dmanr; + unsigned sample_rate; +@@ -195,60 +277,224 @@ + } + } + +-/* Just a place holder. The Wolfson codec is a write only device, +- * so we would have to keep a local copy of the data. +- */ +-#if 0 +-static u8 +-rdcodec(u8 addr) +-{ +- return 0 /* data */; +-} +-#endif +- +- + static void +-wrcodec(u8 ctlreg, u8 val) ++wrcodec(u8 ctlreg, u16 val) + { + int rcnt; + extern int pb1550_wm_codec_write(u8 addr, u8 reg, u8 val); +- + /* The codec is a write only device, with a 16-bit control/data + * word. Although it is written as two bytes on the I2C, the + * format is actually 7 bits of register and 9 bits of data. + * The ls bit of the first byte is the ms bit of the data. + */ + rcnt = 0; +- while ((pb1550_wm_codec_write((0x36 >> 1), ctlreg, val) != 1) +- && (rcnt < 50)) { ++ while ((pb1550_wm_codec_write((0x36 >> 1), ++ (ctlreg << 1) | ((val >> 8) & 0x01), ++ (u8) (val & 0x00FF)) != 1) && ++ (rcnt < 50)) { + rcnt++; +-#if 0 +- printk("Codec write retry %02x %02x\n", ctlreg, val); +-#endif + } ++ ++ au1550_delay(10); ++} ++ ++static int ++au1550_open_mixdev(struct inode *inode, struct file *file) ++{ ++ file->private_data = &au1550_state; ++ return 0; ++} ++ ++static int ++au1550_release_mixdev(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++static int wm_i2s_read_mixer(struct au1550_state *s, int oss_channel) ++{ ++ int ret = 0; ++ ++ if (WM_I2S_STEREO_MASK & (1 << oss_channel)) { ++ /* nice stereo mixers .. */ ++ ++ ret = s->level_left | (s->level_right << 8); ++ } else if (oss_channel == SOUND_MIXER_MIC) { ++ ret = 0; ++ /* TODO: Implement read mixer for input/output codecs */ ++ } ++ ++ return ret; + } + ++static void wm_i2s_write_mixer(struct au1550_state *s, int oss_channel, unsigned int left, unsigned int right) ++{ ++ if (WM_I2S_STEREO_MASK & (1 << oss_channel)) { ++ /* stereo mixers */ ++ s->level_left = left; ++ s->level_right = right; ++ ++ right = (right * WM_VOLUME_SCALE) / 100; ++ left = (left * WM_VOLUME_SCALE) / 100; ++ if (right > WM_VOLUME_SCALE) ++ right = WM_VOLUME_SCALE; ++ if (left > WM_VOLUME_SCALE) ++ left = WM_VOLUME_SCALE; ++ ++ right += WM_VOLUME_MIN; ++ left += WM_VOLUME_MIN; ++ ++ wrcodec(WM_REG_L_HEADPHONE_OUT, left); ++ wrcodec(WM_REG_R_HEADPHONE_OUT, right); ++ ++ }else if (oss_channel == SOUND_MIXER_MIC) { ++ /* TODO: implement write mixer for input/output codecs */ ++ } ++} ++ ++/* a thin wrapper for write_mixer */ ++static void wm_i2s_set_mixer(struct au1550_state *s, unsigned int oss_mixer, unsigned int val ) ++{ ++ unsigned int left,right; ++ ++ /* cleanse input a little */ ++ right = ((val >> 8) & 0xff) ; ++ left = (val & 0xff) ; ++ ++ if (right > 100) right = 100; ++ if (left > 100) left = 100; ++ ++ wm_i2s_write_mixer(s, oss_mixer, left, right); ++} ++ ++static int ++au1550_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ struct au1550_state *s = (struct au1550_state *)file->private_data; ++ ++ int i, val = 0; ++ ++ if (cmd == SOUND_MIXER_INFO) { ++ mixer_info info; ++ strncpy(info.id, CODEC_NAME, sizeof(info.id)); ++ strncpy(info.name, CODEC_NAME, sizeof(info.name)); ++ info.modify_counter = 0; ++ if (copy_to_user((void *)arg, &info, sizeof(info))) ++ return -EFAULT; ++ return 0; ++ } ++ if (cmd == SOUND_OLD_MIXER_INFO) { ++ _old_mixer_info info; ++ strncpy(info.id, CODEC_NAME, sizeof(info.id)); ++ strncpy(info.name, CODEC_NAME, sizeof(info.name)); ++ if (copy_to_user((void *)arg, &info, sizeof(info))) ++ return -EFAULT; ++ return 0; ++ } ++ ++ if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int)) ++ return -EINVAL; ++ ++ if (cmd == OSS_GETVERSION) ++ return put_user(SOUND_VERSION, (int *)arg); ++ ++ if (_SIOC_DIR(cmd) == _SIOC_READ) { ++ switch (_IOC_NR(cmd)) { ++ case SOUND_MIXER_RECSRC: /* give them the current record src */ ++ val = 0; ++ /* ++ if (!codec->recmask_io) { ++ val = 0; ++ } else { ++ val = codec->recmask_io(codec, 1, 0); ++ }*/ ++ break; ++ ++ case SOUND_MIXER_DEVMASK: /* give them the supported mixers */ ++ val = WM_I2S_SUPPORTED_MASK; ++ break; ++ ++ case SOUND_MIXER_RECMASK: ++ /* Arg contains a bit for each supported recording ++ * source */ ++ val = WM_I2S_RECORD_MASK; ++ break; ++ ++ case SOUND_MIXER_STEREODEVS: ++ /* Mixer channels supporting stereo */ ++ val = WM_I2S_STEREO_MASK; ++ break; ++ ++ case SOUND_MIXER_CAPS: ++ val = SOUND_CAP_EXCL_INPUT; ++ break; ++ ++ default: /* read a specific mixer */ ++ i = _IOC_NR(cmd); ++ ++ if (!supported_mixer(i)) ++ return -EINVAL; ++ ++ val = wm_i2s_read_mixer(s, i); ++ break; ++ } ++ return put_user(val, (int *)arg); ++ } ++ ++ if (_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) { ++ if (get_user(val, (int *)arg)) ++ return -EFAULT; ++ ++ switch (_IOC_NR(cmd)) { ++ case SOUND_MIXER_RECSRC: ++ /* Arg contains a bit for each recording source */ ++ if (!WM_I2S_RECORD_MASK) ++ return -EINVAL; ++ if (!val) ++ return 0; ++ if (!(val &= WM_I2S_RECORD_MASK)) ++ return -EINVAL; ++ ++ return 0; ++ default: /* write a specific mixer */ ++ i = _IOC_NR(cmd); ++ ++ if (!supported_mixer(i)) ++ return -EINVAL; ++ ++ wm_i2s_set_mixer(s, i, val); ++ ++ return 0; ++ } ++} ++ return -EINVAL; ++} ++ ++static loff_t ++au1550_llseek(struct file *file, loff_t offset, int origin) ++{ ++ return -ESPIPE; ++} ++ ++static /*const */ struct file_operations au1550_mixer_fops = { ++ owner:THIS_MODULE, ++ llseek:au1550_llseek, ++ ioctl:au1550_ioctl_mixdev, ++ open:au1550_open_mixdev, ++ release:au1550_release_mixdev, ++}; ++ + void +-codec_init(void) ++codec_init(struct au1550_state *s) + { +- wrcodec(0x1e, 0x00); /* Reset */ +- au1550_delay(200); +- wrcodec(0x0c, 0x00); /* Power up everything */ +- au1550_delay(10); +- wrcodec(0x12, 0x00); /* Deactivate codec */ +- au1550_delay(10); +- wrcodec(0x08, 0x10); /* Select DAC outputs to line out */ +- au1550_delay(10); +- wrcodec(0x0a, 0x00); /* Disable output mute */ +- au1550_delay(10); +- wrcodec(0x05, 0x70); /* lower output volume on headphone */ +- au1550_delay(10); +- wrcodec(0x0e, 0x02); /* Set slave, 16-bit, I2S modes */ +- au1550_delay(10); +- wrcodec(0x10, 0x01); /* 12MHz (USB), 250fs */ +- au1550_delay(10); +- wrcodec(0x12, 0x01); /* Activate codec */ +- au1550_delay(10); ++ wrcodec(WM_REG_RESET, 0x00); /* Reset */ ++ wrcodec(WM_REG_POWER_DOWN_CTRL, 0x00); /* Power up everything */ ++ wrcodec(WM_REG_ACTIVE_CTRL, 0x00); /* Deactivate codec */ ++ wrcodec(WM_REG_ANALOGUE_AUDIO_PATH_CTRL, 0x10); /* Select DAC outputs to line out */ ++ wrcodec(WM_REG_DIGITAL_AUDIO_PATH_CTRL, 0x00); /* Disable output mute */ ++ wm_i2s_write_mixer(s, SOUND_MIXER_PCM, 74, 74); ++ wrcodec(WM_REG_DIGITAL_AUDIO_IF, 0x02); /* Set slave, 16-bit, I2S modes */ ++ wrcodec(WM_REG_ACTIVE_CTRL, 0x01); /* Activate codec */ + } + + /* stop the ADC before calling */ +@@ -256,27 +502,16 @@ + set_adc_rate(struct au1550_state *s, unsigned rate) + { + struct dmabuf *adc = &s->dma_adc; +- struct dmabuf *dac = &s->dma_dac; + +- if (s->no_vra) { +- /* calc SRC factor +- */ ++ #if defined(WM_MODE_USB) + adc->src_factor = (((SAMP_RATE*2) / rate) + 1) >> 1; + adc->sample_rate = SAMP_RATE / adc->src_factor; + return; +- } ++ #else ++ //TODO: Need code for normal mode ++ #endif + + adc->src_factor = 1; +- +- +-#if 0 +- rate = rate > SAMP_RATE ? SAMP_RATE : rate; +- +- wrcodec(0, 0); /* I don't yet know what to write here if we vra */ +- +- adc->sample_rate = rate; +- dac->sample_rate = rate; +-#endif + } + + /* stop the DAC before calling */ +@@ -284,26 +519,89 @@ + set_dac_rate(struct au1550_state *s, unsigned rate) + { + struct dmabuf *dac = &s->dma_dac; +- struct dmabuf *adc = &s->dma_adc; + +- if (s->no_vra) { +- /* calc SRC factor +- */ +- dac->src_factor = (((SAMP_RATE*2) / rate) + 1) >> 1; +- dac->sample_rate = SAMP_RATE / dac->src_factor; +- return; ++ u16 sr, ws, div, bosr, mode; ++ volatile psc_i2s_t* ip = (volatile psc_i2s_t *)I2S_PSC_BASE; ++ u32 cfg; ++ ++ #if defined(CONFIG_MIPS_FICMMP) ++ rate = ficmmp_set_i2s_sample_rate(rate); ++ #endif ++ ++ switch(rate) ++ { ++ case 96000: ++ sr = WM_SC_SR_96000; ++ ws = WS_64FS; ++ div = PSC_I2SCFG_DIV2; ++ break; ++ case 88200: ++ sr = WM_SC_SR_88200; ++ ws = WS_64FS; ++ div = PSC_I2SCFG_DIV2; ++ break; ++ case 44100: ++ sr = WM_SC_SR_44100; ++ ws = WS_128FS; ++ div = PSC_I2SCFG_DIV2; ++ break; ++ case 48000: ++ sr = WM_SC_SR_48000; ++ ws = WS_128FS; ++ div = PSC_I2SCFG_DIV2; ++ break; ++ case 32000: ++ sr = WM_SC_SR_32000; ++ ws = WS_96FS; ++ div = PSC_I2SCFG_DIV4; ++ break; ++ case 8018: ++ sr = WM_SC_SR_8018; ++ ws = WS_128FS; ++ div = PSC_I2SCFG_DIV2; ++ break; ++ case 8000: ++ default: ++ sr = WM_SC_SR_8000; ++ ws = WS_96FS; ++ div = PSC_I2SCFG_DIV16; ++ break; + } + ++ #if defined(WM_MODE_USB) ++ mode = WM_SC_MODE_USB; ++ #else ++ mode = WM_SC_MODE_NORMAL; ++ #endif ++ ++ bosr = 0; ++ + dac->src_factor = 1; ++ dac->sample_rate = rate; + +-#if 0 +- rate = rate > SAMP_RATE ? SAMP_RATE : rate; ++ /* Deactivate codec */ ++ wrcodec(WM_REG_ACTIVE_CTRL, 0x00); + +- wrcodec(0, 0); /* I don't yet know what to write here if we vra */ ++ /* Disable I2S controller */ ++ ip->psc_i2scfg &= ~PSC_I2SCFG_DE_ENABLE; ++ /* Wait for device disabled */ ++ while ((ip->psc_i2sstat & PSC_I2SSTAT_DR) == 1); ++ ++ cfg = ip->psc_i2scfg; ++ /* Clear WS and DIVIDER values */ ++ cfg &= ~(PSC_I2SCFG_WS_MASK | PSC_I2SCFG_DIV_MASK); ++ cfg |= PSC_I2SCFG_WS(ws) | div; ++ /* Reconfigure and enable */ ++ ip->psc_i2scfg = cfg | PSC_I2SCFG_DE_ENABLE; + +- adc->sample_rate = rate; +- dac->sample_rate = rate; +-#endif ++ /* Wait for device enabled */ ++ while ((ip->psc_i2sstat & PSC_I2SSTAT_DR) == 0); ++ ++ /* Set appropriate sampling rate */ ++ wrcodec(WM_REG_SAMPLING_CONTROL, bosr | mode | sr); ++ ++ /* Activate codec */ ++ wrcodec(WM_REG_ACTIVE_CTRL, 0x01); + } + + static void +@@ -354,8 +652,7 @@ + ip->psc_i2spcr = PSC_I2SPCR_RP; + au_sync(); + +- /* Wait for Receive Busy to show disabled. +- */ ++ /* Wait for Receive Busy to show disabled. */ + do { + stat = ip->psc_i2sstat; + au_sync(); +@@ -463,7 +760,6 @@ + if (db->num_channels == 1) + db->cnt_factor *= 2; + db->cnt_factor *= db->src_factor; +- + db->count = 0; + db->dma_qcount = 0; + db->nextIn = db->nextOut = db->rawbuf; +@@ -546,12 +842,13 @@ + if (i2s_stat & (PSC_I2SSTAT_TF | PSC_I2SSTAT_TR | PSC_I2SSTAT_TF)) + dbg("I2S status = 0x%08x", i2s_stat); + #endif ++ + db->dma_qcount--; + + if (db->count >= db->fragsize) { +- if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, +- db->fragsize) == 0) { +- err("qcount < 2 and no ring room!"); ++ if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, db->fragsize) == 0) ++ { ++ err("qcount < MIN_Q_COUNT and no ring room!"); + } + db->nextOut += db->fragsize; + if (db->nextOut >= db->rawbuf + db->dmasize) +@@ -606,65 +903,43 @@ + + } + +-static loff_t +-au1550_llseek(struct file *file, loff_t offset, int origin) +-{ +- return -ESPIPE; +-} +- +- +-#if 0 +-static int +-au1550_open_mixdev(struct inode *inode, struct file *file) +-{ +- file->private_data = &au1550_state; +- return 0; +-} +- +-static int +-au1550_release_mixdev(struct inode *inode, struct file *file) +-{ +- return 0; +-} +- +-static int +-mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, +- unsigned long arg) +-{ +- return codec->mixer_ioctl(codec, cmd, arg); +-} +- +-static int +-au1550_ioctl_mixdev(struct inode *inode, struct file *file, +- unsigned int cmd, unsigned long arg) +-{ +- struct au1550_state *s = (struct au1550_state *)file->private_data; +- struct ac97_codec *codec = s->codec; +- +- return mixdev_ioctl(codec, cmd, arg); +-} +- +-static /*const */ struct file_operations au1550_mixer_fops = { +- owner:THIS_MODULE, +- llseek:au1550_llseek, +- ioctl:au1550_ioctl_mixdev, +- open:au1550_open_mixdev, +- release:au1550_release_mixdev, +-}; +-#endif +- + static int + drain_dac(struct au1550_state *s, int nonblock) + { + unsigned long flags; + int count, tmo; + ++ struct dmabuf *db = &s->dma_dac; ++ ++ //DPRINTF(); + if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped) + return 0; + + for (;;) { + spin_lock_irqsave(&s->lock, flags); +- count = s->dma_dac.count; ++ count = db->count; ++ ++ /* Pad the ddma buffer with zeros if the amount remaining ++ * is not a multiple of fragsize */ ++ if(count % db->fragsize != 0) ++ { ++ int pad = db->fragsize - (count % db->fragsize); ++ char* bufptr = db->nextIn; ++ char* bufend = db->rawbuf + db->dmasize; ++ ++ if((bufend - bufptr) < pad) ++ printk("Error! ddma padding is bigger than available ring space!\n"); ++ else ++ { ++ memset((void*)bufptr, 0, pad); ++ count += pad; ++ db->nextIn += pad; ++ db->count += pad; ++ if (db->dma_qcount == 0) ++ start_dac(s); ++ db->dma_qcount++; ++ } ++ } + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; +@@ -672,9 +947,9 @@ + break; + if (nonblock) + return -EBUSY; +- tmo = 1000 * count / (s->no_vra ? +- SAMP_RATE : s->dma_dac.sample_rate); ++ tmo = 1000 * count / s->dma_dac.sample_rate; + tmo /= s->dma_dac.dma_bytes_per_sample; ++ + au1550_delay(tmo); + } + if (signal_pending(current)) +@@ -698,8 +973,7 @@ + * If interpolating (no VRA), duplicate every audio frame src_factor times. + */ + static int +-translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf, +- int dmacount) ++translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf, int dmacount) + { + int sample, i; + int interp_bytes_per_sample; +@@ -737,11 +1011,12 @@ + + /* duplicate every audio frame src_factor times + */ +- for (i = 0; i < db->src_factor; i++) ++ for (i = 0; i < db->src_factor; i++) { + memcpy(dmabuf, dmasample, db->dma_bytes_per_sample); ++ dmabuf += interp_bytes_per_sample; ++ } + + userbuf += db->user_bytes_per_sample; +- dmabuf += interp_bytes_per_sample; + } + + return num_samples * interp_bytes_per_sample; +@@ -996,15 +1271,14 @@ + * on the dma queue. If the queue count reaches zero, + * we know the dma has stopped. + */ +- while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { ++ while ((db->dma_qcount < MIN_Q_COUNT) && (db->count >= db->fragsize)) { + if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, + db->fragsize) == 0) { +- err("qcount < 2 and no ring room!"); ++ err("qcount < MIN_Q_COUNT and no ring room!"); + } + db->nextOut += db->fragsize; + if (db->nextOut >= db->rawbuf + db->dmasize) + db->nextOut -= db->dmasize; +- db->count -= db->fragsize; + db->total_bytes += db->dma_fragsize; + if (db->dma_qcount == 0) + start_dac(s); +@@ -1017,7 +1291,6 @@ + buffer += usercnt; + ret += usercnt; + } /* while (count > 0) */ +- + out: + up(&s->sem); + out2: +@@ -1371,9 +1644,6 @@ + s->dma_dac.cnt_factor; + abinfo.fragstotal = s->dma_dac.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; +-#ifdef AU1000_VERBOSE_DEBUG +- dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments); +-#endif + return copy_to_user((void *) arg, &abinfo, + sizeof(abinfo)) ? -EFAULT : 0; + +@@ -1536,13 +1806,9 @@ + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_FILTER: + return -EINVAL; ++ default: break; + } +- +-#if 0 +- return mixdev_ioctl(s->codec, cmd, arg); +-#else + return 0; +-#endif + } + + +@@ -1664,15 +1930,15 @@ + MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com"); + MODULE_DESCRIPTION("Au1550 Audio Driver"); + ++#if defined(WM_MODE_USB) + /* Set up an internal clock for the PSC3. This will then get + * driven out of the Au1550 as the master. + */ + static void + intclk_setup(void) + { +- uint clk, rate, stat; +- +- /* Wire up Freq4 as a clock for the PSC3. ++ uint clk, rate; ++ /* Wire up Freq4 as a clock for the PSC. + * We know SMBus uses Freq3. + * By making changes to this rate, plus the word strobe + * size, we can make fine adjustments to the actual data rate. +@@ -1700,11 +1966,17 @@ + */ + clk = au_readl(SYS_CLKSRC); + au_sync(); ++#if defined(CONFIG_SOC_AU1550) + clk &= ~0x01f00000; + clk |= (6 << 22); ++#elif defined(CONFIG_SOC_AU1200) ++ clk &= ~0x3e000000; ++ clk |= (6 << 27); ++#endif + au_writel(clk, SYS_CLKSRC); + au_sync(); + } ++#endif + + static int __devinit + au1550_probe(void) +@@ -1724,6 +1996,11 @@ + init_MUTEX(&s->open_sem); + spin_lock_init(&s->lock); + ++ /* CPLD Mux for I2s */ ++ ++#if defined(CONFIG_MIPS_PB1200) ++ bcsr->resets |= BCSR_RESETS_PCS1MUX; ++#endif + + s->psc_addr = (volatile psc_i2s_t *)I2S_PSC_BASE; + ip = s->psc_addr; +@@ -1765,9 +2042,8 @@ + + if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0) + goto err_dev1; +-#if 0 +- if ((s->codec->dev_mixer = +- register_sound_mixer(&au1550_mixer_fops, -1)) < 0) ++#if 1 ++ if ((s->dev_mixer = register_sound_mixer(&au1550_mixer_fops, -1)) < 0) + goto err_dev2; + #endif + +@@ -1777,7 +2053,6 @@ + proc_au1550_dump, NULL); + #endif /* AU1550_DEBUG */ + +- intclk_setup(); + + /* The GPIO for the appropriate PSC was configured by the + * board specific start up. +@@ -1786,7 +2061,12 @@ + */ + ip->psc_ctrl = PSC_CTRL_DISABLE; /* Disable PSC */ + au_sync(); ++#if defined(WM_MODE_USB) ++ intclk_setup(); + ip->psc_sel = (PSC_SEL_CLK_INTCLK | PSC_SEL_PS_I2SMODE); ++#else ++ ip->psc_sel = (PSC_SEL_CLK_EXTCLK | PSC_SEL_PS_I2SMODE); ++#endif + au_sync(); + + /* Enable PSC +@@ -1806,42 +2086,18 @@ + * Actual I2S mode (first bit delayed by one clock). + * Master mode (We provide the clock from the PSC). + */ +- val = PSC_I2SCFG_SET_LEN(16); +-#ifdef TRY_441KHz +- /* This really should be 250, but it appears that all of the +- * PLLs, dividers and so on in the chain shift it. That's the +- * problem with sourceing the clock instead of letting the very +- * stable codec provide it. But, the PSC doesn't appear to want +- * to work in slave mode, so this is what we get. It's not +- * studio quality timing, but it's good enough for listening +- * to mp3s. +- */ +- val |= PSC_I2SCFG_SET_WS(252); +-#else +- val |= PSC_I2SCFG_SET_WS(250); +-#endif +- val |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8 | \ ++ ++ val = PSC_I2SCFG_SET_LEN(16) | PSC_I2SCFG_WS(WS_128FS) | PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8 | \ + PSC_I2SCFG_BI | PSC_I2SCFG_XM; + +- ip->psc_i2scfg = val; +- au_sync(); +- val |= PSC_I2SCFG_DE_ENABLE; +- ip->psc_i2scfg = val; +- au_sync(); ++ ip->psc_i2scfg = val | PSC_I2SCFG_DE_ENABLE; + +- /* Wait for Device ready. +- */ +- do { +- val = ip->psc_i2sstat; +- au_sync(); +- } while ((val & PSC_I2SSTAT_DR) == 0); ++ set_dac_rate(s, 8000); //Set default rate + +- val = ip->psc_i2scfg; +- au_sync(); ++ codec_init(s); + +- codec_init(); ++ s->no_vra = vra ? 0 : 1; + +- s->no_vra = 1; + if (s->no_vra) + info("no VRA, interpolating and decimating"); + +@@ -1866,6 +2122,8 @@ + err_dev2: + unregister_sound_dsp(s->dev_audio); + #endif ++ err_dev2: ++ unregister_sound_dsp(s->dev_audio); + err_dev1: + au1xxx_dbdma_chan_free(s->dma_adc.dmanr); + err_dma2: +diff -Nur linux-2.4.32-rc1/drivers/sound/au1550_psc.c linux-2.4.32-rc1.mips/drivers/sound/au1550_psc.c +--- linux-2.4.32-rc1/drivers/sound/au1550_psc.c 2005-01-19 15:10:04.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/sound/au1550_psc.c 2005-01-30 09:01:28.000000000 +0100 +@@ -30,6 +30,7 @@ + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ ++ + #include + #include + #include +@@ -63,6 +64,14 @@ + #include + #endif + ++#ifdef CONFIG_MIPS_PB1200 ++#include ++#endif ++ ++#ifdef CONFIG_MIPS_DB1200 ++#include ++#endif ++ + #undef OSS_DOCUMENTED_MIXER_SEMANTICS + + #define AU1550_MODULE_NAME "Au1550 psc audio" +@@ -521,7 +530,14 @@ + spin_unlock_irqrestore(&s->lock, flags); + } + +- ++/* ++ NOTE: The xmit slots cannot be changed on the fly when in full-duplex ++ because the AC'97 block must be stopped/started. When using this driver ++ in full-duplex (in & out at the same time), the DMA engine will stop if ++ you disable the block. ++ TODO: change implementation to properly restart adc/dac after setting ++ xmit slots. ++*/ + static void + set_xmit_slots(int num_channels) + { +@@ -565,6 +581,14 @@ + } while ((stat & PSC_AC97STAT_DR) == 0); + } + ++/* ++ NOTE: The recv slots cannot be changed on the fly when in full-duplex ++ because the AC'97 block must be stopped/started. When using this driver ++ in full-duplex (in & out at the same time), the DMA engine will stop if ++ you disable the block. ++ TODO: change implementation to properly restart adc/dac after setting ++ recv slots. ++*/ + static void + set_recv_slots(int num_channels) + { +@@ -608,7 +632,6 @@ + + spin_lock_irqsave(&s->lock, flags); + +- set_xmit_slots(db->num_channels); + au_writel(PSC_AC97PCR_TC, PSC_AC97PCR); + au_sync(); + au_writel(PSC_AC97PCR_TS, PSC_AC97PCR); +@@ -640,7 +663,6 @@ + db->nextIn -= db->dmasize; + } + +- set_recv_slots(db->num_channels); + au1xxx_dbdma_start(db->dmanr); + au_writel(PSC_AC97PCR_RC, PSC_AC97PCR); + au_sync(); +@@ -752,12 +774,16 @@ + if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE)) + dbg("AC97C status = 0x%08x", ac97c_stat); + #endif ++ /* There is a possiblity that we are getting 1 interrupt for ++ multiple descriptors. Use ddma api to find out how many ++ completed. ++ */ + db->dma_qcount--; + + if (db->count >= db->fragsize) { + if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, + db->fragsize) == 0) { +- err("qcount < 2 and no ring room!"); ++ err("qcount < 2 and no ring room1!"); + } + db->nextOut += db->fragsize; + if (db->nextOut >= db->rawbuf + db->dmasize) +@@ -941,11 +967,12 @@ + + /* duplicate every audio frame src_factor times + */ +- for (i = 0; i < db->src_factor; i++) ++ for (i = 0; i < db->src_factor; i++) { + memcpy(dmabuf, dmasample, db->dma_bytes_per_sample); ++ dmabuf += interp_bytes_per_sample; ++ } + + userbuf += db->user_bytes_per_sample; +- dmabuf += interp_bytes_per_sample; + } + + return num_samples * interp_bytes_per_sample; +@@ -1203,7 +1230,7 @@ + while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { + if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, + db->fragsize) == 0) { +- err("qcount < 2 and no ring room!"); ++ err("qcount < 2 and no ring room!0"); + } + db->nextOut += db->fragsize; + if (db->nextOut >= db->rawbuf + db->dmasize) +@@ -1481,6 +1508,7 @@ + return -EINVAL; + stop_adc(s); + s->dma_adc.num_channels = val; ++ set_recv_slots(val); + if ((ret = prog_dmabuf_adc(s))) + return ret; + } +@@ -1538,6 +1566,7 @@ + } + + s->dma_dac.num_channels = val; ++ set_xmit_slots(val); + if ((ret = prog_dmabuf_dac(s))) + return ret; + } +@@ -1832,10 +1861,8 @@ + down(&s->open_sem); + } + +- stop_dac(s); +- stop_adc(s); +- + if (file->f_mode & FMODE_READ) { ++ stop_adc(s); + s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = + s->dma_adc.subdivision = s->dma_adc.total_bytes = 0; + s->dma_adc.num_channels = 1; +@@ -1846,6 +1873,7 @@ + } + + if (file->f_mode & FMODE_WRITE) { ++ stop_dac(s); + s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = + s->dma_dac.subdivision = s->dma_dac.total_bytes = 0; + s->dma_dac.num_channels = 1; +@@ -2091,6 +2119,9 @@ + ac97_read_proc, &s->codec); + #endif + ++ set_xmit_slots(1); ++ set_recv_slots(1); ++ + return 0; + + err_dev3: +diff -Nur linux-2.4.32-rc1/drivers/sound/Config.in linux-2.4.32-rc1.mips/drivers/sound/Config.in +--- linux-2.4.32-rc1/drivers/sound/Config.in 2005-01-19 15:10:04.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/sound/Config.in 2005-04-21 07:53:07.000000000 +0200 +@@ -72,10 +72,15 @@ + if [ "$CONFIG_DDB5477" = "y" ]; then + dep_tristate ' NEC Vrc5477 AC97 sound' CONFIG_SOUND_VRC5477 $CONFIG_SOUND + fi +-if [ "$CONFIG_SOC_AU1X00" = "y" -o "$CONFIG_SOC_AU1500" = "y" ]; then +- dep_tristate ' Au1x00 Sound' CONFIG_SOUND_AU1X00 $CONFIG_SOUND +- dep_tristate ' Au1550 PSC Sound' CONFIG_SOUND_AU1550_PSC $CONFIG_SOUND +- dep_tristate ' Au1550 I2S Sound' CONFIG_SOUND_AU1550_I2S $CONFIG_SOUND ++if [ "$CONFIG_SOC_AU1000" = "y" -o \ ++ "$CONFIG_SOC_AU1500" = "y" -o \ ++ "$CONFIG_SOC_AU1100" = "y" ]; then ++ dep_tristate ' Au1x00 AC97 Sound' CONFIG_SOUND_AU1X00 $CONFIG_SOUND ++fi ++if [ "$CONFIG_SOC_AU1550" = "y" -o \ ++ "$CONFIG_SOC_AU1200" = "y" ]; then ++ dep_tristate ' Au1550/Au1200 PSC AC97 Sound' CONFIG_SOUND_AU1550_PSC $CONFIG_SOUND ++ dep_tristate ' Au1550/Au1200 PSC I2S Sound' CONFIG_SOUND_AU1550_I2S $CONFIG_SOUND + fi + + dep_tristate ' Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND $CONFIG_PCI +diff -Nur linux-2.4.32-rc1/drivers/tc/lk201.c linux-2.4.32-rc1.mips/drivers/tc/lk201.c +--- linux-2.4.32-rc1/drivers/tc/lk201.c 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/tc/lk201.c 2004-09-28 02:53:04.000000000 +0200 +@@ -5,7 +5,7 @@ + * for more details. + * + * Copyright (C) 1999-2002 Harald Koerfgen +- * Copyright (C) 2001, 2002, 2003 Maciej W. Rozycki ++ * Copyright (C) 2001, 2002, 2003, 2004 Maciej W. Rozycki + */ + + #include +@@ -23,8 +23,8 @@ + #include + #include + #include ++#include + +-#include "zs.h" + #include "lk201.h" + + /* +@@ -55,19 +55,20 @@ + unsigned char kbd_sysrq_key = -1; + #endif + +-#define KEYB_LINE 3 ++#define KEYB_LINE_ZS 3 ++#define KEYB_LINE_DZ 0 + +-static int __init lk201_init(struct dec_serial *); +-static void __init lk201_info(struct dec_serial *); +-static void lk201_kbd_rx_char(unsigned char, unsigned char); ++static int __init lk201_init(void *); ++static void __init lk201_info(void *); ++static void lk201_rx_char(unsigned char, unsigned char); + +-struct zs_hook lk201_kbdhook = { ++static struct dec_serial_hook lk201_hook = { + .init_channel = lk201_init, + .init_info = lk201_info, + .rx_char = NULL, + .poll_rx_char = NULL, + .poll_tx_char = NULL, +- .cflags = B4800 | CS8 | CSTOPB | CLOCAL ++ .cflags = B4800 | CS8 | CSTOPB | CLOCAL, + }; + + /* +@@ -93,28 +94,28 @@ + LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4), + }; + +-static struct dec_serial* lk201kbd_info; ++static void *lk201_handle; + +-static int lk201_send(struct dec_serial *info, unsigned char ch) ++static int lk201_send(unsigned char ch) + { +- if (info->hook->poll_tx_char(info, ch)) { ++ if (lk201_hook.poll_tx_char(lk201_handle, ch)) { + printk(KERN_ERR "lk201: transmit timeout\n"); + return -EIO; + } + return 0; + } + +-static inline int lk201_get_id(struct dec_serial *info) ++static inline int lk201_get_id(void) + { +- return lk201_send(info, LK_CMD_REQ_ID); ++ return lk201_send(LK_CMD_REQ_ID); + } + +-static int lk201_reset(struct dec_serial *info) ++static int lk201_reset(void) + { + int i, r; + + for (i = 0; i < sizeof(lk201_reset_string); i++) { +- r = lk201_send(info, lk201_reset_string[i]); ++ r = lk201_send(lk201_reset_string[i]); + if (r < 0) + return r; + } +@@ -203,24 +204,26 @@ + + static int write_kbd_rate(struct kbd_repeat *rep) + { +- struct dec_serial* info = lk201kbd_info; + int delay, rate; + int i; + + delay = rep->delay / 5; + rate = rep->rate; + for (i = 0; i < 4; i++) { +- if (info->hook->poll_tx_char(info, LK_CMD_RPT_RATE(i))) ++ if (lk201_hook.poll_tx_char(lk201_handle, ++ LK_CMD_RPT_RATE(i))) + return 1; +- if (info->hook->poll_tx_char(info, LK_PARAM_DELAY(delay))) ++ if (lk201_hook.poll_tx_char(lk201_handle, ++ LK_PARAM_DELAY(delay))) + return 1; +- if (info->hook->poll_tx_char(info, LK_PARAM_RATE(rate))) ++ if (lk201_hook.poll_tx_char(lk201_handle, ++ LK_PARAM_RATE(rate))) + return 1; + } + return 0; + } + +-static int lk201kbd_rate(struct kbd_repeat *rep) ++static int lk201_kbd_rate(struct kbd_repeat *rep) + { + if (rep == NULL) + return -EINVAL; +@@ -237,10 +240,8 @@ + return 0; + } + +-static void lk201kd_mksound(unsigned int hz, unsigned int ticks) ++static void lk201_kd_mksound(unsigned int hz, unsigned int ticks) + { +- struct dec_serial* info = lk201kbd_info; +- + if (!ticks) + return; + +@@ -253,20 +254,19 @@ + ticks = 7; + ticks = 7 - ticks; + +- if (info->hook->poll_tx_char(info, LK_CMD_ENB_BELL)) ++ if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_ENB_BELL)) + return; +- if (info->hook->poll_tx_char(info, LK_PARAM_VOLUME(ticks))) ++ if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_VOLUME(ticks))) + return; +- if (info->hook->poll_tx_char(info, LK_CMD_BELL)) ++ if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_BELL)) + return; + } + + void kbd_leds(unsigned char leds) + { +- struct dec_serial* info = lk201kbd_info; + unsigned char l = 0; + +- if (!info) /* FIXME */ ++ if (!lk201_handle) /* FIXME */ + return; + + /* FIXME -- Only Hold and Lock LEDs for now. --macro */ +@@ -275,13 +275,13 @@ + if (leds & LED_CAP) + l |= LK_LED_LOCK; + +- if (info->hook->poll_tx_char(info, LK_CMD_LEDS_ON)) ++ if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_ON)) + return; +- if (info->hook->poll_tx_char(info, LK_PARAM_LED_MASK(l))) ++ if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(l))) + return; +- if (info->hook->poll_tx_char(info, LK_CMD_LEDS_OFF)) ++ if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_OFF)) + return; +- if (info->hook->poll_tx_char(info, LK_PARAM_LED_MASK(~l))) ++ if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(~l))) + return; + } + +@@ -307,7 +307,7 @@ + return 0x80; + } + +-static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat) ++static void lk201_rx_char(unsigned char ch, unsigned char fl) + { + static unsigned char id[6]; + static int id_i; +@@ -316,9 +316,8 @@ + static int prev_scancode; + unsigned char c = scancodeRemap[ch]; + +- if (stat && stat != TTY_OVERRUN) { +- printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", +- stat); ++ if (fl != TTY_NORMAL && fl != TTY_OVERRUN) { ++ printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl); + return; + } + +@@ -335,7 +334,7 @@ + /* OK, the power-up concluded. */ + lk201_report(id); + if (id[2] == LK_STAT_PWRUP_OK) +- lk201_get_id(lk201kbd_info); ++ lk201_get_id(); + else { + id_i = 0; + printk(KERN_ERR "lk201: keyboard power-up " +@@ -345,7 +344,7 @@ + /* We got the ID; report it and start operation. */ + id_i = 0; + lk201_id(id); +- lk201_reset(lk201kbd_info); ++ lk201_reset(); + } + return; + } +@@ -398,29 +397,28 @@ + tasklet_schedule(&keyboard_tasklet); + } + +-static void __init lk201_info(struct dec_serial *info) ++static void __init lk201_info(void *handle) + { + } + +-static int __init lk201_init(struct dec_serial *info) ++static int __init lk201_init(void *handle) + { + /* First install handlers. */ +- lk201kbd_info = info; +- kbd_rate = lk201kbd_rate; +- kd_mksound = lk201kd_mksound; ++ lk201_handle = handle; ++ kbd_rate = lk201_kbd_rate; ++ kd_mksound = lk201_kd_mksound; + +- info->hook->rx_char = lk201_kbd_rx_char; ++ lk201_hook.rx_char = lk201_rx_char; + + /* Then just issue a reset -- the handlers will do the rest. */ +- lk201_send(info, LK_CMD_POWER_UP); ++ lk201_send(LK_CMD_POWER_UP); + + return 0; + } + + void __init kbd_init_hw(void) + { +- extern int register_zs_hook(unsigned int, struct zs_hook *); +- extern int unregister_zs_hook(unsigned int); ++ int keyb_line; + + /* Maxine uses LK501 at the Access.Bus. */ + if (!LK_IFACE) +@@ -428,19 +426,15 @@ + + printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n"); + +- if (LK_IFACE_ZS) { +- /* +- * kbd_init_hw() is being called before +- * rs_init() so just register the kbd hook +- * and let zs_init do the rest :-) +- */ +- if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook)) +- unregister_zs_hook(KEYB_LINE); +- } else { +- /* +- * TODO: modify dz.c to allow similar hooks +- * for LK201 handling on DS2100, DS3100, and DS5000/200 +- */ +- printk(KERN_ERR "lk201: support for DZ11 not yet ready.\n"); +- } ++ /* ++ * kbd_init_hw() is being called before ++ * rs_init() so just register the kbd hook ++ * and let zs_init do the rest :-) ++ */ ++ if (LK_IFACE_ZS) ++ keyb_line = KEYB_LINE_ZS; ++ else ++ keyb_line = KEYB_LINE_DZ; ++ if (!register_dec_serial_hook(keyb_line, &lk201_hook)) ++ unregister_dec_serial_hook(keyb_line); + } +diff -Nur linux-2.4.32-rc1/drivers/tc/zs.c linux-2.4.32-rc1.mips/drivers/tc/zs.c +--- linux-2.4.32-rc1/drivers/tc/zs.c 2005-01-19 15:10:05.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/tc/zs.c 2004-12-27 05:13:50.000000000 +0100 +@@ -68,6 +68,8 @@ + #include + #include + #include ++#include ++ + #ifdef CONFIG_DECSTATION + #include + #include +@@ -160,8 +162,8 @@ + #ifdef CONFIG_SERIAL_DEC_CONSOLE + static struct console sercons; + #endif +-#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) \ +- && !defined(MODULE) ++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ ++ !defined(MODULE) + static unsigned long break_pressed; /* break, really ... */ + #endif + +@@ -196,7 +198,6 @@ + /* + * Debugging. + */ +-#undef SERIAL_DEBUG_INTR + #undef SERIAL_DEBUG_OPEN + #undef SERIAL_DEBUG_FLOW + #undef SERIAL_DEBUG_THROTTLE +@@ -221,10 +222,6 @@ + static struct termios *serial_termios[NUM_CHANNELS]; + static struct termios *serial_termios_locked[NUM_CHANNELS]; + +-#ifndef MIN +-#define MIN(a,b) ((a) < (b) ? (a) : (b)) +-#endif +- + /* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the copy_from_user blocks while swapping in a page, +@@ -386,8 +383,6 @@ + * ----------------------------------------------------------------------- + */ + +-static int tty_break; /* Set whenever BREAK condition is detected. */ +- + /* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. +@@ -414,20 +409,15 @@ + if (!tty && (!info->hook || !info->hook->rx_char)) + continue; + +- if (tty_break) { +- tty_break = 0; +-#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE) +- if (info->line == sercons.index) { +- if (!break_pressed) { +- break_pressed = jiffies; +- goto ignore_char; +- } +- break_pressed = 0; +- } +-#endif ++ flag = TTY_NORMAL; ++ if (info->tty_break) { ++ info->tty_break = 0; + flag = TTY_BREAK; + if (info->flags & ZILOG_SAK) + do_SAK(tty); ++ /* Ignore the null char got when BREAK is removed. */ ++ if (ch == 0) ++ continue; + } else { + if (stat & Rx_OVR) { + flag = TTY_OVERRUN; +@@ -435,20 +425,22 @@ + flag = TTY_FRAME; + } else if (stat & PAR_ERR) { + flag = TTY_PARITY; +- } else +- flag = 0; +- if (flag) ++ } ++ if (flag != TTY_NORMAL) + /* reset the error indication */ + write_zsreg(info->zs_channel, R0, ERR_RES); + } + +-#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE) ++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ ++ !defined(MODULE) + if (break_pressed && info->line == sercons.index) { +- if (ch != 0 && +- time_before(jiffies, break_pressed + HZ*5)) { ++ /* Ignore the null char got when BREAK is removed. */ ++ if (ch == 0) ++ continue; ++ if (time_before(jiffies, break_pressed + HZ * 5)) { + handle_sysrq(ch, regs, NULL, NULL); + break_pressed = 0; +- goto ignore_char; ++ continue; + } + break_pressed = 0; + } +@@ -459,23 +451,7 @@ + return; + } + +- if (tty->flip.count >= TTY_FLIPBUF_SIZE) { +- static int flip_buf_ovf; +- ++flip_buf_ovf; +- continue; +- } +- tty->flip.count++; +- { +- static int flip_max_cnt; +- if (flip_max_cnt < tty->flip.count) +- flip_max_cnt = tty->flip.count; +- } +- +- *tty->flip.flag_buf_ptr++ = flag; +- *tty->flip.char_buf_ptr++ = ch; +-#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE) +- ignore_char: +-#endif ++ tty_insert_flip_char(tty, ch, flag); + } + if (tty) + tty_flip_buffer_push(tty); +@@ -517,11 +493,15 @@ + /* Get status from Read Register 0 */ + stat = read_zsreg(info->zs_channel, R0); + +- if (stat & BRK_ABRT) { +-#ifdef SERIAL_DEBUG_INTR +- printk("handling break...."); ++ if ((stat & BRK_ABRT) && !(info->read_reg_zero & BRK_ABRT)) { ++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \ ++ !defined(MODULE) ++ if (info->line == sercons.index) { ++ if (!break_pressed) ++ break_pressed = jiffies; ++ } else + #endif +- tty_break = 1; ++ info->tty_break = 1; + } + + if (info->zs_channel != info->zs_chan_a) { +@@ -957,7 +937,7 @@ + save_flags(flags); + while (1) { + cli(); +- c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, ++ c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; +@@ -965,7 +945,7 @@ + if (from_user) { + down(&tmp_buf_sem); + copy_from_user(tmp_buf, buf, c); +- c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, ++ c = min(c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + up(&tmp_buf_sem); +@@ -1282,46 +1262,48 @@ + } + + switch (cmd) { +- case TIOCMGET: +- error = verify_area(VERIFY_WRITE, (void *) arg, +- sizeof(unsigned int)); +- if (error) +- return error; +- return get_modem_info(info, (unsigned int *) arg); +- case TIOCMBIS: +- case TIOCMBIC: +- case TIOCMSET: +- return set_modem_info(info, cmd, (unsigned int *) arg); +- case TIOCGSERIAL: +- error = verify_area(VERIFY_WRITE, (void *) arg, +- sizeof(struct serial_struct)); +- if (error) +- return error; +- return get_serial_info(info, +- (struct serial_struct *) arg); +- case TIOCSSERIAL: +- return set_serial_info(info, +- (struct serial_struct *) arg); +- case TIOCSERGETLSR: /* Get line status register */ +- error = verify_area(VERIFY_WRITE, (void *) arg, +- sizeof(unsigned int)); +- if (error) +- return error; +- else +- return get_lsr_info(info, (unsigned int *) arg); ++ case TIOCMGET: ++ error = verify_area(VERIFY_WRITE, (void *)arg, ++ sizeof(unsigned int)); ++ if (error) ++ return error; ++ return get_modem_info(info, (unsigned int *)arg); + +- case TIOCSERGSTRUCT: +- error = verify_area(VERIFY_WRITE, (void *) arg, +- sizeof(struct dec_serial)); +- if (error) +- return error; +- copy_from_user((struct dec_serial *) arg, +- info, sizeof(struct dec_serial)); +- return 0; ++ case TIOCMBIS: ++ case TIOCMBIC: ++ case TIOCMSET: ++ return set_modem_info(info, cmd, (unsigned int *)arg); + +- default: +- return -ENOIOCTLCMD; +- } ++ case TIOCGSERIAL: ++ error = verify_area(VERIFY_WRITE, (void *)arg, ++ sizeof(struct serial_struct)); ++ if (error) ++ return error; ++ return get_serial_info(info, (struct serial_struct *)arg); ++ ++ case TIOCSSERIAL: ++ return set_serial_info(info, (struct serial_struct *)arg); ++ ++ case TIOCSERGETLSR: /* Get line status register */ ++ error = verify_area(VERIFY_WRITE, (void *)arg, ++ sizeof(unsigned int)); ++ if (error) ++ return error; ++ else ++ return get_lsr_info(info, (unsigned int *)arg); ++ ++ case TIOCSERGSTRUCT: ++ error = verify_area(VERIFY_WRITE, (void *)arg, ++ sizeof(struct dec_serial)); ++ if (error) ++ return error; ++ copy_from_user((struct dec_serial *)arg, info, ++ sizeof(struct dec_serial)); ++ return 0; ++ ++ default: ++ return -ENOIOCTLCMD; ++ } + return 0; + } + +@@ -1446,7 +1428,8 @@ + static void rs_wait_until_sent(struct tty_struct *tty, int timeout) + { + struct dec_serial *info = (struct dec_serial *) tty->driver_data; +- unsigned long orig_jiffies, char_time; ++ unsigned long orig_jiffies; ++ int char_time; + + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) + return; +@@ -1462,7 +1445,7 @@ + if (char_time == 0) + char_time = 1; + if (timeout) +- char_time = MIN(char_time, timeout); ++ char_time = min(char_time, timeout); + while ((read_zsreg(info->zs_channel, 1) & Tx_BUF_EMP) == 0) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(char_time); +@@ -1714,7 +1697,7 @@ + + static void __init show_serial_version(void) + { +- printk("DECstation Z8530 serial driver version 0.08\n"); ++ printk("DECstation Z8530 serial driver version 0.09\n"); + } + + /* Initialize Z8530s zs_channels +@@ -1994,8 +1977,9 @@ + * polling I/O routines + */ + static int +-zs_poll_tx_char(struct dec_serial *info, unsigned char ch) ++zs_poll_tx_char(void *handle, unsigned char ch) + { ++ struct dec_serial *info = handle; + struct dec_zschannel *chan = info->zs_channel; + int ret; + +@@ -2017,8 +2001,9 @@ + } + + static int +-zs_poll_rx_char(struct dec_serial *info) ++zs_poll_rx_char(void *handle) + { ++ struct dec_serial *info = handle; + struct dec_zschannel *chan = info->zs_channel; + int ret; + +@@ -2038,12 +2023,13 @@ + return -ENODEV; + } + +-unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook) ++int register_zs_hook(unsigned int channel, struct dec_serial_hook *hook) + { + struct dec_serial *info = &zs_soft[channel]; + + if (info->hook) { +- printk(__FUNCTION__": line %d has already a hook registered\n", channel); ++ printk("%s: line %d has already a hook registered\n", ++ __FUNCTION__, channel); + + return 0; + } else { +@@ -2055,7 +2041,7 @@ + } + } + +-unsigned int unregister_zs_hook(unsigned int channel) ++int unregister_zs_hook(unsigned int channel) + { + struct dec_serial *info = &zs_soft[channel]; + +@@ -2063,8 +2049,8 @@ + info->hook = NULL; + return 1; + } else { +- printk(__FUNCTION__": trying to unregister hook on line %d," +- " but none is registered\n", channel); ++ printk("%s: trying to unregister hook on line %d," ++ " but none is registered\n", __FUNCTION__, channel); + return 0; + } + } +@@ -2319,22 +2305,23 @@ + write_zsreg(chan, 9, nine); + } + +-static int kgdbhook_init_channel(struct dec_serial* info) ++static int kgdbhook_init_channel(void *handle) + { + return 0; + } + +-static void kgdbhook_init_info(struct dec_serial* info) ++static void kgdbhook_init_info(void *handle) + { + } + +-static void kgdbhook_rx_char(struct dec_serial* info, +- unsigned char ch, unsigned char stat) ++static void kgdbhook_rx_char(void *handle, unsigned char ch, unsigned char fl) + { ++ struct dec_serial *info = handle; ++ ++ if (fl != TTY_NORMAL) ++ return; + if (ch == 0x03 || ch == '$') + breakpoint(); +- if (stat & (Rx_OVR|FRM_ERR|PAR_ERR)) +- write_zsreg(info->zs_channel, 0, ERR_RES); + } + + /* This sets up the serial port we're using, and turns on +@@ -2360,11 +2347,11 @@ + * for /dev/ttyb which is determined in setup_arch() from the + * boot command line flags. + */ +-struct zs_hook zs_kgdbhook = { +- init_channel : kgdbhook_init_channel, +- init_info : kgdbhook_init_info, +- cflags : B38400|CS8|CLOCAL, +- rx_char : kgdbhook_rx_char, ++struct dec_serial_hook zs_kgdbhook = { ++ .init_channel = kgdbhook_init_channel, ++ .init_info = kgdbhook_init_info, ++ .rx_char = kgdbhook_rx_char, ++ .cflags = B38400 | CS8 | CLOCAL, + } + + void __init zs_kgdb_hook(int tty_num) +diff -Nur linux-2.4.32-rc1/drivers/tc/zs.h linux-2.4.32-rc1.mips/drivers/tc/zs.h +--- linux-2.4.32-rc1/drivers/tc/zs.h 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/tc/zs.h 2004-07-01 15:28:54.000000000 +0200 +@@ -1,14 +1,18 @@ + /* +- * macserial.h: Definitions for the Macintosh Z8530 serial driver. ++ * drivers/tc/zs.h: Definitions for the DECstation Z85C30 serial driver. + * + * Adapted from drivers/sbus/char/sunserial.h by Paul Mackerras. ++ * Adapted from drivers/macintosh/macserial.h by Harald Koerfgen. + * + * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) ++ * Copyright (C) 2004 Maciej W. Rozycki + */ + #ifndef _DECSERIAL_H + #define _DECSERIAL_H + ++#include ++ + #define NUM_ZSREGS 16 + + struct serial_struct { +@@ -89,63 +93,50 @@ + unsigned char curregs[NUM_ZSREGS]; + }; + +-struct dec_serial; +- +-struct zs_hook { +- int (*init_channel)(struct dec_serial* info); +- void (*init_info)(struct dec_serial* info); +- void (*rx_char)(unsigned char ch, unsigned char stat); +- int (*poll_rx_char)(struct dec_serial* info); +- int (*poll_tx_char)(struct dec_serial* info, +- unsigned char ch); +- unsigned cflags; +-}; +- + struct dec_serial { +- struct dec_serial *zs_next; /* For IRQ servicing chain */ +- struct dec_zschannel *zs_channel; /* Channel registers */ +- struct dec_zschannel *zs_chan_a; /* A side registers */ +- unsigned char read_reg_zero; +- +- char soft_carrier; /* Use soft carrier on this channel */ +- char break_abort; /* Is serial console in, so process brk/abrt */ +- struct zs_hook *hook; /* Hook on this channel */ +- char is_cons; /* Is this our console. */ +- unsigned char tx_active; /* character is being xmitted */ +- unsigned char tx_stopped; /* output is suspended */ +- +- /* We need to know the current clock divisor +- * to read the bps rate the chip has currently +- * loaded. ++ struct dec_serial *zs_next; /* For IRQ servicing chain. */ ++ struct dec_zschannel *zs_channel; /* Channel registers. */ ++ struct dec_zschannel *zs_chan_a; /* A side registers. */ ++ unsigned char read_reg_zero; ++ ++ struct dec_serial_hook *hook; /* Hook on this channel. */ ++ int tty_break; /* Set on BREAK condition. */ ++ int is_cons; /* Is this our console. */ ++ int tx_active; /* Char is being xmitted. */ ++ int tx_stopped; /* Output is suspended. */ ++ ++ /* ++ * We need to know the current clock divisor ++ * to read the bps rate the chip has currently loaded. + */ +- unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */ +- int zs_baud; ++ int clk_divisor; /* May be 1, 16, 32, or 64. */ ++ int zs_baud; + +- char change_needed; ++ char change_needed; + + int magic; + int baud_base; + int port; + int irq; +- int flags; /* defined in tty.h */ +- int type; /* UART type */ ++ int flags; /* Defined in tty.h. */ ++ int type; /* UART type. */ + struct tty_struct *tty; + int read_status_mask; + int ignore_status_mask; + int timeout; + int xmit_fifo_size; + int custom_divisor; +- int x_char; /* xon/xoff character */ ++ int x_char; /* XON/XOFF character. */ + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + unsigned long event; + unsigned long last_active; + int line; +- int count; /* # of fd on device */ +- int blocked_open; /* # of blocked opens */ +- long session; /* Session of opening process */ +- long pgrp; /* pgrp of opening process */ ++ int count; /* # of fds on device. */ ++ int blocked_open; /* # of blocked opens. */ ++ long session; /* Sess of opening process. */ ++ long pgrp; /* Pgrp of opening process. */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; +diff -Nur linux-2.4.32-rc1/drivers/video/au1200fb.c linux-2.4.32-rc1.mips/drivers/video/au1200fb.c +--- linux-2.4.32-rc1/drivers/video/au1200fb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-rc1.mips/drivers/video/au1200fb.c 2005-03-13 09:04:16.000000000 +0100 +@@ -0,0 +1,1564 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * Au1200 LCD Driver. ++ * ++ * Copyright 2004 AMD ++ * Author: AMD ++ * ++ * Based on: ++ * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device ++ * Created 28 Dec 1997 by Geert Uytterhoeven ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include "au1200fb.h" ++ ++#include