diff -urN linux-original/arch/ppc/Kconfig linux/arch/ppc/Kconfig --- linux-original/arch/ppc/Kconfig 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/Kconfig 2005-07-08 08:55:27.000000000 -0400 @@ -628,6 +628,15 @@ End of Life: - URL: +config IOMEGA8241 + bool "IOMEGA8241" + ---help--- + Iomega StorCenter Network Hard Drive + Manufacturer: Iomega Corporation + Date of Release: May 2005 + End of Life: - + URL: + config SBS8260 bool "SBS8260" @@ -755,7 +764,7 @@ depends on SANDPOINT || MCPN765 || SPRUCE || PPLUS || PCORE || \ PRPMC750 || K2 || PRPMC800 || LOPEC || \ (EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \ - 83xx + 83xx || IOMEGA8241 default y config FORCE @@ -823,7 +832,7 @@ config MPC10X_BRIDGE bool - depends on PCORE || POWERPMC250 || LOPEC || SANDPOINT + depends on PCORE || POWERPMC250 || LOPEC || SANDPOINT || IOMEGA8241 default y config FSL_OCP @@ -833,7 +842,7 @@ config MPC10X_OPENPIC bool - depends on POWERPMC250 || LOPEC || SANDPOINT + depends on POWERPMC250 || LOPEC || SANDPOINT || IOMEGA8241 default y config MPC10X_STORE_GATHERING diff -urN linux-original/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile --- linux-original/arch/ppc/boot/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/boot/Makefile 2005-07-08 08:55:27.000000000 -0400 @@ -13,7 +13,7 @@ CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include HOSTCFLAGS += -Iarch/$(ARCH)/boot/include -BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd uImage bootdir-y := simple bootdir-$(CONFIG_PPC_OF) += openfirmware diff -urN linux-original/arch/ppc/boot/simple/Makefile linux/arch/ppc/boot/simple/Makefile --- linux-original/arch/ppc/boot/simple/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/boot/simple/Makefile 2005-07-08 08:55:27.000000000 -0400 @@ -135,6 +135,10 @@ end-$(CONFIG_SANDPOINT) := sandpoint cacheflag-$(CONFIG_SANDPOINT) := -include $(clear_L2_L3) + end-$(CONFIG_IOMEGA8241) := iomega8241 + cacheflag-$(CONFIG_IOMEGA8241) := -include $(clear_L2_L3) + + zimage-$(CONFIG_SPRUCE) := zImage-TREE zimageinitrd-$(CONFIG_SPRUCE) := zImage.initrd-TREE end-$(CONFIG_SPRUCE) := spruce diff -urN linux-original/arch/ppc/configs/iomega8241_defconfig linux/arch/ppc/configs/iomega8241_defconfig --- linux-original/arch/ppc/configs/iomega8241_defconfig 1969-12-31 19:00:00.000000000 -0500 +++ linux/arch/ppc/configs/iomega8241_defconfig 2005-08-08 13:13:35.000000000 -0400 @@ -0,0 +1,1094 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12 +# Mon Jul 18 11:03:36 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +# CONFIG_KOBJECT_UEVENT is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +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=y + +# +# Processor +# +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_E500 is not set +CONFIG_PPC_FPU=y +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set +# CONFIG_CPU_FREQ is not set +CONFIG_PPC_GEN550=y +# CONFIG_PM is not set +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +# CONFIG_PPC_MULTIPLATFORM is not set +# CONFIG_APUS is not set +# CONFIG_KATANA is not set +# CONFIG_WILLOW is not set +# CONFIG_CPCI690 is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_CHESTNUT is not set +# CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_RADSTONE_PPC7D is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +CONFIG_IOMEGA8241=y +# CONFIG_SBS8260 is not set +# CONFIG_RPX8260 is not set +# CONFIG_TQM8260 is not set +# CONFIG_ADS8272 is not set +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_MPC834x_SYS is not set +CONFIG_MPC10X_BRIDGE=y +CONFIG_FSL_OCP=y +CONFIG_MPC10X_OPENPIC=y +# CONFIG_MPC10X_STORE_GATHERING is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=/dev/ttyS0,115200" +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCI_NAMES is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_FTL=y +CONFIG_NFTL=y +CONFIG_NFTL_RW=y +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +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 is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xFF800000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +CONFIG_MTD_IOMEGA8241=y + +# +# 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 + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_LBD=y +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# 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_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_OFFBOARD=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX 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_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +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_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# 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 is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET 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=y +# CONFIG_R8169_NAPI is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# 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 is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT 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_NR_UARTS=2 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA 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=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X 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_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_ISA is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_DS1337=y +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_M41T00 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# 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=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +# 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 + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# 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_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL 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_TEST is not set + +# +# USB ATM/DSL drivers +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_NET2280=y +CONFIG_USB_NET2280=y +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# 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=y +CONFIG_JFFS_FS_VERBOSE=0 +CONFIG_JFFS_PROC_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# 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 + +# +# 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 is not set +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=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# 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_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# 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=y + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y + +# +# 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_SERIAL_TEXT_DEBUG=y +CONFIG_PPC_OCP=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff -urN linux-original/arch/ppc/configs/iomega8241m_defconfig linux/arch/ppc/configs/iomega8241m_defconfig --- linux-original/arch/ppc/configs/iomega8241m_defconfig 1969-12-31 19:00:00.000000000 -0500 +++ linux/arch/ppc/configs/iomega8241m_defconfig 2005-08-18 09:46:48.000000000 -0400 @@ -0,0 +1,1104 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12 +# Mon Aug 15 10:22:39 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +# CONFIG_KOBJECT_UEVENT is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +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=y + +# +# Processor +# +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_E500 is not set +CONFIG_PPC_FPU=y +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set +# CONFIG_CPU_FREQ is not set +CONFIG_PPC_GEN550=y +# CONFIG_PM is not set +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +# CONFIG_PPC_MULTIPLATFORM is not set +# CONFIG_APUS is not set +# CONFIG_KATANA is not set +# CONFIG_WILLOW is not set +# CONFIG_CPCI690 is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_CHESTNUT is not set +# CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_RADSTONE_PPC7D is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +CONFIG_IOMEGA8241=y +# CONFIG_SBS8260 is not set +# CONFIG_RPX8260 is not set +# CONFIG_TQM8260 is not set +# CONFIG_ADS8272 is not set +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_MPC834x_SYS is not set +CONFIG_MPC10X_BRIDGE=y +CONFIG_FSL_OCP=y +CONFIG_MPC10X_OPENPIC=y +# CONFIG_MPC10X_STORE_GATHERING is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=/dev/ttyS0,115200" +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCI_NAMES is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_FTL=y +CONFIG_NFTL=y +CONFIG_NFTL_RW=y +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +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 is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xFF800000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +CONFIG_MTD_IOMEGA8241=y + +# +# 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 + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_LBD=y +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# 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_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_OFFBOARD=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX 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_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_BLK_DEV_DM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +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_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# 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 is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET 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=y +# CONFIG_R8169_NAPI is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# 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 is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT 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_NR_UARTS=2 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA 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=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X 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_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_ISA is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +CONFIG_I2C_SENSOR=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +CONFIG_SENSORS_DS1337=y +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_M41T00 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# 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=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=y + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +# 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 + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# 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_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL 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_TEST is not set + +# +# USB ATM/DSL drivers +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_NET2280=y +CONFIG_USB_NET2280=y +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_QUOTA=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# 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=y +CONFIG_JFFS_FS_VERBOSE=0 +CONFIG_JFFS_PROC_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_CRAMFS=y +# 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 + +# +# 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 is not set +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=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# 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_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# 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=y + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y + +# +# 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_SERIAL_TEXT_DEBUG=y +CONFIG_PPC_OCP=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff -urN linux-original/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile --- linux-original/arch/ppc/kernel/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/kernel/Makefile 2005-07-08 08:55:27.000000000 -0400 @@ -31,4 +31,3 @@ ifndef CONFIG_MATH_EMULATION obj-$(CONFIG_8xx) += softemu8xx.o endif - diff -urN linux-original/arch/ppc/platforms/Makefile linux/arch/ppc/platforms/Makefile --- linux-original/arch/ppc/platforms/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/platforms/Makefile 2005-07-08 08:55:27.000000000 -0400 @@ -44,6 +44,7 @@ obj-$(CONFIG_RADSTONE_PPC7D) += radstone_ppc7d.o obj-$(CONFIG_SANDPOINT) += sandpoint.o obj-$(CONFIG_SBC82xx) += sbc82xx.o +obj-$(CONFIG_IOMEGA8241) += iomega8241.o obj-$(CONFIG_SPRUCE) += spruce.o obj-$(CONFIG_LITE5200) += lite5200.o diff -urN linux-original/arch/ppc/platforms/iomega8241.c linux/arch/ppc/platforms/iomega8241.c --- linux-original/arch/ppc/platforms/iomega8241.c 1969-12-31 19:00:00.000000000 -0500 +++ linux/arch/ppc/platforms/iomega8241.c 2005-08-08 12:53:30.000000000 -0400 @@ -0,0 +1,567 @@ +/* + * arch/ppc/platforms/iomega8241.c + * + * The Iomega StorCenter Network Hard Drive platform is based on the + * original sandpoint test platform. That GNU copyright information + * is reproduced below: + * + * Board setup routines for the Motorola SPS Sandpoint Test Platform. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * 2000-2003 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +/* + * Iomega StorCenter Network Hard Drive. + * + * Maintainer (Iomega Port): Anthony Russello + * russello@iomega.com + * Much of the below code was taken from the original sandpoint.c/.h port + * done my Mark A. Greer (see above copyright information). It was adapted + * to support a custom board. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for linux/serial_core.h */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iomega8241.h" + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* defined in iomega8241.h */ +}; + +/* Real Time Clock */ +extern spinlock_t rtc_lock; +extern int ds1337_do_command(int id, int cmd, void *arg); +#define DS1337_GET_DATE 0 +#define DS1337_SET_DATE 1 + +unsigned char __res[sizeof(bd_t)]; + +static void iomega8241_halt(void); + +/* + * Define all of the IRQ senses and polarities. + */ +static u_char iomega8241_openpic_initsenses[] __initdata = { + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 0: AN983B */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 1: IDE VIA DS6410 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 2: USB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 3: USB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 4: USB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 5: UART0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 6: UART1 */ +}; + +/* + * Define all of the PCI IRQ Mappings + */ +static inline int +iomega8241_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 1, 1, 0, 0 }, + { 2, 3, 4, 1 }, + { 0, 0, 4, 4 }, + { 3, 3, 4, 4 }, + { 3, 3, 4, 4 }, + }; + + const long min_idsel = 13, max_idsel = 17, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +static int +iomega8241_exclude_device(u_char bus, u_char devfn) +{ + if ((bus == 0) && (PCI_SLOT(devfn) == IOMEGA8241_HOST_BRIDGE_IDSEL)) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + +static void __init +iomega8241_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0x1; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE) == 0) { + + ppc_md.pci_exclude_device = iomega8241_exclude_device; + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = iomega8241_map_irq; + } + else { + if (ppc_md.progress) + ppc_md.progress("Bridge init failed", 0x100); + printk("Host bridge init failed\n"); + } + return; +} + +static void __init +iomega8241_setup_arch(void) +{ + int i = 0; + + loops_per_jiffy = 100000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + + /* Lookup PCI host bridges */ + iomega8241_find_bridges(); + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + for (i = 0; i < 2; i++) { + rs_table[i].port = (ulong) ioremap (rs_table[i].port, PAGE_SIZE); + rs_table[i].iomem_base = (u8 *) rs_table[i].port; + } + + writeb(readb(rs_table[1].iomem_base + 0x11) | 0x1, rs_table[1].iomem_base + 0x11); + + printk(KERN_INFO "Iomega StorCenter Network Hard Drive\n"); + printk(KERN_INFO "Based on the Freescale Sandpoint Development System\n"); + + /* DINK32 12.3 and below do not correctly enable any caches. + * We will do this now with good known values. Future versions + * of DINK32 are supposed to get this correct. + */ + if (cpu_has_feature(CPU_FTR_SPEC7450)) + /* 745x is different. We only want to pass along enable. */ + _set_L2CR(L2CR_L2E); + else if (cpu_has_feature(CPU_FTR_L2CR)) + /* All modules have 1MB of L2. We also assume that an + * L2 divisor of 3 will work. + */ + _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3 + | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF); +#if 0 + /* Untested right now. */ + if (cpu_has_feature(CPU_FTR_L3CR)) { + /* Magic value. */ + _set_L3CR(0x8f032000); + } +#endif +} + +#define IOMEGA8241_87308_CFG_ADDR 0x15c +#define IOMEGA8241_87308_CFG_DATA 0x15d + +#define IOMEGA8241_87308_CFG_INB(addr, byte) { \ + outb((addr), IOMEGA8241_87308_CFG_ADDR); \ + (byte) = inb(IOMEGA8241_87308_CFG_DATA); \ +} + +#define IOMEGA8241_87308_CFG_OUTB(addr, byte) { \ + outb((addr), IOMEGA8241_87308_CFG_ADDR); \ + outb((byte), IOMEGA8241_87308_CFG_DATA); \ +} + +#define IOMEGA8241_87308_SELECT_DEV(dev_num) { \ + IOMEGA8241_87308_CFG_OUTB(0x07, (dev_num)); \ +} + +#define IOMEGA8241_87308_DEV_ENABLE(dev_num) { \ + IOMEGA8241_87308_SELECT_DEV(dev_num); \ + IOMEGA8241_87308_CFG_OUTB(0x30, 0x01); \ +} + +static int __init +iomega8241_request_io(void) +{ + request_region(0x00,0x20,"dma1"); + request_region(0x20,0x20,"pic1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xa0,0x20,"pic2"); + request_region(0xc0,0x20,"dma2"); + + return 0; +} + +arch_initcall(iomega8241_request_io); + +/* + * Interrupt setup and service. Interrrupts on the Sandpoint come + * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO). + * The 8259 is cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4, + * IDE is on EPIC 7 and 8. + */ +static void __init +iomega8241_init_IRQ(void) +{ + OpenPIC_InitSenses = iomega8241_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(iomega8241_openpic_initsenses); + + /* + * We need to tell openpic_set_sources where things actually are. + * mpc10x_common will set up OpenPIC_Addr at ioremap(EUMB phys base + + * EPIC offset (0x40000)); The EPIC IRQ register address map - + * Interrupt Source Configuration Registers gives these numbers as + * offsets starting at 0x50200, we need to adjust accordingly + */ + openpic_set_sources(0, 5, OpenPIC_Addr + 0x10200); + openpic_set_sources(5, 2, OpenPIC_Addr + 0x11120); + + openpic_init(0); +} + +static int +iomega8241_get_irq(struct pt_regs *regs) +{ + int irq; + + irq = openpic_irq(); + if (irq == OPENPIC_VEC_SPURIOUS) + irq = -1; + + return irq; +} + +static u32 +iomega8241_irq_canonicalize(u32 irq) +{ + return irq; +} + +static void __init +iomega8241_init2(void) +{ + return; +} + +static unsigned long __init +iomega8241_find_end_of_memory(void) +{ + bd_t *bp = (bd_t *)__res; + + if (bp->bi_memsize) + return bp->bi_memsize; + + return 64*1024*1024; +} + +static void __init +iomega8241_map_io(void) +{ + /* changes suggested by Freescale: */ + io_block_mapping(0xfc000000, 0xfc000000, 0x04000000, _PAGE_IO); +} + +static void +iomega8241_restart(char *cmd) +{ + local_irq_disable(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + for(;;); /* Spin until reset happens */ +} + +static void +iomega8241_power_off(void) +{ + local_irq_disable(); + for(;;); /* No way to shut power off with software */ + /* NOTREACHED */ +} + +static void +iomega8241_halt(void) +{ + iomega8241_power_off(); + /* NOTREACHED */ +} + +static int +iomega8241_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Iomega Corporation\n"); + seq_printf(m, "machine\t\t: Iomega StorCenter Network Hard Drive\n"); + + return 0; +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE support. + */ +static int iomega8241_ide_ports_known = 0; +static unsigned long iomega8241_ide_regbase[MAX_HWIFS]; +static unsigned long iomega8241_ide_ctl_regbase[MAX_HWIFS]; +static unsigned long iomega8241_idedma_regbase; + +static void +iomega8241_ide_probe(void) +{ + struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_6410, NULL); + + if (pdev) { + iomega8241_ide_regbase[0]=pdev->resource[0].start; + iomega8241_ide_regbase[1]=pdev->resource[2].start; + iomega8241_ide_ctl_regbase[0]=pdev->resource[1].start; + iomega8241_ide_ctl_regbase[1]=pdev->resource[3].start; + iomega8241_idedma_regbase=pdev->resource[4].start; + + printk("Found: VIA VT6410 based IDE\n"); + } + + iomega8241_ide_ports_known = 1; +} + +static int +iomega8241_ide_default_irq(unsigned long base) +{ + if (iomega8241_ide_ports_known == 0) + iomega8241_ide_probe(); + + if (base == iomega8241_ide_regbase[0]) + return IDE_INTRUPT; + else if (base == iomega8241_ide_regbase[1]) + return IDE_INTRUPT; + else + return 0; +} + +static unsigned long +iomega8241_ide_default_io_base(int index) +{ + if (iomega8241_ide_ports_known == 0) + iomega8241_ide_probe(); + + return iomega8241_ide_regbase[index]; +} + +static void __init +iomega8241_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, + unsigned long ctrl_port, int *irq) +{ + unsigned long reg = data_port; + uint alt_status_base; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg++; + } + + if (data_port == iomega8241_ide_regbase[0]) { + alt_status_base = iomega8241_ide_ctl_regbase[0] + 2; + hw->irq = IDE_INTRUPT; + } else if (data_port == iomega8241_ide_regbase[1]) { + alt_status_base = iomega8241_ide_ctl_regbase[1] + 2; + hw->irq = IDE_INTRUPT; + } else { + alt_status_base = 0; + hw->irq = 0; + } + + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base; + } + + if (irq != NULL) { + *irq = hw->irq; + } +} +#endif + +/* + * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1. + */ +static __inline__ void +iomega8241_set_bat(void) +{ + unsigned long bat3u, bat3l; + + __asm__ __volatile__( + " lis %0,0xf800\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x0ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); +} + +TODC_ALLOC(); + +/* Real Time Clock support. + * StorCenter has a DS1337 accessed by I2C. + */ +static ulong iomega8241_get_rtc_time(void) +{ + struct rtc_time tm; + int result; + + spin_lock(&rtc_lock); + result = ds1337_do_command(0, DS1337_GET_DATE, &tm); + spin_unlock(&rtc_lock); + + if (result == 0) + result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + + return result; +} + +static int iomega8241_set_rtc_time(unsigned long nowtime) +{ + struct rtc_time tm; + int result; + + spin_lock(&rtc_lock); + to_tm(nowtime, &tm); + result = ds1337_do_command(0, DS1337_SET_DATE, &tm); + spin_unlock(&rtc_lock); + + return result; +} + + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer) + * are non-zero, then we should use the board info from the bd_t + * structure and the cmdline pointed to by r6 instead of the + * information from birecs, if any. Otherwise, use the information + * from birecs as discovered by the preceeding call to + * parse_bootinfo(). This rule should work with both PPCBoot, which + * uses a bd_t board info structure, and the kernel boot wrapper, + * which uses birecs. + */ + if (r3 && r6) { + /* copy board info structure */ + memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); + /* copy command line */ + *(char *)(r7+KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6+KERNELBASE)); + } + +#ifdef CONFIG_BLK_DEV_INITRD + /* take care of initrd if we have one */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Map in board regs, etc. */ + iomega8241_set_bat(); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = iomega8241_setup_arch; + ppc_md.show_cpuinfo = iomega8241_show_cpuinfo; + ppc_md.irq_canonicalize = iomega8241_irq_canonicalize; + ppc_md.init_IRQ = iomega8241_init_IRQ; + ppc_md.get_irq = iomega8241_get_irq; + ppc_md.init = iomega8241_init2; + + ppc_md.restart = iomega8241_restart; + ppc_md.power_off = iomega8241_power_off; + ppc_md.halt = iomega8241_halt; + + ppc_md.find_end_of_memory = iomega8241_find_end_of_memory; + ppc_md.setup_io_mappings = iomega8241_map_io; + + /* What USI had in their 2.4.21 kernel: */ + ppc_md.set_rtc_time = iomega8241_set_rtc_time; + ppc_md.get_rtc_time = iomega8241_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.find_end_of_memory = iomega8241_find_end_of_memory; + ppc_md.setup_io_mappings = iomega8241_map_io; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.default_irq = iomega8241_ide_default_irq; + ppc_ide_md.default_io_base = iomega8241_ide_default_io_base; + ppc_ide_md.ide_init_hwif = iomega8241_ide_init_hwif_ports; +#endif +} diff -urN linux-original/arch/ppc/platforms/iomega8241.h linux/arch/ppc/platforms/iomega8241.h --- linux-original/arch/ppc/platforms/iomega8241.h 1969-12-31 19:00:00.000000000 -0500 +++ linux/arch/ppc/platforms/iomega8241.h 2005-08-08 13:11:35.000000000 -0400 @@ -0,0 +1,76 @@ +/* + * arch/ppc/platforms/iomega8241.h + * + * The Iomega StorCenter Network Hard Drive platform is based on the + * original sandpoint test platform. That GNU copyright information + * is reproduced below: + * + * Board setup routines for the Motorola SPS Sandpoint Test Platform. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * 2000-2003 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef __PPC_PLATFORMS_IOMEGA8241_H +#define __PPC_PLATFORMS_IOMEGA8241_H + +#include +#include + +/* + * G2 Configuration: + * + * DEVICE IDSEL INTERRUPT NUMBER + * AN983B AD12 IRQ0 + * IDE Via DS6410 AD13 IRQ1 + * NEC USB uPD720101 AD14 IRQ2,3,4 + */ + +#define IDE_INTRUPT 1 + +/* + * The sandpoint boards have processor modules that either have an 8240 or + * an MPC107 host bridge on them. These bridges have an IDSEL line that allows + * them to respond to PCI transactions as if they were a normal PCI devices. + * However, the processor on the processor side of the bridge can not reach + * out onto the PCI bus and then select the bridge or bad things will happen + * (documented in the 8240 and 107 manuals). + * Because of this, we always skip the bridge PCI device when accessing the + * PCI bus. The PCI slot that the bridge occupies is defined by the macro + * below. + */ +#define IOMEGA8241_HOST_BRIDGE_IDSEL 12 + +void board_find_bridges(void); +void iomega8241_fix_uart(void); +/* + * Serial defines. + */ +#define IOMEGA8241_SERIAL_0 0xFDF04500 +#define IOMEGA8241_SERIAL_1 0xFDF04600 + +#define RS_TABLE_SIZE 4 + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD ( 100000000 / 16 ) /* 100Mhz speed, divided by 16 + to make the output freqency*/ +#define UART_CLK 1843200 + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) + +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, IOMEGA8241_SERIAL_0, 5, STD_COM_FLAGS, /* ttyS0 */ \ + iomem_base: (u8 *)IOMEGA8241_SERIAL_0, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, IOMEGA8241_SERIAL_1, 6, STD_COM_FLAGS, /* ttyS1 */ \ + iomem_base: (u8 *)IOMEGA8241_SERIAL_1, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DFNS + +#endif /* __PPC_PLATFORMS_IOMEGA8241_H */ diff -urN linux-original/arch/ppc/syslib/Makefile linux/arch/ppc/syslib/Makefile --- linux-original/arch/ppc/syslib/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/syslib/Makefile 2005-07-08 08:55:27.000000000 -0400 @@ -77,6 +77,7 @@ obj-$(CONFIG_PRPMC800) += open_pic.o indirect_pci.o pci_auto.o obj-$(CONFIG_RADSTONE_PPC7D) += i8259.o pci_auto.o obj-$(CONFIG_SANDPOINT) += i8259.o pci_auto.o todc_time.o +obj-$(CONFIG_IOMEGA8241) += i8259.o pci_auto.o todc_time.o obj-$(CONFIG_SBC82xx) += todc_time.o obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ todc_time.o diff -urN linux-original/arch/ppc/syslib/mpc10x_common.c linux/arch/ppc/syslib/mpc10x_common.c --- linux-original/arch/ppc/syslib/mpc10x_common.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/syslib/mpc10x_common.c 2005-07-08 08:55:27.000000000 -0400 @@ -330,7 +330,7 @@ * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd. */ if (host_bridge == MPC10X_BRIDGE_8245) { - ulong picr2; + uint picr2 = 0; early_read_config_dword(hose, 0, PCI_DEVFN(0,0), MPC10X_CFG_PICR2_REG, &picr2); diff -urN linux-original/arch/ppc/syslib/open_pic.c linux/arch/ppc/syslib/open_pic.c --- linux-original/arch/ppc/syslib/open_pic.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/syslib/open_pic.c 2005-07-08 08:55:27.000000000 -0400 @@ -319,8 +319,7 @@ } OpenPIC = (volatile struct OpenPIC __iomem *)OpenPIC_Addr; -#ifdef CONFIG_EPIC_SERIAL_MODE - /* Have to start from ground zero. +#if defined(CONFIG_EPIC_SERIAL_MODE) */ openpic_reset(); #endif @@ -1073,4 +1072,3 @@ } subsys_initcall(init_openpic_sysfs); - diff -urN linux-original/arch/ppc/syslib/todc_time.c linux/arch/ppc/syslib/todc_time.c --- linux-original/arch/ppc/syslib/todc_time.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/arch/ppc/syslib/todc_time.c 2005-08-08 12:58:47.000000000 -0400 @@ -412,6 +412,7 @@ return 0; } +#ifndef CONFIG_IOMEGA8241 /* Not used by the Iomega8241 platform */ /* * Manipulates read bit to reliably read seconds at a high rate. */ @@ -450,6 +451,8 @@ return val; } +#endif /* CONFIG_IOMEGA8241 */ + /* * This was taken from prep_setup.c * Use the NVRAM RTC to time a second to calibrate the decrementer. @@ -457,10 +460,13 @@ void __init todc_calibrate_decr(void) { +#ifdef CONFIG_IOMEGA8241 + ulong freq = 25000000; +#else ulong freq; ulong tbl, tbu; - long i, loop_count; - u_char sec; + long i, loop_count; + u_char sec; todc_time_init(); @@ -502,7 +508,8 @@ freq -= tbl; } while ((get_tbu() != tbu) && (++loop_count < 2)); - +#endif /* CONFIG_IOMEGA8241 */ + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", freq/1000000, freq%1000000); diff -urN linux-original/drivers/char/rtc.c linux/drivers/char/rtc.c --- linux-original/drivers/char/rtc.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/char/rtc.c 2005-07-08 08:55:27.000000000 -0400 @@ -498,9 +498,16 @@ } case RTC_RD_TIME: /* Read the time/date from RTC */ { +#ifdef CONFIG_IOMEGA8241 + unsigned long usi_time; + usi_time = ds1337_get_time(); + to_tm(usi_time,wtime); + break; +#else memset(&wtime, 0, sizeof(struct rtc_time)); rtc_get_rtc_time(&wtime); break; +#endif /* CONFIG_IOMEGA8241 */ } case RTC_SET_TIME: /* Set the RTC */ { @@ -542,7 +549,7 @@ if ((yrs -= epoch) > 255) /* They are unsigned */ return -EINVAL; - +#ifndef CONFIG_IOMEGA8241 spin_lock_irq(&rtc_lock); #ifdef CONFIG_MACH_DECSTATION real_yrs = yrs; @@ -598,6 +605,11 @@ spin_unlock_irq(&rtc_lock); return 0; +#else /* CONFIG_IOMEGA8241 */ + /* next is the forth API provided by ds1337.c USI-SS */ + ds1337_usi_set_time(yrs,mon,day,hrs,min,sec); + break; +#endif /* CONFIG_IOMEGA8241 */ } #ifdef RTC_IRQ case RTC_IRQP_READ: /* Read the periodic IRQ rate. */ diff -urN linux-original/drivers/i2c/busses/i2c-mpc.c linux/drivers/i2c/busses/i2c-mpc.c --- linux-original/drivers/i2c/busses/i2c-mpc.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/i2c/busses/i2c-mpc.c 2005-08-26 15:04:29.000000000 -0400 @@ -68,6 +68,7 @@ writeb(x, i2c->base + MPC_I2C_CR); } +#ifndef CONFIG_IOMEGA8241 static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs *regs) { struct mpc_i2c *i2c = dev_id; @@ -79,6 +80,7 @@ } return IRQ_HANDLED; } +#endif /* CONFIG_IOMEGA8241 */ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) { @@ -291,7 +293,11 @@ .algo = &mpc_algo, .class = I2C_CLASS_HWMON, .timeout = 1, +#ifdef CONFIG_IOMEGA8241 + .retries = 400 +#else .retries = 1 +#endif /* CONFIG_IOMEGA8241 */ }; #ifdef CONFIG_FSL_OCP @@ -322,6 +328,7 @@ goto fail_map; } +#ifndef CONFIG_IOMEGA8241 if (i2c->irq != OCP_IRQ_NA) { if ((result = request_irq(ocp->def->irq, mpc_i2c_isr, @@ -331,6 +338,7 @@ goto fail_irq; } } else +#endif /* CONFIG_IOMEGA8241 */ i2c->irq = 0; i2c->adap = mpc_ops; @@ -348,8 +356,10 @@ fail_add: if (ocp->def->irq != OCP_IRQ_NA) free_irq(ocp->def->irq, 0); +#ifndef CONFIG_IOMEGA8241 fail_irq: iounmap(i2c->base); +#endif /* CONFIG_IOMEGA8241 */ fail_map: release_mem_region(ocp->def->paddr, MPC_I2C_REGION); kfree(i2c); diff -urN linux-original/drivers/i2c/chips/ds1337.c linux/drivers/i2c/chips/ds1337.c --- linux-original/drivers/i2c/chips/ds1337.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/i2c/chips/ds1337.c 2005-09-13 15:16:43.000000000 -0400 @@ -20,10 +20,11 @@ #include #include #include -#include /* get the user-level API */ +#include #include #include + /* Device registers */ #define DS1337_REG_HOUR 2 #define DS1337_REG_DAY 3 @@ -75,7 +76,9 @@ /* * Internal variables */ +#ifndef CONFIG_IOMEGA8241 static int ds1337_id; +#endif /* CONFIG_IOMEGA8241 */ static LIST_HEAD(ds1337_clients); static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value) @@ -95,7 +98,9 @@ */ static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt) { +#ifndef CONFIG_IOMEGA8241 struct ds1337_data *data = i2c_get_clientdata(client); +#endif /* CONFIG_IOMEGA8241 */ int result; u8 buf[7]; u8 val; @@ -119,8 +124,12 @@ msg[1].len = sizeof(buf); msg[1].buf = &buf[0]; +#ifdef CONFIG_IOMEGA8241 + result = i2c_transfer(client->adapter, msg, 2); +#else result = client->adapter->algo->master_xfer(client->adapter, &msg[0], 2); +#endif /* CONFIG_IOMEGA8241 */ dev_dbg(&client->adapter->dev, "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n", @@ -145,6 +154,7 @@ __FUNCTION__, dt->tm_sec, dt->tm_min, dt->tm_hour, dt->tm_mday, dt->tm_mon, dt->tm_year, dt->tm_wday); +#ifndef CONFIG_IOMEGA8241 } else { dev_err(&client->adapter->dev, "ds1337[%d]: error reading " "data! %d\n", data->id, result); @@ -152,11 +162,20 @@ } return result; +#else + return 0; + } + dev_err(&client->dev, "error reading data! %d\n", result); + return -EIO; +#endif /* CONFIG_IOMEGA8241 */ + } static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt) { +#ifndef CONFIG_IOMEGA8241 struct ds1337_data *data = i2c_get_clientdata(client); +#endif /* CONFIG_IOMEGA8241 */ int result; u8 buf[8]; u8 val; @@ -177,7 +196,7 @@ buf[0] = 0; /* reg offset */ buf[1] = BIN_TO_BCD(dt->tm_sec); buf[2] = BIN_TO_BCD(dt->tm_min); - buf[3] = BIN_TO_BCD(dt->tm_hour) | (1 << 6); + buf[3] = BIN_TO_BCD(dt->tm_hour) /*& (0 << 6)*/; buf[4] = BIN_TO_BCD(dt->tm_wday) + 1; buf[5] = BIN_TO_BCD(dt->tm_mday); buf[6] = BIN_TO_BCD(dt->tm_mon); @@ -194,6 +213,14 @@ msg[0].len = sizeof(buf); msg[0].buf = &buf[0]; +#ifdef CONFIG_IOMEGA8241 + result = i2c_transfer(client->adapter, msg, 1); + + if (result == 1) + return 0; + dev_err(&client->dev, "error writing data! %d\n", result); + return -EIO; +#else result = client->adapter->algo->master_xfer(client->adapter, &msg[0], 1); if (result < 0) { @@ -205,6 +232,7 @@ } return result; +#endif /* CONFIG_IOMEGA8241 */ } static int ds1337_command(struct i2c_client *client, unsigned int cmd, @@ -228,6 +256,22 @@ * Public API for access to specific device. Useful for low-level * RTC access from kernel code. */ +#ifdef CONFIG_IOMEGA8241 +int ds1337_do_command(int bus, int cmd, void *arg) +{ + struct list_head *walk; + struct list_head *tmp; + struct ds1337_data *data; + + list_for_each_safe(walk, tmp, &ds1337_clients) { + data = list_entry(walk, struct ds1337_data, list); + if (data->client.adapter->nr == bus) + return ds1337_command(&data->client, cmd, arg); + } + + return -ENODEV; +} +#else int ds1337_do_command(int id, int cmd, void *arg) { struct list_head *walk; @@ -242,6 +286,7 @@ return -ENODEV; } +#endif /* CONFIG_IOMEGA8241 */ static int ds1337_attach_adapter(struct i2c_adapter *adapter) { @@ -346,7 +391,9 @@ ds1337_init_client(new_client); /* Add client to local list */ +#ifndef CONFIG_IOMEGA8241 data->id = ds1337_id++; +#endif /* CONFIG_IOMEGA8241 */ list_add(&data->list, &ds1337_clients); return 0; @@ -363,9 +410,9 @@ /* Ensure that device is set in 24-hour mode */ val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); - if ((val >= 0) && (val & (1 << 6)) == 0) + if ((val >= 0) && (val & (0 << 6))) i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, - val | (1 << 6)); + val & 0x3f); } static int ds1337_detach_client(struct i2c_client *client) @@ -398,5 +445,9 @@ MODULE_DESCRIPTION("DS1337 RTC driver"); MODULE_LICENSE("GPL"); +#ifdef CONFIG_IOMEGA8241 +EXPORT_SYMBOL_GPL(ds1337_do_command); +#endif /* CONFIG_IOMEGA8241 */ + module_init(ds1337_init); module_exit(ds1337_exit); diff -urN linux-original/drivers/ide/pci/via82cxxx.c linux/drivers/ide/pci/via82cxxx.c --- linux-original/drivers/ide/pci/via82cxxx.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/ide/pci/via82cxxx.c 2005-08-08 13:06:52.000000000 -0400 @@ -79,6 +79,7 @@ u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, @@ -145,6 +146,7 @@ int len; u16 c, w; u8 t, x; + u8 ar0, ar1, ar2, ar3; char *p = buffer; via_print("----------VIA BusMastering IDE Configuration" @@ -176,6 +178,108 @@ via_print("Max DRDY Pulse Width: %s%s", via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : ""); +#ifdef CONFIG_IOMEGA8241 + if(via_config->id == PCI_DEVICE_ID_VIA_6410) { + /* + * Additional debug information for the VIA VT6410 + * IDE Host Controller + */ + + pci_read_config_byte(dev, 0x9, &ar0); + via_print("Programming Interface: %#x",ar0); + + pci_read_config_byte(dev, 0xa, &ar0); + via_print("Sub Class Code: %#x",ar0); + + pci_read_config_byte(dev, 0xb, &ar0); + via_print("Base Class Code: %#x",ar0); + + pci_read_config_byte(dev, 0xd, &ar0); + via_print("Latency Timer: %#x",ar0); + + pci_read_config_byte(dev, 0x34, &ar0); + via_print("Capability Pointer: %#x",ar0); + + pci_read_config_byte(dev, 0x3c, &ar0); + via_print("Interrupt Line: %#x",ar0); + + pci_read_config_byte(dev, 0x3d, &ar0); + via_print("Interrupt Pin: %#x",ar0); + + pci_read_config_byte(dev, 0x3e, &ar0); + via_print("Minimum Grant: %#x",ar0); + + pci_read_config_byte(dev, 0x3f, &ar0); + via_print("Maximum Latency: %#x",ar0); + + pci_read_config_byte(dev, 0x40, &ar0); + via_print("IDE Chip Enable: %#x",ar0); + + pci_read_config_byte(dev, VIA_IDE_CONFIG, &ar0); + via_print("IDE Configuration I: %#x",ar0); + + pci_read_config_byte(dev, VIA_IDE_CONFIG+1, &ar0); + via_print("IDE Configuration II: %#x",ar0); + + pci_read_config_byte(dev, VIA_FIFO_CONFIG, &ar0); + via_print("IDE FIFO Configuration: %#x",ar0); + + pci_read_config_byte(dev, 0x44, &ar0); + via_print("IDE Miscellaneous Control 1: %#x",ar0); + + pci_read_config_byte(dev, 0x45, &ar0); + via_print("IDE Miscellaneous Control 2: %#x",ar0); + + pci_read_config_byte(dev, 0x46, &ar0); + via_print("IDE Miscellaneous Control 3: %#x",ar0); + + pci_read_config_byte(dev, VIA_DRIVE_TIMING+3, &ar0); + pci_read_config_byte(dev, VIA_DRIVE_TIMING+2, &ar1); + pci_read_config_byte(dev, VIA_DRIVE_TIMING+1, &ar2); + pci_read_config_byte(dev, VIA_DRIVE_TIMING, &ar3); + via_print("IDE Drive Timing Control: %#x%x%x%x",ar0, ar1, ar2, ar3); + + pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &ar0); + via_print("IDE Address Setup TIme: %#x",ar0); + + pci_read_config_byte(dev, 0x4e, &ar0); + via_print("Sec Non-1FO Port Access Timing: %#x",ar0); + + pci_read_config_byte(dev, 0x4f, &ar0); + via_print("Pri Non-1FO Port Access Timing: %#x",ar0); + + pci_read_config_byte(dev, VIA_UDMA_TIMING+3, &ar0); + pci_read_config_byte(dev, VIA_UDMA_TIMING+2, &ar1); + pci_read_config_byte(dev, VIA_UDMA_TIMING+1, &ar2); + pci_read_config_byte(dev, VIA_UDMA_TIMING, &ar3); + via_print("UltraDMA Extended Timing Control: %#x%x%x%x",ar0, ar1, ar2, ar3); + + pci_read_config_byte(dev, 0x54, &ar0); + via_print("Revision Register: %#x",ar0); + + pci_read_config_byte(dev, 0x58, &ar0); + via_print("PLL Ctrl/Test Mode Enabled: %#x",ar0); + + pci_read_config_byte(dev, 0x59, &ar0); + via_print("Slew Rate Control: %#x",ar0); + + pci_read_config_byte(dev, 0x5a, &ar0); + via_print("DRVRST Clock Gate/Bus TS Ctrl: %#x",ar0); + + pci_read_config_byte(dev, 0x70, &ar0); + via_print("IDE Primary Status: %#x",ar0); + + pci_read_config_byte(dev, 0x71, &ar0); + via_print("IDE Pri Interrupt Control: %#x",ar0); + + pci_read_config_byte(dev, 0x78, &ar0); + via_print("IDE Secondary Status: %#x",ar0); + + pci_read_config_byte(dev, 0x79, &ar0); + via_print("IDE Sec Interrupt Control: %#x",ar0); + } +#endif /* CONFIG_IOMEGA8241 */ + via_print("-----------------------Primary IDE" "-------Secondary IDE------"); via_print("Read DMA FIFO flush: %10s%20s", @@ -479,10 +583,15 @@ case VIA_UDMA_133: pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); +#ifdef CONFIG_IOMEGA8241 + /* The VIA 6410 iis not properly detecting cable types */ + for (i = 24; i >= 0; i -= 8) { +#else for (i = 24; i >= 0; i -= 8) if (((u >> i) & 0x10) || (((u >> i) & 0x20) && - (((u >> i) & 7) < 6))) { + (((u >> i) & 7) < 4))) { +#endif /* CONFIG_IOMEGA8241 */ /* BIOS 80-wire bit or * UDMA w/ < 60ns/cycle */ @@ -502,6 +611,10 @@ /* * Check whether interfaces are enabled. */ + if(via_config->id == PCI_DEVICE_ID_VIA_6410) { + pci_read_config_byte(dev, VIA_IDE_ENABLE, &v); + pci_write_config_byte(dev, VIA_IDE_ENABLE, v | 0x3); + } pci_read_config_byte(dev, VIA_IDE_ENABLE, &v); @@ -615,25 +728,35 @@ hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; } - -static ide_pci_device_t via82cxxx_chipset __devinitdata = { - .name = "VP_IDE", - .init_chipset = init_chipset_via82cxxx, - .init_hwif = init_hwif_via82cxxx, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, - .bootable = ON_BOARD, +static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { + {/* 0 */ + .name = "VP_IDE", + .init_chipset = init_chipset_via82cxxx, + .init_hwif = init_hwif_via82cxxx, + .channels = 2, + .autodma = NOAUTODMA, + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, + .bootable = ON_BOARD, + },{ /* 1 */ + .name = "VP_IDE", + .init_chipset = init_chipset_via82cxxx, + .init_hwif = init_hwif_via82cxxx, + .channels = 2, + .autodma = AUTODMA, // AUTODMA + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, + .bootable = NEVER_BOARD, + } }; static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return ide_setup_pci_device(dev, &via82cxxx_chipset); + return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]); } static struct pci_device_id via_pci_tbl[] = { { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { 0, }, }; MODULE_DEVICE_TABLE(pci, via_pci_tbl); diff -urN linux-original/drivers/mtd/maps/Kconfig linux/drivers/mtd/maps/Kconfig --- linux-original/drivers/mtd/maps/Kconfig 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/mtd/maps/Kconfig 2005-07-08 08:55:27.000000000 -0400 @@ -659,5 +659,10 @@ help This enables access to the flash chip on the Sharp SL Series of PDAs. -endmenu +config MTD_IOMEGA8241 + tristate "Map driver for the Iomega 8241 StorCenter board" + depends on IOMEGA8241 + help + Map driver for the Iomega StorCenter Network Hard Drive. +endmenu diff -urN linux-original/drivers/mtd/maps/Makefile linux/drivers/mtd/maps/Makefile --- linux-original/drivers/mtd/maps/Makefile 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/mtd/maps/Makefile 2005-07-08 08:55:27.000000000 -0400 @@ -71,3 +71,4 @@ obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o obj-$(CONFIG_MTD_DMV182) += dmv182.o obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o +obj-$(CONFIG_MTD_IOMEGA8241) += iomega8241_mtd.o diff -urN linux-original/drivers/mtd/maps/iomega8241_mtd.c linux/drivers/mtd/maps/iomega8241_mtd.c --- linux-original/drivers/mtd/maps/iomega8241_mtd.c 1969-12-31 19:00:00.000000000 -0500 +++ linux/drivers/mtd/maps/iomega8241_mtd.c 2005-08-08 13:08:50.000000000 -0400 @@ -0,0 +1,102 @@ +/* + * drivers/mtd/maps/iomega8241_mtd.c + * + * Iomega Corporation + * + * Flash mapping for the Iomega StorCenter Network Hard Drive + * + * This module is based on the mpc1211.c file created by + * Saito.K & Jeanne + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct mtd_info *iomegamtd; +static struct mtd_partition *parsed_parts; + +struct map_info iomega8241_flash_map = { + .name = "Flash", + .phys = 0xFF800000, + .size = 0x800000, + .bankwidth = 1, +}; + +static struct mtd_partition iomega8241_partitions[] = { + { + .name = "kernel", + /* 1507328 bytes: kernel space */ + .size = 0x00170000, + .offset = 0, + }, { + .name = "filesystem", + /* 5832704 bytes: root partition */ + .size = 0x00590000, + /* start is FF970000 */ + .offset = MTDPART_OFS_APPEND, + }, { + .name = "bootloader", + /* 262144 bytes for u-boot */ + .size = 0x00040000, + /* start is FFF00000 */ + .offset = MTDPART_OFS_APPEND, + }, { + .name = "sysconfig", + /* 786432 bytes: sysconf partition */ + .size = 0x000C0000, + /* start is FFF40000 */ + .offset = MTDPART_OFS_APPEND, + } +}; + +static int __init +init_iomega8241_flash(void) +{ + int nr_parts; + + iomega8241_flash_map.virt = ioremap(iomega8241_flash_map.phys, iomega8241_flash_map.size); + + simple_map_init(&iomega8241_flash_map); + + printk("Iomega8241: Probing for flash...\n"); + iomegamtd = do_map_probe("cfi_probe", &iomega8241_flash_map); + if (!iomegamtd) { + printk(KERN_NOTICE "Flash chips not detected at either possible location.\n"); + return -ENXIO; + } + printk("Iomega8241: Flash found at location 0x%x\n", iomega8241_flash_map.phys); + iomegamtd->owner = THIS_MODULE; + + parsed_parts = iomega8241_partitions; + nr_parts = ARRAY_SIZE(iomega8241_partitions); + + add_mtd_partitions(iomegamtd, parsed_parts, nr_parts); + return 0; +} + +static void __exit +cleanup_iomega8241_flash(void) +{ + if (parsed_parts) + del_mtd_partitions(iomegamtd); + else + del_mtd_device(iomegamtd); + map_destroy(iomegamtd); +} + +module_init(init_iomega8241_flash); +module_exit(cleanup_iomega8241_flash); + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Anthony Russello "); +MODULE_DESCRIPTION("Flash mapping for the Iomega StorCenter Network Hard Drive"); diff -urN linux-original/drivers/net/r8169.c linux/drivers/net/r8169.c --- linux-original/drivers/net/r8169.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/net/r8169.c 2005-07-08 08:55:27.000000000 -0400 @@ -1,261 +1,268 @@ /* ========================================================================= - r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver for Linux kernel 2.4.x. + r8169.c: A RealTek RTL8169s/8110s Gigabit Ethernet driver for Linux kernel 2.4.x. -------------------------------------------------------------------- History: Feb 4 2002 - created initially by ShuChen . May 20 2002 - Add link status force-mode and TBI mode support. - 2004 - Massive updates. See kernel SCM system for details. ========================================================================= - 1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes. - Command: 'insmod r8169 media = SET_MEDIA' - Ex: 'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex. - - SET_MEDIA can be: - _10_Half = 0x01 - _10_Full = 0x02 - _100_Half = 0x04 - _100_Full = 0x08 - _1000_Full = 0x10 - - 2. Support TBI mode. -========================================================================= -VERSION 1.1 <2002/10/4> + +RTL8169_VERSION "1.1" <2002/10/4> The bit4:0 of MII register 4 is called "selector field", and have to be 00001b to indicate support of IEEE std 802.3 during NWay process of - exchanging Link Code Word (FLP). + exchanging Link Code Word (FLP). -VERSION 1.2 <2002/11/30> +RTL8169_VERSION "1.2" <2003/6/17> + Update driver module name. + Modify ISR. + Add chip mcfg. + +RTL8169_VERSION "1.3" <2003/6/20> + Add chip pcfg. + Add priv->phy_timer_t, rtl8169_phy_timer_t_handler() + Add rtl8169_hw_PHY_config() + Add rtl8169_hw_PHY_reset() + +RTL8169_VERSION "1.4" <2003/7/14> + Add tx_bytes, rx_bytes. + +RTL8169_VERSION "1.5" <2003/7/18> + Set 0x0000 to PHY at offset 0x0b. + Modify chip mcfg, pcfg + Force media for multiple card. +RTL8169_VERSION "1.6" <2003/8/25> + Modify receive data buffer. + +RTL8169_VERSION "1.7" <2003/9/18> + Add Jumbo Frame support. + +RTL8169_VERSION "1.8" <2003/10/21> + Performance and CPU Utilizaion Enhancement. + +RTL8169_VERSION "1.9" <2003/12/29> + Enable Tx/Rx flow control. + +RTL8169_VERSION "2.0" <2004/03/26> + Beta version. + Support for linux 2.6.x + +RTL8169_VERSION "2.1" <2004/07/05> + Modify parameters. + +RTL8169_VERSION "2.2" <2004/08/09> + Add.pci_dma_sync_single. + Add pci_alloc_consistent()/pci_free_consistent(). + Revise parameters. + Recognize our interrupt for linux 2.6.x. +*/ - - Large style cleanup - - Use ether_crc in stock kernel (linux/crc32.h) - - Copy mc_filter setup code from 8139cp - (includes an optimization, and avoids set_bit use) - -VERSION 1.6LK <2004/04/14> - - - Merge of Realtek's version 1.6 - - Conversion to DMA API - - Suspend/resume - - Endianness - - Misc Rx/Tx bugs - -VERSION 2.2LK <2005/01/25> - - - RX csum, TX csum/SG, TSO - - VLAN - - baby (< 7200) Jumbo frames support - - Merge of Realtek's version 2.2 (new phy) - */ #include -#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include + +#include #include -#include -#include -#include -#define RTL8169_VERSION "2.2LK" -#define MODULENAME "r8169" +#define RTL8169_VERSION "2.2" +#define MODULENAME "RTL8169s/8110s" +#define RTL8169_DRIVER_NAME MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION #define PFX MODULENAME ": " + +#undef RTL8169_DEBUG +#undef RTL8169_JUMBO_FRAME_SUPPORT +#undef RTL8169_HW_FLOW_CONTROL_SUPPORT + + +#undef RTL8169_IOCTL_SUPPORT +#undef RTL8169_DYNAMIC_CONTROL +#define RTL8169_USE_IO + + #ifdef RTL8169_DEBUG -#define assert(expr) \ - if(!(expr)) { \ - printk( "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr,__FILE__,__FUNCTION__,__LINE__); \ - } -#define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) -#else -#define assert(expr) do {} while (0) -#define dprintk(fmt, args...) do {} while (0) -#endif /* RTL8169_DEBUG */ - -#define TX_BUFFS_AVAIL(tp) \ - (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1) - -#ifdef CONFIG_R8169_NAPI -#define rtl8169_rx_skb netif_receive_skb -#define rtl8169_rx_hwaccel_skb vlan_hwaccel_rx -#define rtl8169_rx_quota(count, quota) min(count, quota) + #define assert(expr) \ + if(!(expr)) { printk( "Assertion failed! %s,%s,%s,line=%d\n", #expr,__FILE__,__FUNCTION__,__LINE__); } + #define DBG_PRINT( fmt, args...) printk("r8169: " fmt, ## args); #else -#define rtl8169_rx_skb netif_rx -#define rtl8169_rx_hwaccel_skb vlan_hwaccel_receive_skb -#define rtl8169_rx_quota(count, quota) count -#endif + #define assert(expr) do {} while (0) + #define DBG_PRINT( fmt, args...) ; +#endif // end of #ifdef RTL8169_DEBUG + /* media options */ #define MAX_UNITS 8 -static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static int num_media = 0; +static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ static int max_interrupt_work = 20; /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). - The RTL chips use a 64 element hash table based on the Ethernet CRC. */ + The RTL chips use a 64 element hash table based on the Ethernet CRC. */ static int multicast_filter_limit = 32; -/* MAC address length */ -#define MAC_ADDR_LEN 6 +/* MAC address length*/ +#define MAC_ADDR_LEN 6 + +#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ +#define RX_DMA_BURST 7 /* Maximum PCI burst, '6' is 1024 */ +#define TX_DMA_BURST 7 /* Maximum PCI burst, '6' is 1024 */ +#define ETTh 0x3F /* 0x3F means NO threshold */ + +#define ETH_HDR_LEN 14 +#define DEFAULT_MTU 1500 +#define DEFAULT_RX_BUF_LEN 1536 + + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT +#define MAX_JUMBO_FRAME_MTU ( 10000 ) +#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN ) +#else +#define MAX_RX_SKBDATA_SIZE 1600 +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + + +#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ -#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ -#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ -#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ -#define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ -#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ - -#define R8169_REGS_SIZE 256 -#define R8169_NAPI_WEIGHT 64 -#define NUM_TX_DESC 64 /* Number of Tx descriptor registers */ -#define NUM_RX_DESC 256 /* Number of Rx descriptor registers */ -#define RX_BUF_SIZE 1536 /* Rx Buffer size */ -#define R8169_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) -#define R8169_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) +#define NUM_TX_DESC 64 /* Number of Tx descriptor registers*/ +#define NUM_RX_DESC 64 /* Number of Rx descriptor registers*/ -#define RTL8169_TX_TIMEOUT (6*HZ) -#define RTL8169_PHY_TIMEOUT (10*HZ) +#define RTL_MIN_IO_SIZE 0x80 +#define TX_TIMEOUT (6*HZ) +#define RTL8169_TIMER_EXPIRE_TIME 100 //100 + + +#ifdef RTL8169_USE_IO +#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg)) +#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg)) +#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg)) +#define RTL_R8(reg) inb (ioaddr + (reg)) +#define RTL_R16(reg) inw (ioaddr + (reg)) +#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg))) +#else /* write/read MMIO register */ -#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) -#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) -#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) -#define RTL_R8(reg) readb (ioaddr + (reg)) -#define RTL_R16(reg) readw (ioaddr + (reg)) -#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) - -enum mac_version { - RTL_GIGA_MAC_VER_B = 0x00, - /* RTL_GIGA_MAC_VER_C = 0x03, */ - RTL_GIGA_MAC_VER_D = 0x01, - RTL_GIGA_MAC_VER_E = 0x02, - RTL_GIGA_MAC_VER_X = 0x04 /* Greater than RTL_GIGA_MAC_VER_E */ -}; +#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) +#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) +#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) +#define RTL_R8(reg) readb (ioaddr + (reg)) +#define RTL_R16(reg) readw (ioaddr + (reg)) +#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) +#endif -enum phy_version { - RTL_GIGA_PHY_VER_C = 0x03, /* PHY Reg 0x03 bit0-3 == 0x0000 */ - RTL_GIGA_PHY_VER_D = 0x04, /* PHY Reg 0x03 bit0-3 == 0x0000 */ - RTL_GIGA_PHY_VER_E = 0x05, /* PHY Reg 0x03 bit0-3 == 0x0000 */ - RTL_GIGA_PHY_VER_F = 0x06, /* PHY Reg 0x03 bit0-3 == 0x0001 */ - RTL_GIGA_PHY_VER_G = 0x07, /* PHY Reg 0x03 bit0-3 == 0x0002 */ - RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */ -}; +#define MCFG_METHOD_1 0x01 +#define MCFG_METHOD_2 0x02 +#define MCFG_METHOD_3 0x03 +#define MCFG_METHOD_4 0x04 + +#define PCFG_METHOD_1 0x01 //PHY Reg 0x03 bit0-3 == 0x0000 +#define PCFG_METHOD_2 0x02 //PHY Reg 0x03 bit0-3 == 0x0001 +#define PCFG_METHOD_3 0x03 //PHY Reg 0x03 bit0-3 == 0x0002 -#define _R(NAME,MAC,MASK) \ - { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK } +#ifdef RTL8169_DYNAMIC_CONTROL +#include "r8169_callback.h" +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + const static struct { const char *name; - u8 mac_version; - u32 RxConfigMask; /* Clears the bits supported by this chip */ + u8 mcfg; /* depend on RTL8169 docs */ + u32 RxConfigMask; /* should clear the bits supported by this chip */ } rtl_chip_info[] = { - _R("RTL8169", RTL_GIGA_MAC_VER_B, 0xff7e1880), - _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_D, 0xff7e1880), - _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_E, 0xff7e1880), - _R("RTL8169s/8110s", RTL_GIGA_MAC_VER_X, 0xff7e1880), + { "RTL8169", MCFG_METHOD_1, 0xff7e1880 }, + { "RTL8169s/8110s", MCFG_METHOD_2, 0xff7e1880 }, + { "RTL8169s/8110s", MCFG_METHOD_3, 0xff7e1880 }, }; -#undef _R -static struct pci_device_id rtl8169_pci_tbl[] = { - {0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x1186, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + +static struct pci_device_id rtl8169_pci_tbl[] __devinitdata = { + { 0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +#ifdef CONFIG_IOMEGA8241 + /* The 8169 without an i2c defaults to reporting as an 8129 */ + { 0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +#endif /* CONFIG_IOMEGA8241 */ {0,}, }; -MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); -static int rx_copybreak = 200; -static int use_dac; +MODULE_DEVICE_TABLE (pci, rtl8169_pci_tbl); + enum RTL8169_registers { - MAC0 = 0, /* Ethernet hardware address. */ - MAR0 = 8, /* Multicast filter. */ - TxDescStartAddrLow = 0x20, - TxDescStartAddrHigh = 0x24, - TxHDescStartAddrLow = 0x28, - TxHDescStartAddrHigh = 0x2c, - FLASH = 0x30, - ERSR = 0x36, - ChipCmd = 0x37, - TxPoll = 0x38, + MAC0 = 0x0, + MAR0 = 0x8, + TxDescStartAddr = 0x20, + TxHDescStartAddr= 0x28, + FLASH = 0x30, + ERSR = 0x36, + ChipCmd = 0x37, + TxPoll = 0x38, IntrMask = 0x3C, IntrStatus = 0x3E, TxConfig = 0x40, RxConfig = 0x44, RxMissed = 0x4C, Cfg9346 = 0x50, - Config0 = 0x51, - Config1 = 0x52, - Config2 = 0x53, - Config3 = 0x54, - Config4 = 0x55, - Config5 = 0x56, + Config0 = 0x51, + Config1 = 0x52, + Config2 = 0x53, + Config3 = 0x54, + Config4 = 0x55, + Config5 = 0x56, MultiIntr = 0x5C, - PHYAR = 0x60, - TBICSR = 0x64, + PHYAR = 0x60, + TBICSR = 0x64, TBI_ANAR = 0x68, TBI_LPAR = 0x6A, PHYstatus = 0x6C, RxMaxSize = 0xDA, CPlusCmd = 0xE0, - IntrMitigate = 0xE2, - RxDescAddrLow = 0xE4, - RxDescAddrHigh = 0xE8, - EarlyTxThres = 0xEC, - FuncEvent = 0xF0, - FuncEventMask = 0xF4, - FuncPresetState = 0xF8, - FuncForceEvent = 0xFC, + RxDescStartAddr = 0xE4, + ETThReg = 0xEC, + FuncEvent = 0xF0, + FuncEventMask = 0xF4, + FuncPresetState = 0xF8, + FuncForceEvent = 0xFC, }; enum RTL8169_register_content { - /* InterruptStatusBits */ - SYSErr = 0x8000, - PCSTimeout = 0x4000, - SWInt = 0x0100, - TxDescUnavail = 0x80, - RxFIFOOver = 0x40, - LinkChg = 0x20, - RxOverflow = 0x10, - TxErr = 0x08, - TxOK = 0x04, - RxErr = 0x02, - RxOK = 0x01, + /*InterruptStatusBits*/ + SYSErr = 0x8000, + PCSTimeout = 0x4000, + SWInt = 0x0100, + TxDescUnavail = 0x80, + RxFIFOOver = 0x40, + LinkChg = 0x20, + RxOverflow = 0x10, + TxErr = 0x08, + TxOK = 0x04, + RxErr = 0x02, + RxOK = 0x01, - /* RxStatusDesc */ + /*RxStatusDesc*/ RxRES = 0x00200000, RxCRC = 0x00080000, - RxRUNT = 0x00100000, + RxRUNT= 0x00100000, RxRWT = 0x00400000, - /* ChipCmdBits */ + /*ChipCmdBits*/ CmdReset = 0x10, CmdRxEnb = 0x08, CmdTxEnb = 0x04, RxBufEmpty = 0x01, - /* Cfg9346Bits */ + /*Cfg9346Bits*/ Cfg9346_Lock = 0x00, Cfg9346_Unlock = 0xC0, - /* rx_mode_bits */ + /*rx_mode_bits*/ AcceptErr = 0x20, AcceptRunt = 0x10, AcceptBroadcast = 0x08, @@ -263,2280 +270,1646 @@ AcceptMyPhys = 0x02, AcceptAllPhys = 0x01, - /* RxConfigBits */ + /*RxConfigBits*/ RxCfgFIFOShift = 13, RxCfgDMAShift = 8, - /* TxConfigBits */ + /*TxConfigBits*/ TxInterFrameGapShift = 24, - TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ + TxDMAShift = 8, - /* TBICSR p.28 */ - TBIReset = 0x80000000, - TBILoopback = 0x40000000, - TBINwEnable = 0x20000000, - TBINwRestart = 0x10000000, - TBILinkOk = 0x02000000, - TBINwComplete = 0x01000000, - - /* CPlusCmd p.31 */ - RxVlan = (1 << 6), - RxChkSum = (1 << 5), - PCIDAC = (1 << 4), - PCIMulRW = (1 << 3), - - /* rtl8169_PHYstatus */ - TBI_Enable = 0x80, - TxFlowCtrl = 0x40, - RxFlowCtrl = 0x20, - _1000bpsF = 0x10, - _100bps = 0x08, - _10bps = 0x04, - LinkStatus = 0x02, - FullDup = 0x01, + /*rtl8169_PHYstatus*/ + TBI_Enable = 0x80, + TxFlowCtrl = 0x40, + RxFlowCtrl = 0x20, + _1000bpsF = 0x10, + _100bps = 0x08, + _10bps = 0x04, + LinkStatus = 0x02, + FullDup = 0x01, - /* GIGABIT_PHY_registers */ + /*GIGABIT_PHY_registers*/ PHY_CTRL_REG = 0, PHY_STAT_REG = 1, PHY_AUTO_NEGO_REG = 4, PHY_1000_CTRL_REG = 9, - /* GIGABIT_PHY_REG_BIT */ - PHY_Restart_Auto_Nego = 0x0200, - PHY_Enable_Auto_Nego = 0x1000, - - /* PHY_STAT_REG = 1 */ - PHY_Auto_Neco_Comp = 0x0020, - - /* PHY_AUTO_NEGO_REG = 4 */ - PHY_Cap_10_Half = 0x0020, - PHY_Cap_10_Full = 0x0040, - PHY_Cap_100_Half = 0x0080, - PHY_Cap_100_Full = 0x0100, - - /* PHY_1000_CTRL_REG = 9 */ - PHY_Cap_1000_Full = 0x0200, - - PHY_Cap_Null = 0x0, - - /* _MediaType */ - _10_Half = 0x01, - _10_Full = 0x02, - _100_Half = 0x04, - _100_Full = 0x08, - _1000_Full = 0x10, + /*GIGABIT_PHY_REG_BIT*/ + PHY_Restart_Auto_Nego = 0x0200, + PHY_Enable_Auto_Nego = 0x1000, + + //PHY_STAT_REG = 1; + PHY_Auto_Neco_Comp = 0x0020, + + //PHY_AUTO_NEGO_REG = 4; + PHY_Cap_10_Half = 0x0020, + PHY_Cap_10_Full = 0x0040, + PHY_Cap_100_Half = 0x0080, + PHY_Cap_100_Full = 0x0100, + + //PHY_1000_CTRL_REG = 9; + PHY_Cap_1000_Full = 0x0200, + + PHY_Cap_PAUSE = 0x0400, + PHY_Cap_ASYM_PAUSE = 0x0800, + + PHY_Cap_Null = 0x0, + + /*_MediaType*/ + _10_Half = 0x01, + _10_Full = 0x02, + _100_Half = 0x04, + _100_Full = 0x08, + _1000_Full = 0x10, - /* _TBICSRBit */ - TBILinkOK = 0x02000000, + /*_TBICSRBit*/ + TBILinkOK = 0x02000000, }; + + enum _DescStatusBit { - DescOwn = (1 << 31), /* Descriptor is owned by NIC */ - RingEnd = (1 << 30), /* End of descriptor ring */ - FirstFrag = (1 << 29), /* First segment of a packet */ - LastFrag = (1 << 28), /* Final segment of a packet */ - - /* Tx private */ - LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ - MSSShift = 16, /* MSS value position */ - MSSMask = 0xfff, /* MSS value + LargeSend bit: 12 bits */ - IPCS = (1 << 18), /* Calculate IP checksum */ - UDPCS = (1 << 17), /* Calculate UDP/IP checksum */ - TCPCS = (1 << 16), /* Calculate TCP/IP checksum */ - TxVlanTag = (1 << 17), /* Add VLAN tag */ - - /* Rx private */ - PID1 = (1 << 18), /* Protocol ID bit 1/2 */ - PID0 = (1 << 17), /* Protocol ID bit 2/2 */ - -#define RxProtoUDP (PID1) -#define RxProtoTCP (PID0) -#define RxProtoIP (PID1 | PID0) -#define RxProtoMask RxProtoIP - - IPFail = (1 << 16), /* IP checksum failed */ - UDPFail = (1 << 15), /* UDP/IP checksum failed */ - TCPFail = (1 << 14), /* TCP/IP checksum failed */ - RxVlanTag = (1 << 16), /* VLAN tag available */ + OWNbit = 0x80000000, + EORbit = 0x40000000, + FSbit = 0x20000000, + LSbit = 0x10000000, }; -#define RsvdMask 0x3fffc000 struct TxDesc { - u32 opts1; - u32 opts2; - u64 addr; + u32 status; + u32 vlan_tag; + u32 buf_addr; + u32 buf_Haddr; }; struct RxDesc { - u32 opts1; - u32 opts2; - u64 addr; + u32 status; + u32 vlan_tag; + u32 buf_addr; + u32 buf_Haddr; }; -struct ring_info { - struct sk_buff *skb; - u32 len; - u8 __pad[sizeof(void *) - sizeof(u32)]; -}; + +typedef struct timer_list rt_timer_t; + struct rtl8169_private { - void __iomem *mmio_addr; /* memory map physical address */ - struct pci_dev *pci_dev; /* Index of PCI device */ - struct net_device_stats stats; /* statistics of net device */ - spinlock_t lock; /* spin lock flag */ + unsigned long ioaddr; /* memory map physical address*/ + struct pci_dev *pci_dev; /* Index of PCI device */ + struct net_device_stats stats; /* statistics of net device */ + spinlock_t lock; /* spin lock flag */ int chipset; - int mac_version; - int phy_version; - u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ - u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ - u32 dirty_rx; - u32 dirty_tx; - struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ - struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ - dma_addr_t TxPhyAddr; - dma_addr_t RxPhyAddr; - struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */ - struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ - unsigned rx_buf_sz; - struct timer_list timer; - u16 cp_cmd; - u16 intr_mask; - int phy_auto_nego_reg; - int phy_1000_ctrl_reg; -#ifdef CONFIG_R8169_VLAN - struct vlan_group *vlgrp; -#endif - int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); - void (*get_settings)(struct net_device *, struct ethtool_cmd *); - void (*phy_reset_enable)(void __iomem *); - unsigned int (*phy_reset_pending)(void __iomem *); - unsigned int (*link_ok)(void __iomem *); - struct work_struct task; + int mcfg; + int pcfg; + rt_timer_t r8169_timer; + unsigned long expire_time; + + unsigned long phy_link_down_cnt; + unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ + unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ + unsigned long dirty_tx; + struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */ + struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */ + struct sk_buff *Tx_skbuff[NUM_TX_DESC];/* Index of Transmit data buffer */ + struct sk_buff *Rx_skbuff[NUM_RX_DESC];/* Receive data buffer */ + unsigned char drvinit_fail; + + dma_addr_t txdesc_array_dma_addr[NUM_TX_DESC]; + dma_addr_t rxdesc_array_dma_addr[NUM_RX_DESC]; + dma_addr_t rx_skbuff_dma_addr[NUM_RX_DESC]; + + void *txdesc_space; + dma_addr_t txdesc_phy_dma_addr; + int sizeof_txdesc_space; + + void *rxdesc_space; + dma_addr_t rxdesc_phy_dma_addr; + int sizeof_rxdesc_space; + + int curr_mtu_size; + int tx_pkt_len; + int rx_pkt_len; + + int hw_rx_pkt_len; + +#ifdef RTL8169_DYNAMIC_CONTROL + struct r8169_cb_t rt; +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + unsigned char linkstatus; }; -MODULE_AUTHOR("Realtek and the Linux r8169 crew "); -MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); -module_param_array(media, int, &num_media, 0); -module_param(rx_copybreak, int, 0); -module_param(use_dac, int, 0); -MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); + +MODULE_AUTHOR ("Realtek"); +MODULE_DESCRIPTION ("RealTek RTL-8169 Gigabit Ethernet driver"); +MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_LICENSE("GPL"); -MODULE_VERSION(RTL8169_VERSION); -static int rtl8169_open(struct net_device *dev); -static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance, - struct pt_regs *regs); -static int rtl8169_init_ring(struct net_device *dev); -static void rtl8169_hw_start(struct net_device *dev); -static int rtl8169_close(struct net_device *dev); -static void rtl8169_set_rx_mode(struct net_device *dev); -static void rtl8169_tx_timeout(struct net_device *dev); -static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev); -static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, - void __iomem *); -static int rtl8169_change_mtu(struct net_device *netdev, int new_mtu); -static void rtl8169_down(struct net_device *dev); -#ifdef CONFIG_R8169_NAPI -static int rtl8169_poll(struct net_device *dev, int *budget); +static int rtl8169_open (struct net_device *dev); +static int rtl8169_start_xmit (struct sk_buff *skb, struct net_device *dev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +typedef int irqreturn_t; +#define IRQ_NONE 0 +#define IRQ_HANDLED 1 +static void rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +#else +static irqreturn_t rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs); #endif -static const u16 rtl8169_intr_mask = - SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; -static const u16 rtl8169_napi_event = - RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr; -static const unsigned int rtl8169_rx_config = - (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); - -#define PHY_Cap_10_Half_Or_Less PHY_Cap_10_Half -#define PHY_Cap_10_Full_Or_Less PHY_Cap_10_Full | PHY_Cap_10_Half_Or_Less -#define PHY_Cap_100_Half_Or_Less PHY_Cap_100_Half | PHY_Cap_10_Full_Or_Less -#define PHY_Cap_100_Full_Or_Less PHY_Cap_100_Full | PHY_Cap_100_Half_Or_Less +static void rtl8169_init_ring (struct net_device *dev); +static void rtl8169_hw_start (struct net_device *dev); +static int rtl8169_close (struct net_device *dev); +static inline u32 ether_crc (int length, unsigned char *data); +static void rtl8169_set_rx_mode (struct net_device *dev); +static void rtl8169_tx_timeout (struct net_device *dev); +static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev); + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + +static void rtl8169_hw_PHY_config (struct net_device *dev); +static void rtl8169_hw_PHY_reset(struct net_device *dev); +static const u16 rtl8169_intr_mask = LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK ; +static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift) | 0x0000000E; + + +#define RTL8169_WRITE_GMII_REG_BIT( ioaddr, reg, bitnum, bitval )\ +{ \ + int val; \ + if( bitval == 1 ){ val = ( RTL8169_READ_GMII_REG( ioaddr, reg ) | (bitval< 0; i--) { - /* Check if the RTL8169 has completed writing to the specified MII register */ - if (!(RTL_R32(PHYAR) & 0x80000000)) + for( i = 2000; i > 0 ; i -- ){ + // Check if the RTL8169 has completed writing to the specified MII register + if( ! (RTL_R32(PHYAR)&0x80000000) ){ break; - udelay(100); - } + } + else{ + udelay(100); + }// end of if( ! (RTL_R32(PHYAR)&0x80000000) ) + }// end of for() loop } - -static int mdio_read(void __iomem *ioaddr, int RegAddr) +//================================================================= +int RTL8169_READ_GMII_REG( unsigned long ioaddr, int RegAddr ) { int i, value = -1; - RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); + RTL_W32 ( PHYAR, 0x0 | (RegAddr&0xFF)<<16 ); udelay(1000); - for (i = 2000; i > 0; i--) { - /* Check if the RTL8169 has completed retrieving data from the specified MII register */ - if (RTL_R32(PHYAR) & 0x80000000) { - value = (int) (RTL_R32(PHYAR) & 0xFFFF); + for( i = 2000; i > 0 ; i -- ){ + // Check if the RTL8169 has completed retrieving data from the specified MII register + if( RTL_R32(PHYAR) & 0x80000000 ){ + value = (int)( RTL_R32(PHYAR)&0xFFFF ); break; } - udelay(100); - } + else{ + udelay(100); + }// end of if( RTL_R32(PHYAR) & 0x80000000 ) + }// end of for() loop return value; } -static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) -{ - RTL_W16(IntrMask, 0x0000); - RTL_W16(IntrStatus, 0xffff); -} +#ifdef RTL8169_IOCTL_SUPPORT +#include "r8169_ioctl.c" +#endif //end #ifdef RTL8169_IOCTL_SUPPORT -static void rtl8169_asic_down(void __iomem *ioaddr) -{ - RTL_W8(ChipCmd, 0x00); - rtl8169_irq_mask_and_ack(ioaddr); - RTL_R16(CPlusCmd); -} -static unsigned int rtl8169_tbi_reset_pending(void __iomem *ioaddr) -{ - return RTL_R32(TBICSR) & TBIReset; -} +#ifdef RTL8169_DYNAMIC_CONTROL +#include "r8169_callback.c" +#endif -static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr) -{ - return mdio_read(ioaddr, 0) & 0x8000; -} -static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr) -{ - return RTL_R32(TBICSR) & TBILinkOk; + +#define rtl8169_request_timer( timer, timer_expires, timer_func, timer_data ) \ +{ \ + init_timer(timer); \ + timer->expires = (unsigned long)(jiffies + timer_expires); \ + timer->data = (unsigned long)(timer_data); \ + timer->function = (void *)(timer_func); \ + add_timer(timer); \ + DBG_PRINT("request_timer at 0x%08lx\n", (unsigned long)timer); \ } -static unsigned int rtl8169_xmii_link_ok(void __iomem *ioaddr) -{ - return RTL_R8(PHYstatus) & LinkStatus; +#define rtl8169_delete_timer( del_timer_t ) \ +{ \ + del_timer(del_timer_t); \ + DBG_PRINT("delete_timer at 0x%08lx\n", (unsigned long)del_timer_t); \ } -static void rtl8169_tbi_reset_enable(void __iomem *ioaddr) -{ - RTL_W32(TBICSR, RTL_R32(TBICSR) | TBIReset); +#define rtl8169_mod_timer( timer, timer_expires ) \ +{ \ + mod_timer( timer, jiffies + timer_expires ); \ } -static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) -{ - unsigned int val; - val = (mdio_read(ioaddr, PHY_CTRL_REG) | 0x8000) & 0xffff; - mdio_write(ioaddr, PHY_CTRL_REG, val); -} -static void rtl8169_check_link_status(struct net_device *dev, - struct rtl8169_private *tp, void __iomem *ioaddr) -{ - unsigned long flags; - spin_lock_irqsave(&tp->lock, flags); - if (tp->link_ok(ioaddr)) { - netif_carrier_on(dev); - printk(KERN_INFO PFX "%s: link up\n", dev->name); - } else - netif_carrier_off(dev); - spin_unlock_irqrestore(&tp->lock, flags); -} - -static void rtl8169_link_option(int idx, u8 *autoneg, u16 *speed, u8 *duplex) -{ - struct { - u16 speed; - u8 duplex; - u8 autoneg; - u8 media; - } link_settings[] = { - { SPEED_10, DUPLEX_HALF, AUTONEG_DISABLE, _10_Half }, - { SPEED_10, DUPLEX_FULL, AUTONEG_DISABLE, _10_Full }, - { SPEED_100, DUPLEX_HALF, AUTONEG_DISABLE, _100_Half }, - { SPEED_100, DUPLEX_FULL, AUTONEG_DISABLE, _100_Full }, - { SPEED_1000, DUPLEX_FULL, AUTONEG_DISABLE, _1000_Full }, - /* Make TBI happy */ - { SPEED_1000, DUPLEX_FULL, AUTONEG_ENABLE, 0xff } - }, *p; - unsigned char option; - - option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff; +//====================================================================================================== +//====================================================================================================== +void rtl8169_phy_timer_t_handler( void *timer_data ) +{ + struct net_device *dev = (struct net_device *)timer_data; + struct rtl8169_private *priv = (struct rtl8169_private *) (dev->priv); + unsigned long ioaddr = priv->ioaddr; - if ((option != 0xff) && !idx) - printk(KERN_WARNING PFX "media option is deprecated.\n"); + assert( priv->mcfg > MCFG_METHOD_1 ); + assert( priv->pcfg < PCFG_METHOD_3 ); - for (p = link_settings; p->media != 0xff; p++) { - if (p->media == option) - break; + if( RTL_R8(PHYstatus) & LinkStatus ){ + priv->phy_link_down_cnt = 0 ; } - *autoneg = p->autoneg; - *speed = p->speed; - *duplex = p->duplex; -} + else{ + priv->phy_link_down_cnt ++ ; + if( priv->phy_link_down_cnt >= 12 ){ + // If link on 1000, perform phy reset. + if( RTL8169_READ_GMII_REG( ioaddr, PHY_1000_CTRL_REG ) & PHY_Cap_1000_Full ) + { + DBG_PRINT("rtl8169_hw_PHY_reset\n"); + rtl8169_hw_PHY_reset( dev ); + } -static void rtl8169_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct rtl8169_private *tp = netdev_priv(dev); + priv->phy_link_down_cnt = 0 ; + } + } - strcpy(info->driver, MODULENAME); - strcpy(info->version, RTL8169_VERSION); - strcpy(info->bus_info, pci_name(tp->pci_dev)); + //--------------------------------------------------------------------------- + //mod_timer is a more efficient way to update the expire field of an active timer. + //--------------------------------------------------------------------------- +// rtl8169_mod_timer( (&priv->phy_timer_t), 100 ); } -static int rtl8169_get_regs_len(struct net_device *dev) -{ - return R8169_REGS_SIZE; -} -static int rtl8169_set_speed_tbi(struct net_device *dev, - u8 autoneg, u16 speed, u8 duplex) + +//====================================================================================================== +//====================================================================================================== +void rtl8169_timer_handler( void *timer_data ) { - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - int ret = 0; - u32 reg; + struct net_device *dev = (struct net_device *)timer_data; + struct rtl8169_private *priv = (struct rtl8169_private *) (dev->priv); - reg = RTL_R32(TBICSR); - if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) && - (duplex == DUPLEX_FULL)) { - RTL_W32(TBICSR, reg & ~(TBINwEnable | TBINwRestart)); - } else if (autoneg == AUTONEG_ENABLE) - RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart); - else { - printk(KERN_WARNING PFX - "%s: incorrect speed setting refused in TBI mode\n", - dev->name); - ret = -EOPNOTSUPP; + if( (priv->mcfg > MCFG_METHOD_1) && (priv->pcfg < PCFG_METHOD_3) ){ + DBG_PRINT("FIX PCS -> rtl8169_phy_timer_t_handler\n"); + priv->phy_link_down_cnt = 0; + rtl8169_phy_timer_t_handler( timer_data ); } - return ret; -} -static int rtl8169_set_speed_xmii(struct net_device *dev, - u8 autoneg, u16 speed, u8 duplex) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - int auto_nego, giga_ctrl; +#ifdef RTL8169_DYNAMIC_CONTROL + { + struct r8169_cb_t *rt = &(priv->rt); + if( priv->linkstatus == _1000_Full ){ + r8169_callback(rt); + } + } +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL - auto_nego = mdio_read(ioaddr, PHY_AUTO_NEGO_REG); - auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full | - PHY_Cap_100_Half | PHY_Cap_100_Full); - giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG); - giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_Null); - if (autoneg == AUTONEG_ENABLE) { - auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full | - PHY_Cap_100_Half | PHY_Cap_100_Full); - giga_ctrl |= PHY_Cap_1000_Full; - } else { - if (speed == SPEED_10) - auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full; - else if (speed == SPEED_100) - auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full; - else if (speed == SPEED_1000) - giga_ctrl |= PHY_Cap_1000_Full; - - if (duplex == DUPLEX_HALF) - auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); - } - - tp->phy_auto_nego_reg = auto_nego; - tp->phy_1000_ctrl_reg = giga_ctrl; - - mdio_write(ioaddr, PHY_AUTO_NEGO_REG, auto_nego); - mdio_write(ioaddr, PHY_1000_CTRL_REG, giga_ctrl); - mdio_write(ioaddr, PHY_CTRL_REG, PHY_Enable_Auto_Nego | - PHY_Restart_Auto_Nego); - return 0; + rtl8169_mod_timer( (&priv->r8169_timer), priv->expire_time ); } -static int rtl8169_set_speed(struct net_device *dev, - u8 autoneg, u16 speed, u8 duplex) + + +//====================================================================================================== +//====================================================================================================== +static int __devinit rtl8169_init_board ( struct pci_dev *pdev, struct net_device **dev_out, unsigned long *ioaddr_out) { - struct rtl8169_private *tp = netdev_priv(dev); - int ret; + unsigned long ioaddr = 0; + struct net_device *dev; + struct rtl8169_private *priv; + int rc, i; + unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; - ret = tp->set_speed(dev, autoneg, speed, duplex); - if (netif_running(dev) && (tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full)) - mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT); + assert (pdev != NULL); + assert (ioaddr_out != NULL); - return ret; -} + *ioaddr_out = 0; + *dev_out = NULL; -static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; - int ret; + // dev zeroed in init_etherdev +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + dev = init_etherdev (NULL, sizeof (*priv)); +#else + dev = alloc_etherdev (sizeof (*priv)); +#endif - spin_lock_irqsave(&tp->lock, flags); - ret = rtl8169_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex); - spin_unlock_irqrestore(&tp->lock, flags); - - return ret; -} + if (dev == NULL) { + printk (KERN_ERR PFX "unable to alloc new ethernet\n"); + return -ENOMEM; + } -static u32 rtl8169_get_rx_csum(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); + SET_MODULE_OWNER(dev); - return tp->cp_cmd & RxChkSum; -} +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + SET_NETDEV_DEV(dev, &pdev->dev); +#endif -static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; + priv = dev->priv; - spin_lock_irqsave(&tp->lock, flags); + // enable device (incl. PCI PM wakeup and hotplug setup) + rc = pci_enable_device (pdev); + if (rc) + goto err_out; - if (data) - tp->cp_cmd |= RxChkSum; - else - tp->cp_cmd &= ~RxChkSum; + mmio_start = pci_resource_start (pdev, 1); + mmio_end = pci_resource_end (pdev, 1); + mmio_flags = pci_resource_flags (pdev, 1); + mmio_len = pci_resource_len (pdev, 1); + + // make sure PCI base addr 1 is MMIO + if (!(mmio_flags & IORESOURCE_MEM)) { + printk (KERN_ERR PFX "region #1 not an MMIO resource, aborting\n"); + rc = -ENODEV; + goto err_out; + } - RTL_W16(CPlusCmd, tp->cp_cmd); - RTL_R16(CPlusCmd); + // check for weird/broken PCI region reporting + if ( mmio_len < RTL_MIN_IO_SIZE ) { + printk (KERN_ERR PFX "Invalid PCI region size(s), aborting\n"); + rc = -ENODEV; + goto err_out; + } - spin_unlock_irqrestore(&tp->lock, flags); - return 0; -} + rc = pci_request_regions (pdev, dev->name); + if (rc) + goto err_out; -#ifdef CONFIG_R8169_VLAN + // enable PCI bus-mastering + pci_set_master (pdev); -static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, - struct sk_buff *skb) -{ - return (tp->vlgrp && vlan_tx_tag_present(skb)) ? - TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; -} +#ifdef RTL8169_USE_IO + ioaddr = pci_resource_start(pdev, 0); +#else + // ioremap MMIO region + ioaddr = (unsigned long)ioremap (mmio_start, mmio_len); + if (ioaddr == 0) { + printk (KERN_ERR PFX "cannot remap MMIO, aborting\n"); + rc = -EIO; + goto err_out_free_res; + } +#endif -static void rtl8169_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; + // Soft reset the chip. + RTL_W8 ( ChipCmd, CmdReset); - spin_lock_irqsave(&tp->lock, flags); - tp->vlgrp = grp; - if (tp->vlgrp) - tp->cp_cmd |= RxVlan; - else - tp->cp_cmd &= ~RxVlan; - RTL_W16(CPlusCmd, tp->cp_cmd); - RTL_R16(CPlusCmd); - spin_unlock_irqrestore(&tp->lock, flags); -} + // Check that the chip has finished the reset. + for (i = 1000; i > 0; i--){ + if ( (RTL_R8(ChipCmd) & CmdReset) == 0){ + break; + } + else{ + udelay (10); + } + } -static void rtl8169_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; + // identify config method + { + unsigned long val32 = (RTL_R32(TxConfig)&0x7c800000); - spin_lock_irqsave(&tp->lock, flags); - if (tp->vlgrp) - tp->vlgrp->vlan_devices[vid] = NULL; - spin_unlock_irqrestore(&tp->lock, flags); -} + if( val32 == (0x1<<28) ){ + priv->mcfg = MCFG_METHOD_4; + } + else if( val32 == (0x1<<26) ){ + priv->mcfg = MCFG_METHOD_3; + } + else if( val32 == (0x1<<23) ){ + priv->mcfg = MCFG_METHOD_2; + } + else if( val32 == 0x00000000 ){ + priv->mcfg = MCFG_METHOD_1; + } + else{ + priv->mcfg = MCFG_METHOD_1; + } + } + { + unsigned char val8 = (unsigned char)(RTL8169_READ_GMII_REG(ioaddr,3)&0x000f); + if( val8 == 0x00 ){ + priv->pcfg = PCFG_METHOD_1; + } + else if( val8 == 0x01 ){ + priv->pcfg = PCFG_METHOD_2; + } + else if( val8 == 0x02 ){ + priv->pcfg = PCFG_METHOD_3; + } + else{ + priv->pcfg = PCFG_METHOD_3; + } + } -static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, - struct sk_buff *skb) -{ - u32 opts2 = le32_to_cpu(desc->opts2); - int ret; - if (tp->vlgrp && (opts2 & RxVlanTag)) { - rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, - swab16(opts2 & 0xffff)); - ret = 0; - } else - ret = -1; - desc->opts2 = 0; - return ret; -} + for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--){ + if (priv->mcfg == rtl_chip_info[i].mcfg) { + priv->chipset = i; + goto match; + } + } -#else /* !CONFIG_R8169_VLAN */ + //if unknown chip, assume array element #0, original RTL-8169 in this case + //printk (KERN_DEBUG PFX "PCI device %s: unknown chip version, assuming RTL-8169\n", pdev->slot_name); + priv->chipset = 0; -static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, - struct sk_buff *skb) -{ +match: + *ioaddr_out = ioaddr; + *dev_out = dev; return 0; -} -static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, - struct sk_buff *skb) -{ - return -1; +#ifndef RTL8169_USE_IO +err_out_free_res: + pci_release_regions (pdev); +#endif + +err_out: + unregister_netdev (dev); + kfree (dev); + return rc; } -#endif -static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - u32 status; - cmd->supported = - SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE; - cmd->port = PORT_FIBRE; - cmd->transceiver = XCVR_INTERNAL; - status = RTL_R32(TBICSR); - cmd->advertising = (status & TBINwEnable) ? ADVERTISED_Autoneg : 0; - cmd->autoneg = !!(status & TBINwEnable); - cmd->speed = SPEED_1000; - cmd->duplex = DUPLEX_FULL; /* Always set */ -} -static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - u8 status; - cmd->supported = SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_TP; +//====================================================================================================== +static int __devinit rtl8169_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct net_device *dev = NULL; + struct rtl8169_private *priv = NULL; + unsigned long ioaddr = 0; + static int board_idx = -1; + int i; + int option = -1, Cap10_100 = 0, Cap1000 = 0; - cmd->autoneg = 1; - cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; - if (tp->phy_auto_nego_reg & PHY_Cap_10_Half) - cmd->advertising |= ADVERTISED_10baseT_Half; - if (tp->phy_auto_nego_reg & PHY_Cap_10_Full) - cmd->advertising |= ADVERTISED_10baseT_Full; - if (tp->phy_auto_nego_reg & PHY_Cap_100_Half) - cmd->advertising |= ADVERTISED_100baseT_Half; - if (tp->phy_auto_nego_reg & PHY_Cap_100_Full) - cmd->advertising |= ADVERTISED_100baseT_Full; - if (tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full) - cmd->advertising |= ADVERTISED_1000baseT_Full; + assert (pdev != NULL); + assert (ent != NULL); - status = RTL_R8(PHYstatus); + board_idx++; - if (status & _1000bpsF) - cmd->speed = SPEED_1000; - else if (status & _100bps) - cmd->speed = SPEED_100; - else if (status & _10bps) - cmd->speed = SPEED_10; - cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ? - DUPLEX_FULL : DUPLEX_HALF; -} + i = rtl8169_init_board (pdev, &dev, &ioaddr); + if (i < 0) { + return i; + } -static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; + priv = dev->priv; - spin_lock_irqsave(&tp->lock, flags); + assert (ioaddr != NULL); + assert (dev != NULL); + assert (priv != NULL); - tp->get_settings(dev, cmd); + // Get MAC address // + for (i = 0; i < MAC_ADDR_LEN ; i++){ + dev->dev_addr[i] = RTL_R8( MAC0 + i ); + } - spin_unlock_irqrestore(&tp->lock, flags); - return 0; -} + dev->open = rtl8169_open; + dev->hard_start_xmit = rtl8169_start_xmit; + dev->get_stats = rtl8169_get_stats; + dev->stop = rtl8169_close; + dev->tx_timeout = rtl8169_tx_timeout; + dev->set_multicast_list = rtl8169_set_rx_mode; + dev->watchdog_timeo = TX_TIMEOUT; + dev->irq = pdev->irq; + dev->base_addr = (unsigned long) ioaddr; + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT + dev->change_mtu = rtl8169_change_mtu; +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + +#ifdef RTL8169_IOCTL_SUPPORT + dev->do_ioctl = rtl8169_ioctl; +#endif //end #ifdef RTL8169_IOCTL_SUPPORT + +#ifdef RTL8169_DYNAMIC_CONTROL + priv->rt.dev = dev; +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + priv = dev->priv; // private data // + priv->pci_dev = pdev; + priv->ioaddr = ioaddr; + +//#ifdef RTL8169_JUMBO_FRAME_SUPPORT + priv->curr_mtu_size = dev->mtu; + priv->tx_pkt_len = dev->mtu + ETH_HDR_LEN; + priv->rx_pkt_len = dev->mtu + ETH_HDR_LEN; + priv->hw_rx_pkt_len = priv->rx_pkt_len + 8; +//#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + + DBG_PRINT("-------------------------- \n"); + DBG_PRINT("dev->mtu = %d \n", dev->mtu); + DBG_PRINT("priv->curr_mtu_size = %d \n", priv->curr_mtu_size); + DBG_PRINT("priv->tx_pkt_len = %d \n", priv->tx_pkt_len); + DBG_PRINT("priv->rx_pkt_len = %d \n", priv->rx_pkt_len); + DBG_PRINT("priv->hw_rx_pkt_len = %d \n", priv->hw_rx_pkt_len); + DBG_PRINT("-------------------------- \n"); + + spin_lock_init (&priv->lock); + + register_netdev (dev); + + pci_set_drvdata(pdev, dev); // pdev->driver_data = data; + + + printk (KERN_DEBUG "%s: Identified chip type is '%s'.\n",dev->name,rtl_chip_info[priv->chipset].name); + printk (KERN_INFO "%s: %s at 0x%lx, " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " + "IRQ %d\n", + dev->name, + RTL8169_DRIVER_NAME, + dev->base_addr, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5], + dev->irq); -static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, - void *p) -{ - struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; - if (regs->len > R8169_REGS_SIZE) - regs->len = R8169_REGS_SIZE; + // Config PHY + rtl8169_hw_PHY_config(dev); - spin_lock_irqsave(&tp->lock, flags); - memcpy_fromio(p, tp->mmio_addr, regs->len); - spin_unlock_irqrestore(&tp->lock, flags); -} - -static struct ethtool_ops rtl8169_ethtool_ops = { - .get_drvinfo = rtl8169_get_drvinfo, - .get_regs_len = rtl8169_get_regs_len, - .get_link = ethtool_op_get_link, - .get_settings = rtl8169_get_settings, - .set_settings = rtl8169_set_settings, - .get_rx_csum = rtl8169_get_rx_csum, - .set_rx_csum = rtl8169_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, - .get_regs = rtl8169_get_regs, -}; + DBG_PRINT("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); + RTL_W8( 0x82, 0x01 ); -static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum, - int bitval) -{ - int val; + if( priv->mcfg < MCFG_METHOD_3 ){ + DBG_PRINT("Set PCI Latency=0x40\n"); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); + } - val = mdio_read(ioaddr, reg); - val = (bitval == 1) ? - val | (bitval << bitnum) : val & ~(0x0001 << bitnum); - mdio_write(ioaddr, reg, val & 0xffff); -} - -static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr) -{ - const struct { - u32 mask; - int mac_version; - } mac_info[] = { - { 0x1 << 28, RTL_GIGA_MAC_VER_X }, - { 0x1 << 26, RTL_GIGA_MAC_VER_E }, - { 0x1 << 23, RTL_GIGA_MAC_VER_D }, - { 0x00000000, RTL_GIGA_MAC_VER_B } /* Catch-all */ - }, *p = mac_info; - u32 reg; - - reg = RTL_R32(TxConfig) & 0x7c800000; - while ((reg & p->mask) != p->mask) - p++; - tp->mac_version = p->mac_version; -} - -static void rtl8169_print_mac_version(struct rtl8169_private *tp) -{ - struct { - int version; - char *msg; - } mac_print[] = { - { RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" }, - { RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" }, - { RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" }, - { 0, NULL } - }, *p; - - for (p = mac_print; p->msg; p++) { - if (tp->mac_version == p->version) { - dprintk("mac_version == %s (%04d)\n", p->msg, - p->version); - return; - } - } - dprintk("mac_version == Unknown\n"); -} - -static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr) -{ - const struct { - u16 mask; - u16 set; - int phy_version; - } phy_info[] = { - { 0x000f, 0x0002, RTL_GIGA_PHY_VER_G }, - { 0x000f, 0x0001, RTL_GIGA_PHY_VER_F }, - { 0x000f, 0x0000, RTL_GIGA_PHY_VER_E }, - { 0x0000, 0x0000, RTL_GIGA_PHY_VER_D } /* Catch-all */ - }, *p = phy_info; - u16 reg; - - reg = mdio_read(ioaddr, 3) & 0xffff; - while ((reg & p->mask) != p->set) - p++; - tp->phy_version = p->phy_version; -} - -static void rtl8169_print_phy_version(struct rtl8169_private *tp) -{ - struct { - int version; - char *msg; - u32 reg; - } phy_print[] = { - { RTL_GIGA_PHY_VER_G, "RTL_GIGA_PHY_VER_G", 0x0002 }, - { RTL_GIGA_PHY_VER_F, "RTL_GIGA_PHY_VER_F", 0x0001 }, - { RTL_GIGA_PHY_VER_E, "RTL_GIGA_PHY_VER_E", 0x0000 }, - { RTL_GIGA_PHY_VER_D, "RTL_GIGA_PHY_VER_D", 0x0000 }, - { 0, NULL, 0x0000 } - }, *p; - - for (p = phy_print; p->msg; p++) { - if (tp->phy_version == p->version) { - dprintk("phy_version == %s (%04x)\n", p->msg, p->reg); - return; - } - } - dprintk("phy_version == Unknown\n"); -} - -static void rtl8169_hw_phy_config(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - struct { - u16 regs[5]; /* Beware of bit-sign propagation */ - } phy_magic[5] = { { - { 0x0000, //w 4 15 12 0 - 0x00a1, //w 3 15 0 00a1 - 0x0008, //w 2 15 0 0008 - 0x1020, //w 1 15 0 1020 - 0x1000 } },{ //w 0 15 0 1000 - { 0x7000, //w 4 15 12 7 - 0xff41, //w 3 15 0 ff41 - 0xde60, //w 2 15 0 de60 - 0x0140, //w 1 15 0 0140 - 0x0077 } },{ //w 0 15 0 0077 - { 0xa000, //w 4 15 12 a - 0xdf01, //w 3 15 0 df01 - 0xdf20, //w 2 15 0 df20 - 0xff95, //w 1 15 0 ff95 - 0xfa00 } },{ //w 0 15 0 fa00 - { 0xb000, //w 4 15 12 b - 0xff41, //w 3 15 0 ff41 - 0xde20, //w 2 15 0 de20 - 0x0140, //w 1 15 0 0140 - 0x00bb } },{ //w 0 15 0 00bb - { 0xf000, //w 4 15 12 f - 0xdf01, //w 3 15 0 df01 - 0xdf20, //w 2 15 0 df20 - 0xff95, //w 1 15 0 ff95 - 0xbf00 } //w 0 15 0 bf00 + if( priv->mcfg == MCFG_METHOD_2 ){ + DBG_PRINT("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); + RTL_W8( 0x82, 0x01 ); + DBG_PRINT("Set PHY Reg 0x0bh = 0x00h\n"); + RTL8169_WRITE_GMII_REG( ioaddr, 0x0b, 0x0000 ); //w 0x0b 15 0 0 + } + + // if TBI is not endbled + if( !(RTL_R8(PHYstatus) & TBI_Enable) ){ + int val = RTL8169_READ_GMII_REG( ioaddr, PHY_AUTO_NEGO_REG ); + +#ifdef RTL8169_HW_FLOW_CONTROL_SUPPORT + val |= PHY_Cap_PAUSE | PHY_Cap_ASYM_PAUSE ; +#endif //end #define RTL8169_HW_FLOW_CONTROL_SUPPORT + + option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx]; + // Force RTL8169 in 10/100/1000 Full/Half mode. + if( option > 0 ){ + printk(KERN_INFO "%s: Force-mode Enabled. \n", dev->name); + Cap10_100 = 0; + Cap1000 = 0; + switch( option ){ + case _10_Half: + Cap10_100 = PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _10_Full: + Cap10_100 = PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _100_Half: + Cap10_100 = PHY_Cap_100_Half | PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _100_Full: + Cap10_100 = PHY_Cap_100_Full | PHY_Cap_100_Half | PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _1000_Full: + Cap10_100 = PHY_Cap_100_Full | PHY_Cap_100_Half | PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_1000_Full; + break; + default: + break; + } + RTL8169_WRITE_GMII_REG( ioaddr, PHY_AUTO_NEGO_REG, Cap10_100 | ( val&0xC1F ) ); //leave PHY_AUTO_NEGO_REG bit4:0 unchanged + RTL8169_WRITE_GMII_REG( ioaddr, PHY_1000_CTRL_REG, Cap1000 ); } - }, *p = phy_magic; - int i; + else{ + printk(KERN_INFO "%s: Auto-negotiation Enabled.\n", dev->name); - rtl8169_print_mac_version(tp); - rtl8169_print_phy_version(tp); + // enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged + RTL8169_WRITE_GMII_REG( ioaddr, PHY_AUTO_NEGO_REG, + PHY_Cap_10_Half | PHY_Cap_10_Full | PHY_Cap_100_Half | PHY_Cap_100_Full | ( val&0xC1F ) ); - if (tp->mac_version <= RTL_GIGA_MAC_VER_B) - return; - if (tp->phy_version >= RTL_GIGA_PHY_VER_H) - return; + // enable 1000 Full Mode + RTL8169_WRITE_GMII_REG( ioaddr, PHY_1000_CTRL_REG, PHY_Cap_1000_Full ); - dprintk("MAC version != 0 && PHY version == 0 or 1\n"); - dprintk("Do final_reg2.cfg\n"); + }// end of if( option > 0 ) - /* Shazam ! */ - if (tp->mac_version == RTL_GIGA_MAC_VER_X) { - mdio_write(ioaddr, 31, 0x0001); - mdio_write(ioaddr, 9, 0x273a); - mdio_write(ioaddr, 14, 0x7bfb); - mdio_write(ioaddr, 27, 0x841e); + // Enable auto-negotiation and restart auto-nigotiation + RTL8169_WRITE_GMII_REG( ioaddr, PHY_CTRL_REG, PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego ); + udelay(100); - mdio_write(ioaddr, 31, 0x0002); - mdio_write(ioaddr, 1, 0x90d0); - mdio_write(ioaddr, 31, 0x0000); - return; - } + // wait for auto-negotiation process + for( i = 10000; i > 0; i-- ){ + //check if auto-negotiation complete + if( RTL8169_READ_GMII_REG(ioaddr, PHY_STAT_REG) & PHY_Auto_Neco_Comp ){ + udelay(100); + option = RTL_R8(PHYstatus); + if( option & _1000bpsF ){ + printk(KERN_INFO "%s: 1000Mbps Full-duplex operation.\n", dev->name); + } + else{ + printk(KERN_INFO "%s: %sMbps %s-duplex operation.\n", dev->name, + (option & _100bps) ? "100" : "10", (option & FullDup) ? "Full" : "Half" ); + } + break; + } + else{ + udelay(100); + }// end of if( RTL8169_READ_GMII_REG(ioaddr, 1) & 0x20 ) + }// end for-loop to wait for auto-negotiation process + + option = RTL_R8(PHYstatus); + if( option & _1000bpsF ){ + priv->linkstatus = _1000_Full; + } + else{ + if(option & _100bps){ + priv->linkstatus = (option & FullDup) ? _100_Full : _100_Half; + } + else{ + priv->linkstatus = (option & FullDup) ? _10_Full : _10_Half; + } + } + DBG_PRINT("priv->linkstatus = 0x%02x\n", priv->linkstatus); - /* phy config for RTL8169s mac_version C chip */ - mdio_write(ioaddr, 31, 0x0001); //w 31 2 0 1 - mdio_write(ioaddr, 21, 0x1000); //w 21 15 0 1000 - mdio_write(ioaddr, 24, 0x65c7); //w 24 15 0 65c7 - rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 + }// end of TBI is not enabled + else{ + udelay(100); + DBG_PRINT("1000Mbps Full-duplex operation, TBI Link %s!\n",(RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed" ); - for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) { - int val, pos = 4; + }// end of TBI is not enabled - val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff); - mdio_write(ioaddr, pos, val); - while (--pos >= 0) - mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff); - rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1 - rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 - } - mdio_write(ioaddr, 31, 0x0000); //w 31 2 0 0 + return 0; } -static void rtl8169_phy_timer(unsigned long __opaque) -{ - struct net_device *dev = (struct net_device *)__opaque; - struct rtl8169_private *tp = netdev_priv(dev); - struct timer_list *timer = &tp->timer; - void __iomem *ioaddr = tp->mmio_addr; - unsigned long timeout = RTL8169_PHY_TIMEOUT; - assert(tp->mac_version > RTL_GIGA_MAC_VER_B); - assert(tp->phy_version < RTL_GIGA_PHY_VER_H); - if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full)) - return; - spin_lock_irq(&tp->lock); - if (tp->phy_reset_pending(ioaddr)) { - /* - * A busy loop could burn quite a few cycles on nowadays CPU. - * Let's delay the execution of the timer for a few ticks. - */ - timeout = HZ/10; - goto out_mod_timer; - } - if (tp->link_ok(ioaddr)) - goto out_unlock; - printk(KERN_WARNING PFX "%s: PHY reset until link up\n", dev->name); +//====================================================================================================== +static void __devexit rtl8169_remove_one (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); - tp->phy_reset_enable(ioaddr); + assert (dev != NULL); + assert (priv != NULL); -out_mod_timer: - mod_timer(timer, jiffies + timeout); -out_unlock: - spin_unlock_irq(&tp->lock); -} + unregister_netdev (dev); -static inline void rtl8169_delete_timer(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct timer_list *timer = &tp->timer; +#ifdef RTL8169_USE_IO +#else + iounmap ((void *)(dev->base_addr)); +#endif + pci_release_regions (pdev); - if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) || - (tp->phy_version >= RTL_GIGA_PHY_VER_H)) - return; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + kfree (dev); +#else + free_netdev(dev); +#endif - del_timer_sync(timer); + pci_set_drvdata (pdev, NULL); } -static inline void rtl8169_request_timer(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct timer_list *timer = &tp->timer; - if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) || - (tp->phy_version >= RTL_GIGA_PHY_VER_H)) - return; - init_timer(timer); - timer->expires = jiffies + RTL8169_PHY_TIMEOUT; - timer->data = (unsigned long)(dev); - timer->function = rtl8169_phy_timer; - add_timer(timer); -} -#ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling 'interrupt' - used by things like netconsole to send skbs - * without having to re-enable interrupts. It's not called while - * the interrupt routine is executing. - */ -static void rtl8169_netpoll(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; - - disable_irq(pdev->irq); - rtl8169_interrupt(pdev->irq, dev, NULL); - enable_irq(pdev->irq); -} -#endif -static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, - void __iomem *ioaddr) -{ - iounmap(ioaddr); - pci_release_regions(pdev); - pci_disable_device(pdev); - free_netdev(dev); -} -static int __devinit -rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out, - void __iomem **ioaddr_out) + +//====================================================================================================== +static int rtl8169_open (struct net_device *dev) { - void __iomem *ioaddr; - struct net_device *dev; - struct rtl8169_private *tp; - int rc = -ENOMEM, i, acpi_idle_state = 0, pm_cap; + struct rtl8169_private *priv = dev->priv; + struct pci_dev *pdev = priv->pci_dev; + int retval; +// u8 diff; +// u32 TxPhyAddr, RxPhyAddr; - assert(ioaddr_out != NULL); - /* dev zeroed in alloc_etherdev */ - dev = alloc_etherdev(sizeof (*tp)); - if (dev == NULL) { - printk(KERN_ERR PFX "unable to alloc new ethernet\n"); - goto err_out; + if( priv->drvinit_fail == 1 ){ + printk("%s: Gigabit driver open failed.\n", dev->name ); + return -ENOMEM; } - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &pdev->dev); - tp = netdev_priv(dev); - - /* enable device (incl. PCI PM wakeup and hotplug setup) */ - rc = pci_enable_device(pdev); - if (rc) { - printk(KERN_ERR PFX "%s: enable failure\n", pci_name(pdev)); - goto err_out_free_dev; - } - - rc = pci_set_mwi(pdev); - if (rc < 0) - goto err_out_disable; - - /* save power state before pci_enable_device overwrites it */ - pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pm_cap) { - u16 pwr_command; - - pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command); - acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK; - } else { - printk(KERN_ERR PFX - "Cannot find PowerManagement capability, aborting.\n"); - goto err_out_mwi; + retval = request_irq (dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev); + if (retval) { + return retval; } - /* make sure PCI base addr 1 is MMIO */ - if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { - printk(KERN_ERR PFX - "region #1 not an MMIO resource, aborting\n"); - rc = -ENODEV; - goto err_out_mwi; + //2004-05-11 + // Allocate tx/rx descriptor space + priv->sizeof_txdesc_space = NUM_TX_DESC * sizeof(struct TxDesc)+256; + priv->txdesc_space = pci_alloc_consistent( pdev, priv->sizeof_txdesc_space, &priv->txdesc_phy_dma_addr ); + if( priv->txdesc_space == NULL ){ + printk("%s: Gigabit driver alloc txdesc_space failed.\n", dev->name ); + return -ENOMEM; } - /* check for weird/broken PCI region reporting */ - if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) { - printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n"); - rc = -ENODEV; - goto err_out_mwi; + priv->sizeof_rxdesc_space = NUM_RX_DESC * sizeof(struct RxDesc)+256; + priv->rxdesc_space = pci_alloc_consistent( pdev, priv->sizeof_rxdesc_space, &priv->rxdesc_phy_dma_addr ); + if( priv->rxdesc_space == NULL ){ + printk("%s: Gigabit driver alloc rxdesc_space failed.\n", dev->name ); + return -ENOMEM; } - rc = pci_request_regions(pdev, MODULENAME); - if (rc) { - printk(KERN_ERR PFX "%s: could not request regions.\n", - pci_name(pdev)); - goto err_out_mwi; + if(priv->txdesc_phy_dma_addr & 0xff){ + printk("%s: Gigabit driver txdesc_phy_dma_addr is not 256-bytes-aligned.\n", dev->name ); } + if(priv->rxdesc_phy_dma_addr & 0xff){ + printk("%s: Gigabit driver rxdesc_phy_dma_addr is not 256-bytes-aligned.\n", dev->name ); + } + // Set tx/rx descriptor space + priv->TxDescArray = (struct TxDesc *)priv->txdesc_space; + priv->RxDescArray = (struct RxDesc *)priv->rxdesc_space; - tp->cp_cmd = PCIMulRW | RxChkSum; + { + int i; + struct sk_buff *skb = NULL; - if ((sizeof(dma_addr_t) > 4) && - !pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac) { - tp->cp_cmd |= PCIDAC; - dev->features |= NETIF_F_HIGHDMA; - } else { - rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (rc < 0) { - printk(KERN_ERR PFX "DMA configuration failed.\n"); - goto err_out_free_res; + for(i=0;iRx_skbuff[i] = skb; + } + else{ + printk("%s: Gigabit driver failed to allocate skbuff.\n", dev->name); + priv->drvinit_fail = 1; + } } } - pci_set_master(pdev); - /* ioremap MMIO region */ - ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE); - if (ioaddr == NULL) { - printk(KERN_ERR PFX "cannot remap MMIO, aborting\n"); - rc = -EIO; - goto err_out_free_res; - } + ////////////////////////////////////////////////////////////////////////////// + rtl8169_init_ring (dev); + rtl8169_hw_start (dev); - /* Unneeded ? Don't mess with Mrs. Murphy. */ - rtl8169_irq_mask_and_ack(ioaddr); - /* Soft reset the chip. */ - RTL_W8(ChipCmd, CmdReset); + // ------------------------------------------------------ + DBG_PRINT("FIX PCS -> rtl8169_request_timer\n"); + priv->expire_time = RTL8169_TIMER_EXPIRE_TIME; + rtl8169_request_timer( (&priv->r8169_timer), priv->expire_time, rtl8169_timer_handler, ((void *)dev) ); //in open() - /* Check that the chip has finished the reset. */ - for (i = 1000; i > 0; i--) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; - udelay(10); - } - /* Identify chip attached to board */ - rtl8169_get_mac_version(tp, ioaddr); - rtl8169_get_phy_version(tp, ioaddr); + DBG_PRINT("%s: %s() alloc_rxskb_cnt = %d\n", dev->name, __FUNCTION__, alloc_rxskb_cnt ); - rtl8169_print_mac_version(tp); - rtl8169_print_phy_version(tp); + return 0; - for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { - if (tp->mac_version == rtl_chip_info[i].mac_version) - break; - } - if (i < 0) { - /* Unknown chip: assume array element #0, original RTL-8169 */ - printk(KERN_DEBUG PFX - "PCI device %s: unknown chip version, assuming %s\n", - pci_name(pdev), rtl_chip_info[0].name); - i++; - } - tp->chipset = i; +}//end of rtl8169_open (struct net_device *dev) - *ioaddr_out = ioaddr; - *dev_out = dev; -out: - return rc; -err_out_free_res: - pci_release_regions(pdev); -err_out_mwi: - pci_clear_mwi(pdev); -err_out_disable: - pci_disable_device(pdev); -err_out_free_dev: - free_netdev(dev); -err_out: - *ioaddr_out = NULL; - *dev_out = NULL; - goto out; -} - -static int __devinit -rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct net_device *dev = NULL; - struct rtl8169_private *tp; - void __iomem *ioaddr = NULL; - static int board_idx = -1; - static int printed_version = 0; - u8 autoneg, duplex; - u16 speed; - int i, rc; - assert(pdev != NULL); - assert(ent != NULL); - board_idx++; - if (!printed_version) { - printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", - MODULENAME, RTL8169_VERSION); - printed_version = 1; - } - - rc = rtl8169_init_board(pdev, &dev, &ioaddr); - if (rc) - return rc; - - tp = netdev_priv(dev); - assert(ioaddr != NULL); - - if (RTL_R8(PHYstatus) & TBI_Enable) { - tp->set_speed = rtl8169_set_speed_tbi; - tp->get_settings = rtl8169_gset_tbi; - tp->phy_reset_enable = rtl8169_tbi_reset_enable; - tp->phy_reset_pending = rtl8169_tbi_reset_pending; - tp->link_ok = rtl8169_tbi_link_ok; - - tp->phy_1000_ctrl_reg = PHY_Cap_1000_Full; /* Implied by TBI */ - } else { - tp->set_speed = rtl8169_set_speed_xmii; - tp->get_settings = rtl8169_gset_xmii; - tp->phy_reset_enable = rtl8169_xmii_reset_enable; - tp->phy_reset_pending = rtl8169_xmii_reset_pending; - tp->link_ok = rtl8169_xmii_link_ok; - } - - /* Get MAC address. FIXME: read EEPROM */ - for (i = 0; i < MAC_ADDR_LEN; i++) - dev->dev_addr[i] = RTL_R8(MAC0 + i); - - dev->open = rtl8169_open; - dev->hard_start_xmit = rtl8169_start_xmit; - dev->get_stats = rtl8169_get_stats; - SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops); - dev->stop = rtl8169_close; - dev->tx_timeout = rtl8169_tx_timeout; - dev->set_multicast_list = rtl8169_set_rx_mode; - dev->watchdog_timeo = RTL8169_TX_TIMEOUT; - dev->irq = pdev->irq; - dev->base_addr = (unsigned long) ioaddr; - dev->change_mtu = rtl8169_change_mtu; - -#ifdef CONFIG_R8169_NAPI - dev->poll = rtl8169_poll; - dev->weight = R8169_NAPI_WEIGHT; - printk(KERN_INFO PFX "NAPI enabled\n"); -#endif +//====================================================================================================== +static void rtl8169_hw_PHY_reset(struct net_device *dev) +{ + int val, phy_reset_expiretime = 50; + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; -#ifdef CONFIG_R8169_VLAN - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->vlan_rx_register = rtl8169_vlan_rx_register; - dev->vlan_rx_kill_vid = rtl8169_vlan_rx_kill_vid; -#endif + DBG_PRINT("%s: Reset RTL8169s PHY\n", dev->name); -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = rtl8169_netpoll; -#endif + val = ( RTL8169_READ_GMII_REG( ioaddr, 0 ) | 0x8000 ) & 0xffff; + RTL8169_WRITE_GMII_REG( ioaddr, 0, val ); - tp->intr_mask = 0xffff; - tp->pci_dev = pdev; - tp->mmio_addr = ioaddr; + do //waiting for phy reset + { + if( RTL8169_READ_GMII_REG( ioaddr, 0 ) & 0x8000 ){ + phy_reset_expiretime --; + udelay(100); + } + else{ + break; + } + }while( phy_reset_expiretime >= 0 ); - spin_lock_init(&tp->lock); + assert( phy_reset_expiretime > 0 ); +} - rc = register_netdev(dev); - if (rc) { - rtl8169_release_board(pdev, dev, ioaddr); - return rc; - } - printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name, - rtl_chip_info[tp->chipset].name); - pci_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: %s at 0x%lx, " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " - "IRQ %d\n", - dev->name, - rtl_chip_info[ent->driver_data].name, - dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], dev->irq); +//====================================================================================================== +static void rtl8169_hw_PHY_config (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + void *ioaddr = (void*)priv->ioaddr; - rtl8169_hw_phy_config(dev); + DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n",priv->mcfg,priv->pcfg); - dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); - RTL_W8(0x82, 0x01); + if( priv->mcfg == MCFG_METHOD_4 ){ + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1F, 0x0001 ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x09, 0x273a ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x0e, 0x7bfb ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1b, 0x841e ); - if (tp->mac_version < RTL_GIGA_MAC_VER_E) { - dprintk("Set PCI Latency=0x40\n"); - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1F, 0x0002 ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x01, 0x90D0 ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1F, 0x0000 ); } - - if (tp->mac_version == RTL_GIGA_MAC_VER_D) { - dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); - RTL_W8(0x82, 0x01); - dprintk("Set PHY Reg 0x0bh = 0x00h\n"); - mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0 + else{ + DBG_PRINT("priv->mcfg=%d. Discard hw PHY config.\n",priv->mcfg); } - - rtl8169_link_option(board_idx, &autoneg, &speed, &duplex); - - rtl8169_set_speed(dev, autoneg, speed, duplex); - - if (RTL_R8(PHYstatus) & TBI_Enable) - printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name); - - return 0; } -static void __devexit -rtl8169_remove_one(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - assert(dev != NULL); - assert(tp != NULL); - unregister_netdev(dev); - rtl8169_release_board(pdev, dev, tp->mmio_addr); - pci_set_drvdata(pdev, NULL); -} -#ifdef CONFIG_PM -static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; - if (!netif_running(dev)) - return 0; - - netif_device_detach(dev); - netif_stop_queue(dev); - spin_lock_irqsave(&tp->lock, flags); - - /* Disable interrupts, stop Rx and Tx */ - RTL_W16(IntrMask, 0); - RTL_W8(ChipCmd, 0); - - /* Update the error counts. */ - tp->stats.rx_missed_errors += RTL_R32(RxMissed); - RTL_W32(RxMissed, 0); - spin_unlock_irqrestore(&tp->lock, flags); - - return 0; -} -static int rtl8169_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - if (!netif_running(dev)) - return 0; - netif_device_attach(dev); - rtl8169_hw_start(dev); - return 0; -} - -#endif /* CONFIG_PM */ - -static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, - struct net_device *dev) +//====================================================================================================== +static void rtl8169_hw_start (struct net_device *dev) { - unsigned int mtu = dev->mtu; - - tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE; -} - -static int rtl8169_open(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; - int retval; - - rtl8169_set_rxbufsize(tp, dev); - - retval = - request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev); - if (retval < 0) - goto out; - - retval = -ENOMEM; - - /* - * Rx and Tx desscriptors needs 256 bytes alignment. - * pci_alloc_consistent provides more. - */ - tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, - &tp->TxPhyAddr); - if (!tp->TxDescArray) - goto err_free_irq; - - tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, - &tp->RxPhyAddr); - if (!tp->RxDescArray) - goto err_free_tx; + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + u32 i; - retval = rtl8169_init_ring(dev); - if (retval < 0) - goto err_free_rx; - INIT_WORK(&tp->task, NULL, dev); + /* Soft reset the chip. */ + RTL_W8 ( ChipCmd, CmdReset); - rtl8169_hw_start(dev); + /* Check that the chip has finished the reset. */ + for (i = 1000; i > 0; i--){ + if ((RTL_R8( ChipCmd ) & CmdReset) == 0) break; + else udelay (10); + } - rtl8169_request_timer(dev); + RTL_W8 ( Cfg9346, Cfg9346_Unlock); + RTL_W8 ( ChipCmd, CmdTxEnb | CmdRxEnb); + RTL_W8 ( ETThReg, ETTh); - rtl8169_check_link_status(dev, tp, tp->mmio_addr); -out: - return retval; + // For gigabit rtl8169 + RTL_W16 ( RxMaxSize, (unsigned short)priv->hw_rx_pkt_len ); -err_free_rx: - pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, - tp->RxPhyAddr); -err_free_tx: - pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, - tp->TxPhyAddr); -err_free_irq: - free_irq(dev->irq, dev); - goto out; -} + // Set Rx Config register + i = rtl8169_rx_config | ( RTL_R32( RxConfig ) & rtl_chip_info[priv->chipset].RxConfigMask); + RTL_W32 ( RxConfig, i); -static void rtl8169_hw_reset(void __iomem *ioaddr) -{ - /* Disable interrupts */ - rtl8169_irq_mask_and_ack(ioaddr); - /* Reset the chipset */ - RTL_W8(ChipCmd, CmdReset); + /* Set DMA burst size and Interframe Gap Time */ + RTL_W32 ( TxConfig, (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << TxInterFrameGapShift) ); - /* PCI commit */ - RTL_R8(ChipCmd); -} -static void -rtl8169_hw_start(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - u32 i; - /* Soft reset the chip. */ - RTL_W8(ChipCmd, CmdReset); + RTL_W16( CPlusCmd, RTL_R16(CPlusCmd) ); - /* Check that the chip has finished the reset. */ - for (i = 1000; i > 0; i--) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; - udelay(10); + if( priv->mcfg == MCFG_METHOD_2 || + priv->mcfg == MCFG_METHOD_3) + { + RTL_W16( CPlusCmd, (RTL_R16(CPlusCmd)|(1<<14)|(1<<3)) ); + DBG_PRINT("Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"); + } + else + { + RTL_W16( CPlusCmd, (RTL_R16(CPlusCmd)|(1<<3)) ); + DBG_PRINT("Set MAC Reg C+CR Offset 0xE0: bit-3.\n"); } - RTL_W8(Cfg9346, Cfg9346_Unlock); - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - RTL_W8(EarlyTxThres, EarlyTxThld); - - /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, 16383); - - /* Set Rx Config register */ - i = rtl8169_rx_config | - (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); - RTL_W32(RxConfig, i); + { + //RTL_W16(0xE2, 0x1517); + //RTL_W16(0xE2, 0x152a); + //RTL_W16(0xE2, 0x282a); + RTL_W16(0xE2, 0x0000); + } - /* Set DMA burst size and Interframe Gap Time */ - RTL_W32(TxConfig, - (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << - TxInterFrameGapShift)); - tp->cp_cmd |= RTL_R16(CPlusCmd); - RTL_W16(CPlusCmd, tp->cp_cmd); - - if ((tp->mac_version == RTL_GIGA_MAC_VER_D) || - (tp->mac_version == RTL_GIGA_MAC_VER_E)) { - dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. " - "Bit-3 and bit-14 MUST be 1\n"); - tp->cp_cmd |= (1 << 14) | PCIMulRW; - RTL_W16(CPlusCmd, tp->cp_cmd); - } - - /* - * Undocumented corner. Supposedly: - * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets - */ - RTL_W16(IntrMitigate, 0x0000); - - RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); - RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); - RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); - RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); - RTL_W8(Cfg9346, Cfg9346_Lock); - udelay(10); - - RTL_W32(RxMissed, 0); - - rtl8169_set_rx_mode(dev); + priv->cur_rx = 0; - /* no early-rx interrupts */ - RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); + RTL_W32 ( TxDescStartAddr, priv->txdesc_phy_dma_addr); + RTL_W32 ( TxDescStartAddr + 4, 0x00); + RTL_W32 ( RxDescStartAddr, priv->rxdesc_phy_dma_addr); + RTL_W32 ( RxDescStartAddr + 4, 0x00); - /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, rtl8169_intr_mask); + RTL_W8 ( Cfg9346, Cfg9346_Lock ); + udelay (10); - netif_start_queue(dev); -} + RTL_W32 ( RxMissed, 0 ); -static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) -{ - struct rtl8169_private *tp = netdev_priv(dev); - int ret = 0; + rtl8169_set_rx_mode (dev); - if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu) - return -EINVAL; + RTL_W16 ( MultiIntr, RTL_R16(MultiIntr) & 0xF000); - dev->mtu = new_mtu; + RTL_W16 ( IntrMask, rtl8169_intr_mask); - if (!netif_running(dev)) - goto out; + netif_start_queue (dev); - rtl8169_down(dev); +}//end of rtl8169_hw_start (struct net_device *dev) - rtl8169_set_rxbufsize(tp, dev); - ret = rtl8169_init_ring(dev); - if (ret < 0) - goto out; - netif_poll_enable(dev); - rtl8169_hw_start(dev); - rtl8169_request_timer(dev); -out: - return ret; -} -static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) +//====================================================================================================== +static void rtl8169_init_ring (struct net_device *dev) { - desc->addr = 0x0badbadbadbadbadull; - desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask); -} + struct rtl8169_private *priv = dev->priv; + struct pci_dev *pdev = priv->pci_dev; + int i; + struct sk_buff *skb; + -static void rtl8169_free_rx_skb(struct rtl8169_private *tp, - struct sk_buff **sk_buff, struct RxDesc *desc) -{ - struct pci_dev *pdev = tp->pci_dev; + priv->cur_rx = 0; + priv->cur_tx = 0; + priv->dirty_tx = 0; + memset(priv->TxDescArray, 0x0, NUM_TX_DESC*sizeof(struct TxDesc)); + memset(priv->RxDescArray, 0x0, NUM_RX_DESC*sizeof(struct RxDesc)); - pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - dev_kfree_skb(*sk_buff); - *sk_buff = NULL; - rtl8169_make_unusable_by_asic(desc); -} -static inline void rtl8169_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz) -{ - u32 eor = le32_to_cpu(desc->opts1) & RingEnd; + for (i=0 ; iTx_skbuff[i]=NULL; + priv->txdesc_array_dma_addr[i] = pci_map_single(pdev, &priv->TxDescArray[i], sizeof(struct TxDesc), PCI_DMA_TODEVICE); + } - desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz); -} + for (i=0; i RxDescArray[i].status = cpu_to_le32((OWNbit | EORbit) | (unsigned long)priv->hw_rx_pkt_len); + } + else{ + priv->RxDescArray[i].status = cpu_to_le32(OWNbit | (unsigned long)priv->hw_rx_pkt_len); + } -static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, - u32 rx_buf_sz) -{ - desc->addr = cpu_to_le64(mapping); - wmb(); - rtl8169_mark_to_asic(desc, rx_buf_sz); + {//----------------------------------------------------------------------- + skb = priv->Rx_skbuff[i]; + priv->rx_skbuff_dma_addr[i] = pci_map_single(pdev, skb->data, MAX_RX_SKBDATA_SIZE, PCI_DMA_FROMDEVICE); + + if( skb != NULL ){ + priv->RxDescArray[i].buf_addr = cpu_to_le32(priv->rx_skbuff_dma_addr[i]); + priv->RxDescArray[i].buf_Haddr = 0; + } + else{ + DBG_PRINT("%s: %s() Rx_skbuff == NULL\n", dev->name, __FUNCTION__); + priv->drvinit_fail = 1; + } + }//----------------------------------------------------------------------- + priv->rxdesc_array_dma_addr[i] = pci_map_single(pdev, &priv->RxDescArray[i], sizeof(struct RxDesc), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(pdev, priv->rxdesc_array_dma_addr[i], sizeof(struct RxDesc), PCI_DMA_TODEVICE); + } } -static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, - struct RxDesc *desc, int rx_buf_sz) -{ - struct sk_buff *skb; - dma_addr_t mapping; - int ret = 0; - skb = dev_alloc_skb(rx_buf_sz + NET_IP_ALIGN); - if (!skb) - goto err_out; - skb_reserve(skb, NET_IP_ALIGN); - *sk_buff = skb; - mapping = pci_map_single(pdev, skb->tail, rx_buf_sz, - PCI_DMA_FROMDEVICE); - rtl8169_map_to_asic(desc, mapping, rx_buf_sz); -out: - return ret; -err_out: - ret = -ENOMEM; - rtl8169_make_unusable_by_asic(desc); - goto out; -} - -static void rtl8169_rx_clear(struct rtl8169_private *tp) +//====================================================================================================== +static void rtl8169_tx_clear (struct rtl8169_private *priv) { int i; - for (i = 0; i < NUM_RX_DESC; i++) { - if (tp->Rx_skbuff[i]) { - rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i, - tp->RxDescArray + i); + priv->cur_tx = 0; + for ( i = 0 ; i < NUM_TX_DESC ; i++ ){ + if ( priv->Tx_skbuff[i] != NULL ) { + dev_kfree_skb ( priv->Tx_skbuff[i] ); + priv->Tx_skbuff[i] = NULL; + priv->stats.tx_dropped++; } } } -static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, - u32 start, u32 end) -{ - u32 cur; - - for (cur = start; end - cur > 0; cur++) { - int ret, i = cur % NUM_RX_DESC; - if (tp->Rx_skbuff[i]) - continue; - - ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, - tp->RxDescArray + i, tp->rx_buf_sz); - if (ret < 0) - break; - } - return cur - start; -} -static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc) -{ - desc->opts1 |= cpu_to_le32(RingEnd); -} -static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) -{ - tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; -} -static int rtl8169_init_ring(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - rtl8169_init_ring_indexes(tp); - memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); - memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); +//====================================================================================================== +static void rtl8169_tx_timeout (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + u8 tmp8; - if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC) - goto err_out; + /* disable Tx, if not already */ + tmp8 = RTL_R8( ChipCmd ); + if (tmp8 & CmdTxEnb){ + RTL_W8 ( ChipCmd, tmp8 & ~CmdTxEnb); + } - rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 ( IntrMask, 0x0000); - return 0; + /* Stop a shared interrupt from scavenging while we are. */ + spin_lock_irq (&priv->lock); + rtl8169_tx_clear (priv); + spin_unlock_irq (&priv->lock); -err_out: - rtl8169_rx_clear(tp); - return -ENOMEM; -} -static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, - struct TxDesc *desc) -{ - unsigned int len = tx_skb->len; + rtl8169_hw_start (dev); - pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE); - desc->opts1 = 0x00; - desc->opts2 = 0x00; - desc->addr = 0x00; - tx_skb->len = 0; + netif_wake_queue (dev); } -static void rtl8169_tx_clear(struct rtl8169_private *tp) -{ - unsigned int i; - for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) { - unsigned int entry = i % NUM_TX_DESC; - struct ring_info *tx_skb = tp->tx_skb + entry; - unsigned int len = tx_skb->len; - if (len) { - struct sk_buff *skb = tx_skb->skb; - rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, - tp->TxDescArray + entry); - if (skb) { - dev_kfree_skb(skb); - tx_skb->skb = NULL; - } - tp->stats.tx_dropped++; - } - } - tp->cur_tx = tp->dirty_tx = 0; -} -static void rtl8169_schedule_work(struct net_device *dev, void (*task)(void *)) -{ - struct rtl8169_private *tp = netdev_priv(dev); - PREPARE_WORK(&tp->task, task, dev); - schedule_delayed_work(&tp->task, 4); -} -static void rtl8169_wait_for_quiescence(struct net_device *dev) +//====================================================================================================== +static int rtl8169_start_xmit (struct sk_buff *skb, struct net_device *dev) { - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - - synchronize_irq(dev->irq); + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + struct pci_dev *pdev = priv->pci_dev; + int entry = priv->cur_tx % NUM_TX_DESC; + int buf_len = 60; + dma_addr_t txbuf_dma_addr; - /* Wait for any pending NAPI task to complete */ - netif_poll_disable(dev); + spin_lock_irq (&priv->lock); - rtl8169_irq_mask_and_ack(ioaddr); - - netif_poll_enable(dev); -} + if( (le32_to_cpu(priv->TxDescArray[entry].status) & OWNbit)==0 ){ -static void rtl8169_reinit_task(void *_data) -{ - struct net_device *dev = _data; - int ret; - - if (netif_running(dev)) { - rtl8169_wait_for_quiescence(dev); - rtl8169_close(dev); - } + priv->Tx_skbuff[entry] = skb; + txbuf_dma_addr = pci_map_single(pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + + priv->TxDescArray[entry].buf_addr = cpu_to_le32(txbuf_dma_addr); + DBG_PRINT("%s: TX pkt_size = %d\n", __FUNCTION__, skb->len); + if( skb->len <= priv->tx_pkt_len ){ + buf_len = skb->len; + } + else{ + printk("%s: Error -- Tx packet size(%d) > mtu(%d)+14\n", dev->name, skb->len, dev->mtu); + buf_len = priv->tx_pkt_len; + } - ret = rtl8169_open(dev); - if (unlikely(ret < 0)) { - if (net_ratelimit()) { - printk(PFX KERN_ERR "%s: reinit failure (status = %d)." - " Rescheduling.\n", dev->name, ret); + if( entry != (NUM_TX_DESC-1) ){ + priv->TxDescArray[entry].status = cpu_to_le32((OWNbit | FSbit | LSbit) | buf_len); + } + else{ + priv->TxDescArray[entry].status = cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | buf_len); } - rtl8169_schedule_work(dev, rtl8169_reinit_task); - } -} -static void rtl8169_reset_task(void *_data) -{ - struct net_device *dev = _data; - struct rtl8169_private *tp = netdev_priv(dev); + pci_dma_sync_single_for_device(pdev, priv->txdesc_array_dma_addr[entry], sizeof(struct TxDesc), PCI_DMA_TODEVICE); - if (!netif_running(dev)) - return; + RTL_W8 ( TxPoll, 0x40); //set polling bit - rtl8169_wait_for_quiescence(dev); + dev->trans_start = jiffies; - rtl8169_rx_interrupt(dev, tp, tp->mmio_addr); - rtl8169_tx_clear(tp); + priv->stats.tx_bytes += ( (skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN); + priv->cur_tx++; + }//end of if( (priv->TxDescArray[entry].status & 0x80000000)==0 ) - if (tp->dirty_rx == tp->cur_rx) { - rtl8169_init_ring_indexes(tp); - rtl8169_hw_start(dev); - netif_wake_queue(dev); - } else { - if (net_ratelimit()) { - printk(PFX KERN_EMERG "%s: Rx buffers shortage\n", - dev->name); + spin_unlock_irq (&priv->lock); + + if ( (priv->cur_tx - NUM_TX_DESC) == priv->dirty_tx ){ + netif_stop_queue (dev); + } + else{ + if (netif_queue_stopped (dev)){ + netif_wake_queue (dev); } - rtl8169_schedule_work(dev, rtl8169_reset_task); } -} - -static void rtl8169_tx_timeout(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - - rtl8169_hw_reset(tp->mmio_addr); - /* Let's wait a bit while any (async) irq lands on */ - rtl8169_schedule_work(dev, rtl8169_reset_task); + return 0; } -static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, - u32 opts1) -{ - struct skb_shared_info *info = skb_shinfo(skb); - unsigned int cur_frag, entry; - struct TxDesc *txd; - - entry = tp->cur_tx; - for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { - skb_frag_t *frag = info->frags + cur_frag; - dma_addr_t mapping; - u32 status, len; - void *addr; - - entry = (entry + 1) % NUM_TX_DESC; - - txd = tp->TxDescArray + entry; - len = frag->size; - addr = ((void *) page_address(frag->page)) + frag->page_offset; - mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE); - /* anti gcc 2.95.3 bugware (sic) */ - status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); - txd->opts1 = cpu_to_le32(status); - txd->addr = cpu_to_le64(mapping); - tp->tx_skb[entry].len = len; - } - if (cur_frag) { - tp->tx_skb[entry].skb = skb; - txd->opts1 |= cpu_to_le32(LastFrag); - } - return cur_frag; -} -static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) +//====================================================================================================== +static void rtl8169_tx_interrupt (struct net_device *dev, struct rtl8169_private *priv, unsigned long ioaddr) { - if (dev->features & NETIF_F_TSO) { - u32 mss = skb_shinfo(skb)->tso_size; - - if (mss) - return LargeSend | ((mss & MSSMask) << MSSShift); + unsigned long dirty_tx, tx_left=0; + int entry = priv->cur_tx % NUM_TX_DESC; + int txloop_cnt = 0; + + assert (dev != NULL); + assert (priv != NULL); + assert (ioaddr != NULL); + + + dirty_tx = priv->dirty_tx; + tx_left = priv->cur_tx - dirty_tx; + + while( (tx_left > 0) && (txloop_cnt < max_interrupt_work) ){ + if( (le32_to_cpu(priv->TxDescArray[entry].status) & OWNbit) == 0 ){ + +#ifdef RTL8169_DYNAMIC_CONTROL + r8169_callback_tx(&(priv->rt), 1, priv->Tx_skbuff[dirty_tx % NUM_TX_DESC]->len); +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + dev_kfree_skb_irq( priv->Tx_skbuff[dirty_tx % NUM_TX_DESC] ); + priv->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL; + priv->stats.tx_packets++; + dirty_tx++; + tx_left--; + entry++; + } + txloop_cnt ++; } - if (skb->ip_summed == CHECKSUM_HW) { - const struct iphdr *ip = skb->nh.iph; - if (ip->protocol == IPPROTO_TCP) - return IPCS | TCPCS; - else if (ip->protocol == IPPROTO_UDP) - return IPCS | UDPCS; - WARN_ON(1); /* we need a WARN() */ + if (priv->dirty_tx != dirty_tx) { + priv->dirty_tx = dirty_tx; + if (netif_queue_stopped (dev)) + netif_wake_queue (dev); } - return 0; } -static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC; - struct TxDesc *txd = tp->TxDescArray + entry; - void __iomem *ioaddr = tp->mmio_addr; - dma_addr_t mapping; - u32 status, len; - u32 opts1; - int ret = 0; - - if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", - dev->name); - goto err_stop; - } - if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) - goto err_stop; - opts1 = DescOwn | rtl8169_tso_csum(skb, dev); - frags = rtl8169_xmit_frags(tp, skb, opts1); - if (frags) { - len = skb_headlen(skb); - opts1 |= FirstFrag; - } else { - len = skb->len; - if (unlikely(len < ETH_ZLEN)) { - skb = skb_padto(skb, ETH_ZLEN); - if (!skb) - goto err_update_stats; - len = ETH_ZLEN; - } - opts1 |= FirstFrag | LastFrag; - tp->tx_skb[entry].skb = skb; - } +//====================================================================================================== +static void rtl8169_rx_interrupt (struct net_device *dev, struct rtl8169_private *priv, unsigned long ioaddr) +{ + struct pci_dev *pdev = priv->pci_dev; + int cur_rx; + int pkt_size = 0 ; + int rxdesc_cnt = 0; + int ret; + struct sk_buff *n_skb = NULL; + struct sk_buff *cur_skb; + struct sk_buff *rx_skb; + struct RxDesc *rxdesc; + + assert (dev != NULL); + assert (priv != NULL); + assert (ioaddr != NULL); + + + cur_rx = priv->cur_rx; + + rxdesc = &priv->RxDescArray[cur_rx]; + pci_dma_sync_single_for_device(pdev, priv->rxdesc_array_dma_addr[cur_rx], sizeof(struct RxDesc), PCI_DMA_FROMDEVICE); + + while ( ((le32_to_cpu(rxdesc->status) & OWNbit)== 0) && (rxdesc_cnt < max_interrupt_work) ){ + + rxdesc_cnt++; + + if( le32_to_cpu(rxdesc->status) & RxRES ){ + printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); + priv->stats.rx_errors++; + if ( le32_to_cpu(rxdesc->status) & (RxRWT|RxRUNT) ) + priv->stats.rx_length_errors++; + if ( le32_to_cpu(rxdesc->status) & RxCRC) + priv->stats.rx_crc_errors++; + } + else{ + pkt_size=(int)(le32_to_cpu(rxdesc->status) & 0x00001FFF)-4; + + if( pkt_size > priv->rx_pkt_len ){ + printk("%s: Error -- Rx packet size(%d) > mtu(%d)+14\n", dev->name, pkt_size, dev->mtu); + pkt_size = priv->rx_pkt_len; + } - mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE); + DBG_PRINT("%s: RX pkt_size = %d\n", __FUNCTION__, pkt_size); - tp->tx_skb[entry].len = len; - txd->addr = cpu_to_le64(mapping); - txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); + {// ----------------------------------------------------- + rx_skb = priv->Rx_skbuff[cur_rx]; + n_skb = RTL8169_ALLOC_RXSKB(MAX_RX_SKBDATA_SIZE); + if( n_skb != NULL ) { + skb_reserve (n_skb, 2); // 16 byte align the IP fields. // - wmb(); + // Indicate rx_skb + if( rx_skb != NULL ){ + rx_skb->dev = dev; + pci_dma_sync_single_for_device(pdev, priv->rx_skbuff_dma_addr[cur_rx], sizeof(struct RxDesc), PCI_DMA_FROMDEVICE); - /* anti gcc 2.95.3 bugware (sic) */ - status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); - txd->opts1 = cpu_to_le32(status); + skb_put ( rx_skb, pkt_size ); + rx_skb->protocol = eth_type_trans ( rx_skb, dev ); + ret = RTL8169_NETIF_RX (rx_skb); - dev->trans_start = jiffies; +// dev->last_rx = jiffies; + priv->stats.rx_bytes += pkt_size; + priv->stats.rx_packets++; - tp->cur_tx += frags + 1; +#ifdef RTL8169_DYNAMIC_CONTROL + r8169_callback_rx( &(priv->rt), 1, pkt_size); +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL - smp_wmb(); + }//end if( rx_skb != NULL ) - RTL_W8(TxPoll, 0x40); /* set polling bit */ + priv->Rx_skbuff[cur_rx] = n_skb; + } + else{ + DBG_PRINT("%s: Allocate n_skb failed!\n",__FUNCTION__ ); + priv->Rx_skbuff[cur_rx] = rx_skb; + } - if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { - netif_stop_queue(dev); - smp_rmb(); - if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) - netif_wake_queue(dev); - } -out: - return ret; + // Update rx descriptor + if( cur_rx == (NUM_RX_DESC-1) ){ + priv->RxDescArray[cur_rx].status = cpu_to_le32((OWNbit | EORbit) | (unsigned long)priv->hw_rx_pkt_len); + } + else{ + priv->RxDescArray[cur_rx].status = cpu_to_le32(OWNbit | (unsigned long)priv->hw_rx_pkt_len); + } -err_stop: - netif_stop_queue(dev); - ret = 1; -err_update_stats: - tp->stats.tx_dropped++; - goto out; -} + cur_skb = priv->Rx_skbuff[cur_rx]; -static void rtl8169_pcierr_interrupt(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; - void __iomem *ioaddr = tp->mmio_addr; - u16 pci_status, pci_cmd; + if( cur_skb != NULL ){ + priv->rx_skbuff_dma_addr[cur_rx] = pci_map_single(pdev, cur_skb->data, MAX_RX_SKBDATA_SIZE, PCI_DMA_FROMDEVICE); + rxdesc->buf_addr = cpu_to_le32(priv->rx_skbuff_dma_addr[cur_rx]); + } + else{ + DBG_PRINT("%s: %s() cur_skb == NULL\n", dev->name, __FUNCTION__); + } - pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); - pci_read_config_word(pdev, PCI_STATUS, &pci_status); + }//------------------------------------------------------------ - printk(KERN_ERR PFX "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n", - dev->name, pci_cmd, pci_status); + }// end of if( priv->RxDescArray[cur_rx].status & RxRES ) - /* - * The recovery sequence below admits a very elaborated explanation: - * - it seems to work; - * - I did not see what else could be done. - * - * Feel free to adjust to your needs. - */ - pci_write_config_word(pdev, PCI_COMMAND, - pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY); + cur_rx = (cur_rx +1) % NUM_RX_DESC; + rxdesc = &priv->RxDescArray[cur_rx]; + pci_dma_sync_single_for_device(pdev, priv->rxdesc_array_dma_addr[cur_rx], sizeof(struct RxDesc), PCI_DMA_FROMDEVICE); - pci_write_config_word(pdev, PCI_STATUS, - pci_status & (PCI_STATUS_DETECTED_PARITY | - PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT | - PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_SIG_TARGET_ABORT)); + }// end of while ( (priv->RxDescArray[cur_rx].status & 0x80000000)== 0) - /* The infamous DAC f*ckup only happens at boot time */ - if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) { - printk(KERN_INFO PFX "%s: disabling PCI DAC.\n", dev->name); - tp->cp_cmd &= ~PCIDAC; - RTL_W16(CPlusCmd, tp->cp_cmd); - dev->features &= ~NETIF_F_HIGHDMA; - rtl8169_schedule_work(dev, rtl8169_reinit_task); + if( rxdesc_cnt >= max_interrupt_work ){ + DBG_PRINT("%s: Too much work at Rx interrupt.\n", dev->name); } - rtl8169_hw_reset(ioaddr); + priv->cur_rx = cur_rx; } -static void -rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) -{ - unsigned int dirty_tx, tx_left; - assert(dev != NULL); - assert(tp != NULL); - assert(ioaddr != NULL); - dirty_tx = tp->dirty_tx; - smp_rmb(); - tx_left = tp->cur_tx - dirty_tx; - while (tx_left > 0) { - unsigned int entry = dirty_tx % NUM_TX_DESC; - struct ring_info *tx_skb = tp->tx_skb + entry; - u32 len = tx_skb->len; - u32 status; - rmb(); - status = le32_to_cpu(tp->TxDescArray[entry].opts1); - if (status & DescOwn) - break; - tp->stats.tx_bytes += len; - tp->stats.tx_packets++; - rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); - if (status & LastFrag) { - dev_kfree_skb_irq(tx_skb->skb); - tx_skb->skb = NULL; - } - dirty_tx++; - tx_left--; - } +//====================================================================================================== +/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +static void rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +#else +static irqreturn_t rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +#endif +{ + struct net_device *dev = (struct net_device *) dev_instance; + struct rtl8169_private *priv = dev->priv; + int boguscnt = max_interrupt_work; + unsigned long ioaddr = priv->ioaddr; + int status = 0; + irqreturn_t interrupt_handled = IRQ_NONE; - if (tp->dirty_tx != dirty_tx) { - tp->dirty_tx = dirty_tx; - smp_wmb(); - if (netif_queue_stopped(dev) && - (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { - netif_wake_queue(dev); - } - } -} + RTL_W16 ( IntrMask, 0x0000); -static inline int rtl8169_fragmented_frame(u32 status) -{ - return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); -} + do { + status = RTL_R16(IntrStatus); -static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) -{ - u32 opts1 = le32_to_cpu(desc->opts1); - u32 status = opts1 & RxProtoMask; + if (status == 0xFFFF) + break; - if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || - ((status == RxProtoUDP) && !(opts1 & UDPFail)) || - ((status == RxProtoIP) && !(opts1 & IPFail))) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb->ip_summed = CHECKSUM_NONE; -} -static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, - struct RxDesc *desc, int rx_buf_sz) -{ - int ret = -1; + RTL_W16( IntrStatus, status ); - if (pkt_size < rx_copybreak) { - struct sk_buff *skb; - skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); - if (skb) { - skb_reserve(skb, NET_IP_ALIGN); - eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0); - *sk_buff = skb; - rtl8169_mark_to_asic(desc, rx_buf_sz); - ret = 0; - } - } - return ret; -} + if ( (status & rtl8169_intr_mask ) == 0 ) + break; + else + interrupt_handled = IRQ_HANDLED; -static int -rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) -{ - unsigned int cur_rx, rx_left; - unsigned int delta, count; - assert(dev != NULL); - assert(tp != NULL); - assert(ioaddr != NULL); + // Rx interrupt +// if (status & (RxOK | RxErr /* | LinkChg | RxOverflow | RxFIFOOver*/)){ + rtl8169_rx_interrupt (dev, priv, ioaddr); +// } + + // Tx interrupt +// if (status & (TxOK | TxErr)) { + spin_lock (&priv->lock); + rtl8169_tx_interrupt (dev, priv, ioaddr); + spin_unlock (&priv->lock); +// } - cur_rx = tp->cur_rx; - rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; - rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota); + boguscnt--; + } while (boguscnt > 0); - while (rx_left > 0) { - unsigned int entry = cur_rx % NUM_RX_DESC; - struct RxDesc *desc = tp->RxDescArray + entry; - u32 status; + if (boguscnt <= 0) { + DBG_PRINT("%s: Too much work at interrupt!\n", dev->name); + RTL_W16( IntrStatus, 0xffff); // Clear all interrupt sources + } - rmb(); - status = le32_to_cpu(desc->opts1); + RTL_W16 ( IntrMask, rtl8169_intr_mask); - if (status & DescOwn) - break; - if (status & RxRES) { - printk(KERN_INFO "%s: Rx ERROR. status = %08x\n", - dev->name, status); - tp->stats.rx_errors++; - if (status & (RxRWT | RxRUNT)) - tp->stats.rx_length_errors++; - if (status & RxCRC) - tp->stats.rx_crc_errors++; - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); - } else { - struct sk_buff *skb = tp->Rx_skbuff[entry]; - int pkt_size = (status & 0x00001FFF) - 4; - void (*pci_action)(struct pci_dev *, dma_addr_t, - size_t, int) = pci_dma_sync_single_for_device; - - /* - * The driver does not support incoming fragmented - * frames. They are seen as a symptom of over-mtu - * sized frames. - */ - if (unlikely(rtl8169_fragmented_frame(status))) { - tp->stats.rx_dropped++; - tp->stats.rx_length_errors++; - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); - goto move_on; - } +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + return interrupt_handled; +#endif +} - rtl8169_rx_csum(skb, desc); - - pci_dma_sync_single_for_cpu(tp->pci_dev, - le64_to_cpu(desc->addr), tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - - if (rtl8169_try_rx_copy(&skb, pkt_size, desc, - tp->rx_buf_sz)) { - pci_action = pci_unmap_single; - tp->Rx_skbuff[entry] = NULL; - } - pci_action(tp->pci_dev, le64_to_cpu(desc->addr), - tp->rx_buf_sz, PCI_DMA_FROMDEVICE); - skb->dev = dev; - skb_put(skb, pkt_size); - skb->protocol = eth_type_trans(skb, dev); - - if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0) - rtl8169_rx_skb(skb); - - dev->last_rx = jiffies; - tp->stats.rx_bytes += pkt_size; - tp->stats.rx_packets++; - } -move_on: - cur_rx++; - rx_left--; - } - - count = cur_rx - tp->cur_rx; - tp->cur_rx = cur_rx; - - delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); - if (!delta && count) - printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name); - tp->dirty_rx += delta; - - /* - * FIXME: until there is periodic timer to try and refill the ring, - * a temporary shortage may definitely kill the Rx process. - * - disable the asic to try and avoid an overflow and kick it again - * after refill ? - * - how do others driver handle this condition (Uh oh...). - */ - if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) - printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name); - return count; -} -/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static irqreturn_t -rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs) + + +//====================================================================================================== +static int rtl8169_close (struct net_device *dev) { - struct net_device *dev = (struct net_device *) dev_instance; - struct rtl8169_private *tp = netdev_priv(dev); - int boguscnt = max_interrupt_work; - void __iomem *ioaddr = tp->mmio_addr; - int status; - int handled = 0; + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + int i; - do { - status = RTL_R16(IntrStatus); + // ----------------------------------------- + rtl8169_delete_timer( &(priv->r8169_timer) ); - /* hotplug/major error/no more work/shared irq */ - if ((status == 0xFFFF) || !status) - break; - handled = 1; + netif_stop_queue (dev); - if (unlikely(!netif_running(dev))) { - rtl8169_asic_down(ioaddr); - goto out; - } + spin_lock_irq (&priv->lock); - status &= tp->intr_mask; - RTL_W16(IntrStatus, - (status & RxFIFOOver) ? (status | RxOverflow) : status); + /* Stop the chip's Tx and Rx processes. */ + RTL_W8 ( ChipCmd, 0x00); - if (!(status & rtl8169_intr_mask)) - break; + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 ( IntrMask, 0x0000); - if (unlikely(status & SYSErr)) { - rtl8169_pcierr_interrupt(dev); - break; - } + /* Update the error counts. */ + priv->stats.rx_missed_errors += RTL_R32(RxMissed); + RTL_W32( RxMissed, 0); - if (status & LinkChg) - rtl8169_check_link_status(dev, tp, ioaddr); + spin_unlock_irq (&priv->lock); -#ifdef CONFIG_R8169_NAPI - RTL_W16(IntrMask, rtl8169_intr_mask & ~rtl8169_napi_event); - tp->intr_mask = ~rtl8169_napi_event; - - if (likely(netif_rx_schedule_prep(dev))) - __netif_rx_schedule(dev); - else { - printk(KERN_INFO "%s: interrupt %04x taken in poll\n", - dev->name, status); - } - break; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + synchronize_irq (); #else - /* Rx interrupt */ - if (status & (RxOK | RxOverflow | RxFIFOOver)) { - rtl8169_rx_interrupt(dev, tp, ioaddr); - } - /* Tx interrupt */ - if (status & (TxOK | TxErr)) - rtl8169_tx_interrupt(dev, tp, ioaddr); + synchronize_irq (dev->irq); #endif + free_irq (dev->irq, dev); - boguscnt--; - } while (boguscnt > 0); + rtl8169_tx_clear (priv); + + //2004-05-11 + if(priv->txdesc_space != NULL){ + pci_free_consistent( + priv->pci_dev, + priv->sizeof_txdesc_space, + priv->txdesc_space, + priv->txdesc_phy_dma_addr + ); + priv->txdesc_space = NULL; + } + + if(priv->rxdesc_space != NULL){ + pci_free_consistent( + priv->pci_dev, + priv->sizeof_rxdesc_space, + priv->rxdesc_space, + priv->rxdesc_phy_dma_addr + ); + priv->rxdesc_space = NULL; + } + + priv->TxDescArray = NULL; + priv->RxDescArray = NULL; + + {//----------------------------------------------------------------------------- + for(i=0;iRx_skbuff[i] != NULL ) { + RTL8169_FREE_RXSKB ( priv->Rx_skbuff[i] ); + } + } + }//----------------------------------------------------------------------------- - if (boguscnt <= 0) { - printk(KERN_WARNING "%s: Too much work at interrupt!\n", - dev->name); - /* Clear all interrupt sources. */ - RTL_W16(IntrStatus, 0xffff); - } -out: - return IRQ_RETVAL(handled); -} - -#ifdef CONFIG_R8169_NAPI -static int rtl8169_poll(struct net_device *dev, int *budget) -{ - unsigned int work_done, work_to_do = min(*budget, dev->quota); - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - - work_done = rtl8169_rx_interrupt(dev, tp, ioaddr); - rtl8169_tx_interrupt(dev, tp, ioaddr); - - *budget -= work_done; - dev->quota -= work_done; - - if (work_done < work_to_do) { - netif_rx_complete(dev); - tp->intr_mask = 0xffff; - /* - * 20040426: the barrier is not strictly required but the - * behavior of the irq handler could be less predictable - * without it. Btw, the lack of flush for the posted pci - * write is safe - FR - */ - smp_wmb(); - RTL_W16(IntrMask, rtl8169_intr_mask); - } + DBG_PRINT("%s: %s() alloc_rxskb_cnt = %d\n", dev->name, __FUNCTION__, alloc_rxskb_cnt ); - return (work_done >= work_to_do); + return 0; } -#endif -static void rtl8169_down(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned int poll_locked = 0; - rtl8169_delete_timer(dev); - netif_stop_queue(dev); - flush_scheduled_work(); -core_down: - spin_lock_irq(&tp->lock); - rtl8169_asic_down(ioaddr); - /* Update the error counts. */ - tp->stats.rx_missed_errors += RTL_R32(RxMissed); - RTL_W32(RxMissed, 0); - - spin_unlock_irq(&tp->lock); - - synchronize_irq(dev->irq); +//====================================================================================================== +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc (int length, unsigned char *data) +{ + int crc = -1; - if (!poll_locked) { - netif_poll_disable(dev); - poll_locked++; + while (--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) + crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); } - /* Give a racing hard_start_xmit a few cycles to complete. */ - synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ - - /* - * And now for the 50k$ question: are IRQ disabled or not ? - * - * Two paths lead here: - * 1) dev->close - * -> netif_running() is available to sync the current code and the - * IRQ handler. See rtl8169_interrupt for details. - * 2) dev->change_mtu - * -> rtl8169_poll can not be issued again and re-enable the - * interruptions. Let's simply issue the IRQ down sequence again. - */ - if (RTL_R16(IntrMask)) - goto core_down; - - rtl8169_tx_clear(tp); - - rtl8169_rx_clear(tp); + return crc; } -static int rtl8169_close(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; - rtl8169_down(dev); - free_irq(dev->irq, dev); - netif_poll_enable(dev); - pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, - tp->RxPhyAddr); - pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, - tp->TxPhyAddr); - tp->TxDescArray = NULL; - tp->RxDescArray = NULL; - return 0; -} -static void -rtl8169_set_rx_mode(struct net_device *dev) + +//====================================================================================================== +static void rtl8169_set_rx_mode (struct net_device *dev) { - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; unsigned long flags; u32 mc_filter[2]; /* Multicast hash filter */ int i, rx_mode; - u32 tmp = 0; + u32 tmp=0; + if (dev->flags & IFF_PROMISC) { /* Unconditionally log net taps. */ - printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", - dev->name); - rx_mode = - AcceptBroadcast | AcceptMulticast | AcceptMyPhys | - AcceptAllPhys; + printk (KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys; mc_filter[1] = mc_filter[0] = 0xffffffff; - } else if ((dev->mc_count > multicast_filter_limit) - || (dev->flags & IFF_ALLMULTI)) { + } else if ((dev->mc_count > multicast_filter_limit) || (dev->flags & IFF_ALLMULTI)) { /* Too many to filter perfectly -- accept all multicasts. */ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; mc_filter[1] = mc_filter[0] = 0xffffffff; } else { struct dev_mc_list *mclist; - rx_mode = AcceptBroadcast | AcceptMyPhys; + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; mc_filter[1] = mc_filter[0] = 0; - for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist = mclist->next) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) + { + set_bit (ether_crc (ETH_ALEN, mclist->dmi_addr) >> 26, mc_filter); + } +#else + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) + { int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); rx_mode |= AcceptMulticast; } +#endif } - spin_lock_irqsave(&tp->lock, flags); + spin_lock_irqsave (&priv->lock, flags); - tmp = rtl8169_rx_config | rx_mode | - (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); + tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) & rtl_chip_info[priv->chipset].RxConfigMask); + + RTL_W32 ( RxConfig, tmp); + RTL_W32 ( MAR0 + 0, mc_filter[0]); + RTL_W32 ( MAR0 + 4, mc_filter[1]); + + spin_unlock_irqrestore (&priv->lock, flags); + +}//end of rtl8169_set_rx_mode (struct net_device *dev) - RTL_W32(RxConfig, tmp); - RTL_W32(MAR0 + 0, mc_filter[0]); - RTL_W32(MAR0 + 4, mc_filter[1]); - spin_unlock_irqrestore(&tp->lock, flags); -} -/** - * rtl8169_get_stats - Get rtl8169 read/write statistics - * @dev: The Ethernet Device to get statistics for - * - * Get TX/RX statistics for rtl8169 - */ -static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) + + + + +//================================================================================ +struct net_device_stats *rtl8169_get_stats(struct net_device *dev) + { - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; + struct rtl8169_private *priv = dev->priv; - if (netif_running(dev)) { - spin_lock_irqsave(&tp->lock, flags); - tp->stats.rx_missed_errors += RTL_R32(RxMissed); - RTL_W32(RxMissed, 0); - spin_unlock_irqrestore(&tp->lock, flags); - } - - return &tp->stats; + return &priv->stats; } + + + + + + + +//================================================================================ static struct pci_driver rtl8169_pci_driver = { - .name = MODULENAME, - .id_table = rtl8169_pci_tbl, - .probe = rtl8169_init_one, - .remove = __devexit_p(rtl8169_remove_one), -#ifdef CONFIG_PM - .suspend = rtl8169_suspend, - .resume = rtl8169_resume, -#endif + name: MODULENAME, + id_table: rtl8169_pci_tbl, + probe: rtl8169_init_one, + remove: rtl8169_remove_one, + suspend: NULL, + resume: NULL, }; -static int __init -rtl8169_init_module(void) + + + + +//====================================================================================================== +static int __init rtl8169_init_module (void) { - return pci_module_init(&rtl8169_pci_driver); + return pci_module_init (&rtl8169_pci_driver); // pci_register_driver (drv) } -static void __exit -rtl8169_cleanup_module(void) + + + +//====================================================================================================== +static void __exit rtl8169_cleanup_module (void) { - pci_unregister_driver(&rtl8169_pci_driver); + pci_unregister_driver (&rtl8169_pci_driver); } + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + + if( new_mtu > MAX_JUMBO_FRAME_MTU ){ + printk("%s: Error -- new_mtu(%d) > MAX_JUMBO_FRAME_MTU(%d).\n", dev->name, new_mtu, MAX_JUMBO_FRAME_MTU); + return -1; + } + + dev->mtu = new_mtu; + + priv->curr_mtu_size = new_mtu; + priv->tx_pkt_len = new_mtu + ETH_HDR_LEN; + priv->rx_pkt_len = new_mtu + ETH_HDR_LEN; + priv->hw_rx_pkt_len = priv->rx_pkt_len + 8; + + RTL_W8 ( Cfg9346, Cfg9346_Unlock); + RTL_W16 ( RxMaxSize, (unsigned short)priv->hw_rx_pkt_len ); + RTL_W8 ( Cfg9346, Cfg9346_Lock); + + DBG_PRINT("-------------------------- \n"); + DBG_PRINT("dev->mtu = %d \n", dev->mtu); + DBG_PRINT("priv->curr_mtu_size = %d \n", priv->curr_mtu_size); + DBG_PRINT("priv->rx_pkt_len = %d \n", priv->rx_pkt_len); + DBG_PRINT("priv->tx_pkt_len = %d \n", priv->tx_pkt_len); + DBG_PRINT("RTL_W16( RxMaxSize, %d )\n", priv->hw_rx_pkt_len); + DBG_PRINT("-------------------------- \n"); + + rtl8169_close (dev); + rtl8169_open (dev); + + return 0; +} +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + + + + + + + + + + + +//====================================================================================================== module_init(rtl8169_init_module); -module_exit(rtl8169_cleanup_module); + module_exit(rtl8169_cleanup_module); diff -urN linux-original/drivers/net/r8169.iomega.c linux/drivers/net/r8169.iomega.c --- linux-original/drivers/net/r8169.iomega.c 1969-12-31 19:00:00.000000000 -0500 +++ linux/drivers/net/r8169.iomega.c 2005-07-08 08:55:27.000000000 -0400 @@ -0,0 +1,1915 @@ +/* +========================================================================= + r8169.c: A RealTek RTL8169s/8110s Gigabit Ethernet driver for Linux kernel 2.4.x. + -------------------------------------------------------------------- + + History: + Feb 4 2002 - created initially by ShuChen . + May 20 2002 - Add link status force-mode and TBI mode support. +========================================================================= + +RTL8169_VERSION "1.1" <2002/10/4> + + The bit4:0 of MII register 4 is called "selector field", and have to be + 00001b to indicate support of IEEE std 802.3 during NWay process of + exchanging Link Code Word (FLP). + +RTL8169_VERSION "1.2" <2003/6/17> + Update driver module name. + Modify ISR. + Add chip mcfg. + +RTL8169_VERSION "1.3" <2003/6/20> + Add chip pcfg. + Add priv->phy_timer_t, rtl8169_phy_timer_t_handler() + Add rtl8169_hw_PHY_config() + Add rtl8169_hw_PHY_reset() + +RTL8169_VERSION "1.4" <2003/7/14> + Add tx_bytes, rx_bytes. + +RTL8169_VERSION "1.5" <2003/7/18> + Set 0x0000 to PHY at offset 0x0b. + Modify chip mcfg, pcfg + Force media for multiple card. +RTL8169_VERSION "1.6" <2003/8/25> + Modify receive data buffer. + +RTL8169_VERSION "1.7" <2003/9/18> + Add Jumbo Frame support. + +RTL8169_VERSION "1.8" <2003/10/21> + Performance and CPU Utilizaion Enhancement. + +RTL8169_VERSION "1.9" <2003/12/29> + Enable Tx/Rx flow control. + +RTL8169_VERSION "2.0" <2004/03/26> + Beta version. + Support for linux 2.6.x + +RTL8169_VERSION "2.1" <2004/07/05> + Modify parameters. + +RTL8169_VERSION "2.2" <2004/08/09> + Add.pci_dma_sync_single. + Add pci_alloc_consistent()/pci_free_consistent(). + Revise parameters. + Recognize our interrupt for linux 2.6.x. +*/ + + +#include +#include +#include +#include +#include +#include + +#include +#include + + +#define RTL8169_VERSION "2.2" +#define MODULENAME "RTL8169s/8110s" +#define RTL8169_DRIVER_NAME MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION +#define PFX MODULENAME ": " + + +#undef RTL8169_DEBUG +#undef RTL8169_JUMBO_FRAME_SUPPORT +#undef RTL8169_HW_FLOW_CONTROL_SUPPORT + + +#undef RTL8169_IOCTL_SUPPORT +#undef RTL8169_DYNAMIC_CONTROL +#define RTL8169_USE_IO + + +#ifdef RTL8169_DEBUG + #define assert(expr) \ + if(!(expr)) { printk( "Assertion failed! %s,%s,%s,line=%d\n", #expr,__FILE__,__FUNCTION__,__LINE__); } + #define DBG_PRINT( fmt, args...) printk("r8169: " fmt, ## args); +#else + #define assert(expr) do {} while (0) + #define DBG_PRINT( fmt, args...) ; +#endif // end of #ifdef RTL8169_DEBUG + + +/* media options */ +#define MAX_UNITS 8 +static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; + +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static int max_interrupt_work = 20; + +/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). + The RTL chips use a 64 element hash table based on the Ethernet CRC. */ +static int multicast_filter_limit = 32; + +/* MAC address length*/ +#define MAC_ADDR_LEN 6 + +#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ +#define RX_DMA_BURST 7 /* Maximum PCI burst, '6' is 1024 */ +#define TX_DMA_BURST 7 /* Maximum PCI burst, '6' is 1024 */ +#define ETTh 0x3F /* 0x3F means NO threshold */ + +#define ETH_HDR_LEN 14 +#define DEFAULT_MTU 1500 +#define DEFAULT_RX_BUF_LEN 1536 + + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT +#define MAX_JUMBO_FRAME_MTU ( 10000 ) +#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN ) +#else +#define MAX_RX_SKBDATA_SIZE 1600 +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + + +#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ + +#define NUM_TX_DESC 64 /* Number of Tx descriptor registers*/ +#define NUM_RX_DESC 64 /* Number of Rx descriptor registers*/ + + +#define RTL_MIN_IO_SIZE 0x80 +#define TX_TIMEOUT (6*HZ) +#define RTL8169_TIMER_EXPIRE_TIME 100 //100 + + +#ifdef RTL8169_USE_IO +#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg)) +#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg)) +#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg)) +#define RTL_R8(reg) inb (ioaddr + (reg)) +#define RTL_R16(reg) inw (ioaddr + (reg)) +#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg))) +#else +/* write/read MMIO register */ +#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) +#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) +#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) +#define RTL_R8(reg) readb (ioaddr + (reg)) +#define RTL_R16(reg) readw (ioaddr + (reg)) +#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) +#endif + +#define MCFG_METHOD_1 0x01 +#define MCFG_METHOD_2 0x02 +#define MCFG_METHOD_3 0x03 +#define MCFG_METHOD_4 0x04 + +#define PCFG_METHOD_1 0x01 //PHY Reg 0x03 bit0-3 == 0x0000 +#define PCFG_METHOD_2 0x02 //PHY Reg 0x03 bit0-3 == 0x0001 +#define PCFG_METHOD_3 0x03 //PHY Reg 0x03 bit0-3 == 0x0002 + + +#ifdef RTL8169_DYNAMIC_CONTROL +#include "r8169_callback.h" +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + +const static struct { + const char *name; + u8 mcfg; /* depend on RTL8169 docs */ + u32 RxConfigMask; /* should clear the bits supported by this chip */ +} rtl_chip_info[] = { + { "RTL8169", MCFG_METHOD_1, 0xff7e1880 }, + { "RTL8169s/8110s", MCFG_METHOD_2, 0xff7e1880 }, + { "RTL8169s/8110s", MCFG_METHOD_3, 0xff7e1880 }, +}; + + +static struct pci_device_id rtl8169_pci_tbl[] __devinitdata = { + { 0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +#ifdef CONFIG_IOMEGA8241 + /* The 8169 without an i2c defaults to reporting as an 8129 */ + { 0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +#endif /* CONFIG_IOMEGA8241 */ + {0,}, +}; + + +MODULE_DEVICE_TABLE (pci, rtl8169_pci_tbl); + + +enum RTL8169_registers { + MAC0 = 0x0, + MAR0 = 0x8, + TxDescStartAddr = 0x20, + TxHDescStartAddr= 0x28, + FLASH = 0x30, + ERSR = 0x36, + ChipCmd = 0x37, + TxPoll = 0x38, + IntrMask = 0x3C, + IntrStatus = 0x3E, + TxConfig = 0x40, + RxConfig = 0x44, + RxMissed = 0x4C, + Cfg9346 = 0x50, + Config0 = 0x51, + Config1 = 0x52, + Config2 = 0x53, + Config3 = 0x54, + Config4 = 0x55, + Config5 = 0x56, + MultiIntr = 0x5C, + PHYAR = 0x60, + TBICSR = 0x64, + TBI_ANAR = 0x68, + TBI_LPAR = 0x6A, + PHYstatus = 0x6C, + RxMaxSize = 0xDA, + CPlusCmd = 0xE0, + RxDescStartAddr = 0xE4, + ETThReg = 0xEC, + FuncEvent = 0xF0, + FuncEventMask = 0xF4, + FuncPresetState = 0xF8, + FuncForceEvent = 0xFC, +}; + +enum RTL8169_register_content { + /*InterruptStatusBits*/ + SYSErr = 0x8000, + PCSTimeout = 0x4000, + SWInt = 0x0100, + TxDescUnavail = 0x80, + RxFIFOOver = 0x40, + LinkChg = 0x20, + RxOverflow = 0x10, + TxErr = 0x08, + TxOK = 0x04, + RxErr = 0x02, + RxOK = 0x01, + + /*RxStatusDesc*/ + RxRES = 0x00200000, + RxCRC = 0x00080000, + RxRUNT= 0x00100000, + RxRWT = 0x00400000, + + /*ChipCmdBits*/ + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x04, + RxBufEmpty = 0x01, + + /*Cfg9346Bits*/ + Cfg9346_Lock = 0x00, + Cfg9346_Unlock = 0xC0, + + /*rx_mode_bits*/ + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x08, + AcceptMulticast = 0x04, + AcceptMyPhys = 0x02, + AcceptAllPhys = 0x01, + + /*RxConfigBits*/ + RxCfgFIFOShift = 13, + RxCfgDMAShift = 8, + + /*TxConfigBits*/ + TxInterFrameGapShift = 24, + TxDMAShift = 8, + + /*rtl8169_PHYstatus*/ + TBI_Enable = 0x80, + TxFlowCtrl = 0x40, + RxFlowCtrl = 0x20, + _1000bpsF = 0x10, + _100bps = 0x08, + _10bps = 0x04, + LinkStatus = 0x02, + FullDup = 0x01, + + /*GIGABIT_PHY_registers*/ + PHY_CTRL_REG = 0, + PHY_STAT_REG = 1, + PHY_AUTO_NEGO_REG = 4, + PHY_1000_CTRL_REG = 9, + + /*GIGABIT_PHY_REG_BIT*/ + PHY_Restart_Auto_Nego = 0x0200, + PHY_Enable_Auto_Nego = 0x1000, + + //PHY_STAT_REG = 1; + PHY_Auto_Neco_Comp = 0x0020, + + //PHY_AUTO_NEGO_REG = 4; + PHY_Cap_10_Half = 0x0020, + PHY_Cap_10_Full = 0x0040, + PHY_Cap_100_Half = 0x0080, + PHY_Cap_100_Full = 0x0100, + + //PHY_1000_CTRL_REG = 9; + PHY_Cap_1000_Full = 0x0200, + + PHY_Cap_PAUSE = 0x0400, + PHY_Cap_ASYM_PAUSE = 0x0800, + + PHY_Cap_Null = 0x0, + + /*_MediaType*/ + _10_Half = 0x01, + _10_Full = 0x02, + _100_Half = 0x04, + _100_Full = 0x08, + _1000_Full = 0x10, + + /*_TBICSRBit*/ + TBILinkOK = 0x02000000, +}; + + + +enum _DescStatusBit { + OWNbit = 0x80000000, + EORbit = 0x40000000, + FSbit = 0x20000000, + LSbit = 0x10000000, +}; + + +struct TxDesc { + u32 status; + u32 vlan_tag; + u32 buf_addr; + u32 buf_Haddr; +}; + +struct RxDesc { + u32 status; + u32 vlan_tag; + u32 buf_addr; + u32 buf_Haddr; +}; + + +typedef struct timer_list rt_timer_t; + + +struct rtl8169_private { + unsigned long ioaddr; /* memory map physical address*/ + struct pci_dev *pci_dev; /* Index of PCI device */ + struct net_device_stats stats; /* statistics of net device */ + spinlock_t lock; /* spin lock flag */ + int chipset; + int mcfg; + int pcfg; + rt_timer_t r8169_timer; + unsigned long expire_time; + + unsigned long phy_link_down_cnt; + unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ + unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ + unsigned long dirty_tx; + struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */ + struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */ + struct sk_buff *Tx_skbuff[NUM_TX_DESC];/* Index of Transmit data buffer */ + struct sk_buff *Rx_skbuff[NUM_RX_DESC];/* Receive data buffer */ + unsigned char drvinit_fail; + + dma_addr_t txdesc_array_dma_addr[NUM_TX_DESC]; + dma_addr_t rxdesc_array_dma_addr[NUM_RX_DESC]; + dma_addr_t rx_skbuff_dma_addr[NUM_RX_DESC]; + + void *txdesc_space; + dma_addr_t txdesc_phy_dma_addr; + int sizeof_txdesc_space; + + void *rxdesc_space; + dma_addr_t rxdesc_phy_dma_addr; + int sizeof_rxdesc_space; + + int curr_mtu_size; + int tx_pkt_len; + int rx_pkt_len; + + int hw_rx_pkt_len; + +#ifdef RTL8169_DYNAMIC_CONTROL + struct r8169_cb_t rt; +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + unsigned char linkstatus; +}; + + +MODULE_AUTHOR ("Realtek"); +MODULE_DESCRIPTION ("RealTek RTL-8169 Gigabit Ethernet driver"); +MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_LICENSE("GPL"); + + +static int rtl8169_open (struct net_device *dev); +static int rtl8169_start_xmit (struct sk_buff *skb, struct net_device *dev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +typedef int irqreturn_t; +#define IRQ_NONE 0 +#define IRQ_HANDLED 1 +static void rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +#else +static irqreturn_t rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +#endif + +static void rtl8169_init_ring (struct net_device *dev); +static void rtl8169_hw_start (struct net_device *dev); +static int rtl8169_close (struct net_device *dev); +static inline u32 ether_crc (int length, unsigned char *data); +static void rtl8169_set_rx_mode (struct net_device *dev); +static void rtl8169_tx_timeout (struct net_device *dev); +static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev); + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + +static void rtl8169_hw_PHY_config (struct net_device *dev); +static void rtl8169_hw_PHY_reset(struct net_device *dev); +static const u16 rtl8169_intr_mask = LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK ; +static const unsigned int rtl8169_rx_config = (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift) | 0x0000000E; + + +#define RTL8169_WRITE_GMII_REG_BIT( ioaddr, reg, bitnum, bitval )\ +{ \ + int val; \ + if( bitval == 1 ){ val = ( RTL8169_READ_GMII_REG( ioaddr, reg ) | (bitval< 0 ; i -- ){ + // Check if the RTL8169 has completed writing to the specified MII register + if( ! (RTL_R32(PHYAR)&0x80000000) ){ + break; + } + else{ + udelay(100); + }// end of if( ! (RTL_R32(PHYAR)&0x80000000) ) + }// end of for() loop +} +//================================================================= +int RTL8169_READ_GMII_REG( unsigned long ioaddr, int RegAddr ) +{ + int i, value = -1; + + RTL_W32 ( PHYAR, 0x0 | (RegAddr&0xFF)<<16 ); + udelay(1000); + + for( i = 2000; i > 0 ; i -- ){ + // Check if the RTL8169 has completed retrieving data from the specified MII register + if( RTL_R32(PHYAR) & 0x80000000 ){ + value = (int)( RTL_R32(PHYAR)&0xFFFF ); + break; + } + else{ + udelay(100); + }// end of if( RTL_R32(PHYAR) & 0x80000000 ) + }// end of for() loop + return value; +} + + +#ifdef RTL8169_IOCTL_SUPPORT +#include "r8169_ioctl.c" +#endif //end #ifdef RTL8169_IOCTL_SUPPORT + + +#ifdef RTL8169_DYNAMIC_CONTROL +#include "r8169_callback.c" +#endif + + + +#define rtl8169_request_timer( timer, timer_expires, timer_func, timer_data ) \ +{ \ + init_timer(timer); \ + timer->expires = (unsigned long)(jiffies + timer_expires); \ + timer->data = (unsigned long)(timer_data); \ + timer->function = (void *)(timer_func); \ + add_timer(timer); \ + DBG_PRINT("request_timer at 0x%08lx\n", (unsigned long)timer); \ +} + +#define rtl8169_delete_timer( del_timer_t ) \ +{ \ + del_timer(del_timer_t); \ + DBG_PRINT("delete_timer at 0x%08lx\n", (unsigned long)del_timer_t); \ +} + +#define rtl8169_mod_timer( timer, timer_expires ) \ +{ \ + mod_timer( timer, jiffies + timer_expires ); \ +} + + + + +//====================================================================================================== +//====================================================================================================== +void rtl8169_phy_timer_t_handler( void *timer_data ) +{ + struct net_device *dev = (struct net_device *)timer_data; + struct rtl8169_private *priv = (struct rtl8169_private *) (dev->priv); + unsigned long ioaddr = priv->ioaddr; + + assert( priv->mcfg > MCFG_METHOD_1 ); + assert( priv->pcfg < PCFG_METHOD_3 ); + + if( RTL_R8(PHYstatus) & LinkStatus ){ + priv->phy_link_down_cnt = 0 ; + } + else{ + priv->phy_link_down_cnt ++ ; + if( priv->phy_link_down_cnt >= 12 ){ + // If link on 1000, perform phy reset. + if( RTL8169_READ_GMII_REG( ioaddr, PHY_1000_CTRL_REG ) & PHY_Cap_1000_Full ) + { + DBG_PRINT("rtl8169_hw_PHY_reset\n"); + rtl8169_hw_PHY_reset( dev ); + } + + priv->phy_link_down_cnt = 0 ; + } + } + + //--------------------------------------------------------------------------- + //mod_timer is a more efficient way to update the expire field of an active timer. + //--------------------------------------------------------------------------- +// rtl8169_mod_timer( (&priv->phy_timer_t), 100 ); +} + + + +//====================================================================================================== +//====================================================================================================== +void rtl8169_timer_handler( void *timer_data ) +{ + struct net_device *dev = (struct net_device *)timer_data; + struct rtl8169_private *priv = (struct rtl8169_private *) (dev->priv); + + if( (priv->mcfg > MCFG_METHOD_1) && (priv->pcfg < PCFG_METHOD_3) ){ + DBG_PRINT("FIX PCS -> rtl8169_phy_timer_t_handler\n"); + priv->phy_link_down_cnt = 0; + rtl8169_phy_timer_t_handler( timer_data ); + } + + +#ifdef RTL8169_DYNAMIC_CONTROL + { + struct r8169_cb_t *rt = &(priv->rt); + if( priv->linkstatus == _1000_Full ){ + r8169_callback(rt); + } + } +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + + rtl8169_mod_timer( (&priv->r8169_timer), priv->expire_time ); +} + + + +//====================================================================================================== +//====================================================================================================== +static int __devinit rtl8169_init_board ( struct pci_dev *pdev, struct net_device **dev_out, unsigned long *ioaddr_out) +{ + unsigned long ioaddr = 0; + struct net_device *dev; + struct rtl8169_private *priv; + int rc, i; + unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; + + + assert (pdev != NULL); + assert (ioaddr_out != NULL); + + *ioaddr_out = 0; + *dev_out = NULL; + + // dev zeroed in init_etherdev +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + dev = init_etherdev (NULL, sizeof (*priv)); +#else + dev = alloc_etherdev (sizeof (*priv)); +#endif + + if (dev == NULL) { + printk (KERN_ERR PFX "unable to alloc new ethernet\n"); + return -ENOMEM; + } + + SET_MODULE_OWNER(dev); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + SET_NETDEV_DEV(dev, &pdev->dev); +#endif + + priv = dev->priv; + + // enable device (incl. PCI PM wakeup and hotplug setup) + rc = pci_enable_device (pdev); + if (rc) + goto err_out; + + mmio_start = pci_resource_start (pdev, 1); + mmio_end = pci_resource_end (pdev, 1); + mmio_flags = pci_resource_flags (pdev, 1); + mmio_len = pci_resource_len (pdev, 1); + + // make sure PCI base addr 1 is MMIO + if (!(mmio_flags & IORESOURCE_MEM)) { + printk (KERN_ERR PFX "region #1 not an MMIO resource, aborting\n"); + rc = -ENODEV; + goto err_out; + } + + // check for weird/broken PCI region reporting + if ( mmio_len < RTL_MIN_IO_SIZE ) { + printk (KERN_ERR PFX "Invalid PCI region size(s), aborting\n"); + rc = -ENODEV; + goto err_out; + } + + + rc = pci_request_regions (pdev, dev->name); + if (rc) + goto err_out; + + // enable PCI bus-mastering + pci_set_master (pdev); + +#ifdef RTL8169_USE_IO + ioaddr = pci_resource_start(pdev, 0); +#else + // ioremap MMIO region + ioaddr = (unsigned long)ioremap (mmio_start, mmio_len); + if (ioaddr == 0) { + printk (KERN_ERR PFX "cannot remap MMIO, aborting\n"); + rc = -EIO; + goto err_out_free_res; + } +#endif + + // Soft reset the chip. + RTL_W8 ( ChipCmd, CmdReset); + + // Check that the chip has finished the reset. + for (i = 1000; i > 0; i--){ + if ( (RTL_R8(ChipCmd) & CmdReset) == 0){ + break; + } + else{ + udelay (10); + } + } + + // identify config method + { + unsigned long val32 = (RTL_R32(TxConfig)&0x7c800000); + + if( val32 == (0x1<<28) ){ + priv->mcfg = MCFG_METHOD_4; + } + else if( val32 == (0x1<<26) ){ + priv->mcfg = MCFG_METHOD_3; + } + else if( val32 == (0x1<<23) ){ + priv->mcfg = MCFG_METHOD_2; + } + else if( val32 == 0x00000000 ){ + priv->mcfg = MCFG_METHOD_1; + } + else{ + priv->mcfg = MCFG_METHOD_1; + } + } + { + unsigned char val8 = (unsigned char)(RTL8169_READ_GMII_REG(ioaddr,3)&0x000f); + if( val8 == 0x00 ){ + priv->pcfg = PCFG_METHOD_1; + } + else if( val8 == 0x01 ){ + priv->pcfg = PCFG_METHOD_2; + } + else if( val8 == 0x02 ){ + priv->pcfg = PCFG_METHOD_3; + } + else{ + priv->pcfg = PCFG_METHOD_3; + } + } + + + for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--){ + if (priv->mcfg == rtl_chip_info[i].mcfg) { + priv->chipset = i; + goto match; + } + } + + //if unknown chip, assume array element #0, original RTL-8169 in this case + //printk (KERN_DEBUG PFX "PCI device %s: unknown chip version, assuming RTL-8169\n", pdev->slot_name); + priv->chipset = 0; + +match: + *ioaddr_out = ioaddr; + *dev_out = dev; + return 0; + +#ifndef RTL8169_USE_IO +err_out_free_res: + pci_release_regions (pdev); +#endif + +err_out: + unregister_netdev (dev); + kfree (dev); + return rc; +} + + + + + + + +//====================================================================================================== +static int __devinit rtl8169_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct net_device *dev = NULL; + struct rtl8169_private *priv = NULL; + unsigned long ioaddr = 0; + static int board_idx = -1; + int i; + int option = -1, Cap10_100 = 0, Cap1000 = 0; + + + assert (pdev != NULL); + assert (ent != NULL); + + board_idx++; + + + i = rtl8169_init_board (pdev, &dev, &ioaddr); + if (i < 0) { + return i; + } + + priv = dev->priv; + + assert (ioaddr != NULL); + assert (dev != NULL); + assert (priv != NULL); + + // Get MAC address // + for (i = 0; i < MAC_ADDR_LEN ; i++){ + dev->dev_addr[i] = RTL_R8( MAC0 + i ); + } + + dev->open = rtl8169_open; + dev->hard_start_xmit = rtl8169_start_xmit; + dev->get_stats = rtl8169_get_stats; + dev->stop = rtl8169_close; + dev->tx_timeout = rtl8169_tx_timeout; + dev->set_multicast_list = rtl8169_set_rx_mode; + dev->watchdog_timeo = TX_TIMEOUT; + dev->irq = pdev->irq; + dev->base_addr = (unsigned long) ioaddr; + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT + dev->change_mtu = rtl8169_change_mtu; +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + +#ifdef RTL8169_IOCTL_SUPPORT + dev->do_ioctl = rtl8169_ioctl; +#endif //end #ifdef RTL8169_IOCTL_SUPPORT + +#ifdef RTL8169_DYNAMIC_CONTROL + priv->rt.dev = dev; +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + priv = dev->priv; // private data // + priv->pci_dev = pdev; + priv->ioaddr = ioaddr; + +//#ifdef RTL8169_JUMBO_FRAME_SUPPORT + priv->curr_mtu_size = dev->mtu; + priv->tx_pkt_len = dev->mtu + ETH_HDR_LEN; + priv->rx_pkt_len = dev->mtu + ETH_HDR_LEN; + priv->hw_rx_pkt_len = priv->rx_pkt_len + 8; +//#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + + DBG_PRINT("-------------------------- \n"); + DBG_PRINT("dev->mtu = %d \n", dev->mtu); + DBG_PRINT("priv->curr_mtu_size = %d \n", priv->curr_mtu_size); + DBG_PRINT("priv->tx_pkt_len = %d \n", priv->tx_pkt_len); + DBG_PRINT("priv->rx_pkt_len = %d \n", priv->rx_pkt_len); + DBG_PRINT("priv->hw_rx_pkt_len = %d \n", priv->hw_rx_pkt_len); + DBG_PRINT("-------------------------- \n"); + + spin_lock_init (&priv->lock); + + register_netdev (dev); + + pci_set_drvdata(pdev, dev); // pdev->driver_data = data; + + + printk (KERN_DEBUG "%s: Identified chip type is '%s'.\n",dev->name,rtl_chip_info[priv->chipset].name); + printk (KERN_INFO "%s: %s at 0x%lx, " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " + "IRQ %d\n", + dev->name, + RTL8169_DRIVER_NAME, + dev->base_addr, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5], + dev->irq); + + + // Config PHY + rtl8169_hw_PHY_config(dev); + + DBG_PRINT("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); + RTL_W8( 0x82, 0x01 ); + + if( priv->mcfg < MCFG_METHOD_3 ){ + DBG_PRINT("Set PCI Latency=0x40\n"); + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); + } + + if( priv->mcfg == MCFG_METHOD_2 ){ + DBG_PRINT("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); + RTL_W8( 0x82, 0x01 ); + DBG_PRINT("Set PHY Reg 0x0bh = 0x00h\n"); + RTL8169_WRITE_GMII_REG( ioaddr, 0x0b, 0x0000 ); //w 0x0b 15 0 0 + } + + // if TBI is not endbled + if( !(RTL_R8(PHYstatus) & TBI_Enable) ){ + int val = RTL8169_READ_GMII_REG( ioaddr, PHY_AUTO_NEGO_REG ); + +#ifdef RTL8169_HW_FLOW_CONTROL_SUPPORT + val |= PHY_Cap_PAUSE | PHY_Cap_ASYM_PAUSE ; +#endif //end #define RTL8169_HW_FLOW_CONTROL_SUPPORT + + option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx]; + // Force RTL8169 in 10/100/1000 Full/Half mode. + if( option > 0 ){ + printk(KERN_INFO "%s: Force-mode Enabled. \n", dev->name); + Cap10_100 = 0; + Cap1000 = 0; + switch( option ){ + case _10_Half: + Cap10_100 = PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _10_Full: + Cap10_100 = PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _100_Half: + Cap10_100 = PHY_Cap_100_Half | PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _100_Full: + Cap10_100 = PHY_Cap_100_Full | PHY_Cap_100_Half | PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_Null; + break; + case _1000_Full: + Cap10_100 = PHY_Cap_100_Full | PHY_Cap_100_Half | PHY_Cap_10_Full | PHY_Cap_10_Half; + Cap1000 = PHY_Cap_1000_Full; + break; + default: + break; + } + RTL8169_WRITE_GMII_REG( ioaddr, PHY_AUTO_NEGO_REG, Cap10_100 | ( val&0xC1F ) ); //leave PHY_AUTO_NEGO_REG bit4:0 unchanged + RTL8169_WRITE_GMII_REG( ioaddr, PHY_1000_CTRL_REG, Cap1000 ); + } + else{ + printk(KERN_INFO "%s: Auto-negotiation Enabled.\n", dev->name); + + // enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged + RTL8169_WRITE_GMII_REG( ioaddr, PHY_AUTO_NEGO_REG, + PHY_Cap_10_Half | PHY_Cap_10_Full | PHY_Cap_100_Half | PHY_Cap_100_Full | ( val&0xC1F ) ); + + // enable 1000 Full Mode + RTL8169_WRITE_GMII_REG( ioaddr, PHY_1000_CTRL_REG, PHY_Cap_1000_Full ); + + }// end of if( option > 0 ) + + + // Enable auto-negotiation and restart auto-nigotiation + RTL8169_WRITE_GMII_REG( ioaddr, PHY_CTRL_REG, PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego ); + udelay(100); + + // wait for auto-negotiation process + for( i = 10000; i > 0; i-- ){ + //check if auto-negotiation complete + if( RTL8169_READ_GMII_REG(ioaddr, PHY_STAT_REG) & PHY_Auto_Neco_Comp ){ + udelay(100); + option = RTL_R8(PHYstatus); + if( option & _1000bpsF ){ + printk(KERN_INFO "%s: 1000Mbps Full-duplex operation.\n", dev->name); + } + else{ + printk(KERN_INFO "%s: %sMbps %s-duplex operation.\n", dev->name, + (option & _100bps) ? "100" : "10", (option & FullDup) ? "Full" : "Half" ); + } + break; + } + else{ + udelay(100); + }// end of if( RTL8169_READ_GMII_REG(ioaddr, 1) & 0x20 ) + }// end for-loop to wait for auto-negotiation process + + option = RTL_R8(PHYstatus); + if( option & _1000bpsF ){ + priv->linkstatus = _1000_Full; + } + else{ + if(option & _100bps){ + priv->linkstatus = (option & FullDup) ? _100_Full : _100_Half; + } + else{ + priv->linkstatus = (option & FullDup) ? _10_Full : _10_Half; + } + } + DBG_PRINT("priv->linkstatus = 0x%02x\n", priv->linkstatus); + + }// end of TBI is not enabled + else{ + udelay(100); + DBG_PRINT("1000Mbps Full-duplex operation, TBI Link %s!\n",(RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed" ); + + }// end of TBI is not enabled + + return 0; +} + + + + + + + +//====================================================================================================== +static void __devexit rtl8169_remove_one (struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + assert (dev != NULL); + assert (priv != NULL); + + unregister_netdev (dev); + +#ifdef RTL8169_USE_IO +#else + iounmap ((void *)(dev->base_addr)); +#endif + pci_release_regions (pdev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + kfree (dev); +#else + free_netdev(dev); +#endif + + pci_set_drvdata (pdev, NULL); +} + + + + + + + +//====================================================================================================== +static int rtl8169_open (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + struct pci_dev *pdev = priv->pci_dev; + int retval; +// u8 diff; +// u32 TxPhyAddr, RxPhyAddr; + + + if( priv->drvinit_fail == 1 ){ + printk("%s: Gigabit driver open failed.\n", dev->name ); + return -ENOMEM; + } + + retval = request_irq (dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev); + if (retval) { + return retval; + } + + //2004-05-11 + // Allocate tx/rx descriptor space + priv->sizeof_txdesc_space = NUM_TX_DESC * sizeof(struct TxDesc)+256; + priv->txdesc_space = pci_alloc_consistent( pdev, priv->sizeof_txdesc_space, &priv->txdesc_phy_dma_addr ); + if( priv->txdesc_space == NULL ){ + printk("%s: Gigabit driver alloc txdesc_space failed.\n", dev->name ); + return -ENOMEM; + } + priv->sizeof_rxdesc_space = NUM_RX_DESC * sizeof(struct RxDesc)+256; + priv->rxdesc_space = pci_alloc_consistent( pdev, priv->sizeof_rxdesc_space, &priv->rxdesc_phy_dma_addr ); + if( priv->rxdesc_space == NULL ){ + printk("%s: Gigabit driver alloc rxdesc_space failed.\n", dev->name ); + return -ENOMEM; + } + + if(priv->txdesc_phy_dma_addr & 0xff){ + printk("%s: Gigabit driver txdesc_phy_dma_addr is not 256-bytes-aligned.\n", dev->name ); + } + if(priv->rxdesc_phy_dma_addr & 0xff){ + printk("%s: Gigabit driver rxdesc_phy_dma_addr is not 256-bytes-aligned.\n", dev->name ); + } + // Set tx/rx descriptor space + priv->TxDescArray = (struct TxDesc *)priv->txdesc_space; + priv->RxDescArray = (struct RxDesc *)priv->rxdesc_space; + + { + int i; + struct sk_buff *skb = NULL; + + for(i=0;iRx_skbuff[i] = skb; + } + else{ + printk("%s: Gigabit driver failed to allocate skbuff.\n", dev->name); + priv->drvinit_fail = 1; + } + } + } + + + ////////////////////////////////////////////////////////////////////////////// + rtl8169_init_ring (dev); + rtl8169_hw_start (dev); + + + // ------------------------------------------------------ + DBG_PRINT("FIX PCS -> rtl8169_request_timer\n"); + priv->expire_time = RTL8169_TIMER_EXPIRE_TIME; + rtl8169_request_timer( (&priv->r8169_timer), priv->expire_time, rtl8169_timer_handler, ((void *)dev) ); //in open() + + + DBG_PRINT("%s: %s() alloc_rxskb_cnt = %d\n", dev->name, __FUNCTION__, alloc_rxskb_cnt ); + + return 0; + +}//end of rtl8169_open (struct net_device *dev) + + + + + + + + +//====================================================================================================== +static void rtl8169_hw_PHY_reset(struct net_device *dev) +{ + int val, phy_reset_expiretime = 50; + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + + DBG_PRINT("%s: Reset RTL8169s PHY\n", dev->name); + + val = ( RTL8169_READ_GMII_REG( ioaddr, 0 ) | 0x8000 ) & 0xffff; + RTL8169_WRITE_GMII_REG( ioaddr, 0, val ); + + do //waiting for phy reset + { + if( RTL8169_READ_GMII_REG( ioaddr, 0 ) & 0x8000 ){ + phy_reset_expiretime --; + udelay(100); + } + else{ + break; + } + }while( phy_reset_expiretime >= 0 ); + + assert( phy_reset_expiretime > 0 ); +} + + + + +//====================================================================================================== +static void rtl8169_hw_PHY_config (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + void *ioaddr = (void*)priv->ioaddr; + + DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n",priv->mcfg,priv->pcfg); + + if( priv->mcfg == MCFG_METHOD_4 ){ + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1F, 0x0001 ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x09, 0x273a ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x0e, 0x7bfb ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1b, 0x841e ); + + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1F, 0x0002 ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x01, 0x90D0 ); + RTL8169_WRITE_GMII_REG( (unsigned long)ioaddr, 0x1F, 0x0000 ); + } + else{ + DBG_PRINT("priv->mcfg=%d. Discard hw PHY config.\n",priv->mcfg); + } +} + + + + + + + + + + +//====================================================================================================== +static void rtl8169_hw_start (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + u32 i; + + + /* Soft reset the chip. */ + RTL_W8 ( ChipCmd, CmdReset); + + /* Check that the chip has finished the reset. */ + for (i = 1000; i > 0; i--){ + if ((RTL_R8( ChipCmd ) & CmdReset) == 0) break; + else udelay (10); + } + + RTL_W8 ( Cfg9346, Cfg9346_Unlock); + RTL_W8 ( ChipCmd, CmdTxEnb | CmdRxEnb); + RTL_W8 ( ETThReg, ETTh); + + // For gigabit rtl8169 + RTL_W16 ( RxMaxSize, (unsigned short)priv->hw_rx_pkt_len ); + + // Set Rx Config register + i = rtl8169_rx_config | ( RTL_R32( RxConfig ) & rtl_chip_info[priv->chipset].RxConfigMask); + RTL_W32 ( RxConfig, i); + + + /* Set DMA burst size and Interframe Gap Time */ + RTL_W32 ( TxConfig, (TX_DMA_BURST << TxDMAShift) | (InterFrameGap << TxInterFrameGapShift) ); + + + + RTL_W16( CPlusCmd, RTL_R16(CPlusCmd) ); + + if( priv->mcfg == MCFG_METHOD_2 || + priv->mcfg == MCFG_METHOD_3) + { + RTL_W16( CPlusCmd, (RTL_R16(CPlusCmd)|(1<<14)|(1<<3)) ); + DBG_PRINT("Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"); + } + else + { + RTL_W16( CPlusCmd, (RTL_R16(CPlusCmd)|(1<<3)) ); + DBG_PRINT("Set MAC Reg C+CR Offset 0xE0: bit-3.\n"); + } + + { + //RTL_W16(0xE2, 0x1517); + //RTL_W16(0xE2, 0x152a); + //RTL_W16(0xE2, 0x282a); + RTL_W16(0xE2, 0x0000); + } + + priv->cur_rx = 0; + + RTL_W32 ( TxDescStartAddr, priv->txdesc_phy_dma_addr); + RTL_W32 ( TxDescStartAddr + 4, 0x00); + RTL_W32 ( RxDescStartAddr, priv->rxdesc_phy_dma_addr); + RTL_W32 ( RxDescStartAddr + 4, 0x00); + + RTL_W8 ( Cfg9346, Cfg9346_Lock ); + udelay (10); + + RTL_W32 ( RxMissed, 0 ); + + rtl8169_set_rx_mode (dev); + + RTL_W16 ( MultiIntr, RTL_R16(MultiIntr) & 0xF000); + + RTL_W16 ( IntrMask, rtl8169_intr_mask); + + netif_start_queue (dev); + +}//end of rtl8169_hw_start (struct net_device *dev) + + + + + + + +//====================================================================================================== +static void rtl8169_init_ring (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + struct pci_dev *pdev = priv->pci_dev; + int i; + struct sk_buff *skb; + + + priv->cur_rx = 0; + priv->cur_tx = 0; + priv->dirty_tx = 0; + memset(priv->TxDescArray, 0x0, NUM_TX_DESC*sizeof(struct TxDesc)); + memset(priv->RxDescArray, 0x0, NUM_RX_DESC*sizeof(struct RxDesc)); + + + for (i=0 ; iTx_skbuff[i]=NULL; + priv->txdesc_array_dma_addr[i] = pci_map_single(pdev, &priv->TxDescArray[i], sizeof(struct TxDesc), PCI_DMA_TODEVICE); + } + + for (i=0; i RxDescArray[i].status = cpu_to_le32((OWNbit | EORbit) | (unsigned long)priv->hw_rx_pkt_len); + } + else{ + priv->RxDescArray[i].status = cpu_to_le32(OWNbit | (unsigned long)priv->hw_rx_pkt_len); + } + + {//----------------------------------------------------------------------- + skb = priv->Rx_skbuff[i]; + priv->rx_skbuff_dma_addr[i] = pci_map_single(pdev, skb->data, MAX_RX_SKBDATA_SIZE, PCI_DMA_FROMDEVICE); + + if( skb != NULL ){ + priv->RxDescArray[i].buf_addr = cpu_to_le32(priv->rx_skbuff_dma_addr[i]); + priv->RxDescArray[i].buf_Haddr = 0; + } + else{ + DBG_PRINT("%s: %s() Rx_skbuff == NULL\n", dev->name, __FUNCTION__); + priv->drvinit_fail = 1; + } + }//----------------------------------------------------------------------- + priv->rxdesc_array_dma_addr[i] = pci_map_single(pdev, &priv->RxDescArray[i], sizeof(struct RxDesc), PCI_DMA_TODEVICE); + pci_dma_sync_single_for_device(pdev, priv->rxdesc_array_dma_addr[i], sizeof(struct RxDesc), PCI_DMA_TODEVICE); + } +} + + + + + + + +//====================================================================================================== +static void rtl8169_tx_clear (struct rtl8169_private *priv) +{ + int i; + + priv->cur_tx = 0; + for ( i = 0 ; i < NUM_TX_DESC ; i++ ){ + if ( priv->Tx_skbuff[i] != NULL ) { + dev_kfree_skb ( priv->Tx_skbuff[i] ); + priv->Tx_skbuff[i] = NULL; + priv->stats.tx_dropped++; + } + } +} + + + + + + + +//====================================================================================================== +static void rtl8169_tx_timeout (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + u8 tmp8; + + /* disable Tx, if not already */ + tmp8 = RTL_R8( ChipCmd ); + if (tmp8 & CmdTxEnb){ + RTL_W8 ( ChipCmd, tmp8 & ~CmdTxEnb); + } + + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 ( IntrMask, 0x0000); + + /* Stop a shared interrupt from scavenging while we are. */ + spin_lock_irq (&priv->lock); + rtl8169_tx_clear (priv); + spin_unlock_irq (&priv->lock); + + + rtl8169_hw_start (dev); + + netif_wake_queue (dev); +} + + + + + + + +//====================================================================================================== +static int rtl8169_start_xmit (struct sk_buff *skb, struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + struct pci_dev *pdev = priv->pci_dev; + int entry = priv->cur_tx % NUM_TX_DESC; + int buf_len = 60; + dma_addr_t txbuf_dma_addr; + + spin_lock_irq (&priv->lock); + + if( (le32_to_cpu(priv->TxDescArray[entry].status) & OWNbit)==0 ){ + + priv->Tx_skbuff[entry] = skb; + txbuf_dma_addr = pci_map_single(pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + + priv->TxDescArray[entry].buf_addr = cpu_to_le32(txbuf_dma_addr); + DBG_PRINT("%s: TX pkt_size = %d\n", __FUNCTION__, skb->len); + if( skb->len <= priv->tx_pkt_len ){ + buf_len = skb->len; + } + else{ + printk("%s: Error -- Tx packet size(%d) > mtu(%d)+14\n", dev->name, skb->len, dev->mtu); + buf_len = priv->tx_pkt_len; + } + + if( entry != (NUM_TX_DESC-1) ){ + priv->TxDescArray[entry].status = cpu_to_le32((OWNbit | FSbit | LSbit) | buf_len); + } + else{ + priv->TxDescArray[entry].status = cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | buf_len); + } + + pci_dma_sync_single_for_device(pdev, priv->txdesc_array_dma_addr[entry], sizeof(struct TxDesc), PCI_DMA_TODEVICE); + + RTL_W8 ( TxPoll, 0x40); //set polling bit + + dev->trans_start = jiffies; + + priv->stats.tx_bytes += ( (skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN); + priv->cur_tx++; + }//end of if( (priv->TxDescArray[entry].status & 0x80000000)==0 ) + + spin_unlock_irq (&priv->lock); + + if ( (priv->cur_tx - NUM_TX_DESC) == priv->dirty_tx ){ + netif_stop_queue (dev); + } + else{ + if (netif_queue_stopped (dev)){ + netif_wake_queue (dev); + } + } + + return 0; +} + + + + + + + +//====================================================================================================== +static void rtl8169_tx_interrupt (struct net_device *dev, struct rtl8169_private *priv, unsigned long ioaddr) +{ + unsigned long dirty_tx, tx_left=0; + int entry = priv->cur_tx % NUM_TX_DESC; + int txloop_cnt = 0; + + assert (dev != NULL); + assert (priv != NULL); + assert (ioaddr != NULL); + + + dirty_tx = priv->dirty_tx; + tx_left = priv->cur_tx - dirty_tx; + + while( (tx_left > 0) && (txloop_cnt < max_interrupt_work) ){ + if( (le32_to_cpu(priv->TxDescArray[entry].status) & OWNbit) == 0 ){ + +#ifdef RTL8169_DYNAMIC_CONTROL + r8169_callback_tx(&(priv->rt), 1, priv->Tx_skbuff[dirty_tx % NUM_TX_DESC]->len); +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + dev_kfree_skb_irq( priv->Tx_skbuff[dirty_tx % NUM_TX_DESC] ); + priv->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL; + priv->stats.tx_packets++; + dirty_tx++; + tx_left--; + entry++; + } + txloop_cnt ++; + } + + if (priv->dirty_tx != dirty_tx) { + priv->dirty_tx = dirty_tx; + if (netif_queue_stopped (dev)) + netif_wake_queue (dev); + } +} + + + + + + +//====================================================================================================== +static void rtl8169_rx_interrupt (struct net_device *dev, struct rtl8169_private *priv, unsigned long ioaddr) +{ + struct pci_dev *pdev = priv->pci_dev; + int cur_rx; + int pkt_size = 0 ; + int rxdesc_cnt = 0; + int ret; + struct sk_buff *n_skb = NULL; + struct sk_buff *cur_skb; + struct sk_buff *rx_skb; + struct RxDesc *rxdesc; + + assert (dev != NULL); + assert (priv != NULL); + assert (ioaddr != NULL); + + + cur_rx = priv->cur_rx; + + rxdesc = &priv->RxDescArray[cur_rx]; + pci_dma_sync_single_for_device(pdev, priv->rxdesc_array_dma_addr[cur_rx], sizeof(struct RxDesc), PCI_DMA_FROMDEVICE); + + while ( ((le32_to_cpu(rxdesc->status) & OWNbit)== 0) && (rxdesc_cnt < max_interrupt_work) ){ + + rxdesc_cnt++; + + if( le32_to_cpu(rxdesc->status) & RxRES ){ + printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); + priv->stats.rx_errors++; + if ( le32_to_cpu(rxdesc->status) & (RxRWT|RxRUNT) ) + priv->stats.rx_length_errors++; + if ( le32_to_cpu(rxdesc->status) & RxCRC) + priv->stats.rx_crc_errors++; + } + else{ + pkt_size=(int)(le32_to_cpu(rxdesc->status) & 0x00001FFF)-4; + + if( pkt_size > priv->rx_pkt_len ){ + printk("%s: Error -- Rx packet size(%d) > mtu(%d)+14\n", dev->name, pkt_size, dev->mtu); + pkt_size = priv->rx_pkt_len; + } + + DBG_PRINT("%s: RX pkt_size = %d\n", __FUNCTION__, pkt_size); + + {// ----------------------------------------------------- + rx_skb = priv->Rx_skbuff[cur_rx]; + n_skb = RTL8169_ALLOC_RXSKB(MAX_RX_SKBDATA_SIZE); + if( n_skb != NULL ) { + skb_reserve (n_skb, 2); // 16 byte align the IP fields. // + + // Indicate rx_skb + if( rx_skb != NULL ){ + rx_skb->dev = dev; + pci_dma_sync_single_for_device(pdev, priv->rx_skbuff_dma_addr[cur_rx], sizeof(struct RxDesc), PCI_DMA_FROMDEVICE); + + skb_put ( rx_skb, pkt_size ); + rx_skb->protocol = eth_type_trans ( rx_skb, dev ); + ret = RTL8169_NETIF_RX (rx_skb); + +// dev->last_rx = jiffies; + priv->stats.rx_bytes += pkt_size; + priv->stats.rx_packets++; + +#ifdef RTL8169_DYNAMIC_CONTROL + r8169_callback_rx( &(priv->rt), 1, pkt_size); +#endif //end #ifdef RTL8169_DYNAMIC_CONTROL + + }//end if( rx_skb != NULL ) + + priv->Rx_skbuff[cur_rx] = n_skb; + } + else{ + DBG_PRINT("%s: Allocate n_skb failed!\n",__FUNCTION__ ); + priv->Rx_skbuff[cur_rx] = rx_skb; + } + + + // Update rx descriptor + if( cur_rx == (NUM_RX_DESC-1) ){ + priv->RxDescArray[cur_rx].status = cpu_to_le32((OWNbit | EORbit) | (unsigned long)priv->hw_rx_pkt_len); + } + else{ + priv->RxDescArray[cur_rx].status = cpu_to_le32(OWNbit | (unsigned long)priv->hw_rx_pkt_len); + } + + cur_skb = priv->Rx_skbuff[cur_rx]; + + if( cur_skb != NULL ){ + priv->rx_skbuff_dma_addr[cur_rx] = pci_map_single(pdev, cur_skb->data, MAX_RX_SKBDATA_SIZE, PCI_DMA_FROMDEVICE); + rxdesc->buf_addr = cpu_to_le32(priv->rx_skbuff_dma_addr[cur_rx]); + } + else{ + DBG_PRINT("%s: %s() cur_skb == NULL\n", dev->name, __FUNCTION__); + } + + }//------------------------------------------------------------ + + }// end of if( priv->RxDescArray[cur_rx].status & RxRES ) + + cur_rx = (cur_rx +1) % NUM_RX_DESC; + rxdesc = &priv->RxDescArray[cur_rx]; + pci_dma_sync_single_for_device(pdev, priv->rxdesc_array_dma_addr[cur_rx], sizeof(struct RxDesc), PCI_DMA_FROMDEVICE); + + }// end of while ( (priv->RxDescArray[cur_rx].status & 0x80000000)== 0) + + if( rxdesc_cnt >= max_interrupt_work ){ + DBG_PRINT("%s: Too much work at Rx interrupt.\n", dev->name); + } + + priv->cur_rx = cur_rx; +} + + + + + + + + +//====================================================================================================== +/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +static void rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +#else +static irqreturn_t rtl8169_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +#endif +{ + struct net_device *dev = (struct net_device *) dev_instance; + struct rtl8169_private *priv = dev->priv; + int boguscnt = max_interrupt_work; + unsigned long ioaddr = priv->ioaddr; + int status = 0; + irqreturn_t interrupt_handled = IRQ_NONE; + + RTL_W16 ( IntrMask, 0x0000); + + do { + status = RTL_R16(IntrStatus); + + if (status == 0xFFFF) + break; + + + RTL_W16( IntrStatus, status ); + + + if ( (status & rtl8169_intr_mask ) == 0 ) + break; + else + interrupt_handled = IRQ_HANDLED; + + + // Rx interrupt +// if (status & (RxOK | RxErr /* | LinkChg | RxOverflow | RxFIFOOver*/)){ + rtl8169_rx_interrupt (dev, priv, ioaddr); +// } + + // Tx interrupt +// if (status & (TxOK | TxErr)) { + spin_lock (&priv->lock); + rtl8169_tx_interrupt (dev, priv, ioaddr); + spin_unlock (&priv->lock); +// } + + boguscnt--; + } while (boguscnt > 0); + + if (boguscnt <= 0) { + DBG_PRINT("%s: Too much work at interrupt!\n", dev->name); + RTL_W16( IntrStatus, 0xffff); // Clear all interrupt sources + } + + RTL_W16 ( IntrMask, rtl8169_intr_mask); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + return interrupt_handled; +#endif +} + + + + + + + +//====================================================================================================== +static int rtl8169_close (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + int i; + + // ----------------------------------------- + rtl8169_delete_timer( &(priv->r8169_timer) ); + + + netif_stop_queue (dev); + + spin_lock_irq (&priv->lock); + + /* Stop the chip's Tx and Rx processes. */ + RTL_W8 ( ChipCmd, 0x00); + + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16 ( IntrMask, 0x0000); + + /* Update the error counts. */ + priv->stats.rx_missed_errors += RTL_R32(RxMissed); + RTL_W32( RxMissed, 0); + + spin_unlock_irq (&priv->lock); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + synchronize_irq (); +#else + synchronize_irq (dev->irq); +#endif + free_irq (dev->irq, dev); + + rtl8169_tx_clear (priv); + + //2004-05-11 + if(priv->txdesc_space != NULL){ + pci_free_consistent( + priv->pci_dev, + priv->sizeof_txdesc_space, + priv->txdesc_space, + priv->txdesc_phy_dma_addr + ); + priv->txdesc_space = NULL; + } + + if(priv->rxdesc_space != NULL){ + pci_free_consistent( + priv->pci_dev, + priv->sizeof_rxdesc_space, + priv->rxdesc_space, + priv->rxdesc_phy_dma_addr + ); + priv->rxdesc_space = NULL; + } + + priv->TxDescArray = NULL; + priv->RxDescArray = NULL; + + {//----------------------------------------------------------------------------- + for(i=0;iRx_skbuff[i] != NULL ) { + RTL8169_FREE_RXSKB ( priv->Rx_skbuff[i] ); + } + } + }//----------------------------------------------------------------------------- + + DBG_PRINT("%s: %s() alloc_rxskb_cnt = %d\n", dev->name, __FUNCTION__, alloc_rxskb_cnt ); + + return 0; +} + + + + + + + +//====================================================================================================== +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc (int length, unsigned char *data) +{ + int crc = -1; + + while (--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) + crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); + } + + return crc; +} + + + + + + + + +//====================================================================================================== +static void rtl8169_set_rx_mode (struct net_device *dev) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + unsigned long flags; + u32 mc_filter[2]; /* Multicast hash filter */ + int i, rx_mode; + u32 tmp=0; + + + if (dev->flags & IFF_PROMISC) { + /* Unconditionally log net taps. */ + printk (KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else if ((dev->mc_count > multicast_filter_limit) || (dev->flags & IFF_ALLMULTI)) { + /* Too many to filter perfectly -- accept all multicasts. */ + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else { + struct dev_mc_list *mclist; + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) + { + set_bit (ether_crc (ETH_ALEN, mclist->dmi_addr) >> 26, mc_filter); + } +#else + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) + { + int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; + + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + rx_mode |= AcceptMulticast; + } +#endif + } + + spin_lock_irqsave (&priv->lock, flags); + + tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) & rtl_chip_info[priv->chipset].RxConfigMask); + + RTL_W32 ( RxConfig, tmp); + RTL_W32 ( MAR0 + 0, mc_filter[0]); + RTL_W32 ( MAR0 + 4, mc_filter[1]); + + spin_unlock_irqrestore (&priv->lock, flags); + +}//end of rtl8169_set_rx_mode (struct net_device *dev) + + + + + + + +//================================================================================ +struct net_device_stats *rtl8169_get_stats(struct net_device *dev) + +{ + struct rtl8169_private *priv = dev->priv; + + return &priv->stats; +} + + + + + + + + +//================================================================================ +static struct pci_driver rtl8169_pci_driver = { + name: MODULENAME, + id_table: rtl8169_pci_tbl, + probe: rtl8169_init_one, + remove: rtl8169_remove_one, + suspend: NULL, + resume: NULL, +}; + + + + + +//====================================================================================================== +static int __init rtl8169_init_module (void) +{ + return pci_module_init (&rtl8169_pci_driver); // pci_register_driver (drv) +} + + + + +//====================================================================================================== +static void __exit rtl8169_cleanup_module (void) +{ + pci_unregister_driver (&rtl8169_pci_driver); +} + + +#ifdef RTL8169_JUMBO_FRAME_SUPPORT +static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) +{ + struct rtl8169_private *priv = dev->priv; + unsigned long ioaddr = priv->ioaddr; + + if( new_mtu > MAX_JUMBO_FRAME_MTU ){ + printk("%s: Error -- new_mtu(%d) > MAX_JUMBO_FRAME_MTU(%d).\n", dev->name, new_mtu, MAX_JUMBO_FRAME_MTU); + return -1; + } + + dev->mtu = new_mtu; + + priv->curr_mtu_size = new_mtu; + priv->tx_pkt_len = new_mtu + ETH_HDR_LEN; + priv->rx_pkt_len = new_mtu + ETH_HDR_LEN; + priv->hw_rx_pkt_len = priv->rx_pkt_len + 8; + + RTL_W8 ( Cfg9346, Cfg9346_Unlock); + RTL_W16 ( RxMaxSize, (unsigned short)priv->hw_rx_pkt_len ); + RTL_W8 ( Cfg9346, Cfg9346_Lock); + + DBG_PRINT("-------------------------- \n"); + DBG_PRINT("dev->mtu = %d \n", dev->mtu); + DBG_PRINT("priv->curr_mtu_size = %d \n", priv->curr_mtu_size); + DBG_PRINT("priv->rx_pkt_len = %d \n", priv->rx_pkt_len); + DBG_PRINT("priv->tx_pkt_len = %d \n", priv->tx_pkt_len); + DBG_PRINT("RTL_W16( RxMaxSize, %d )\n", priv->hw_rx_pkt_len); + DBG_PRINT("-------------------------- \n"); + + rtl8169_close (dev); + rtl8169_open (dev); + + return 0; +} +#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + + + + + + + + + + + +//====================================================================================================== +module_init(rtl8169_init_module); + module_exit(rtl8169_cleanup_module); diff -urN linux-original/drivers/pci/probe.c linux/drivers/pci/probe.c --- linux-original/drivers/pci/probe.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/pci/probe.c 2005-07-08 08:55:27.000000000 -0400 @@ -551,6 +551,20 @@ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); class >>= 8; /* upper 3 bytes */ dev->class = class; +#ifdef CONFIG_IOMEGA8241 + /* + * The VIA VT6410 used on the Iomega StorCenter Network Hard Drive reports + * with a class of 0x01040 (PCI_CLASS_STORAGE_RAID). + * + * The following correction allows it to be used as a standard PCI IDE + * controller (0x0101) + */ + if((dev->vendor==PCI_VENDOR_ID_VIA)&&(dev->device==PCI_DEVICE_ID_VIA_6410)) { + dev->class=0x01018f; + printk("PCI: Adjustments for the VIA VT6410 controller have been made\n"); + } +#endif /* CONFIG_IOMEGA8241 */ + class >>= 8; pr_debug("PCI: Found %s [%04x/%04x] %06x %02x\n", pci_name(dev), diff -urN linux-original/drivers/serial/8250.c linux/drivers/serial/8250.c --- linux-original/drivers/serial/8250.c 2005-06-17 15:48:29.000000000 -0400 +++ linux/drivers/serial/8250.c 2005-07-08 09:02:11.000000000 -0400 @@ -46,6 +46,10 @@ #include "8250.h" +#ifdef CONFIG_IOMEGA8241 +#include +#endif /* CONFIG_IOMEGA8241 */ + /* * Configuration: * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option @@ -68,7 +72,8 @@ #define DEBUG_INTR(fmt...) do { } while (0) #endif -#define PASS_LIMIT 256 +//#define PASS_LIMIT 256 +#define PASS_LIMIT 32 /* * We default to IRQ0 for the "no irq" hack. Some @@ -1543,7 +1548,15 @@ * are set via set_termios(), which will be occurring imminently * anyway, so we don't enable them here. */ +#ifdef CONFIG_IOMEGA8241 + /* We do not enable UART_IER_RLSI because it causes problem + * when you send data to the port before you open it. + * -xianghua xiao 2005.7.7 + */ + up->ier = UART_IER_RDI; +#else up->ier = UART_IER_RLSI | UART_IER_RDI; +#endif /* CONFIG_IOMEGA8241 */ serial_outp(up, UART_IER, up->ier); if (up->port.flags & UPF_FOURPORT) { diff -urN linux-original/include/asm-ppc/mpc10x.h linux/include/asm-ppc/mpc10x.h --- linux-original/include/asm-ppc/mpc10x.h 2005-06-17 15:48:29.000000000 -0400 +++ linux/include/asm-ppc/mpc10x.h 2005-07-08 08:55:27.000000000 -0400 @@ -76,7 +76,11 @@ #define MPC10X_MAPB_PCI_INTACK_ADDR 0xfef00000 #define MPC10X_MAPB_PCI_IO_START 0x00000000 +#ifdef CONFIG_IOMEGA8241 +#define MPC10X_MAPB_PCI_IO_END 0xFFFF +#else #define MPC10X_MAPB_PCI_IO_END (0x00c00000 - 1) +#endif /* CONFIG_IOMEGA8241 */ #define MPC10X_MAPB_PCI_MEM_START 0x80000000 #define MPC10X_MAPB_PCI_MEM_END (0xc0000000 - 1) @@ -157,8 +161,11 @@ */ extern unsigned long ioremap_base; #define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE) +#ifdef CONFIG_IOMEGA8241 +#define MPC10X_MAPB_EUMB_BASE 0xFDF00000 +#else #define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE - +#endif /* CONFIG_IOMEGA8241 */ int mpc10x_bridge_init(struct pci_controller *hose, uint current_map, diff -urN linux-original/include/asm-ppc/serial.h linux/include/asm-ppc/serial.h --- linux-original/include/asm-ppc/serial.h 2005-06-17 15:48:29.000000000 -0400 +++ linux/include/asm-ppc/serial.h 2005-07-08 08:55:27.000000000 -0400 @@ -40,6 +40,8 @@ #include #elif defined(CONFIG_RADSTONE_PPC7D) #include +#elif defined(CONFIG_IOMEGA8241) +#include #else /* diff -urN linux-original/include/linux/ds1337.h linux/include/linux/ds1337.h --- linux-original/include/linux/ds1337.h 1969-12-31 19:00:00.000000000 -0500 +++ linux/include/linux/ds1337.h 2005-07-08 08:55:27.000000000 -0400 @@ -0,0 +1,103 @@ +/* + * include/linux/ds1337.h + * + * Copyright (C) 2005 USI(Shanghai) Co., Ltd. + * + * Original Ported by Martin. Check and clean up by Sam Song. + * + * 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. + */ + +#include +#include "i2c_export.h" + +typedef struct _rtc_second +{ + unsigned char resv:1; + unsigned char ten:3; + unsigned char one:4; +}RTC_SECOND; + +typedef struct _rtc_minute +{ + unsigned char resv:1; + unsigned char ten:3; + unsigned char one:4; +}RTC_MINUTE; + +typedef struct _rtc_hour +{ + unsigned char resv:1; + unsigned char ampm:1; + unsigned char ten1:1; + unsigned char ten2:1; + unsigned char one:4; +}RTC_HOUR; + +typedef struct _rtc_day +{ + unsigned char resv:5; + unsigned char one:3; +}RTC_DAY; + +typedef struct _rtc_date +{ + unsigned char resv:2; + unsigned char ten:2; + unsigned char one:4; +}RTC_DATE; + +struct _rtc_month +{ + unsigned char century:1; + unsigned char resv:2; + unsigned char ten:1; + unsigned char one:4; +}; + +struct _rtc_year +{ + unsigned char ten:4; + unsigned char one:4; +}; + +/* we should pay attention to the structure when it is in memory */ +typedef struct _rtc_time +{ + RTC_SECOND second; + RTC_MINUTE minute; + RTC_HOUR hour; + RTC_DAY day; + RTC_DATE date; + struct _rtc_month month; + struct _rtc_year year; +}RTC_TIME; + +/* next should be some struct for the Alarm register */ +/* but now we don't need to implement it */ +typedef struct _rtc_ctrl +{ + unsigned char eosc:1; + unsigned char resv:2; + unsigned char rs2:1; + unsigned char rs1:1; + unsigned char intcn:1; + unsigned char a2ie:1; + unsigned char a1ie:1; +}RTC_CTRL; + +typedef struct _rtc_sts +{ + unsigned char osf:1; + unsigned char resv:5; + unsigned char a2f:1; + unsigned char a1f:1; +}RTC_STS; + +extern long ds1337_init(void); +extern int ds1337_set_time(unsigned long settime); +extern unsigned long ds1337_get_time(void); +void ds1337_usi_set_time(unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec); diff -urN linux-original/include/linux/i2c_export.h linux/include/linux/i2c_export.h --- linux-original/include/linux/i2c_export.h 1969-12-31 19:00:00.000000000 -0500 +++ linux/include/linux/i2c_export.h 2005-07-08 08:55:27.000000000 -0400 @@ -0,0 +1,179 @@ +/* + * include/linux/i2c_export.h + * + * Copyright (C) 2005 USI(Shanghai) Co., Ltd. + * + * Original Ported by Martin. Check and clean up by Sam Song. + * + * 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 I2CADR 0x00003000 +#define I2CFDR 0x00003004 +#define I2CCR 0x00003008 +#define I2CSR 0x0000300C +#define I2CDR 0x00003010 + +typedef enum _i2cstatus +{ + I2CSUCCESS = 0x3000, + I2CADDRESS, + I2CERROR, + I2CBUFFFULL, + I2CBUFFEMPTY, + I2CXMITERROR, + I2CRCVERROR, + I2CBUSBUSY, + I2CALOSS, + I2CNOEVENT, +} I2CStatus; + +/* These are the defined return values for the I2C_do_transaction function. + * Any non-zero value indicates failure. Failure modes can be added for + * more detailed error reporting. + */ +typedef enum _i2c_status +{ + I2C_SUCCESS = 0, + I2C_ERROR, + }I2C_Status; + +typedef enum i2c_control +{ + MEN = 0x00000080, + MIEN = 0x00000040, + MSTA = 0x00000020, + MTX = 0x00000010, + TXAK = 0x00000008, + RSTA = 0x00000004, +} I2C_CONTROL; + +typedef enum i2c_status +{ + MCF = 0x00000080, + MAAS = 0x00000040, + MBB = 0x00000020, + MAL = 0x00000010, + SRW = 0x00000004, + MIF = 0x00000002, + RXAK = 0x00000001, +} I2C_STATUS; + +typedef struct _i2c_ctrl +{ + unsigned int reserved0 : 24; + unsigned int men : 1; + unsigned int mien : 1; + unsigned int msta : 1; + unsigned int mtx : 1; + unsigned int txak : 1; + unsigned int rsta : 1; + unsigned int reserved1 : 2; +} I2C_CTRL; + +typedef struct _i2c_stat +{ + unsigned int rsrv0 : 24; + unsigned int mcf : 1; + unsigned int maas : 1; + unsigned int mbb : 1; + unsigned int mal : 1; + unsigned int rsrv1 : 1; + unsigned int srw : 1; + unsigned int mif : 1; + unsigned int rxak : 1; +} I2C_STAT; + +typedef enum _i2c_mode +{ + RCV = 0, + XMIT = 1, +} I2C_MODE; + + +/* These are the defined tasks for I2C_do_transaction. + * Modes for SLAVE_RCV and SLAVE_XMIT will be added. + */ +typedef enum _i2c_transaction_mode +{ + I2C_MASTER_RCV = 0, + I2C_MASTER_XMIT = 1, +} I2C_TRANSACTION_MODE; + +typedef enum _i2c_interrupt_mode +{ + I2C_INT_DISABLE = 0, + I2C_INT_ENABLE = 1, +} I2C_INTERRUPT_MODE; + +typedef enum _i2c_stop +{ + I2C_NO_STOP = 0, + I2C_STOP = 1, +} I2C_STOP_MODE; + +typedef enum _i2c_restart +{ + I2C_NO_RESTART = 0, + I2C_RESTART = 1, +} I2C_RESTART_MODE; + +/******************** App. API ******************** + * The application API is for user level application + * to use the functionality provided by I2C driver. + * This is a "generic" I2C interface, it should contain + * nothing specific to the Kahlua implementation. + * Only the generic functions are exported by the library. + * + * Note: Its App.s responsibility to swap the data + * byte. In our API, we just transfer whatever + * we are given + **************************************************/ + +/* Initialize I2C unit with the following: + * driver's slave address + * interrupt enabled + * optional pointer to application layer print function + * + * These parameters may be added: + * desired clock rate + * digital filter frequency sampling rate + * + * This function must be called before I2C unit can be used. + */ +extern I2C_Status I2C_Initialize( + unsigned char addr, /* driver's I2C slave address */ + I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt + * 0 - disable I2C interrupt + */ + int (*app_print_function)(char *,...)); + /* pointer to optional "printf" + * provided by application + */ + +/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV + * are implemented. Both are only in polling mode. + * + * en_int controls interrupt/polling mode + * act is the type of transaction + * addr is the I2C address of the slave device + * len is the length of data to send or receive + * buffer is the address of the data buffer + * stop = I2C_NO_STOP, don't signal STOP at end of transaction + * I2C_STOP, signal STOP at end of transaction + * retry is the timeout retry value, currently ignored + * rsta = I2C_NO_RESTART, this is not continuation of existing transaction + * I2C_RESTART, this is a continuation of existing transaction + */ +extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int, + I2C_TRANSACTION_MODE act, + unsigned char i2c_addr, + unsigned char data_addr, + int len, + char *buffer, + I2C_STOP_MODE stop, + int retry, + I2C_RESTART_MODE rsta); diff -urN linux-original/include/linux/pci_ids.h linux/include/linux/pci_ids.h --- linux-original/include/linux/pci_ids.h 2005-06-17 15:48:29.000000000 -0400 +++ linux/include/linux/pci_ids.h 2005-07-08 08:55:27.000000000 -0400 @@ -1396,6 +1396,7 @@ #define PCI_DEVICE_ID_VIA_8703_51_0 0x3148 #define PCI_DEVICE_ID_VIA_8237_SATA 0x3149 #define PCI_DEVICE_ID_VIA_XN266 0x3156 +#define PCI_DEVICE_ID_VIA_6410 0x3164 #define PCI_DEVICE_ID_VIA_8754C_0 0x3168 #define PCI_DEVICE_ID_VIA_8235 0x3177 #define PCI_DEVICE_ID_VIA_P4N333 0x3178