include upstream ip1000a driver version 2.09f
authorDobrica Pavlinusic <dpavlin@brr.lan>
Mon, 14 May 2007 05:51:43 +0000 (00:51 -0500)
committerDobrica Pavlinusic <dpavlin@brr.lan>
Mon, 14 May 2007 05:51:43 +0000 (00:51 -0500)
18 files changed:
drivers/net/Config.in
drivers/net/Makefile
drivers/net/ip1000a/.ipg.o.flags [new file with mode: 0644]
drivers/net/ip1000a/.ipg_main.o.flags [new file with mode: 0644]
drivers/net/ip1000a/Makefile [new file with mode: 0644]
drivers/net/ip1000a/Makefile.orig [new file with mode: 0644]
drivers/net/ip1000a/PhyParam.h [new file with mode: 0644]
drivers/net/ip1000a/ipg.h [new file with mode: 0644]
drivers/net/ip1000a/ipg.o [new file with mode: 0644]
drivers/net/ip1000a/ipg_constants.h [new file with mode: 0644]
drivers/net/ip1000a/ipg_macros.h [new file with mode: 0644]
drivers/net/ip1000a/ipg_main.c [new file with mode: 0644]
drivers/net/ip1000a/ipg_main.o [new file with mode: 0644]
drivers/net/ip1000a/ipg_structs.h [new file with mode: 0644]
drivers/net/ip1000a/ipg_tune.h [new file with mode: 0644]
drivers/net/ip1000a/make2.2.sh [new file with mode: 0644]
drivers/net/ip1000a/make2.2mod.sh [new file with mode: 0644]
drivers/net/ip1000a/readme.txt [new file with mode: 0644]

index 188fe42..21da023 100644 (file)
@@ -259,6 +259,7 @@ dep_tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACE
 if [ "$CONFIG_ACENIC" != "n" ]; then
    bool '  Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I
 fi
+dep_tristate 'IC PLUS IP1000 1000/100/10 based Ethernet support' CONFIG_IP1000A $CONFIG_PCI
 dep_tristate 'D-Link DL2000-based Gigabit Ethernet support' CONFIG_DL2K $CONFIG_PCI
 dep_tristate 'Intel(R) PRO/1000 Gigabit Ethernet support' CONFIG_E1000 $CONFIG_PCI
 if [ "$CONFIG_E1000" != "n" ]; then
index 82f52fe..464cfc2 100644 (file)
@@ -31,6 +31,10 @@ ifeq ($(CONFIG_E1000),y)
   obj-y += e1000/e1000.o
 endif
 
+ifeq ($(CONFIG_IP1000A),y)
+  obj-y += ip1000a/ipg.o
+endif
+
 ifeq ($(CONFIG_BONDING),y)
   obj-y += bonding/bonding.o
 endif
@@ -53,6 +57,7 @@ subdir-$(CONFIG_SK98LIN) += sk98lin
 subdir-$(CONFIG_SKFP) += skfp
 subdir-$(CONFIG_E100) += e100
 subdir-$(CONFIG_E1000) += e1000
+subdir-$(CONFIG_IP1000A) += ip1000a
 subdir-$(CONFIG_BONDING) += bonding
 
 #
diff --git a/drivers/net/ip1000a/.ipg.o.flags b/drivers/net/ip1000a/.ipg.o.flags
new file mode 100644 (file)
index 0000000..0396297
--- /dev/null
@@ -0,0 +1,3 @@
+ifeq (ipg_main.o,$(strip $(subst $(comma),:,$(LDFLAGS) $(EXTRA_LDFLAGS) $(obj-y))))
+FILES_FLAGS_UP_TO_DATE += ipg.o
+endif
diff --git a/drivers/net/ip1000a/.ipg_main.o.flags b/drivers/net/ip1000a/.ipg_main.o.flags
new file mode 100644 (file)
index 0000000..318bce9
--- /dev/null
@@ -0,0 +1,3 @@
+ifeq (-D__KERNEL__ -I/rest/ppc/linux-2.4.34.4/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-builtin-sprintf -fomit-frame-pointer -I/rest/ppc/linux-2.4.34.4/arch/ppc -fsigned-char -msoft-float -pipe -ffixed-r2 -Wno-uninitialized -mmultiple -mstring -nostdinc -iwithprefix include,$(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS_nostdinc) $(CFLAGS_ipg_main.o))))
+FILES_FLAGS_UP_TO_DATE += ipg_main.o
+endif
diff --git a/drivers/net/ip1000a/Makefile b/drivers/net/ip1000a/Makefile
new file mode 100644 (file)
index 0000000..18f4740
--- /dev/null
@@ -0,0 +1,6 @@
+O_TARGET := ipg.o
+
+obj-y  := ipg_main.o
+obj-m  := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff --git a/drivers/net/ip1000a/Makefile.orig b/drivers/net/ip1000a/Makefile.orig
new file mode 100644 (file)
index 0000000..c91b384
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# Makefile for IC Plus Ethernet Adapter driver for Linux
+# Copyright (c) 2004 by IC Plus Corporation.
+#
+#
+OBJS   = ipg_main.o
+TARGET  = ipg.o
+MAPPING_MODE= -DUSE_IO_OPS
+#MAPPING_MODE= -DUSE_IO_OPS -DJUMBO_FRAME -DJUMBO_FRAME_SIZE_4K
+
+KernelVersion            := $(shell uname -r)
+KernelBuildDir           := /lib/modules/$(KernelVersion)/build
+kernelMisc               := /lib/modules/$(KernelVersion)/kernel/drivers/net/
+kernelExtension          := $(shell echo $(KernelVersion) | sed -ne 's/^2\.[567]\..*/k/p')o
+kernelFlag26               := kernel2$(shell echo $(KernelVersion) | sed -ne 's/^2\.[6]\..*/6/p')x
+
+
+#======================Makefile for kernel 2.2.x and 2.4.x======================
+ifneq ($(kernelFlag26),kernel26x)
+CC     = gcc
+CFLAGS = -D__KERNEL__ -DMODULE -O -Wall -Wstrict-prototypes -I$(INCLUDEDIR)
+EXTRA_CFLAGS := $(MAPPING_MODE) 
+EXTRA_CFLAGS := $(EXTRA_CFLAGS) -D_COMPAT_WITH_OLD_KERNEL
+
+
+KernelSrcPath :=  /lib/modules/$(shell uname -r)/build \
+        /usr/src/linux-$(shell uname -r) \
+        /usr/src/linux-$(shell uname -r | sed 's/-.*//') \
+        /usr/src/kernel-headers-$(shell uname -r) \
+        /usr/src/kernel-source-$(shell uname -r) \
+        /usr/src/linux-$(shell uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \
+        /usr/src/linux
+FindDir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
+KernelSrcPath := $(foreach dir, $(KernelSrcPath), $(FindDir))
+KernelSrc := $(firstword $(KernelSrcPath))
+
+# Support Linux software VLAN
+#EXTRA_CFLAGS := $(EXTRA_CFLAGS) -DCONFIG_VLAN_8021Q
+
+#EXTRA_CFLAGS := $(EXTRA_CFLAGS) -DEXTRA_STATS
+#DEBUG_FLAGS = -O -g -DALTA_DEBUG
+K_VER=$(shell uname -r)
+INCLUDEDIR=$(shell if [ -e /usr/src/linux-$(K_VER)/include ]; \
+       then echo "/usr/src/linux-$(K_VER)/include"; \
+       elif [ -e /usr/src/linux-2.4/include ]; \
+       then echo "/usr/src/linux-2.4/include"; \
+       elif [ -e /usr/src/linux/include ]; \
+       then echo "/usr/src/linux/include"; \
+       else echo "/usr/include"; fi)
+#
+# Old kernel need to configure modversions.h
+#
+#EXTRA_CFLAGS := $(EXTRA_CFLAGS) \
+#      $(shell if [ -e $(INCLUDEDIR)/linux/modversions.h ]; \
+#      then echo -DCONFIG_MODVERSIONS; fi)
+
+CFLAGS+=$(shell [ -f $(KernelSrc)/include/linux/modversions.h ] && \
+                echo "-DMODVERSIONS -include $(KernelSrc)/include/linux/modversions.h")
+                
+$(TARGET):     $(OBJS)
+               $(LD) -r -o $@ $(OBJS)
+#
+# Dependency to create object file.
+#
+all:    $(TARGET)
+#
+#
+# Common make rules
+# 
+%.o:%.c
+       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(DEBUG_FLAGS) -c -o $@ $< 
+endif
+
+
+#===========================Makefile for kernel 2.6.x===========================
+ifeq ($(kernelFlag26),kernel26x)
+EXTRA_CFLAGS+=$(MAPPING_MODE)
+
+all:
+       $(MAKE) -C $(KernelBuildDir) SUBDIRS=$(PWD) modules 
+       
+install:
+       install -m 644 -c ipg.$(kernelExtension) $(kernelMisc)
+
+ipg-objs:=$(OBJS)
+obj-m+=$(TARGET)
+endif
+
+#===========================Makefile common section============================
+# Delete existing object file 
+#
+clean:
+       rm -f *.o *.ko *~ core* .dep* .*.d .*.cmd *.mod.c *.a *.s .*.flags
diff --git a/drivers/net/ip1000a/PhyParam.h b/drivers/net/ip1000a/PhyParam.h
new file mode 100644 (file)
index 0000000..b2a30b2
--- /dev/null
@@ -0,0 +1,59 @@
+// PhyParam.h
+//variable record -- index by leading revision/length
+//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
+unsigned short DefaultPhyParam[] = {
+       // 11/12/03 IP1000A v1-3 rev=0x40
+       /*--------------------------------------------------------------------------
+       (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
+                                27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
+                                31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7,  9, 0x0700,
+         --------------------------------------------------------------------------*/
+       // 12/17/03 IP1000A v1-4 rev=0x40
+       (0x4000|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x41
+       (0x4100|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x42
+       (0x4200|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x43
+       (0x4300|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x44
+       (0x4400|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x45
+       (0x4500|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x46
+       (0x4600|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x47
+       (0x4700|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x48
+       (0x4800|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x49
+       (0x4900|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x4A
+       (0x4A00|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x4B
+       (0x4B00|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x4C
+       (0x4C00|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x4D
+       (0x4D00|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x4E
+       (0x4E00|(07*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, 0x0000,
+                        30, 0x005e,  9, 0x0700,
+        0x0000};
+
+
+
diff --git a/drivers/net/ip1000a/ipg.h b/drivers/net/ip1000a/ipg.h
new file mode 100644 (file)
index 0000000..557ef75
--- /dev/null
@@ -0,0 +1,181 @@
+/*\r
+ *\r
+ * ipg.h\r
+ *\r
+ * Include file for Gigabit Ethernet device driver for Network\r
+ * Interface Cards (NICs) utilizing the Tamarack Microelectronics\r
+ * Inc. IPG Gigabit or Triple Speed Ethernet Media Access\r
+ * Controller.\r
+ *\r
+ * Craig Rich\r
+ * Sundance Technology, Inc.\r
+ * 1485 Saratoga Avenue\r
+ * Suite 200\r
+ * San Jose, CA 95129\r
+ * 408 873 4117\r
+ * www.sundanceti.com\r
+ * craig_rich@sundanceti.com\r
+ *\r
+ * Rev  Date     Description\r
+ * --------------------------------------------------------------\r
+ * 0.1  11/8/99  Initial revision work begins\r
+ *\r
+ * 0.2  12/1/99  Minor update to modversions.h inclusion.\r
+ *\r
+ * 0.3  12/30/99 Updates to fully comply with IPG spec.\r
+ *\r
+ * 0.4  4/24/00  Updates to allow for removal of FCS generation\r
+ *               and verification.\r
+ * 0.5  8/15/00  Updates for MII PHY registers and fields.\r
+ *\r
+ * 0.6  8/31/00  Updates to change to using 64 bit data types\r
+ *\r
+ * 0.7  10/31/00 Added DDEBUG_MSG to allow for easy activation of\r
+ *               individual DEBUG_MSGs.\r
+ *\r
+ * 0.8  11/06/00 Changed LastFreedRxBuff to LastRestoredRxBuff for\r
+ *               clarity.\r
+ *\r
+ * 0.9  11/10/00 Changed Sundance DeviceID to 0x9020\r
+ *\r
+ * 0.10 2/14/01  Changed "DROP_ON_ERRORS", breaking out Ethernet from\r
+ *               TCP/IP errors.\r
+ *\r
+ * 0.11 3/16/01  Changed "IPG_FRAMESBETWEENTXCOMPLETES" to\r
+ *               "IPG_FRAMESBETWEENTXDMACOMPLETES" since will\r
+ *               be using TxDMAIndicate instead of TxIndicate to\r
+ *               improve performance. Added TFDunavailCount and\r
+ *               RFDlistendCount to aid in performance improvement.\r
+ *\r
+ * 0.12 3/22/01  Removed IPG_DROP_ON_RX_TCPIP_ERRORS.\r
+ *\r
+ * 0.13 3/23/01  Removed IPG_TXQUEUE_MARGIN.\r
+ *\r
+ * 0.14 3/30/01  Broke out sections into multiple files and added\r
+ *               OS version specific detection and settings.\r
+ */\r
+\r
+\r
+/*\r
+ * Linux header utilization:\r
+ *\r
+ * config.h     For PCI support, namely CONFIG_PCI macro.\r
+ *\r
+ * version.h   For Linux kernel version detection.\r
+ *\r
+ * module.h    For modularized driver support.\r
+ *\r
+ * kernel.h     For 'printk'.\r
+ *\r
+ * pci.h        PCI support, including ID, VENDOR, and CLASS\r
+ *              standard definitions; PCI specific structures,\r
+ *              including pci_dev struct.\r
+ *\r
+ * ioport.h     I/O ports, check_region, request_region,\r
+ *              release_region.\r
+ *\r
+ * errno.h      Standard error numbers, e.g. ENODEV.\r
+ *\r
+ * asm/io.h     For reading/writing I/O ports, and for virt_to_bus\r
+ *             function.\r
+ *\r
+ * delay.h      For milisecond delays.\r
+ *\r
+ * types.h      For specific typedefs (i.e. u32, u16, u8).\r
+ *\r
+ * netdevice.h  For device structure needed for network support.\r
+ *\r
+ * etherdevice.h       For ethernet device support.\r
+ *\r
+ * init.h       For __initfunc.\r
+ *\r
+ * skbuff.h    Socket buffer (skbuff) definition.\r
+ *\r
+ * asm/bitops.h        For test_and_set_bit, clear_bit functions.\r
+ *\r
+ * asm/spinlock.h For spin_lock_irqsave, spin_lock_irqrestore functions.\r
+ *\r
+ */\r
+\r
+\r
+#include <linux/config.h>\r
+#include <linux/version.h>\r
+#include <linux/module.h>\r
+\r
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) &&  defined(MODVERSIONS))\r
+       #include <linux/modversions.h>\r
+#endif\r
+\r
+#include <linux/kernel.h>\r
+#include <linux/pci.h>\r
+#include <linux/ioport.h>\r
+#include <linux/errno.h>\r
+#include <asm/io.h>\r
+#include <linux/delay.h>\r
+#include <linux/types.h>\r
+#include <linux/netdevice.h>\r
+#include <linux/etherdevice.h>\r
+#include <linux/init.h>\r
+#include <linux/skbuff.h>\r
+#include <linux/version.h>\r
+#include <asm/bitops.h>\r
+/*#include <asm/spinlock.h>*/\r
+\r
+#define DrvVer "2.09d"\r
+\r
+const char *version =\r
+"ipg : "DrvVer" Written by Craig Rich, www.sundanceti.com\n";\r
+\r
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0))\r
+       char kernel_version[] = UTS_RELEASE;\r
+#endif\r
+\r
+#if (defined(MODULE) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,1,15)))\r
+       MODULE_AUTHOR("IC Plus Corp. 2003                                           ");\r
+   MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver "DrvVer);\r
+#endif\r
+\r
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))\r
+       #define IPG_LINUX2_2\r
+       #undef IPG_LINUX2_4\r
+\r
+       #define IPG_DEV_KFREE_SKB(skb) dev_kfree_skb(skb)\r
+\r
+       #define IPG_HOST2BUS_MAP(addr) virt_to_bus(addr)\r
+\r
+       #define IPG_PCI_RESOURCE_START(dev, bar) dev->base_address[bar]\r
+\r
+       #define IPG_TX_NOTBUSY(dev) clear_bit(0,(void*)&dev->tbusy)\r
+       #define IPG_IS_TX_BUSY(dev) test_and_set_bit(0, (void*)&dev->tbusy)\r
+\r
+       #define IPG_DEVICE_TYPE struct device\r
+       #define IPG_STATS_TYPE struct enet_statistics\r
+#else\r
+       #undef IPG_LINUX2_2\r
+       #define IPG_LINUX2_4\r
+\r
+       #define IPG_DEV_KFREE_SKB(skb) dev_kfree_skb_irq(skb)\r
+\r
+       #define IPG_HOST2BUS_MAP(addr) addr\r
+\r
+       #define IPG_PCI_RESOURCE_START(dev, bar) dev->resource[bar].start\r
+\r
+       #define IPG_TX_NOTBUSY(dev) netif_wake_queue(dev)\r
+       #define IPG_IS_TX_BUSY(dev) netif_queue_stopped(dev)\r
+\r
+       #define IPG_DEVICE_TYPE struct net_device\r
+       #define IPG_STATS_TYPE struct net_device_stats\r
+#endif\r
+\r
+/* Order of the following includes is important, the following must\r
+ * appear first:\r
+ * ipg_constants.h\r
+ * ipg_tune.h\r
+ */\r
+#include "ipg_constants.h"\r
+#include "ipg_tune.h"\r
+#include "ipg_macros.h"\r
+#include "ipg_structs.h"\r
+#include "PhyParam.h"\r
+\r
+/* end ipg.h */\r
diff --git a/drivers/net/ip1000a/ipg.o b/drivers/net/ip1000a/ipg.o
new file mode 100644 (file)
index 0000000..912f255
Binary files /dev/null and b/drivers/net/ip1000a/ipg.o differ
diff --git a/drivers/net/ip1000a/ipg_constants.h b/drivers/net/ip1000a/ipg_constants.h
new file mode 100644 (file)
index 0000000..fbc0787
--- /dev/null
@@ -0,0 +1,563 @@
+/*\r
+ *\r
+ * ipg_constants.h\r
+ *\r
+ * Include file with non-tunable constants for Gigabit Ethernet\r
+ * device driver for Network Interface Cards (NICs) utilizing the\r
+ * Tamarack Microelectronics Inc. IPG Gigabit or Triple Speed\r
+ * Ethernet Media Access Controller.\r
+ *\r
+ * Craig Rich\r
+ * Sundance Technology, Inc.\r
+ * 1485 Saratoga Avenue\r
+ * Suite 200\r
+ * San Jose, CA 95129\r
+ * 408 873 4117\r
+ * www.sundanceti.com\r
+ * craig_rich@sundanceti.com\r
+ *\r
+ * Rev  Date     Description\r
+ * --------------------------------------------------------------\r
+ * 0.1  3/30/01  New file created from original ipg.h\r
+ *\r
+ * 0.2  8/13/01  Added GMII based PHY IDs and GMII_ID_1.\r
+ *\r
+ * 0.3  8/16/01  Added GMII_PHY_CONTROL_RESET.\r
+ */\r
+\r
+/* GMII based PHY IDs */\r
+#define                NS                              0x2000\r
+#define                MARVELL                         0x0141\r
+#define                ICPLUS_PHY              0x243\r
+\r
+/* NIC Physical Layer Device MII register addresses. */\r
+#define         MII_PHY_CONTROL                 0x00\r
+#define         MII_PHY_STATUS                  0x01\r
+#define         MII_PHY_IDENTIFIER_MSB          0x02\r
+#define         MII_PHY_IDENTIFIER_LSB          0x03\r
+#define         MII_PHY_AUTONEGADVERTISEMENT    0x04\r
+#define         MII_PHY_AUTONEGLINKPARTABILITY  0x05\r
+#define         MII_PHY_AUTONEGEXPANSION        0x06\r
+#define         MII_PHY_AUTONEGNP_TRANSMIT      0x07\r
+#define         MII_PHY_AUTONEGLP_RECEIVE_NP    0x08\r
+#define         MII_PHY_EXTENDED_STATUS         0x0F\r
+\r
+/* NIC Physical Layer Device MII register fields. */\r
+#define         MII_PHY_CONTROL_RESTARTAN       0x0200\r
+#define         MII_PHY_SELECTORFIELD           0x001F\r
+#define         MII_PHY_SELECTOR_IEEE8023       0x0001\r
+#define         MII_PHY_TECHABILITYFIELD        0x1FE0\r
+#define         MII_PHY_TECHABILITY_10BT        0x0020\r
+#define         MII_PHY_TECHABILITY_10BTFD      0x0040\r
+#define         MII_PHY_TECHABILITY_100BTX      0x0080\r
+#define         MII_PHY_TECHABILITY_100BTXFD    0x0100\r
+#define         MII_PHY_TECHABILITY_100BT4      0x0200\r
+#define         MII_PHY_TECHABILITY_PAUSE_FIELDS 0x0C00\r
+#define         MII_PHY_TECHABILITY_PAUSE       0x0400\r
+#define         MII_PHY_TECHABILITY_ASM_DIR     0x0800\r
+#define         MII_PHY_TECHABILITY_RSVD2       0x1000\r
+#define         MII_PHY_STATUS_AUTONEG_ABILITY  0x0008\r
+\r
+/* NIC Physical Layer Device GMII register addresses. */\r
+#define         GMII_PHY_CONTROL                 0x00\r
+#define         GMII_PHY_STATUS                  0x01\r
+#define                        GMII_PHY_ID_1                    0x02\r
+#define         GMII_PHY_AUTONEGADVERTISEMENT    0x04\r
+#define         GMII_PHY_AUTONEGLINKPARTABILITY  0x05\r
+#define         GMII_PHY_AUTONEGEXPANSION        0x06\r
+#define         GMII_PHY_AUTONEGNEXTPAGE         0x07\r
+#define         GMII_PHY_AUTONEGLINKPARTNEXTPAGE 0x08\r
+#define         GMII_PHY_EXTENDEDSTATUS          0x0F\r
+\r
+#define         GMII_PHY_1000BASETCONTROL        0x09\r
+#define         GMII_PHY_1000BASETSTATUS         0x0A\r
+\r
+/* GMII_PHY_1000 need to set to prefer master */\r
+#define         GMII_PHY_1000BASETCONTROL_PreferMaster 0x0400\r
+\r
+#define         GMII_PHY_1000BASETCONTROL_FULL_DUPLEX 0x0200\r
+#define         GMII_PHY_1000BASETCONTROL_HALF_DUPLEX 0x0100\r
+#define         GMII_PHY_1000BASETSTATUS_FULL_DUPLEX 0x0800\r
+#define         GMII_PHY_1000BASETSTATUS_HALF_DUPLEX 0x0400\r
+\r
+/* NIC Physical Layer Device GMII register Fields. */\r
+#define         GMII_PHY_CONTROL_RESET          0x8000\r
+#define         GMII_PHY_CONTROL_FULL_DUPLEX    0x0100\r
+#define         GMII_PHY_STATUS_AUTONEG_ABILITY 0x0008\r
+#define         GMII_PHY_ADV_FULL_DUPLEX        0x0020\r
+#define         GMII_PHY_ADV_HALF_DUPLEX        0x0040\r
+#define         GMII_PHY_ADV_PAUSE              0x0180\r
+#define         GMII_PHY_ADV_PAUSE_PS1          0x0080\r
+#define         GMII_PHY_ADV_ASM_DIR_PS2        0x0100\r
+\r
+/* NIC Physical Layer Device GMII constants. */\r
+#define         GMII_PREAMBLE                    0xFFFFFFFF\r
+#define         GMII_ST                          0x1\r
+#define         GMII_READ                        0x2\r
+#define         GMII_WRITE                       0x1\r
+#define         GMII_TA_READ_MASK                0x1\r
+#define         GMII_TA_WRITE                    0x2\r
+\r
+/* PCI register addresses. */\r
+#define         IPG_POWERMGMTCTRL              0x54\r
+#define         IPG_POWERMGMTCAP               0x52\r
+#define         IPG_NEXTITEMPTR                0x51\r
+#define         IPG_CAPID                      0x50\r
+#define         IPG_MAXLAT                     0x3F\r
+#define         IPG_MINGNT                     0x3E\r
+#define         IPG_INTERRUPTPIN               0x3D\r
+#define         IPG_INTERRUPTLINE              0x3C\r
+#define         IPG_CAPPTR                     0x34\r
+#define         IPG_EXPROMBASEADDRESS  0x30\r
+#define         IPG_SUBSYSTEMID                0x2E\r
+#define         IPG_SUBSYSTEMVENDORID  0x2C\r
+#define         IPG_MEMBASEADDRESS             0x14\r
+#define         IPG_IOBASEADDRESS              0x10\r
+#define         IPG_HEADERTYPE         0x0E\r
+#define         IPG_LATENCYTIMER               0x0D\r
+#define         IPG_CACHELINESIZE              0x0C\r
+#define         IPG_CLASSCODE          0x09\r
+#define         IPG_REVISIONID         0x08\r
+#define         IPG_CONFIGSTATUS               0x06\r
+#define         IPG_CONFIGCOMMAND              0x04\r
+#define         IPG_DEVICEID                   0x02\r
+#define         IPG_VENDORID                   0x00\r
+\r
+/* I/O register offsets. */\r
+#define        IPG_DMACTRL                     0x00\r
+#define        IPG_RXDMASTATUS         0x08 /* RESERVED */\r
+#define        IPG_TFDLISTPTR0         0x10\r
+#define        IPG_TFDLISTPTR1         0x14\r
+#define        IPG_TXDMABURSTTHRESH            0x18\r
+#define        IPG_TXDMAURGENTTHRESH   0x19\r
+#define        IPG_TXDMAPOLLPERIOD             0x1A\r
+#define        IPG_RFDLISTPTR0         0x1C\r
+#define        IPG_RFDLISTPTR1         0x20\r
+#define        IPG_RXDMABURSTTHRESH            0x24\r
+#define        IPG_RXDMAURGENTTHRESH   0x25\r
+#define        IPG_RXDMAPOLLPERIOD             0x26\r
+#define        IPG_RXDMAINTCTRL                0x28\r
+#define        IPG_DEBUGCTRL           0x2C\r
+#define        IPG_ASICCTRL                    0x30\r
+#define        IPG_FIFOCTRL                    0x38\r
+#define        IPG_RXEARLYTHRESH               0x3A\r
+#define        IPG_FLOWOFFTHRESH               0x3C\r
+#define        IPG_FLOWONTHRESH                0x3E\r
+#define        IPG_TXSTARTTHRESH               0x44\r
+#define        IPG_EEPROMDATA          0x48\r
+#define        IPG_EEPROMCTRL          0x4A\r
+#define        IPG_EXPROMADDR          0x4C\r
+#define        IPG_EXPROMDATA          0x50\r
+#define        IPG_WAKEEVENT           0x51\r
+#define        IPG_COUNTDOWN           0x54\r
+#define        IPG_INTSTATUSACK                0x5A\r
+#define        IPG_INTENABLE           0x5C\r
+#define        IPG_INTSTATUS           0x5E\r
+#define        IPG_TXSTATUS                    0x60\r
+#define        IPG_MACCTRL                     0x6C\r
+#define        IPG_VLANTAG                     0x70\r
+#define        IPG_PHYSET                      0x75    //JES20040127EEPROM\r
+#define        IPG_PHYCTRL                     0x76\r
+#define        IPG_STATIONADDRESS0             0x78\r
+#define        IPG_STATIONADDRESS1             0x7A\r
+#define        IPG_STATIONADDRESS2             0x7C\r
+#define        IPG_MAXFRAMESIZE                0x86\r
+#define        IPG_RECEIVEMODE         0x88\r
+#define        IPG_HASHTABLE0          0x8C\r
+#define        IPG_HASHTABLE1          0x90\r
+#define        IPG_RMONSTATISTICSMASK  0x98\r
+#define        IPG_STATISTICSMASK              0x9C\r
+#define        IPG_RXJUMBOFRAMES               0xBC\r
+#define        IPG_TCPCHECKSUMERRORS   0xC0\r
+#define        IPG_IPCHECKSUMERRORS            0xC2\r
+#define        IPG_UDPCHECKSUMERRORS   0xC4\r
+#define        IPG_TXJUMBOFRAMES               0xF4\r
+\r
+/* Ethernet MIB statistic register offsets. */\r
+#define        IPG_OCTETRCVOK          0xA8\r
+#define        IPG_MCSTOCTETRCVDOK             0xAC\r
+#define        IPG_BCSTOCTETRCVOK              0xB0\r
+#define        IPG_FRAMESRCVDOK                0xB4\r
+#define        IPG_MCSTFRAMESRCVDOK            0xB8\r
+#define        IPG_BCSTFRAMESRCVDOK            0xBE\r
+#define        IPG_MACCONTROLFRAMESRCVD        0xC6\r
+#define        IPG_FRAMETOOLONGERRRORS 0xC8\r
+#define        IPG_INRANGELENGTHERRORS 0xCA\r
+#define        IPG_FRAMECHECKSEQERRORS 0xCC\r
+#define        IPG_FRAMESLOSTRXERRORS  0xCE\r
+#define        IPG_OCTETXMTOK          0xD0\r
+#define        IPG_MCSTOCTETXMTOK              0xD4\r
+#define        IPG_BCSTOCTETXMTOK              0xD8\r
+#define        IPG_FRAMESXMTDOK                0xDC\r
+#define        IPG_MCSTFRAMESXMTDOK            0xE0\r
+#define        IPG_FRAMESWDEFERREDXMT  0xE4\r
+#define        IPG_LATECOLLISIONS              0xE8\r
+#define        IPG_MULTICOLFRAMES              0xEC\r
+#define        IPG_SINGLECOLFRAMES             0xF0\r
+#define        IPG_BCSTFRAMESXMTDOK            0xF6\r
+#define        IPG_CARRIERSENSEERRORS  0xF8\r
+#define        IPG_MACCONTROLFRAMESXMTDOK      0xFA\r
+#define        IPG_FRAMESABORTXSCOLLS  0xFC\r
+#define        IPG_FRAMESWEXDEFERRAL   0xFE\r
+\r
+/* RMON statistic register offsets. */\r
+#define        IPG_ETHERSTATSCOLLISIONS                        0x100\r
+#define        IPG_ETHERSTATSOCTETSTRANSMIT                    0x104\r
+#define        IPG_ETHERSTATSPKTSTRANSMIT                      0x108\r
+#define        IPG_ETHERSTATSPKTS64OCTESTSTRANSMIT             0x10C\r
+#define        IPG_ETHERSTATSPKTS65TO127OCTESTSTRANSMIT        0x110\r
+#define        IPG_ETHERSTATSPKTS128TO255OCTESTSTRANSMIT       0x114\r
+#define        IPG_ETHERSTATSPKTS256TO511OCTESTSTRANSMIT       0x118\r
+#define        IPG_ETHERSTATSPKTS512TO1023OCTESTSTRANSMIT      0x11C\r
+#define        IPG_ETHERSTATSPKTS1024TO1518OCTESTSTRANSMIT     0x120\r
+#define        IPG_ETHERSTATSCRCALIGNERRORS                    0x124\r
+#define        IPG_ETHERSTATSUNDERSIZEPKTS                     0x128\r
+#define        IPG_ETHERSTATSFRAGMENTS                 0x12C\r
+#define        IPG_ETHERSTATSJABBERS                   0x130\r
+#define        IPG_ETHERSTATSOCTETS                            0x134\r
+#define        IPG_ETHERSTATSPKTS                              0x138\r
+#define        IPG_ETHERSTATSPKTS64OCTESTS                     0x13C\r
+#define        IPG_ETHERSTATSPKTS65TO127OCTESTS                0x140\r
+#define        IPG_ETHERSTATSPKTS128TO255OCTESTS               0x144\r
+#define        IPG_ETHERSTATSPKTS256TO511OCTESTS               0x148\r
+#define        IPG_ETHERSTATSPKTS512TO1023OCTESTS              0x14C\r
+#define        IPG_ETHERSTATSPKTS1024TO1518OCTESTS             0x150\r
+\r
+/* RMON statistic register equivalents. */\r
+#define        IPG_ETHERSTATSMULTICASTPKTSTRANSMIT             0xE0\r
+#define        IPG_ETHERSTATSBROADCASTPKTSTRANSMIT             0xF6\r
+#define        IPG_ETHERSTATSMULTICASTPKTS                     0xB8\r
+#define        IPG_ETHERSTATSBROADCASTPKTS                     0xBE\r
+#define        IPG_ETHERSTATSOVERSIZEPKTS                      0xC8\r
+#define        IPG_ETHERSTATSDROPEVENTS                        0xCE\r
+\r
+/* Serial EEPROM offsets */\r
+#define        IPG_EEPROM_CONFIGPARAM  0x00\r
+#define        IPG_EEPROM_ASICCTRL             0x01\r
+#define        IPG_EEPROM_SUBSYSTEMVENDORID    0x02\r
+#define        IPG_EEPROM_SUBSYSTEMID  0x03\r
+#define        IPG_EEPROM_STATIONADDRESS0      0x10\r
+#define        IPG_EEPROM_STATIONADDRESS1      0x11\r
+#define        IPG_EEPROM_STATIONADDRESS2      0x12\r
+\r
+\r
+/* Register & data structure bit masks */\r
+\r
+/* PCI register masks. */\r
+\r
+/* IOBaseAddress */\r
+#define         IPG_PIB_RSVD_MASK              0xFFFFFE01\r
+#define         IPG_PIB_IOBASEADDRESS  0xFFFFFF00\r
+#define         IPG_PIB_IOBASEADDRIND  0x00000001\r
+\r
+/* MemBaseAddress */\r
+#define         IPG_PMB_RSVD_MASK              0xFFFFFE07\r
+#define         IPG_PMB_MEMBASEADDRIND 0x00000001\r
+#define         IPG_PMB_MEMMAPTYPE             0x00000006\r
+#define         IPG_PMB_MEMMAPTYPE0            0x00000002\r
+#define         IPG_PMB_MEMMAPTYPE1            0x00000004\r
+#define         IPG_PMB_MEMBASEADDRESS 0xFFFFFE00\r
+\r
+/* ConfigStatus */\r
+#define IPG_CS_RSVD_MASK                0xFFB0\r
+#define IPG_CS_CAPABILITIES             0x0010\r
+#define IPG_CS_66MHZCAPABLE             0x0020\r
+#define IPG_CS_FASTBACK2BACK            0x0080\r
+#define IPG_CS_DATAPARITYREPORTED       0x0100\r
+#define IPG_CS_DEVSELTIMING             0x0600\r
+#define IPG_CS_SIGNALEDTARGETABORT      0x0800\r
+#define IPG_CS_RECEIVEDTARGETABORT      0x1000\r
+#define IPG_CS_RECEIVEDMASTERABORT      0x2000\r
+#define IPG_CS_SIGNALEDSYSTEMERROR      0x4000\r
+#define IPG_CS_DETECTEDPARITYERROR      0x8000\r
+\r
+/* TFD data structure masks. */\r
+\r
+/* TFDList, TFC */\r
+#define        IPG_TFC_RSVD_MASK                       0x0000FFFF9FFFFFFF\r
+#define        IPG_TFC_FRAMEID                 0x000000000000FFFF\r
+#define        IPG_TFC_WORDALIGN                       0x0000000000030000\r
+#define        IPG_TFC_WORDALIGNTODWORD                0x0000000000000000\r
+#define        IPG_TFC_WORDALIGNTOWORD         0x0000000000020000\r
+#define        IPG_TFC_WORDALIGNDISABLED               0x0000000000030000\r
+#define        IPG_TFC_TCPCHECKSUMENABLE               0x0000000000040000\r
+#define        IPG_TFC_UDPCHECKSUMENABLE               0x0000000000080000\r
+#define        IPG_TFC_IPCHECKSUMENABLE                0x0000000000100000\r
+#define        IPG_TFC_FCSAPPENDDISABLE                0x0000000000200000\r
+#define        IPG_TFC_TXINDICATE                      0x0000000000400000\r
+#define        IPG_TFC_TXDMAINDICATE           0x0000000000800000\r
+#define        IPG_TFC_FRAGCOUNT                       0x000000000F000000\r
+#define        IPG_TFC_VLANTAGINSERT           0x0000000010000000\r
+#define        IPG_TFC_TFDDONE                 0x0000000080000000\r
+#define        IPG_TFC_VID                             0x00000FFF00000000\r
+#define        IPG_TFC_CFI                             0x0000100000000000\r
+#define        IPG_TFC_USERPRIORITY                    0x0000E00000000000\r
+\r
+/* TFDList, FragInfo */\r
+#define        IPG_TFI_RSVD_MASK                       0xFFFF00FFFFFFFFFF\r
+#define        IPG_TFI_FRAGADDR                        0x000000FFFFFFFFFF\r
+#define        IPG_TFI_FRAGLEN                 0xFFFF000000000000LL\r
+\r
+/* RFD data structure masks. */\r
+\r
+/* RFDList, RFS */\r
+#define        IPG_RFS_RSVD_MASK                       0x0000FFFFFFFFFFFF\r
+#define        IPG_RFS_RXFRAMELEN                      0x000000000000FFFF\r
+#define        IPG_RFS_RXFIFOOVERRUN           0x0000000000010000\r
+#define        IPG_RFS_RXRUNTFRAME                     0x0000000000020000\r
+#define        IPG_RFS_RXALIGNMENTERROR                0x0000000000040000\r
+#define        IPG_RFS_RXFCSERROR                      0x0000000000080000\r
+#define        IPG_RFS_RXOVERSIZEDFRAME                0x0000000000100000\r
+#define        IPG_RFS_RXLENGTHERROR           0x0000000000200000\r
+#define        IPG_RFS_VLANDETECTED                    0x0000000000400000\r
+#define        IPG_RFS_TCPDETECTED                     0x0000000000800000\r
+#define        IPG_RFS_TCPERROR                        0x0000000001000000\r
+#define        IPG_RFS_UDPDETECTED                     0x0000000002000000\r
+#define        IPG_RFS_UDPERROR                        0x0000000004000000\r
+#define        IPG_RFS_IPDETECTED                      0x0000000008000000\r
+#define        IPG_RFS_IPERROR                 0x0000000010000000\r
+#define        IPG_RFS_FRAMESTART                      0x0000000020000000\r
+#define        IPG_RFS_FRAMEEND                        0x0000000040000000\r
+#define        IPG_RFS_RFDDONE                 0x0000000080000000\r
+#define        IPG_RFS_TCI                             0x0000FFFF00000000\r
+\r
+\r
+/* RFDList, FragInfo */\r
+#define        IPG_RFI_RSVD_MASK                       0xFFFF00FFFFFFFFFF\r
+#define        IPG_RFI_FRAGADDR                        0x000000FFFFFFFFFF\r
+#define        IPG_RFI_FRAGLEN                 0xFFFF000000000000LL\r
+\r
+/* I/O Register masks. */\r
+\r
+/* RMON Statistics Mask */\r
+#define        IPG_RZ_ALL                                      0x0FFFFFFF\r
+\r
+/* Statistics Mask */\r
+#define        IPG_SM_ALL                                      0x0FFFFFFF\r
+#define        IPG_SM_OCTETRCVOK_FRAMESRCVDOK          0x00000001\r
+#define        IPG_SM_MCSTOCTETRCVDOK_MCSTFRAMESRCVDOK 0x00000002\r
+#define        IPG_SM_BCSTOCTETRCVDOK_BCSTFRAMESRCVDOK 0x00000004\r
+#define        IPG_SM_RXJUMBOFRAMES                            0x00000008\r
+#define        IPG_SM_TCPCHECKSUMERRORS                        0x00000010\r
+#define        IPG_SM_IPCHECKSUMERRORS                 0x00000020\r
+#define        IPG_SM_UDPCHECKSUMERRORS                        0x00000040\r
+#define        IPG_SM_MACCONTROLFRAMESRCVD                     0x00000080\r
+#define        IPG_SM_FRAMESTOOLONGERRORS                      0x00000100\r
+#define        IPG_SM_INRANGELENGTHERRORS                      0x00000200\r
+#define        IPG_SM_FRAMECHECKSEQERRORS                      0x00000400\r
+#define        IPG_SM_FRAMESLOSTRXERRORS                       0x00000800\r
+#define        IPG_SM_OCTETXMTOK_FRAMESXMTOK           0x00001000\r
+#define        IPG_SM_MCSTOCTETXMTOK_MCSTFRAMESXMTDOK  0x00002000\r
+#define        IPG_SM_BCSTOCTETXMTOK_BCSTFRAMESXMTDOK  0x00004000\r
+#define        IPG_SM_FRAMESWDEFERREDXMT                       0x00008000\r
+#define        IPG_SM_LATECOLLISIONS                   0x00010000\r
+#define        IPG_SM_MULTICOLFRAMES                   0x00020000\r
+#define        IPG_SM_SINGLECOLFRAMES                  0x00040000\r
+#define        IPG_SM_TXJUMBOFRAMES                            0x00080000\r
+#define        IPG_SM_CARRIERSENSEERRORS                       0x00100000\r
+#define        IPG_SM_MACCONTROLFRAMESXMTD                     0x00200000\r
+#define        IPG_SM_FRAMESABORTXSCOLLS                       0x00400000\r
+#define        IPG_SM_FRAMESWEXDEFERAL                 0x00800000\r
+\r
+\r
+/* Countdown */\r
+#define        IPG_CD_RSVD_MASK                0x0700FFFF\r
+#define        IPG_CD_COUNT                    0x0000FFFF\r
+#define        IPG_CD_COUNTDOWNSPEED   0x01000000\r
+#define        IPG_CD_COUNTDOWNMODE            0x02000000\r
+#define        IPG_CD_COUNTINTENABLED  0x04000000\r
+\r
+/* TxDMABurstThresh */\r
+#define IPG_TB_RSVD_MASK                0xFF\r
+\r
+/* TxDMAUrgentThresh */\r
+#define IPG_TU_RSVD_MASK                0xFF\r
+\r
+/* TxDMAPollPeriod */\r
+#define IPG_TP_RSVD_MASK                0xFF\r
+\r
+/* RxDMAUrgentThresh */\r
+#define IPG_RU_RSVD_MASK                0xFF\r
+\r
+/* RxDMAPollPeriod */\r
+#define IPG_RP_RSVD_MASK                0xFF\r
+\r
+/* TxStartThresh */\r
+#define IPG_TT_RSVD_MASK                0x0FFF\r
+\r
+/* RxEarlyThresh */\r
+#define IPG_RE_RSVD_MASK                0x07FF\r
+\r
+/* ReceiveMode */\r
+#define IPG_RM_RSVD_MASK                0x3F\r
+#define IPG_RM_RECEIVEUNICAST           0x01\r
+#define IPG_RM_RECEIVEMULTICAST         0x02\r
+#define IPG_RM_RECEIVEBROADCAST         0x04\r
+#define IPG_RM_RECEIVEALLFRAMES         0x08\r
+#define IPG_RM_RECEIVEMULTICASTHASH     0x10\r
+#define IPG_RM_RECEIVEIPMULTICAST       0x20\r
+\r
+/* PhySet JES20040127EEPROM*/\r
+#define IPG_PS_MEM_LENB9B               0x01\r
+#define IPG_PS_MEM_LEN9                 0x02\r
+#define IPG_PS_NON_COMPDET              0x04\r
+\r
+/* PhyCtrl */\r
+#define IPG_PC_RSVD_MASK                0xFF\r
+#define IPG_PC_MGMTCLK_LO               0x00\r
+#define IPG_PC_MGMTCLK_HI               0x01\r
+#define IPG_PC_MGMTCLK                  0x01\r
+#define IPG_PC_MGMTDATA                 0x02\r
+#define IPG_PC_MGMTDIR                  0x04\r
+#define IPG_PC_DUPLEX_POLARITY          0x08\r
+#define IPG_PC_DUPLEX_STATUS            0x10\r
+#define IPG_PC_LINK_POLARITY            0x20\r
+#define IPG_PC_LINK_SPEED               0xC0\r
+#define IPG_PC_LINK_SPEED_10MBPS        0x40\r
+#define IPG_PC_LINK_SPEED_100MBPS       0x80\r
+#define IPG_PC_LINK_SPEED_1000MBPS      0xC0\r
+\r
+/* DMACtrl */\r
+#define IPG_DC_RSVD_MASK                0xC07D9818\r
+#define IPG_DC_RX_DMA_COMPLETE          0x00000008\r
+#define IPG_DC_RX_DMA_POLL_NOW          0x00000010\r
+#define IPG_DC_TX_DMA_COMPLETE          0x00000800\r
+#define IPG_DC_TX_DMA_POLL_NOW          0x00001000\r
+#define IPG_DC_TX_DMA_IN_PROG           0x00008000\r
+#define IPG_DC_RX_EARLY_DISABLE         0x00010000\r
+#define IPG_DC_MWI_DISABLE              0x00040000\r
+#define IPG_DC_TX_WRITE_BACK_DISABLE    0x00080000\r
+#define IPG_DC_TX_BURST_LIMIT           0x00700000\r
+#define IPG_DC_TARGET_ABORT             0x40000000\r
+#define IPG_DC_MASTER_ABORT             0x80000000\r
+\r
+/* ASICCtrl */\r
+#define IPG_AC_RSVD_MASK                0x07FFEFF2\r
+#define IPG_AC_EXP_ROM_SIZE             0x00000002\r
+#define IPG_AC_PHY_SPEED10              0x00000010\r
+#define IPG_AC_PHY_SPEED100             0x00000020\r
+#define IPG_AC_PHY_SPEED1000            0x00000040\r
+#define IPG_AC_PHY_MEDIA                0x00000080\r
+#define IPG_AC_FORCED_CFG               0x00000700\r
+#define IPG_AC_D3RESETDISABLE           0x00000800\r
+#define IPG_AC_SPEED_UP_MODE            0x00002000\r
+#define IPG_AC_LED_MODE                 0x00004000\r
+#define IPG_AC_RST_OUT_POLARITY         0x00008000\r
+#define IPG_AC_GLOBAL_RESET             0x00010000\r
+#define IPG_AC_RX_RESET                 0x00020000\r
+#define IPG_AC_TX_RESET                 0x00040000\r
+#define IPG_AC_DMA                      0x00080000\r
+#define IPG_AC_FIFO                     0x00100000\r
+#define IPG_AC_NETWORK                  0x00200000\r
+#define IPG_AC_HOST                     0x00400000\r
+#define IPG_AC_AUTO_INIT                0x00800000\r
+#define IPG_AC_RST_OUT                  0x01000000\r
+#define IPG_AC_INT_REQUEST              0x02000000\r
+#define IPG_AC_RESET_BUSY               0x04000000\r
+#define IPG_AC_LED_SPEED                0x08000000     //JES20040127EEPROM\r
+#define IPG_AC_LED_MODE_BIT_1           0x20000000 //JES20040127EEPROM\r
+\r
+/* EepromCtrl */\r
+#define IPG_EC_RSVD_MASK                0x83FF\r
+#define IPG_EC_EEPROM_ADDR              0x00FF\r
+#define IPG_EC_EEPROM_OPCODE            0x0300\r
+#define IPG_EC_EEPROM_SUBCOMMAD         0x0000\r
+#define IPG_EC_EEPROM_WRITEOPCODE       0x0100\r
+#define IPG_EC_EEPROM_READOPCODE        0x0200\r
+#define IPG_EC_EEPROM_ERASEOPCODE       0x0300\r
+#define IPG_EC_EEPROM_BUSY              0x8000\r
+\r
+/* FIFOCtrl */\r
+#define IPG_FC_RSVD_MASK                0xC001\r
+#define IPG_FC_RAM_TEST_MODE            0x0001\r
+#define IPG_FC_TRANSMITTING             0x4000\r
+#define IPG_FC_RECEIVING                0x8000\r
+\r
+/* TxStatus */\r
+#define IPG_TS_RSVD_MASK                0xFFFF00DD\r
+#define IPG_TS_TX_ERROR                 0x00000001\r
+#define IPG_TS_LATE_COLLISION           0x00000004\r
+#define IPG_TS_TX_MAX_COLL              0x00000008\r
+#define IPG_TS_TX_UNDERRUN              0x00000010\r
+#define IPG_TS_TX_IND_REQD              0x00000040\r
+#define IPG_TS_TX_COMPLETE              0x00000080\r
+#define IPG_TS_TX_FRAMEID               0xFFFF0000\r
+\r
+/* WakeEvent */\r
+#define IPG_WE_WAKE_PKT_ENABLE          0x01\r
+#define IPG_WE_MAGIC_PKT_ENABLE         0x02\r
+#define IPG_WE_LINK_EVT_ENABLE          0x04\r
+#define IPG_WE_WAKE_POLARITY            0x08\r
+#define IPG_WE_WAKE_PKT_EVT             0x10\r
+#define IPG_WE_MAGIC_PKT_EVT            0x20\r
+#define IPG_WE_LINK_EVT                 0x40\r
+#define IPG_WE_WOL_ENABLE               0x80\r
+\r
+/* IntEnable */\r
+#define IPG_IE_RSVD_MASK                0x1FFE\r
+#define IPG_IE_HOST_ERROR               0x0002\r
+#define IPG_IE_TX_COMPLETE              0x0004\r
+#define IPG_IE_MAC_CTRL_FRAME           0x0008\r
+#define IPG_IE_RX_COMPLETE              0x0010\r
+#define IPG_IE_RX_EARLY                 0x0020\r
+#define IPG_IE_INT_REQUESTED            0x0040\r
+#define IPG_IE_UPDATE_STATS             0x0080\r
+#define IPG_IE_LINK_EVENT               0x0100\r
+#define IPG_IE_TX_DMA_COMPLETE          0x0200\r
+#define IPG_IE_RX_DMA_COMPLETE          0x0400\r
+#define IPG_IE_RFD_LIST_END             0x0800\r
+#define IPG_IE_RX_DMA_PRIORITY          0x1000\r
+\r
+/* IntStatus */\r
+#define IPG_IS_RSVD_MASK                0x1FFF\r
+#define IPG_IS_INTERRUPT_STATUS         0x0001\r
+#define IPG_IS_HOST_ERROR               0x0002\r
+#define IPG_IS_TX_COMPLETE              0x0004\r
+#define IPG_IS_MAC_CTRL_FRAME           0x0008\r
+#define IPG_IS_RX_COMPLETE              0x0010\r
+#define IPG_IS_RX_EARLY                 0x0020\r
+#define IPG_IS_INT_REQUESTED            0x0040\r
+#define IPG_IS_UPDATE_STATS             0x0080\r
+#define IPG_IS_LINK_EVENT               0x0100\r
+#define IPG_IS_TX_DMA_COMPLETE          0x0200\r
+#define IPG_IS_RX_DMA_COMPLETE          0x0400\r
+#define IPG_IS_RFD_LIST_END             0x0800\r
+#define IPG_IS_RX_DMA_PRIORITY          0x1000\r
+\r
+/* MACCtrl */\r
+#define IPG_MC_RSVD_MASK                0x7FE33FA3\r
+#define IPG_MC_IFS_SELECT               0x00000003\r
+#define IPG_MC_IFS_4352BIT              0x00000003\r
+#define IPG_MC_IFS_1792BIT              0x00000002\r
+#define IPG_MC_IFS_1024BIT              0x00000001\r
+#define IPG_MC_IFS_96BIT                0x00000000\r
+#define IPG_MC_DUPLEX_SELECT            0x00000020\r
+#define IPG_MC_DUPLEX_SELECT_FD         0x00000020\r
+#define IPG_MC_DUPLEX_SELECT_HD         0x00000000\r
+#define IPG_MC_TX_FLOW_CONTROL_ENABLE   0x00000080\r
+#define IPG_MC_RX_FLOW_CONTROL_ENABLE   0x00000100\r
+#define IPG_MC_RCV_FCS                  0x00000200\r
+#define IPG_MC_FIFO_LOOPBACK            0x00000400\r
+#define IPG_MC_MAC_LOOPBACK             0x00000800\r
+#define IPG_MC_AUTO_VLAN_TAGGING        0x00001000\r
+#define IPG_MC_AUTO_VLAN_UNTAGGING      0x00002000\r
+#define IPG_MC_COLLISION_DETECT         0x00010000\r
+#define IPG_MC_CARRIER_SENSE            0x00020000\r
+#define IPG_MC_STATISTICS_ENABLE        0x00200000\r
+#define IPG_MC_STATISTICS_DISABLE       0x00400000\r
+#define IPG_MC_STATISTICS_ENABLED       0x00800000\r
+#define IPG_MC_TX_ENABLE                0x01000000\r
+#define IPG_MC_TX_DISABLE               0x02000000\r
+#define IPG_MC_TX_ENABLED               0x04000000\r
+#define IPG_MC_RX_ENABLE                0x08000000\r
+#define IPG_MC_RX_DISABLE               0x10000000\r
+#define IPG_MC_RX_ENABLED               0x20000000\r
+#define IPG_MC_PAUSED                   0x40000000\r
+\r
+/* RxDMAIntCtrl */\r
+#define IPG_RI_RSVD_MASK                0xFFFF1CFF\r
+#define IPG_RI_RXFRAME_COUNT            0x000000FF\r
+#define IPG_RI_PRIORITY_THRESH          0x00001C00\r
+#define IPG_RI_RXDMAWAIT_TIME           0xFFFF0000\r
+\r
+/* end ipg_constants.h */\r
diff --git a/drivers/net/ip1000a/ipg_macros.h b/drivers/net/ip1000a/ipg_macros.h
new file mode 100644 (file)
index 0000000..0d0d31a
--- /dev/null
@@ -0,0 +1,462 @@
+/*\r
+ *\r
+ * ipg_macros.h\r
+ *\r
+ * Include file with macros for Gigabit Ethernet\r
+ * device driver for Network Interface Cards (NICs) utilizing the\r
+ * Tamarack Microelectronics Inc. IPG Gigabit or Triple Speed\r
+ * Ethernet Media Access Controller.\r
+ *\r
+ * Craig Rich\r
+ * Sundance Technology, Inc.\r
+ * 1485 Saratoga Avenue\r
+ * Suite 200\r
+ * San Jose, CA 95129\r
+ * 408 873 4117\r
+ * www.sundanceti.com\r
+ * craig_rich@sundanceti.com\r
+ *\r
+ * Rev  Date     Description\r
+ * --------------------------------------------------------------\r
+ * 0.1  3/30/01  New file created from original ipg.h\r
+ */\r
+\r
+/*\r
+ * Miscellaneous macros.\r
+ */\r
+\r
+/* Marco for printing debug statements.\r
+#  define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " ## args) */\r
+#ifdef IPG_DEBUG\r
+#  define IPG_DEBUG_MSG(args...) \r
+#  define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " args)\r
+#  define IPG_DUMPRFDLIST(args) ipg_dump_rfdlist(args)\r
+#  define IPG_DUMPTFDLIST(args) ipg_dump_tfdlist(args)\r
+#else\r
+#  define IPG_DEBUG_MSG(args...)\r
+#  define IPG_DDEBUG_MSG(args...)\r
+#  define IPG_DUMPRFDLIST(args)\r
+#  define IPG_DUMPTFDLIST(args)\r
+#endif\r
+\r
+/*\r
+ * End miscellaneous macros.\r
+ */\r
+\r
+/*\r
+ * Register access macros.\r
+ */\r
+\r
+#ifdef USE_IO_OPS\r
+\r
+/* Use I/O access for IPG registers. */\r
+\r
+#define RD8 inb\r
+#define RD16 inw\r
+#define RD32 inl\r
+#define WR8 outb\r
+#define WR16 outw\r
+#define WR32 outl\r
+\r
+#else\r
+\r
+/* Use memory access for IPG registers. */\r
+\r
+#define RD8 readb\r
+#define RD16 readw\r
+#define RD32 readl\r
+#define WR8 writeb\r
+#define WR16 writew\r
+#define WR32 writel\r
+\r
+#endif\r
+\r
+#define                IPG_READ_BYTEREG(regaddr)       RD8(regaddr)\r
+\r
+#define                IPG_READ_WORDREG(regaddr) RD16(regaddr)\r
+\r
+#define                IPG_READ_LONGREG(regaddr)       RD32(regaddr)\r
+\r
+#define                IPG_WRITE_BYTEREG(regaddr, writevalue)  WR8(writevalue, regaddr)\r
+\r
+#define                IPG_WRITE_WORDREG(regaddr, writevalue)  WR16(writevalue, regaddr)\r
+\r
+#define                IPG_WRITE_LONGREG(regaddr, writevalue)  WR32(writevalue, regaddr)\r
+\r
+#define                IPG_READ_ASICCTRL(baseaddr)     RD32(baseaddr + IPG_ASICCTRL)\r
+\r
+//Jesse20040128EEPROM_VALUE\r
+//#define              IPG_WRITE_ASICCTRL(baseaddr, writevalue)        WR32(IPG_AC_RSVD_MASK & (writevalue), baseaddr + IPG_ASICCTRL)\r
+#define                IPG_WRITE_ASICCTRL(baseaddr, writevalue)        WR32(writevalue, baseaddr + IPG_ASICCTRL)\r
+\r
+#define                IPG_READ_EEPROMCTRL(baseaddr)   RD16(baseaddr + IPG_EEPROMCTRL)\r
+\r
+#define                IPG_WRITE_EEPROMCTRL(baseaddr, writevalue)      WR16(IPG_EC_RSVD_MASK & (writevalue), baseaddr + IPG_EEPROMCTRL)\r
+\r
+#define                IPG_READ_EEPROMDATA(baseaddr)   RD16(baseaddr + IPG_EEPROMDATA)\r
+\r
+#define                IPG_WRITE_EEPROMDATA(baseaddr, writevalue)      WR16(writevalue, (baseaddr + IPG_EEPROMDATA)\r
+\r
+#define                IPG_READ_PHYSET(baseaddr)       RD8(baseaddr + IPG_PHYSET)//Jesse20040128EEPROM_VALUE\r
+\r
+#define                IPG_WRITE_PHYSET(baseaddr, writevalue)  WR8(writevalue, baseaddr + IPG_PHYSET)//Jesse20040128EEPROM_VALUE\r
+\r
+#define                IPG_READ_PHYCTRL(baseaddr)      RD8(baseaddr + IPG_PHYCTRL)\r
+\r
+#define                IPG_WRITE_PHYCTRL(baseaddr, writevalue) WR8(IPG_PC_RSVD_MASK & (writevalue), baseaddr + IPG_PHYCTRL)\r
+\r
+#define                IPG_READ_RECEIVEMODE(baseaddr)  RD8(baseaddr + IPG_RECEIVEMODE)\r
+\r
+#define                IPG_WRITE_RECEIVEMODE(baseaddr, writevalue)     WR8(IPG_RM_RSVD_MASK & (writevalue), baseaddr + IPG_RECEIVEMODE)\r
+\r
+#define                IPG_READ_MAXFRAMESIZE(baseaddr) RD16(baseaddr + IPG_MAXFRAMESIZE)\r
+\r
+#define                IPG_WRITE_MAXFRAMESIZE(baseaddr, writevalue)    WR16(writevalue, baseaddr + IPG_MAXFRAMESIZE)\r
+\r
+#define                IPG_READ_MACCTRL(baseaddr)      RD32(baseaddr + IPG_MACCTRL)\r
+\r
+#define                IPG_WRITE_MACCTRL(baseaddr, writevalue) WR32(IPG_MC_RSVD_MASK & (writevalue), baseaddr + IPG_MACCTRL)\r
+\r
+#define                IPG_READ_INTSTATUSACK(baseaddr) RD16(baseaddr + IPG_INTSTATUSACK)\r
+\r
+#define                IPG_READ_INTSTATUS(baseaddr)    RD16(baseaddr + IPG_INTSTATUS)\r
+\r
+#define                IPG_WRITE_INTSTATUS(baseaddr, writevalue)       WR16(IPG_IS_RSVD_MASK & (writevalue), baseaddr + IPG_INTSTATUS)\r
+\r
+#define                IPG_READ_INTENABLE(baseaddr)    RD16(baseaddr + IPG_INTENABLE)\r
+\r
+#define                IPG_WRITE_INTENABLE(baseaddr, writevalue)       WR16(IPG_IE_RSVD_MASK & (writevalue), baseaddr + IPG_INTENABLE)\r
+\r
+#define                IPG_READ_WAKEEVENT(baseaddr)    RD8(baseaddr + IPG_WAKEEVENT)\r
+\r
+#define                IPG_WRITE_WAKEEVENT(baseaddr, writevalue)       WR8(writevalue, baseaddr + IPG_WAKEEVENT)\r
+\r
+#define                IPG_READ_RXEARLYTHRESH(baseaddr)        RD16(baseaddr + IPG_RXEARLYTHRESH)\r
+\r
+#define                IPG_WRITE_RXEARLYTHRESH(baseaddr, writevalue)   WR16(IPG_RE_RSVD_MASK & (writevalue), baseaddr + IPG_RXEARLYTHRESH)\r
+\r
+#define                IPG_READ_TXSTARTTHRESH(baseaddr)        RD32(baseaddr + IPG_TXSTARTTHRESH)\r
+\r
+#define                IPG_WRITE_TXSTARTTHRESH(baseaddr, writevalue)   WR32(IPG_TT_RSVD_MASK & (writevalue), baseaddr + IPG_TXSTARTTHRESH)\r
+\r
+#define                IPG_READ_FIFOCTRL(baseaddr)     RD16(baseaddr + IPG_FIFOCTRL)\r
+\r
+#define                IPG_WRITE_FIFOCTRL(baseaddr, writevalue)        WR16(IPG_FC_RSVD_MASK & (writevalue), baseaddr + IPG_FIFOCTRL)\r
+\r
+#define                IPG_READ_RXDMAPOLLPERIOD(baseaddr)      RD8(baseaddr + IPG_RXDMAPOLLPERIOD)\r
+\r
+#define                IPG_WRITE_RXDMAPOLLPERIOD(baseaddr, writevalue) WR8(IPG_RP_RSVD_MASK & (writevalue), baseaddr + IPG_RXDMAPOLLPERIOD)\r
+\r
+#define                IPG_READ_RXDMAURGENTTHRESH(baseaddr)    RD8(baseaddr + IPG_RXDMAURGENTTHRESH)\r
+\r
+#define                IPG_WRITE_RXDMAURGENTTHRESH(baseaddr, writevalue)       WR8(IPG_RU_RSVD_MASK & (writevalue), baseaddr + IPG_RXDMAURGENTTHRESH)\r
+\r
+#define                IPG_READ_RXDMABURSTTHRESH(baseaddr)     RD8(baseaddr + IPG_RXDMABURSTTHRESH)\r
+\r
+#define                IPG_WRITE_RXDMABURSTTHRESH(baseaddr, writevalue)        WR8(writevalue, baseaddr + IPG_RXDMABURSTTHRESH)\r
+\r
+#define                IPG_READ_RFDLISTPTR0(baseaddr)  RD32(baseaddr + IPG_RFDLISTPTR0)\r
+\r
+#define                IPG_WRITE_RFDLISTPTR0(baseaddr, writevalue)     WR32(writevalue, baseaddr + IPG_RFDLISTPTR0)\r
+\r
+#define                IPG_READ_RFDLISTPTR1(baseaddr)  RD32(baseaddr + IPG_RFDLISTPTR1)\r
+\r
+#define                IPG_WRITE_RFDLISTPTR1(baseaddr, writevalue)     WR32(writevalue, baseaddr + IPG_RFDLISTPTR1)\r
+\r
+#define                IPG_READ_TXDMAPOLLPERIOD(baseaddr)      RD8(baseaddr + IPG_TXDMAPOLLPERIOD)\r
+\r
+#define                IPG_WRITE_TXDMAPOLLPERIOD(baseaddr, writevalue) WR8(IPG_TP_RSVD_MASK & (writevalue), baseaddr + IPG_TXDMAPOLLPERIOD)\r
+\r
+#define                IPG_READ_TXDMAURGENTTHRESH(baseaddr)    RD8(baseaddr + IPG_TXDMAURGENTTHRESH)\r
+\r
+#define                IPG_WRITE_TXDMAURGENTTHRESH(baseaddr, writevalue)       WR8(IPG_TU_RSVD_MASK & (writevalue), baseaddr + IPG_TXDMAURGENTTHRESH)\r
+\r
+#define                IPG_READ_TXDMABURSTTHRESH(baseaddr)     RD8(baseaddr + IPG_TXDMABURSTTHRESH)\r
+\r
+#define                IPG_WRITE_TXDMABURSTTHRESH(baseaddr, writevalue)        WR8(IPG_TB_RSVD_MASK & (writevalue), baseaddr + IPG_TXDMABURSTTHRESH)\r
+\r
+#define                IPG_READ_TFDLISTPTR0(baseaddr)  RD32(baseaddr + IPG_TFDLISTPTR0)\r
+\r
+#define                IPG_WRITE_TFDLISTPTR0(baseaddr, writevalue)     WR32(writevalue, baseaddr + IPG_TFDLISTPTR0)\r
+\r
+#define                IPG_READ_TFDLISTPTR1(baseaddr)  RD32(baseaddr + IPG_TFDLISTPTR1)\r
+\r
+#define                IPG_WRITE_TFDLISTPTR1(baseaddr, writevalue)     WR32(writevalue, baseaddr + IPG_TFDLISTPTR1)\r
+\r
+#define                IPG_READ_DMACTRL(baseaddr)      RD32(baseaddr + IPG_DMACTRL)\r
+\r
+#define                IPG_WRITE_DMACTRL(baseaddr, writevalue) WR32(IPG_DC_RSVD_MASK & (writevalue), baseaddr + IPG_DMACTRL)\r
+\r
+#define                IPG_READ_TXSTATUS(baseaddr)     RD32(baseaddr + IPG_TXSTATUS)\r
+\r
+#define                IPG_WRITE_TXSTATUS(baseaddr, writevalue)        WR32(IPG_TS_RSVD_MASK & (writevalue), baseaddr + IPG_TXSTATUS)\r
+\r
+#define                IPG_READ_STATIONADDRESS0(baseaddr)      RD16(baseaddr + IPG_STATIONADDRESS0)\r
+\r
+#define                IPG_READ_STATIONADDRESS1(baseaddr)      RD16(baseaddr + IPG_STATIONADDRESS1)\r
+\r
+#define                IPG_READ_STATIONADDRESS2(baseaddr)      RD16(baseaddr + IPG_STATIONADDRESS2)\r
+\r
+#define                IPG_WRITE_STATIONADDRESS0(baseaddr,writevalue)  WR16(writevalue,baseaddr + IPG_STATIONADDRESS0)//JES20040127EEPROM\r
+\r
+#define                IPG_WRITE_STATIONADDRESS1(baseaddr,writevalue)  WR16(writevalue,baseaddr + IPG_STATIONADDRESS1)//JES20040127EEPROM\r
+\r
+#define                IPG_WRITE_STATIONADDRESS2(baseaddr,writevalue)  WR16(writevalue,baseaddr + IPG_STATIONADDRESS2)//JES20040127EEPROM\r
+\r
+#define                IPG_READ_COUNTDOWN(baseaddr)    RD32(baseaddr + IPG_COUNTDOWN)\r
+\r
+#define                IPG_WRITE_COUNTDOWN(baseaddr, writevalue)       WR32(IPG_CD_RSVD_MASK & (writevalue), baseaddr + IPG_COUNTDOWN)\r
+\r
+#define                IPG_READ_RXDMASTATUS(baseaddr)  RD16(baseaddr + IPG_RXDMASTATUS)\r
+\r
+#define                IPG_WRITE_HASHTABLE0(baseaddr, writevalue)      WR32(writevalue, baseaddr + IPG_HASHTABLE0)\r
+\r
+#define                IPG_WRITE_HASHTABLE1(baseaddr, writevalue)      WR32(writevalue, baseaddr + IPG_HASHTABLE1)\r
+\r
+#define                IPG_READ_STATISTICSMASK(baseaddr)       RD32(baseaddr + IPG_STATISTICSMASK)\r
+\r
+#define                IPG_WRITE_STATISTICSMASK(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_STATISTICSMASK)\r
+\r
+#define                IPG_READ_RMONSTATISTICSMASK(baseaddr)   RD32(baseaddr + IPG_RMONSTATISTICSMASK)\r
+\r
+#define                IPG_WRITE_RMONSTATISTICSMASK(baseaddr, writevalue)      WR32(writevalue, baseaddr + IPG_RMONSTATISTICSMASK)\r
+\r
+#define                IPG_READ_VLANTAG(baseaddr)      RD32(baseaddr + IPG_VLANTAG)\r
+\r
+#define                IPG_WRITE_VLANTAG(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_VLANTAG)\r
+\r
+#define                IPG_READ_FLOWONTHRESH(baseaddr) RD16(baseaddr + IPG_FLOWONTHRESH)\r
+\r
+#define                IPG_WRITE_FLOWONTHRESH(baseaddr, writevalue)    WR16(writevalue, baseaddr + IPG_FLOWONTHRESH)\r
+\r
+#define                IPG_READ_FLOWOFFTHRESH(baseaddr)        RD16(baseaddr + IPG_FLOWOFFTHRESH)\r
+\r
+#define                IPG_WRITE_FLOWOFFTHRESH(baseaddr, writevalue)   WR16(writevalue, baseaddr + IPG_FLOWOFFTHRESH)\r
+\r
+#define                IPG_READ_DEBUGCTRL(baseaddr)    RD16(baseaddr + IPG_DEBUGCTRL)\r
+\r
+#define                IPG_WRITE_DEBUGCTRL(baseaddr, writevalue)       WR16(writevalue, baseaddr + IPG_DEBUGCTRL)\r
+\r
+#define                IPG_READ_RXDMAINTCTRL(baseaddr) RD32(baseaddr + IPG_RXDMAINTCTRL)\r
+\r
+#define                IPG_WRITE_RXDMAINTCTRL(baseaddr, writevalue)    WR32(writevalue, baseaddr + IPG_RXDMAINTCTRL)\r
+\r
+#define                IPG_READ_TXJUMBOFRAMES(baseaddr)        RD16(baseaddr + IPG_TXJUMBOFRAMES)\r
+\r
+#define                IPG_WRITE_TXJUMBOFRAMES(baseaddr, writevalue)   WR16(writevalue, baseaddr + IPG_TXJUMBOFRAMES)\r
+\r
+#define                IPG_READ_UDPCHECKSUMERRORS(baseaddr)    RD16(baseaddr + IPG_UDPCHECKSUMERRORS)\r
+\r
+#define                IPG_WRITE_UDPCHECKSUMERRORS(baseaddr, writevalue)       WR16(writevalue, baseaddr + IPG_UDPCHECKSUMERRORS)\r
+\r
+#define                IPG_READ_IPCHECKSUMERRORS(baseaddr)     RD16(baseaddr + IPG_IPCHECKSUMERRORS)\r
+\r
+#define                IPG_WRITE_IPCHECKSUMERRORS(baseaddr, writevalue)        WR16(writevalue, baseaddr + IPG_IPCHECKSUMERRORS)\r
+\r
+#define                IPG_READ_TCPCHECKSUMERRORS(baseaddr)    RD16(baseaddr + IPG_TCPCHECKSUMERRORS)\r
+\r
+#define                IPG_WRITE_TCPCHECKSUMERRORS(baseaddr, writevalue)       WR16(writevalue, baseaddr + IPG_TCPCHECKSUMERRORS)\r
+\r
+#define                IPG_READ_RXJUMBOFRAMES(baseaddr)        RD16(baseaddr + IPG_RXJUMBOFRAMES)\r
+\r
+#define                IPG_WRITE_RXJUMBOFRAMES(baseaddr, writevalue)   WR16(writevalue, baseaddr + IPG_RXJUMBOFRAMES)\r
+\r
+\r
+\r
+/* Statistic register read/write macros. */\r
+\r
+#define                IPG_READ_OCTETRCVOK(baseaddr)   RD32(baseaddr + IPG_OCTETRCVOK)\r
+\r
+#define                IPG_WRITE_OCTETRCVOK(baseaddr, writevalue)      WR32(writevalue, baseaddr + IPG_OCTETRCVOK)\r
+\r
+#define                IPG_READ_MCSTOCTETRCVDOK(baseaddr)      RD32(baseaddr + IPG_MCSTOCTETRCVDOK)\r
+\r
+#define                IPG_WRITE_MCSTOCTETRCVDOK(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_MCSTOCTETRCVDOK)\r
+\r
+#define                IPG_READ_BCSTOCTETRCVOK(baseaddr)       RD32(baseaddr + IPG_BCSTOCTETRCVOK)\r
+\r
+#define                IPG_WRITE_BCSTOCTETRCVOK(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_BCSTOCTETRCVOK)\r
+\r
+#define                IPG_READ_FRAMESRCVDOK(baseaddr) RD32(baseaddr + IPG_FRAMESRCVDOK)\r
+\r
+#define                IPG_WRITE_FRAMESRCVDOK(baseaddr, writevalue)    WR32(writevalue, baseaddr + IPG_FRAMESRCVDOK)\r
+\r
+#define                IPG_READ_MCSTFRAMESRCVDOK(baseaddr)     RD32(baseaddr + IPG_MCSTFRAMESRCVDOK)\r
+\r
+#define                IPG_WRITE_MCSTFRAMESRCVDOK(baseaddr, writevalue)        WR32(writevalue, baseaddr + IPG_MCSTFRAMESRCVDOK)\r
+\r
+#define                IPG_READ_BCSTFRAMESRCVDOK(baseaddr)     RD16(baseaddr + IPG_BCSTFRAMESRCVDOK)\r
+\r
+#define                IPG_WRITE_BCSTFRAMESRCVDOK(baseaddr, writevalue)        WR16(writevalue, baseaddr + IPG_BCSTFRAMESRCVDOK)\r
+\r
+#define                IPG_READ_MACCONTROLFRAMESRCVD(baseaddr) RD16(baseaddr + IPG_MACCONTROLFRAMESRCVD)\r
+\r
+#define                IPG_WRITE_MACCONTROLFRAMESRCVD(baseaddr, writevalue)    WR16(writevalue, baseaddr + IPG_MACCONTROLFRAMESRCVD)\r
+\r
+#define                IPG_READ_FRAMETOOLONGERRRORS(baseaddr)  RD16(baseaddr + IPG_FRAMETOOLONGERRRORS)\r
+\r
+#define                IPG_WRITE_FRAMETOOLONGERRRORS(baseaddr, writevalue)     WR16(writevalue, baseaddr + IPG_FRAMETOOLONGERRRORS)\r
+\r
+#define                IPG_READ_INRANGELENGTHERRORS(baseaddr)  RD16(baseaddr + IPG_INRANGELENGTHERRORS)\r
+\r
+#define                IPG_WRITE_INRANGELENGTHERRORS(baseaddr, writevalue)     WR16(writevalue, baseaddr + IPG_INRANGELENGTHERRORS)\r
+\r
+#define                IPG_READ_FRAMECHECKSEQERRORS(baseaddr)  RD16(baseaddr + IPG_FRAMECHECKSEQERRORS)\r
+\r
+#define                IPG_WRITE_FRAMECHECKSEQERRORS(baseaddr, writevalue)     WR16(writevalue, baseaddr + IPG_FRAMECHECKSEQERRORS)\r
+\r
+#define                IPG_READ_FRAMESLOSTRXERRORS(baseaddr)   RD16(baseaddr + IPG_FRAMESLOSTRXERRORS)\r
+\r
+#define                IPG_WRITE_FRAMESLOSTRXERRORS(baseaddr, writevalue) WR16(writevalue, baseaddr + IPG_FRAMESLOSTRXERRORS)\r
+\r
+#define                IPG_READ_FRAMESLOSTRXERRORS(baseaddr)   RD16(baseaddr + IPG_FRAMESLOSTRXERRORS)\r
+\r
+#define                IPG_WRITE_FRAMESLOSTRXERRORS(baseaddr, writevalue)      WR16(writevalue, baseaddr + IPG_FRAMESLOSTRXERRORS)\r
+\r
+#define                IPG_READ_OCTETXMTOK(baseaddr)   RD32(baseaddr + IPG_OCTETXMTOK)\r
+\r
+#define                IPG_WRITE_OCTETXMTOK(baseaddr, writevalue)      WR32(writevalue, baseaddr + IPG_OCTETXMTOK)\r
+\r
+#define                IPG_READ_MCSTOCTETXMTOK(baseaddr)       RD32(baseaddr + IPG_MCSTOCTETXMTOK)\r
+\r
+#define                IPG_WRITE_MCSTOCTETXMTOK(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_MCSTOCTETXMTOK)\r
+\r
+#define                IPG_READ_BCSTOCTETXMTOK(baseaddr)       RD32(baseaddr + IPG_BCSTOCTETXMTOK)\r
+\r
+#define                IPG_WRITE_BCSTOCTETXMTOK(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_BCSTOCTETXMTOK)\r
+\r
+#define                IPG_READ_FRAMESXMTDOK(baseaddr) RD32(baseaddr + IPG_FRAMESXMTDOK)\r
+\r
+#define                IPG_WRITE_FRAMESXMTDOK(baseaddr, writevalue)    WR32(writevalue, baseaddr + IPG_FRAMESXMTDOK)\r
+\r
+#define                IPG_READ_MCSTFRAMESXMTDOK(baseaddr)     RD32(baseaddr + IPG_MCSTFRAMESXMTDOK)\r
+\r
+#define                IPG_WRITE_MCSTFRAMESXMTDOK(baseaddr, writevalue)        WR32(writevalue, baseaddr + IPG_MCSTFRAMESXMTDOK)\r
+\r
+#define                IPG_READ_FRAMESWDEFERREDXMT(baseaddr)   RD32(baseaddr + IPG_FRAMESWDEFERREDXMT)\r
+\r
+#define                IPG_WRITE_FRAMESWDEFERREDXMT(baseaddr, writevalue)      WR32(writevalue, baseaddr + IPG_FRAMESWDEFERREDXMT)\r
+\r
+#define                IPG_READ_LATECOLLISIONS(baseaddr)       RD32(baseaddr + IPG_LATECOLLISIONS)\r
+\r
+#define                IPG_WRITE_LATECOLLISIONS(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_LATECOLLISIONS)\r
+\r
+#define                IPG_READ_MULTICOLFRAMES(baseaddr)       RD32(baseaddr + IPG_MULTICOLFRAMES)\r
+\r
+#define                IPG_WRITE_MULTICOLFRAMES(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_MULTICOLFRAMES)\r
+\r
+#define                IPG_READ_SINGLECOLFRAMES(baseaddr)      RD32(baseaddr + IPG_SINGLECOLFRAMES)\r
+\r
+#define                IPG_WRITE_SINGLECOLFRAMES(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_SINGLECOLFRAMES)\r
+\r
+#define                IPG_READ_BCSTFRAMESXMTDOK(baseaddr)     RD16(baseaddr + IPG_BCSTFRAMESXMTDOK)\r
+\r
+#define                IPG_WRITE_BCSTFRAMESXMTDOK(baseaddr, writevalue)        WR16(writevalue, baseaddr + IPG_BCSTFRAMESXMTDOK)\r
+\r
+#define                IPG_READ_CARRIERSENSEERRORS(baseaddr)   RD16(baseaddr + IPG_CARRIERSENSEERRORS)\r
+\r
+#define                IPG_WRITE_CARRIERSENSEERRORS(baseaddr, writevalue)      WR16(writevalue, baseaddr + IPG_CARRIERSENSEERRORS)\r
+\r
+#define                IPG_READ_MACCONTROLFRAMESXMTDOK(baseaddr)       RD16(baseaddr + IPG_MACCONTROLFRAMESXMTDOK)\r
+\r
+#define                IPG_WRITE_MACCONTROLFRAMESXMTDOK(baseaddr, writevalue) WR16(writevalue, baseaddr + IPG_MACCONTROLFRAMESXMTDOK)\r
+\r
+#define                IPG_READ_FRAMESABORTXSCOLLS(baseaddr)   RD16(baseaddr + IPG_FRAMESABORTXSCOLLS)\r
+\r
+#define                IPG_WRITE_FRAMESABORTXSCOLLS(baseaddr, writevalue)      WR16(writevalue, baseaddr + IPG_FRAMESABORTXSCOLLS)\r
+\r
+#define                IPG_READ_FRAMESWEXDEFERRAL(baseaddr)    RD16(baseaddr + IPG_FRAMESWEXDEFERRAL)\r
+\r
+#define                IPG_WRITE_FRAMESWEXDEFERRAL(baseaddr, writevalue)       WR16(writevalue, baseaddr + IPG_FRAMESWEXDEFERRAL)\r
+\r
+/* RMON statistic register read/write macros. */\r
+\r
+#define                IPG_READ_ETHERSTATSCOLLISIONS(baseaddr) RD32(baseaddr + IPG_ETHERSTATSCOLLISIONS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSCOLLISIONS(baseaddr, writevalue)    WR32(writevalue, baseaddr + IPG_ETHERSTATSCOLLISIONS)\r
+\r
+#define                IPG_READ_ETHERSTATSOCTETSTRANSMIT(baseaddr)     RD32(baseaddr + IPG_ETHERSTATSOCTETSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSOCTETSTRANSMIT(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_ETHERSTATSOCTETSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTSTRANSMIT(baseaddr)       RD32(baseaddr + IPG_ETHERSTATSPKTSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTSTRANSMIT(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS64OCTESTSTRANSMIT(baseaddr)      RD32(baseaddr + IPG_ETHERSTATSPKTS64OCTESTSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS64OCTESTSTRANSMIT(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS64OCTESTSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS65TO127OCTESTSTRANSMIT(baseaddr) RD32(baseaddr + IPG_ETHERSTATSPKTS65TO127OCTESTSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS65TO127OCTESTSTRANSMIT(baseaddr, writevalue)    WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS65TO127OCTESTSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS128TO255OCTESTSTRANSMIT(baseaddr)        RD32(baseaddr + IPG_ETHERSTATSPKTS128TO255OCTESTSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS128TO255OCTESTSTRANSMIT(baseaddr, writevalue)   WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS128TO255OCTESTSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS256TO511OCTESTSTRANSMIT(baseaddr) RD32(baseaddr + IPG_ETHERSTATSPKTS256TO511OCTESTSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS256TO511OCTESTSTRANSMIT(baseaddr, writevalue)   WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS256TO511OCTESTSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS512TO1023OCTESTSTRANSMIT(baseaddr) RD32(baseaddr + IPG_ETHERSTATSPKTS512TO1023OCTESTSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS512TO1023OCTESTSTRANSMIT(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS512TO1023OCTESTSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS1024TO1518OCTESTSTRANSMIT(baseaddr) RD32(baseaddr + IPG_ETHERSTATSPKTS1024TO1518OCTESTSTRANSMIT)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS1024TO1518OCTESTSTRANSMIT(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS1024TO1518OCTESTSTRANSMIT)\r
+\r
+#define                IPG_READ_ETHERSTATSCRCALIGNERRORS(baseaddr)     RD32(baseaddr + IPG_ETHERSTATSCRCALIGNERRORS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSCRCALIGNERRORS(baseaddr, writevalue)        WR32(writevalue, baseaddr + IPG_ETHERSTATSCRCALIGNERRORS)\r
+\r
+#define                IPG_READ_ETHERSTATSUNDERSIZEPKTS(baseaddr)      RD32(baseaddr + IPG_ETHERSTATSUNDERSIZEPKTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSUNDERSIZEPKTS(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_ETHERSTATSUNDERSIZEPKTS)\r
+\r
+#define                IPG_READ_ETHERSTATSFRAGMENTS(baseaddr)  RD32(baseaddr + IPG_ETHERSTATSFRAGMENTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSFRAGMENTS(baseaddr, writevalue)     WR32(writevalue, baseaddr + IPG_ETHERSTATSFRAGMENTS)\r
+\r
+#define                IPG_READ_ETHERSTATSJABBERS(baseaddr)    RD32(baseaddr + IPG_ETHERSTATSJABBERS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSJABBERS(baseaddr, writevalue)       WR32(writevalue, baseaddr + IPG_ETHERSTATSJABBERS)\r
+\r
+#define                IPG_READ_ETHERSTATSOCTETS(baseaddr)     RD32(baseaddr + IPG_ETHERSTATSOCTETS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSOCTETS(baseaddr, writevalue)        WR32(writevalue, baseaddr + IPG_ETHERSTATSOCTETS)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS(baseaddr)       RD32(baseaddr + IPG_ETHERSTATSPKTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS64OCTESTS(baseaddr)      RD32(baseaddr + IPG_ETHERSTATSPKTS64OCTESTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS64OCTESTS(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS64OCTESTS)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS65TO127OCTESTS(baseaddr) RD32(baseaddr + IPG_ETHERSTATSPKTS65TO127OCTESTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS65TO127OCTESTS(baseaddr, writevalue)    WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS65TO127OCTESTS)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS128TO255OCTESTS(baseaddr)        RD32(baseaddr + IPG_ETHERSTATSPKTS128TO255OCTESTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS128TO255OCTESTS(baseaddr, writevalue)   WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS128TO255OCTESTS)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS256TO511OCTESTS(baseaddr)        RD32(baseaddr + IPG_ETHERSTATSPKTS256TO511OCTESTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS256TO511OCTESTS(baseaddr, writevalue)   WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS256TO511OCTESTS)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS512TO1023OCTESTS(baseaddr)       RD32(baseaddr + IPG_ETHERSTATSPKTS512TO1023OCTESTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS512TO1023OCTESTS(baseaddr, writevalue)  WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS512TO1023OCTESTS)\r
+\r
+#define                IPG_READ_ETHERSTATSPKTS1024TO1518OCTESTS(baseaddr)      RD32(baseaddr + IPG_ETHERSTATSPKTS1024TO1518OCTESTS)\r
+\r
+#define                IPG_WRITE_ETHERSTATSPKTS1024TO1518OCTESTS(baseaddr, writevalue) WR32(writevalue, baseaddr + IPG_ETHERSTATSPKTS1024TO1518OCTESTS)\r
+\r
+/*\r
+ * End register access macros.\r
+ */\r
+\r
+/* end ipg_macros.h */\r
diff --git a/drivers/net/ip1000a/ipg_main.c b/drivers/net/ip1000a/ipg_main.c
new file mode 100644 (file)
index 0000000..11223c7
--- /dev/null
@@ -0,0 +1,4289 @@
+/*PCI_DEVICE_ID_IP1000\r
+ *\r
+ * ipg.c\r
+ *\r
+ * IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver v2.01   \r
+ * by IC Plus Corp. 2003                     \r
+ *\r
+ * Craig Rich\r
+ * Sundance Technology, Inc.\r
+ * 1485 Saratoga Avenue\r
+ * Suite 200\r
+ * San Jose, CA 95129\r
+ * 408 873 4117\r
+ * www.sundanceti.com\r
+ * craig_rich@sundanceti.com\r
+ *\r
+ * Rev  Date     Description\r
+ * --------------------------------------------------------------\r
+ * 0.1  11/8/99  Initial revision work begins.\r
+ *\r
+ * 0.2  11/12/99  Basic operation achieved, continuing work.\r
+ *\r
+ * 0.3  11/19/99  MAC Loop Back for sync problem testing.\r
+ *\r
+ * 0.4  12/22/99  ioctl for diagnotic program 'hunter' support.\r
+ *\r
+ * 0.5  4/13/00   Updates to\r
+ *\r
+ * 0.6  6/14/00   Slight correction to handling TFDDONE, and\r
+ *                preservation of PHYCTRL polarity bits.\r
+ *\r
+ * 0.7  7/27/00   Modifications to accomodate triple speed\r
+ *                autonegotiation. Also change to ioctl routine\r
+ *                to handle unknown PHY address.\r
+ *\r
+ * 0.8  8/11/00   Added change_mtu function.\r
+ *\r
+ * 0.9  8/15/00   Corrected autonegotiation resolution.\r
+ *\r
+ * 0.10 8/30/00   Changed constants to use IPG in place\r
+ *                of RIO. Also, removed most of debug\r
+ *                code in preparation for production release.\r
+ *\r
+ * 0.11 8/31/00   Utilize 64 bit data types where appropriate.\r
+ *\r
+ * 0.12 9/1/00    Move some constants to include file and utilize\r
+ *                RxDMAInt register.\r
+ *\r
+ * 0.13 10/31/00  Several minor modifications to improve stability.\r
+ *\r
+ * 0.14 11/28/00  Added call to nic_tx_free if TFD not available.\r
+ *\r
+ * 0.15 12/5/00   Corrected problem with receive errors, always set\r
+ *                receive buffer address to NULL. Release RX buffers\r
+ *                on errors.\r
+ *\r
+ * 0.16 12/20/00  Corrected autoneg resolution issue, must detect\r
+ *                speed via PHYCTRL register. Also, perform only 1\r
+ *                loop in the nic_txcleanup routine.\r
+ *\r
+ * 0.17 2/7/01    Changed all references of ST2021 to IPG.\r
+ *                When next TFD not available, return -ENOMEM instead\r
+ *                of 0. Removed references to RUBICON.\r
+ *\r
+ * 0.18 2/14/01   Corrected problem when unexpected jumbo frames are\r
+ *                received (now dropped properly.) Changed\r
+ *                "DROP_ON_ERRORS" breaking out Ethernet errors and\r
+ *                TCP/IP errors serparately. Corrected Gigabit\r
+ *                copper PAUSE autonegotiation.\r
+ *\r
+ * 0.19 2/22/01   Changed interrupt handling of RFD_LIST_END,\r
+ *                INT_REQUESTED, and RX_DMA_COMPLETE. Masked off\r
+ *                RMON statistics and unused MIB statistics.\r
+ *                Make sure *all* statistics are accounted for\r
+ *                (either masked or read in get_stats) to avoid\r
+ *                perpetual UpdateStats interrupt from causing\r
+ *                driver to crash.\r
+ *\r
+ * 0.20 3/2/01    Corrected error in nic_stop. Need to set\r
+ *                TxBuff[] = NULL after freeing TxBuff and\r
+ *                RxBuff[] = NULL after freeing RxBuff.\r
+ *\r
+ * 0.21 3/5/01    Correct 10/100Mbit PAUSE autonegotiation.\r
+ *\r
+ * 0.22 3/16/01   Used TxDMAIndicate for 100/1000Mbps modes. Add\r
+ *                "TFD unavailable" and "RFD list end" counters\r
+ *                to assist with performance measurement. Added\r
+ *                check for maxtfdcnt != 0 to while loop within\r
+ *                txcleanup.\r
+ *\r
+ * 0.23 3/22/01   Set the CurrentTxFrameID to 1 upon detecting\r
+ *                a TxDMAComplete to reduce the number of TxDMAComplete.\r
+ *                Also, indicate IP/TCP/UDP checksum is unneseccary\r
+ *                if IPG indicates checksum validates.\r
+ *\r
+ * 0.24 3/23/01   Changed the txfree routine, eliminating the margin\r
+ *                between the last freed TFD and the current TFD.\r
+ *\r
+ * 0.25 4/3/01    Corrected errors in config_autoneg to deal with\r
+ *                fiber flag properly.\r
+ *\r
+ * 0.26 5/1/01    Port for operation with Linux 2.2 or 2.4 kernel.\r
+ *\r
+ * 0.27 5/22/01   Cleaned up some extraneous comments.\r
+ *\r
+ * 0.28 6/20/01   Added auto IP, TCP, and UDP checksum addition\r
+ *                on transmit based on compilation option.\r
+ *\r
+ * 0.29 7/26/01   Comment out #include <asm/spinlock.h> from ipg.h\r
+ *                for compatibility with RedHat 7.1. Unkown reason.\r
+ *\r
+ * 0.30 8/10/01   Added debug message to each function, print function\r
+ *                name when entered. Added DEBUGCTRL register bit 5 for\r
+ *                Rx DMA Poll Now bug work around. Added ifdef IPG_DEBUG\r
+ *                flags to IPG_TFDlistunabvail and IPG_RFDlistend\r
+ *                counters. Removed clearing of sp->stat struct from\r
+ *                nic_open and added check in get_stats to make sure\r
+ *                NIC is initialized before reading statistic registers.\r
+ *                Corrected erroneous MACCTRL setting for Fiber based\r
+ *                10/100 boards. Corrected storage of phyctrlpolarity\r
+ *                variable.\r
+ *\r
+ * 0.31 8/13/01   Incorporate STI or TMI fiber based NIC detection.\r
+ *                Corrected problem with _pciremove_linux2_4 routine.\r
+ *                Corrected setting of IP/TCP/UDP checksumming on receive\r
+ *                and transmit.\r
+ *\r
+ * 0.32 8/15/01   Changed the tmi_fiber_detect routine.\r
+ *\r
+ * 0.33 8/16/01   Changed PHY reset method in nic_open routine. Added\r
+ *                a chip reset in nic_stop to shut down the IPG.\r
+ *\r
+ * 0.34 9/5/01    Corrected some misuage of dev_kfree_skb.\r
+ *\r
+ * 0.35 10/30/01  Unmap register space (IO or memory) in the nic_stop\r
+ *                routine instead of in the cleanup or remove routines.\r
+ *                Corrects driver up/down/up problem when using IO\r
+ *                register mapping.\r
+ *\r
+ * 0.36 10/31/01  Modify the constant IPG_FRAMESBETWEENTXDMACOMPLETES\r
+ *               from 0x10 to 1.\r
+ * 0.37 11/05/03  Modify the IPG_PHY_1000BASETCONTROL\r
+ *                               in IP1000A this register is without 1000BPS Ability by default\r
+ *                               so enable 1000BPS ability before PHY RESET/RESTART_AN\r
+ * 0.38 11/05/03  update ipg_config_autoneg routine\r
+ * 0.39 11/05/03  add Vendor_ID=13F0/Device_ID=1023 into support_cards\r
+ * 2.05 10/16/04  Remove IPG_IE_RFD_LIST_END for pass SmartBit test.\r
+ *                (see 20041019Jesse_For_SmartBit.)\r
+ * 2.06 10/27/04 Support for kernel 2.6.x\r
+ * 2.06a 11/03/04 remove some compile warring message.\r
+ * 2.09b 06/03/05 Support 4k jumbo  (IC Plus, Jesse)\r
+ * 2.09d 06/22/05 Support 10k jumbo, more than 4k will using copy mode (IC Plus, Jesse)\r
+ */\r
+#define JUMBO_FRAME_4k_ONLY\r
+enum {\r
+       netdev_io_size = 128\r
+};\r
+\r
+#include "ipg.h"\r
+#define DRV_NAME       "ipg"\r
+/* notify kernel that this software is under GNU Public License */\r
+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10) )\r
+    MODULE_LICENSE("GPL");\r
+#endif\r
+\r
+/* Function prototypes. */\r
+u16     read_phy_register(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                          int phy_address, int phy_register);\r
+//int     ipg_reset(u32 baseaddr, u32 resetflags); //JES20040127EEPROM: change type of param1\r
+int     ipg_reset(IPG_DEVICE_TYPE *ipg_ethernet_device, u32 resetflags);\r
+int     ipg_io_config(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+void    ipg_interrupt_handler(int ipg_irq, void *device_instance,\r
+                                struct pt_regs *regs);\r
+#else\r
+static  irqreturn_t  ipg_interrupt_handler(int ipg_irq, void *device_instance,\r
+                                struct pt_regs *regs);\r
+#endif\r
+\r
+void    ipg_nic_txcleanup(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+void   ipg_nic_txfree(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int     ipg_nic_open(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int     ipg_nic_stop(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int     ipg_nic_hard_start_xmit(struct sk_buff *skb,\r
+                                   IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+IPG_STATS_TYPE* ipg_nic_get_stats(IPG_DEVICE_TYPE\r
+                                        *ipg_ethernet_device);\r
+void ipg_nic_set_multicast_list(IPG_DEVICE_TYPE *dev);\r
+int ipg_nic_init(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int ipg_nic_rx(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int ipg_nic_rxrestore(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int init_rfdlist(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int init_tfdlist(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int ipg_get_rxbuff(IPG_DEVICE_TYPE *ipg_ethernet_device, int rfd);\r
+int ipg_sti_fiber_detect(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+int ipg_tmi_fiber_detect(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                            int phyaddr);\r
+int ipg_config_autoneg(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+unsigned ether_crc_le(int length, unsigned char *data);\r
+int ipg_nic_do_ioctl(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                        struct ifreq *req, int cmd);\r
+int ipg_nic_change_mtu(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                          int new_mtu);\r
+\r
+#ifdef IPG_LINUX2_2\r
+int ipg_pcibussearch_linux2_2(void);\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+int ipg_pciprobe_linux2_4(struct pci_dev*, const struct pci_device_id*);\r
+void ipg_pciremove_linux2_4(struct pci_dev*);\r
+#endif\r
+\r
+void bSetPhyDefaultParam(unsigned char Rev,\r
+               IPG_DEVICE_TYPE *ipg_ethernet_device,int phy_address);\r
+\r
+//JES20040127EEPROM:Add three new function\r
+int read_eeprom(IPG_DEVICE_TYPE *ipg_ethernet_device, int eep_addr);\r
+void Set_LED_Mode(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+void Set_PHYSet(IPG_DEVICE_TYPE *ipg_ethernet_device);\r
+/* End function prototypes. */\r
+\r
+#ifdef IPG_DEBUG\r
+void ipg_dump_rfdlist(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       u32                             baseaddr;\r
+       int                             i;\r
+       u32                             offset;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_dump_rfdlist\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       printk(KERN_INFO "CurrentRFD         = %2.2x\n", sp->CurrentRFD);\r
+       printk(KERN_INFO "LastRestoredRxBuff = %2.2x\n",\r
+              sp->LastRestoredRxBuff);\r
+#ifdef IPG_LINUX2_2\r
+       printk(KERN_INFO "RFDList start address = %16.16lx\n",\r
+              (unsigned long int)(IPG_HOST2BUS_MAP(sp->RFDList)));\r
+#endif\r
+#ifdef IPG_LINUX2_4\r
+       printk(KERN_INFO "RFDList start address = %16.16lx\n",\r
+              (unsigned long int)(sp->RFDListDMAhandle));\r
+#endif\r
+       printk(KERN_INFO "RFDListPtr register   = %8.8x%8.8x\n",\r
+              IPG_READ_RFDLISTPTR1(baseaddr),\r
+              IPG_READ_RFDLISTPTR0(baseaddr));\r
+\r
+       for(i=0;i<IPG_RFDLIST_LENGTH;i++)\r
+       {\r
+               offset = (u32)(&sp->RFDList[i].RFDNextPtr)\r
+                        - (u32)(sp->RFDList);\r
+               printk(KERN_INFO "%2.2x %4.4x RFDNextPtr = %16.16lx\n", i,\r
+                      offset, (unsigned long int) sp->RFDList[i].RFDNextPtr);\r
+               offset = (u32)(&sp->RFDList[i].RFS)\r
+                        - (u32)(sp->RFDList);\r
+               printk(KERN_INFO "%2.2x %4.4x RFS        = %16.16lx\n", i,\r
+                      offset, (unsigned long int)sp->RFDList[i].RFS);\r
+               offset = (u32)(&sp->RFDList[i].FragInfo)\r
+                        - (u32)(sp->RFDList);\r
+               printk(KERN_INFO "%2.2x %4.4x FragInfo   = %16.16lx\n", i,\r
+                      offset, (unsigned long int)sp->RFDList[i].FragInfo);\r
+       }\r
+\r
+       return;\r
+}\r
+\r
+void ipg_dump_tfdlist(IPG_DEVICE_TYPE  *ipg_ethernet_device)\r
+{\r
+       u32                             baseaddr;\r
+       int                             i;\r
+       u32                             offset;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_dump_tfdlist\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       printk(KERN_INFO "CurrentTFD         = %2.2x\n", sp->CurrentTFD);\r
+       printk(KERN_INFO "LastFreedTxBuff = %2.2x\n",\r
+              sp->LastFreedTxBuff);\r
+#ifdef IPG_LINUX2_2\r
+       printk(KERN_INFO "TFDList start address = %16.16lx\n",\r
+              (unsigned long int)(IPG_HOST2BUS_MAP(sp->TFDList)));\r
+#endif\r
+#ifdef IPG_LINUX2_4\r
+       printk(KERN_INFO "TFDList start address = %16.16lx\n",\r
+              (unsigned long int)(sp->TFDListDMAhandle));\r
+#endif\r
+       printk(KERN_INFO "TFDListPtr register   = %8.8x%8.8x\n",\r
+              IPG_READ_TFDLISTPTR1(baseaddr),\r
+              IPG_READ_TFDLISTPTR0(baseaddr));\r
+\r
+       for(i=0;i<IPG_TFDLIST_LENGTH;i++)\r
+       {\r
+               offset = (u32)(&sp->TFDList[i].TFDNextPtr)\r
+                        - (u32)(sp->TFDList);\r
+               printk(KERN_INFO "%2.2x %4.4x TFDNextPtr = %16.16lx\n", i,\r
+                      offset, (unsigned long int)sp->TFDList[i].TFDNextPtr);\r
+\r
+               offset = (u32)(&sp->TFDList[i].TFC)\r
+                        - (u32)(sp->TFDList);\r
+               printk(KERN_INFO "%2.2x %4.4x TFC        = %16.16lx\n", i,\r
+                      offset, (unsigned long int)sp->TFDList[i].TFC);\r
+               offset = (u32)(&sp->TFDList[i].FragInfo)\r
+                        - (u32)(sp->TFDList);\r
+               printk(KERN_INFO "%2.2x %4.4x FragInfo   = %16.16lx\n", i,\r
+                      offset, (unsigned long int)sp->TFDList[i].FragInfo);\r
+       }\r
+\r
+       return;\r
+}\r
+#else /* Not in debug mode. */\r
+#endif\r
+\r
+void send_three_state(u32 baseaddr, u8 phyctrlpolarity)\r
+{\r
+       IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_LO |\r
+                                                       (IPG_PC_MGMTDATA & 0) |\r
+                                    IPG_PC_MGMTDIR | phyctrlpolarity);\r
+\r
+       mdelay(IPG_PC_PHYCTRLWAIT);\r
+\r
+       IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_HI |\r
+                                    (IPG_PC_MGMTDATA & 0) |\r
+                                    IPG_PC_MGMTDIR | phyctrlpolarity);\r
+\r
+       mdelay(IPG_PC_PHYCTRLWAIT);\r
+       return;\r
+}\r
+\r
+void send_end(u32 baseaddr, u8 phyctrlpolarity)\r
+{\r
+       IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_LO |\r
+                                                       (IPG_PC_MGMTDATA & 0) |\r
+                                    IPG_PC_MGMTDIR | phyctrlpolarity);\r
+       return;\r
+}\r
+\r
+\r
+u16 read_phy_bit(u32 baseaddr, u8 phyctrlpolarity)\r
+{   u16 bit_data;\r
+       IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_LO |\r
+                                    phyctrlpolarity);\r
+\r
+       mdelay(IPG_PC_PHYCTRLWAIT);\r
+\r
+       bit_data=((IPG_READ_PHYCTRL(baseaddr) & IPG_PC_MGMTDATA) >> 1) & 1;\r
+\r
+       IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_HI |\r
+                                    phyctrlpolarity);\r
+\r
+       mdelay(IPG_PC_PHYCTRLWAIT);\r
+       return bit_data;\r
+}\r
+\r
+u16    read_phy_register(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                         int phy_address, int phy_register)\r
+{\r
+       /* Read a register from the Physical Layer device located\r
+        * on the IPG NIC, using the IPG PHYCTRL register.\r
+        */\r
+\r
+       u32     baseaddr;\r
+       int     i;\r
+       int     j;\r
+       int     fieldlen[8];\r
+       u32     field[8];\r
+       u8      databit;\r
+        u8      phyctrlpolarity;\r
+\r
+       IPG_DEBUG_MSG("read_phy_register\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       /* The GMII mangement frame structure for a read is as follows:\r
+        *\r
+        * |Preamble|st|op|phyad|regad|ta|      data      |idle|\r
+        * |< 32 1s>|01|10|AAAAA|RRRRR|z0|DDDDDDDDDDDDDDDD|z   |\r
+        *\r
+        * <32 1s> = 32 consecutive logic 1 values\r
+        * A = bit of Physical Layer device address (MSB first)\r
+        * R = bit of register address (MSB first)\r
+        * z = High impedance state\r
+        * D = bit of read data (MSB first)\r
+        *\r
+        * Transmission order is 'Preamble' field first, bits transmitted\r
+        * left to right (first to last).\r
+        */\r
+\r
+       field[0]    = GMII_PREAMBLE;\r
+       fieldlen[0] = 32;               /* Preamble */\r
+       field[1]    = GMII_ST;\r
+       fieldlen[1] = 2;                /* ST */\r
+       field[2]    = GMII_READ;\r
+       fieldlen[2] = 2;                /* OP */\r
+       field[3]    = phy_address;\r
+       fieldlen[3] = 5;                /* PHYAD */\r
+       field[4]    = phy_register;\r
+       fieldlen[4] = 5;                /* REGAD */\r
+       field[5]    = 0x0000;\r
+       fieldlen[5] = 2;                /* TA */\r
+       field[6]    = 0x0000;\r
+       fieldlen[6] = 16;               /* DATA */\r
+       field[7]    = 0x0000;\r
+       fieldlen[7] = 1;                /* IDLE */\r
+\r
+        /* Store the polarity values of PHYCTRL. */\r
+        phyctrlpolarity = IPG_READ_PHYCTRL(baseaddr) &\r
+                          (IPG_PC_DUPLEX_POLARITY |\r
+                          IPG_PC_LINK_POLARITY);\r
+\r
+       /* Create the Preamble, ST, OP, PHYAD, and REGAD field. */\r
+       for(j=0; j<5; j++)\r
+       for(i=0; i<fieldlen[j]; i++)\r
+       {\r
+               /* For each variable length field, the MSB must be\r
+                * transmitted first. Rotate through the field bits,\r
+                * starting with the MSB, and move each bit into the\r
+                * the 1st (2^1) bit position (this is the bit position\r
+                * corresponding to the MgmtData bit of the PhyCtrl\r
+                * register for the IPG).\r
+                *\r
+                * Example: ST = 01;\r
+                *\r
+                *          First write a '0' to bit 1 of the PhyCtrl\r
+                *          register, then write a '1' to bit 1 of the\r
+                *          PhyCtrl register.\r
+                *\r
+                * To do this, right shift the MSB of ST by the value:\r
+                * [field length - 1 - #ST bits already written]\r
+                * then left shift this result by 1.\r
+                */\r
+               databit = (field[j] >> (fieldlen[j] - 1 - i)) << 1;\r
+\r
+               IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_LO |\r
+                                    (IPG_PC_MGMTDATA & databit) |\r
+                                    IPG_PC_MGMTDIR | phyctrlpolarity);\r
+\r
+               mdelay(IPG_PC_PHYCTRLWAIT);\r
+\r
+               IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_HI |\r
+                                    (IPG_PC_MGMTDATA & databit) |\r
+                                    IPG_PC_MGMTDIR | phyctrlpolarity);\r
+\r
+               mdelay(IPG_PC_PHYCTRLWAIT);\r
+       }\r
+\r
+       send_three_state(baseaddr, phyctrlpolarity);\r
+\r
+       read_phy_bit(baseaddr, phyctrlpolarity);\r
+\r
+       /* For a read cycle, the bits for the next two fields (TA and\r
+        * DATA) are driven by the PHY (the IPG reads these bits).\r
+        */\r
+//     for(j=6; j<8; j++)\r
+       for(i=0; i<fieldlen[6]; i++)\r
+       {\r
+               field[6] |= (read_phy_bit(baseaddr, phyctrlpolarity) << (fieldlen[6]- 1 - i));\r
+\r
+       }\r
+\r
+       send_three_state(baseaddr, phyctrlpolarity);\r
+       send_three_state(baseaddr, phyctrlpolarity);\r
+       send_three_state(baseaddr, phyctrlpolarity);\r
+       send_end(baseaddr, phyctrlpolarity);\r
+\r
+       /* Return the value of the DATA field. */\r
+       return field[6];\r
+}\r
+\r
+void   write_phy_register(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                         int phy_address, int phy_register, u16 writeval)\r
+{\r
+       /* Write to a register from the Physical Layer device located\r
+        * on the IPG NIC, using the IPG PHYCTRL register.\r
+        */\r
+\r
+       u32     baseaddr;\r
+       int     i;\r
+       int     j;\r
+       int     fieldlen[8];\r
+       u32     field[8];\r
+       u8      databit;\r
+       u8      phyctrlpolarity;\r
+\r
+       IPG_DEBUG_MSG("write_phy_register\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       /* The GMII mangement frame structure for a read is as follows:\r
+        *\r
+        * |Preamble|st|op|phyad|regad|ta|      data      |idle|\r
+        * |< 32 1s>|01|10|AAAAA|RRRRR|z0|DDDDDDDDDDDDDDDD|z   |\r
+        *\r
+        * <32 1s> = 32 consecutive logic 1 values\r
+        * A = bit of Physical Layer device address (MSB first)\r
+        * R = bit of register address (MSB first)\r
+        * z = High impedance state\r
+        * D = bit of write data (MSB first)\r
+        *\r
+        * Transmission order is 'Preamble' field first, bits transmitted\r
+        * left to right (first to last).\r
+        */\r
+\r
+       field[0]    = GMII_PREAMBLE;\r
+       fieldlen[0] = 32;               /* Preamble */\r
+       field[1]    = GMII_ST;\r
+       fieldlen[1] = 2;                /* ST */\r
+       field[2]    = GMII_WRITE;\r
+       fieldlen[2] = 2;                /* OP */\r
+       field[3]    = phy_address;\r
+       fieldlen[3] = 5;                /* PHYAD */\r
+       field[4]    = phy_register;\r
+       fieldlen[4] = 5;                /* REGAD */\r
+       field[5]    = 0x0002;\r
+       fieldlen[5] = 2;                /* TA */\r
+       field[6]    = writeval;\r
+       fieldlen[6] = 16;               /* DATA */\r
+       field[7]    = 0x0000;\r
+       fieldlen[7] = 1;                /* IDLE */\r
+\r
+        /* Store the polarity values of PHYCTRL. */\r
+        phyctrlpolarity = IPG_READ_PHYCTRL(baseaddr) &\r
+                          (IPG_PC_DUPLEX_POLARITY |\r
+                          IPG_PC_LINK_POLARITY);\r
+\r
+       /* Create the Preamble, ST, OP, PHYAD, and REGAD field. */\r
+       for(j=0; j<7; j++)\r
+       for(i=0; i<fieldlen[j]; i++)\r
+       {\r
+               /* For each variable length field, the MSB must be\r
+                * transmitted first. Rotate through the field bits,\r
+                * starting with the MSB, and move each bit into the\r
+                * the 1st (2^1) bit position (this is the bit position\r
+                * corresponding to the MgmtData bit of the PhyCtrl\r
+                * register for the IPG).\r
+                *\r
+                * Example: ST = 01;\r
+                *\r
+                *          First write a '0' to bit 1 of the PhyCtrl\r
+                *          register, then write a '1' to bit 1 of the\r
+                *          PhyCtrl register.\r
+                *\r
+                * To do this, right shift the MSB of ST by the value:\r
+                * [field length - 1 - #ST bits already written]\r
+                * then left shift this result by 1.\r
+                */\r
+               databit = (field[j] >> (fieldlen[j] - 1 - i)) << 1;\r
+\r
+               IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_LO |\r
+                                    (IPG_PC_MGMTDATA & databit) |\r
+                                    IPG_PC_MGMTDIR | phyctrlpolarity);\r
+\r
+               mdelay(IPG_PC_PHYCTRLWAIT);\r
+\r
+               IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_HI |\r
+                                    (IPG_PC_MGMTDATA & databit) |\r
+                                    IPG_PC_MGMTDIR | phyctrlpolarity);\r
+\r
+               mdelay(IPG_PC_PHYCTRLWAIT);\r
+       }\r
+\r
+       /* The last cycle is a tri-state, so read from the PHY.\r
+        */\r
+       for(j=7; j<8; j++)\r
+       for(i=0; i<fieldlen[j]; i++)\r
+       {\r
+               IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_LO |\r
+                                    phyctrlpolarity);\r
+\r
+               mdelay(IPG_PC_PHYCTRLWAIT);\r
+\r
+               field[j] |= ((IPG_READ_PHYCTRL(baseaddr) &\r
+                            IPG_PC_MGMTDATA) >> 1)\r
+                           << (fieldlen[j] - 1 - i);\r
+\r
+               IPG_WRITE_PHYCTRL(baseaddr, IPG_PC_MGMTCLK_HI |\r
+                                    phyctrlpolarity);\r
+\r
+               mdelay(IPG_PC_PHYCTRLWAIT);\r
+\r
+       }\r
+\r
+       return;\r
+}\r
+//int     ipg_reset(u32 baseaddr, u32 resetflags) //JES20040127EEPROM: change type of param1\r
+int    ipg_reset(IPG_DEVICE_TYPE *ipg_ethernet_device, u32 resetflags)\r
+{\r
+       /* Assert functional resets via the IPG AsicCtrl\r
+        * register as specified by the 'resetflags' input\r
+        * parameter.\r
+        */\r
+        u32    baseaddr;//JES20040127EEPROM:   \r
+       int timeout_count;\r
+       baseaddr = ipg_ethernet_device->base_addr;//JES20040127EEPROM:\r
+\r
+       IPG_DEBUG_MSG("_reset\n");\r
+\r
+       IPG_WRITE_ASICCTRL(baseaddr, IPG_READ_ASICCTRL(baseaddr) |\r
+                      resetflags);\r
+\r
+       /* Wait until IPG reset is complete. */\r
+       timeout_count = 0;\r
+\r
+       /* Delay added to account for problem with 10Mbps reset. */\r
+       mdelay(IPG_AC_RESETWAIT);\r
+\r
+       while (IPG_AC_RESET_BUSY & IPG_READ_ASICCTRL(baseaddr))\r
+       {\r
+               mdelay(IPG_AC_RESETWAIT);\r
+               timeout_count++;\r
+               if (timeout_count > IPG_AC_RESET_TIMEOUT)\r
+                       return -ETIME;\r
+       }\r
+   /* Set LED Mode in Asic Control JES20040127EEPROM */\r
+   Set_LED_Mode(ipg_ethernet_device);\r
+        \r
+   /* Set PHYSet Register Value JES20040127EEPROM */\r
+       Set_PHYSet(ipg_ethernet_device);\r
+       return 0;\r
+}\r
+\r
+int    ipg_sti_fiber_detect(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Determine if NIC is fiber based by reading the PhyMedia\r
+        * bit in the AsicCtrl register.\r
+        */\r
+\r
+       u32                             asicctrl;\r
+       u32                             baseaddr;\r
+\r
+       IPG_DEBUG_MSG("_sti_fiber_detect\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       asicctrl = IPG_READ_ASICCTRL(baseaddr);\r
+\r
+        if (asicctrl & IPG_AC_PHY_MEDIA)\r
+       {\r
+               /* Fiber NIC. */\r
+               return 1;\r
+       } else\r
+       {\r
+               /* Not a fiber NIC. */\r
+               return 0;\r
+       }\r
+}\r
+\r
+int    ipg_tmi_fiber_detect(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                               int phyaddr)\r
+{\r
+       /* Determine if NIC is fiber based by reading the ID register\r
+        * of the PHY and the GMII address.\r
+        */\r
+\r
+       u16                             phyid;\r
+       u32                             baseaddr;\r
+\r
+       IPG_DEBUG_MSG("_tmi_fiber_detect\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       phyid = read_phy_register(ipg_ethernet_device,\r
+                                 phyaddr, GMII_PHY_ID_1);\r
+\r
+       IPG_DEBUG_MSG("PHY ID = %x\n", phyid);\r
+\r
+       /* We conclude the mode is fiber if the GMII address\r
+        * is 0x1 and the PHY ID is 0x0000.\r
+        */\r
+        if ((phyaddr == 0x1) && (phyid == 0x0000))\r
+       {\r
+               /* Fiber NIC. */\r
+               return 1;\r
+       } else\r
+       {\r
+               /* Not a fiber NIC. */\r
+               return 0;\r
+       }\r
+}\r
+\r
+int    ipg_find_phyaddr(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Find the GMII PHY address. */\r
+\r
+       int     i;\r
+       int     phyaddr;\r
+       u32     status;\r
+\r
+        for(i=0;i<32;i++)\r
+        {\r
+                /* Search for the correct PHY address among 32 possible. */\r
+                phyaddr = (IPG_NIC_PHY_ADDRESS + i) % 32;\r
+\r
+                               /* 10/22/03 Grace change verify from GMII_PHY_STATUS to\r
+                                  GMII_PHY_ID1\r
+                                */\r
+\r
+                status = read_phy_register(ipg_ethernet_device,\r
+                                           phyaddr, GMII_PHY_STATUS);\r
+\r
+                               // if (status != 0xFFFF)\r
+                if ((status != 0xFFFF) && (status != 0))\r
+                      return phyaddr;\r
+\r
+                /*----------------------------------------------------\r
+                status = read_phy_register(ipg_ethernet_device,\r
+                                                                  phyaddr, GMII_PHY_ID_1);\r
+                               if (status == 0x243) {\r
+                                       printk("PHY Addr = %x\n", phyaddr);\r
+                                       return phyaddr;\r
+                               }\r
+                               -------------------------------------------------*/\r
+        }\r
+\r
+       return -1;\r
+}\r
+\r
+#ifdef NOTGRACE\r
+int    ipg_config_autoneg(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Configure IPG based on result of IEEE 802.3 PHY\r
+        * auto-negotiation.\r
+        */\r
+\r
+        int                             phyaddr = 0;\r
+       u8                              phyctrl;\r
+       u32                             asicctrl;\r
+       u32                             baseaddr;\r
+        u16                             status = 0;\r
+       u16                             advertisement;\r
+       u16                             linkpartner_ability;\r
+       u16                             gigadvertisement;\r
+       u16                             giglinkpartner_ability;\r
+        u16                             techabilities;\r
+        int                             fiber;\r
+        int                             gig;\r
+        int                             fullduplex;\r
+        int                             txflowcontrol;\r
+        int                             rxflowcontrol;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_config_autoneg\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       asicctrl = IPG_READ_ASICCTRL(baseaddr);\r
+    phyctrl = IPG_READ_PHYCTRL(baseaddr);\r
+\r
+       /* Set flags for use in resolving auto-negotation, assuming\r
+        * non-1000Mbps, half duplex, no flow control.\r
+        */\r
+       fiber = 0;\r
+       fullduplex = 0;\r
+       txflowcontrol = 0;\r
+       rxflowcontrol = 0;\r
+       gig = 0;\r
+\r
+       /* To accomodate a problem in 10Mbps operation,\r
+        * set a global flag if PHY running in 10Mbps mode.\r
+        */\r
+       sp->tenmbpsmode = 0;\r
+\r
+       printk("Link speed = ");\r
+\r
+       /* Determine actual speed of operation. */\r
+       switch (phyctrl & IPG_PC_LINK_SPEED)\r
+       {\r
+               case IPG_PC_LINK_SPEED_10MBPS :\r
+                       printk("10Mbps.\n");\r
+                       printk(KERN_INFO "%s: 10Mbps operational mode enabled.\n",ipg_ethernet_device->name);\r
+                       sp->tenmbpsmode = 1;\r
+                       break;\r
+               case IPG_PC_LINK_SPEED_100MBPS :\r
+                       printk("100Mbps.\n");\r
+                       break;\r
+               case IPG_PC_LINK_SPEED_1000MBPS :\r
+                       printk("1000Mbps.\n");\r
+                       gig = 1;\r
+                       break;\r
+               default : printk("undefined!\n");\r
+       }\r
+\r
+#ifndef IPG_TMI_FIBER_DETECT\r
+       fiber = ipg_sti_fiber_detect(ipg_ethernet_device);\r
+\r
+        /* Determine if auto-negotiation resolution is necessary.\r
+        * First check for fiber based media 10/100 media.\r
+        */\r
+        if ((fiber == 1) && (asicctrl &\r
+           (IPG_AC_PHY_SPEED10 | IPG_AC_PHY_SPEED100)))\r
+        {\r
+                printk(KERN_INFO "%s: Fiber based PHY, setting full duplex, no flow control.\n", ipg_ethernet_device->name);\r
+                return -EILSEQ;\r
+                IPG_WRITE_MACCTRL(baseaddr, (IPG_READ_MACCTRL(baseaddr) |\r
+                                                IPG_MC_DUPLEX_SELECT_FD) &\r
+                                     ~IPG_MC_TX_FLOW_CONTROL_ENABLE &\r
+                                     ~IPG_MC_RX_FLOW_CONTROL_ENABLE);\r
+\r
+                return 0;\r
+        }\r
+#endif\r
+\r
+        /* Determine if PHY is auto-negotiation capable. */\r
+       phyaddr = ipg_find_phyaddr(ipg_ethernet_device);\r
+\r
+        if (phyaddr == -1)\r
+        {\r
+                printk(KERN_INFO "%s: Error on read to GMII/MII Status register.\n",ipg_ethernet_device->name);\r
+                return -EILSEQ;\r
+        }\r
+\r
+       IPG_DEBUG_MSG("GMII/MII PHY address = %x\n", phyaddr);\r
+\r
+        status = read_phy_register(ipg_ethernet_device,\r
+                                   phyaddr, GMII_PHY_STATUS);\r
+\r
+       printk("PHYStatus = %x \n", status);\r
+        if ((status & GMII_PHY_STATUS_AUTONEG_ABILITY) == 0)\r
+        {\r
+                printk(KERN_INFO "%s: Error PHY unable to perform auto-negotiation.\n",\r
+                       ipg_ethernet_device->name);\r
+                return -EILSEQ;\r
+        }\r
+\r
+       advertisement = read_phy_register(ipg_ethernet_device, phyaddr,\r
+                                         GMII_PHY_AUTONEGADVERTISEMENT);\r
+       linkpartner_ability = read_phy_register(ipg_ethernet_device, phyaddr,\r
+                                               GMII_PHY_AUTONEGLINKPARTABILITY);\r
+\r
+       printk("PHYadvertisement=%x LinkPartner=%x \n",advertisement,linkpartner_ability);\r
+       if ((advertisement == 0xFFFF) || (linkpartner_ability == 0xFFFF))\r
+       {\r
+               printk(KERN_INFO "%s: Error on read to GMII/MII registers 4 and/or 5.\n", ipg_ethernet_device->name);\r
+               return -EILSEQ;\r
+       }\r
+\r
+#ifdef IPG_TMI_FIBER_DETECT\r
+       fiber = ipg_tmi_fiber_detect(ipg_ethernet_device, phyaddr);\r
+#endif\r
+\r
+        /* Resolve full/half duplex if 1000BASE-X. */\r
+       if ((gig == 1) && (fiber == 1))\r
+        {\r
+               /* Compare the full duplex bits in the GMII registers\r
+                * for the local device, and the link partner. If these\r
+                * bits are logic 1 in both registers, configure the\r
+                * IPG for full duplex operation.\r
+                */\r
+               if ((advertisement & GMII_PHY_ADV_FULL_DUPLEX) ==\r
+                   (linkpartner_ability & GMII_PHY_ADV_FULL_DUPLEX))\r
+               {\r
+                       fullduplex = 1;\r
+\r
+                       /* In 1000BASE-X using IPG's internal PCS\r
+                        * layer, so write to the GMII duplex bit.\r
+                        */\r
+                       write_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          GMII_PHY_CONTROL,\r
+                                          read_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          GMII_PHY_CONTROL) |\r
+                                          GMII_PHY_CONTROL_FULL_DUPLEX);\r
+\r
+               } else\r
+               {\r
+                       fullduplex = 0;\r
+\r
+                       /* In 1000BASE-X using IPG's internal PCS\r
+                        * layer, so write to the GMII duplex bit.\r
+                        */\r
+                       write_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          GMII_PHY_CONTROL,\r
+                                          read_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          GMII_PHY_CONTROL) &\r
+                                          ~GMII_PHY_CONTROL_FULL_DUPLEX);\r
+               }\r
+       }\r
+\r
+        /* Resolve full/half duplex if 1000BASE-T. */\r
+       if ((gig == 1) && (fiber == 0))\r
+        {\r
+               /* Read the 1000BASE-T "Control" and "Status"\r
+                * registers which represent the advertised and\r
+                * link partner abilities exchanged via next page\r
+                * transfers.\r
+                */\r
+               gigadvertisement = read_phy_register(ipg_ethernet_device,\r
+                                                    phyaddr,\r
+                                                GMII_PHY_1000BASETCONTROL);\r
+               giglinkpartner_ability = read_phy_register(ipg_ethernet_device,\r
+                                                          phyaddr,\r
+                                                 GMII_PHY_1000BASETSTATUS);\r
+\r
+               /* Compare the full duplex bits in the 1000BASE-T GMII\r
+                * registers for the local device, and the link partner.\r
+                * If these bits are logic 1 in both registers, configure\r
+                * the IPG for full duplex operation.\r
+                */\r
+               if ((gigadvertisement & GMII_PHY_1000BASETCONTROL_FULL_DUPLEX) &&\r
+                   (giglinkpartner_ability & GMII_PHY_1000BASETSTATUS_FULL_DUPLEX))\r
+               {\r
+                       fullduplex = 1;\r
+               } else\r
+               {\r
+                       fullduplex = 0;\r
+               }\r
+       }\r
+\r
+        /* Resolve full/half duplex for 10/100BASE-T. */\r
+       if (gig == 0)\r
+       {\r
+               /* Autonegotiation Priority Resolution algorithm, as defined in\r
+                * IEEE 802.3 Annex 28B.\r
+                */\r
+               if (((advertisement & MII_PHY_SELECTORFIELD) ==\r
+                    MII_PHY_SELECTOR_IEEE8023) &&\r
+                   ((linkpartner_ability & MII_PHY_SELECTORFIELD) ==\r
+                    MII_PHY_SELECTOR_IEEE8023))\r
+               {\r
+                       techabilities = (advertisement & linkpartner_ability &\r
+                                        MII_PHY_TECHABILITYFIELD);\r
+\r
+                       fullduplex = 0;\r
+\r
+                       /* 10BASE-TX half duplex is lowest priority. */\r
+                       if (techabilities & MII_PHY_TECHABILITY_10BT)\r
+                       {\r
+                               fullduplex = 0;\r
+                       }\r
+\r
+                       if (techabilities & MII_PHY_TECHABILITY_10BTFD)\r
+                       {\r
+                               fullduplex = 1;\r
+                       }\r
+\r
+                       if (techabilities & MII_PHY_TECHABILITY_100BTX)\r
+                       {\r
+                               fullduplex = 0;\r
+                       }\r
+\r
+                       if (techabilities & MII_PHY_TECHABILITY_100BT4)\r
+                       {\r
+                               fullduplex = 0;\r
+                       }\r
+\r
+                       /* 100BASE-TX half duplex is highest priority. */ //Sorbica full duplex ?\r
+                       if (techabilities & MII_PHY_TECHABILITY_100BTXFD)\r
+                       {\r
+                               fullduplex = 1;\r
+                       }\r
+\r
+                       if (fullduplex == 1)\r
+                       {\r
+                               /* If in full duplex mode, determine if PAUSE\r
+                                * functionality is supported by the local\r
+                                * device, and the link partner.\r
+                                */\r
+                               if (techabilities & MII_PHY_TECHABILITY_PAUSE)\r
+                               {\r
+                                       txflowcontrol = 1;\r
+                                       rxflowcontrol = 1;\r
+                               }\r
+                               else\r
+                               {\r
+                                       txflowcontrol = 0;\r
+                                       rxflowcontrol = 0;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       /* If in 1000Mbps, fiber, and full duplex mode, resolve\r
+        * 1000BASE-X PAUSE capabilities. */\r
+       if ((fullduplex == 1) && (fiber == 1) && (gig == 1))\r
+       {\r
+               /* In full duplex mode, resolve PAUSE\r
+                * functionality.\r
+                */\r
+               switch(((advertisement & GMII_PHY_ADV_PAUSE) >> 5) |\r
+                      ((linkpartner_ability & GMII_PHY_ADV_PAUSE) >> 7))\r
+               {\r
+                       case 0x7 :\r
+                       txflowcontrol = 1;\r
+                       rxflowcontrol = 0;\r
+                       break;\r
+\r
+                       case 0xA : case 0xB: case 0xE: case 0xF:\r
+                       txflowcontrol = 1;\r
+                       rxflowcontrol = 1;\r
+                       break;\r
+\r
+                       case 0xD :\r
+                       txflowcontrol = 0;\r
+                       rxflowcontrol = 1;\r
+                       break;\r
+\r
+                       default :\r
+                       txflowcontrol = 0;\r
+                       rxflowcontrol = 0;\r
+               }\r
+       }\r
+\r
+       /* If in 1000Mbps, non-fiber, full duplex mode, resolve\r
+        * 1000BASE-T PAUSE capabilities. */\r
+       if ((fullduplex == 1) && (fiber == 0) && (gig == 1))\r
+       {\r
+               /* Make sure the PHY is advertising we are PAUSE\r
+                * capable.\r
+                */\r
+               if (!(advertisement & (MII_PHY_TECHABILITY_PAUSE |\r
+                                      MII_PHY_TECHABILITY_ASM_DIR)))\r
+               {\r
+                       /* PAUSE is not being advertised. Advertise\r
+                        * PAUSE and restart auto-negotiation.\r
+                        */\r
+                       write_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          MII_PHY_AUTONEGADVERTISEMENT,\r
+                                          (advertisement |\r
+                                            MII_PHY_TECHABILITY_PAUSE |\r
+                                           MII_PHY_TECHABILITY_ASM_DIR));\r
+                       write_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          MII_PHY_CONTROL,\r
+                                          MII_PHY_CONTROL_RESTARTAN);\r
+\r
+                       return -EAGAIN;\r
+               }\r
+\r
+               /* In full duplex mode, resolve PAUSE\r
+                * functionality.\r
+                */\r
+               switch(((advertisement &\r
+                        MII_PHY_TECHABILITY_PAUSE_FIELDS) >> 0x8) |\r
+                      ((linkpartner_ability &\r
+                        MII_PHY_TECHABILITY_PAUSE_FIELDS) >> 0xA))\r
+               {\r
+                       case 0x7 :\r
+                       txflowcontrol = 1;\r
+                       rxflowcontrol = 0;\r
+                       break;\r
+\r
+                       case 0xA : case 0xB: case 0xE: case 0xF:\r
+                       txflowcontrol = 1;\r
+                       rxflowcontrol = 1;\r
+                       break;\r
+\r
+                       case 0xD :\r
+                       txflowcontrol = 0;\r
+                       rxflowcontrol = 1;\r
+                       break;\r
+\r
+                       default :\r
+                       txflowcontrol = 0;\r
+                       rxflowcontrol = 0;\r
+               }\r
+       }\r
+\r
+       /* If in 10/100Mbps, non-fiber, full duplex mode, assure\r
+        * 10/100BASE-T PAUSE capabilities are advertised. */\r
+       if ((fullduplex == 1) && (fiber == 0) && (gig == 0))\r
+       {\r
+               /* Make sure the PHY is advertising we are PAUSE\r
+                * capable.\r
+                */\r
+               if (!(advertisement & (MII_PHY_TECHABILITY_PAUSE)))\r
+               {\r
+                       /* PAUSE is not being advertised. Advertise\r
+                        * PAUSE and restart auto-negotiation.\r
+                        */\r
+                       write_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          MII_PHY_AUTONEGADVERTISEMENT,\r
+                                          (advertisement |\r
+                                            MII_PHY_TECHABILITY_PAUSE));\r
+                       write_phy_register(ipg_ethernet_device,\r
+                                          phyaddr,\r
+                                          MII_PHY_CONTROL,\r
+                                          MII_PHY_CONTROL_RESTARTAN);\r
+\r
+                       return -EAGAIN;\r
+               }\r
+\r
+       }\r
+\r
+        if (fiber == 1)\r
+       {\r
+               printk(KERN_INFO "%s: Fiber based PHY, ",\r
+                      ipg_ethernet_device->name);\r
+       } else\r
+       {\r
+               printk(KERN_INFO "%s: Copper based PHY, ",\r
+                      ipg_ethernet_device->name);\r
+       }\r
+\r
+       /* Configure full duplex, and flow control. */\r
+       if (fullduplex == 1)\r
+       {\r
+               /* Configure IPG for full duplex operation. */\r
+               printk("setting full duplex, ");\r
+\r
+               IPG_WRITE_MACCTRL(baseaddr, IPG_READ_MACCTRL(baseaddr) |\r
+                                    IPG_MC_DUPLEX_SELECT_FD);\r
+\r
+               if (txflowcontrol == 1)\r
+               {\r
+                       printk("TX flow control");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) |\r
+                                            IPG_MC_TX_FLOW_CONTROL_ENABLE);\r
+               } else\r
+               {\r
+                       printk("no TX flow control");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) &\r
+                                            ~IPG_MC_TX_FLOW_CONTROL_ENABLE);\r
+               }\r
+\r
+               if (rxflowcontrol == 1)\r
+               {\r
+                       printk(", RX flow control.");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) |\r
+                                            IPG_MC_RX_FLOW_CONTROL_ENABLE);\r
+               } else\r
+               {\r
+                       printk(", no RX flow control.");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) &\r
+                                            ~IPG_MC_RX_FLOW_CONTROL_ENABLE);\r
+               }\r
+\r
+               printk("\n");\r
+       } else\r
+       {\r
+               /* Configure IPG for half duplex operation. */\r
+               printk("setting half duplex, no TX flow control, no RX flow control.\n");\r
+\r
+               IPG_WRITE_MACCTRL(baseaddr, IPG_READ_MACCTRL(baseaddr) &\r
+                                    ~IPG_MC_DUPLEX_SELECT_FD &\r
+                                    ~IPG_MC_TX_FLOW_CONTROL_ENABLE &\r
+                                    ~IPG_MC_RX_FLOW_CONTROL_ENABLE);\r
+       }\r
+\r
+\r
+       IPG_DEBUG_MSG("G/MII reg 4 (advertisement) = %4.4x\n", advertisement);\r
+       IPG_DEBUG_MSG("G/MII reg 5 (link partner)  = %4.4x\n", linkpartner_ability);\r
+       IPG_DEBUG_MSG("G/MII reg 9 (1000BASE-T control) = %4.4x\n", advertisement);\r
+       IPG_DEBUG_MSG("G/MII reg 10 (1000BASE-T status) = %4.4x\n", linkpartner_ability);\r
+\r
+       IPG_DEBUG_MSG("Auto-neg complete, MACCTRL = %8.8x\n",\r
+                 IPG_READ_MACCTRL(baseaddr));\r
+\r
+       return 0;\r
+}\r
+#else\r
+int    ipg_config_autoneg(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Configure IPG based on result of IEEE 802.3 PHY\r
+        * auto-negotiation.\r
+        */\r
+\r
+//    int                             phyaddr = 0;\r
+       u8                              phyctrl;\r
+       u32                             asicctrl;\r
+       u32                             baseaddr;\r
+//    u16                             status = 0;\r
+//     u16                             advertisement;\r
+//     u16                             linkpartner_ability;\r
+//     u16                             gigadvertisement;\r
+//     u16                             giglinkpartner_ability;\r
+//        u16                             techabilities;\r
+        int                             fiber;\r
+        int                             gig;\r
+        int                             fullduplex;\r
+        int                             txflowcontrol;\r
+        int                             rxflowcontrol;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_config_autoneg\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       asicctrl = IPG_READ_ASICCTRL(baseaddr);\r
+        phyctrl = IPG_READ_PHYCTRL(baseaddr);\r
+\r
+       /* Set flags for use in resolving auto-negotation, assuming\r
+        * non-1000Mbps, half duplex, no flow control.\r
+        */\r
+       fiber = 0;\r
+       fullduplex = 0;\r
+       txflowcontrol = 0;\r
+       rxflowcontrol = 0;\r
+       gig = 0;\r
+\r
+       /* To accomodate a problem in 10Mbps operation,\r
+        * set a global flag if PHY running in 10Mbps mode.\r
+        */\r
+       sp->tenmbpsmode = 0;\r
+\r
+       printk("Link speed = ");\r
+\r
+       /* Determine actual speed of operation. */\r
+       switch (phyctrl & IPG_PC_LINK_SPEED)\r
+       {\r
+               case IPG_PC_LINK_SPEED_10MBPS :\r
+                       printk("10Mbps.\n");\r
+                       printk(KERN_INFO "%s: 10Mbps operational mode enabled.\n",ipg_ethernet_device->name);\r
+                       sp->tenmbpsmode = 1;\r
+                       break;\r
+               case IPG_PC_LINK_SPEED_100MBPS :\r
+                       printk("100Mbps.\n");\r
+                       break;\r
+               case IPG_PC_LINK_SPEED_1000MBPS :\r
+                       printk("1000Mbps.\n");\r
+                       gig = 1;\r
+                       break;\r
+               default : printk("undefined!\n");\r
+                                 return 0;\r
+       }\r
+\r
+       if ( phyctrl & IPG_PC_DUPLEX_STATUS)\r
+       {\r
+               fullduplex = 1;\r
+               txflowcontrol = 1;\r
+               rxflowcontrol = 1;\r
+       }\r
+       else\r
+       {\r
+               fullduplex = 0;\r
+               txflowcontrol = 0;\r
+               rxflowcontrol = 0;\r
+       }\r
+\r
+\r
+       /* Configure full duplex, and flow control. */\r
+       if (fullduplex == 1)\r
+       {\r
+               /* Configure IPG for full duplex operation. */\r
+        printk("setting full duplex, ");\r
+\r
+               IPG_WRITE_MACCTRL(baseaddr, IPG_READ_MACCTRL(baseaddr) |\r
+                                    IPG_MC_DUPLEX_SELECT_FD);\r
+\r
+               if (txflowcontrol == 1)\r
+               {\r
+               printk("TX flow control");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) |\r
+                                            IPG_MC_TX_FLOW_CONTROL_ENABLE);\r
+               } else\r
+               {\r
+               printk("no TX flow control");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) &\r
+                                            ~IPG_MC_TX_FLOW_CONTROL_ENABLE);\r
+               }\r
+\r
+               if (rxflowcontrol == 1)\r
+               {\r
+                       printk(", RX flow control.");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) |\r
+                                            IPG_MC_RX_FLOW_CONTROL_ENABLE);\r
+               } else\r
+               {\r
+                       printk(", no RX flow control.");\r
+                       IPG_WRITE_MACCTRL(baseaddr,\r
+                                            IPG_READ_MACCTRL(baseaddr) &\r
+                                            ~IPG_MC_RX_FLOW_CONTROL_ENABLE);\r
+               }\r
+\r
+               printk("\n");\r
+       } else\r
+       {\r
+               /* Configure IPG for half duplex operation. */\r
+               printk("setting half duplex, no TX flow control, no RX flow control.\n");\r
+\r
+               IPG_WRITE_MACCTRL(baseaddr, IPG_READ_MACCTRL(baseaddr) &\r
+                                    ~IPG_MC_DUPLEX_SELECT_FD &\r
+                                    ~IPG_MC_TX_FLOW_CONTROL_ENABLE &\r
+                                    ~IPG_MC_RX_FLOW_CONTROL_ENABLE);\r
+       }\r
+       return 0;\r
+}\r
+\r
+#endif\r
+\r
+int    ipg_io_config(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Initialize the IPG I/O registers. */\r
+\r
+       u32             baseaddr;\r
+       u32             origmacctrl;\r
+       u32             restoremacctrl;\r
+\r
+       IPG_DEBUG_MSG("_io_config\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       /* Save the original value of MACCTRL. */\r
+       origmacctrl = IPG_READ_MACCTRL(baseaddr);\r
+\r
+       /* Establish a vlaue to restore MACCTRL when done. */\r
+       restoremacctrl = origmacctrl;\r
+\r
+       /* Enable statistics gathering. */\r
+       restoremacctrl |= IPG_MC_STATISTICS_ENABLE;\r
+\r
+        /* Based on compilation option, determine if FCS is to be\r
+         * stripped on receive frames by IPG.\r
+         */\r
+        if (!(IPG_STRIP_FCS_ON_RX))\r
+        {\r
+               restoremacctrl |= IPG_MC_RCV_FCS;\r
+        }\r
+\r
+       /* Determine if transmitter and/or receiver are\r
+        * enabled so we may restore MACCTRL correctly.\r
+        */\r
+       if (origmacctrl & IPG_MC_TX_ENABLED)\r
+       {\r
+               restoremacctrl |= IPG_MC_TX_ENABLE;\r
+       }\r
+\r
+       if (origmacctrl & IPG_MC_RX_ENABLED)\r
+       {\r
+               restoremacctrl |= IPG_MC_RX_ENABLE;\r
+       }\r
+\r
+       /* Transmitter and receiver must be disabled before setting\r
+        * IFSSelect.\r
+        */\r
+       IPG_WRITE_MACCTRL(baseaddr, origmacctrl & (IPG_MC_RX_DISABLE |\r
+                            IPG_MC_TX_DISABLE));\r
+\r
+       /* Now that transmitter and receiver are disabled, write\r
+        * to IFSSelect.\r
+        */\r
+       IPG_WRITE_MACCTRL(baseaddr, origmacctrl & IPG_MC_IFS_96BIT);\r
+\r
+       /* Set RECEIVEMODE register. */\r
+       ipg_nic_set_multicast_list(ipg_ethernet_device);\r
+\r
+       IPG_WRITE_MAXFRAMESIZE(baseaddr, IPG_MAX_RXFRAME_SIZE);\r
+       IPG_WRITE_RXEARLYTHRESH(baseaddr, IPG_RXEARLYTHRESH_VALUE);\r
+       IPG_WRITE_TXSTARTTHRESH(baseaddr, IPG_TXSTARTTHRESH_VALUE);\r
+       IPG_WRITE_RXDMAINTCTRL(baseaddr, (IPG_RI_RSVD_MASK &\r
+                                     ((IPG_RI_RXFRAME_COUNT &\r
+                                       IPG_RXFRAME_COUNT) |\r
+                                      (IPG_RI_PRIORITY_THRESH &\r
+                                       (IPG_PRIORITY_THRESH << 12)) |\r
+                                      (IPG_RI_RXDMAWAIT_TIME &\r
+                                       (IPG_RXDMAWAIT_TIME << 16)))));\r
+       IPG_WRITE_RXDMAPOLLPERIOD(baseaddr, IPG_RXDMAPOLLPERIOD_VALUE);\r
+       IPG_WRITE_RXDMAURGENTTHRESH(baseaddr,\r
+                                      IPG_RXDMAURGENTTHRESH_VALUE);\r
+       IPG_WRITE_RXDMABURSTTHRESH(baseaddr,\r
+                                     IPG_RXDMABURSTTHRESH_VALUE);\r
+       IPG_WRITE_TXDMAPOLLPERIOD(baseaddr,\r
+                                    IPG_TXDMAPOLLPERIOD_VALUE);\r
+       IPG_WRITE_TXDMAURGENTTHRESH(baseaddr,\r
+                                      IPG_TXDMAURGENTTHRESH_VALUE);\r
+       IPG_WRITE_TXDMABURSTTHRESH(baseaddr,\r
+                                     IPG_TXDMABURSTTHRESH_VALUE);\r
+       IPG_WRITE_INTENABLE(baseaddr, IPG_IE_HOST_ERROR |\r
+                                 IPG_IE_TX_DMA_COMPLETE |\r
+                                 IPG_IE_TX_COMPLETE |\r
+                                 IPG_IE_INT_REQUESTED |\r
+                                 IPG_IE_UPDATE_STATS |\r
+                                 IPG_IE_LINK_EVENT |\r
+                                 IPG_IE_RX_DMA_COMPLETE |\r
+                                 //IPG_IE_RFD_LIST_END |   //20041019Jesse_For_SmartBit: remove\r
+                                 IPG_IE_RX_DMA_PRIORITY);\r
+\r
+       IPG_WRITE_FLOWONTHRESH(baseaddr, IPG_FLOWONTHRESH_VALUE);\r
+       IPG_WRITE_FLOWOFFTHRESH(baseaddr, IPG_FLOWOFFTHRESH_VALUE);\r
+\r
+       /* IPG multi-frag frame bug workaround.\r
+        * Per silicon revision B3 eratta.\r
+        */\r
+       IPG_WRITE_DEBUGCTRL(baseaddr,\r
+                              IPG_READ_DEBUGCTRL(baseaddr) | 0x0200);\r
+\r
+       /* IPG TX poll now bug workaround.\r
+        * Per silicon revision B3 eratta.\r
+        */\r
+       IPG_WRITE_DEBUGCTRL(baseaddr,\r
+                              IPG_READ_DEBUGCTRL(baseaddr) | 0x0010);\r
+\r
+       /* IPG RX poll now bug workaround.\r
+        * Per silicon revision B3 eratta.\r
+        */\r
+       IPG_WRITE_DEBUGCTRL(baseaddr,\r
+                              IPG_READ_DEBUGCTRL(baseaddr) | 0x0020);\r
+\r
+       /* Now restore MACCTRL to original setting. */\r
+       IPG_WRITE_MACCTRL(baseaddr, restoremacctrl);\r
+\r
+       /* Disable unused RMON statistics. */\r
+       IPG_WRITE_RMONSTATISTICSMASK(baseaddr, IPG_RZ_ALL);\r
+\r
+       /* Disable unused MIB statistics. */\r
+       IPG_WRITE_STATISTICSMASK(baseaddr,\r
+                            IPG_SM_MACCONTROLFRAMESXMTD |\r
+                            IPG_SM_BCSTOCTETXMTOK_BCSTFRAMESXMTDOK |\r
+                            IPG_SM_MCSTOCTETXMTOK_MCSTFRAMESXMTDOK |\r
+                            IPG_SM_MACCONTROLFRAMESRCVD |\r
+                            IPG_SM_BCSTOCTETRCVDOK_BCSTFRAMESRCVDOK |\r
+                            IPG_SM_TXJUMBOFRAMES |\r
+                            IPG_SM_UDPCHECKSUMERRORS |\r
+                            IPG_SM_IPCHECKSUMERRORS |\r
+                            IPG_SM_TCPCHECKSUMERRORS |\r
+                            IPG_SM_RXJUMBOFRAMES);\r
+\r
+       return 0;\r
+}\r
+\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+void ipg_interrupt_handler(int ipg_irq, void *device_instance,\r
+                                struct pt_regs *regs)\r
+#else\r
+static  irqreturn_t  ipg_interrupt_handler(int ipg_irq, void *device_instance,\r
+                                struct pt_regs *regs)\r
+#endif\r
+{\r
+       int                             error;\r
+       u32                             baseaddr;\r
+       u16                             intstatusackword;\r
+        IPG_DEVICE_TYPE                *ipg_ethernet_device =\r
+                                       (IPG_DEVICE_TYPE *)device_instance;\r
+\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)\r
+        irqreturn_t intr_handled= IRQ_HANDLED;//IRQ_NONE;\r
+#endif\r
+\r
+#ifdef IPG_DEBUG\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+#endif\r
+\r
+       IPG_DEBUG_MSG("_interrupt_handler\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+#ifdef IPG_LINUX2_2\r
+        /*\r
+         * The following code fragment was authored by Donald Becker.\r
+         */\r
+#if defined(__i386__)\r
+                /* A lock to prevent simultaneous entry bug on Intel SMP machines. */\r
+                if (test_and_set_bit(0, (void*)&ipg_ethernet_device->interrupt)) {\r
+                        printk(KERN_ERR "%s: SMP simultaneous entry of an interrupt handler.\n",\r
+                               ipg_ethernet_device->name);\r
+                        ipg_ethernet_device->interrupt = 0;     /* Avoid halting machine. */\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)\r
+                        return intr_handled;\r
+#else\r
+                        return;\r
+#endif\r
+\r
+                }\r
+#else\r
+                if (ipg_ethernet_device->interrupt) {\r
+                        printk(KERN_ERR "%s: Re-entering the interrupt handler.\n",\r
+                               ipg_ethernet_device->name);\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)\r
+                        return intr_handled;\r
+#else\r
+                        return;\r
+#endif\r
+                }\r
+                ipg_ethernet_device->interrupt = 1;\r
+#endif\r
+        /*\r
+         * End of code fragment authored by Donald Becker.\r
+         */\r
+\r
+        /* Setting ipg_ethernet_device->interrupt = 1\r
+         * indicates to higher network layers an\r
+         * Ethernet NIC interrupt is being serviced.\r
+         */\r
+#endif\r
+\r
+#ifdef JUMBO_FRAME\r
+       ipg_nic_rxrestore(ipg_ethernet_device);\r
+#endif\r
+       /* Get interrupt source information, and acknowledge\r
+        * some (i.e. TxDMAComplete, RxDMAComplete, RxEarly,\r
+        * IntRequested, MacControlFrame, LinkEvent) interrupts\r
+        * if issued. Also, all IPG interrupts are disabled by\r
+        * reading IntStatusAck.\r
+        */\r
+       intstatusackword = IPG_READ_INTSTATUSACK(baseaddr);\r
+\r
+       IPG_DEBUG_MSG("IntStatusAck = %4.4x\n", intstatusackword);\r
+\r
+       /* If RFDListEnd interrupt, restore all used RFDs. */\r
+       if (intstatusackword & IPG_IS_RFD_LIST_END)\r
+       {\r
+               IPG_DEBUG_MSG("RFDListEnd Interrupt.\n");\r
+\r
+               /* The RFD list end indicates an RFD was encountered\r
+                * with a 0 NextPtr, or with an RFDDone bit set to 1\r
+                * (indicating the RFD is not read for use by the\r
+                * IPG.) Try to restore all RFDs.\r
+                */\r
+               ipg_nic_rxrestore(ipg_ethernet_device);\r
+\r
+#ifdef IPG_DEBUG\r
+               /* Increment the RFDlistendCount counter. */\r
+               sp->RFDlistendCount++;\r
+#endif\r
+       }\r
+\r
+       /* If RFDListEnd, RxDMAPriority, RxDMAComplete, or\r
+        * IntRequested interrupt, process received frames. */\r
+       if ((intstatusackword & IPG_IS_RX_DMA_PRIORITY) ||\r
+           (intstatusackword & IPG_IS_RFD_LIST_END) ||\r
+           (intstatusackword & IPG_IS_RX_DMA_COMPLETE) ||\r
+           (intstatusackword & IPG_IS_INT_REQUESTED))\r
+       {\r
+\r
+#ifdef IPG_DEBUG\r
+       /* Increment the RFD list checked counter if interrupted\r
+        * only to check the RFD list. */\r
+       if (intstatusackword & (~(IPG_IS_RX_DMA_PRIORITY |\r
+           IPG_IS_RFD_LIST_END | IPG_IS_RX_DMA_COMPLETE |\r
+           IPG_IS_INT_REQUESTED) &\r
+                                 (IPG_IS_HOST_ERROR |\r
+                                 IPG_IS_TX_DMA_COMPLETE |\r
+                                 IPG_IS_TX_COMPLETE |\r
+                                 IPG_IS_UPDATE_STATS |\r
+                                 IPG_IS_LINK_EVENT)))\r
+\r
+       {\r
+               sp->RFDListCheckedCount++;\r
+       }\r
+#endif\r
+\r
+               ipg_nic_rx(ipg_ethernet_device);\r
+       }\r
+\r
+       /* If TxDMAComplete interrupt, free used TFDs. */\r
+       if (intstatusackword & IPG_IS_TX_DMA_COMPLETE)\r
+       {\r
+               /* Free used TFDs. */\r
+               ipg_nic_txfree(ipg_ethernet_device);\r
+       }\r
+\r
+       /* TxComplete interrupts indicate one of numerous actions.\r
+        * Determine what action to take based on TXSTATUS register.\r
+        */\r
+       if (intstatusackword & IPG_IS_TX_COMPLETE)\r
+       {\r
+               ipg_nic_txcleanup(ipg_ethernet_device);\r
+       }\r
+\r
+       /* If UpdateStats interrupt, update Linux Ethernet statistics */\r
+       if (intstatusackword & IPG_IS_UPDATE_STATS)\r
+       {\r
+               ipg_nic_get_stats(ipg_ethernet_device);\r
+       }\r
+\r
+       /* If HostError interrupt, reset IPG. */\r
+       if (intstatusackword & IPG_IS_HOST_ERROR)\r
+       {\r
+               IPG_DDEBUG_MSG("HostError Interrupt\n");\r
+\r
+               IPG_DDEBUG_MSG("DMACtrl = %8.8x\n",\r
+                IPG_READ_DMACTRL(baseaddr));\r
+\r
+               /* Acknowledge HostError interrupt by resetting\r
+                * IPG DMA and HOST.\r
+                */\r
+               ipg_reset(ipg_ethernet_device,\r
+                           IPG_AC_GLOBAL_RESET |\r
+                           IPG_AC_HOST |\r
+                           IPG_AC_DMA);\r
+\r
+               error = ipg_io_config(ipg_ethernet_device);\r
+               if (error < 0)\r
+               {\r
+                       printk(KERN_INFO "%s: Cannot recover from PCI error.\n",\r
+                              ipg_ethernet_device->name);\r
+               }\r
+\r
+               init_rfdlist(ipg_ethernet_device);\r
+\r
+               init_tfdlist(ipg_ethernet_device);\r
+       }\r
+\r
+       /* If LinkEvent interrupt, resolve autonegotiation. */\r
+       if (intstatusackword & IPG_IS_LINK_EVENT)\r
+       {\r
+               if (ipg_config_autoneg(ipg_ethernet_device) < 0)\r
+                       printk(KERN_INFO "%s: Auto-negotiation error.\n",\r
+                              ipg_ethernet_device->name);\r
+\r
+       }\r
+\r
+       /* If MACCtrlFrame interrupt, do nothing. */\r
+       if (intstatusackword & IPG_IS_MAC_CTRL_FRAME)\r
+       {\r
+               IPG_DEBUG_MSG("MACCtrlFrame interrupt.\n");\r
+       }\r
+\r
+       /* If RxComplete interrupt, do nothing. */\r
+       if (intstatusackword & IPG_IS_RX_COMPLETE)\r
+       {\r
+               IPG_DEBUG_MSG("RxComplete interrupt.\n");\r
+       }\r
+\r
+       /* If RxEarly interrupt, do nothing. */\r
+       if (intstatusackword & IPG_IS_RX_EARLY)\r
+       {\r
+               IPG_DEBUG_MSG("RxEarly interrupt.\n");\r
+       }\r
+\r
+       /* Re-enable IPG interrupts. */\r
+       IPG_WRITE_INTENABLE(baseaddr, IPG_IE_HOST_ERROR |\r
+                                 IPG_IE_TX_DMA_COMPLETE |\r
+                                 IPG_IE_TX_COMPLETE |\r
+                                 IPG_IE_INT_REQUESTED |\r
+                                 IPG_IE_UPDATE_STATS |\r
+                                 IPG_IE_LINK_EVENT |\r
+                                 IPG_IE_RX_DMA_COMPLETE |\r
+                                 //IPG_IE_RFD_LIST_END | //20041019Jesse_For_SmartBit: remove\r
+                                 IPG_IE_RX_DMA_PRIORITY);\r
+\r
+        /* Indicate to higher network layers the Ethernet NIC\r
+         * interrupt servicing is complete.\r
+         */\r
+\r
+#ifdef IPG_LINUX2_2\r
+        /*\r
+         * The following code fragment was authored by Donald Becker.\r
+         */\r
+#if defined(__i386__)\r
+                clear_bit(0, (void*)&ipg_ethernet_device->interrupt);\r
+#else\r
+                ipg_ethernet_device->interrupt = 0;\r
+#endif\r
+        /*\r
+         * End of code fragment authored by Donald Becker.\r
+         */\r
+#endif\r
+\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)\r
+                        return intr_handled;\r
+#else\r
+                        return;\r
+#endif\r
+}\r
+\r
+void ipg_nic_txcleanup(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* For TxComplete interrupts, free all transmit\r
+        * buffers which have already been transfered via DMA\r
+        * to the IPG.\r
+        */\r
+\r
+       int                             maxtfdcount;\r
+       u32                             baseaddr;\r
+       u32                             txstatusdword;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_nic_txcleanup\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       maxtfdcount = IPG_TFDLIST_LENGTH;\r
+\r
+       do\r
+       {\r
+               /* Reading the TXSTATUS register clears the\r
+                * TX_COMPLETE interrupt.\r
+                */\r
+               txstatusdword = IPG_READ_TXSTATUS(baseaddr);\r
+\r
+               IPG_DEBUG_MSG("TxStatus = %8.8x\n",txstatusdword);\r
+\r
+               /* Check for Transmit errors. Error bits only valid if\r
+                * TX_COMPLETE bit in the TXSTATUS register is a 1.\r
+                */\r
+               if (txstatusdword & IPG_TS_TX_COMPLETE)\r
+               {\r
+\r
+                       /* If in 10Mbps mode, indicate transmit is ready. */\r
+                       if (sp->tenmbpsmode)\r
+                       {\r
+                               spin_lock(&sp->lock);\r
+                               IPG_TX_NOTBUSY(ipg_ethernet_device);\r
+                               spin_unlock(&sp->lock);\r
+                       }\r
+\r
+                       /* Transmit error, increment stat counters. */\r
+                       if (txstatusdword & IPG_TS_TX_ERROR)\r
+                       {\r
+                               IPG_DEBUG_MSG("Transmit error.\n");\r
+                               sp->stats.tx_errors++;\r
+                       }\r
+\r
+                       /* Late collision, re-enable transmitter. */\r
+                       if (txstatusdword & IPG_TS_LATE_COLLISION)\r
+                       {\r
+                               IPG_DEBUG_MSG("Late collision on transmit.\n");\r
+                               IPG_WRITE_MACCTRL(baseaddr,\r
+                                 IPG_READ_MACCTRL(baseaddr) |\r
+                                 IPG_MC_TX_ENABLE);\r
+                       }\r
+\r
+                       /* Maximum collisions, re-enable transmitter. */\r
+                       if (txstatusdword & IPG_TS_TX_MAX_COLL)\r
+                       {\r
+                               IPG_DEBUG_MSG("Maximum collisions on transmit.\n");\r
+\r
+                               IPG_WRITE_MACCTRL(baseaddr,\r
+                                 IPG_READ_MACCTRL(baseaddr) |\r
+                                 IPG_MC_TX_ENABLE);\r
+                       }\r
+\r
+                       /* Transmit underrun, reset and re-enable\r
+                        * transmitter.\r
+                        */\r
+                       if (txstatusdword & IPG_TS_TX_UNDERRUN)\r
+                       {\r
+                               IPG_DEBUG_MSG("Transmitter underrun.\n");\r
+                               sp->stats.tx_fifo_errors++;\r
+                               ipg_reset(ipg_ethernet_device, IPG_AC_TX_RESET |\r
+                                                      IPG_AC_DMA |\r
+                                                      IPG_AC_NETWORK);\r
+\r
+                               /* Re-configure after DMA reset. */\r
+                               if ((ipg_io_config(ipg_ethernet_device) < 0) ||\r
+                                   (init_tfdlist(ipg_ethernet_device) < 0))\r
+                               {\r
+                                       printk(KERN_INFO "%s: Error during re-configuration.\n",\r
+                                              ipg_ethernet_device->name);\r
+                               }\r
+\r
+                               IPG_WRITE_MACCTRL(baseaddr,\r
+                                 IPG_READ_MACCTRL(baseaddr) |\r
+                                 IPG_MC_TX_ENABLE);\r
+                       }\r
+               }\r
+               else\r
+                       break;\r
+\r
+               maxtfdcount--;\r
+\r
+       }\r
+       while(maxtfdcount != 0);\r
+\r
+       ipg_nic_txfree(ipg_ethernet_device);\r
+\r
+       return;\r
+}\r
+\r
+void ipg_nic_txfree(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+        /* Free all transmit buffers which have already been transfered\r
+         * via DMA to the IPG.\r
+         */\r
+\r
+        int                             NextToFree;\r
+        int                             maxtfdcount;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_nic_txfree\n");\r
+\r
+       maxtfdcount = IPG_TFDLIST_LENGTH;\r
+\r
+       /* Set the CurrentTxFrameID to skip the next\r
+        * TxDMACompleteInterrupt.\r
+        */\r
+       sp->CurrentTxFrameID = 1;\r
+\r
+       do\r
+       {\r
+               /* Calculate next TFD to release. */\r
+               NextToFree = (sp->LastFreedTxBuff + 1) % IPG_TFDLIST_LENGTH;\r
+\r
+               IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long int)\r
+                                sp->TFDList[NextToFree].TFC);\r
+\r
+               /* Look at each TFD's TFC field beginning\r
+                * at the last freed TFD up to the current TFD.\r
+                * If the TFDDone bit is set, free the associated\r
+                * buffer.\r
+                */\r
+               if ((le64_to_cpu(sp->TFDList[NextToFree].TFC) &\r
+                    IPG_TFC_TFDDONE) &&\r
+                   (NextToFree != sp->CurrentTFD))\r
+               {\r
+                       /* Free the transmit buffer. */\r
+                       if (sp->TxBuff[NextToFree] != NULL)\r
+                       {\r
+#ifdef IPG_LINUX2_4\r
+                               pci_unmap_single(sp->ipg_pci_device,\r
+                                sp->TxBuffDMAhandle[NextToFree].dmahandle,\r
+                                sp->TxBuffDMAhandle[NextToFree].len,\r
+                                PCI_DMA_TODEVICE);\r
+#endif\r
+\r
+                               IPG_DEV_KFREE_SKB(sp->TxBuff[NextToFree]);\r
+\r
+                               sp->TxBuff[NextToFree] = NULL;\r
+                       }\r
+\r
+                       sp->LastFreedTxBuff = NextToFree;\r
+               }\r
+                else\r
+                        break;\r
+\r
+                maxtfdcount--;\r
+\r
+        } while(maxtfdcount != 0);\r
+\r
+       return;\r
+}\r
+\r
+int    ipg_nic_open(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* The IPG NIC Ethernet interface is opened when activated\r
+        * by ifconfig.\r
+        */\r
+\r
+       int                             phyaddr = 0;\r
+       int                             error = 0;\r
+       int                             i;\r
+       u32                             baseaddr;\r
+       u8                                      revisionid=0;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+        IPG_DEBUG_MSG("_nic_open\n");\r
+\r
+\r
+\r
+#ifdef USE_IO_OPS\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       /* Check for I/O port address conflicts, return error\r
+        * if requested range is already in use.\r
+        */\r
+       if ((error = check_region(IPG_PCI_RESOURCE_START(\r
+                                 sp->ipg_pci_device, 0) &\r
+                                 IPG_PIB_IOBASEADDRESS,\r
+                                 IPG_IO_REG_RANGE)) < 0)\r
+       {\r
+               printk(KERN_INFO "%s: Error registering I/O ports.\n",\r
+                      ipg_ethernet_device->name);\r
+               return error;\r
+       }\r
+\r
+       /* Requested range is free, reserve that range for\r
+        * use by the IPG.\r
+        */\r
+       request_region(IPG_PCI_RESOURCE_START(sp->ipg_pci_device, 0) &\r
+                      IPG_PIB_IOBASEADDRESS,\r
+                      IPG_IO_REG_RANGE,\r
+                      IPG_DRIVER_NAME);\r
+\r
+       /* Use I/O space to access IPG registers. */\r
+       ipg_ethernet_device->base_addr =\r
+               (IPG_PCI_RESOURCE_START(sp->ipg_pci_device, 0) &\r
+                IPG_PIB_IOBASEADDRESS);\r
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+\r
+#else /* Not using I/O space. */\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       /* Use memory space to access IPG registers. ioremap\r
+        * is used to map high-memory PCI buffer address space\r
+        * to user address space.\r
+        */\r
+       ipg_ethernet_device->base_addr = (unsigned long)\r
+         (ioremap(IPG_PCI_RESOURCE_START(sp->ipg_pci_device, 1) &\r
+         IPG_PMB_MEMBASEADDRESS, IPG_MEM_REG_RANGE));\r
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+#ifdef IPG_LINUX2_4\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       ipg_ethernet_device->mem_start = pci_resource_start(\r
+                                            sp->ipg_pci_device, 1);\r
+       ipg_ethernet_device->mem_end = ipg_ethernet_device->mem_start + IPG_MEM_REG_RANGE;\r
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)                                       \r
+#endif\r
+\r
+#endif\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       /* Reset all functions within the IPG. Do not assert\r
+        * RST_OUT as not compatible with some PHYs.\r
+        */\r
+       i = IPG_AC_GLOBAL_RESET | IPG_AC_RX_RESET |\r
+           IPG_AC_TX_RESET | IPG_AC_DMA |\r
+           IPG_AC_FIFO | IPG_AC_NETWORK |\r
+           IPG_AC_HOST | IPG_AC_AUTO_INIT;\r
+   /* Read/Write and Reset EEPROM Value Jesse20040128EEPROM_VALUE */\r
+       /* Read LED Mode Configuration from EEPROM */\r
+       sp->LED_Mode=read_eeprom(ipg_ethernet_device, 6);\r
+       \r
+       error = ipg_reset(ipg_ethernet_device, i);\r
+       if (error < 0)\r
+       {\r
+               return error;\r
+       }\r
+\r
+       /* Reset PHY. */\r
+       phyaddr = ipg_find_phyaddr(ipg_ethernet_device);\r
+\r
+       if (phyaddr != -1)\r
+       {   u16 mii_phyctrl, mii_1000cr;\r
+               mii_1000cr = read_phy_register(ipg_ethernet_device,\r
+                                          phyaddr, GMII_PHY_1000BASETCONTROL);\r
+               write_phy_register(ipg_ethernet_device, phyaddr,\r
+                                                       GMII_PHY_1000BASETCONTROL,\r
+                                                       mii_1000cr |\r
+                                                               GMII_PHY_1000BASETCONTROL_FULL_DUPLEX |\r
+                                                               GMII_PHY_1000BASETCONTROL_HALF_DUPLEX |\r
+                                                               GMII_PHY_1000BASETCONTROL_PreferMaster);\r
+\r
+               mii_phyctrl = read_phy_register(ipg_ethernet_device,\r
+                                               phyaddr, GMII_PHY_CONTROL);\r
+                       /* Set default phyparam*/\r
+                       pci_read_config_byte(sp->ipg_pci_device,PCI_REVISION_ID,&revisionid);\r
+                       bSetPhyDefaultParam(revisionid,ipg_ethernet_device,phyaddr);\r
+                       \r
+                       /* reset Phy*/                  \r
+                       write_phy_register(ipg_ethernet_device,\r
+                                       phyaddr, GMII_PHY_CONTROL,\r
+                                                       (mii_phyctrl | GMII_PHY_CONTROL_RESET |\r
+                                               MII_PHY_CONTROL_RESTARTAN));\r
+\r
+       }\r
+\r
+        /* Intitalize lock variable before requesting interrupt. */\r
+    sp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;\r
+\r
+       /* Check for interrupt line conflicts, and request interrupt\r
+        * line for IPG.\r
+        *\r
+        * IMPORTANT: Disable IPG interrupts prior to registering\r
+        *            IRQ.\r
+        */\r
+       IPG_WRITE_INTENABLE(baseaddr, 0x0000);\r
+\r
+       /* Register the interrupt line to be used by the IPG within\r
+        * the Linux system.\r
+        */\r
+       if ((error = request_irq(sp->ipg_pci_device->irq,\r
+                                &ipg_interrupt_handler,\r
+                                SA_SHIRQ,\r
+                                ipg_ethernet_device->name,\r
+                                ipg_ethernet_device)) < 0)\r
+       {\r
+               printk(KERN_INFO "%s: Error when requesting interrupt.\n",\r
+                               ipg_ethernet_device->name);\r
+               return error;\r
+       }\r
+\r
+       ipg_ethernet_device->irq = sp->ipg_pci_device->irq;\r
+\r
+#ifdef IPG_LINUX2_2\r
+       /* Reserve memory for RFD list which must lie on an 8 byte\r
+        * boundary. So, allocated memory must be adjusted to account\r
+        * for this alignment.\r
+        */\r
+       sp->RFDList = kmalloc((sizeof(struct RFD) * IPG_RFDLIST_LENGTH) +\r
+                             IPG_DMALIST_ALIGN_PAD, GFP_KERNEL);\r
+\r
+       if (sp->RFDList != NULL)\r
+       {\r
+               /* Adjust the start address of the allocated\r
+                * memory to assure it begins on an 8 byte\r
+                * boundary.\r
+                */\r
+               sp->RFDList = (void *)(((long)(sp->RFDList) +\r
+                              IPG_DMALIST_ALIGN_PAD) &\r
+                              ~IPG_DMALIST_ALIGN_PAD);\r
+       }\r
+\r
+       /* Reserve memory for TFD list which must lie on an 8 byte\r
+        * boundary. So, allocated memory must be adjusted to account\r
+        * for this alignment.\r
+        */\r
+       sp->TFDList = kmalloc((sizeof(struct TFD) * IPG_TFDLIST_LENGTH) +\r
+                             IPG_DMALIST_ALIGN_PAD, GFP_KERNEL);\r
+\r
+       if (sp->TFDList != NULL)\r
+       {\r
+               /* Adjust the start address of the allocated\r
+                * memory to assure it begins on an 8 byte\r
+                * boundary.\r
+                */\r
+               sp->TFDList = (void *)(((long)(sp->TFDList) +\r
+                              IPG_DMALIST_ALIGN_PAD) &\r
+                              ~IPG_DMALIST_ALIGN_PAD);\r
+       }\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       sp->RFDList = pci_alloc_consistent(sp->ipg_pci_device,\r
+                                          (sizeof(struct RFD) *\r
+                                          IPG_RFDLIST_LENGTH),\r
+                                          &sp->RFDListDMAhandle);\r
+\r
+       sp->TFDList = pci_alloc_consistent(sp->ipg_pci_device,\r
+                                          (sizeof(struct TFD) *\r
+                                          IPG_TFDLIST_LENGTH),\r
+                                          &sp->TFDListDMAhandle);\r
+#endif\r
+\r
+       if ((sp->RFDList == NULL) || (sp->TFDList == NULL))\r
+       {\r
+               printk(KERN_INFO "%s: No memory available for IP1000 RFD and/or TFD lists.\n", ipg_ethernet_device->name);\r
+               return -ENOMEM;\r
+       }\r
+\r
+       error = init_rfdlist(ipg_ethernet_device);\r
+       if (error < 0)\r
+       {\r
+               printk(KERN_INFO "%s: Error during configuration.\n",\r
+                               ipg_ethernet_device->name);\r
+               return error;\r
+       }\r
+\r
+       error = init_tfdlist(ipg_ethernet_device);\r
+       if (error < 0)\r
+       {\r
+               printk(KERN_INFO "%s: Error during configuration.\n",\r
+                               ipg_ethernet_device->name);\r
+               return error;\r
+       }\r
+       \r
+       /* Read MAC Address from EERPOM Jesse20040128EEPROM_VALUE */\r
+       sp->StationAddr0=read_eeprom(ipg_ethernet_device, 16);\r
+       sp->StationAddr1=read_eeprom(ipg_ethernet_device, 17);\r
+       sp->StationAddr2=read_eeprom(ipg_ethernet_device, 18);\r
+       /* Write MAC Address to Station Address */\r
+       IPG_WRITE_STATIONADDRESS0(baseaddr,sp->StationAddr0);\r
+       IPG_WRITE_STATIONADDRESS1(baseaddr,sp->StationAddr1);\r
+       IPG_WRITE_STATIONADDRESS2(baseaddr,sp->StationAddr2);\r
+\r
+       /* Set station address in ethernet_device structure. */\r
+       ipg_ethernet_device->dev_addr[0] =\r
+         IPG_READ_STATIONADDRESS0(baseaddr) & 0x00FF;\r
+       ipg_ethernet_device->dev_addr[1] =\r
+         (IPG_READ_STATIONADDRESS0(baseaddr) & 0xFF00) >> 8;\r
+       ipg_ethernet_device->dev_addr[2] =\r
+         IPG_READ_STATIONADDRESS1(baseaddr) & 0x00FF;\r
+       ipg_ethernet_device->dev_addr[3] =\r
+         (IPG_READ_STATIONADDRESS1(baseaddr) & 0xFF00) >> 8;\r
+       ipg_ethernet_device->dev_addr[4] =\r
+         IPG_READ_STATIONADDRESS2(baseaddr) & 0x00FF;\r
+       ipg_ethernet_device->dev_addr[5] =\r
+         (IPG_READ_STATIONADDRESS2(baseaddr) & 0xFF00) >> 8;\r
+\r
+       /* Configure IPG I/O registers. */\r
+       error = ipg_io_config(ipg_ethernet_device);\r
+       if (error < 0)\r
+       {\r
+               printk(KERN_INFO "%s: Error during configuration.\n",\r
+                               ipg_ethernet_device->name);\r
+               return error;\r
+       }\r
+\r
+       /* Resolve autonegotiation. */\r
+       if (ipg_config_autoneg(ipg_ethernet_device) < 0)\r
+       {\r
+               printk(KERN_INFO "%s: Auto-negotiation error.\n",\r
+                      ipg_ethernet_device->name);\r
+       }\r
+\r
+#ifdef JUMBO_FRAME\r
+    /* initialize JUMBO Frame control variable */\r
+    sp->Jumbo.FoundStart=0;\r
+    sp->Jumbo.CurrentSize=0;\r
+    sp->Jumbo.skb=0;\r
+    ipg_ethernet_device->mtu = IPG_TXFRAG_SIZE;\r
+#endif\r
+\r
+       /* Enable transmit and receive operation of the IPG. */\r
+       IPG_WRITE_MACCTRL(baseaddr, IPG_READ_MACCTRL(baseaddr) |\r
+                            IPG_MC_RX_ENABLE | IPG_MC_TX_ENABLE);\r
+\r
+#ifdef IPG_LINUX2_2\r
+       ipg_ethernet_device->interrupt = 0;\r
+       ipg_ethernet_device->start = 1;\r
+       clear_bit(0,(void*)&ipg_ethernet_device->tbusy);\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       netif_start_queue(ipg_ethernet_device);\r
+#endif\r
+\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       /* Increment the usage count for this IPG driver module. */\r
+       MOD_INC_USE_COUNT;\r
+#endif\r
+\r
+       return 0;\r
+}\r
+\r
+int init_rfdlist(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Initialize the RFDList. */\r
+\r
+       int                             i;\r
+       u32                             baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_init_rfdlist\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       /* Clear the receive buffer not ready flag. */\r
+       sp->RxBuffNotReady = 0;\r
+\r
+       for(i=0; i<IPG_RFDLIST_LENGTH; i++)\r
+       {\r
+               /* Free any allocated receive buffers. */\r
+#ifdef IPG_LINUX2_4\r
+               pci_unmap_single(sp->ipg_pci_device,\r
+                                 sp->RxBuffDMAhandle[i].dmahandle,\r
+                                sp->RxBuffDMAhandle[i].len,\r
+                                PCI_DMA_FROMDEVICE);\r
+#endif\r
+               if (sp->RxBuff[i] != NULL)\r
+                       IPG_DEV_KFREE_SKB(sp->RxBuff[i]);\r
+               sp->RxBuff[i] = NULL;\r
+\r
+               /* Clear out the RFS field. */\r
+               sp->RFDList[i].RFS = 0x0000000000000000;\r
+\r
+               if (ipg_get_rxbuff(ipg_ethernet_device, i) < 0)\r
+               {\r
+                       /* A receive buffer was not ready, break the\r
+                        * RFD list here and set the receive buffer\r
+                        * not ready flag.\r
+                        */\r
+                       sp->RxBuffNotReady = 1;\r
+\r
+                       IPG_DEBUG_MSG("Cannot allocate Rx buffer.\n");\r
+\r
+                       /* Just in case we cannot allocate a single RFD.\r
+                        * Should not occur.\r
+                        */\r
+                       if (i == 0)\r
+                       {\r
+                               printk(KERN_ERR "%s: No memory available for RFD list.\n",\r
+                                      ipg_ethernet_device->name);\r
+                               return -ENOMEM;\r
+                       }\r
+               }\r
+\r
+               /* Set up RFDs to point to each other. A ring structure. */\r
+#ifdef IPG_LINUX2_2\r
+               sp->RFDList[i].RFDNextPtr = cpu_to_le64(\r
+                                                IPG_HOST2BUS_MAP(\r
+                                                &sp->RFDList[(i + 1) %\r
+                                                IPG_RFDLIST_LENGTH]));\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+               sp->RFDList[i].RFDNextPtr = cpu_to_le64(\r
+                                           sp->RFDListDMAhandle +\r
+                                           ((sizeof(struct RFD)) *\r
+                                            ((i + 1) %\r
+                                             IPG_RFDLIST_LENGTH)));\r
+#endif\r
+       }\r
+\r
+       sp->CurrentRFD = 0;\r
+       sp->LastRestoredRxBuff = i - 1;\r
+\r
+       /* Write the location of the RFDList to the IPG. */\r
+#ifdef IPG_LINUX2_2\r
+       IPG_WRITE_RFDLISTPTR0(baseaddr,\r
+         (u32)(IPG_HOST2BUS_MAP(sp->RFDList)));\r
+       IPG_WRITE_RFDLISTPTR1(baseaddr, 0x00000000);\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       IPG_WRITE_RFDLISTPTR0(baseaddr, (u32)(sp->RFDListDMAhandle));\r
+       IPG_WRITE_RFDLISTPTR1(baseaddr, 0x00000000);\r
+#endif\r
+\r
+       return 0;\r
+}\r
+\r
+int init_tfdlist(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Initialize TFDList. */\r
+\r
+       int                             i;\r
+       u32                             baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_init_tfdlist\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       for(i=0; i<IPG_TFDLIST_LENGTH; i++)\r
+       {\r
+#ifdef IPG_LINUX2_2\r
+               sp->TFDList[i].TFDNextPtr = cpu_to_le64(\r
+                                                IPG_HOST2BUS_MAP(\r
+                                                &sp->TFDList[(i + 1) %\r
+                                                IPG_TFDLIST_LENGTH]));\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+               sp->TFDList[i].TFDNextPtr = cpu_to_le64(\r
+                                           sp->TFDListDMAhandle +\r
+                                           ((sizeof(struct TFD)) *\r
+                                            ((i + 1) %\r
+                                             IPG_TFDLIST_LENGTH)));\r
+#endif\r
+\r
+               sp->TFDList[i].TFC = cpu_to_le64(IPG_TFC_TFDDONE);\r
+               if (sp->TxBuff[i] != NULL)\r
+                       IPG_DEV_KFREE_SKB(sp->TxBuff[i]);\r
+               sp->TxBuff[i] = NULL;\r
+       }\r
+\r
+       sp->CurrentTFD = IPG_TFDLIST_LENGTH - 1;\r
+       sp->CurrentTxFrameID = 0;\r
+       sp->LastFreedTxBuff = IPG_TFDLIST_LENGTH - 1;\r
+\r
+       /* Write the location of the TFDList to the IPG. */\r
+#ifdef IPG_LINUX2_2\r
+       IPG_WRITE_TFDLISTPTR0(baseaddr, (u32)(IPG_HOST2BUS_MAP(\r
+                                                sp->TFDList)));\r
+       IPG_WRITE_TFDLISTPTR1(baseaddr, 0x00000000);\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       IPG_DDEBUG_MSG("Starting TFDListPtr = %8.8x\n",\r
+         (u32)(sp->TFDListDMAhandle));\r
+       IPG_WRITE_TFDLISTPTR0(baseaddr, (u32)(sp->TFDListDMAhandle));\r
+       IPG_WRITE_TFDLISTPTR1(baseaddr, 0x00000000);\r
+#endif\r
+\r
+       return 0;\r
+}\r
+\r
+int    ipg_get_rxbuff(IPG_DEVICE_TYPE *ipg_ethernet_device, int rfd)\r
+{\r
+       /* Create a receive buffer within system memory and update\r
+        * NIC private structure appropriately.\r
+        */\r
+       u64                             rxfragsize;\r
+       struct sk_buff                  *skb;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_get_rxbuff\n");\r
+\r
+       /* Allocate memory buffers for receive frames. Pad by\r
+        * 2 to account for IP field alignment.\r
+        */\r
+       skb = dev_alloc_skb(IPG_RXSUPPORT_SIZE + 2);\r
+\r
+       if (skb == NULL)\r
+       {\r
+               sp->RxBuff[rfd] = NULL;\r
+               return -ENOMEM;\r
+       }\r
+\r
+       /* Adjust the data start location within the buffer to\r
+        * align IP address field to a 16 byte boundary.\r
+        */\r
+       skb_reserve(skb, 2);\r
+\r
+       /* Associate the receive buffer with the IPG NIC. */\r
+       skb->dev = ipg_ethernet_device;\r
+\r
+       /* Save the address of the sk_buff structure. */\r
+       sp->RxBuff[rfd] = skb;\r
+\r
+#ifdef IPG_LINUX2_2\r
+       /* The sk_buff struct "data" field holds the address\r
+        * of the beginning of valid octets. Assign this address\r
+        * to the fragement address field of the RFD.\r
+        */\r
+       sp->RFDList[rfd].FragInfo = cpu_to_le64(\r
+                                        IPG_HOST2BUS_MAP(skb->data));\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       sp->RxBuffDMAhandle[rfd].len = IPG_RXSUPPORT_SIZE;\r
+       sp->RxBuffDMAhandle[rfd].dmahandle = pci_map_single(\r
+                                             sp->ipg_pci_device,\r
+                                             skb->data, IPG_RXSUPPORT_SIZE,\r
+                                             PCI_DMA_FROMDEVICE);\r
+       sp->RFDList[rfd].FragInfo = cpu_to_le64(\r
+                                       sp->RxBuffDMAhandle[rfd].dmahandle);\r
+#endif\r
+\r
+       /* Set the RFD fragment length. */\r
+       rxfragsize = IPG_RXFRAG_SIZE;\r
+       sp->RFDList[rfd].FragInfo |= cpu_to_le64((rxfragsize << 48) &\r
+                                                IPG_RFI_FRAGLEN);\r
+\r
+       return 0;\r
+}\r
+\r
+int    ipg_nic_stop(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Release resources requested by driver open function. */\r
+\r
+       int     i;\r
+       int     error;\r
+       u32     baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_nic_stop\n");\r
+       \r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)\r
+   netif_stop_queue(ipg_ethernet_device);\r
+   //netif_msg_ifdown(sp);\r
+#endif\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       IPG_DDEBUG_MSG("TFDunavailCount = %i\n", sp->TFDunavailCount);\r
+       IPG_DDEBUG_MSG("RFDlistendCount = %i\n", sp->RFDlistendCount);\r
+       IPG_DDEBUG_MSG("RFDListCheckedCount = %i\n", sp->RFDListCheckedCount);\r
+       IPG_DDEBUG_MSG("EmptyRFDListCount = %i\n", sp->EmptyRFDListCount);\r
+       IPG_DUMPTFDLIST(ipg_ethernet_device);\r
+\r
+       /* Reset all functions within the IPG to shut down the\r
+        IP1000* .\r
+        */\r
+       i = IPG_AC_GLOBAL_RESET | IPG_AC_RX_RESET |\r
+           IPG_AC_TX_RESET | IPG_AC_DMA |\r
+           IPG_AC_FIFO | IPG_AC_NETWORK |\r
+           IPG_AC_HOST | IPG_AC_AUTO_INIT;\r
+\r
+       error = ipg_reset(ipg_ethernet_device, i);\r
+       if (error < 0)\r
+       {\r
+               return error;\r
+       }\r
+\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       /* Decrement the usage count for this IPG driver module. */\r
+       MOD_DEC_USE_COUNT;\r
+#endif\r
+\r
+       /* Free all receive buffers. */\r
+       for(i=0; i<IPG_RFDLIST_LENGTH; i++)\r
+       {\r
+#ifdef IPG_LINUX2_4\r
+               pci_unmap_single(sp->ipg_pci_device,\r
+                                 sp->RxBuffDMAhandle[i].dmahandle,\r
+                                sp->RxBuffDMAhandle[i].len,\r
+                                PCI_DMA_FROMDEVICE);\r
+#endif\r
+               if (sp->RxBuff[i] != NULL)\r
+                       IPG_DEV_KFREE_SKB(sp->RxBuff[i]);\r
+               sp->RxBuff[i] = NULL;\r
+       }\r
+\r
+       /* Free all transmit buffers. */\r
+       for(i=0; i<IPG_TFDLIST_LENGTH; i++)\r
+       {\r
+               if (sp->TxBuff[i] != NULL)\r
+                       IPG_DEV_KFREE_SKB(sp->TxBuff[i]);\r
+               sp->TxBuff[i] = NULL;\r
+       }\r
+\r
+#ifdef IPG_LINUX2_2\r
+       ipg_ethernet_device->start = 0;\r
+       set_bit(0,(void*)&ipg_ethernet_device->tbusy);\r
+\r
+       /* Free memory associated with the RFDList. */\r
+       kfree(sp->RFDList);\r
+\r
+       /* Free memory associated with the TFDList. */\r
+       kfree(sp->TFDList);\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       netif_stop_queue(ipg_ethernet_device);\r
+\r
+       /* Free memory associated with the RFDList. */\r
+       pci_free_consistent(sp->ipg_pci_device,\r
+                            (sizeof(struct RFD) *\r
+                            IPG_RFDLIST_LENGTH),\r
+                           sp->RFDList, sp->RFDListDMAhandle);\r
+\r
+       /* Free memory associated with the TFDList. */\r
+       pci_free_consistent(sp->ipg_pci_device,\r
+                            (sizeof(struct TFD) *\r
+                            IPG_TFDLIST_LENGTH),\r
+                           sp->TFDList, sp->TFDListDMAhandle);\r
+#endif\r
+\r
+       /* Release interrupt line. */\r
+       free_irq(ipg_ethernet_device->irq, ipg_ethernet_device);\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)\r
+         return 0;\r
+#endif\r
+\r
+#ifdef USE_IO_OPS\r
+\r
+       /* Release I/O range reserved for IPG registers. */\r
+       release_region(ipg_ethernet_device->base_addr,\r
+                      IPG_IO_REG_RANGE);\r
+\r
+#else /* Not using I/O space. */\r
+\r
+       /* Unmap memory used for IPG registers. */\r
+\r
+       /* The following line produces strange results unless\r
+        * unregister_netdev precedes it.\r
+        */\r
+       iounmap((void *)ipg_ethernet_device->base_addr);\r
+\r
+#endif\r
+\r
+       return 0;\r
+}\r
+\r
+int    ipg_nic_hard_start_xmit(struct sk_buff *skb,\r
+                                 IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Transmit an Ethernet frame. */\r
+\r
+       u64                             fraglen;\r
+       u64                             vlanvid;\r
+       u64                             vlancfi;\r
+       u64                             vlanuserpriority;\r
+        unsigned long                   flags;\r
+       int                             NextTFD;\r
+       u32                             baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+        IPG_DDEBUG_MSG("_nic_hard_start_xmit\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+#ifdef IPG_LINUX2_2\r
+       /* If IPG NIC is already busy, return error. */\r
+       if (test_and_set_bit(0, (void*)&ipg_ethernet_device->tbusy) != 0)\r
+       {\r
+                IPG_DEBUG_MSG("Transmit busy!\n");\r
+\r
+               return -EBUSY;\r
+       }\r
+#endif\r
+\r
+        /* Disable interrupts. */\r
+        spin_lock_irqsave(&sp->lock, flags);\r
+\r
+#ifdef IPG_LINUX2_4\r
+       /* If in 10Mbps mode, stop the transmit queue so\r
+        * no more transmit frames are accepted.\r
+        */\r
+       if (sp->tenmbpsmode)\r
+       {\r
+               netif_stop_queue(ipg_ethernet_device);\r
+       }\r
+#endif\r
+\r
+       /* Next TFD is found by incrementing the CurrentTFD\r
+        * counter, modulus the length of the TFDList.\r
+        */\r
+       NextTFD = (sp->CurrentTFD + 1) % IPG_TFDLIST_LENGTH;\r
+\r
+       /* Check for availability of next TFD. */\r
+       if (!(le64_to_cpu(sp->TFDList[NextTFD].TFC) &\r
+             IPG_TFC_TFDDONE) || (NextTFD == sp->LastFreedTxBuff))\r
+       {\r
+               IPG_DEBUG_MSG("Next TFD not available.\n");\r
+\r
+               /* Attempt to free any used TFDs. */\r
+               ipg_nic_txfree(ipg_ethernet_device);\r
+\r
+#ifdef IPG_LINUX2_2\r
+                /* Transmit no longer busy. */\r
+               clear_bit(0,(void*)&ipg_ethernet_device->tbusy);\r
+#endif\r
+\r
+                /* Restore interrupts. */\r
+                spin_unlock_irqrestore(&sp->lock, flags);\r
+\r
+#ifdef IPG_DEBUG\r
+               /* Increment the TFDunavailCount counter. */\r
+               sp->TFDunavailCount++;\r
+#endif\r
+\r
+                return -ENOMEM;\r
+       }\r
+\r
+#ifdef IPG_LINUX2_4\r
+       sp->TxBuffDMAhandle[NextTFD].len = skb->len;\r
+       sp->TxBuffDMAhandle[NextTFD].dmahandle = pci_map_single(\r
+                                                 sp->ipg_pci_device,\r
+                                                 skb->data, skb->len,\r
+                                                 PCI_DMA_TODEVICE);\r
+#endif\r
+\r
+       /* Save the sk_buff pointer so interrupt handler can later free\r
+        * memory occupied by buffer.\r
+        */\r
+       sp->TxBuff[NextTFD] = skb;\r
+\r
+       /* Clear all TFC fields, except TFDDONE. */\r
+       sp->TFDList[NextTFD].TFC = cpu_to_le64(IPG_TFC_TFDDONE);\r
+\r
+       /* Specify the TFC field within the TFD. */\r
+       sp->TFDList[NextTFD].\r
+               TFC |= cpu_to_le64(IPG_TFC_WORDALIGNDISABLED |\r
+                                  (IPG_TFC_FRAMEID &\r
+                                   cpu_to_le64(sp->CurrentTxFrameID)) |\r
+                                  (IPG_TFC_FRAGCOUNT & (1 << 24)));\r
+\r
+       /* Request TxComplete interrupts at an interval defined\r
+        * by the constant IPG_FRAMESBETWEENTXCOMPLETES.\r
+        * Request TxComplete interrupt for every frame\r
+        * if in 10Mbps mode to accomodate problem with 10Mbps\r
+        * processing.\r
+        */\r
+       if (sp->tenmbpsmode)\r
+       {\r
+               sp->TFDList[NextTFD].TFC |=\r
+               cpu_to_le64(IPG_TFC_TXINDICATE);\r
+       }\r
+       else if ((sp->CurrentTxFrameID %\r
+                IPG_FRAMESBETWEENTXDMACOMPLETES) == 0)\r
+       {\r
+               sp->TFDList[NextTFD].TFC |=\r
+               cpu_to_le64(IPG_TFC_TXDMAINDICATE);\r
+       }\r
+\r
+        /* Based on compilation option, determine if FCS is to be\r
+         * appended to transmit frame by IPG.\r
+         */\r
+        if (!(IPG_APPEND_FCS_ON_TX))\r
+        {\r
+               sp->TFDList[NextTFD].\r
+                        TFC |= cpu_to_le64(IPG_TFC_FCSAPPENDDISABLE);\r
+        }\r
+\r
+        /* Based on compilation option, determine if IP, TCP and/or\r
+        * UDP checksums are to be added to transmit frame by IPG.\r
+         */\r
+        if (IPG_ADD_IPCHECKSUM_ON_TX)\r
+        {\r
+               sp->TFDList[NextTFD].\r
+                        TFC |= cpu_to_le64(IPG_TFC_IPCHECKSUMENABLE);\r
+        }\r
+        if (IPG_ADD_TCPCHECKSUM_ON_TX)\r
+        {\r
+               sp->TFDList[NextTFD].\r
+                        TFC |= cpu_to_le64(IPG_TFC_TCPCHECKSUMENABLE);\r
+        }\r
+        if (IPG_ADD_UDPCHECKSUM_ON_TX)\r
+        {\r
+               sp->TFDList[NextTFD].\r
+                        TFC |= cpu_to_le64(IPG_TFC_UDPCHECKSUMENABLE);\r
+        }\r
+\r
+        /* Based on compilation option, determine if VLAN tag info is to be\r
+         * inserted into transmit frame by IPG.\r
+         */\r
+        if (IPG_INSERT_MANUAL_VLAN_TAG)\r
+        {\r
+               vlanvid = IPG_MANUAL_VLAN_VID;\r
+               vlancfi = IPG_MANUAL_VLAN_CFI;\r
+               vlanuserpriority = IPG_MANUAL_VLAN_USERPRIORITY;\r
+\r
+               sp->TFDList[NextTFD].TFC |= cpu_to_le64(\r
+                                           IPG_TFC_VLANTAGINSERT |\r
+                                            (vlanvid << 32) |\r
+                                           (vlancfi << 44) |\r
+                                           (vlanuserpriority << 45));\r
+        }\r
+\r
+       /* The fragment start location within system memory is defined\r
+        * by the sk_buff structure's data field. The physical address\r
+        * of this location within the system's virtual memory space\r
+        * is determined using the IPG_HOST2BUS_MAP function.\r
+        */\r
+#ifdef IPG_LINUX2_2\r
+       sp->TFDList[NextTFD].FragInfo = cpu_to_le64(\r
+                                            IPG_HOST2BUS_MAP(skb->data));\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       sp->TFDList[NextTFD].FragInfo = cpu_to_le64(\r
+                                       sp->TxBuffDMAhandle[NextTFD].dmahandle);\r
+#endif\r
+\r
+       /* The length of the fragment within system memory is defined by\r
+        * the sk_buff structure's len field.\r
+        */\r
+       fraglen = (u16)skb->len;\r
+       sp->TFDList[NextTFD].FragInfo |= cpu_to_le64(IPG_TFI_FRAGLEN &\r
+                                        (fraglen << 48));\r
+\r
+       /* Clear the TFDDone bit last to indicate the TFD is ready\r
+        * for transfer to the IPG.\r
+        */\r
+       sp->TFDList[NextTFD].TFC &= cpu_to_le64(~IPG_TFC_TFDDONE);\r
+\r
+       /* Record frame transmit start time (jiffies = Linux\r
+        * kernel current time stamp).\r
+        */\r
+       ipg_ethernet_device->trans_start = jiffies;\r
+\r
+       /* Update current TFD indicator. */\r
+       sp->CurrentTFD = NextTFD;\r
+\r
+       /* Calculate the new ID for the next transmit frame by\r
+        * incrementing the CurrentTxFrameID counter.\r
+        */\r
+       sp->CurrentTxFrameID++;\r
+\r
+       /* Force a transmit DMA poll event. */\r
+       IPG_WRITE_DMACTRL(baseaddr, IPG_DC_TX_DMA_POLL_NOW);\r
+\r
+        /* Restore interrupts. */\r
+        spin_unlock_irqrestore(&sp->lock, flags);\r
+\r
+#ifdef IPG_LINUX2_2\r
+        /* Transmit no longer busy.\r
+        * If in 10Mbps mode, do not indicate transmit is free\r
+        * until receive TxComplete interrupt.\r
+        */\r
+       if (!(sp->tenmbpsmode))\r
+       {\r
+               clear_bit(0,(void*)&ipg_ethernet_device->tbusy);\r
+       }\r
+#endif\r
+\r
+       return 0;\r
+}\r
+\r
+#ifdef JUMBO_FRAME\r
+\r
+/* use jumboindex and jumbosize to control jumbo frame status\r
+   initial status is jumboindex=-1 and jumbosize=0\r
+   1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done.\r
+   2. jumboindex != -1 and jumbosize != 0 : jumbo frame is not over size and receiving\r
+   3. jumboindex = -1 and jumbosize != 0 : jumbo frame is over size, already dump\r
+                previous receiving and need to continue dumping the current one\r
+*/\r
+enum {NormalPacket,ErrorPacket};\r
+enum {Frame_NoStart_NoEnd=0,Frame_WithStart=1,Frame_WithEnd=10,Frame_WithStart_WithEnd=11};\r
+inline void ipg_nic_rx__FreeSkb(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)ipg_ethernet_device->priv;\r
+                                       if (sp->RxBuff[sp->CurrentRFD] != NULL)\r
+                               {\r
+#ifdef IPG_LINUX2_4\r
+                                               pci_unmap_single(sp->ipg_pci_device,sp->RxBuffDMAhandle[sp->CurrentRFD].dmahandle,sp->RxBuffDMAhandle[sp->CurrentRFD].len,PCI_DMA_FROMDEVICE);\r
+#endif\r
+                                               IPG_DEV_KFREE_SKB(sp->RxBuff[sp->CurrentRFD]);\r
+                                               sp->RxBuff[sp->CurrentRFD] = NULL;\r
+                               }               \r
+}\r
+inline int ipg_nic_rx__CheckFrameSEType(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)ipg_ethernet_device->priv;\r
+       int FoundStartEnd=0;\r
+       \r
+       if(le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS)&IPG_RFS_FRAMESTART)FoundStartEnd+=1;\r
+       if(le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS)&IPG_RFS_FRAMEEND)FoundStartEnd+=10;\r
+       return FoundStartEnd; //Frame_NoStart_NoEnd=0,Frame_WithStart=1,Frame_WithEnd=10,Frame_WithStart_WithEnd=11\r
+}\r
+inline int ipg_nic_rx__CheckError(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)ipg_ethernet_device->priv;\r
+       \r
+                                  if (IPG_DROP_ON_RX_ETH_ERRORS &&\r
+                               (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) &\r
+                               (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME |\r
+                                IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR |\r
+                            IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR)))\r
+                         {\r
+                                       IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n",\r
+                                          (unsigned long int) sp->RFDList[sp->CurrentRFD].RFS);\r
+\r
+                                       /* Increment general receive error statistic. */\r
+                                       sp->stats.rx_errors++;\r
+\r
+                                       /* Increment detailed receive error statistics. */\r
+                                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) & IPG_RFS_RXFIFOOVERRUN)\r
+                                       {\r
+                                               IPG_DEBUG_MSG("RX FIFO overrun occured.\n");\r
+\r
+                                               sp->stats.rx_fifo_errors++;\r
+\r
+                                               if (sp->RxBuffNotReady == 1)\r
+                                               {\r
+                                                       /* If experience a RxFIFO overrun, and\r
+                                                        * the RxBuffNotReady flag is set,\r
+                                                        * assume the FIFO overran due to lack\r
+                                                        * of an RFD.\r
+                                                        */\r
+                                                       sp->stats.rx_dropped++;\r
+                                               }\r
+                                       }\r
+\r
+                                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) & IPG_RFS_RXRUNTFRAME)\r
+                                       {\r
+                                               IPG_DEBUG_MSG("RX runt occured.\n");\r
+                                               sp->stats.rx_length_errors++;\r
+                                       }\r
+\r
+                                       /* Do nothing for IPG_RFS_RXOVERSIZEDFRAME,\r
+                                        * error count handled by a IPG statistic register.\r
+                                        */\r
+\r
+                                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) & IPG_RFS_RXALIGNMENTERROR)\r
+                                       {\r
+                                               IPG_DEBUG_MSG("RX alignment error occured.\n");\r
+                                               sp->stats.rx_frame_errors++;\r
+                                       }\r
+\r
+\r
+                                       /* Do nothing for IPG_RFS_RXFCSERROR, error count\r
+                                        * handled by a IPG statistic register.\r
+                                        */\r
+\r
+                                       /* Free the memory associated with the RX\r
+                                        * buffer since it is erroneous and we will\r
+                                        * not pass it to higher layer processes.\r
+                                        */\r
+                                       if (sp->RxBuff[sp->CurrentRFD] != NULL)\r
+                                       {\r
+#ifdef IPG_LINUX2_4\r
+                                               pci_unmap_single(sp->ipg_pci_device,\r
+                                 sp->RxBuffDMAhandle[sp->CurrentRFD].dmahandle,\r
+                                            sp->RxBuffDMAhandle[sp->CurrentRFD].len,\r
+                                            PCI_DMA_FROMDEVICE);\r
+#endif\r
+\r
+                                               IPG_DEV_KFREE_SKB(sp->RxBuff[sp->CurrentRFD]);\r
+                                               sp->RxBuff[sp->CurrentRFD] = NULL;\r
+                                       }\r
+                               return ErrorPacket;\r
+                         }\r
+                         return NormalPacket;\r
+}\r
+int ipg_nic_rx(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Transfer received Ethernet frames to higher network layers. */\r
+\r
+       int                             maxrfdcount;\r
+       int                             framelen;\r
+       int            ThisEndFrameLen;\r
+       u32                             baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+       struct sk_buff                  *skb;\r
+\r
+\r
+       IPG_DEBUG_MSG("_nic_rx\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       maxrfdcount = IPG_MAXRFDPROCESS_COUNT;\r
+\r
+    while(le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) & IPG_RFS_RFDDONE)\r
+    {\r
+               if (--maxrfdcount == 0)\r
+           {\r
+               /* There are more RFDs to process, however the\r
+                * allocated amount of RFD processing time has\r
+                        * expired. Assert Interrupt Requested to make\r
+                        * sure we come back to process the remaining RFDs.\r
+                */\r
+                   IPG_WRITE_ASICCTRL(baseaddr,\r
+                                          IPG_READ_ASICCTRL(baseaddr) |\r
+                                      IPG_AC_INT_REQUEST);\r
+                   break;\r
+        }\r
+\r
+                  switch(ipg_nic_rx__CheckFrameSEType(ipg_ethernet_device))\r
+                  { // Frame in one RFD\r
+//-----------\r
+                  case Frame_WithStart_WithEnd:        \r
+                       if(sp->Jumbo.FoundStart)\r
+                       {\r
+                                       IPG_DEV_KFREE_SKB(sp->Jumbo.skb);\r
+                                       sp->Jumbo.FoundStart=0;\r
+                               sp->Jumbo.CurrentSize=0;\r
+                               sp->Jumbo.skb=NULL;\r
+                       }\r
+                    if(ipg_nic_rx__CheckError(ipg_ethernet_device)==NormalPacket)//1: found error, 0 no error\r
+                         { // accept this frame and send to upper layer\r
+                                       skb = sp->RxBuff[sp->CurrentRFD];\r
+                                       if(skb)\r
+                                       {\r
+                                               framelen=le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) & IPG_RFS_RXFRAMELEN;\r
+                                               if (framelen > IPG_RXFRAG_SIZE) framelen=IPG_RXFRAG_SIZE;\r
+                                               skb_put(skb, framelen);\r
+                                               /* Set the buffer's protocol field to Ehternet */\r
+                                               skb->protocol=eth_type_trans(skb, ipg_ethernet_device);\r
+                                               /* Not handle TCP/UDP/IP checksum */\r
+                                               skb->ip_summed=CHECKSUM_NONE;\r
+                                               netif_rx(skb);\r
+                                               ipg_ethernet_device->last_rx=jiffies;\r
+                                               sp->RxBuff[sp->CurrentRFD] = NULL;\r
+                                       }\r
+                         }//if(ipg_nic_rx__CheckError(ipg_ethernet_device)==0)//1: found error, 0 no error\r
+                       break;//case Frame_WithStart_WithEnd:   \r
+//-----------\r
+                       case Frame_WithStart: \r
+                    if(ipg_nic_rx__CheckError(ipg_ethernet_device)==NormalPacket)//1: found error, 0 no error\r
+                         { // accept this frame and send to upper layer\r
+                                       skb = sp->RxBuff[sp->CurrentRFD];\r
+                                       if(skb)\r
+                                       {\r
+                                               if(sp->Jumbo.FoundStart)\r
+                                               {\r
+                                                       IPG_DEV_KFREE_SKB(sp->Jumbo.skb);\r
+                                               }\r
+#ifdef IPG_LINUX2_4\r
+                               pci_unmap_single(sp->ipg_pci_device,\r
+                                 sp->RxBuffDMAhandle[sp->CurrentRFD].dmahandle,\r
+                                sp->RxBuffDMAhandle[sp->CurrentRFD].len,\r
+                                PCI_DMA_FROMDEVICE);\r
+#endif\r
+                                               sp->Jumbo.FoundStart=1;\r
+                                               sp->Jumbo.CurrentSize=IPG_RXFRAG_SIZE;                                                  \r
+                                               sp->Jumbo.skb=skb;\r
+                                               skb_put(sp->Jumbo.skb, IPG_RXFRAG_SIZE);\r
+                                                       sp->RxBuff[sp->CurrentRFD] = NULL;\r
+                                                       ipg_ethernet_device->last_rx=jiffies;\r
+                                       }\r
+                         }//if(ipg_nic_rx__CheckError(ipg_ethernet_device)==0)//1: found error, 0 no error\r
+                       break;//case Frame_WithStart: \r
+//-----------\r
+                       case Frame_WithEnd: \r
+                    if(ipg_nic_rx__CheckError(ipg_ethernet_device)==NormalPacket)//1: found error, 0 no error\r
+                         { // accept this frame and send to upper layer\r
+                                       skb = sp->RxBuff[sp->CurrentRFD];\r
+                                       if(skb)\r
+                                       {\r
+                                               if(sp->Jumbo.FoundStart)\r
+                                               {\r
+                                                       framelen=le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) & IPG_RFS_RXFRAMELEN;\r
+                                                       ThisEndFrameLen=framelen-sp->Jumbo.CurrentSize;\r
+                                                       //if (framelen > IPG_RXFRAG_SIZE) framelen=IPG_RXFRAG_SIZE;\r
+                                                       if(framelen>IPG_RXSUPPORT_SIZE)\r
+                                                       {\r
+                                                               IPG_DEV_KFREE_SKB(sp->Jumbo.skb);\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               memcpy(skb_put(sp->Jumbo.skb,ThisEndFrameLen),skb->data,ThisEndFrameLen);\r
+                                                               /* Set the buffer's protocol field to Ehternet */\r
+                                                               sp->Jumbo.skb->protocol=eth_type_trans(sp->Jumbo.skb, ipg_ethernet_device);\r
+                                                               /* Not handle TCP/UDP/IP checksum */\r
+                                                               sp->Jumbo.skb->ip_summed=CHECKSUM_NONE;\r
+                                                               netif_rx(sp->Jumbo.skb);                                                        \r
+                                                       }                                                       \r
+                                               }//"if(sp->Jumbo.FoundStart)"\r
+                                               \r
+                                               ipg_ethernet_device->last_rx=jiffies;\r
+                                               sp->Jumbo.FoundStart=0;\r
+                                       sp->Jumbo.CurrentSize=0;\r
+                                       sp->Jumbo.skb=NULL;\r
+                                       //Free this buffer(JC-ADVANCE)\r
+                                               ipg_nic_rx__FreeSkb(ipg_ethernet_device);\r
+                                       }//"if(skb)"\r
+                         }//"if(ipg_nic_rx__CheckError(ipg_ethernet_device)==0)//1: found error, 0 no error"\r
+                         else\r
+                         {\r
+                                       IPG_DEV_KFREE_SKB(sp->Jumbo.skb);\r
+                                       sp->Jumbo.FoundStart=0;\r
+                               sp->Jumbo.CurrentSize=0;\r
+                               sp->Jumbo.skb=NULL;\r
+                         }\r
+                       break;//case Frame_WithEnd:\r
+//-----------\r
+                       case Frame_NoStart_NoEnd: \r
+                    if(ipg_nic_rx__CheckError(ipg_ethernet_device)==NormalPacket)//1: found error, 0 no error\r
+                         { // accept this frame and send to upper layer\r
+                                       skb = sp->RxBuff[sp->CurrentRFD];\r
+                                       if(skb)\r
+                                       {\r
+                                               if(sp->Jumbo.FoundStart)\r
+                                               {\r
+                                                       //if (framelen > IPG_RXFRAG_SIZE) framelen=IPG_RXFRAG_SIZE;\r
+                                                       sp->Jumbo.CurrentSize+=IPG_RXFRAG_SIZE;\r
+                                                       if(sp->Jumbo.CurrentSize>IPG_RXSUPPORT_SIZE)\r
+                                                       {\r
+                                                               /*IPG_DEV_KFREE_SKB(sp->Jumbo.skb);\r
+                                                               sp->Jumbo.FoundStart=0;\r
+                                                       sp->Jumbo.CurrentSize=0;\r
+                                                       sp->Jumbo.skb=NULL;*/\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               memcpy(skb_put(sp->Jumbo.skb,IPG_RXFRAG_SIZE),skb->data,IPG_RXFRAG_SIZE);\r
+                                                       }\r
+                                               }//"if(sp->Jumbo.FoundStart)"\r
+                                               ipg_ethernet_device->last_rx=jiffies;\r
+                                               ipg_nic_rx__FreeSkb(ipg_ethernet_device);\r
+                                       }\r
+                         }//if(ipg_nic_rx__CheckError(ipg_ethernet_device)==0)//1: found error, 0 no error\r
+                         else\r
+                         {\r
+                                       IPG_DEV_KFREE_SKB(sp->Jumbo.skb);\r
+                                       sp->Jumbo.FoundStart=0;\r
+                               sp->Jumbo.CurrentSize=0;\r
+                               sp->Jumbo.skb=NULL;\r
+                         }\r
+                       break;//case Frame_NoStart_NoEnd:\r
+                       }//switch(ipg_nic_rx__CheckFrameSEType(ipg_ethernet_device))\r
+\r
+           sp->CurrentRFD = (sp->CurrentRFD+1) % IPG_RFDLIST_LENGTH;\r
+       } /* end of while(IPG_RFS_RFDDONE)*/\r
+       \r
+       ipg_nic_rxrestore(ipg_ethernet_device);\r
+       return 0;\r
+}\r
+\r
+\r
+#else\r
+int ipg_nic_rx(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Transfer received Ethernet frames to higher network layers. */\r
+\r
+       int                             maxrfdcount;\r
+       int                             framelen;\r
+       u32                             baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+       struct sk_buff                  *skb;\r
+\r
+       IPG_DEBUG_MSG("_nic_rx\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       maxrfdcount = IPG_MAXRFDPROCESS_COUNT;\r
+\r
+       while((le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS)) &\r
+              IPG_RFS_RFDDONE &&\r
+             (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS)) &\r
+              IPG_RFS_FRAMESTART &&\r
+             (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS)) &\r
+              IPG_RFS_FRAMEEND &&\r
+             (sp->RxBuff[sp->CurrentRFD] != NULL))\r
+       {\r
+                if (--maxrfdcount == 0)\r
+                {\r
+                        /* There are more RFDs to process, however the\r
+                        * allocated amount of RFD processing time has\r
+                        * expired. Assert Interrupt Requested to make\r
+                        * sure we come back to process the remaining RFDs.\r
+                         */\r
+                        IPG_WRITE_ASICCTRL(baseaddr,\r
+                                             IPG_READ_ASICCTRL(baseaddr) |\r
+                                              IPG_AC_INT_REQUEST);\r
+                        break;\r
+                }\r
+\r
+               /* Get received frame length. */\r
+               framelen = le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS) &\r
+                               IPG_RFS_RXFRAMELEN;\r
+\r
+               /* Check for jumbo frame arrival with too small\r
+                * RXFRAG_SIZE.\r
+                */\r
+               if (framelen > IPG_RXFRAG_SIZE)\r
+               {\r
+                       IPG_DEBUG_MSG("RFS FrameLen > allocated fragment size.\n");\r
+\r
+                       framelen = IPG_RXFRAG_SIZE;\r
+               }\r
+\r
+               /* Get the received frame buffer. */\r
+               skb = sp->RxBuff[sp->CurrentRFD];\r
+\r
+               if ((IPG_DROP_ON_RX_ETH_ERRORS &&\r
+                    (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                     (IPG_RFS_RXFIFOOVERRUN |\r
+                      IPG_RFS_RXRUNTFRAME |\r
+                      IPG_RFS_RXALIGNMENTERROR |\r
+                      IPG_RFS_RXFCSERROR |\r
+                      IPG_RFS_RXOVERSIZEDFRAME |\r
+                      IPG_RFS_RXLENGTHERROR)))))\r
+               {\r
+\r
+                       IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n", (unsigned long int) sp->RFDList[sp->CurrentRFD].RFS);\r
+\r
+                       /* Increment general receive error statistic. */\r
+                       sp->stats.rx_errors++;\r
+\r
+                       /* Increment detailed receive error statistics. */\r
+                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                           IPG_RFS_RXFIFOOVERRUN))\r
+                       {\r
+                               IPG_DEBUG_MSG("RX FIFO overrun occured.\n");\r
+\r
+                               sp->stats.rx_fifo_errors++;\r
+\r
+                               if (sp->RxBuffNotReady == 1)\r
+                               {\r
+                                       /* If experience a RxFIFO overrun, and\r
+                                        * the RxBuffNotReady flag is set,\r
+                                        * assume the FIFO overran due to lack\r
+                                        * of an RFD.\r
+                                        */\r
+                                       sp->stats.rx_dropped++;\r
+                               }\r
+                       }\r
+\r
+                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                           IPG_RFS_RXRUNTFRAME))\r
+                       {\r
+                               IPG_DEBUG_MSG("RX runt occured.\n");\r
+                               sp->stats.rx_length_errors++;\r
+                       }\r
+\r
+                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                           IPG_RFS_RXOVERSIZEDFRAME));\r
+                       /* Do nothing, error count handled by a IPG\r
+                        * statistic register.\r
+                        */\r
+\r
+                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                           IPG_RFS_RXALIGNMENTERROR))\r
+                       {\r
+                               IPG_DEBUG_MSG("RX alignment error occured.\n");\r
+                               sp->stats.rx_frame_errors++;\r
+                       }\r
+\r
+\r
+                       if (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                           IPG_RFS_RXFCSERROR));\r
+                       /* Do nothing, error count handled by a IPG\r
+                        * statistic register.\r
+                        */\r
+\r
+                       /* Free the memory associated with the RX\r
+                        * buffer since it is erroneous and we will\r
+                        * not pass it to higher layer processes.\r
+                        */\r
+                       if (sp->RxBuff[sp->CurrentRFD] != NULL)\r
+                       {\r
+#ifdef IPG_LINUX2_4\r
+                               pci_unmap_single(sp->ipg_pci_device,\r
+                                 sp->RxBuffDMAhandle[sp->CurrentRFD].dmahandle,\r
+                                sp->RxBuffDMAhandle[sp->CurrentRFD].len,\r
+                                PCI_DMA_FROMDEVICE);\r
+#endif\r
+\r
+                               IPG_DEV_KFREE_SKB(sp->RxBuff[sp->CurrentRFD]);\r
+                       }\r
+\r
+               }\r
+               else\r
+               {\r
+\r
+                       /* Adjust the new buffer length to accomodate the size\r
+                        * of the received frame.\r
+                        */\r
+                       skb_put(skb, framelen);\r
+\r
+                       /* Set the buffer's protocol field to Ethernet. */\r
+                       skb->protocol = eth_type_trans(skb,\r
+                                                      ipg_ethernet_device);\r
+\r
+                       /* If the frame contains an IP/TCP/UDP frame,\r
+                        * determine if upper layer must check IP/TCP/UDP\r
+                        * checksums.\r
+                        *\r
+                        * NOTE: DO NOT RELY ON THE TCP/UDP CHECKSUM\r
+                        *       VERIFICATION FOR SILICON REVISIONS B3\r
+                        *       AND EARLIER!\r
+                        *\r
+                       if ((le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                            (IPG_RFS_TCPDETECTED |\r
+                             IPG_RFS_UDPDETECTED |\r
+                             IPG_RFS_IPDETECTED))) &&\r
+                           !(le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+                             (IPG_RFS_TCPERROR |\r
+                              IPG_RFS_UDPERROR |\r
+                              IPG_RFS_IPERROR))))\r
+                       {\r
+                               * Indicate IP checksums were performed\r
+                                * by the IPG.\r
+                                *\r
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;\r
+                       }\r
+                       else\r
+                       */\r
+                       if (1==1)\r
+                       {\r
+                               /* The IPG encountered an error with (or\r
+                                * there were no) IP/TCP/UDP checksums.\r
+                                * This may or may not indicate an invalid\r
+                                * IP/TCP/UDP frame was received. Let the\r
+                                * upper layer decide.\r
+                                */\r
+                               skb->ip_summed = CHECKSUM_NONE;\r
+                       }\r
+\r
+                       /* Hand off frame for higher layer processing.\r
+                        * The function netif_rx() releases the sk_buff\r
+                        * when processing completes.\r
+                        */\r
+                       netif_rx(skb);\r
+\r
+                       /* Record frame receive time (jiffies = Linux\r
+                        * kernel current time stamp).\r
+                        */\r
+                       ipg_ethernet_device->last_rx = jiffies;\r
+               }\r
+\r
+               /* Assure RX buffer is not reused by IPG. */\r
+               sp->RxBuff[sp->CurrentRFD] = NULL;\r
+\r
+               /* Increment the current RFD counter. */\r
+               sp->CurrentRFD = (sp->CurrentRFD + 1) % IPG_RFDLIST_LENGTH;\r
+\r
+       }\r
+\r
+\r
+#ifdef IPG_DEBUG\r
+       /* Check if the RFD list contained no receive frame data. */\r
+       if (maxrfdcount == IPG_MAXRFDPROCESS_COUNT)\r
+       {\r
+               sp->EmptyRFDListCount++;\r
+       }\r
+#endif\r
+       while((le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+              IPG_RFS_RFDDONE)) &&\r
+             !((le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+              IPG_RFS_FRAMESTART)) &&\r
+             (le64_to_cpu(sp->RFDList[sp->CurrentRFD].RFS &\r
+              IPG_RFS_FRAMEEND))))\r
+       {\r
+               IPG_DEBUG_MSG("Frame requires multiple RFDs.\n");\r
+\r
+               /* An unexpected event, additional code needed to handle\r
+                * properly. So for the time being, just disregard the\r
+                * frame.\r
+                */\r
+\r
+               /* Free the memory associated with the RX\r
+                * buffer since it is erroneous and we will\r
+                * not pass it to higher layer processes.\r
+                */\r
+               if (sp->RxBuff[sp->CurrentRFD] != NULL)\r
+               {\r
+#ifdef IPG_LINUX2_4\r
+                       pci_unmap_single(sp->ipg_pci_device,\r
+                                sp->RxBuffDMAhandle[sp->CurrentRFD].dmahandle,\r
+                               sp->RxBuffDMAhandle[sp->CurrentRFD].len,\r
+                               PCI_DMA_FROMDEVICE);\r
+#endif\r
+                       IPG_DEV_KFREE_SKB(sp->RxBuff[sp->CurrentRFD]);\r
+               }\r
+\r
+               /* Assure RX buffer is not reused by IPG. */\r
+               sp->RxBuff[sp->CurrentRFD] = NULL;\r
+\r
+               /* Increment the current RFD counter. */\r
+               sp->CurrentRFD = (sp->CurrentRFD + 1) % IPG_RFDLIST_LENGTH;\r
+       }\r
+\r
+        /* Check to see if there are a minimum number of used\r
+         * RFDs before restoring any (should improve performance.)\r
+         */\r
+        if (((sp->CurrentRFD > sp->LastRestoredRxBuff) &&\r
+             ((sp->LastRestoredRxBuff + IPG_MINUSEDRFDSTOFREE) <=\r
+              sp->CurrentRFD)) ||\r
+            ((sp->CurrentRFD < sp->LastRestoredRxBuff) &&\r
+             ((sp->LastRestoredRxBuff + IPG_MINUSEDRFDSTOFREE) <=\r
+              (sp->CurrentRFD + IPG_RFDLIST_LENGTH))))\r
+        {\r
+               ipg_nic_rxrestore(ipg_ethernet_device);\r
+       }\r
+\r
+       return 0;\r
+}\r
+#endif\r
+int ipg_nic_rxrestore(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Restore used receive buffers. */\r
+\r
+       int                             i;\r
+       struct ipg_nic_private        *sp = (struct ipg_nic_private *)\r
+                                       ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_nic_rxrestore\n");\r
+\r
+       /* Assume receive buffers will be available. */\r
+       sp->RxBuffNotReady = 0;\r
+\r
+        while (sp->RxBuff[i = ((sp->LastRestoredRxBuff + 1) %\r
+               IPG_RFDLIST_LENGTH)] == NULL)\r
+       {\r
+               /* Generate a new receive buffer to replace the\r
+                * current buffer (which will be released by the\r
+                * Linux system).\r
+                */\r
+               if (ipg_get_rxbuff(ipg_ethernet_device, i) < 0)\r
+               {\r
+                       IPG_DEBUG_MSG("Cannot allocate new Rx buffer.\n");\r
+\r
+                       /* Mark a flag indicating a receive buffer\r
+                        * was not available. Use this flag to update\r
+                        * the rx_dropped Linux statistic.\r
+                        */\r
+                       sp->RxBuffNotReady = 1;\r
+\r
+                       break;\r
+               }\r
+\r
+               /* Reset the RFS field. */\r
+               sp->RFDList[i].RFS = 0x0000000000000000;\r
+\r
+               sp->LastRestoredRxBuff = i;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+IPG_STATS_TYPE* ipg_nic_get_stats(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Provides statistical information about the IPG NIC. */\r
+\r
+       u16                             temp1;\r
+       u16                             temp2;\r
+       u32                             baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_nic_get_stats\n");\r
+\r
+       /* Check to see if the NIC has been initialized via nic_open,\r
+        * before trying to read statistic registers.\r
+        */\r
+#ifdef IPG_LINUX2_2\r
+       if (ipg_ethernet_device->start == 0)\r
+       {\r
+#endif\r
+#ifdef IPG_LINUX2_4\r
+       if (!test_bit(__LINK_STATE_START, &ipg_ethernet_device->state))\r
+       {\r
+#endif\r
+               return &sp->stats;\r
+       }\r
+\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+        sp->stats.rx_packets += IPG_READ_FRAMESRCVDOK(baseaddr);\r
+        sp->stats.tx_packets += IPG_READ_FRAMESXMTDOK(baseaddr);\r
+        sp->stats.rx_bytes   += IPG_READ_OCTETRCVOK(baseaddr);\r
+        sp->stats.tx_bytes   += IPG_READ_OCTETXMTOK(baseaddr);\r
+       temp1 = IPG_READ_FRAMESLOSTRXERRORS(baseaddr);\r
+        sp->stats.rx_errors  += temp1;\r
+        sp->stats.rx_missed_errors += temp1;\r
+       temp1 = IPG_READ_SINGLECOLFRAMES(baseaddr) +\r
+               IPG_READ_MULTICOLFRAMES(baseaddr) +\r
+               IPG_READ_LATECOLLISIONS(baseaddr);\r
+       temp2 = IPG_READ_CARRIERSENSEERRORS(baseaddr);\r
+        sp->stats.collisions += temp1;\r
+       sp->stats.tx_dropped += IPG_READ_FRAMESABORTXSCOLLS(baseaddr);\r
+        sp->stats.tx_errors  += IPG_READ_FRAMESWEXDEFERRAL(baseaddr) +\r
+                               IPG_READ_FRAMESWDEFERREDXMT(baseaddr) +\r
+                               temp1 + temp2;\r
+        sp->stats.multicast  += IPG_READ_MCSTOCTETRCVDOK(baseaddr);\r
+\r
+        /* detailed tx_errors */\r
+        sp->stats.tx_carrier_errors += temp2;\r
+\r
+        /* detailed rx_errors */\r
+       sp->stats.rx_length_errors += IPG_READ_INRANGELENGTHERRORS(baseaddr) +\r
+                                     IPG_READ_FRAMETOOLONGERRRORS(baseaddr);\r
+       sp->stats.rx_crc_errors += IPG_READ_FRAMECHECKSEQERRORS(baseaddr);\r
+\r
+       /* Unutilized IPG statistic registers. */\r
+       IPG_READ_MCSTFRAMESRCVDOK(baseaddr);\r
+\r
+        /* Masked IPG statistic registers (need not be read to clear)\r
+       IPG_READ_MACCONTROLFRAMESXMTDOK(baseaddr);\r
+       IPG_READ_BCSTFRAMESXMTDOK(baseaddr);\r
+       IPG_READ_MCSTFRAMESXMTDOK(baseaddr);\r
+       IPG_READ_BCSTOCTETXMTOK(baseaddr);\r
+       IPG_READ_MCSTOCTETXMTOK(baseaddr);\r
+       IPG_READ_MACCONTROLFRAMESRCVD(baseaddr);\r
+       IPG_READ_BCSTFRAMESRCVDOK(baseaddr);\r
+       IPG_READ_BCSTOCTETRCVOK(baseaddr);\r
+       IPG_READ_TXJUMBOFRAMES(baseaddr);\r
+       IPG_READ_UDPCHECKSUMERRORS(baseaddr);\r
+       IPG_READ_IPCHECKSUMERRORS(baseaddr);\r
+       IPG_READ_TCPCHECKSUMERRORS(baseaddr);\r
+       IPG_READ_RXJUMBOFRAMES(baseaddr);\r
+       */\r
+\r
+\r
+       /* Unutilized RMON statistic registers. */\r
+\r
+        /* Masked IPG statistic registers (need not be read to clear)\r
+       IPG_READ_ETHERSTATSCOLLISIONS(baseaddr);\r
+       IPG_READ_ETHERSTATSOCTETSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS64OCTESTSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS65TO127OCTESTSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS128TO255OCTESTSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS256TO511OCTESTSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS512TO1023OCTESTSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS1024TO1518OCTESTSTRANSMIT(baseaddr);\r
+       IPG_READ_ETHERSTATSCRCALIGNERRORS(baseaddr);\r
+       IPG_READ_ETHERSTATSUNDERSIZEPKTS(baseaddr);\r
+       IPG_READ_ETHERSTATSFRAGMENTS(baseaddr);\r
+       IPG_READ_ETHERSTATSJABBERS(baseaddr);\r
+       IPG_READ_ETHERSTATSOCTETS(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS64OCTESTS(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS65TO127OCTESTS(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS128TO255OCTESTS(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS256TO511OCTESTS(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS512TO1023OCTESTS(baseaddr);\r
+       IPG_READ_ETHERSTATSPKTS1024TO1518OCTESTS(baseaddr);\r
+       */\r
+\r
+       return &sp->stats;\r
+}\r
+\r
+void ipg_nic_set_multicast_list(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Determine and configure multicast operation and set\r
+        * receive mode for IPG.\r
+        */\r
+       u8                      receivemode;\r
+       u32                     hashtable[2];\r
+       unsigned int            hashindex;\r
+       u32                     baseaddr;\r
+       struct dev_mc_list      *mc_list_ptr;\r
+\r
+\r
+       IPG_DEBUG_MSG("_nic_set_multicast_list\n");\r
+\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+       receivemode = IPG_RM_RECEIVEUNICAST |\r
+                     IPG_RM_RECEIVEBROADCAST;\r
+\r
+       if (ipg_ethernet_device->flags & IFF_PROMISC)\r
+       {\r
+               /* NIC to be configured in promiscuous mode. */\r
+               receivemode = IPG_RM_RECEIVEALLFRAMES;\r
+       }\r
+       else if ((ipg_ethernet_device->flags & IFF_ALLMULTI) ||\r
+                (ipg_ethernet_device->flags & IFF_MULTICAST &\r
+                 (ipg_ethernet_device->mc_count >\r
+                  IPG_MULTICAST_HASHTABLE_SIZE)))\r
+       {\r
+               /* NIC to be configured to receive all multicast\r
+                * frames. */\r
+               receivemode |= IPG_RM_RECEIVEMULTICAST;\r
+       }\r
+       else if (ipg_ethernet_device->flags & IFF_MULTICAST &\r
+           (ipg_ethernet_device->mc_count > 0))\r
+       {\r
+               /* NIC to be configured to receive selected\r
+                * multicast addresses. */\r
+               receivemode |= IPG_RM_RECEIVEMULTICASTHASH;\r
+       }\r
+\r
+       /* Calculate the bits to set for the 64 bit, IPG HASHTABLE.\r
+        * The IPG applies a cyclic-redundancy-check (the same CRC\r
+        * used to calculate the frame data FCS) to the destination\r
+        * address all incoming multicast frames whose destination\r
+        * address has the multicast bit set. The least significant\r
+        * 6 bits of the CRC result are used as an addressing index\r
+        * into the hash table. If the value of the bit addressed by\r
+        * this index is a 1, the frame is passed to the host system.\r
+        */\r
+\r
+       /* Clear hashtable. */\r
+       hashtable[0] = 0x00000000;\r
+       hashtable[1] = 0x00000000;\r
+\r
+       /* Cycle through all multicast addresses to filter.*/\r
+       for (mc_list_ptr = ipg_ethernet_device->mc_list;\r
+            mc_list_ptr != NULL;\r
+            mc_list_ptr = mc_list_ptr->next)\r
+       {\r
+               /* Calculate CRC result for each multicast address. */\r
+               hashindex = ether_crc_le(ETH_ALEN, mc_list_ptr->dmi_addr);\r
+\r
+               /* Use only the least significant 6 bits. */\r
+               hashindex = hashindex & 0x3F;\r
+\r
+               /* Within "hashtable", set bit number "hashindex"\r
+                * to a logic 1.\r
+                */\r
+               set_bit(hashindex, (void*)hashtable);\r
+       }\r
+\r
+       /* Write the value of the hashtable, to the 4, 16 bit\r
+        * HASHTABLE IPG registers.\r
+        */\r
+       IPG_WRITE_HASHTABLE0(baseaddr, hashtable[0]);\r
+       IPG_WRITE_HASHTABLE1(baseaddr, hashtable[1]);\r
+\r
+       IPG_WRITE_RECEIVEMODE(baseaddr, receivemode);\r
+\r
+       IPG_DEBUG_MSG("ReceiveMode = %x\n",IPG_READ_RECEIVEMODE(baseaddr));\r
+\r
+       return;\r
+}\r
+\r
+/*\r
+ * The following code fragment was authored by Donald Becker.\r
+ */\r
+\r
+/* The little-endian AUTODIN II ethernet CRC calculations.\r
+   A big-endian version is also available.\r
+   This is slow but compact code.  Do not use this routine for bulk data,\r
+   use a table-based routine instead.\r
+   This is common code and should be moved to net/core/crc.c.\r
+   Chips may use the upper or lower CRC bits, and may reverse and/or invert\r
+   them.  Select the endian-ness that results in minimal calculations.\r
+*/\r
+unsigned const ethernet_polynomial_le = 0xedb88320U;\r
+unsigned ether_crc_le(int length, unsigned char *data)\r
+{\r
+        unsigned int crc = 0xffffffff;  /* Initial value. */\r
+        while(--length >= 0) {\r
+                unsigned char current_octet = *data++;\r
+                int bit;\r
+                for (bit = 8; --bit >= 0; current_octet >>= 1) {\r
+                        if ((crc ^ current_octet) & 1) {\r
+                                crc >>= 1;\r
+                                crc ^= ethernet_polynomial_le;\r
+                        } else\r
+                                crc >>= 1;\r
+                }\r
+        }\r
+        return crc;\r
+}\r
+/*\r
+ * End of code fragment authored by Donald Becker.\r
+ */\r
+\r
+int ipg_nic_init(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+       /* Initialize IPG NIC. */\r
+\r
+       struct ipg_nic_private  *sp = NULL;\r
+\r
+       IPG_DEBUG_MSG("_nic_init\n");\r
+\r
+       /* Register the IPG NIC in the list of Ethernet devices. */\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       ipg_ethernet_device = init_etherdev(ipg_ethernet_device,\r
+                                sizeof(struct ipg_nic_private));\r
+#else\r
+   ipg_ethernet_device=alloc_etherdev(sizeof(struct ipg_nic_private));\r
+#endif\r
+\r
+       if (ipg_ethernet_device == NULL)\r
+       {\r
+               printk(KERN_INFO "Could not initialize IP1000 based NIC.\n");\r
+               return -ENODEV;\r
+       }\r
+\r
+       /* Reserve memory for ipg_nic_private structure. */\r
+       sp = kmalloc(sizeof(struct ipg_nic_private),\r
+                           GFP_KERNEL);\r
+\r
+       if (sp == NULL)\r
+       {\r
+               printk(KERN_INFO "%s: No memory available for IP1000 private strucutre.\n", ipg_ethernet_device->name);\r
+               return -ENOMEM;\r
+       }\r
+       else\r
+       {\r
+               /* Fill the allocated memory space with 0s.\r
+                * Essentially sets all ipg_nic_private\r
+                * structure fields to 0.\r
+                */\r
+               memset(sp, 0, sizeof(*sp));\r
+               ipg_ethernet_device->priv = sp;\r
+       }\r
+\r
+       /* Assign the new device to the list of IPG Ethernet devices. */\r
+       sp->next_ipg_ethernet_device = root_ipg_ethernet_device;\r
+       root_ipg_ethernet_device = ipg_ethernet_device;\r
+\r
+       /* Declare IPG NIC functions for Ethernet device methods.\r
+        */\r
+       ipg_ethernet_device->open = &ipg_nic_open;\r
+       ipg_ethernet_device->stop = &ipg_nic_stop;\r
+       ipg_ethernet_device->hard_start_xmit = &ipg_nic_hard_start_xmit;\r
+       ipg_ethernet_device->get_stats = &ipg_nic_get_stats;\r
+       ipg_ethernet_device->set_multicast_list =\r
+         &ipg_nic_set_multicast_list;\r
+       ipg_ethernet_device->do_ioctl = & ipg_nic_do_ioctl;\r
+       /* rebuild_header not defined. */\r
+       /* hard_header not defined. */\r
+       /* set_config not defined */\r
+       /* set_mac_address not defined. */\r
+       /* header_cache_bind not defined. */\r
+       /* header_cache_update not defined. */\r
+        ipg_ethernet_device->change_mtu = &ipg_nic_change_mtu;\r
+#ifdef IPG_LINUX2_4\r
+        /* ipg_ethernet_device->tx_timouet not defined. */\r
+        /* ipg_ethernet_device->watchdog_timeo not defined. */\r
+#endif\r
+\r
+       return 0;\r
+}\r
+\r
+int ipg_nic_do_ioctl(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                        struct ifreq *req, int cmd)\r
+{\r
+       /* IOCTL commands for IPG NIC.\r
+        *\r
+        * SIOCDEVPRIVATE       nothing\r
+        * SIOCDEVPRIVATE+1     register read\r
+        *                      ifr_data[0] = 0x08, 0x10, 0x20\r
+        *                      ifr_data[1] = register offset\r
+        *                      ifr_data[2] = value read\r
+        * SIOCDEVPRIVATE+2     register write\r
+        *                      ifr_data[0] = 0x08, 0x10, 0x20\r
+        *                      ifr_data[1] = register offset\r
+        *                      ifr_data[2] = value to write\r
+        * SIOCDEVPRIVATE+3     GMII register read\r
+        *                      ifr_data[1] = register offset\r
+        * SIOCDEVPRIVATE+4     GMII register write\r
+        *                      ifr_data[1] = register offset\r
+        *                      ifr_data[2] = value to write\r
+        * SIOCDEVPRIVATE+5     PCI register read\r
+        *                      ifr_data[0] = 0x08, 0x10, 0x20\r
+        *                      ifr_data[1] = register offset\r
+        *                      ifr_data[2] = value read\r
+        * SIOCDEVPRIVATE+6     PCI register write\r
+        *                      ifr_data[0] = 0x08, 0x10, 0x20\r
+        *                      ifr_data[1] = register offset\r
+        *                      ifr_data[2] = value to write\r
+        *\r
+        */\r
+\r
+       u8                              val8;\r
+       u16                             val16;\r
+       u32                             val32;\r
+       unsigned int                    *data;\r
+        int                             phyaddr = 0;\r
+       u32                             baseaddr;\r
+       struct ipg_nic_private  *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+\r
+       IPG_DEBUG_MSG("_nic_do_ioctl\n");\r
+\r
+        data = (unsigned int *)&req->ifr_data;\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+\r
+        switch(cmd)\r
+       {\r
+               case SIOCDEVPRIVATE:\r
+               return 0;\r
+\r
+               case SIOCDEVPRIVATE+1:\r
+               switch(data[0])\r
+               {\r
+                       case 0x08:\r
+                       data[2] = IPG_READ_BYTEREG(baseaddr + data[1]);\r
+                       return 0;\r
+\r
+                       case 0x10:\r
+                       data[2] = IPG_READ_WORDREG(baseaddr + data[1]);\r
+                       return 0;\r
+\r
+                       case 0x20:\r
+                       data[2] = IPG_READ_LONGREG(baseaddr + data[1]);\r
+                       return 0;\r
+\r
+                       default:\r
+                       data[2] = 0x00;\r
+                       return -EINVAL;\r
+               }\r
+\r
+               case SIOCDEVPRIVATE+2:\r
+               switch(data[0])\r
+               {\r
+                       case 0x08:\r
+                       IPG_WRITE_BYTEREG(baseaddr + data[1], data[2]);\r
+                       return 0;\r
+\r
+                       case 0x10:\r
+                       IPG_WRITE_WORDREG(baseaddr + data[1], data[2]);\r
+                       return 0;\r
+\r
+                       case 0x20:\r
+                       IPG_WRITE_LONGREG(baseaddr + data[1], data[2]);\r
+                       return 0;\r
+\r
+                       default:\r
+                       return -EINVAL;\r
+               }\r
+\r
+               case SIOCDEVPRIVATE+3:\r
+               phyaddr = ipg_find_phyaddr(ipg_ethernet_device);\r
+\r
+               if (phyaddr == -1)\r
+                       return -EINVAL;\r
+\r
+               data[2] = read_phy_register(ipg_ethernet_device,\r
+                                           phyaddr, data[1]);\r
+\r
+               return 0;\r
+\r
+               case SIOCDEVPRIVATE+4:\r
+               phyaddr = ipg_find_phyaddr(ipg_ethernet_device);\r
+\r
+               if (phyaddr == -1)\r
+                       return -EINVAL;\r
+\r
+               write_phy_register(ipg_ethernet_device,\r
+                                  phyaddr, data[1], (u16)data[2]);\r
+\r
+               return 0;\r
+\r
+               case SIOCDEVPRIVATE+5:\r
+               switch(data[0])\r
+               {\r
+                       case 0x08:\r
+                       pci_read_config_byte(sp->ipg_pci_device,data[1],\r
+                                            &val8);\r
+                       data[2] = (unsigned int)val8;\r
+                       return 0;\r
+\r
+                       case 0x10:\r
+                       pci_read_config_word(sp->ipg_pci_device,data[1],\r
+                                            &val16);\r
+                       data[2] = (unsigned int)val16;\r
+                       return 0;\r
+\r
+                       case 0x20:\r
+                       pci_read_config_dword(sp->ipg_pci_device,data[1],\r
+                                            &val32);\r
+                       data[2] = (unsigned int)val32;\r
+                       return 0;\r
+\r
+                       default:\r
+                       data[2] = 0x00;\r
+                       return -EINVAL;\r
+               }\r
+\r
+               case SIOCDEVPRIVATE+6:\r
+               switch(data[0])\r
+               {\r
+                       case 0x08:\r
+                       pci_write_config_byte(sp->ipg_pci_device,data[1],\r
+                                             (u8)data[2]);\r
+                       return 0;\r
+\r
+                       case 0x10:\r
+                       pci_write_config_word(sp->ipg_pci_device,data[1],\r
+                                             (u16)data[2]);\r
+                       return 0;\r
+\r
+                       case 0x20:\r
+                       pci_write_config_dword(sp->ipg_pci_device,data[1],\r
+                                              (u32)data[2]);\r
+                       return 0;\r
+\r
+                       default:\r
+                       return -EINVAL;\r
+               }\r
+\r
+               case SIOCSIFMTU:\r
+               {\r
+                       return 0;\r
+               }\r
+\r
+               default:\r
+               return -EOPNOTSUPP;\r
+        }\r
+}\r
+\r
+int ipg_nic_change_mtu(IPG_DEVICE_TYPE *ipg_ethernet_device,\r
+                          int new_mtu)\r
+{\r
+        /* Function to accomodate changes to Maximum Transfer Unit\r
+         * (or MTU) of IPG NIC. Cannot use default function since\r
+         * the default will not allow for MTU > 1500 bytes.\r
+         */\r
+\r
+       IPG_DEBUG_MSG("_nic_change_mtu\n");\r
+\r
+        /* Check that the new MTU value is between 68 (14 byte header, 46\r
+         * byte payload, 4 byte FCS) and IPG_MAX_RXFRAME_SIZE, which\r
+         * corresponds to the MAXFRAMESIZE register in the IPG.\r
+         */\r
+        if ((new_mtu < 68) || (new_mtu > IPG_MAX_RXFRAME_SIZE))\r
+        {\r
+                return -EINVAL;\r
+        }\r
+\r
+        ipg_ethernet_device->mtu = new_mtu;\r
+\r
+        return 0;\r
+}\r
+\r
+#ifdef IPG_LINUX2_2\r
+int ipg_pcibussearch_linux2_2(void)\r
+{\r
+       /* Search for IPG based devices on the Ethernet bus.\r
+        * Code specific to the Linux 2.2 kernel.\r
+        */\r
+\r
+       int                             error;\r
+       int                             i;\r
+       int                             foundipgnic = 0;\r
+       IPG_DEVICE_TYPE         *ipg_ethernet_device;\r
+       struct ipg_nic_private  *sp;\r
+       struct pci_dev                  *ipg_pci_device;\r
+\r
+       IPG_DEBUG_MSG("_pcibussearch_linux_2_2\n");\r
+\r
+       for(i=0; ; i++)\r
+       {\r
+               if (nics_supported[i].vendorid == 0xFFFF)\r
+                       break;\r
+\r
+               /* Start with the list of all PCI devices. */\r
+               ipg_pci_device = pci_devices;\r
+\r
+               /* Check each entry in the list of all PCI devices. */\r
+               while (ipg_pci_device)\r
+               {\r
+                       if ((ipg_pci_device->vendor ==\r
+                            nics_supported[i].vendorid) &&\r
+                           (ipg_pci_device->device ==\r
+                            nics_supported[i].deviceid))\r
+                       {\r
+                               foundipgnic = 1;\r
+\r
+                               printk(KERN_INFO "%s found.\n",\r
+                                      nics_supported[i].NICname);\r
+                               printk(KERN_INFO "Bus %x Slot %x\n",\r
+                                      ipg_pci_device->bus->number,\r
+                                      PCI_SLOT(ipg_pci_device->devfn));\r
+\r
+                               ipg_ethernet_device = NULL;\r
+\r
+                               /* A IPG based NIC was found on the PCI bus.\r
+                                * Initialize the NIC.\r
+                                */\r
+                               error = ipg_nic_init(ipg_ethernet_device);\r
+                               if (error < 0)\r
+                               {\r
+                                       printk(KERN_INFO "Could not intialize IP1000 based NIC.\n");\r
+                                       return error;\r
+                               }\r
+                               else\r
+                               {\r
+                                       printk(KERN_INFO "Ethernet device registered as: %s\n",\r
+                                          root_ipg_ethernet_device->name);\r
+                               }\r
+\r
+                               sp = (struct ipg_nic_private *)\r
+                                    root_ipg_ethernet_device->priv;\r
+\r
+                               /* Save the pointer to the PCI device\r
+                                * information.\r
+                                */\r
+                               sp->ipg_pci_device = ipg_pci_device;\r
+                       }\r
+\r
+                       /* Move onto the next PCI device in the list. */\r
+                       ipg_pci_device = ipg_pci_device->next;\r
+               }\r
+\r
+       }\r
+\r
+       return foundipgnic;\r
+}\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+\r
+/* PCI driver structure for Linux 2.4. */\r
+struct  pci_driver      ipg_pci_driver =\r
+{\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) \r
+        name: IPG_DRIVER_NAME,\r
+        id_table: pci_devices_supported,\r
+        probe: ipg_pciprobe_linux2_4,\r
+        remove: ipg_pciremove_linux2_4,\r
+#else\r
+                 {NULL, NULL},\r
+        IPG_DRIVER_NAME,\r
+        pci_devices_supported,\r
+        ipg_pciprobe_linux2_4,\r
+        ipg_pciremove_linux2_4,\r
+        NULL,\r
+        NULL\r
+#endif\r
+};\r
+\r
+void ipg_pciremove_linux2_4(struct pci_dev *ipg_pci_device_to_remove)\r
+{\r
+       /* Remove function called when a IPG device is\r
+        * to be shut down.\r
+        */\r
+\r
+       IPG_DEVICE_TYPE         *prev_ipg_ethernet_device = NULL;\r
+       IPG_DEVICE_TYPE         *ipg_ethernet_device = NULL;\r
+       IPG_DEVICE_TYPE         *ipg_ethernet_device_to_remove =\r
+                                         NULL;\r
+       struct ipg_nic_private  *prev_sp = NULL;\r
+       struct ipg_nic_private  *sp = NULL;\r
+       struct ipg_nic_private  *sp_to_remove = NULL;\r
+\r
+       IPG_DEBUG_MSG("_pciremove_linux2_4\n");\r
+\r
+       ipg_ethernet_device = root_ipg_ethernet_device;\r
+\r
+       /* Move through list of Ethernet devices looking for\r
+        * a match.\r
+        */\r
+       while (ipg_ethernet_device)\r
+       {\r
+               sp = (struct ipg_nic_private *)\r
+                              (ipg_ethernet_device->priv);\r
+\r
+               if (sp->ipg_pci_device == ipg_pci_device_to_remove)\r
+               {\r
+                       /* Save the pointer to the previous Ethernet\r
+                        * device.\r
+                        */\r
+                       ipg_ethernet_device_to_remove =\r
+                         ipg_ethernet_device;\r
+\r
+                       sp_to_remove = sp;\r
+\r
+                       break;\r
+               }\r
+\r
+               /* Save the "previous" device in the list. */\r
+               prev_ipg_ethernet_device = ipg_ethernet_device;\r
+\r
+               /* Retrieve next Ethernet device to be\r
+                * released.\r
+                */\r
+               ipg_ethernet_device = sp->next_ipg_ethernet_device;\r
+       }\r
+\r
+       /* Check if there is a device to remove. */\r
+       if (ipg_ethernet_device_to_remove == NULL)\r
+       {\r
+               /* There are no Ethernet devices to remove. */\r
+               printk(KERN_INFO "A device remove request does not match with any Ethernet devices.\n");\r
+\r
+               return;\r
+       }\r
+\r
+       /* Check to see if we are removing the root device in the list. */\r
+       if (root_ipg_ethernet_device == ipg_ethernet_device_to_remove)\r
+       {\r
+               /* Change the root Ethernet device to the next device to be\r
+                * released.\r
+                */\r
+               root_ipg_ethernet_device =\r
+                 sp_to_remove->next_ipg_ethernet_device;\r
+       }\r
+       else if (sp_to_remove->next_ipg_ethernet_device != NULL)\r
+               /* Check if we need to re-link the list of devices. */\r
+       {\r
+               /* If the "previous" Ethernet device is NULL,\r
+                * the device is at the head of the list, and\r
+                * no re-linking is needed.\r
+                */\r
+               prev_sp = (struct ipg_nic_private *)\r
+                         (prev_ipg_ethernet_device->priv);\r
+\r
+               prev_sp->next_ipg_ethernet_device =\r
+                               sp_to_remove->next_ipg_ethernet_device;\r
+       }\r
+\r
+       /* Free memory associated with Ethernet device's\r
+        * private data structure.\r
+        */\r
+       if (sp_to_remove)\r
+       {\r
+               kfree(sp_to_remove);\r
+       }\r
+\r
+       printk(KERN_INFO "Un-registering Ethernet device %s\n",\r
+              ipg_ethernet_device_to_remove->name);\r
+\r
+       /* Un-register Ethernet device. */\r
+       unregister_netdev(ipg_ethernet_device_to_remove);\r
+\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) \r
+#ifdef USE_IO_OPS\r
+       pci_release_regions(ipg_pci_device_to_remove);\r
+#else\r
+       iounmap((void *)ipg_ethernet_device->base_addr);\r
+#endif\r
+#endif\r
+\r
+\r
+       /* Free memory associated with Ethernet device. */\r
+       if (ipg_ethernet_device_to_remove)\r
+       {\r
+               kfree(ipg_ethernet_device_to_remove);\r
+       }\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) \r
+   pci_set_drvdata(ipg_pci_device_to_remove,NULL);\r
+#endif\r
+       return;\r
+}\r
+\r
+int ipg_pciprobe_linux2_4(struct pci_dev *ipg_pci_device,\r
+                              const struct pci_device_id *id)\r
+{\r
+       /* Probe function called when a IPG device is found\r
+        * on the PCI bus.\r
+        */\r
+\r
+       int                             error;\r
+       int                             i;\r
+       IPG_DEVICE_TYPE         *ipg_ethernet_device = NULL;\r
+       struct ipg_nic_private  *sp;\r
+\r
+       IPG_DEBUG_MSG("_pciprobe_linux2_4\n");\r
+\r
+       /* Enable IPG PCI device in Linux system. */\r
+       error = pci_enable_device(ipg_pci_device);\r
+       if (error < 0)\r
+       {\r
+               return error;\r
+       }\r
+\r
+       /* Get the index for the driver description string. */\r
+       i = id->driver_data;\r
+\r
+       printk(KERN_INFO "%s found.\n",\r
+              nics_supported[i].NICname);\r
+        printk(KERN_INFO "Bus %x Slot %x\n",\r
+              ipg_pci_device->bus->number,\r
+              PCI_SLOT(ipg_pci_device->devfn));\r
+\r
+       /* Configure IPG PCI device within Linux system as\r
+        * a bus master.\r
+        */\r
+       pci_set_master(ipg_pci_device);\r
+\r
+       /* Indicate that we can supply 32 bits of address\r
+        * during PCI bus mastering.\r
+        */\r
+       if (pci_dma_supported(ipg_pci_device, 0xFFFFFFFF) < 0)\r
+       {\r
+               printk(KERN_INFO "pci_dma_supported failed.\n");\r
+               return -ENODEV;\r
+       }\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       /* A IPG based NIC was found on the PCI bus.\r
+        * Initialize the NIC.\r
+        */\r
+       if ((ipg_nic_init(ipg_ethernet_device)) < 0)\r
+       {\r
+               printk(KERN_INFO "Could not intialize IP1000 based NIC.\n");\r
+               return -ENODEV;\r
+       }\r
+       else\r
+       {\r
+               printk(KERN_INFO "Ethernet device registered as: %s\n",\r
+                      root_ipg_ethernet_device->name);\r
+       }\r
+       sp = (struct ipg_nic_private *)root_ipg_ethernet_device->priv;\r
+       /* Save the pointer to the PCI device information. */\r
+       sp->ipg_pci_device = ipg_pci_device;\r
+#else \r
+       if ((ipg_nic_init(ipg_ethernet_device)) < 0)\r
+       {\r
+               printk(KERN_INFO "Could not intialize IP1000 based NIC.\n");\r
+               return -ENODEV;\r
+       }\r
+       ipg_ethernet_device=root_ipg_ethernet_device;\r
+   SET_MODULE_OWNER(ipg_ethernet_device);\r
+   pci_request_regions(ipg_pci_device,DRV_NAME);\r
+//   if(pci_request_regions(ipg_pci_device,DRV_NAME)=err) goto xxx;\r
+\r
+#ifdef USE_IO_OPS\r
+       ipg_ethernet_device->base_addr = pci_resource_start(ipg_pci_device, 0)&0xffffff80;////20040826Jesse_mask_BaseAddr:Mask IOBaseAddr[bit0~6]\r
+#else\r
+       ipg_ethernet_device->base_addr = pci_resource_start(ipg_pci_device, 1)&0xffffff80;//20040826Jesse_mask_BaseAddr:Mask MemBaseAddr[bit0~6]\r
+       ipg_ethernet_device->base_addr = (long) ioremap (ipg_ethernet_device->base_addr, netdev_io_size);\r
+//     if (!ioaddr)goto err_out_res;\r
+#endif//#ifdef USE_IO_OPS\r
+       sp = (struct ipg_nic_private *)root_ipg_ethernet_device->priv;\r
+       /* Save the pointer to the PCI device information. */\r
+       sp->ipg_pci_device = ipg_pci_device;\r
+       \r
+   pci_set_drvdata(ipg_pci_device,ipg_ethernet_device);\r
+  \r
+   i = register_netdev(ipg_ethernet_device);\r
+//     if (i)goto err_out_unmap_rx;\r
+\r
+       printk(KERN_INFO "Ethernet device registered as: %s\n",\r
+                      ipg_ethernet_device->name);\r
+#endif//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+\r
+\r
+       return 0;\r
+}\r
+#endif //#ifdef IPG_LINUX2_4\r
+\r
+\r
+\r
+#ifdef MODULE\r
+/* A modularized driver, i.e. not part of mainstream Linux\r
+ * kernel distribution.\r
+ */\r
+int    init_module(void)\r
+{\r
+       /* Initialize the IPG driver module. */\r
+\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \r
+       int     foundipgnic = 0;\r
+#endif\r
+\r
+       IPG_DEBUG_MSG("init_module\n");\r
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) \r
+       return pci_module_init(&ipg_pci_driver);\r
+#else\r
+       \r
+        printk(KERN_INFO "%s", version);\r
+\r
+       /* Define EXPORT_NO_SYMBOLS macro for specifying no\r
+        * symbols to be exported.\r
+        */\r
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)\r
+       EXPORT_NO_SYMBOLS;\r
+#endif\r
+\r
+       /* The CONFIG_PCI macro is defined for systems which\r
+        * have a PCI bus. If the macro is undefined, there is no\r
+        * PCI bus and the ipg cannot be utilized.\r
+        */\r
+#ifdef CONFIG_PCI\r
+\r
+       printk(KERN_INFO "IPG module searching for Ethernet devices on PCI bus...\n");\r
+\r
+#ifdef IPG_LINUX2_2\r
+       foundipgnic = ipg_pcibussearch_linux2_2();\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       if (pci_register_driver(&ipg_pci_driver) != 0)\r
+       {\r
+               foundipgnic = 1;\r
+       }\r
+       else\r
+       {\r
+               foundipgnic = 0;\r
+       }\r
+#endif\r
+\r
+       if (foundipgnic == 0)\r
+       {\r
+               printk(KERN_INFO " IP1000 based Ethernet device not found on PCI bus.\n");\r
+               return -ENODEV;\r
+       }\r
+\r
+#else /* PCI not available. */\r
+               /* PCI not supported in system. */\r
+               printk(KERN_INFO "No PCI bus, required by IP1000.\n");\r
+               return -ENODEV;\r
+#endif\r
+\r
+       printk(KERN_INFO "IPG module loaded.\n");\r
+\r
+       return 0;\r
+#endif\r
+}\r
+\r
+void   cleanup_module(void)\r
+{\r
+       /* Clean up system modifications made by IPG driver\r
+        * module.\r
+        */\r
+\r
+#ifdef IPG_LINUX2_2\r
+\r
+       IPG_DEVICE_TYPE         *next_ipg_ethernet_device;\r
+       struct ipg_nic_private  *sp;\r
+\r
+       IPG_DEBUG_MSG("cleanup_module\n");\r
+\r
+       /* Unregister all IPG NICs from the list of Ethernet\r
+        * devices.\r
+        */\r
+       while (root_ipg_ethernet_device)\r
+       {\r
+               sp = (struct ipg_nic_private *)\r
+                    (root_ipg_ethernet_device->priv);\r
+\r
+               /* Retrieve next Ethernet device to be\r
+                * released.\r
+                */\r
+               next_ipg_ethernet_device = sp->next_ipg_ethernet_device;\r
+\r
+               printk(KERN_INFO "Un-registering Ethernet device %s\n",\r
+                      root_ipg_ethernet_device->name);\r
+\r
+               /* Un-register Ethernet device. */\r
+               unregister_netdev(root_ipg_ethernet_device);\r
+\r
+               /* Free memory associated with Ethernet device's\r
+                * private data structure.\r
+                */\r
+               kfree(sp);\r
+\r
+               /* Free memory associated with Ethernet device. */\r
+               kfree(root_ipg_ethernet_device);\r
+\r
+               /* Move to next Ethernet device. */\r
+               root_ipg_ethernet_device = next_ipg_ethernet_device;\r
+       }\r
+\r
+#endif\r
+\r
+#ifdef IPG_LINUX2_4\r
+       IPG_DEBUG_MSG("cleanup_module\n");\r
+\r
+       pci_unregister_driver(&ipg_pci_driver);\r
+#endif\r
+\r
+       printk(KERN_INFO "IPG module unloaded.\n");\r
+}\r
+#else /* not MODULE */\r
+\r
+int    ipg_nic_probe(IPG_DEVICE_TYPE *dev)\r
+{\r
+       int     error;\r
+\r
+       IPG_DEBUG_MSG("_nic_probe\n");\r
+\r
+       error = ipg_nic_init(dev);\r
+       if (error < 0)\r
+               return -ENODEV;\r
+        printk(KERN_INFO "%s", version);\r
+\r
+       return 0;\r
+}\r
+\r
+#endif\r
+void bSetPhyDefaultParam(unsigned char Rev,\r
+               IPG_DEVICE_TYPE *ipg_ethernet_device,int phy_address)\r
+{\r
+       unsigned short Length;\r
+       unsigned char Revision;\r
+       unsigned short *pPHYParam;\r
+       unsigned short address,value;\r
+       \r
+       pPHYParam = &DefaultPhyParam[0];\r
+       Length = *pPHYParam & 0x00FF;\r
+       Revision = (unsigned char) ((*pPHYParam) >> 8);\r
+       pPHYParam++;\r
+       while(Length != 0)\r
+       {\r
+               if(Rev == Revision)\r
+               {\r
+                       while(Length >1)\r
+                       {\r
+                               address=*pPHYParam; \r
+                               value=*(pPHYParam+1);\r
+                               pPHYParam+=2;\r
+                               write_phy_register(ipg_ethernet_device,phy_address,address, value);\r
+                               Length -= 4;\r
+                       }\r
+\r
+                       break;\r
+               }\r
+               else // advanced to next revision\r
+               {\r
+                       pPHYParam += Length/2;\r
+                       Length = *pPHYParam & 0x00FF;\r
+                       Revision = (unsigned char) ((*pPHYParam) >> 8);\r
+                       pPHYParam++;\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+/*JES20040127EEPROM*/\r
+int read_eeprom(IPG_DEVICE_TYPE *ipg_ethernet_device, int eep_addr)\r
+{\r
+   u32 baseaddr;\r
+   int            i = 1000;\r
+       baseaddr = ipg_ethernet_device->base_addr;\r
+       \r
+   IPG_WRITE_EEPROMCTRL(baseaddr,  IPG_EC_EEPROM_READOPCODE | (eep_addr & 0xff));\r
+   while (i-- > 0) {\r
+       mdelay(10);\r
+        if (!(IPG_READ_EEPROMCTRL(baseaddr)&IPG_EC_EEPROM_BUSY)) {\r
+                return IPG_READ_EEPROMDATA (baseaddr);\r
+       }\r
+   }\r
+   return 0;\r
+}\r
+\r
+/* Write EEPROM JES20040127EEPROM */\r
+//void Eeprom_Write(unsigned int card_index, unsigned eep_addr, unsigned writedata)\r
+void write_eeprom(IPG_DEVICE_TYPE *ipg_ethernet_device, unsigned int eep_addr, unsigned int writedata)\r
+{\r
+/* \r
+   u32 baseaddr;\r
+   baseaddr = ipg_ethernet_device->base_addr;\r
+   IPG_WRITE_EEPROMDATA(baseaddr, writedata );\r
+   while ( (IPG_READ_EEPROMCTRL(baseaddr) & IPG_EC_EEPROM_BUSY ) ) {   \r
+   }\r
+   IPG_WRITE_EEPROMCTRL (baseaddr, 0xC0 );\r
+   while ( (IPG_READ_EEPROMCTRL(baseaddr)&IPG_EC_EEPROM_BUSY) ) {   \r
+   }\r
+   IPG_WRITE_EEPROMCTRL(baseaddr, IPG_EC_EEPROM_WRITEOPCODE | (eep_addr & 0xff) );\r
+   while ( (IPG_READ_EEPROMCTRL(baseaddr)&IPG_EC_EEPROM_BUSY) ) {   \r
+   }\r
+   \r
+   return;*/\r
+}\r
+\r
+/* Set LED_Mode JES20040127EEPROM */\r
+void Set_LED_Mode(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+   u32 LED_Mode_Value;\r
+   u32 baseaddr;       \r
+   struct ipg_nic_private      *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+       baseaddr = ipg_ethernet_device->base_addr;                                            \r
+   \r
+   LED_Mode_Value=IPG_READ_ASICCTRL(baseaddr);\r
+   LED_Mode_Value &= ~(IPG_AC_LED_MODE_BIT_1 | IPG_AC_LED_MODE |IPG_AC_LED_SPEED);\r
+   \r
+   if((sp->LED_Mode & 0x03) > 1){\r
+       /* Write Asic Control Bit 29 */\r
+       LED_Mode_Value |=IPG_AC_LED_MODE_BIT_1;\r
+   }\r
+   if((sp->LED_Mode & 0x01) == 1){\r
+        /* Write Asic Control Bit 14 */\r
+        LED_Mode_Value |=IPG_AC_LED_MODE;\r
+   }\r
+   if((sp->LED_Mode & 0x08) == 8){\r
+        /* Write Asic Control Bit 27 */\r
+        LED_Mode_Value |=IPG_AC_LED_SPEED;\r
+   }   \r
+   IPG_WRITE_ASICCTRL(baseaddr,LED_Mode_Value);        \r
+   \r
+   return;\r
+}\r
+\r
+/* Set PHYSet JES20040127EEPROM */\r
+void Set_PHYSet(IPG_DEVICE_TYPE *ipg_ethernet_device)\r
+{\r
+   int PHYSet_Value;\r
+   u32 baseaddr;       \r
+   struct ipg_nic_private      *sp = (struct ipg_nic_private *)\r
+                                             ipg_ethernet_device->priv;\r
+       baseaddr = ipg_ethernet_device->base_addr;                                            \r
+   \r
+   PHYSet_Value=IPG_READ_PHYSET(baseaddr);\r
+   PHYSet_Value &= ~(IPG_PS_MEM_LENB9B | IPG_PS_MEM_LEN9 |IPG_PS_NON_COMPDET);\r
+   PHYSet_Value |= ((sp->LED_Mode & 0x70) >> 4);\r
+   IPG_WRITE_PHYSET(baseaddr,PHYSet_Value);\r
+\r
+   return;\r
+}\r
+/* end ipg.c */\r
diff --git a/drivers/net/ip1000a/ipg_main.o b/drivers/net/ip1000a/ipg_main.o
new file mode 100644 (file)
index 0000000..aa0ec0a
Binary files /dev/null and b/drivers/net/ip1000a/ipg_main.o differ
diff --git a/drivers/net/ip1000a/ipg_structs.h b/drivers/net/ip1000a/ipg_structs.h
new file mode 100644 (file)
index 0000000..37babfb
--- /dev/null
@@ -0,0 +1,176 @@
+/*\r
+ *\r
+ * ipg.h\r
+ *\r
+ * Include file with structures for Gigabit Ethernet\r
+ * device driver for Network Interface Cards (NICs) utilizing the\r
+ * Tamarack Microelectronics Inc. IPG Gigabit or Triple Speed\r
+ * Ethernet Media Access Controller.\r
+ *\r
+ * Craig Rich\r
+ * Sundance Technology, Inc.\r
+ * 1485 Saratoga Avenue\r
+ * Suite 200\r
+ * San Jose, CA 95129\r
+ * 408 873 4117\r
+ * www.sundanceti.com\r
+ * craig_rich@sundanceti.com\r
+ *\r
+ * Rev  Date     Description\r
+ * --------------------------------------------------------------\r
+ * 0.1  3/30/01  New file created from original ipg.h\r
+ *\r
+ * 0.2  5/22/01  Added PCI_DEVICE_ID_TAMARACK_TC9020_9021_ALT\r
+ *               to nics_supported[] array.\r
+ */\r
+\r
+/* IPG Ethernet device structure, used for removing module. */\r
+IPG_DEVICE_TYPE *root_ipg_ethernet_device = NULL;\r
+\r
+/* Transmit Frame Descriptor. The IPG supports 15 fragments,\r
+ * however Linux requires only a single fragment. Note, each\r
+ * TFD field is 64 bits wide.\r
+ */\r
+struct TFD\r
+{\r
+       u64             TFDNextPtr;\r
+       u64             TFC;\r
+       u64             FragInfo;\r
+};\r
+\r
+/* Receive Frame Descriptor. Note, each RFD field is 64 bits wide.\r
+ */\r
+struct RFD\r
+{\r
+       u64             RFDNextPtr;\r
+       u64             RFS;\r
+       u64             FragInfo;\r
+};\r
+\r
+#ifdef IPG_LINUX2_4\r
+struct ipg_dmabuff\r
+{\r
+       dma_addr_t      dmahandle;\r
+       unsigned long   len;\r
+};\r
+\r
+#endif\r
+struct SJumbo\r
+{\r
+       int FoundStart;\r
+       int CurrentSize;\r
+       struct sk_buff                  *skb;\r
+};\r
+/* Structure of IPG NIC specific data. */\r
+struct ipg_nic_private\r
+{\r
+        struct TFD             *TFDList;\r
+        struct RFD             *RFDList;\r
+#ifdef IPG_LINUX2_4\r
+       dma_addr_t              TFDListDMAhandle;\r
+       dma_addr_t              RFDListDMAhandle;\r
+       struct ipg_dmabuff      TxBuffDMAhandle[IPG_TFDLIST_LENGTH];\r
+       struct ipg_dmabuff      RxBuffDMAhandle[IPG_RFDLIST_LENGTH];\r
+#endif\r
+       struct sk_buff          *TxBuff[IPG_TFDLIST_LENGTH];\r
+       struct sk_buff          *RxBuff[IPG_RFDLIST_LENGTH];\r
+       u16                     CurrentTxFrameID;\r
+       int                     CurrentTFD;\r
+       int                     LastFreedTxBuff;\r
+       int                     CurrentRFD;\r
+// Add by Grace 2005/05/19\r
+#ifdef JUMBO_FRAME\r
+       struct SJumbo      Jumbo;\r
+#endif\r
+       int                     LastRestoredRxBuff;\r
+       int                     RxBuffNotReady;\r
+       struct pci_dev          *ipg_pci_device;\r
+       IPG_STATS_TYPE  stats;\r
+       IPG_DEVICE_TYPE *next_ipg_ethernet_device;\r
+        spinlock_t              lock;\r
+       int                     tenmbpsmode;\r
+       \r
+       /*Jesse20040128EEPROM_VALUE */\r
+       u16         LED_Mode;\r
+       u16         StationAddr0;   /* Station Address in EEPROM Reg 0x10 */\r
+   u16         StationAddr1;   /* Station Address in EEPROM Reg 0x11 */        \r
+       u16         StationAddr2;   /* Station Address in EEPROM Reg 0x12 */   \r
+\r
+#ifdef IPG_DEBUG\r
+       int                     TFDunavailCount;\r
+       int                     RFDlistendCount;\r
+       int                     RFDListCheckedCount;\r
+       int                     EmptyRFDListCount;\r
+#endif\r
+};\r
+\r
+struct nic_id\r
+{\r
+       char*           NICname;\r
+       int             vendorid;\r
+       int             deviceid;\r
+};\r
+\r
+struct nic_id  nics_supported[] =\r
+{\r
+       {"IC PLUS IP1000 1000/100/10 based NIC",\r
+        PCI_VENDOR_ID_ICPLUS,\r
+        PCI_DEVICE_ID_IP1000},\r
+       {"Sundance Technology ST2021 based NIC",\r
+     PCI_VENDOR_ID_SUNDANCE,\r
+        PCI_DEVICE_ID_SUNDANCE_ST2021},\r
+       {"Tamarack Microelectronics TC9020/9021 based NIC",\r
+        PCI_VENDOR_ID_SUNDANCE,\r
+        PCI_DEVICE_ID_TAMARACK_TC9020_9021},\r
+       {"Tamarack Microelectronics TC9020/9021 based NIC",\r
+        PCI_VENDOR_ID_SUNDANCE,\r
+        PCI_DEVICE_ID_TAMARACK_TC9020_9021_ALT},\r
+       {"D-Link NIC",\r
+        PCI_VENDOR_ID_DLINK,\r
+        PCI_DEVICE_ID_DLINK_1002},\r
+       {"D-Link NIC IP1000A",\r
+        PCI_VENDOR_ID_DLINK,\r
+        PCI_DEVICE_ID_DLINK_IP1000A},\r
+        \r
+       {"N/A", 0xFFFF, 0}\r
+};\r
+\r
+#ifdef IPG_LINUX2_4\r
+struct pci_device_id   pci_devices_supported[] =\r
+{\r
+       {PCI_VENDOR_ID_ICPLUS,\r
+        PCI_DEVICE_ID_IP1000,\r
+        PCI_ANY_ID,\r
+        PCI_ANY_ID,\r
+        0x020000,\r
+        0xFFFFFF,\r
+        0},\r
+\r
+       {PCI_VENDOR_ID_SUNDANCE,\r
+        PCI_DEVICE_ID_SUNDANCE_ST2021,\r
+        PCI_ANY_ID,\r
+        PCI_ANY_ID,\r
+        0x020000,\r
+        0xFFFFFF,\r
+        1},\r
+\r
+       {PCI_VENDOR_ID_SUNDANCE,\r
+        PCI_DEVICE_ID_TAMARACK_TC9020_9021,\r
+        PCI_ANY_ID,\r
+        PCI_ANY_ID,\r
+        0x020000,\r
+        0xFFFFFF,\r
+        2},\r
+\r
+       {PCI_VENDOR_ID_DLINK,\r
+        PCI_DEVICE_ID_DLINK_1002,\r
+        PCI_ANY_ID,\r
+        PCI_ANY_ID,\r
+        0x020000,\r
+        0xFFFFFF,\r
+        3},\r
+\r
+       {0,}\r
+};\r
+#endif\r
+/* end ipg_structs.h */\r
diff --git a/drivers/net/ip1000a/ipg_tune.h b/drivers/net/ip1000a/ipg_tune.h
new file mode 100644 (file)
index 0000000..74a4926
--- /dev/null
@@ -0,0 +1,350 @@
+/*\r
+ *\r
+ * ipg_tune.h\r
+ *\r
+ * Include file with tunable driver parameters for Gigabit Ethernet\r
+ * device driver for Network Interface Cards (NICs) utilizing the\r
+ * Tamarack Microelectronics Inc. IPG Gigabit or Triple Speed\r
+ * Ethernet Media Access Controller.\r
+ *\r
+ * Craig Rich\r
+ * Sundance Technology, Inc.\r
+ * 1485 Saratoga Avenue\r
+ * Suite 200\r
+ * San Jose, CA 95129\r
+ * 408 873 4117\r
+ * www.sundanceti.com\r
+ * craig_rich@sundanceti.com\r
+ *\r
+ * Rev  Date     Description\r
+ * --------------------------------------------------------------\r
+ * 0.1  3/30/01  New file created from original ipg.h\r
+ *\r
+ * 0.2  5/22/01  Added PCI_DEVICE_ID_TAMARACK_TC9020_9021_ALT.\r
+ *\r
+ * 0.3  6/20/01  Added IPG_ADD_IPCHECKSUM_ON_TX,\r
+ *               IPG_ADD_TCPCHECKSUM_ON_TX, and\r
+ *               IPG_ADD_UDPCHECKSUM_ON_TX.\r
+ *\r
+ * 0.4  8/11/01  Added comments about avoiding use of TCP/UDP\r
+ *               checksums for silicon revs B3 and earlier.\r
+ *\r
+ * 0.5  10/30/01 Optimized numerous settings.\r
+ */\r
+\r
+/* Define PCI vendor and device IDs if not already\r
+ * defined in pci.h.\r
+ */\r
+\r
+#ifndef PCI_VENDOR_ID_ICPLUS\r
+#  define       PCI_VENDOR_ID_ICPLUS            0x13F0\r
+#endif\r
+#ifndef PCI_DEVICE_ID_IP1000\r
+#  define       PCI_DEVICE_ID_IP1000               0x1023\r
+#endif\r
+#ifndef PCI_VENDOR_ID_SUNDANCE\r
+#  define       PCI_VENDOR_ID_SUNDANCE          0x13F0\r
+#endif\r
+#ifndef PCI_DEVICE_ID_SUNDANCE_IPG\r
+#  define       PCI_DEVICE_ID_SUNDANCE_ST2021   0x2021\r
+#endif\r
+#ifndef PCI_DEVICE_ID_TAMARACK_TC9020_9021_ALT\r
+#  define       PCI_DEVICE_ID_TAMARACK_TC9020_9021_ALT 0x9021\r
+#endif\r
+#ifndef PCI_DEVICE_ID_TAMARACK_TC9020_9021\r
+#  define       PCI_DEVICE_ID_TAMARACK_TC9020_9021 0x1021\r
+#endif\r
+#ifndef PCI_VENDOR_ID_DLINK\r
+#  define       PCI_VENDOR_ID_DLINK             0x1186\r
+#endif\r
+#ifndef PCI_DEVICE_ID_DLINK_1002\r
+#  define       PCI_DEVICE_ID_DLINK_1002        0x4000\r
+#endif\r
+#ifndef PCI_DEVICE_ID_DLINK_IP1000A\r
+#  define PCI_DEVICE_ID_DLINK_IP1000A          0x4020\r
+#endif\r
+\r
+/* Miscellaneous Constants. */\r
+#define   TRUE  1\r
+#define   FALSE 0\r
+\r
+/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS append on TX. */\r
+#define         IPG_APPEND_FCS_ON_TX         TRUE\r
+\r
+/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS strip on RX. */\r
+#define         IPG_STRIP_FCS_ON_RX          TRUE\r
+\r
+/* Assign IPG_DROP_ON_RX_ETH_ERRORS > 0 to drop RX frames with\r
+ * Ethernet errors.\r
+ */\r
+#define         IPG_DROP_ON_RX_ETH_ERRORS    TRUE\r
+\r
+/* Assign IPG_INSERT_MANUAL_VLAN_TAG > 0 to insert VLAN tags manually\r
+ * (via TFC).\r
+ */\r
+#define                IPG_INSERT_MANUAL_VLAN_TAG   FALSE\r
+\r
+/* Assign IPG_ADD_IPCHECKSUM_ON_TX > 0 for auto IP checksum on TX. */\r
+#define         IPG_ADD_IPCHECKSUM_ON_TX     FALSE\r
+\r
+/* Assign IPG_ADD_TCPCHECKSUM_ON_TX > 0 for auto TCP checksum on TX.\r
+ * DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.\r
+ */\r
+#define         IPG_ADD_TCPCHECKSUM_ON_TX    FALSE\r
+\r
+/* Assign IPG_ADD_UDPCHECKSUM_ON_TX > 0 for auto UDP checksum on TX.\r
+ * DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.\r
+ */\r
+#define         IPG_ADD_UDPCHECKSUM_ON_TX    FALSE\r
+\r
+/* If inserting VLAN tags manually, assign the IPG_MANUAL_VLAN_xx\r
+ * constants as desired.\r
+ */\r
+#define                IPG_MANUAL_VLAN_VID             0xABC\r
+#define                IPG_MANUAL_VLAN_CFI             0x1\r
+#define                IPG_MANUAL_VLAN_USERPRIORITY 0x5\r
+\r
+#define         IPG_IO_REG_RANGE               0xFF\r
+#define         IPG_MEM_REG_RANGE              0x154\r
+#define         IPG_DRIVER_NAME                "Sundance Technology IPG Triple-Speed Ethernet"\r
+#define         IPG_NIC_PHY_ADDRESS          0x01\r
+#define                IPG_DMALIST_ALIGN_PAD   0x07\r
+#define                IPG_MULTICAST_HASHTABLE_SIZE    0x40\r
+\r
+/* Number of miliseconds to wait after issuing a software reset.\r
+ * 0x05 <= IPG_AC_RESETWAIT to account for proper 10Mbps operation.\r
+ */\r
+#define         IPG_AC_RESETWAIT             0x05\r
+\r
+/* Number of IPG_AC_RESETWAIT timeperiods before declaring timeout. */\r
+#define         IPG_AC_RESET_TIMEOUT         0x0A\r
+\r
+/* Minimum number of miliseconds used to toggle MDC clock during\r
+ * MII/GMII register access.\r
+ */\r
+#define         IPG_PC_PHYCTRLWAIT           0x01\r
+\r
+#define                IPG_TFDLIST_LENGTH              0x100\r
+\r
+/* Number of frames between TxDMAComplete interrupt.\r
+ * 0 < IPG_FRAMESBETWEENTXDMACOMPLETES <= IPG_TFDLIST_LENGTH\r
+ */\r
+#define                IPG_FRAMESBETWEENTXDMACOMPLETES 0x1\r
+\r
+#ifdef JUMBO_FRAME\r
+\r
+# ifdef JUMBO_FRAME_SIZE_2K\r
+# define JUMBO_FRAME_SIZE 2048\r
+# define __IPG_RXFRAG_SIZE 2048\r
+# else\r
+#  ifdef JUMBO_FRAME_SIZE_3K\r
+#  define JUMBO_FRAME_SIZE 3072\r
+#  define __IPG_RXFRAG_SIZE 3072\r
+#  else\r
+#   ifdef JUMBO_FRAME_SIZE_4K\r
+#   define JUMBO_FRAME_SIZE 4096\r
+#   define __IPG_RXFRAG_SIZE 4088\r
+#   else\r
+#    ifdef JUMBO_FRAME_SIZE_5K\r
+#    define JUMBO_FRAME_SIZE 5120\r
+#    define __IPG_RXFRAG_SIZE 4088\r
+#    else\r
+#     ifdef JUMBO_FRAME_SIZE_6K\r
+#     define JUMBO_FRAME_SIZE 6144\r
+#     define __IPG_RXFRAG_SIZE 4088\r
+#     else\r
+#      ifdef JUMBO_FRAME_SIZE_7K\r
+#      define JUMBO_FRAME_SIZE 7168\r
+#      define __IPG_RXFRAG_SIZE 4088\r
+#      else\r
+#       ifdef JUMBO_FRAME_SIZE_8K\r
+#       define JUMBO_FRAME_SIZE 8192\r
+#       define __IPG_RXFRAG_SIZE 4088\r
+#       else\r
+#        ifdef JUMBO_FRAME_SIZE_9K\r
+#        define JUMBO_FRAME_SIZE 9216\r
+#        define __IPG_RXFRAG_SIZE 4088\r
+#        else\r
+#         ifdef JUMBO_FRAME_SIZE_10K\r
+#         define JUMBO_FRAME_SIZE 10240\r
+#         define __IPG_RXFRAG_SIZE 4088\r
+#         else\r
+#         define JUMBO_FRAME_SIZE 4096\r
+#         endif \r
+#        endif \r
+#       endif \r
+#      endif \r
+#     endif \r
+#    endif \r
+#   endif \r
+#  endif \r
+# endif \r
+#endif\r
+\r
+/* Size of allocated received buffers. Nominally 0x0600.\r
+ * Define larger if expecting jumbo frames.\r
+ */\r
+#ifdef JUMBO_FRAME\r
+//IPG_TXFRAG_SIZE must <= 0x2b00, or TX will crash\r
+#define                IPG_TXFRAG_SIZE         JUMBO_FRAME_SIZE\r
+#endif\r
+\r
+\r
+/* Size of allocated received buffers. Nominally 0x0600.\r
+ * Define larger if expecting jumbo frames.\r
+ */\r
+#ifdef JUMBO_FRAME\r
+//4088=4096-8\r
+#define                IPG_RXFRAG_SIZE         __IPG_RXFRAG_SIZE\r
+#define     IPG_RXSUPPORT_SIZE   IPG_MAX_RXFRAME_SIZE\r
+#else\r
+#define                IPG_RXFRAG_SIZE         0x0600\r
+#define     IPG_RXSUPPORT_SIZE   IPG_RXFRAG_SIZE\r
+#endif\r
+\r
+/* IPG_MAX_RXFRAME_SIZE <= IPG_RXFRAG_SIZE */\r
+#ifdef JUMBO_FRAME\r
+#define                IPG_MAX_RXFRAME_SIZE            JUMBO_FRAME_SIZE\r
+#else\r
+#define                IPG_MAX_RXFRAME_SIZE            0x0600\r
+#endif\r
+\r
+#define                IPG_RFDLIST_LENGTH              0x100\r
+\r
+/* Maximum number of RFDs to process per interrupt.\r
+ * 1 < IPG_MAXRFDPROCESS_COUNT < IPG_RFDLIST_LENGTH\r
+ */\r
+#define                IPG_MAXRFDPROCESS_COUNT 0x80\r
+\r
+/* Minimum margin between last freed RFD, and current RFD.\r
+ * 1 < IPG_MINUSEDRFDSTOFREE < IPG_RFDLIST_LENGTH\r
+ */\r
+#define                IPG_MINUSEDRFDSTOFREE   0x80\r
+\r
+/* Specify priority threshhold for a RxDMAPriority interrupt. */\r
+#define                IPG_PRIORITY_THRESH             0x07\r
+\r
+/* Specify the number of receive frames transferred via DMA\r
+ * before a RX interrupt is issued.\r
+ */\r
+#define                IPG_RXFRAME_COUNT               0x08\r
+\r
+/* specify the jumbo frame maximum size\r
+ * per unit is 0x600 (the RxBuffer size that one RFD can carry)\r
+ */\r
+#define     MAX_JUMBOSIZE              0x8   // max is 12K\r
+\r
+/* Specify the maximum amount of time (in 64ns increments) to wait\r
+ * before issuing a RX interrupt if number of frames received\r
+ * is less than IPG_RXFRAME_COUNT.\r
+ *