diff options
author | Andrew Wilcox <andy@protium.com> | 2006-12-07 19:10:02 +0000 |
---|---|---|
committer | Andrew Wilcox <andy@protium.com> | 2006-12-07 19:10:02 +0000 |
commit | 1d5f50bce888b5b4f20ff3bd14f6685f2c0355e7 (patch) | |
tree | e049136cac188f128c93055b1c0f065be32331a7 /packages/linux/linux-storcenter/kernel.patch-2.6.12.6 | |
parent | 6363b1e9e61b4b4d8cc6541ae1a75de3e5e09870 (diff) |
linux-storcenter: kernel patch, default config, and bitbake file for storcenter kernel.
Diffstat (limited to 'packages/linux/linux-storcenter/kernel.patch-2.6.12.6')
-rw-r--r-- | packages/linux/linux-storcenter/kernel.patch-2.6.12.6 | 9895 |
1 files changed, 9895 insertions, 0 deletions
diff --git a/packages/linux/linux-storcenter/kernel.patch-2.6.12.6 b/packages/linux/linux-storcenter/kernel.patch-2.6.12.6 new file mode 100644 index 0000000000..094b7e14e9 --- /dev/null +++ b/packages/linux/linux-storcenter/kernel.patch-2.6.12.6 @@ -0,0 +1,9895 @@ +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: <http://www.windriver.com/> + ++config IOMEGA8241 ++ bool "IOMEGA8241" ++ ---help--- ++ Iomega StorCenter Network Hard Drive ++ Manufacturer: Iomega Corporation ++ Date of Release: May 2005 ++ End of Life: - ++ URL: <http://www.iomega.com/> ++ + 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 <linux/config.h> ++#include <linux/stddef.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/errno.h> ++#include <linux/reboot.h> ++#include <linux/pci.h> ++#include <linux/kdev_t.h> ++#include <linux/major.h> ++#include <linux/initrd.h> ++#include <linux/console.h> ++#include <linux/delay.h> ++#include <linux/irq.h> ++#include <linux/ide.h> ++#include <linux/seq_file.h> ++#include <linux/root_dev.h> ++#include <linux/serial.h> ++#include <linux/tty.h> /* for linux/serial_core.h */ ++#include <linux/serial_core.h> ++#include <linux/serialP.h> ++#include <linux/serial_reg.h> ++ ++#include <asm/system.h> ++#include <asm/pgtable.h> ++#include <asm/page.h> ++#include <asm/time.h> ++#include <asm/dma.h> ++#include <asm/io.h> ++#include <asm/machdep.h> ++#include <asm/prom.h> ++#include <asm/smp.h> ++#include <asm/vga.h> ++#include <asm/open_pic.h> ++#include <asm/i8259.h> ++#include <asm/todc.h> ++#include <asm/bootinfo.h> ++#include <asm/mpc10x.h> ++#include <asm/pci-bridge.h> ++#include <asm/kgdb.h> ++ ++#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 <asm/ppcboot.h> ++#include <linux/config.h> ++ ++/* ++ * 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 <linux/i2c.h> + #include <linux/i2c-sensor.h> + #include <linux/string.h> +-#include <linux/rtc.h> /* get the user-level API */ ++#include <linux/rtc.h> + #include <linux/bcd.h> + #include <linux/list.h> + ++ + /* 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 <ksaito@interface.co.jp> ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/types.h> ++#include <linux/kernel.h> ++#include <asm/io.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/map.h> ++#include <linux/config.h> ++#include <linux/mtd/partitions.h> ++ ++#include <asm/immap_cpm2.h> ++ ++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 <russello@iomega.com>"); ++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 <shuchen@realtek.com.tw>. + 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 <linux/module.h> +-#include <linux/moduleparam.h> + #include <linux/pci.h> + #include <linux/netdevice.h> + #include <linux/etherdevice.h> + #include <linux/delay.h> +-#include <linux/ethtool.h> +-#include <linux/mii.h> +-#include <linux/if_vlan.h> +-#include <linux/crc32.h> +-#include <linux/in.h> +-#include <linux/ip.h> +-#include <linux/tcp.h> ++#include <linux/version.h> ++ ++#include <linux/timer.h> + #include <linux/init.h> +-#include <linux/dma-mapping.h> + +-#include <asm/io.h> +-#include <asm/irq.h> + +-#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 <netdev@vger.kernel.org>"); +-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<<bitnum) ) & 0xffff ; } \ ++ else{ val = ( RTL8169_READ_GMII_REG( ioaddr, reg ) & (~(0x0001<<bitnum)) ) & 0xffff ; } \ ++ RTL8169_WRITE_GMII_REG( ioaddr, reg, val ); \ ++} ++ ++ ++ ++#ifdef RTL8169_DEBUG ++unsigned alloc_rxskb_cnt = 0; ++#define RTL8169_ALLOC_RXSKB(bufsize) dev_alloc_skb(bufsize); alloc_rxskb_cnt ++ ; ++#define RTL8169_FREE_RXSKB(skb) kfree_skb(skb); alloc_rxskb_cnt -- ; ++#define RTL8169_NETIF_RX(skb) netif_rx(skb); alloc_rxskb_cnt -- ; ++#else ++#define RTL8169_ALLOC_RXSKB(bufsize) dev_alloc_skb(bufsize); ++#define RTL8169_FREE_RXSKB(skb) kfree_skb(skb); ++#define RTL8169_NETIF_RX(skb) netif_rx(skb); ++#endif //end #ifdef RTL8169_DEBUG ++ ++ ++ + +-static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) ++ ++ ++//================================================================= ++// PHYAR ++// bit Symbol ++// 31 Flag ++// 30-21 reserved ++// 20-16 5-bit GMII/MII register address ++// 15-0 16-bit GMII/MII register data ++//================================================================= ++void RTL8169_WRITE_GMII_REG( unsigned long ioaddr, int RegAddr, int value ) + { +- int i; ++ int i; + +- RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); ++ RTL_W32 ( PHYAR, 0x80000000 | (RegAddr&0xFF)<<16 | value); + udelay(1000); + +- for (i = 2000; i > 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;i<NUM_RX_DESC;i++){ ++ skb = RTL8169_ALLOC_RXSKB(MAX_RX_SKBDATA_SIZE); ++ if( skb != NULL ) { ++ skb_reserve (skb, 2); // 16 byte align the IP fields. // ++ priv->Rx_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 ; i<NUM_TX_DESC ; i++){ ++ priv->Tx_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 <NUM_RX_DESC; i++) { ++ if(i==(NUM_RX_DESC-1)){ ++ priv->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;i<NUM_RX_DESC;i++){ ++ if( priv->Rx_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 <shuchen@realtek.com.tw>. ++ 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 <linux/module.h> ++#include <linux/pci.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/delay.h> ++#include <linux/version.h> ++ ++#include <linux/timer.h> ++#include <linux/init.h> ++ ++ ++#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<<bitnum) ) & 0xffff ; } \ ++ else{ val = ( RTL8169_READ_GMII_REG( ioaddr, reg ) & (~(0x0001<<bitnum)) ) & 0xffff ; } \ ++ RTL8169_WRITE_GMII_REG( ioaddr, reg, val ); \ ++} ++ ++ ++ ++#ifdef RTL8169_DEBUG ++unsigned alloc_rxskb_cnt = 0; ++#define RTL8169_ALLOC_RXSKB(bufsize) dev_alloc_skb(bufsize); alloc_rxskb_cnt ++ ; ++#define RTL8169_FREE_RXSKB(skb) kfree_skb(skb); alloc_rxskb_cnt -- ; ++#define RTL8169_NETIF_RX(skb) netif_rx(skb); alloc_rxskb_cnt -- ; ++#else ++#define RTL8169_ALLOC_RXSKB(bufsize) dev_alloc_skb(bufsize); ++#define RTL8169_FREE_RXSKB(skb) kfree_skb(skb); ++#define RTL8169_NETIF_RX(skb) netif_rx(skb); ++#endif //end #ifdef RTL8169_DEBUG ++ ++ ++ ++ ++ ++ ++//================================================================= ++// PHYAR ++// bit Symbol ++// 31 Flag ++// 30-21 reserved ++// 20-16 5-bit GMII/MII register address ++// 15-0 16-bit GMII/MII register data ++//================================================================= ++void RTL8169_WRITE_GMII_REG( unsigned long ioaddr, int RegAddr, int value ) ++{ ++ int i; ++ ++ RTL_W32 ( PHYAR, 0x80000000 | (RegAddr&0xFF)<<16 | value); ++ udelay(1000); ++ ++ for( i = 2000; i > 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;i<NUM_RX_DESC;i++){ ++ skb = RTL8169_ALLOC_RXSKB(MAX_RX_SKBDATA_SIZE); ++ if( skb != NULL ) { ++ skb_reserve (skb, 2); // 16 byte align the IP fields. // ++ priv->Rx_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 ; i<NUM_TX_DESC ; i++){ ++ priv->Tx_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 <NUM_RX_DESC; i++) { ++ if(i==(NUM_RX_DESC-1)){ ++ priv->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;i<NUM_RX_DESC;i++){ ++ if( priv->Rx_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 <platforms/iomega8241.h> ++#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 <asm/mpc85xx.h> + #elif defined(CONFIG_RADSTONE_PPC7D) + #include <platforms/radstone_ppc7d.h> ++#elif defined(CONFIG_IOMEGA8241) ++#include <platforms/iomega8241.h> + #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 <asm/time.h> ++#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 |