

From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
Subject: OKI Semiconductor PCH GbE driver

This driver implements GbE controls for PCH.

Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
Acked-by: Wang Qi <qi.wang@intel.com>

---
 drivers/net/Kconfig                        | 5 ++
 drivers/net/Makefile                       | 1
 drivers/net/pch_gbe/Makefile               | 6
 drivers/net/pch_gbe/pch_gbe_api.c          | 644
 drivers/net/pch_gbe/pch_gbe_api.h          | 252
 drivers/net/pch_gbe/pch_gbe_defines.h      | 367
 drivers/net/pch_gbe/pch_gbe_ethtool.c      | 1306
 drivers/net/pch_gbe/pch_gbe.h              | 230
 drivers/net/pch_gbe/pch_gbe_hw.h           | 259
 drivers/net/pch_gbe/pch_gbe_mac.c          | 522
 drivers/net/pch_gbe/pch_gbe_mac.h          | 121
 drivers/net/pch_gbe/pch_gbe_main.c         | 2973
 drivers/net/pch_gbe/pch_gbe_nvm.c          | 129
 drivers/net/pch_gbe/pch_gbe_nvm.h          | 85
 drivers/net/pch_gbe/pch_gbe_osdep.h        | 74
 drivers/net/pch_gbe/pch_gbe_param.c        | 594
 drivers/net/pch_gbe/pch_gbe_pci_ids.h      | 38
 drivers/net/pch_gbe/pch_gbe_phy.c          | 493
 drivers/net/pch_gbe/pch_gbe_phy.h          | 136
 drivers/net/pch_gbe/pch_gbe_plat.c         | 175
 drivers/net/pch_gbe/pch_gbe_regs.h         | 351
+++++++++++++++++++++++++++++++ 21 files changed, 8761 insertions(+)
diff -urN linux-2.6.33-rc3/drivers/net/Kconfig topcliff-2.6.33-rc3/drivers/net/Kconfig
--- linux-2.6.33-rc3/drivers/net/Kconfig	2010-01-06 09:02:46.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/Kconfig	2010-03-12 16:24:03.000000000 +0900
@@ -1977,6 +1977,11 @@
 	  If you say N, all options in this submenu will be skipped and disabled.
 
 if NETDEV_1000
+config PCH_GBE
+        tristate "PCH Gigabit Ethernet"
+        ---help---
+          This is an gigabit ethernet driver for PCH.
+          resources.
 
 config ACENIC
 	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
diff -urN linux-2.6.33-rc3/drivers/net/Makefile topcliff-2.6.33-rc3/drivers/net/Makefile
--- linux-2.6.33-rc3/drivers/net/Makefile	2010-01-06 09:02:46.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/Makefile	2010-03-05 10:25:56.000000000 +0900
@@ -287,3 +287,4 @@
 obj-$(CONFIG_WIMAX) += wimax/
 
 obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
+obj-$(CONFIG_PCH_GBE) += pch_gbe/
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/Makefile topcliff-2.6.33-rc3/drivers/net/pch_gbe/Makefile
--- linux-2.6.33-rc3/drivers/net/pch_gbe/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/Makefile	2010-03-11 09:35:16.000000000 +0900
@@ -0,0 +1,6 @@
+ifeq ($(CONFIG_PCH_GBE_DEBUG_CORE),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_GBE) += pch_gbe.o
+pch_gbe-objs := pch_gbe_mac.o pch_gbe_phy.o pch_gbe_nvm.o pch_gbe_ethtool.o pch_gbe_plat.o pch_gbe_param.o pch_gbe_api.o pch_gbe_main.o
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.c	2010-03-11 15:12:34.000000000 +0900
@@ -0,0 +1,646 @@
+/*!
+ * @file ioh_gbe_api.c
+ * @brief Linux IOH Gigabit Ethernet Driver HAL API source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_mac.h"
+#include "pch_gbe_api.h"
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw)
+ * @brief   Sets MAC type
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks This function sets the mac type of the adapter based on the
+ *          device ID stored in the hw structure.
+ *          MUST BE FIRST FUNCTION CALLED (explicitly or through
+ *          ioh_gbe_hal_setup_init_funcs()).
+ */
+s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw)
+{
+	struct ioh_gbe_mac_info *mac = &hw->mac;
+	s32 ret_val = IOH_GBE_SUCCESS;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_set_mac_type");
+
+	switch ((u16) hw->device_id) {
+	case PCI_DEVICE_ID_INTEL_IOH1_GBE:
+		mac->type = IOH_GBE_MAC_TYPE_IOH1;
+		break;
+	default:
+		/* Should never have loaded on this device */
+		mac->type = IOH_GBE_MAC_TYPE_UNDEFINED;
+		ret_val = -IOH_GBE_ERR_MAC_INIT;
+		break;
+	}
+	IOH_GBE_TESTOUT("mac->type:0x%x  ret_val:0x%x\n", mac->type, ret_val);
+	return ret_val;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw)
+ * @brief   Initializes function pointers
+ * @param   hw [INOUT] pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks This function must be called by a driver in order to use the rest
+ *          of the 'shared' code files. Called by drivers only.
+ */
+s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw)
+{
+	s32 ret_val;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_setup_init_funcs");
+
+	/* Can't do much good without knowing the MAC type.
+	 */
+	ret_val = ioh_gbe_hal_set_mac_type(hw);
+	if (ret_val) {
+		IOH_GBE_DBGOUT("ERROR: MAC type could not be set properly.\n");
+		goto out;
+	}
+
+	if (!hw->hw_addr) {
+		IOH_GBE_DBGOUT("ERROR: Registers not mapped\n");
+		ret_val = -IOH_GBE_ERR_CONFIG;
+		goto out;
+	}
+
+	/* Set up the init function pointers. These are functions within the
+	 * adapter family file that sets up function pointers for the rest of
+	 * the functions in that family.
+	 */
+	switch (hw->mac.type) {
+	case IOH_GBE_MAC_TYPE_IOH1:
+	case IOH_GBE_MAC_TYPE_IOH2:
+		ioh_gbe_plat_init_function_pointers(hw);
+		break;
+	default:
+		IOH_GBE_DBGOUT("Hardware not supported\n");
+		ret_val = -IOH_GBE_ERR_CONFIG;
+		break;
+	}
+out:
+	IOH_GBE_TESTOUT("ret_val:0x%x\n", ret_val);
+	return ret_val;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw)
+ * @brief   Obtain bus information for adapter
+ * @param   hw [INOUT] pointer to the HW structure
+ * @return  None
+ * @remarks This will obtain information about the HW bus for which the
+ *          adaper is attached and stores it in the hw structure. This is a
+ *          function pointer entry point called by drivers.
+ */
+void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_get_bus_info");
+
+	if (hw->func.get_bus_info != NULL)
+		hw->func.get_bus_info(hw);
+	else
+		IOH_GBE_ERR("Error: configuration\n");
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw,
+ *               u8 *mc_addr_list, u32 mc_addr_count,
+ *               u32 mar_used_count, u32 mar_count)
+ * @brief   Update Multicast addresses
+ * @param   hw        [INOUT] Pointer to the HW structure
+ * @param   mc_addr_list   [IN]Array of multicast addresses to program
+ * @param   mc_addr_count  [IN]Number of multicast addresses to program
+ * @param   mar_used_count [IN]The first MAC Address register free to program
+ * @param   mar_count [IN]Total number of supported MAC Address Registers
+ * @return  None
+ * @remarks
+ *  Updates the MAC Address Registers and Multicast Table Array.
+ *  The caller must have a packed mc_addr_list of multicast addresses.
+ *  The parameter mar_count will usually be hw->mac.mar_entry_count
+ *  unless there are workarounds that change this.  Currently no func pointer
+ *  exists and all implementations are handled in the generic version of this
+ *  function.
+ */
+void
+ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw,
+				u8 *mc_addr_list,
+				u32 mc_addr_count,
+				u32 mar_used_count, u32 mar_count)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_mc_addr_list_update");
+
+	if (hw->func.mc_addr_list_update != NULL) {
+		hw->func.mc_addr_list_update(hw,
+					     mc_addr_list,
+					     mc_addr_count,
+					     mar_used_count, mar_count);
+	}
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw)
+ * @brief   Force MAC flow control
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Force the MAC's flow control settings. Currently no func pointer exists
+ *  and all implementations are handled in the generic version of this
+ *  function.
+ */
+s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_force_mac_fc");
+
+	return ioh_gbe_mac_force_mac_fc(hw);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw)
+ * @brief   Reset hardware
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  This resets the hardware into a known state. This is a function pointer
+ *  entry point called by drivers.
+ */
+s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_reset_hw");
+
+	if (hw->func.reset_hw != NULL) {
+		hw->func.reset_hw(hw);
+		return IOH_GBE_SUCCESS;
+	} else {
+		IOH_GBE_ERR("Error: configuration\n");
+		return -IOH_GBE_ERR_CONFIG;
+	}
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw)
+ * @brief   Initialize hardware
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  This inits the hardware readying it for operation. This is a function
+ *  pointer entry point called by drivers.
+ */
+s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_init_hw");
+
+	if (hw->func.init_hw != NULL) {
+		return hw->func.init_hw(hw);
+	} else {
+		IOH_GBE_ERR("Error: configuration\n");
+		return -IOH_GBE_ERR_CONFIG;
+	}
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw)
+ * @brief   Configures link and flow control
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  This configures link and flow control settings for the adapter. This
+ *  is a function pointer entry point called by drivers. While modules can
+ *  also call this, they probably call their own version of this function.
+ */
+s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_setup_link");
+
+	if (hw->func.setup_link != NULL) {
+		return hw->func.setup_link(hw);
+	} else {
+		IOH_GBE_ERR("Error: configuration\n");
+		return -IOH_GBE_ERR_CONFIG;
+	}
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw)
+ * @brief   Configures SW controllable LED
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  This prepares the SW controllable LED for use and saves the current state
+ *  of the LED so it can be later restored. This is a function pointer entry
+ *  point called by drivers.
+ */
+s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_setup_led");
+
+	if (hw->func.setup_led != NULL)
+		return hw->func.setup_led(hw);
+	else
+		return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw)
+ * @brief   Restores SW controllable LED
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  This restores the SW controllable LED to the value saved off by
+ *  ioh_gbe_hal_setup_led.
+ *  This is a function pointer entry point called by drivers.
+ */
+s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_cleanup_led");
+
+	if (hw->func.cleanup_led != NULL)
+		return hw->func.cleanup_led(hw);
+	else
+		return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw)
+ * @brief   Turn on SW controllable LED
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Turns the SW defined LED on. This is a function pointer entry point
+ *  called by drivers.
+ */
+s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_led_on");
+
+	if (hw->func.led_on != NULL)
+		return hw->func.led_on(hw);
+	else
+		return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw)
+ * @brief   Turn off SW controllable LED
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Turns the SW defined LED off. This is a function pointer entry point
+ *  called by drivers.
+ */
+s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_led_off");
+
+	if (hw->func.led_off != NULL)
+		return hw->func.led_off(hw);
+	else
+		return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index)
+ * @brief   Sets a MAC address register
+ * @param   hw    [INOUT] Pointer to the HW structure
+ * @param   addr  [IN] Address to set the RAR to
+ * @param   index [IN] The RAR to set
+ * @return  None
+ * @remarks
+ *  Sets a MAC Address Register (RAR) to the specified address.
+ *  Currently no func pointer exists and all implementations are
+ *  handled in the generic version of this function.
+ */
+void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_mar_set");
+
+	ioh_gbe_mac_mar_set(hw, addr, index);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw,
+ *                                       u32 offset, u16 *data)
+ * @brief   Reads PHY register
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   offset [IN] The register to read
+ * @param   data   [IN] The buffer to store the 16-bit read.
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Reads the PHY register and returns the value in data.
+ *  This is a function pointer entry point called by drivers.
+ */
+s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 *data)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_read_phy_reg");
+
+	if (hw->func.read_phy_reg != NULL)
+		return hw->func.read_phy_reg(hw, offset, data);
+	else
+		return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw,
+ *                                        u32 offset, u16 data)
+ * @brief   Writes PHY register
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   offset [IN] The register to write
+ * @param   data   [IN] The value to write.
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Writes the PHY register at offset with the value in data.
+ *  This is a function pointer entry point called by drivers.
+ */
+s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 data)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_write_phy_reg");
+
+	if (hw->func.write_phy_reg != NULL)
+		return hw->func.write_phy_reg(hw, offset, data);
+	else
+		return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw)
+ * @brief   Hard PHY reset
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  None
+ * @remarks
+ *  Performs a hard PHY reset. This is a function pointer entry point called
+ *  by drivers.
+ */
+void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_phy_hw_reset");
+
+	if (hw->func.reset_phy != NULL)
+		hw->func.reset_phy(hw);
+	else
+		IOH_GBE_ERR("Error: configuration\n");
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw)
+ * @brief   Soft PHY reset
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  None
+ * @remarks
+ *  Performs a soft PHY reset on those that apply. This is a function pointer
+ *  entry point called by drivers.
+ */
+void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_phy_sw_reset");
+
+	if (hw->func.sw_reset_phy != NULL)
+		hw->func.sw_reset_phy(hw);
+	else
+		IOH_GBE_ERR("Error: configuration\n");
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw)
+ * @brief   Reads MAC address
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Reads the MAC address out of the adapter and stores it in the HW structure.
+ *  Currently no func pointer exists and all implementations are handled in the
+ *  generic version of this function.
+ */
+s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_read_mac_addr");
+
+	if (hw->func.read_mac_addr != NULL) {
+		return hw->func.read_mac_addr(hw);
+	} else {
+		IOH_GBE_ERR("Error: configuration\n");
+		return -IOH_GBE_ERR_CONFIG;
+	}
+}
+
+#ifdef CONFIG_PCH_PCIEQOS
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw)
+ * @brief   Verifies NVM (EEPROM) checksum
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Validates the NVM checksum is correct. This is a function pointer entry
+ *  point called by drivers.
+ */
+s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_validate_nvm_checksum");
+
+	if (hw->func.validate_nvm != NULL) {
+		return hw->func.validate_nvm(hw);
+	} else {
+		IOH_GBE_ERR("Error: configuration\n");
+		return -IOH_GBE_ERR_CONFIG;
+	}
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw,
+ *                                   u32 offset, u8 *data)
+ * @brief   Reads NVM (EEPROM)
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   offset [IN] The word offset to read
+ * @param   data   [IN] Pointer to the properly sized buffer for the data.
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Reads 16-bit chunks of data from the NVM (EEPROM). This is a function
+ *  pointer entry point called by drivers.
+ */
+s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_read_nvm");
+
+	if (hw->func.read_nvm != NULL) {
+		return hw->func.read_nvm(hw, offset, data);
+	} else {
+		IOH_GBE_ERR("Error: configuration\n");
+		return -IOH_GBE_ERR_CONFIG;
+	}
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw,
+ *                                    u32 offset, u8 *data)
+ * @brief   Writes to NVM (EEPROM)
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   offset [IN] The word offset to read
+ * @param   data   [IN] Pointer to the properly sized buffer for the data.
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  Writes 16-bit chunks of data to the NVM (EEPROM). This is a function
+ *  pointer entry point called by drivers.
+ */
+s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_write_nvm");
+
+	if (hw->func.write_nvm != NULL)
+		return hw->func.write_nvm(hw, offset, data);
+	else
+		return IOH_GBE_SUCCESS;
+}
+#endif /* CONFIG_PCH_PCIEQOS */
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt)
+ * @brief   Set wake-on-lan event
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   wu_evt [IN] Wake up event
+ * @return  None
+ */
+void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_set_wol_event");
+
+	ioh_gbe_mac_set_wol_event(hw, wu_evt);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw)
+ * @brief   Power up PHY
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  None
+ */
+void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_power_up_phy");
+
+	if (hw->func.power_up_phy != NULL)
+		hw->func.power_up_phy(hw);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw)
+ * @brief   Power down PHY
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  None
+ */
+void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_power_down_phy");
+
+	if (hw->func.power_down_phy != NULL)
+		hw->func.power_down_phy(hw);
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      u16 ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw,
+ *                                    u32 addr, u32 dir, u32 reg, u16 data)
+ * @brief   Control MII Management IF
+ * @param   hw   [INOUT] Pointer to the HW structure
+ * @param   addr [IN] Address of PHY
+ * @param   dir  [IN] Operetion. (Write or Read)
+ * @param   reg  [IN] Access register of PHY
+ * @param   data [IN] Write data
+ * @return  None
+ */
+u16
+ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
+		      u16 data)
+{
+	IOH_GBE_DBGOUT2("ioh_gbe_hal_ctrl_miim\n");
+
+	if (hw->func.ctrl_miim != NULL) {
+		return hw->func.ctrl_miim(hw, addr, dir, reg, data);
+	} else {
+		IOH_GBE_ERR("Error: configuration\n");
+		return IOH_GBE_SUCCESS;
+	}
+}
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw)
+ * @brief   Set pause packet
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  None
+ */
+void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_hal_set_pause_packet");
+
+	if (hw->func.pause_packet != NULL)
+		hw->func.pause_packet(hw);
+	else
+		IOH_GBE_ERR("Error: configuration\n");
+}
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_api.h	2010-03-11 15:11:51.000000000 +0900
@@ -0,0 +1,252 @@
+/*!
+ * @file ioh_gbe_api.h
+ * @brief Linux IOH Gigabit Ethernet Driver HAL API header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+
+#ifndef _IOH_GBE_API_H_
+#define _IOH_GBE_API_H_
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw)
+ * @brief   Sets MAC type
+ */
+s32 ioh_gbe_hal_set_mac_type(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw)
+ * @brief   Initializes function pointers
+ */
+s32 ioh_gbe_hal_setup_init_funcs(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw)
+ * @brief   Obtain bus information for adapter
+ */
+void ioh_gbe_hal_get_bus_info(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw,
+ *               u8 *mc_addr_list, u32 mc_addr_count,
+ *               u32 mar_used_count, u32 mar_count)
+ * @brief   Update Multicast addresses
+ */
+void ioh_gbe_hal_mc_addr_list_update(struct ioh_gbe_hw *hw,
+					u8 *mc_addr_list, u32 mc_addr_count,
+					u32 mar_used_count, u32 mar_count);
+
+/*
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw)
+ * @brief   Force MAC flow control
+ */
+s32 ioh_gbe_hal_force_mac_fc(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw)
+ * @brief   Reset hardware
+ */
+s32 ioh_gbe_hal_reset_hw(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw)
+ * @brief   Initialize hardware
+ */
+s32 ioh_gbe_hal_init_hw(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw)
+ * @brief   Configures link and flow control
+ */
+s32 ioh_gbe_hal_setup_link(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw)
+ * @brief   Configures SW controllable LED
+ */
+s32 ioh_gbe_hal_setup_led(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw)
+ * @brief   Restores SW controllable LED
+ */
+s32 ioh_gbe_hal_cleanup_led(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw)
+ * @brief   Turn on SW controllable LED
+ */
+s32 ioh_gbe_hal_led_on(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw)
+ * @brief   Turn off SW controllable LED
+ */
+s32 ioh_gbe_hal_led_off(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index)
+ * @brief   Sets a MAC address register
+ */
+void ioh_gbe_hal_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw,
+ *						u32 offset, u16 *data)
+ * @brief   Reads PHY register
+ */
+s32 ioh_gbe_hal_read_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 *data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw,
+ *						u32 offset, u16 data)
+ * @brief   Writes PHY register
+ */
+s32 ioh_gbe_hal_write_phy_reg(struct ioh_gbe_hw *hw, u32 offset, u16 data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw)
+ * @brief   Hard PHY reset
+ */
+void ioh_gbe_hal_phy_hw_reset(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw)
+ * @brief   Soft PHY reset
+ */
+void ioh_gbe_hal_phy_sw_reset(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw)
+ * @brief   Reads MAC address
+ */
+s32 ioh_gbe_hal_read_mac_addr(struct ioh_gbe_hw *hw);
+
+#ifdef CONFIG_PCH_PCIEQOS
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw)
+ * @brief   Verifies NVM (EEPROM) checksum
+ */
+s32 ioh_gbe_hal_validate_nvm_checksum(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw,
+ *					u32 offset, u8 *data)
+ * @brief   Reads NVM (EEPROM)
+ */
+s32 ioh_gbe_hal_read_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw,
+ *					u32 offset, u8 *data)
+ * @brief   Writes to NVM (EEPROM)
+ */
+s32 ioh_gbe_hal_write_nvm(struct ioh_gbe_hw *hw, u32 offset, u8 *data);
+#endif /* CONFIG_PCH_PCIEQOS */
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt)
+ * @brief   Set wake-on-lan event
+ */
+void ioh_gbe_hal_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw)
+ * @brief   Power up PHY
+ */
+void ioh_gbe_hal_power_up_phy(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw)
+ * @brief   Power down PHY
+ */
+void ioh_gbe_hal_power_down_phy(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      u16 ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw,
+ *                                    u32 addr, u32 dir, u32 reg, u16 data)
+ * @brief   Control MII Management IF
+ */
+u16 ioh_gbe_hal_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
+			  u16 data);
+
+/*!
+ * @ingroup HAL API Layer
+ * @fn      void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw)
+ * @brief   Set pause packet
+ */
+void ioh_gbe_hal_set_pause_packet(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup  HAL API Layer
+ * @def      IOH_GBE_HAL_MIIM_READ
+ * @brief    Read operation is done through MII Management IF
+ */
+#define IOH_GBE_HAL_MIIM_READ          ((u32)0x00000000)
+
+/*!
+ * @ingroup  HAL API Layer
+ * @def      IOH_GBE_HAL_MIIM_WRITE
+ * @brief    Write operation is done through MII Management IF
+ */
+#define IOH_GBE_HAL_MIIM_WRITE         ((u32)0x04000000)
+
+/* pch_gbe_plat.c */
+/*!
+ * @ingroup HAL internal functions
+ * @fn      void ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw)
+ * @brief   Init func ptrs.
+ */
+void ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw);
+
+#endif
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_defines.h	2010-03-09 09:27:26.000000000 +0900
@@ -0,0 +1,367 @@
+/*!
+ * @file ioh_gbe_defines.h
+ * @brief Linux IOH Gigabit Ethernet Driver defines macro header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_DEFINES_H_
+#define _IOH_GBE_DEFINES_H_
+
+#include "pch_gbe_pci_ids.h"	/* Pci vender/device ID */
+
+/* DEBUG OPTION */
+/* #define DEBUG_TEST */
+/* #define NVM_MAC_FIX *//* MAC: 00 21 97 77 65 13 */
+/* #define NVM_DUMMY_READ */
+#define PHY_RESET_REG_INIT
+
+#ifdef DEBUG_TEST
+#define IOH_GBE_NETIF_MSG_DEFAULT       0x7fff	/* ALL Enable */
+#else
+#define IOH_GBE_NETIF_MSG_DEFAULT       0x0000	/* All Disable */
+#endif
+/*-- Kind of Messege --------------------------
+	NETIF_MSG_DRV		= 0x0001,
+	NETIF_MSG_PROBE		= 0x0002,
+	NETIF_MSG_LINK		= 0x0004,
+	NETIF_MSG_TIMER		= 0x0008,
+	NETIF_MSG_IFDOWN	= 0x0010,
+	NETIF_MSG_IFUP		= 0x0020,
+	NETIF_MSG_RX_ERR	= 0x0040,
+	NETIF_MSG_TX_ERR	= 0x0080,
+	NETIF_MSG_TX_QUEUED	= 0x0100,
+	NETIF_MSG_INTR		= 0x0200,
+	NETIF_MSG_TX_DONE	= 0x0400,
+	NETIF_MSG_RX_STATUS	= 0x0800,
+	NETIF_MSG_PKTDATA	= 0x1000,
+	NETIF_MSG_HW		= 0x2000,
+	NETIF_MSG_WOL		= 0x4000,
+-----------------------------------------------*/
+
+#ifdef DEBUG_TEST
+#define IOH_GBE_ERR(args...)        printk(KERN_ERR DRV_NAME": " args)
+#define IOH_GBE_DBGOUT(S)           printk(KERN_INFO S)
+/* #define IOH_GBE_DBGOUT1(S, A...)    printk(KERN_INFO S, A) */
+#define IOH_GBE_DBGOUT1(S, A...)
+/* #define IOH_GBE_DBGOUT2(S)          IOH_GBE_DBGOUT(S) */
+#define IOH_GBE_DBGOUT2(S, A...)
+#define IOH_GBE_TESTOUT(S, A...)    printk(KERN_INFO "  TEST_OUT:"S, A)
+/* #define IOH_GBE_TESTOUT2(S, A...)    printk(KERN_INFO "  TEST_OUT:"S, A) */
+#define IOH_GBE_TESTOUT2(S, A...)
+#define IOH_GBE_DBGFUNC(F)          (IOH_GBE_DBGOUT(F "\n"))
+#else
+#define IOH_GBE_ERR(args...)        printk(KERN_ERR DRV_NAME": " args)
+#define IOH_GBE_DBGOUT(S)
+#define IOH_GBE_DBGOUT1(S, A...)
+#define IOH_GBE_DBGOUT2(S, A...)
+#define IOH_GBE_TESTOUT(S, A...)
+#define IOH_GBE_TESTOUT2(S, A...)
+#define IOH_GBE_DBGFUNC(F)
+#endif
+
+/* IF OPTION */
+#define IOH_GBE_MAC_IFOP_RGMII
+#define IOH_GBE_MAC_RGMII_CTRL_SETTING ( \
+    IOH_GBE_CHIP_TYPE_INTERNAL | \
+    IOH_GBE_RGMII_MODE_RGMII   | \
+    IOH_GBE_CRS_SEL              \
+    )
+
+/* TX/RX descriptor defines */
+#define IOH_GBE_DEFAULT_TXD                  256
+#define IOH_GBE_MAX_TXD                     4096
+#define IOH_GBE_MIN_TXD                        8
+#define IOH_GBE_DEFAULT_RXD                  256
+#define IOH_GBE_MAX_RXD                     4096
+#define IOH_GBE_MIN_RXD                        8
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define IOH_GBE_TX_DESC_MULTIPLE               8
+#define IOH_GBE_RX_DESC_MULTIPLE               8
+
+/* Checksum Offload defines Enable/Disable */
+#define IOH_GBE_DEFAULT_RX_CSUM             TRUE	/* TRUEorFALSE */
+#define IOH_GBE_DEFAULT_TX_CSUM             TRUE	/* TRUEorFALSE */
+
+/* Copybreak default */
+#define IOH_GBE_COPYBREAK_DEFAULT       256
+#define IOH_GBE_PCI_BAR                 1
+
+/* Device Driver infomation */
+#define DRV_NAME        "ioh_gbe"
+#define DRV_STRING      "IOH Network Driver"
+#define DRV_EXT         "-NAPI"
+#define DRV_VERSION     "0.91"DRV_EXT
+#define DRV_DESCRIPTION \
+	"OKI semiconductor sample Linux driver for IOH Gigabit ethernet"
+#define DRV_COPYRIGHT   "Copyright(c) 2009 OKI semiconductor"
+#define FIRM_VERSION    "N/A"
+
+#define IOH_GBE_MAC_REGS_LEN    76
+#define IOH_GBE_PHY_REGS_LEN    32
+#define IOH_GBE_REGS_LEN        (IOH_GBE_MAC_REGS_LEN + IOH_GBE_PHY_REGS_LEN)
+
+/* #define IOH_GBE_DMA_ALIGN           48 */
+#define IOH_GBE_DMA_ALIGN           (32)	/*for 2.6.33-rc3 */
+#define IOH_GBE_ETH_ALEN            6
+
+/* Initialize the wake-on-LAN settings */
+#define IOH_GBE_WL_INIT_SETTING    ( \
+    IOH_GBE_WLC_BR  |\
+    IOH_GBE_WLC_MLT |\
+    IOH_GBE_WLC_IND |\
+    IOH_GBE_WLC_MP   \
+    )
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXT0   = Receiver Timer Interrupt (ring 0)
+ *   o TXDW   = Transmit Descriptor Written Back
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error
+ *   o LSC    = Link Status Change
+ */
+#define IOH_GBE_INT_ENABLE_MASK ( \
+	IOH_GBE_INT_RX_DMA_CMPLT |    \
+	IOH_GBE_INT_RX_DSC_EMP   |    \
+	IOH_GBE_INT_WOL_DET      |    \
+	IOH_GBE_INT_TX_CMPLT          \
+    )
+
+/* Ethertype field values */
+#define IOH_GBE_MAX_JUMBO_FRAME_SIZE    (10318)
+#define IOH_GBE_FRAME_SIZE_2048         (2048)
+#define IOH_GBE_FRAME_SIZE_4096         (4096)
+#define IOH_GBE_FRAME_SIZE_8192         (8192)
+
+/* watchdog time */
+#define IOH_GBE_WATCHDOG_PERIOD        (1 * HZ)
+
+#define IOH_GBE_TX_WEIGHT         64
+#define IOH_GBE_RX_WEIGHT         64
+#define IOH_GBE_RX_BUFFER_WRITE   16
+
+#define DSC_INIT16  0xC000
+
+/* MAC Address */
+/* Number of high/low register pairs in the MAC_ADR. The MAC_ADR (MAC Address
+ * Registers) holds the directed and multicast addresses that we monitor.
+ * Technically, we have 16 spots.  However, we reserve one of these spots
+ * (MAC_ADR[15]) for our directed address used by controllers with
+ * manageability enabled, allowing us room for 15 multicast addresses.
+ */
+#define IOH_GBE_MAR_ENTRIES      16
+#define IOH_GBE_SHORT_PKT        64
+
+/* PHY param */
+#define	IOH_GBE_PHY_RESET_DELAY_US  10
+/* NVM param */
+#define	IOH_GBE_NVM_WORD_SIZE       3	/* 16bit word size */
+
+/* Error Codes */
+#define IOH_GBE_SUCCESS                      0
+#define IOH_GBE_ERR_NVM                      1
+#define IOH_GBE_ERR_PHY                      2
+#define IOH_GBE_ERR_CONFIG                   3
+#define IOH_GBE_ERR_PARAM                    4
+#define IOH_GBE_ERR_MAC_INIT                 5
+#define IOH_GBE_ERR_PHY_TYPE                 6
+#define IOH_GBE_ERR_RESET                    9
+#define IOH_GBE_ERR_MASTER_REQUESTS_PENDING 10
+#define IOH_GBE_ERR_HOST_INTERFACE_COMMAND  11
+#define IOH_GBE_BLK_PHY_RESET               12
+#define IOH_GBE_ERR_SWFW_SYNC               13
+#define IOH_GBE_NOT_IMPLEMENTED             14
+
+#define PHY_MAX_REG_ADDRESS   0x1F	/* 5 bit address bus (0-0x1F) */
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CONTROL           0x00  /* Control Register */
+#define PHY_STATUS            0x01  /* Status Regiser */
+#define PHY_ID1               0x02  /* Phy Id Register (word 1) */
+#define PHY_ID2               0x03  /* Phy Id Register (word 2) */
+#define PHY_AUTONEG_ADV       0x04  /* Autoneg Advertisement */
+#define PHY_LP_ABILITY        0x05  /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP       0x06  /* Autoneg Expansion Register */
+#define PHY_NEXT_PAGE_TX      0x07  /* Next Page TX */
+#define PHY_LP_NEXT_PAGE      0x08  /* Link Partner Next Page */
+#define PHY_1000T_CTRL        0x09  /* 1000Base-T Control Register */
+#define PHY_1000T_STATUS      0x0A  /* 1000Base-T Status Register */
+#define PHY_EXT_STATUS        0x0F  /* Extended Status Register */
+#define PHY_PHYSP_CONTROL     0x10  /* PHY Specific Control Register */
+#define PHY_EXT_PHYSP_CONTROL 0x14  /* Extended PHY Specific Control Register */
+#define PHY_LED_CONTROL       0x18  /* LED Control Register */
+#define PHY_EXT_PHYSP_STATUS  0x1B  /* Extended PHY Specific Status Register */
+
+/* PHY Control Register */
+#define MII_CR_SPEED_SELECT_MSB 0x0040	/* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_COLL_TEST_ENABLE 0x0080	/* Collision test enable */
+#define MII_CR_FULL_DUPLEX      0x0100	/* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG 0x0200	/* Restart auto negotiation */
+#define MII_CR_ISOLATE          0x0400	/* Isolate PHY from MII */
+#define MII_CR_POWER_DOWN       0x0800	/* Power down */
+#define MII_CR_AUTO_NEG_EN      0x1000	/* Auto Neg Enable */
+#define MII_CR_SPEED_SELECT_LSB 0x2000	/* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_LOOPBACK         0x4000	/* 0 = normal, 1 = loopback */
+#define MII_CR_RESET            0x8000	/* 0 = normal, 1 = PHY reset */
+#define MII_CR_SPEED_1000       0x0040
+#define MII_CR_SPEED_100        0x2000
+#define MII_CR_SPEED_10         0x0000
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS     0x0001	/* Extended register capabilities */
+#define MII_SR_JABBER_DETECT     0x0002	/* Jabber Detected */
+#define MII_SR_LINK_STATUS       0x0004	/* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS      0x0008	/* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT      0x0010	/* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE  0x0020	/* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040	/* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS   0x0100	/* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS     0x0200	/* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS     0x0400	/* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS       0x0800	/* 10T   Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS       0x1000	/* 10T   Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS      0x2000	/* 100X  Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS      0x4000	/* 100X  Full Duplex Capable */
+#define MII_SR_100T4_CAPS        0x8000	/* 100T4 Capable */
+
+/* Phy Id Register (word 2) */
+#define PHY_REVISION_MASK        0x000F
+
+/* Autoneg Advertisement Register */
+#define NWAY_AR_SELECTOR_FIELD   0x0001	/* indicates IEEE 802.3 CSMA/CD */
+#define NWAY_AR_10T_HD_CAPS      0x0020	/* 10T   Half Duplex Capable */
+#define NWAY_AR_10T_FD_CAPS      0x0040	/* 10T   Full Duplex Capable */
+#define NWAY_AR_100TX_HD_CAPS    0x0080	/* 100TX Half Duplex Capable */
+#define NWAY_AR_100TX_FD_CAPS    0x0100	/* 100TX Full Duplex Capable */
+#define NWAY_AR_100T4_CAPS       0x0200	/* 100T4 Capable */
+#define NWAY_AR_PAUSE            0x0400	/* Pause operation desired */
+#define NWAY_AR_ASM_DIR          0x0800	/* Asymmetric Pause Direction bit */
+#define NWAY_AR_REMOTE_FAULT     0x2000	/* Remote Fault detected */
+#define NWAY_AR_NEXT_PAGE        0x8000	/* Next Page ability supported */
+
+/* Link Partner Ability Register (Base Page) */
+#define NWAY_LPAR_SELECTOR_FIELD 0x0000	/* LP protocol selector field */
+#define NWAY_LPAR_10T_HD_CAPS    0x0020	/* LP is 10T   Half Duplex Capable */
+#define NWAY_LPAR_10T_FD_CAPS    0x0040	/* LP is 10T   Full Duplex Capable */
+#define NWAY_LPAR_100TX_HD_CAPS  0x0080	/* LP is 100TX Half Duplex Capable */
+#define NWAY_LPAR_100TX_FD_CAPS  0x0100	/* LP is 100TX Full Duplex Capable */
+#define NWAY_LPAR_100T4_CAPS     0x0200	/* LP is 100T4 Capable */
+#define NWAY_LPAR_PAUSE          0x0400	/* LP Pause operation desired */
+#define NWAY_LPAR_ASM_DIR        0x0800	/* LP Asymmetric Pause Direction bit */
+#define NWAY_LPAR_REMOTE_FAULT   0x2000	/* LP has detected Remote Fault */
+#define NWAY_LPAR_ACKNOWLEDGE    0x4000	/* LP has rx'd link code word */
+#define NWAY_LPAR_NEXT_PAGE      0x8000	/* Next Page ability supported */
+
+/* Autoneg Expansion Register */
+#define NWAY_ER_LP_NWAY_CAPS      0x0001 /* LP has Auto Neg Capability */
+#define NWAY_ER_PAGE_RXD          0x0002 /* LP is 10T   Half Duplex Capable */
+#define NWAY_ER_NEXT_PAGE_CAPS    0x0004 /* LP is 10T   Full Duplex Capable */
+#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
+#define NWAY_ER_PAR_DETECT_FAULT  0x0010 /* LP is 100TX Full Duplex Capable */
+
+/* 1000BASE-T Control Register */
+#define CR_1000T_ASYM_PAUSE      0x0080	/* Advertise asymmetric pause bit */
+#define CR_1000T_HD_CAPS         0x0100	/* Advertise 1000T HD capability */
+#define CR_1000T_FD_CAPS         0x0200	/* Advertise 1000T FD capability  */
+#define CR_1000T_REPEATER_DTE    0x0400	/* 1=Repeater/switch device port */
+					/* 0=DTE device */
+#define CR_1000T_MS_VALUE        0x0800	/* 1=Configure PHY as Master */
+					/* 0=Configure PHY as Slave */
+#define CR_1000T_MS_ENABLE       0x1000	/* 1=Master/Slave manual config value */
+					/* 0=Automatic Master/Slave config */
+#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
+#define CR_1000T_TEST_MODE_1      0x2000 /* Transmit Waveform test */
+#define CR_1000T_TEST_MODE_2      0x4000 /* Master Transmit Jitter test */
+#define CR_1000T_TEST_MODE_3      0x6000 /* Slave Transmit Jitter test */
+#define CR_1000T_TEST_MODE_4      0x8000 /* Transmitter Distortion test */
+
+/* 1000BASE-T Status Register */
+#define SR_1000T_IDLE_ERROR_CNT   0x00FF /* Num idle errors since last read */
+#define SR_1000T_ASYM_PAUSE_DIR   0x0100 /* LP asymmetric pause direction bit */
+#define SR_1000T_LP_HD_CAPS       0x0400 /* LP is 1000T HD capable */
+#define SR_1000T_LP_FD_CAPS       0x0800 /* LP is 1000T FD capable */
+#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
+#define SR_1000T_LOCAL_RX_STATUS  0x2000 /* Local receiver OK */
+#define SR_1000T_MS_CONFIG_RES    0x4000 /* 1=Local TX is Master, 0=Slave */
+#define SR_1000T_MS_CONFIG_FAULT  0x8000 /* Master/Slave config fault */
+
+/* PHY Specific Control Register */
+#define PHYSP_CTRL_ASSERT_CRS_TX  0x0800
+
+/* LED Control Register */
+#define PHY_LED_CTRL_ON           0x4103
+#define PHY_LED_CTRL_OFF          0x4102
+#define PHY_LED_CTRL_CLEANUP      0x4100
+
+/* Extended PHY Specific Status Register */
+#define HWCFG_MODE_GMII_COPPER    0x000F /* GMII to Copper */
+#define HWCFG_MODE_RGMII_COPPER   0x000B /* RGMII/Modiffied MII to Copper */
+#define HWCFG_MODE_GMII_FIBER     0x0007 /* GMII to Fiber */
+#define HWCFG_MODE_RGMII_FIBER    0x0003 /* RGMII to Fiber */
+#define HWCFG_MODE_GMII_SGMII     0x000E /* GMII to SGMII */
+#define HWCFG_MODE_RGMII_SGMII    0x0006 /* RGMII to SGMII */
+#define HWCFG_MODE_TBI_COPPER     0x000D /* TBI to Copper */
+#define HWCFG_MODE_RTBI_COPPER    0x0009 /* RTBI to Copper */
+#define HWCFG_MODE_MASK           0x000F
+
+#define PHY_SPEED_10    10
+#define PHY_SPEED_100   100
+#define PHY_SPEED_1000  1000
+#define PHY_HALF_DUPLEX 1
+#define PHY_FULL_DUPLEX 2
+
+#define PHY_ADVERTISE_10_HALF      0x0001
+#define PHY_ADVERTISE_10_FULL      0x0002
+#define PHY_ADVERTISE_100_HALF     0x0004
+#define PHY_ADVERTISE_100_FULL     0x0008
+#define PHY_ADVERTISE_1000_HALF    0x0010 /* Not used, just FYI */
+#define PHY_ADVERTISE_1000_FULL    0x0020
+
+/* 1000/H is not supported, nor spec-compliant. */
+#define IOH_GBE_ALL_SPEED_DUPLEX	(PHY_ADVERTISE_10_HALF  | \
+					 PHY_ADVERTISE_10_FULL  | \
+					 PHY_ADVERTISE_100_HALF | \
+					 PHY_ADVERTISE_100_FULL | \
+					 PHY_ADVERTISE_1000_FULL)
+#define IOH_GBE_ALL_NOT_GIG		(PHY_ADVERTISE_10_HALF  | \
+					 PHY_ADVERTISE_10_FULL  | \
+					 PHY_ADVERTISE_100_HALF | \
+					 PHY_ADVERTISE_100_FULL)
+#define IOH_GBE_ALL_100_SPEED		(PHY_ADVERTISE_100_HALF | \
+					 PHY_ADVERTISE_100_FULL)
+#define IOH_GBE_ALL_10_SPEED		(PHY_ADVERTISE_10_HALF  | \
+					 PHY_ADVERTISE_10_FULL)
+#define IOH_GBE_ALL_FULL_DUPLEX		(PHY_ADVERTISE_10_FULL  | \
+					 PHY_ADVERTISE_100_FULL | \
+					 PHY_ADVERTISE_1000_FULL)
+#define IOH_GBE_ALL_HALF_DUPLEX		(PHY_ADVERTISE_10_HALF  | \
+					 PHY_ADVERTISE_100_HALF)
+
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT   IOH_GBE_ALL_SPEED_DUPLEX
+
+#endif
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_ethtool.c	2010-03-11 15:12:31.000000000 +0900
@@ -0,0 +1,1306 @@
+/*!
+ * @file ioh_gbe_ethtool.c
+ * @brief Linux IOH Gigabit Ethernet Ethtool Driver source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_regs.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_api.h"
+#include "pch_gbe.h"
+
+
+/* ----------------------------------------------------------------------------
+	Function prototype
+---------------------------------------------------------------------------- */
+static int ioh_gbe_get_settings(struct net_device *netdev,
+				struct ethtool_cmd *ecmd);
+static int ioh_gbe_set_settings(struct net_device *netdev,
+				struct ethtool_cmd *ecmd);
+static void ioh_gbe_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo);
+static int ioh_gbe_get_regs_len(struct net_device *netdev);
+static void ioh_gbe_get_regs(struct net_device *netdev,
+			     struct ethtool_regs *regs, void *p);
+static void ioh_gbe_get_wol(struct net_device *netdev,
+			    struct ethtool_wolinfo *wol);
+static int ioh_gbe_set_wol(struct net_device *netdev,
+			   struct ethtool_wolinfo *wol);
+static u32 ioh_gbe_get_msglevel(struct net_device *netdev);
+static void ioh_gbe_set_msglevel(struct net_device *netdev, u32 data);
+static int ioh_gbe_nway_reset(struct net_device *netdev);
+#ifdef CONFIG_PCH_PCIEQOS
+static int ioh_gbe_get_eeprom_len(struct net_device *netdev);
+static int ioh_gbe_get_eeprom(struct net_device *netdev,
+			      struct ethtool_eeprom *eeprom, u8 *bytes);
+static int ioh_gbe_set_eeprom(struct net_device *netdev,
+			      struct ethtool_eeprom *eeprom, u8 *bytes);
+#endif
+static void ioh_gbe_get_ringparam(struct net_device *netdev,
+				  struct ethtool_ringparam *ring);
+static int ioh_gbe_set_ringparam(struct net_device *netdev,
+				 struct ethtool_ringparam *ring);
+static void ioh_gbe_get_pauseparam(struct net_device *netdev,
+				   struct ethtool_pauseparam *pause);
+static int ioh_gbe_set_pauseparam(struct net_device *netdev,
+				  struct ethtool_pauseparam *pause);
+static u32 ioh_gbe_get_rx_csum(struct net_device *netdev);
+static int ioh_gbe_set_rx_csum(struct net_device *netdev, u32 data);
+static u32 ioh_gbe_get_tx_csum(struct net_device *netdev);
+static int ioh_gbe_set_tx_csum(struct net_device *netdev, u32 data);
+static void ioh_gbe_diag_test(struct net_device *netdev,
+			      struct ethtool_test *eth_test, u64 *data);
+static void ioh_gbe_get_strings(struct net_device *netdev,
+				u32 stringset, u8 *data);
+static void ioh_gbe_led_blink_callback(unsigned long data);
+static int ioh_gbe_phys_id(struct net_device *netdev, u32 data);
+static void ioh_gbe_get_ethtool_stats(struct net_device *netdev,
+				      struct ethtool_stats *stats, u64 *data);
+static int ioh_gbe_reg_test(struct ioh_gbe_adapter *adapter, uint64_t *data);
+static bool reg_pattern_test(struct ioh_gbe_adapter *adapter, uint64_t *data,
+			     int reg, uint32_t mask, uint32_t write);
+
+/* ----------------------------------------------------------------------------
+	Data
+---------------------------------------------------------------------------- */
+/*!
+ * @ingroup Ethtool driver Layer
+ * @struct  ioh_gbe_stats
+ * @brief   Stats item infomation
+ */
+struct ioh_gbe_stats {
+	signed char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+};
+
+#define IOH_GBE_STAT1(m) (int)(sizeof(((struct ioh_gbe_adapter *)0)->m))
+#define IOH_GBE_STAT2(m) offsetof(struct ioh_gbe_adapter, m)
+
+/*!
+ * @ingroup Ethtool driver Layer
+ * @struct  ioh_gbe_gstrings_stats
+ * @brief   ethtool information status name list
+ */
+static const struct ioh_gbe_stats ioh_gbe_gstrings_stats[] = {
+	{"rx_packets", IOH_GBE_STAT1(stats.rx_packets),
+	 IOH_GBE_STAT2(stats.rx_packets)},
+	{"tx_packets", IOH_GBE_STAT1(stats.tx_packets),
+	 IOH_GBE_STAT2(stats.tx_packets)},
+	{"rx_bytes", IOH_GBE_STAT1(stats.rx_bytes),
+	 IOH_GBE_STAT2(stats.rx_bytes)},
+	{"tx_bytes", IOH_GBE_STAT1(stats.tx_bytes),
+	 IOH_GBE_STAT2(stats.tx_bytes)},
+	{"rx_errors", IOH_GBE_STAT1(stats.rx_errors),
+	 IOH_GBE_STAT2(stats.rx_errors)},
+	{"tx_errors", IOH_GBE_STAT1(stats.tx_errors),
+	 IOH_GBE_STAT2(stats.tx_errors)},
+	{"rx_dropped", IOH_GBE_STAT1(stats.rx_dropped),
+	 IOH_GBE_STAT2(stats.rx_dropped)},
+	{"tx_dropped", IOH_GBE_STAT1(stats.tx_dropped),
+	 IOH_GBE_STAT2(stats.tx_dropped)},
+	{"multicast", IOH_GBE_STAT1(stats.multicast),
+	 IOH_GBE_STAT2(stats.multicast)},
+	{"collisions", IOH_GBE_STAT1(stats.collisions),
+	 IOH_GBE_STAT2(stats.collisions)},
+	{"rx_crc_errors", IOH_GBE_STAT1(stats.rx_crc_errors),
+	 IOH_GBE_STAT2(stats.rx_crc_errors)},
+	{"rx_frame_errors", IOH_GBE_STAT1(stats.rx_frame_errors),
+	 IOH_GBE_STAT2(stats.rx_frame_errors)},
+	{"rx_buff_failed", IOH_GBE_STAT1(stats.rx_alloc_buff_failed),
+	 IOH_GBE_STAT2(stats.rx_alloc_buff_failed)},
+	{"tx_length_errors", IOH_GBE_STAT1(stats.tx_length_errors),
+	 IOH_GBE_STAT2(stats.tx_length_errors)},
+	{"tx_aborted_errors", IOH_GBE_STAT1(stats.tx_aborted_errors),
+	 IOH_GBE_STAT2(stats.tx_aborted_errors)},
+	{"tx_carrier_errors", IOH_GBE_STAT1(stats.tx_carrier_errors),
+	 IOH_GBE_STAT2(stats.tx_carrier_errors)},
+	{"tx_timeout_count", IOH_GBE_STAT1(stats.tx_timeout_count),
+	 IOH_GBE_STAT2(stats.tx_timeout_count)},
+	{"tx_restart_count", IOH_GBE_STAT1(stats.tx_restart_count),
+	 IOH_GBE_STAT2(stats.tx_restart_count)},
+	{"intr_rx_dsc_empty_count",
+	 IOH_GBE_STAT1(stats.intr_rx_dsc_empty_count),
+	 IOH_GBE_STAT2(stats.intr_rx_dsc_empty_count)},
+	{"intr_rx_frame_err_count",
+	 IOH_GBE_STAT1(stats.intr_rx_frame_err_count),
+	 IOH_GBE_STAT2(stats.intr_rx_frame_err_count)},
+	{"intr_rx_fifo_err_count", IOH_GBE_STAT1(stats.intr_rx_fifo_err_count),
+	 IOH_GBE_STAT2(stats.intr_rx_fifo_err_count)},
+	{"intr_rx_dma_err_count", IOH_GBE_STAT1(stats.intr_rx_dma_err_count),
+	 IOH_GBE_STAT2(stats.intr_rx_dma_err_count)},
+	{"intr_tx_fifo_err_count", IOH_GBE_STAT1(stats.intr_tx_fifo_err_count),
+	 IOH_GBE_STAT2(stats.intr_tx_fifo_err_count)},
+	{"intr_tx_dma_err_count", IOH_GBE_STAT1(stats.intr_tx_dma_err_count),
+	 IOH_GBE_STAT2(stats.intr_tx_dma_err_count)},
+	{"intr_tcpip_err_count", IOH_GBE_STAT1(stats.intr_tcpip_err_count),
+	 IOH_GBE_STAT2(stats.intr_tcpip_err_count)}
+};
+
+#define IOH_GBE_QUEUE_STATS_LEN 0
+#define IOH_GBE_GLOBAL_STATS_LEN	\
+((int)sizeof(ioh_gbe_gstrings_stats) / (int)sizeof(struct ioh_gbe_stats))
+
+/*!
+ * @ingroup  Ethtool driver
+ * @def      IOH_GBE_STATS_LEN
+ * @brief    The size of status
+*/
+#define IOH_GBE_STATS_LEN (IOH_GBE_GLOBAL_STATS_LEN + IOH_GBE_QUEUE_STATS_LEN)
+
+/*!
+ * @ingroup Ethtool driver Layer
+ * @struct  ioh_gbe_gstrings_test
+ * @brief   self test item name list
+ */
+static const signed char ioh_gbe_gstrings_test[][ETH_GSTRING_LEN] = {
+	"Register test  (offline)"
+};
+
+/*!
+ * @ingroup  Ethtool driver
+ * @def      IOH_GBE_TEST_LEN
+ * @brief    The size of test packet
+*/
+#define IOH_GBE_TEST_LEN \
+	((int)sizeof(ioh_gbe_gstrings_test) / ETH_GSTRING_LEN)
+
+/*!
+ * @ingroup  Ethtool driver
+ * @def      IOH_GBE_ID_INTERVAL
+ * @brief    Toggle LED 4 times per second = 2 "blinks" per second
+*/
+#define IOH_GBE_ID_INTERVAL	(HZ/4)
+
+/*!
+ * @ingroup  Ethtool driver
+ * @def      IOH_GBE_LED_ON
+ * @brief    Bit defines for adapter->led_status
+*/
+#define IOH_GBE_LED_ON		0
+
+/* ----------------------------------------------------------------------------
+	Function
+---------------------------------------------------------------------------- */
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_get_settings(struct net_device *netdev,
+ *                                          struct ethtool_cmd *ecmd)
+ * @brief   Get device-specific settings
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   ecmd   [INOUT] Ethtool command
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	int ret;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_settings");
+
+	ret = mii_ethtool_gset(&adapter->mii, ecmd);
+	ecmd->supported &= (u32) (~SUPPORTED_TP);
+	ecmd->supported &= (u32) (~SUPPORTED_1000baseT_Half);
+	ecmd->advertising &= (u32) (~ADVERTISED_TP);
+	ecmd->advertising &= (u32) (~ADVERTISED_1000baseT_Half);
+
+	if (netif_carrier_ok(adapter->netdev)) {
+		;
+	} else {
+		ecmd->speed = 0xFFFF;
+		ecmd->duplex = 0xFF;
+	}
+	return ret;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_set_settings(struct net_device *netdev,
+ *                                          struct ethtool_cmd *ecmd)
+ * @brief   Set device-specific settings
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   ecmd   [INOUT] Ethtool command
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	int ret;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_settings");
+
+	while (test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags) != 0)
+		msleep(1);
+	ioh_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
+
+	if (ecmd->speed == 0xFFFF)
+		ecmd->speed = SPEED_1000;
+	if (ecmd->duplex == 0xFF)
+		ecmd->duplex = DUPLEX_FULL;
+	ret = mii_ethtool_sset(&adapter->mii, ecmd);
+	if (ret != 0) {
+		IOH_GBE_ERR("Error: mii_ethtool_sset\n");
+		clear_bit(__IOH_GBE_RESETTING, &adapter->flags);
+		return ret;
+	}
+	hw->mac.link_speed = ecmd->speed;
+	hw->mac.link_duplex = ecmd->duplex;
+	hw->phy.autoneg_advertised = ecmd->advertising;
+	hw->mac.autoneg = ecmd->autoneg;
+	ioh_gbe_hal_phy_sw_reset(hw);
+
+	/* reset the link */
+	if (netif_running(adapter->netdev) != 0) {
+		ioh_gbe_down(adapter);
+		ret = ioh_gbe_up(adapter);
+	} else {
+		ioh_gbe_reset(adapter);
+	}
+
+	clear_bit(__IOH_GBE_RESETTING, &adapter->flags);
+	return ret;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_get_drvinfo(struct net_device *netdev,
+ *                                          struct ethtool_drvinfo *drvinfo)
+ * @brief   Report driver information
+ * @param   netdev  [INOUT] Network interface device structure
+ * @param   drvinfo [INOUT] Driver information structure
+ * @return  None
+ */
+static void
+ioh_gbe_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_drvinfo");
+
+	strcpy(drvinfo->driver, DRV_NAME);
+	strcpy(drvinfo->version, DRV_VERSION);
+	strcpy(drvinfo->fw_version, FIRM_VERSION);
+	strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
+
+	drvinfo->n_stats = IOH_GBE_STATS_LEN;
+	drvinfo->testinfo_len = IOH_GBE_TEST_LEN;
+	drvinfo->regdump_len = ioh_gbe_get_regs_len(netdev);
+#ifdef CONFIG_PCH_PCIEQOS
+	drvinfo->eedump_len = ioh_gbe_get_eeprom_len(netdev);
+#endif
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_get_regs_len(struct net_device *netdev)
+ * @brief   Report the size of device registers
+ * @param   netdev [INOUT] Network interface device structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int ioh_gbe_get_regs_len(struct net_device *netdev)
+{
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_regs_len");
+
+	return IOH_GBE_REGS_LEN * (int)sizeof(u32);
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_get_regs(struct net_device *netdev,
+ *                                       struct ethtool_regs *regs, void *p)
+ * @brief   Get device registers
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   regs   [INOUT] Ethtool register structure
+ * @param   p      [INOUT] Buffer pointer of read device register date
+ * @return  None
+ */
+static void
+ioh_gbe_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 *regs_buff = p;
+	u16 i, reg, tmp;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_regs");
+
+	regs->version = hw->revision_id;
+	regs->version = 0x1000000 | (regs->version << 16) | hw->device_id;
+
+	memset(p, 0, IOH_GBE_REGS_LEN * (int)sizeof(u32));
+	/* 000: */
+	regs_buff[0] = IOH_GBE_READ_REG(hw, INT_ST);
+	regs_buff[1] = IOH_GBE_READ_REG(hw, INT_EN);
+	regs_buff[2] = IOH_GBE_READ_REG(hw, MODE);
+	regs_buff[3] = IOH_GBE_READ_REG(hw, RESET);
+	/* 010: */
+	regs_buff[4] = IOH_GBE_READ_REG(hw, TCPIP_ACC);
+	regs_buff[5] = IOH_GBE_READ_REG(hw, EX_LIST);
+	regs_buff[6] = IOH_GBE_READ_REG(hw, INT_ST_HOLD);
+	regs_buff[7] = IOH_GBE_READ_REG(hw, PHY_INT_CTRL);
+	/* 020: */
+	regs_buff[8] = IOH_GBE_READ_REG(hw, MAC_RX_EN);
+	regs_buff[9] = IOH_GBE_READ_REG(hw, RX_FCTRL);
+	regs_buff[10] = IOH_GBE_READ_REG(hw, PAUSE_REQ);
+	regs_buff[11] = IOH_GBE_READ_REG(hw, RX_MODE);
+	/* 030: */
+	regs_buff[12] = IOH_GBE_READ_REG(hw, TX_MODE);
+	regs_buff[13] = IOH_GBE_READ_REG(hw, RX_FIFO_ST);
+	regs_buff[14] = IOH_GBE_READ_REG(hw, TX_FIFO_ST);
+	regs_buff[15] = IOH_GBE_READ_REG(hw, TX_FID);
+	/* 040: */
+	regs_buff[16] = IOH_GBE_READ_REG(hw, TX_RESULT);
+	regs_buff[17] = IOH_GBE_READ_REG(hw, PAUSE_PKT1);
+	regs_buff[18] = IOH_GBE_READ_REG(hw, PAUSE_PKT2);
+	regs_buff[19] = IOH_GBE_READ_REG(hw, PAUSE_PKT3);
+	/* 050: */
+	regs_buff[20] = IOH_GBE_READ_REG(hw, PAUSE_PKT4);
+	regs_buff[21] = IOH_GBE_READ_REG(hw, PAUSE_PKT5);
+	regs_buff[22] = IOH_GBE_READ_REG(hw, MAC_ADR);
+	regs_buff[23] = IOH_GBE_READ_REG(hw, MAC_ADR1A);
+	/* 060: */
+	regs_buff[24] = IOH_GBE_READ_REG(hw, MAC_ADR1B);
+	regs_buff[25] = IOH_GBE_READ_REG(hw, MAC_ADR2A);
+	regs_buff[26] = IOH_GBE_READ_REG(hw, MAC_ADR2B);
+	regs_buff[27] = IOH_GBE_READ_REG(hw, MAC_ADR3A);
+	/* 070: */
+	regs_buff[28] = IOH_GBE_READ_REG(hw, MAC_ADR3B);
+	regs_buff[29] = IOH_GBE_READ_REG(hw, MAC_ADR4A);
+	regs_buff[30] = IOH_GBE_READ_REG(hw, MAC_ADR4B);
+	regs_buff[31] = IOH_GBE_READ_REG(hw, MAC_ADR5A);
+	/* 080: */
+	regs_buff[32] = IOH_GBE_READ_REG(hw, MAC_ADR5B);
+	regs_buff[33] = IOH_GBE_READ_REG(hw, MAC_ADR6A);
+	regs_buff[34] = IOH_GBE_READ_REG(hw, MAC_ADR6B);
+	regs_buff[35] = IOH_GBE_READ_REG(hw, MAC_ADR7A);
+	/* 090: */
+	regs_buff[36] = IOH_GBE_READ_REG(hw, MAC_ADR7B);
+	regs_buff[37] = IOH_GBE_READ_REG(hw, MAC_ADR8A);
+	regs_buff[38] = IOH_GBE_READ_REG(hw, MAC_ADR8B);
+	regs_buff[39] = IOH_GBE_READ_REG(hw, MAC_ADR9A);
+	/* 0a0: */
+	regs_buff[40] = IOH_GBE_READ_REG(hw, MAC_ADR9B);
+	regs_buff[41] = IOH_GBE_READ_REG(hw, MAC_ADR10A);
+	regs_buff[42] = IOH_GBE_READ_REG(hw, MAC_ADR10B);
+	regs_buff[43] = IOH_GBE_READ_REG(hw, MAC_ADR11A);
+	/* 0b0: */
+	regs_buff[44] = IOH_GBE_READ_REG(hw, MAC_ADR11B);
+	regs_buff[45] = IOH_GBE_READ_REG(hw, MAC_ADR12A);
+	regs_buff[46] = IOH_GBE_READ_REG(hw, MAC_ADR12B);
+	regs_buff[47] = IOH_GBE_READ_REG(hw, MAC_ADR13A);
+	/* 0c0: */
+	regs_buff[48] = IOH_GBE_READ_REG(hw, MAC_ADR13B);
+	regs_buff[49] = IOH_GBE_READ_REG(hw, MAC_ADR14A);
+	regs_buff[50] = IOH_GBE_READ_REG(hw, MAC_ADR14B);
+	regs_buff[51] = IOH_GBE_READ_REG(hw, MAC_ADR15A);
+	/* 0d0: */
+	regs_buff[52] = IOH_GBE_READ_REG(hw, MAC_ADR15B);
+	regs_buff[53] = IOH_GBE_READ_REG(hw, MAC_ADR16A);
+	regs_buff[54] = IOH_GBE_READ_REG(hw, MAC_ADR16B);
+	regs_buff[55] = IOH_GBE_READ_REG(hw, ADDR_MASK);
+	/* 0e0: */
+	regs_buff[56] = IOH_GBE_READ_REG(hw, MIIM);
+	regs_buff[57] = IOH_GBE_READ_REG(hw, RGMII_ST);
+	regs_buff[58] = IOH_GBE_READ_REG(hw, RGMII_CTRL);
+	regs_buff[59] = IOH_GBE_READ_REG(hw, DMA_CTRL);
+	/* 0f0: */
+	regs_buff[60] = IOH_GBE_READ_REG(hw, RX_DSC_BASE);
+	regs_buff[61] = IOH_GBE_READ_REG(hw, RX_DSC_SIZE);
+	regs_buff[62] = IOH_GBE_READ_REG(hw, RX_DSC_HW_P);
+	regs_buff[63] = IOH_GBE_READ_REG(hw, RX_DSC_HW_P_HLD);
+	/* 100: */
+	regs_buff[64] = IOH_GBE_READ_REG(hw, RX_DSC_SW_P);
+	regs_buff[65] = IOH_GBE_READ_REG(hw, TX_DSC_BASE);
+	regs_buff[66] = IOH_GBE_READ_REG(hw, TX_DSC_SIZE);
+	regs_buff[67] = IOH_GBE_READ_REG(hw, TX_DSC_HW_P);
+	/* 110: */
+	regs_buff[68] = IOH_GBE_READ_REG(hw, TX_DSC_HW_P_HLD);
+	regs_buff[69] = IOH_GBE_READ_REG(hw, TX_DSC_SW_P);
+	regs_buff[70] = IOH_GBE_READ_REG(hw, RX_DMA_ST);
+	regs_buff[71] = IOH_GBE_READ_REG(hw, TX_DMA_ST);
+	/* 120: */
+	regs_buff[72] = IOH_GBE_READ_REG(hw, WOL_ST);
+	regs_buff[73] = IOH_GBE_READ_REG(hw, WOL_CTRL);
+	regs_buff[74] = IOH_GBE_READ_REG(hw, WOL_ADDR_MASK);
+	regs_buff[75] = 0x00000000;	/* Dummy read */
+
+	/* 130: */
+	/* PHY register */
+	for (i = IOH_GBE_MAC_REGS_LEN, reg = 0; reg < IOH_GBE_PHY_REGS_LEN;
+	     i++, reg++) {
+		ioh_gbe_hal_read_phy_reg(&adapter->hw, reg, &tmp);
+		regs_buff[i] = tmp;
+	}
+
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_get_wol(struct net_device *netdev,
+ *                                      struct ethtool_wolinfo *wol)
+ * @brief   Report whether Wake-on-Lan is enabled
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   wol    [OUT] Wake-on-Lan information
+ * @return  None
+ */
+static void
+ioh_gbe_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_wol");
+
+	wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+	wol->wolopts = 0;
+
+	if ((adapter->wake_up_evt & IOH_GBE_WLC_IND) != 0)
+		wol->wolopts |= WAKE_UCAST;
+	if ((adapter->wake_up_evt & IOH_GBE_WLC_MLT) != 0)
+		wol->wolopts |= WAKE_MCAST;
+	if ((adapter->wake_up_evt & IOH_GBE_WLC_BR) != 0)
+		wol->wolopts |= WAKE_BCAST;
+	if ((adapter->wake_up_evt & IOH_GBE_WLC_MP) != 0)
+		wol->wolopts |= WAKE_MAGIC;
+	return;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_set_wol(struct net_device *netdev,
+ *                                     struct ethtool_wolinfo *wol)
+ * @brief   Turn Wake-on-Lan on or off
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   wol    [IN] Pointer of wake-on-Lan information straucture
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_wol");
+
+	if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) != 0)
+		return -EOPNOTSUPP;
+	/* these settings will always override what we currently have */
+	adapter->wake_up_evt = 0;
+
+	if ((wol->wolopts & WAKE_UCAST) != 0)
+		adapter->wake_up_evt |= IOH_GBE_WLC_IND;
+	if ((wol->wolopts & WAKE_MCAST) != 0)
+		adapter->wake_up_evt |= IOH_GBE_WLC_MLT;
+	if ((wol->wolopts & WAKE_BCAST) != 0)
+		adapter->wake_up_evt |= IOH_GBE_WLC_BR;
+	if ((wol->wolopts & WAKE_MAGIC) != 0)
+		adapter->wake_up_evt |= IOH_GBE_WLC_MP;
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static u32 ioh_gbe_get_msglevel(struct net_device *netdev)
+ * @brief   Report driver message level
+ * @param   netdev [INOUT] Network interface device structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static u32 ioh_gbe_get_msglevel(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_msglevel");
+
+	return adapter->msg_enable;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_set_msglevel(struct net_device *netdev,
+ *                                           u32 data)
+ * @brief   Set driver message level
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   data   [IN] Driver message level
+ * @return  None
+ */
+static void ioh_gbe_set_msglevel(struct net_device *netdev, u32 data)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_msglevel");
+
+	adapter->msg_enable = data;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_nway_reset(struct net_device *netdev)
+ * @brief   Restart autonegotiation
+ * @param   netdev [INOUT] Network interface device structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int ioh_gbe_nway_reset(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_nway_reset");
+
+	return mii_nway_restart(&adapter->mii);
+}
+
+#ifdef CONFIG_PCH_PCIEQOS
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_get_eeprom_len(struct net_device *netdev)
+ * @brief   Report the device EEPROM memory size
+ * @param   netdev [INOUT] Network interface device structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int ioh_gbe_get_eeprom_len(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_eeprom_len");
+
+	return adapter->hw.nvm.word_size * 2;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_get_eeprom(struct net_device *netdev,
+ *                         struct ethtool_eeprom *eeprom, u8 *bytes)
+ * @brief   Read data from the device EEPROM
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   eeprom [INOUT] EEPROM get information structur
+ * @param   bytes  [OUT] Pointer of read data
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_get_eeprom(struct net_device *netdev,
+		   struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	int ret = IOH_GBE_SUCCESS;
+	u32 offset;
+	u8 i;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_eeprom");
+
+	if (eeprom->len == 0)
+		return -EINVAL;
+	eeprom->magic = (hw->vendor_id);
+
+	for (i = 0, offset = eeprom->offset; i < (eeprom->len); i++, offset++) {
+		ret = ioh_gbe_hal_read_nvm(hw, offset, (bytes + i));
+		if (ret)
+			break;
+	}
+	return ret;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_set_eeprom(struct net_device *netdev,
+ *                         struct ethtool_eeprom *eeprom, u8 *bytes)
+ * @brief   Write data to the device EEPROM
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   eeprom [INOUT] EEPROM get information structur
+ * @param   bytes  [IN] Pointer of write data
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_set_eeprom(struct net_device *netdev,
+		   struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	int ret;
+	u32 offset;
+	u8 i;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_eeprom");
+
+	if (eeprom->len == 0) {
+		IOH_GBE_ERR("EOPNOTSUPP\n");
+		return -EOPNOTSUPP;
+	}
+	if (eeprom->magic != (hw->vendor_id)) {
+		IOH_GBE_ERR("EFAULT\n");
+		IOH_GBE_TESTOUT("eeprom->magic : 0x%08x  magic : %0x\n",
+				eeprom->magic, (hw->vendor_id));
+		return -EFAULT;
+	}
+
+	for (i = 0, offset = eeprom->offset; i < (eeprom->len); i++, offset++) {
+		ret = ioh_gbe_hal_write_nvm(hw, offset, (bytes + i));
+		if (ret)
+			return ret;
+	}
+	return IOH_GBE_SUCCESS;
+}
+#endif
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_get_ringparam(struct net_device *netdev,
+ *                                            struct ethtool_ringparam *ring)
+ * @brief   Report ring sizes
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   ring   [OUT] Ring param structure
+ * @return  None
+ */
+static void
+ioh_gbe_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_tx_ring *txdr = adapter->tx_ring;
+	struct ioh_gbe_rx_ring *rxdr = adapter->rx_ring;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_ringparam");
+
+	ring->rx_max_pending = IOH_GBE_MAX_RXD;
+	ring->tx_max_pending = IOH_GBE_MAX_TXD;
+	ring->rx_mini_max_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_pending = rxdr->count;
+	ring->tx_pending = txdr->count;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_set_ringparam(struct net_device *netdev,
+ *                                           struct ethtool_ringparam *ring)
+ * @brief   Set ring sizes
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   ring   [IN] Ring param structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_tx_ring *txdr, *tx_old;
+	struct ioh_gbe_rx_ring *rxdr, *rx_old;
+	int tx_ring_size, rx_ring_size;
+	int err = IOH_GBE_SUCCESS;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_ringparam");
+
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+		return -EINVAL;
+	tx_ring_size = (int)sizeof(struct ioh_gbe_tx_ring);
+	rx_ring_size = (int)sizeof(struct ioh_gbe_rx_ring);
+
+	while ((test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags)) != 0)
+		msleep(1);
+	if ((netif_running(adapter->netdev)) != 0)
+		ioh_gbe_down(adapter);
+	tx_old = adapter->tx_ring;
+	rx_old = adapter->rx_ring;
+
+	txdr = kzalloc(tx_ring_size, GFP_KERNEL);
+	if (!txdr) {
+		err = -ENOMEM;
+		goto err_alloc_tx;
+	}
+	rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
+	if (!rxdr) {
+		err = -ENOMEM;
+		goto err_alloc_rx;
+	}
+	adapter->tx_ring = txdr;
+	adapter->rx_ring = rxdr;
+
+	rxdr->count = max(ring->rx_pending, (u32) IOH_GBE_MIN_RXD);
+	rxdr->count = min(rxdr->count, (u32) IOH_GBE_MAX_RXD);
+	IOH_GBE_ROUNDUP(rxdr->count, IOH_GBE_RX_DESC_MULTIPLE);
+
+	txdr->count = max(ring->tx_pending, (u32) IOH_GBE_MIN_TXD);
+	txdr->count = min(txdr->count, (u32) IOH_GBE_MAX_TXD);
+	IOH_GBE_ROUNDUP(txdr->count, IOH_GBE_TX_DESC_MULTIPLE);
+
+	if ((netif_running(adapter->netdev)) != 0) {
+		/* Try to get new resources before deleting old */
+		err = ioh_gbe_setup_rx_resources(adapter, adapter->rx_ring);
+		if (err != 0)
+			goto err_setup_rx;
+		err = ioh_gbe_setup_tx_resources(adapter, adapter->tx_ring);
+		if (err != 0)
+			goto err_setup_tx;
+		/* save the new, restore the old in order to free it,
+		 * then restore the new back again */
+		adapter->rx_ring = rx_old;
+		adapter->tx_ring = tx_old;
+		ioh_gbe_free_rx_resources(adapter, adapter->rx_ring);
+		ioh_gbe_free_tx_resources(adapter, adapter->tx_ring);
+		kfree(tx_old);
+		kfree(rx_old);
+		adapter->rx_ring = rxdr;
+		adapter->tx_ring = txdr;
+		err = ioh_gbe_up(adapter);
+	}
+
+	clear_bit(__IOH_GBE_RESETTING, &adapter->flags);
+	return err;
+
+err_setup_tx:
+	ioh_gbe_free_rx_resources(adapter, adapter->rx_ring);
+err_setup_rx:
+	adapter->rx_ring = rx_old;
+	adapter->tx_ring = tx_old;
+	kfree(rxdr);
+err_alloc_rx:
+	kfree(txdr);
+err_alloc_tx:
+	if (netif_running(adapter->netdev))
+		ioh_gbe_up(adapter);
+	clear_bit(__IOH_GBE_RESETTING, &adapter->flags);
+	return err;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_get_pauseparam(struct net_device *netdev,
+ *                                            struct ethtool_pauseparam *pause)
+ * @brief   Report pause parameters
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   pause  [OUT] Pause parameters structure
+ * @return  None
+ */
+static void
+ioh_gbe_get_pauseparam(struct net_device *netdev,
+		       struct ethtool_pauseparam *pause)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_pauseparam");
+
+	pause->autoneg =
+	    ((hw->mac.fc_autoneg != 0) ? AUTONEG_ENABLE : AUTONEG_DISABLE);
+
+	if (hw->mac.fc == ioh_gbe_fc_rx_pause) {
+		pause->rx_pause = 1;
+	} else if (hw->mac.fc == ioh_gbe_fc_tx_pause) {
+		pause->tx_pause = 1;
+	} else if (hw->mac.fc == ioh_gbe_fc_full) {
+		pause->rx_pause = 1;
+		pause->tx_pause = 1;
+	}
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_set_pauseparam(struct net_device *netdev,
+ *                                     struct ethtool_pauseparam *pause)
+ * @brief   Set pause paramters
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   pause  [IN] Pause parameters structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_set_pauseparam(struct net_device *netdev,
+		       struct ethtool_pauseparam *pause)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	int ret = IOH_GBE_SUCCESS;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_pauseparam");
+
+	hw->mac.fc_autoneg = pause->autoneg;
+
+	while ((test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags)) != 0)
+		msleep(1);
+	if ((pause->rx_pause) && (pause->tx_pause))
+		hw->mac.fc = ioh_gbe_fc_full;
+	else if ((pause->rx_pause) && (!pause->tx_pause))
+		hw->mac.fc = ioh_gbe_fc_rx_pause;
+	else if ((!pause->rx_pause) && (pause->tx_pause))
+		hw->mac.fc = ioh_gbe_fc_tx_pause;
+	else if ((!pause->rx_pause) && (!pause->tx_pause))
+		hw->mac.fc = ioh_gbe_fc_none;
+
+	if (hw->mac.fc_autoneg == AUTONEG_ENABLE) {
+		if ((netif_running(adapter->netdev)) != 0) {
+			ioh_gbe_down(adapter);
+			ret = ioh_gbe_up(adapter);
+		} else {
+			ioh_gbe_reset(adapter);
+		}
+	} else {
+		ret = ioh_gbe_hal_force_mac_fc(hw);
+	}
+	clear_bit(__IOH_GBE_RESETTING, &adapter->flags);
+	return ret;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static u32 ioh_gbe_get_rx_csum(struct net_device *netdev)
+ * @brief   Report whether receive checksums are turned on or off
+ * @param   netdev [INOUT] Network interface device structure
+ * @return  TRUE(1):  Checksum On
+ * @return  FALSE(0): Checksum Off
+ */
+static u32 ioh_gbe_get_rx_csum(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_rx_csum");
+
+	return adapter->rx_csum;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_set_rx_csum(struct net_device *netdev, u32 data)
+ * @brief   Turn receive checksum on or off
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   data   [IN] Checksum On[TRUE] or Off[FALSE]
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int ioh_gbe_set_rx_csum(struct net_device *netdev, u32 data)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_rx_csum");
+
+	adapter->rx_csum = data;
+	if ((netif_running(netdev)) != 0)
+		ioh_gbe_reinit_locked(adapter);
+	else
+		ioh_gbe_reset(adapter);
+
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static u32 ioh_gbe_get_tx_csum(struct net_device *netdev)
+ * @brief   Report whether transmit checksums are turned on or off
+ * @param   netdev [INOUT] Network interface device structure
+ * @return  TRUE(1):  Checksum On
+ * @return  FALSE(0): Checksum Off
+ */
+static u32 ioh_gbe_get_tx_csum(struct net_device *netdev)
+{
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_tx_csum");
+
+	return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_set_tx_csum(struct net_device *netdev, u32 data)
+ * @brief   Turn transmit checksums on or off
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   data   [IN] Checksum on[TRUE] or off[FALSE]
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int ioh_gbe_set_tx_csum(struct net_device *netdev, u32 data)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_tx_csum");
+
+	adapter->tx_csum = data;
+
+	if (data != 0)
+		netdev->features |= NETIF_F_HW_CSUM;
+	else
+		netdev->features &= ~NETIF_F_HW_CSUM;
+
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_diag_test(struct net_device *netdev,
+ *                         struct ethtool_test *eth_test, u64 *data)
+ * @brief   Run specified self-tests
+ * @param   netdev   [IN] Network interface device structure
+ * @param   eth_test [IN] Ethtool test structure
+ * @param   data     [OUT] Data for test result.
+ * @return  None
+ */
+static void
+ioh_gbe_diag_test(struct net_device *netdev,
+		  struct ethtool_test *eth_test, u64 *data)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	unsigned char if_running = netif_running(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_diag_test");
+
+	set_bit(__IOH_GBE_TESTING, &adapter->flags);
+
+	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+		/* Offline tests */
+		DPRINTK(HW, INFO, "offline testing starting\n");
+
+		if (if_running) {
+			/* indicate we're in test mode */
+			dev_close(netdev);
+		} else {
+			ioh_gbe_reset(adapter);
+		}
+		/* Register test */
+		if (ioh_gbe_reg_test(adapter, &data[0]))
+			eth_test->flags |= ETH_TEST_FL_FAILED;
+
+		ioh_gbe_reset(adapter);
+		clear_bit(__IOH_GBE_TESTING, &adapter->flags);
+		if (if_running)
+			dev_open(netdev);
+
+	} else {
+		/* Online tests */
+		DPRINTK(HW, INFO, "online testing starting\n");
+		data[0] = 0;
+		clear_bit(__IOH_GBE_TESTING, &adapter->flags);
+	}
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_get_strings(struct net_device *netdev,
+ *                                             u32 stringset, u8 *data)
+ * @brief   Return a set of strings that describe the requested objects
+ * @param   netdev    [INOUT] Network interface device structure
+ * @param   stringset [IN] Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]
+ * @param   data      [OUT]Pointer of read string data.
+ * @return  None
+ */
+static void
+ioh_gbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
+{
+	u8 *p = data;
+	int i;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_strings");
+
+	switch (stringset) {
+	case (u32) ETH_SS_TEST:
+		memcpy(data, *ioh_gbe_gstrings_test,
+		       (int)sizeof(ioh_gbe_gstrings_test));
+		break;
+	case (u32) ETH_SS_STATS:
+		for (i = 0; i < IOH_GBE_GLOBAL_STATS_LEN; i++) {
+			memcpy(p, ioh_gbe_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+		break;
+	}
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_led_blink_callback(unsigned long data)
+ * @brief   Callback function for blink led
+ * @param   data [IN] Pointer Address of Board private structure
+ * @return  None
+ */
+static void ioh_gbe_led_blink_callback(unsigned long data)
+{
+	struct ioh_gbe_adapter *adapter = (struct ioh_gbe_adapter *)data;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_led_blink_callback");
+
+	if ((test_and_change_bit(IOH_GBE_LED_ON, &adapter->led_status)) != 0)
+		ioh_gbe_hal_led_off(&adapter->hw);
+	else
+		ioh_gbe_hal_led_on(&adapter->hw);
+	mod_timer(&adapter->blink_timer, jiffies + IOH_GBE_ID_INTERVAL);
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static int ioh_gbe_phys_id(struct net_device *netdev, u32 data)
+ * @brief   Identify the device
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   data   [IN] Sleep time[ms]
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int ioh_gbe_phys_id(struct net_device *netdev, u32 data)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_phys_id");
+
+	if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))
+		data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ);
+	if (!adapter->blink_timer.function) {
+		init_timer(&adapter->blink_timer);
+		adapter->blink_timer.function = ioh_gbe_led_blink_callback;
+		adapter->blink_timer.data = (unsigned long)adapter;
+	}
+	ioh_gbe_hal_setup_led(&adapter->hw);
+	mod_timer(&adapter->blink_timer, jiffies);
+	msleep_interruptible(data * 1000);
+	del_timer_sync(&adapter->blink_timer);
+
+	ioh_gbe_hal_led_off(&adapter->hw);
+	clear_bit(IOH_GBE_LED_ON, &adapter->led_status);
+	ioh_gbe_hal_cleanup_led(&adapter->hw);
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Ethtool driver
+ * @fn      static void ioh_gbe_get_ethtool_stats(struct net_device *netdev,
+ *                                   struct ethtool_stats *stats, u64 *data)
+ * @brief   Return statistics about the device
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   stats  [INOUT] Ethtool statue structure
+ * @param   data   [OUT] Pointer of read status area
+ * @return  None
+ */
+static void
+ioh_gbe_get_ethtool_stats(struct net_device *netdev,
+			  struct ethtool_stats *stats, u64 *data)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_get_ethtool_stats");
+
+	ioh_gbe_update_stats(adapter);
+	for (i = 0; i < IOH_GBE_GLOBAL_STATS_LEN; i++) {
+		signed char *p =
+			(signed char *)adapter +
+			ioh_gbe_gstrings_stats[i].stat_offset;
+		data[i] =
+			(ioh_gbe_gstrings_stats[i].sizeof_stat ==
+			(int)sizeof(u64)) ? *(u64 *) p:(*(u32 *) p);
+	}
+}
+
+/*!
+ * @ingroup Ethtool driver Layer
+ * @struct  ioh_gbe_ethtool_ops
+ * @brief   Store the pointers of ethtool interfaces to kernel
+ */
+static struct ethtool_ops ioh_gbe_ethtool_ops = {
+	.get_settings = ioh_gbe_get_settings,
+	.set_settings = ioh_gbe_set_settings,
+	.get_drvinfo = ioh_gbe_get_drvinfo,
+	.get_regs_len = ioh_gbe_get_regs_len,
+	.get_regs = ioh_gbe_get_regs,
+	.get_wol = ioh_gbe_get_wol,
+	.set_wol = ioh_gbe_set_wol,
+	.get_msglevel = ioh_gbe_get_msglevel,
+	.set_msglevel = ioh_gbe_set_msglevel,
+	.nway_reset = ioh_gbe_nway_reset,
+	.get_link = ethtool_op_get_link,
+#ifdef CONFIG_PCH_PCIEQOS
+	.get_eeprom_len = ioh_gbe_get_eeprom_len,
+	.get_eeprom = ioh_gbe_get_eeprom,
+	.set_eeprom = ioh_gbe_set_eeprom,
+#endif
+	.get_ringparam = ioh_gbe_get_ringparam,
+	.set_ringparam = ioh_gbe_set_ringparam,
+	.get_pauseparam = ioh_gbe_get_pauseparam,
+	.set_pauseparam = ioh_gbe_set_pauseparam,
+	.get_rx_csum = ioh_gbe_get_rx_csum,
+	.set_rx_csum = ioh_gbe_set_rx_csum,
+	.get_tx_csum = ioh_gbe_get_tx_csum,
+	.set_tx_csum = ioh_gbe_set_tx_csum,
+	.self_test = ioh_gbe_diag_test,
+	.get_strings = ioh_gbe_get_strings,
+	.phys_id = ioh_gbe_phys_id,
+	.get_ethtool_stats = ioh_gbe_get_ethtool_stats,
+};
+
+/*!
+ * @ingroup Ethtool driver internal functions
+ * @fn      void ioh_gbe_set_ethtool_ops(struct net_device *netdev)
+ * @brief   Set the Ethtool to network device data
+ * @param   netdev [INOUT] Network interface device structure
+ * @return  None
+ */
+void ioh_gbe_set_ethtool_ops(struct net_device *netdev)
+{
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_set_ethtool_ops");
+
+	SET_ETHTOOL_OPS(netdev, &ioh_gbe_ethtool_ops);
+}
+
+#define IOH_GBE_REG_PATTERN_TEST(reg, mask, write) \
+	do { \
+		if (reg_pattern_test(adapter, data, \
+			IOH_GBE_##reg, mask, write)) \
+			return 1; \
+	} while (0)
+
+/*!
+ * @ingroup Ethtool driver internal functions
+ * @fn      static int ioh_gbe_reg_test(struct ioh_gbe_adapter *adapter, uint64_t *data)
+ * @brief   Register test
+ * @param   adapter  [IN] Board private structure
+ * @param   data     [INOUT] Pointer to test result data
+ * @return  IOH_GBE_SUCCESS
+ */
+static int ioh_gbe_reg_test(struct ioh_gbe_adapter *adapter, uint64_t *data)
+{
+	IOH_GBE_DBGFUNC("ethtool: ioh_gbe_reg_test");
+
+	ioh_gbe_reset(adapter);
+	IOH_GBE_REG_PATTERN_TEST(INT_EN, 0x11111F3F, 0x11111F3F);
+	IOH_GBE_REG_PATTERN_TEST(MODE, 0xC2000000, 0xC2000000);
+	IOH_GBE_REG_PATTERN_TEST(TCPIP_ACC, 0x0000000F, 0x0000000F);
+	IOH_GBE_REG_PATTERN_TEST(EX_LIST, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(PHY_INT_CTRL, 0x00010003, 0x00010003);
+	IOH_GBE_REG_PATTERN_TEST(MAC_RX_EN, 0x00000001, 0x00000001);
+	IOH_GBE_REG_PATTERN_TEST(RX_FCTRL, 0x80000000, 0x80000000);
+	IOH_GBE_REG_PATTERN_TEST(PAUSE_REQ, 0x80000000, 0x80000000);
+	IOH_GBE_REG_PATTERN_TEST(RX_MODE, 0xC000FE00, 0xC000FE00);
+	IOH_GBE_REG_PATTERN_TEST(TX_MODE, 0xF800FE00, 0xF800FE00);
+	IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT1, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT2, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT3, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT4, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(PAUSE_PKT5, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR1A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR1B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR2A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR2B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR3A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR3B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR4A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR4B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR5A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR5B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR6A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR6B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR7A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR7B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR8A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR8B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR9A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR9B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR10A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR10B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR11A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR11B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR12A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR12B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR13A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR13B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR14A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR14B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR15A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR15B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR16A, 0xFFFFFFFF, 0xFFFFFFFF);
+	IOH_GBE_REG_PATTERN_TEST(MAC_ADR16B, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(ADDR_MASK, 0x0000FFFF, 0x0000FFFF);
+	IOH_GBE_REG_PATTERN_TEST(RGMII_CTRL, 0x0000001F, 0x0000001F);
+	IOH_GBE_REG_PATTERN_TEST(DMA_CTRL, 0x00000003, 0x00000003);
+	IOH_GBE_REG_PATTERN_TEST(RX_DSC_BASE, 0xFFFFFFF0, 0xFFFFFFF0);
+	IOH_GBE_REG_PATTERN_TEST(RX_DSC_SIZE, 0x0000FFF0, 0x0000FFF0);
+	IOH_GBE_REG_PATTERN_TEST(RX_DSC_HW_P, 0xFFFFFFF0, 0xFFFFFFF0);
+	IOH_GBE_REG_PATTERN_TEST(RX_DSC_SW_P, 0xFFFFFFF0, 0xFFFFFFF0);
+	IOH_GBE_REG_PATTERN_TEST(TX_DSC_BASE, 0xFFFFFFF0, 0xFFFFFFF0);
+	IOH_GBE_REG_PATTERN_TEST(TX_DSC_SIZE, 0x0000FFF0, 0x0000FFF0);
+	IOH_GBE_REG_PATTERN_TEST(TX_DSC_HW_P, 0xFFFFFFF0, 0xFFFFFFF0);
+	IOH_GBE_REG_PATTERN_TEST(TX_DSC_SW_P, 0xFFFFFFF0, 0xFFFFFFF0);
+	IOH_GBE_REG_PATTERN_TEST(WOL_ST, 0x0000000F, 0x0000000F);
+	IOH_GBE_REG_PATTERN_TEST(WOL_CTRL, 0x0001017F, 0x0001017F);
+	IOH_GBE_REG_PATTERN_TEST(WOL_ADDR_MASK, 0x0000FFFF, 0x0000FFFF);
+
+	*data = 0;
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Ethtool driver internal functions
+ * @fn      static bool reg_pattern_test(struct ioh_gbe_adapter *adapter,
+ *                                       uint64_t *data,   int reg,
+ *                                       uint32_t mask,    uint32_t write)
+ * @brief   Register pattern test
+ * @param   adapter  [IN] Board private structure
+ * @param   data     [INOUT] Pointer to test result data
+ * @param   reg      [INOUT] Register address
+ * @param   mask     [INOUT] Mask pattern
+ * @param   write    [INOUT] Write data
+ * @return  true     : Successfully
+ * @return  false    : Failed
+ */
+static bool
+reg_pattern_test(struct ioh_gbe_adapter *adapter,
+		 uint64_t *data, int reg, uint32_t mask, uint32_t write)
+{
+	static const uint32_t test[] = {
+		0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
+	};
+	uint8_t __iomem *address = adapter->hw.hw_addr + reg;
+	uint32_t read;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(test); i++) {
+		writel(write & test[i], address);
+		read = (readl(address) & mask);
+		if (read != (write & test[i] & mask)) {
+			DPRINTK(DRV, ERR, "pattern test reg %04X failed: "
+				"got 0x%08X expected 0x%08X\n",
+				reg, read, (write & test[i] & mask));
+			*data = reg;
+			return true;
+		}
+	}
+	return false;
+}
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe.h	2010-03-09 09:27:26.000000000 +0900
@@ -0,0 +1,230 @@
+/*!
+ * @file ioh_gbe.h
+ * @brief Linux IOH Gigabit Ethernet Driver main header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+
+#ifndef _IOH_GBE_H_
+#define _IOH_GBE_H_
+
+struct ioh_gbe_adapter;
+
+#define PFX "ioh_gbe: "
+#define DPRINTK(nlevel, klevel, fmt, args...) \
+	do { \
+		if (printk_ratelimit()) \
+			(void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
+			printk(KERN_##klevel PFX "%s: %s: " fmt, \
+			adapter->netdev->name, __func__ , ## args)); \
+	} while (0)
+
+/* only works for sizes that are powers of 2 */
+#define IOH_GBE_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_buffer
+ * @brief   Buffer infomation
+ * @remarks
+ *  wrapper around a pointer to a socket buffer,
+ *  so a DMA handle can be stored along with the buffer
+ */
+struct ioh_gbe_buffer {
+	struct sk_buff *skb;	    /**< pointer to a socket buffer  */
+	struct sk_buff *kernel_skb;
+		/**< pointer to a socket buffer received from the kernel */
+	dma_addr_t dma;		    /**< DMA address  */
+	unsigned long time_stamp;   /**< time stamp  */
+	u16 length;		    /**< data size  */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_tx_ring
+ * @brief   tx ring infomation
+ */
+struct ioh_gbe_tx_ring {
+	void *desc;		/**< pointer to the descriptor ring memory  */
+	dma_addr_t dma;		/**< physical address of the descriptor ring  */
+	unsigned int size;	/**< length of descriptor ring in bytes  */
+	unsigned int count;	/**< number of descriptors in the ring  */
+	unsigned int next_to_use;
+			/**< next descriptor to associate a buffer with  */
+	unsigned int next_to_clean;
+			/**< next descriptor to check for DD status bit  */
+	struct ioh_gbe_buffer *buffer_info;
+			/**< array of buffer information structs  */
+	spinlock_t tx_lock;	/**< spinlock structs  */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_rx_ring
+ * @brief   rx ring infomation
+ */
+struct ioh_gbe_rx_ring {
+	void *desc;		/**< pointer to the descriptor ring memory  */
+	dma_addr_t dma;		/**< physical address of the descriptor ring  */
+	unsigned int size;	/**< length of descriptor ring in bytes  */
+	unsigned int count;	/**< number of descriptors in the ring  */
+	unsigned int next_to_use;
+			/**< next descriptor to associate a buffer with  */
+	unsigned int next_to_clean;
+			/**< next descriptor to check for DD status bit  */
+	struct ioh_gbe_buffer *buffer_info;
+			/**< array of buffer information structs  */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_hw_stats
+ * @brief   Statistics counters collected by the MAC
+ */
+struct ioh_gbe_hw_stats {
+	u64 rx_packets;		    /**< total packets received  */
+	u64 tx_packets;		    /**< total packets transmitted  */
+	u64 rx_bytes;		    /**< total bytes received  */
+	u64 tx_bytes;		    /**< total bytes transmitted  */
+	u64 rx_errors;		    /**< bad packets received  */
+	u64 tx_errors;		    /**< packet transmit problems  */
+	u64 rx_dropped;		    /**< no space in Linux buffers  */
+	u64 tx_dropped;		    /**< no space available in Linux  */
+	u64 multicast;		    /**< multicast packets received  */
+	u64 collisions;		    /**< collisions */
+	u64 rx_crc_errors;	    /**< received packet with crc error  */
+	u64 rx_frame_errors;	    /**< received frame alignment error  */
+	u64 rx_alloc_buff_failed;   /**< allocate failure of a receive buffer */
+	u64 tx_length_errors;	    /**< transmit length error  */
+	u64 tx_aborted_errors;	    /**< transmit aborted error  */
+	u64 tx_carrier_errors;	    /**< transmit carrier error  */
+	u64 tx_timeout_count;	    /**< Number of transmit timeout  */
+	u64 tx_restart_count;	    /**< Number of transmit restert  */
+	u64 intr_rx_dsc_empty_count;
+			/**< Interrupt count of receive descriptor empty  */
+	u64 intr_rx_frame_err_count;
+			/**< Interrupt count of receive frame error  */
+	u64 intr_rx_fifo_err_count;
+			/**< Interrupt count of receive FIFO error  */
+	u64 intr_rx_dma_err_count;
+			/**< Interrupt count of receive DMA error  */
+	u64 intr_tx_fifo_err_count;
+			/**< Interrupt count of transmit FIFO error  */
+	u64 intr_tx_dma_err_count;
+			/**< Interrupt count of transmit DMA error  */
+	u64 intr_tcpip_err_count;
+			/**< Interrupt count of TCP/IP Accelerator  */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_adapter
+ * @brief   board specific private data structure
+ */
+struct ioh_gbe_adapter {
+	/* OS defined structs */
+	struct net_device *netdev;  /**<  Pointer of network device structure */
+	struct pci_dev *pdev;	    /**<  Pointer of pci device structure */
+	struct net_device_stats net_stats; /**<  Network status */
+	struct net_device *polling_netdev;
+			/**<  Pointer of polling network device structure */
+	struct napi_struct napi;	/**<  NAPI structure */
+
+	/* structs defined in ioh_gbe_hw.h */
+	struct ioh_gbe_hw hw;		/**<  Pointer of hardware structure */
+	struct ioh_gbe_hw_stats stats;	/**<  Hardware status */
+	struct work_struct reset_task;	/**<  Reset task */
+	struct mii_if_info mii;		/**<  MII information structure */
+	struct timer_list watchdog_timer;	/**<  Watchdog timer list */
+
+	u32 bd_number;		/**<  The number of the found NIC cards */
+	u32 wake_up_evt;	/**<  Wake up event */
+	u32 *config_space;	/**<  Configuration space */
+	int msg_enable;		/**<  Driver message level */
+
+	spinlock_t stats_lock;	    /**<  Spinlock structure for status */
+	spinlock_t tx_queue_lock;   /**<  Spinlock structure for transmit */
+	spinlock_t int_en_lock;	    /**<  Spinlock structure for IRQ enable */
+	atomic_t irq_sem;	    /**<  Semaphore for interrupt */
+
+	struct timer_list blink_timer;	/**<  LED blink timer list */
+	unsigned long led_status;	/**<  LED status */
+
+	/* TX,RX */
+	struct ioh_gbe_tx_ring *tx_ring;
+		/**<  Pointer of Tx descriptor ring structure  */
+	struct ioh_gbe_rx_ring *rx_ring;
+		/**<  Pointer of Rx descriptor ring structure */
+	unsigned long rx_buffer_len;	/**<  Receive buffer length */
+	unsigned long tx_queue_len;	/**<  Transmit queue length */
+
+	unsigned char rx_csum;
+		/**<  Receive TCP/IP checksum enable/disable */
+	unsigned char tx_csum;
+		/**<  Transmit TCP/IP checksum enable/disable */
+
+	unsigned char have_msi;		/**<  PCI MSI mode flag */
+
+	/* to not mess up cache alignment, always add to the bottom */
+	unsigned long flags;		/**<  Driver status flag */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @def  ioh_gbe_state_t
+ * @brief   Driver Status
+ */
+enum ioh_gbe_state_t {
+	__IOH_GBE_TESTING,	   /**<  Testing  */
+	__IOH_GBE_RESETTING,	   /**<  Reseting */
+};
+
+/* pch_gbe_main.c */
+int ioh_gbe_up(struct ioh_gbe_adapter *adapter);
+void ioh_gbe_down(struct ioh_gbe_adapter *adapter);
+void ioh_gbe_reinit_locked(struct ioh_gbe_adapter *adapter);
+void ioh_gbe_reset(struct ioh_gbe_adapter *adapter);
+int ioh_gbe_setup_tx_resources(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_tx_ring *txdr);
+int ioh_gbe_setup_rx_resources(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_rx_ring *rxdr);
+void ioh_gbe_free_tx_resources(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_tx_ring *tx_ring);
+void ioh_gbe_free_rx_resources(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_rx_ring *rx_ring);
+void ioh_gbe_update_stats(struct ioh_gbe_adapter *adapter);
+int ioh_gbe_mdio_read(struct net_device *netdev, int addr, int reg);
+void ioh_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data);
+/* ioh_gbe_param.c */
+void ioh_gbe_check_options(struct ioh_gbe_adapter *adapter);
+
+/* ioh_gbe_ethtool.c */
+void ioh_gbe_set_ethtool_ops(struct net_device *netdev);
+
+
+#endif /* _IOH_GBE_H_ */
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_hw.h	2010-03-11 15:11:49.000000000 +0900
@@ -0,0 +1,259 @@
+/*!
+ * @file ioh_gbe_hw.h
+ * @brief Linux IOH Gigabit Ethernet Driver Hardware layer header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_HW_H_
+#define _IOH_GBE_HW_H_
+
+struct ioh_gbe_hw;
+
+/* mac type values */
+#define IOH_GBE_MAC_TYPE_UNDEFINED	0
+#define IOH_GBE_MAC_TYPE_IOH1		1
+#define IOH_GBE_MAC_TYPE_IOH2		2
+
+/* bus type values */
+#define ioh_gbe_bus_type_unknown	0
+#define ioh_gbe_bus_type_pci		1
+#define ioh_gbe_bus_type_pcix		2
+#define ioh_gbe_bus_type_pci_express	3
+#define ioh_gbe_bus_type_reserved	4
+
+/* bus speed values */
+#define ioh_gbe_bus_speed_unknown	0
+#define ioh_gbe_bus_speed_33		1
+#define ioh_gbe_bus_speed_66		2
+#define ioh_gbe_bus_speed_100		3
+#define ioh_gbe_bus_speed_120		4
+#define ioh_gbe_bus_speed_133		5
+#define ioh_gbe_bus_speed_2500		6
+#define ioh_gbe_bus_speed_reserved	7
+
+/* bus width values */
+#define ioh_gbe_bus_width_unknown	0
+#define ioh_gbe_bus_width_pcie_x1	1
+#define ioh_gbe_bus_width_pcie_x2	2
+#define ioh_gbe_bus_width_pcie_x4	4
+#define ioh_gbe_bus_width_32		5
+#define ioh_gbe_bus_width_64		6
+#define ioh_gbe_bus_width_reserved	7
+
+/* flow control values */
+#define ioh_gbe_fc_none			0
+#define ioh_gbe_fc_rx_pause		1
+#define ioh_gbe_fc_tx_pause		2
+#define ioh_gbe_fc_full			3
+
+#define IOH_GBE_FC_DEFAULT  ioh_gbe_fc_full
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_rx_desc
+ * @brief   Receive Descriptor
+ */
+struct ioh_gbe_rx_desc {
+	u32 buffer_addr;	/** RX Frame Buffer Address */
+	u32 tcp_ip_status;	/** TCP/IP Accelerator Status */
+	u16 rx_words_eob;	/** RX word count and Byte position */
+	u16 gbec_status;	/** GMAC Status */
+	u8 dma_status;		/** DMA Status */
+	u8 reserved1;		/** Reserved */
+	u16 reserved2;		/** Reserved */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_tx_desc
+ * @brief   Transmit Descriptor
+ */
+struct ioh_gbe_tx_desc {
+	u32 buffer_addr;	/** TX Frame Buffer Address */
+	u16 length;		/** Data buffer length */
+	u16 reserved1;		/** Reserved */
+	u16 tx_words_eob;	/** TX word count and Byte position */
+	u16 tx_frame_ctrl;	/** TX Frame Control */
+	u8 dma_status;		/** DMA Status */
+	u8 reserved2;		/** Reserved */
+	u16 gbec_status;	/** GMAC Status */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_functions
+ * @brief   HAL APi function pointer
+ */
+struct ioh_gbe_functions {
+	/* Function pointers for the MAC. */
+	s32(*cleanup_led) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_cleanup_led */
+
+	void (*get_bus_info) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_get_bus_info */
+
+	s32(*led_on) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_led_on */
+
+	s32(*led_off) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_led_off */
+
+	void (*mc_addr_list_update) (struct ioh_gbe_hw *, u8 *, u32, u32, u32);
+		/** for ioh_gbe_hal_mc_addr_list_update */
+
+	void (*reset_hw) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_reset_hw */
+
+	s32(*init_hw) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_init_hw */
+
+	s32(*setup_link) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_setup_link */
+
+	s32(*setup_physical_interface) (struct ioh_gbe_hw *);
+		/** for setup link of PHY */
+
+	s32(*setup_led) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_setup_led */
+
+	void (*pause_packet) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_set_pause_packet */
+
+	/* Function pointers for the PHY. */
+	s32(*read_phy_reg) (struct ioh_gbe_hw *, u32, u16 *);
+		/** for ioh_gbe_hal_read_phy_reg */
+
+	s32(*write_phy_reg) (struct ioh_gbe_hw *, u32, u16);
+		/** for ioh_gbe_hal_write_phy_reg */
+
+	void (*reset_phy) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_phy_hw_reset */
+
+	void (*sw_reset_phy) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_phy_sw_reset */
+
+	void (*power_up_phy) (struct ioh_gbe_hw *hw);
+		/** for ioh_gbe_hal_power_up_phy */
+
+	void (*power_down_phy) (struct ioh_gbe_hw *hw);
+		/** for ioh_gbe_hal_power_down_phy */
+#ifdef CONFIG_PCH_PCIEQOS
+	/* Function pointers for the NVM. */
+	s32(*validate_nvm) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_validate_nvm_checksum */
+
+	s32(*read_nvm) (struct ioh_gbe_hw *, u32, u8 *);
+		/** for ioh_gbe_hal_read_nvm */
+
+	s32(*write_nvm) (struct ioh_gbe_hw *, u32, u8 *);
+		/** for ioh_gbe_hal_write_nvm */
+#endif
+	s32(*read_mac_addr) (struct ioh_gbe_hw *);
+		/** for ioh_gbe_hal_read_mac_addr */
+
+	u16(*ctrl_miim) (struct ioh_gbe_hw *, u32, u32, u32, u16);
+		/** for ioh_gbe_hal_ctrl_miim */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_mac_info
+ * @brief   MAC infomation
+ */
+struct ioh_gbe_mac_info {
+	u8 addr[6];		/** Store the MAC address */
+	u8 type;		/** Type of MAC */
+	u8 fc;			/** Mode of flow control */
+	u8 fc_autoneg;   /** Auto negotiation enable for flow control setting */
+	u8 tx_fc_enable;	/** Enable flag of Transmit flow control */
+	u32 max_frame_size;	/** Max transmit frame size */
+	u32 min_frame_size;	/** Min transmit frame size */
+	u16 mar_entry_count;	/** Entry count of MAC address registers */
+	u8 autoneg;	/** Auto negotiation enable */
+	u16 link_speed;		/** Link speed */
+	u16 link_duplex;	/** Link duplex */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_phy_info
+ * @brief   PHY infomation
+ */
+struct ioh_gbe_phy_info {
+	u32 addr;		/** PHY address */
+	u32 id;			/** PHY's identifier */
+	u32 revision;		/** PHY's revision */
+	u32 reset_delay_us;	/** HW reset delay time[us] */
+	u16 autoneg_advertised;	/** Autoneg advertised */
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_nvm_info
+ * @brief   NVM infomation
+ */
+struct ioh_gbe_nvm_info {
+	u16 word_size;
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_bus_info
+ * @brief   Bus infomation
+ */
+struct ioh_gbe_bus_info {
+	u8 type;
+	u8 speed;
+	u8 width;
+};
+
+/*!
+ * @ingroup Gigabit Ether driver Layer
+ * @struct  ioh_gbe_hw
+ * @brief   Hardware infomation
+ */
+struct ioh_gbe_hw {
+	void *back;
+
+	u8 *hw_addr;
+	spinlock_t miim_lock;
+
+	struct ioh_gbe_functions func;
+	struct ioh_gbe_mac_info mac;
+	struct ioh_gbe_phy_info phy;
+	struct ioh_gbe_nvm_info nvm;
+	struct ioh_gbe_bus_info bus;
+
+	u16 vendor_id;
+	u16 device_id;
+	u16 subsystem_vendor_id;
+	u16 subsystem_device_id;
+	u8 revision_id;
+};
+
+#endif
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.c	2010-03-11 15:11:58.000000000 +0900
@@ -0,0 +1,522 @@
+/*!
+ * @file ioh_gbe_mac.c
+ * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (MAC) source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#include <linux/ethtool.h>
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_regs.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_mac.h"
+#include "pch_gbe_api.h"
+
+/* Pause packet value */
+#define	IOH_GBE_PAUSE_PKT1_VALUE    0x00C28001
+#define	IOH_GBE_PAUSE_PKT2_VALUE    0x00000100
+#define	IOH_GBE_PAUSE_PKT4_VALUE    0x01000888
+#define	IOH_GBE_PAUSE_PKT5_VALUE    0x0000FFFF
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw)
+ * @brief   Reset hardware
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ * @remarks
+ *  This resets the hardware into a known state (Reset only MAC).
+ *  This is a function pointer entry point called by the api module.
+ */
+void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw)
+{
+	u32 tmp = 0;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_reset_hw");
+
+#ifndef CONFIG_PCH_PCIEQOS
+	/* Read the MAC address. and store to the private data */
+	ioh_gbe_mac_read_mac_addr(hw);
+#endif
+
+	IOH_GBE_WRITE_REG(hw, RESET, IOH_GBE_ALL_RST);
+#ifdef IOH_GBE_MAC_IFOP_RGMII
+	IOH_GBE_WRITE_REG(hw, MODE, IOH_GBE_MODE_GMII_ETHER);
+#endif
+	while ((IOH_GBE_READ_REG(hw, RESET)) != 0) {
+		udelay(1);
+		tmp++;
+		if (tmp == 5) {
+			IOH_GBE_ERR("MAC HW RESET\n");
+			break;
+		}
+	}
+#ifndef CONFIG_PCH_PCIEQOS
+	/* Setup the receive address */
+	ioh_gbe_mac_mar_set(hw, hw->mac.addr, 0);
+#endif
+	return;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw,
+ *                                         u16 mar_count)
+ * @brief   Initialize receive address's
+ * @param   hw        [INOUT] Pointer to the HW structure
+ * @param   mar_count [IN] Receive address registers
+ * @return  None
+ * @remarks
+ *  Setups the receive address registers by setting the base receive address
+ *  register to the devices MAC address and clearing all the other receive
+ *  address registers to 0.
+ *  This is a function pointer entry point called by the api module.
+ */
+void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw, u16 mar_count)
+{
+	u32 i;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_init_rx_addrs");
+	IOH_GBE_DBGOUT("Programming MAC Address into MAC_ADDR[0]\n");
+	IOH_GBE_TESTOUT("Clearing MAC_ADDR[1-%u]\n", mar_count - 1);
+
+	/* Setup the receive address */
+	ioh_gbe_hal_mar_set(hw, hw->mac.addr, 0);
+
+	/* Zero out the other (mar_entry_count - 1) receive addresses */
+	for (i = 1; i < mar_count; i++) {
+		IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, (i << 1), 0);
+		IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, ((i << 1) + 1), 0);
+	}
+	IOH_GBE_WRITE_REG(hw, ADDR_MASK, 0xFFFE);
+	/* wait busy */
+	while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY) != 0)
+		;
+#ifdef DEBUG_TEST
+	{
+		unsigned char ti;
+		IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit) : 0x%08x\n",
+				IOH_GBE_READ_REG(hw, ADDR_MASK));
+		for (ti = 0; ti < 16; ti++) {
+			IOH_GBE_TESTOUT("MAC_ADR%dAB reg : 0x%08x 0x%08x\n",
+					(ti + 1),
+					IOH_GBE_READ_REG(hw,
+							 MAC_ADR1A +
+							 (0x08 * ti)),
+					IOH_GBE_READ_REG(hw,
+							 MAC_ADR1B +
+							 (0x08 * ti)));
+		}
+	}
+#endif
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index)
+ * @brief   Set MAC address register
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   addr   [IN] Pointer to the MAC address
+ * @param   index  [IN] MAC address array register
+ * @return  None
+ */
+void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 * addr, u32 index)
+{
+	u32 mar_low, mar_high, adrmask;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_mar_set");
+	IOH_GBE_TESTOUT("index : 0x%x\n", index);
+
+	/* HW expects these in little endian so we reverse the byte order
+	 * from network order (big endian) to little endian
+	 */
+	mar_low = ((u32) addr[0] |
+		   ((u32) addr[1] << 8) |
+		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
+
+	mar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+	/* Stop the MAC Address of index. */
+	adrmask = IOH_GBE_READ_REG(hw, ADDR_MASK);
+	IOH_GBE_WRITE_REG(hw, ADDR_MASK, (adrmask | (0x0001 << index)));
+
+	IOH_GBE_TESTOUT("ADDR_MASK reg : 0x%08x\n", adrmask);
+	IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit) : 0x%08x\n",
+			IOH_GBE_READ_REG(hw, ADDR_MASK));
+	/* wait busy */
+	while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY) != 0)
+		;
+	IOH_GBE_TESTOUT("ADDR_MASK reg(check BUSY bit:1) : 0x%08x\n",
+			IOH_GBE_READ_REG(hw, ADDR_MASK));
+
+	/* Set the MAC address to the MAC address 1A/1B register */
+	IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, (index << 1), mar_low);
+	IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, ((index << 1) + 1), mar_high);
+	/* Start the MAC address of index */
+	IOH_GBE_WRITE_REG(hw, ADDR_MASK, (adrmask & ~(0x0001 << index)));
+	IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit:0) : 0x%08x\n",
+			IOH_GBE_READ_REG(hw, ADDR_MASK));
+	/* wait busy */
+	while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY) != 0)
+		;
+	IOH_GBE_TESTOUT("ADDR_MASK reg(check BUSY bit) : 0x%08x\n",
+			IOH_GBE_READ_REG(hw, ADDR_MASK));
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_mar_set:End");
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw,
+ *                               u8 *mc_addr_list,   u32 mc_addr_count,
+ *                               u32 mar_used_count, u32 mar_total_num)
+ * @brief   Update Multicast addresses
+ * @param   hw             [INOUT] Pointer to the HW structure
+ * @param   mc_addr_list   [IN] Array of multicast addresses to program
+ * @param   mc_addr_count  [IN] Number of multicast addresses to program
+ * @param   mar_used_count [IN] The first MAC Address register free to program
+ * @param   mar_total_num  [IN] Total number of supported MAC Address Registers
+ * @return  None
+ */
+void
+ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw,
+				u8 *mc_addr_list, u32 mc_addr_count,
+				u32 mar_used_count, u32 mar_total_num)
+{
+	u32 i, adrmask;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_mc_addr_list_update");
+
+#ifdef DEBUG_TEST
+	{
+		u32 ti, tj;
+		IOH_GBE_TESTOUT
+		    ("mc_addr_count = %d  mar_used_count = %d  "
+		     "mar_total_num = %d\n",
+		     mc_addr_count, mar_used_count, mar_total_num);
+		for (ti = 0; ti < mc_addr_count; ti++) {
+			tj = ti * IOH_GBE_ETH_ALEN;
+			IOH_GBE_TESTOUT
+			    ("mc_addr_list[%d] = 0x%02x %02x %02x "
+			     "%02x %02x %02x \n",
+			     ti, mc_addr_list[tj], mc_addr_list[tj + 1],
+			     mc_addr_list[tj + 2], mc_addr_list[tj + 3],
+			     mc_addr_list[tj + 4], mc_addr_list[tj + 5]);
+		}
+	}
+#endif
+	/* Load the first set of multicast addresses into the exact
+	 * filters (RAR).  If there are not enough to fill the RAR
+	 * array, clear the filters.
+	 */
+	for (i = mar_used_count; i < mar_total_num; i++) {
+		if (mc_addr_count != 0) {
+			ioh_gbe_mac_mar_set(hw, mc_addr_list, i);
+			mc_addr_count--;
+			mc_addr_list += IOH_GBE_ETH_ALEN;
+		} else {
+			/* Clear MAC address mask */
+			adrmask = IOH_GBE_READ_REG(hw, ADDR_MASK);
+			IOH_GBE_WRITE_REG(hw, ADDR_MASK,
+					  (adrmask | (0x0001 << i)));
+			/* wait busy */
+			while ((IOH_GBE_READ_REG(hw, ADDR_MASK) & IOH_GBE_BUSY)
+			       != 0) {
+				;
+			}
+			/* Clear MAC address */
+			IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, i << 1, 0);
+			IOH_GBE_WRITE_REG_ARRAY(hw, MAC_ADR, (i << 1) + 1, 0);
+		}
+	}
+#ifdef DEBUG_TEST
+	{
+		unsigned char ti;
+		IOH_GBE_TESTOUT("ADDR_MASK reg(check index bit) : 0x%08x\n",
+				IOH_GBE_READ_REG(hw, ADDR_MASK));
+		for (ti = 0; ti < 16; ti++) {
+			IOH_GBE_TESTOUT("MAC_ADR%dAB reg : 0x%08x 0x%08x\n",
+					(ti + 1),
+					IOH_GBE_READ_REG(hw,
+							 MAC_ADR1A +
+							 (0x08 * ti)),
+					IOH_GBE_READ_REG(hw,
+							 MAC_ADR1B +
+							 (0x08 * ti)));
+		}
+	}
+#endif
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw)
+ * @brief   Setup flow control and link settings
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw)
+{
+	struct ioh_gbe_functions *func = &hw->func;
+	s32 ret_val = IOH_GBE_SUCCESS;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_setup_link");
+
+	/* Call the necessary media_type subroutine to configure the link. */
+	ret_val = func->setup_physical_interface(hw);
+
+	return ret_val;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw)
+ * @brief   Force the MAC's flow control settings
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw)
+{
+	struct ioh_gbe_mac_info *mac = &hw->mac;
+	u32 rx_fctrl;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_force_mac_fc");
+	IOH_GBE_TESTOUT("mac->fc = %u\n", mac->fc);
+
+	rx_fctrl = IOH_GBE_READ_REG(hw, RX_FCTRL);
+
+	switch (mac->fc) {
+	case ioh_gbe_fc_none:
+		rx_fctrl &= ~IOH_GBE_FL_CTRL_EN;
+		mac->tx_fc_enable = FALSE;
+		break;
+	case ioh_gbe_fc_rx_pause:
+		rx_fctrl |= IOH_GBE_FL_CTRL_EN;
+		mac->tx_fc_enable = FALSE;
+		break;
+	case ioh_gbe_fc_tx_pause:
+		rx_fctrl &= ~IOH_GBE_FL_CTRL_EN;
+		mac->tx_fc_enable = TRUE;
+		break;
+	case ioh_gbe_fc_full:
+		rx_fctrl |= IOH_GBE_FL_CTRL_EN;
+		mac->tx_fc_enable = TRUE;
+		break;
+	default:
+		IOH_GBE_DBGOUT("Flow control param set incorrectly\n");
+		return -IOH_GBE_ERR_CONFIG;
+	}
+	if (mac->link_duplex == DUPLEX_HALF)
+		rx_fctrl &= ~IOH_GBE_FL_CTRL_EN;
+	IOH_GBE_WRITE_REG(hw, RX_FCTRL, rx_fctrl);
+	IOH_GBE_TESTOUT("RX_FCTRL reg : 0x%08x  mac->tx_fc_enable : %d\n",
+			IOH_GBE_READ_REG(hw, RX_FCTRL), mac->tx_fc_enable);
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw)
+ * @brief   Configures flow control after link
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ */
+s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_config_fc_after_link_up");
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt)
+ * @brief   Set wake-on-lan event
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   wu_evt [IN] Wake up event
+ * @return  None
+ */
+void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt)
+{
+	u32 addr_mask;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_set_wol_event");
+	IOH_GBE_TESTOUT("wu_evt : 0x%08x  ADDR_MASK reg : 0x%08x\n",
+			wu_evt, IOH_GBE_READ_REG(hw, ADDR_MASK));
+
+	if (wu_evt != 0) {
+		/* Set Wake-On-Lan address mask */
+		addr_mask = IOH_GBE_READ_REG(hw, ADDR_MASK);
+		IOH_GBE_WRITE_REG(hw, WOL_ADDR_MASK, addr_mask);
+		/* wait busy */
+		while ((IOH_GBE_READ_REG(hw, WOL_ADDR_MASK) & IOH_GBE_WLA_BUSY)
+		       != 0) {
+			;
+		}
+		IOH_GBE_WRITE_REG(hw, WOL_ST, 0);
+		IOH_GBE_WRITE_REG(hw, WOL_CTRL,
+				  (wu_evt | IOH_GBE_WLC_WOL_MODE));
+		IOH_GBE_WRITE_REG(hw, INT_EN, IOH_GBE_INT_ENABLE_MASK);
+	} else {
+		IOH_GBE_WRITE_REG(hw, WOL_CTRL, 0);
+		IOH_GBE_WRITE_REG(hw, WOL_ST, 0);
+	}
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT
+	    ("WOL_ADDR_MASK reg : 0x%08x  WOL_CTRL reg : 0x%08x  "
+	     "WOL_ST reg : 0x%08x\n",
+	     IOH_GBE_READ_REG(hw, WOL_ADDR_MASK),
+	     IOH_GBE_READ_REG(hw, WOL_CTRL),
+	     IOH_GBE_READ_REG(hw, WOL_ST));
+#endif
+	return;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      u16 ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr,
+ *                                    u32 dir, u32 reg, u16 data)
+ * @brief   Set wake-on-lan event
+ * @param   hw   [INOUT] Pointer to the HW structure
+ * @param   addr [IN] Address of PHY
+ * @param   dir  [IN] Operetion. (Write or Read)
+ * @param   reg  [IN] Access register of PHY
+ * @param   data [IN] Write data.
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+u16
+ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
+			u16 data)
+{
+	u32 data_out = 0;
+	unsigned int i;
+	unsigned long flags;
+
+	IOH_GBE_DBGOUT2("ioh_gbe_mac_ctrl_miim\n");
+	spin_lock_irqsave(&hw->miim_lock, flags);
+
+	for (i = 100; i; --i) {
+		if ((IOH_GBE_READ_REG(hw, MIIM) & IOH_GBE_MIIM_OPER_READY) != 0)
+			break;
+		udelay(20);
+	}
+	if (i == 0) {
+		IOH_GBE_DBGOUT("ioh-sample-gbe.miim won't go Ready\n");
+		spin_unlock_irqrestore(&hw->miim_lock, flags);
+		return IOH_GBE_SUCCESS;	/* No way to indicate timeout error */
+	}
+	IOH_GBE_WRITE_REG(hw, MIIM, ((reg << IOH_GBE_MIIM_REG_ADDR_SHIFT) |
+				     (addr << IOH_GBE_MIIM_PHY_ADDR_SHIFT) |
+				     dir | data));
+	for (i = 0; i < 100; i++) {
+		udelay(20);
+		data_out = IOH_GBE_READ_REG(hw, MIIM);
+		if ((data_out & IOH_GBE_MIIM_OPER_READY) != 0)
+			break;
+	}
+	spin_unlock_irqrestore(&hw->miim_lock, flags);
+
+	IOH_GBE_DBGOUT1("%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
+			dir == IOH_GBE_MIIM_OPER_READ ? "READ" : "WRITE",
+			addr, reg, data, data_out);
+	return (u16) data_out;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw)
+ * @brief   Set pause packet
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  None
+ */
+void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw)
+{
+	unsigned long tmp2, tmp3;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_set_pause_packet");
+
+	/* Set Pause packet */
+	tmp2 = hw->mac.addr[1];
+	tmp2 = (tmp2 << 8) | hw->mac.addr[0];
+	tmp2 = IOH_GBE_PAUSE_PKT2_VALUE | (tmp2 << 16);
+
+	tmp3 = hw->mac.addr[5];
+	tmp3 = (tmp3 << 8) | hw->mac.addr[4];
+	tmp3 = (tmp3 << 8) | hw->mac.addr[3];
+	tmp3 = (tmp3 << 8) | hw->mac.addr[2];
+
+	IOH_GBE_WRITE_REG(hw, PAUSE_PKT1, IOH_GBE_PAUSE_PKT1_VALUE);
+	IOH_GBE_WRITE_REG(hw, PAUSE_PKT2, tmp2);
+	IOH_GBE_WRITE_REG(hw, PAUSE_PKT3, tmp3);
+	IOH_GBE_WRITE_REG(hw, PAUSE_PKT4, IOH_GBE_PAUSE_PKT4_VALUE);
+	IOH_GBE_WRITE_REG(hw, PAUSE_PKT5, IOH_GBE_PAUSE_PKT5_VALUE);
+
+	/* Transmit Pause Packet */
+	IOH_GBE_WRITE_REG(hw, PAUSE_REQ, IOH_GBE_PS_PKT_RQ);
+
+	IOH_GBE_TESTOUT
+	    ("PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	     IOH_GBE_READ_REG(hw, PAUSE_PKT1), IOH_GBE_READ_REG(hw, PAUSE_PKT2),
+	     IOH_GBE_READ_REG(hw, PAUSE_PKT3), IOH_GBE_READ_REG(hw, PAUSE_PKT4),
+	     IOH_GBE_READ_REG(hw, PAUSE_PKT5));
+
+	return;
+}
+
+#ifndef CONFIG_PCH_PCIEQOS
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw)
+ * @brief   Read MAC address
+ * @param   hw [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS
+ */
+s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw)
+{
+	u32  adr1a, adr1b;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_mac_read_mac_addr");
+
+	adr1a = IOH_GBE_READ_REG(hw, MAC_ADR1A);
+	adr1b = IOH_GBE_READ_REG(hw, MAC_ADR1B);
+
+	hw->mac.addr[0] = (u8)(adr1a & 0xFF);
+	hw->mac.addr[1] = (u8)((adr1a >> 8) & 0xFF);
+	hw->mac.addr[2] = (u8)((adr1a >> 16) & 0xFF);
+	hw->mac.addr[3] = (u8)((adr1a >> 24) & 0xFF);
+	hw->mac.addr[4] = (u8)(adr1b & 0xFF);
+	hw->mac.addr[5] = (u8)((adr1b >> 8) & 0xFF);
+
+	IOH_GBE_TESTOUT("hw->mac.addr : 0x%02x %02x %02x %02x %02x %02x\n",
+		hw->mac.addr[0], hw->mac.addr[1], hw->mac.addr[2],
+		hw->mac.addr[3], hw->mac.addr[4], hw->mac.addr[5]);
+	return IOH_GBE_SUCCESS;
+}
+#endif /* CONFIG_PCH_PCIEQOS */
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_mac.h	2010-03-11 15:11:47.000000000 +0900
@@ -0,0 +1,121 @@
+/*!
+ * @file ioh_gbe_mac.h
+ * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (MAC) header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_MAC_H_
+#define _IOH_GBE_MAC_H_
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw)
+ * @brief   Reset hardware
+ */
+void ioh_gbe_mac_reset_hw(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw,
+ *                                         u16 mar_count)
+ * @brief   Initialize receive address's
+ */
+void ioh_gbe_mac_init_rx_addrs(struct ioh_gbe_hw *hw, u16 mar_count);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index)
+ * @brief   Set MAC address register
+ */
+void ioh_gbe_mac_mar_set(struct ioh_gbe_hw *hw, u8 *addr, u32 index);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw,
+ *                                u8 *mc_addr_list,   u32 mc_addr_count,
+ *                                u32 mar_used_count, u32 mar_total_num)
+ * @brief   Update Multicast addresses
+ */
+void ioh_gbe_mac_mc_addr_list_update(struct ioh_gbe_hw *hw,
+				     u8 *mc_addr_list, u32 mc_addr_count,
+				     u32 mar_used_count, u32 mar_count);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw)
+ * @brief   Setup flow control and link settings
+ */
+s32 ioh_gbe_mac_setup_link(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw)
+ * @brief   Force the MAC's flow control settings
+ */
+s32 ioh_gbe_mac_force_mac_fc(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw)
+ * @brief   Configures flow control after link
+ */
+s32 ioh_gbe_mac_config_fc_after_link_up(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt)
+ * @brief   Set wake-on-lan event
+ */
+void ioh_gbe_mac_set_wol_event(struct ioh_gbe_hw *hw, u32 wu_evt);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      u16 ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw, u32 addr,
+ *                                    u32 dir, u32 reg, u16 data)
+ * @brief   Set wake-on-lan event
+ */
+u16 ioh_gbe_mac_ctrl_miim(struct ioh_gbe_hw *hw,
+			  u32 addr, u32 dir, u32 reg, u16 data);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw)
+ * @brief   Set pause packet
+ */
+void ioh_gbe_mac_set_pause_packet(struct ioh_gbe_hw *hw);
+
+#ifndef CONFIG_PCH_PCIEQOS
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw)
+ * @brief   Read MAC address
+ */
+s32 ioh_gbe_mac_read_mac_addr(struct ioh_gbe_hw *hw);
+#endif /* CONFIG_PCH_PCIEQOS */
+
+#endif /* _IOH_GBE_MAC_H_ */
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_main.c	2010-03-11 15:13:21.000000000 +0900
@@ -0,0 +1,2973 @@
+/*!
+ * @file ioh_gbe_main.c
+ * @brief Linux IOH Gigabit Ethernet Driver main source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <net/ip.h>
+
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_regs.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_api.h"
+#include "pch_gbe.h"
+
+/* ----------------------------------------------------------------------------
+	Function prototype
+---------------------------------------------------------------------------- */
+static int
+ioh_gbe_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id);
+static void ioh_gbe_remove(struct pci_dev *pdev);
+static int ioh_gbe_suspend(struct pci_dev *pdev, pm_message_t state);
+static int ioh_gbe_resume(struct pci_dev *pdev);
+static void ioh_gbe_shutdown(struct pci_dev *pdev);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ioh_gbe_netpoll(struct net_device *netdev);
+#endif
+static pci_ers_result_t
+ioh_gbe_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state);
+static pci_ers_result_t ioh_gbe_io_slot_reset(struct pci_dev *pdev);
+static void ioh_gbe_io_resume(struct pci_dev *pdev);
+
+static int ioh_gbe_init_module(void);
+static void ioh_gbe_exit_module(void);
+static int ioh_gbe_open(struct net_device *netdev);
+static int ioh_gbe_stop(struct net_device *netdev);
+static int ioh_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+static struct net_device_stats *ioh_gbe_get_stats(struct net_device *netdev);
+static void ioh_gbe_set_multi(struct net_device *netdev);
+static int ioh_gbe_set_mac(struct net_device *netdev, void *p);
+static int ioh_gbe_change_mtu(struct net_device *netdev, int new_mtu);
+static int ioh_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
+static void ioh_gbe_tx_timeout(struct net_device *dev);
+
+static int ioh_gbe_sw_init(struct ioh_gbe_adapter *adapter);
+static int ioh_gbe_alloc_queues(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_init_stats(struct ioh_gbe_adapter *adapter);
+static int ioh_gbe_init_nvm(struct ioh_gbe_adapter *adapter);
+static int ioh_gbe_init_phy(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_reset_task(struct work_struct *work);
+static int ioh_gbe_request_irq(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_free_irq(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_irq_disable(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_irq_enable(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_clean_tx_ring(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_tx_ring *tx_ring);
+static void ioh_gbe_clean_rx_ring(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_rx_ring *rx_ring);
+static void
+ioh_gbe_unmap_and_free_tx_resource(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_buffer *buffer_info);
+static void
+ioh_gbe_unmap_and_free_rx_resource(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_buffer *buffer_info);
+
+static void ioh_gbe_setup_tctl(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_configure_tx(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_setup_rctl(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_configure_rx(struct ioh_gbe_adapter *adapter);
+static void ioh_gbe_set_rgmii_ctrl(struct ioh_gbe_adapter *adapter,
+					u16 speed, u16 duplex);
+static void ioh_gbe_set_mode(struct ioh_gbe_adapter *adapter,
+					u16 speed, u16 duplex);
+static void ioh_gbe_watchdog(unsigned long data);
+static irqreturn_t ioh_gbe_intr(int irq, void *data);
+static unsigned char ioh_gbe_clean_tx(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_tx_ring *tx_ring);
+static int ioh_gbe_napi_poll(struct napi_struct *napi, int budget);
+static unsigned char ioh_gbe_clean_rx(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_rx_ring *rx_ring,
+				int *work_done, int work_to_do);
+static void ioh_gbe_alloc_rx_buffers(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_rx_ring *rx_ring,
+				int cleaned_count);
+static void ioh_gbe_alloc_tx_buffers(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_tx_ring *tx_ring);
+static void ioh_gbe_tx_queue(struct ioh_gbe_adapter *adapter,
+			struct ioh_gbe_tx_ring *tx_ring,
+			struct sk_buff *skb);
+
+/* ----------------------------------------------------------------------------
+	Data
+---------------------------------------------------------------------------- */
+/*!
+ * @ingroup PCI driver Layer
+ * @struct  ioh_gbe_pcidev_id
+ * @brief   PCI Device ID Table
+ * @remarks
+ *  This is an instance of pci_device_id structure defined in linux/pci.h,
+ *  and holds information of the PCI devices that are supported by this driver.
+ */
+static const struct pci_device_id ioh_gbe_pcidev_id[3] = {
+	{.vendor = PCI_VENDOR_ID_INTEL,
+	 .device = PCI_DEVICE_ID_INTEL_IOH1_GBE,
+	 .subvendor = PCI_ANY_ID,
+	 .subdevice = PCI_ANY_ID,
+	 .class = (PCI_CLASS_NETWORK_ETHERNET << 8),
+	 .class_mask = (0xFFFF00)
+	 },
+	/* required last entry */
+	{0}
+};
+
+/*!
+ * @ingroup PCI driver Layer
+ * @struct  ioh_gbe_err_handler
+ * @brief   Error handler Table
+ * @remarks
+ *  This is an instance of pci_error_handlers structure defined in linux/pci.h,
+ *  and holds information of the PCI devices that are supported by this driver.
+ */
+static struct pci_error_handlers ioh_gbe_err_handler = {
+	.error_detected = ioh_gbe_io_error_detected,
+	.slot_reset = ioh_gbe_io_slot_reset,
+	.resume = ioh_gbe_io_resume
+};
+
+/*!
+ * @ingroup PCI driver Layer
+ * @struct  ioh_gbe_pcidev
+ * @brief   Store the pointers of pci driver interfaces to kernel
+ */
+static struct pci_driver ioh_gbe_pcidev = {
+	.name = DRV_NAME,
+	.id_table = ioh_gbe_pcidev_id,
+	.probe = ioh_gbe_probe,
+	.remove = ioh_gbe_remove,
+	/* Power Managment Hooks */
+#ifdef CONFIG_PM
+	.suspend = ioh_gbe_suspend,
+	.resume = ioh_gbe_resume,
+#endif
+	.shutdown = ioh_gbe_shutdown,
+	.err_handler = &ioh_gbe_err_handler
+};
+
+static int debug = IOH_GBE_NETIF_MSG_DEFAULT;
+static unsigned int copybreak __read_mostly = IOH_GBE_COPYBREAK_DEFAULT;
+
+/* ----------------------------------------------------------------------------
+	module
+---------------------------------------------------------------------------- */
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+MODULE_DEVICE_TABLE(pci, ioh_gbe_pcidev_id);
+
+module_param(copybreak, uint, 0644);
+MODULE_PARM_DESC(copybreak,
+	"Maximum size of packet that is copied to a new buffer on receive");
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+module_init(ioh_gbe_init_module);
+module_exit(ioh_gbe_exit_module);
+
+/* ----------------------------------------------------------------------------
+	Macro Function
+---------------------------------------------------------------------------- */
+#define IOH_GBE_GET_DESC(R, i, type)    (&(((struct type *)((R).desc))[i]))
+#define IOH_GBE_RX_DESC(R, i)           IOH_GBE_GET_DESC(R, i, ioh_gbe_rx_desc)
+#define IOH_GBE_TX_DESC(R, i)           IOH_GBE_GET_DESC(R, i, ioh_gbe_tx_desc)
+#define IOH_GBE_DESC_UNUSED(R) \
+	((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
+	(R)->next_to_clean - (R)->next_to_use - 1)
+
+/* ----------------------------------------------------------------------------
+	Function
+---------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------------
+	PCI driver methods
+---------------------------------------------------------------------------- */
+
+static const struct net_device_ops ioh_gbe_netdev_ops = {
+	.ndo_open = ioh_gbe_open,
+	.ndo_stop = ioh_gbe_stop,
+	.ndo_start_xmit = ioh_gbe_xmit_frame,
+	.ndo_get_stats = ioh_gbe_get_stats,
+	.ndo_set_mac_address = ioh_gbe_set_mac,
+	.ndo_tx_timeout = ioh_gbe_tx_timeout,
+	.ndo_change_mtu = ioh_gbe_change_mtu,
+	.ndo_do_ioctl = ioh_gbe_ioctl,
+	.ndo_set_multicast_list = &ioh_gbe_set_multi,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = ioh_gbe_netpoll,
+#endif
+};
+
+/*!
+ * @ingroup PCI driver method
+ * @fn      static int ioh_gbe_probe(struct pci_dev *pdev,
+ *                                   const struct pci_device_id *pci_id)
+ * @brief   Device Initialization Routine
+ * @param   pdev    [INOUT] PCI device information struct
+ * @param   pci_id  [INOUT] Entry in ioh_gbe_pcidev_id
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ * @remarks
+ *  This function initializes an adapter identified by a pci_dev structure.
+ *  The OS initialization, configuring of the adapter private structure,
+ *  and a hardware reset occur.
+ */
+static int
+ioh_gbe_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+	struct net_device *netdev;
+	struct ioh_gbe_adapter *adapter;
+	unsigned long mmio_start;
+	unsigned long mmio_len;
+	static int cards_found;
+	int i, ret;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_probe");
+
+	cards_found = 0;
+	ret = pci_enable_device(pdev);
+	if (ret != 0)
+		return ret;
+	ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	if (ret != 0) {
+		ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+		if (ret != 0) {
+			IOH_GBE_ERR
+			    ("ERR: No usable DMA configuration, aborting\n");
+			goto err_disable_device;
+		}
+	}
+	ret = pci_request_regions(pdev, DRV_NAME);
+	if (ret != 0) {
+		IOH_GBE_ERR
+		    ("ERR: Can't reserve PCI I/O and memory resources\n");
+		goto err_disable_device;
+	}
+	pci_set_master(pdev);
+
+	netdev = alloc_etherdev((int)sizeof(struct ioh_gbe_adapter));
+	if (!netdev) {
+		ret = -ENOMEM;
+		IOH_GBE_ERR
+		    ("ERR: Can't allocates and sets up an Ethernet device\n");
+		goto err_release_pci;
+	}
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
+	pci_set_drvdata(pdev, netdev);
+	adapter = netdev_priv(netdev);
+	adapter->netdev = netdev;
+	adapter->pdev = pdev;
+	adapter->msg_enable = (1 << debug) - 1;
+	adapter->bd_number = cards_found;
+	adapter->hw.back = adapter;
+	mmio_start = pci_resource_start(pdev, IOH_GBE_PCI_BAR);
+	mmio_len = pci_resource_len(pdev, IOH_GBE_PCI_BAR);
+	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
+	if (!adapter->hw.hw_addr) {
+		ret = -EIO;
+		DPRINTK(PROBE, ERR, "Can't ioremap\n");
+		goto err_free_netdev;
+	}
+
+	netdev->netdev_ops = &ioh_gbe_netdev_ops;
+
+	netdev->watchdog_timeo = IOH_GBE_WATCHDOG_PERIOD;
+	netif_napi_add(netdev, &adapter->napi,
+		       ioh_gbe_napi_poll, IOH_GBE_RX_WEIGHT);
+	strncpy(netdev->name, pci_name(pdev), (int)sizeof(netdev->name) - 1);
+	netdev->mem_start = mmio_start;
+	netdev->mem_end = mmio_start + mmio_len;
+	netdev->features = NETIF_F_HW_CSUM;
+	ioh_gbe_set_ethtool_ops(netdev);
+
+	/* setup the private structure */
+	ret = ioh_gbe_sw_init(adapter);
+	if (ret != 0)
+		goto err_iounmap;
+
+	ioh_gbe_hal_reset_hw(&adapter->hw);
+	/* Initialize PHY */
+	ret = ioh_gbe_init_phy(adapter);
+	if (ret != 0) {
+		DPRINTK(PROBE, ERR, "PHY initialize error\n");
+		goto err_free_adapter;
+	}
+
+	ioh_gbe_hal_get_bus_info(&adapter->hw);
+
+	/* Initialize NVM */
+	ret = ioh_gbe_init_nvm(adapter);
+	if (ret != 0) {
+		DPRINTK(PROBE, ERR, "NVM initialize error\n");
+		goto err_free_adapter;
+	}
+
+#ifdef CONFIG_PCH_PCIEQOS
+	/* Read the MAC address. and store to the private data */
+	ret = ioh_gbe_hal_read_mac_addr(&adapter->hw);
+	if (ret != 0) {
+		DPRINTK(PROBE, ERR, "MAC address Read Error\n");
+		goto err_free_adapter;
+	}
+#endif
+	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
+		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
+		ret = -EIO;
+		goto err_free_adapter;
+	}
+
+	init_timer(&adapter->watchdog_timer);
+	adapter->watchdog_timer.function = &ioh_gbe_watchdog;
+	adapter->watchdog_timer.data = (unsigned long)adapter;
+
+	INIT_WORK(&adapter->reset_task, ioh_gbe_reset_task);
+
+	ioh_gbe_check_options(adapter);
+
+	if (adapter->tx_csum != 0)
+		netdev->features |= NETIF_F_HW_CSUM;
+	else
+		netdev->features &= ~NETIF_F_HW_CSUM;
+
+	/* initialize the wol settings based on the eeprom settings */
+	adapter->wake_up_evt = IOH_GBE_WL_INIT_SETTING;
+
+	/* print bus type/speed/width info */
+	{
+		struct ioh_gbe_hw *hw = &adapter->hw;
+		DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
+		((hw->bus.type == ioh_gbe_bus_type_pcix) ? "-X" :
+		  (hw->bus.type == ioh_gbe_bus_type_pci_express) ? " Express" :
+		""),
+		((hw->bus.speed == ioh_gbe_bus_speed_2500) ? "2.5Gb/s" :
+		  (hw->bus.speed == ioh_gbe_bus_speed_133) ? "133MHz" :
+		  (hw->bus.speed == ioh_gbe_bus_speed_120) ? "120MHz" :
+		  (hw->bus.speed == ioh_gbe_bus_speed_100) ? "100MHz" :
+		  (hw->bus.speed == ioh_gbe_bus_speed_66) ? "66MHz" :
+		  (hw->bus.speed == ioh_gbe_bus_speed_33) ? "33MHz" :
+		""),
+		((hw->bus.width == ioh_gbe_bus_width_64) ? "64-bit" :
+		  (hw->bus.width == ioh_gbe_bus_width_32) ? "32-bit" :
+		  (hw->bus.width == ioh_gbe_bus_width_pcie_x4) ? "Width x4" :
+		  (hw->bus.width == ioh_gbe_bus_width_pcie_x2) ? "Width x2" :
+		  (hw->bus.width == ioh_gbe_bus_width_pcie_x1) ? "Width x1" :
+		""));
+	}
+	for (i = 0; i < 6; i++)
+		printk(KERN_INFO "%2.2x%c",
+			netdev->dev_addr[i], i == 5 ? '\n' : ':');
+
+	/* reset the hardware with the new settings */
+	ioh_gbe_reset(adapter);
+
+	strcpy(netdev->name, "eth%d");
+	ret = register_netdev(netdev);
+	if (ret != 0)
+		goto err_free_adapter;
+	/* tell the stack to leave us alone until ioh_gbe_open() is called */
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	DPRINTK(PROBE, INFO, "OKIsemi(R) IOH Network Connection\n");
+
+	cards_found++;
+	device_set_wakeup_enable(&pdev->dev, 1);
+	return IOH_GBE_SUCCESS;
+
+err_free_adapter:
+	ioh_gbe_hal_phy_hw_reset(&adapter->hw);
+	dev_put(adapter->polling_netdev);
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+	kfree(adapter->polling_netdev);
+err_iounmap:
+	iounmap(adapter->hw.hw_addr);
+err_free_netdev:
+	free_netdev(netdev);
+err_release_pci:
+	pci_release_regions(pdev);
+err_disable_device:
+	pci_disable_device(pdev);
+	return ret;
+}
+
+/*!
+ * @ingroup PCI driver method
+ * @fn      static void ioh_gbe_remove(struct pci_dev *pdev)
+ * @brief   Device Removal Routine
+ * @param   pdev     [INOUT] PCI device information struct
+ * @return  None
+ * @remarks
+ *  This function is called by the PCI subsystem to alert the driver
+ *  that it should release a PCI device.  The could be caused by a
+ *  Hot-Plug event, or because the driver is going to be removed from
+ *  memory.
+ */
+static void ioh_gbe_remove(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	flush_scheduled_work();
+	unregister_netdev(netdev);
+	dev_put(adapter->polling_netdev);
+
+	ioh_gbe_hal_phy_hw_reset(&adapter->hw);
+
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+	kfree(adapter->polling_netdev);
+
+	iounmap(adapter->hw.hw_addr);
+	pci_release_regions(pdev);
+	free_netdev(netdev);
+	pci_disable_device(pdev);
+}
+
+/*!
+ * @ingroup PCI driver method
+ * @fn      static int ioh_gbe_suspend(struct pci_dev *pdev, pm_message_t state)
+ * @brief   Device Suspend Routine
+ * @param   pdev     [INOUT] PCI device information struct
+ * @param   state    [IN] Power status
+ * @return  None
+ */
+static int ioh_gbe_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 wufc = adapter->wake_up_evt;
+	int retval = IOH_GBE_SUCCESS;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev) != 0)
+		ioh_gbe_down(adapter);
+#ifdef CONFIG_PM
+	/* Implement our own version of pci_save_state(pdev) because pci-
+	 * express adapters have 256-byte config spaces. */
+	retval = pci_save_state(pdev);
+	if (retval != 0) {
+		DPRINTK(PROBE, DEBUG, "pci_save_state failed\n");
+		return retval;
+	}
+#endif
+
+	if (wufc != 0) {
+		ioh_gbe_set_multi(netdev);
+		ioh_gbe_setup_rctl(adapter);
+		ioh_gbe_configure_rx(adapter);
+		ioh_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
+					hw->mac.link_duplex);
+		ioh_gbe_set_mode(adapter, hw->mac.link_speed,
+					hw->mac.link_duplex);
+		ioh_gbe_hal_set_wol_event(hw, wufc);
+		pci_disable_device(pdev);
+		retval = pci_set_power_state(pdev, PCI_D0);
+		if (retval)
+			DPRINTK(PROBE, DEBUG, "pci_set_power_state failed\n");
+		retval = pci_enable_wake(pdev, PCI_D0, 1);
+		if (retval)
+			DPRINTK(PROBE, DEBUG, "pci_enable_wake failed\n");
+	} else {
+		ioh_gbe_hal_power_down_phy(hw);
+		ioh_gbe_hal_set_wol_event(hw, wufc);
+		pci_disable_device(pdev);
+		pci_enable_wake(pdev, PCI_D0, 0);
+		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	}
+	return retval;
+}
+
+#ifdef CONFIG_PM
+/*!
+ * @ingroup PCI driver method
+ * @fn      static int ioh_gbe_resume(struct pci_dev *pdev)
+ * @brief   Device Resume Routine
+ * @param   pdev     [INOUT] PCI device information struct
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  negative:  Failed
+ */
+static int ioh_gbe_resume(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 err;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	err = pci_enable_device(pdev);
+	if (err != 0) {
+		DPRINTK(PROBE, ERR, "Cannot enable PCI device from suspend\n");
+		return err;
+	}
+	pci_set_master(pdev);
+	ioh_gbe_hal_power_up_phy(hw);
+	ioh_gbe_reset(adapter);
+	/* Clear wake on lan control and status */
+	ioh_gbe_hal_set_wol_event(hw, 0);
+
+	if (netif_running(netdev) != 0)
+		ioh_gbe_up(adapter);
+	netif_device_attach(netdev);
+
+	return IOH_GBE_SUCCESS;
+}
+#endif /* CONFIG_PM */
+
+/*!
+ * @ingroup PCI driver method
+ * @fn      static void ioh_gbe_shutdown(struct pci_dev *pdev)
+ * @brief   Device shutdown Routine
+ * @param   pdev    [INOUT] PCI device information struct
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ */
+static void ioh_gbe_shutdown(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	ioh_gbe_suspend(pdev, PMSG_SUSPEND);
+}
+
+/*!
+ * @ingroup PCI driver method
+ * @fn      static pci_ers_result_t ioh_gbe_io_error_detected(
+ *                                  struct pci_dev *pdev,
+ *                                  pci_channel_state_t state)
+ * @brief   Called when PCI error is detected
+ * @param   pdev     [INOUT] PCI device information struct
+ * @param   state    [IN] The current pci connection state
+ * @return  PCI_ERS_RESULT_NEED_RESET
+ * @remarks
+ *   This function is called after a PCI bus error affecting
+ *   this device has been detected.
+ */
+static pci_ers_result_t
+ioh_gbe_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev) != 0)
+		ioh_gbe_down(adapter);
+	pci_disable_device(pdev);
+
+	/* Request a slot slot reset. */
+	return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/*!
+ * @ingroup PCI driver method
+ * @fn      static pci_ers_result_t ioh_gbe_io_slot_reset(struct pci_dev *pdev)
+ * @brief   Called after the pci bus has been reset.
+ * @param   pdev    [INOUT] PCI device information struct
+ * @return  PCI_ERS_RESULT_DISCONNECT
+ * @return  PCI_ERS_RESULT_RECOVERED
+ * @remarks
+ *   Restart the card from scratch, as if from a cold-boot. Implementation
+ *   resembles the first-half of the ioh_gbe_resume routine.
+ */
+static pci_ers_result_t ioh_gbe_io_slot_reset(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	if (pci_enable_device(pdev) != 0) {
+		DPRINTK(PROBE, ERR,
+			"Cannot re-enable PCI device after reset.\n");
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+	pci_set_master(pdev);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	ioh_gbe_hal_power_up_phy(hw);
+	ioh_gbe_reset(adapter);
+	/* Clear wake up status */
+	ioh_gbe_hal_set_wol_event(hw, 0);
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+/*!
+ * @ingroup PCI driver method
+ * @fn      static void ioh_gbe_io_resume(struct pci_dev *pdev)
+ * @brief   Called when traffic can start flowing again.
+ * @param   pdev    [INOUT] PCI device information struct
+ * @return  PCI_ERS_RESULT_DISCONNECT
+ * @return  PCI_ERS_RESULT_RECOVERED
+ * @remarks
+ *   This callback is called when the error recovery driver tells us that
+ *   its OK to resume normal operation. Implementation resembles the
+ *   second-half of the ioh_gbe_resume routine.
+ */
+static void ioh_gbe_io_resume(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	if (netif_running(netdev) != 0) {
+		if (ioh_gbe_up(adapter) != 0) {
+			DPRINTK(PROBE, DEBUG,
+				"can't bring device back up after reset\n");
+			return;
+		}
+	}
+	netif_device_attach(netdev);
+}
+
+/* ----------------------------------------------------------------------------
+	Gigabit Ethernet driver methods
+---------------------------------------------------------------------------- */
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int __init ioh_gbe_init_module(void)
+ * @brief   Driver Registration Routine
+ * @return  IOH_GBE_SUCCESS  Successfully
+ * @return  negative value  Failed
+ * @remarks
+ *   ioh_gbe_init_module is the first routine called when the driver is
+ *   loaded. All it does is register with the PCI subsystem.
+ */
+static int __init ioh_gbe_init_module(void)
+{
+	int ret;
+	IOH_GBE_DBGFUNC("ioh_gbe_init_module");
+	printk(KERN_INFO "%s - version %s\n", DRV_STRING, DRV_VERSION);
+
+	ret = pci_register_driver(&ioh_gbe_pcidev);
+	if (copybreak != IOH_GBE_COPYBREAK_DEFAULT) {
+		if (copybreak == 0) {
+			printk(KERN_INFO "ioh_gbe: copybreak disabled\n");
+		} else {
+			printk(KERN_INFO "ioh_gbe: copybreak enabled for "
+				"packets <= %u bytes\n", copybreak);
+		}
+	}
+	return ret;
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static void __exit ioh_gbe_exit_module(void)
+ * @brief   Driver Exit Cleanup Routine
+ * @return  None
+ * @remarks
+ *   ioh_gbe_exit_module is called just before the driver is removed
+ *   from memory.
+ */
+static void __exit ioh_gbe_exit_module(void)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_exit_module");
+	pci_unregister_driver(&ioh_gbe_pcidev);
+
+	printk(KERN_INFO "%s - unregister\n", DRV_STRING);
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int ioh_gbe_open(struct net_device *netdev)
+ * @brief   Called when a network interface is made active
+ * @param   netdev  [INOUT] network interface device structure
+ * @return  IOH_GBE_SUCCESS - Successfully
+ * @return  negative value - Failed
+ * @remarks
+ *   The open entry point is called when a network interface is made
+ *   active by the system (IFF_UP).  At this point all resources needed
+ *   for transmit and receive operations are allocated, the interrupt
+ *   handler is registered with the OS, the watchdog timer is started,
+ *   and the stack is notified that the interface is ready.
+ */
+static int ioh_gbe_open(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	int err;
+
+	DPRINTK(IFUP, DEBUG, "\n");
+
+	/* disallow open during test */
+	if ((test_bit(__IOH_GBE_TESTING, &adapter->flags)) != 0)
+		return -EBUSY;
+	/* allocate transmit descriptors */
+	err = ioh_gbe_setup_tx_resources(adapter, adapter->tx_ring);
+	if (err != 0)
+		goto err_setup_tx;
+	/* allocate receive descriptors */
+	err = ioh_gbe_setup_rx_resources(adapter, adapter->rx_ring);
+	if (err != 0)
+		goto err_setup_rx;
+	ioh_gbe_hal_power_up_phy(hw);
+	err = ioh_gbe_up(adapter);
+	if (err != 0)
+		goto err_up;
+	DPRINTK(PROBE, DEBUG, "Success End\n");
+	return IOH_GBE_SUCCESS;
+
+err_up:
+	if (!adapter->wake_up_evt)
+		ioh_gbe_hal_power_down_phy(hw);
+	ioh_gbe_free_rx_resources(adapter, adapter->rx_ring);
+err_setup_rx:
+	ioh_gbe_free_tx_resources(adapter, adapter->tx_ring);
+err_setup_tx:
+	ioh_gbe_reset(adapter);
+	DPRINTK(PROBE, ERR, "Error End\n");
+	return err;
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int ioh_gbe_stop(struct net_device *netdev)
+ * @brief   Disables a network interface
+ * @param   netdev  [INOUT] network interface device structure
+ * @return  IOH_GBE_SUCCESS - Successfully (This is not allowed to fail)
+ * @remarks
+ *   The close entry point is called when an interface is de-activated
+ *   by the OS.  The hardware is still under the drivers control, but
+ *   needs to be disabled.  A global MAC reset is issued to stop the
+ *   hardware, and all transmit and receive resources are freed.
+ */
+static int ioh_gbe_stop(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+
+	DPRINTK(IFDOWN, DEBUG, "\n");
+
+	ioh_gbe_down(adapter);
+	if (!adapter->wake_up_evt)
+		ioh_gbe_hal_power_down_phy(hw);
+	ioh_gbe_free_tx_resources(adapter, adapter->tx_ring);
+	ioh_gbe_free_rx_resources(adapter, adapter->rx_ring);
+
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int ioh_gbe_xmit_frame(struct sk_buff *skb,
+ *                                        struct net_device *netdev)
+ * @brief   Packet transmitting start
+ * @param   skb    [INOUT] socket buffer structure
+ * @param   netdev [INOUT] network interface device structure
+ * @return  NETDEV_TX_OK: Normal end
+ * @return  NETDEV_TX_BUSY: Error end
+ */
+static int ioh_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_tx_ring *tx_ring = adapter->tx_ring;
+	unsigned long flags;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	if (unlikely(skb->len <= 0)) {
+		dev_kfree_skb_any(skb);
+		IOH_GBE_TESTOUT("Return : OK  skb len : %d\n", skb->len);
+		return NETDEV_TX_OK;
+	}
+	if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) {
+		DPRINTK(PROBE, ERR, "Transfer length Error: %d over %d\n",
+			skb->len, adapter->hw.mac.max_frame_size);
+		dev_kfree_skb_any(skb);
+		adapter->stats.tx_length_errors++;
+		return NETDEV_TX_BUSY;
+	}
+	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
+		/* Collision - tell upper layer to requeue */
+		return NETDEV_TX_LOCKED;
+	}
+	if (unlikely(!IOH_GBE_DESC_UNUSED(tx_ring))) {
+		netif_stop_queue(netdev);
+		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+		IOH_GBE_TESTOUT
+		("Return : BUSY  next_to use : 0x%08x  "
+		 "next_to clean : 0x%08x\n",
+		 tx_ring->next_to_use, tx_ring->next_to_clean);
+		return NETDEV_TX_BUSY;
+	}
+	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+
+	/* CRC,ITAG no support */
+	ioh_gbe_tx_queue(adapter, tx_ring, skb);
+	netdev->trans_start = jiffies;
+	return NETDEV_TX_OK;
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static struct net_device_stats *ioh_gbe_get_stats(
+ *                                          struct net_device *netdev)
+ * @brief   Get System Network Statistics
+ * @param   netdev [INOUT] network interface device structure
+ * @return  The current stats
+ * @remarks
+ *   Returns the address of the device statistics structure.
+ *   The statistics are actually updated from the timer callback.
+ */
+static struct net_device_stats *ioh_gbe_get_stats(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	/* only return the current stats */
+	return &adapter->net_stats;
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static void ioh_gbe_set_multi(struct net_device *netdev)
+ * @brief   Multicast and Promiscuous mode set
+ * @param   netdev [INOUT] network interface device structure
+ * @return  None
+ * @remarks
+ *   The set_multi entry point is called whenever the multicast address
+ *   list or the network interface flags are updated.  This routine is
+ *   responsible for configuring the hardware for proper multicast,
+ *   promiscuous mode, and all-multi behavior.
+ */
+static void ioh_gbe_set_multi(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	struct ioh_gbe_mac_info *mac = &hw->mac;
+	struct dev_mc_list *mc_ptr;
+	u8 *mta_list;
+	u32 rctl;
+	int i;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	IOH_GBE_TESTOUT("netdev->flags : 0x%08x\n", netdev->flags);
+
+	/* Check for Promiscuous and All Multicast modes */
+	rctl = IOH_GBE_READ_REG(hw, RX_MODE);
+
+	if ((netdev->flags & IFF_PROMISC) != 0) {
+		rctl &= ~IOH_GBE_ADD_FIL_EN;
+		rctl &= ~IOH_GBE_MLT_FIL_EN;
+	} else if ((netdev->flags & IFF_ALLMULTI) != 0) {
+		/* all the multicasting receive permissions */
+		rctl |= IOH_GBE_ADD_FIL_EN;
+		rctl &= ~IOH_GBE_MLT_FIL_EN;
+	} else {
+		if (netdev->mc_count >= IOH_GBE_MAR_ENTRIES) {
+			/* all the multicasting receive permissions */
+			rctl |= IOH_GBE_ADD_FIL_EN;
+			rctl &= ~IOH_GBE_MLT_FIL_EN;
+		} else {
+			rctl |= (IOH_GBE_ADD_FIL_EN | IOH_GBE_MLT_FIL_EN);
+		}
+	}
+	IOH_GBE_WRITE_REG(hw, RX_MODE, rctl);
+
+	if (netdev->mc_count >= IOH_GBE_MAR_ENTRIES)
+		return;
+	mta_list = kmalloc(netdev->mc_count * ETH_ALEN, GFP_ATOMIC);
+	if (!mta_list)
+		return;
+	/* The shared function expects a packed array of only addresses. */
+	mc_ptr = netdev->mc_list;
+
+	for (i = 0; i < netdev->mc_count; i++) {
+		if (!mc_ptr)
+			break;
+		memcpy(mta_list + (i * ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
+		mc_ptr = mc_ptr->next;
+	}
+
+	ioh_gbe_hal_mc_addr_list_update(hw, mta_list, i, 1,
+					mac->mar_entry_count);
+	kfree(mta_list);
+
+	IOH_GBE_TESTOUT
+	("RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x  "
+	 "netdev->mc_count : 0x%08x\n",
+	 IOH_GBE_READ_REG(hw, RX_MODE), netdev->mc_count);
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int ioh_gbe_set_mac(struct net_device *netdev, void *addr)
+ * @brief   Change the Ethernet Address of the NIC
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   addr   [IN] Pointer to an address structure
+ * @return  IOH_GBE_SUCCESS: Successfully
+ * @return  -EADDRNOTAVAIL:  Failed
+ */
+static int ioh_gbe_set_mac(struct net_device *netdev, void *addr)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct sockaddr *skaddr = addr;
+	int ret_val;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	if (!is_valid_ether_addr(skaddr->sa_data)) {
+		ret_val = -EADDRNOTAVAIL;
+	} else {
+		memcpy(netdev->dev_addr, skaddr->sa_data, netdev->addr_len);
+		memcpy(adapter->hw.mac.addr, skaddr->sa_data, netdev->addr_len);
+		ioh_gbe_hal_mar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+		ret_val = IOH_GBE_SUCCESS;
+	}
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("ret_val : 0x%08x\n", ret_val);
+	IOH_GBE_TESTOUT("dev_addr : %02x:%02x:%02x:%02x:%02x:%02x\n",
+			netdev->dev_addr[0], netdev->dev_addr[1],
+			netdev->dev_addr[2], netdev->dev_addr[3],
+			netdev->dev_addr[4], netdev->dev_addr[5]);
+	IOH_GBE_TESTOUT("mac_addr : %02x:%02x:%02x:%02x:%02x:%02x\n",
+			adapter->hw.mac.addr[0], adapter->hw.mac.addr[1],
+			adapter->hw.mac.addr[2], adapter->hw.mac.addr[3],
+			adapter->hw.mac.addr[4], adapter->hw.mac.addr[5]);
+	IOH_GBE_TESTOUT("MAC_ADR1AB reg : 0x%08x 0x%08x\n",
+			IOH_GBE_READ_REG(&adapter->hw, MAC_ADR1A),
+			IOH_GBE_READ_REG(&adapter->hw, MAC_ADR1B));
+#endif
+	return ret_val;
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int ioh_gbe_change_mtu(struct net_device *netdev,
+ *                                        int new_mtu)
+ * @brief   Change the Maximum Transfer Unit
+ * @param   netdev  [INOUT] Network interface device structure
+ * @param   new_mtu [IN] New value for maximum frame size
+ * @return  IOH_GBE_SUCCESS: Successfully
+ * @return  -EINVAL:  Failed
+ */
+static int ioh_gbe_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	int max_frame;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+		(max_frame > IOH_GBE_MAX_JUMBO_FRAME_SIZE)) {
+		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
+		return -EINVAL;
+	}
+	if (max_frame <= IOH_GBE_FRAME_SIZE_2048)
+		adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_2048;
+	else if (max_frame <= IOH_GBE_FRAME_SIZE_4096)
+		adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_4096;
+	else if (max_frame <= IOH_GBE_FRAME_SIZE_8192)
+		adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_8192;
+	else
+		adapter->rx_buffer_len = IOH_GBE_MAX_JUMBO_FRAME_SIZE;
+	netdev->mtu = new_mtu;
+	adapter->hw.mac.max_frame_size = max_frame;
+
+	if (netif_running(netdev) != 0)
+		ioh_gbe_reinit_locked(adapter);
+	else
+		ioh_gbe_reset(adapter);
+
+	IOH_GBE_TESTOUT
+	("max_frame : %d  rx_buffer_len : %d  mtu : %d  max_frame_size : %d\n",
+	 max_frame, (u32) adapter->rx_buffer_len, netdev->mtu,
+	 adapter->hw.mac.max_frame_size);
+
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int ioh_gbe_ioctl(struct net_device *netdev,
+ *                                   struct ifreq *ifr, int cmd)
+ * @brief   Controls register through a MII interface
+ * @param   netdev   [INOUT] Network interface device structure
+ * @param   ifr      [IN] Pointer to ifr structure
+ * @param   cmd      [IN] Control command
+ * @return  IOH_GBE_SUCCESS: Successfully
+ * @return  Negative value:  Failed
+ */
+static int ioh_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	IOH_GBE_TESTOUT("cmd : 0x%04x\n", cmd);
+
+	return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static void ioh_gbe_tx_timeout(struct net_device *netdev)
+ * @brief   Respond to a Tx Hang
+ * @param   netdev   [INOUT] Network interface device structure
+ * @return  None
+ */
+static void ioh_gbe_tx_timeout(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(TX_ERR, DEBUG, "\n");
+
+	/* Do the reset outside of interrupt context */
+	adapter->stats.tx_timeout_count++;
+	schedule_work(&adapter->reset_task);
+}
+
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static int ioh_gbe_napi_poll(struct napi_struct *napi, int budget)
+ * @brief   NAPI receive and transfer polling callback
+ * @param   napi    [INOUT] Pointer of polling device struct
+ * @param   budget  [IN] The maximum number of a packet
+ * @return  0 : Exit the polling mode
+ * @return  1 : Continue the polling mode
+ */
+static int ioh_gbe_napi_poll(struct napi_struct *napi, int budget)
+{
+	struct ioh_gbe_adapter *adapter =
+	    container_of(napi, struct ioh_gbe_adapter, napi);
+	struct net_device *netdev = adapter->netdev;
+	int work_done = 0;
+	int poll_end_flag = 0;
+	int cleaned = 0;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	IOH_GBE_TESTOUT("budget : %d\n", budget);
+
+	/* Keep link state information with original netdev */
+	if (!netif_carrier_ok(netdev)) {
+		poll_end_flag = 1;
+	} else {
+		cleaned = ioh_gbe_clean_tx(adapter, adapter->tx_ring);
+		ioh_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
+
+		if (cleaned)
+			work_done = budget;
+		/* If no Tx and not enough Rx work done,
+		 * exit the polling mode
+		 */
+		if ((work_done < budget) || !netif_running(netdev))
+			poll_end_flag = 1;
+	}
+
+	if (poll_end_flag == 1) {
+		napi_complete(napi);
+		ioh_gbe_irq_enable(adapter);
+	}
+
+	IOH_GBE_TESTOUT("poll_end_flag : %d  work_done : %d  budget : %d\n",
+			poll_end_flag, work_done, budget);
+	return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*!
+ * @ingroup Gigabit Ethernet driver methods
+ * @fn      static void ioh_gbe_netpoll(struct net_device *netdev)
+ * @brief   Used by things like netconsole to send skbs
+ * @param   netdev  [INOUT] Network interface device structure
+ * @return  None
+ * @remarks
+ *   used by things like netconsole to send skbs
+ *   without having to re-enable interrupts.
+ *   It's not called while the interrupt routine is executing.
+ */
+static void ioh_gbe_netpoll(struct net_device *netdev)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	disable_irq(adapter->pdev->irq);
+	ioh_gbe_intr(adapter->pdev->irq, netdev);
+	enable_irq(adapter->pdev->irq);
+}
+#endif
+
+/* ----------------------------------------------------------------------------
+	Linux driver internal function
+---------------------------------------------------------------------------- */
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static int ioh_gbe_sw_init(struct ioh_gbe_adapter *adapter)
+ * @brief   Initialize general software structures (struct ioh_gbe_adapter)
+ * @param   adapter  [INOUT] Board private structure to initialize
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *   ioh_gbe_sw_init initializes the Adapter private data structure.
+ *   Fields are initialized based on PCI device information and
+ *   OS network device settings (MTU size).
+ */
+static int ioh_gbe_sw_init(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	/* PCI config space info */
+	hw->vendor_id = pdev->vendor;
+	hw->device_id = pdev->device;
+	hw->subsystem_vendor_id = pdev->subsystem_vendor;
+	hw->subsystem_device_id = pdev->subsystem_device;
+
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
+
+	adapter->rx_buffer_len = IOH_GBE_FRAME_SIZE_2048;
+	hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+	hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+
+	/* Initialize the hardware-specific values */
+	if (ioh_gbe_hal_setup_init_funcs(hw) != 0) {
+		DPRINTK(PROBE, ERR, "Hardware Initialization Failure\n");
+		return -EIO;
+	}
+	if (ioh_gbe_alloc_queues(adapter) != 0) {
+		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+		return -ENOMEM;
+	}
+	dev_hold(adapter->polling_netdev);
+	set_bit(__LINK_STATE_START, &adapter->polling_netdev->state);
+
+	spin_lock_init(&adapter->hw.miim_lock);
+	spin_lock_init(&adapter->stats_lock);
+	atomic_set(&adapter->irq_sem, 0);
+	ioh_gbe_irq_disable(adapter);
+
+	ioh_gbe_init_stats(adapter);
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("hw->vendor_id : 0x%08x\n", hw->vendor_id);
+	IOH_GBE_TESTOUT("hw->device_id : 0x%08x\n", hw->device_id);
+	IOH_GBE_TESTOUT("hw->subsystem_vendor_id :0x%08x\n",
+			hw->subsystem_vendor_id);
+	IOH_GBE_TESTOUT("hw->subsystem_device_id :0x%08x\n",
+			hw->subsystem_device_id);
+	IOH_GBE_TESTOUT("hw->revision_id :0x%08x\n", hw->revision_id);
+	IOH_GBE_TESTOUT("adapter->rx_buffer_len : %d\n",
+			(u32) adapter->rx_buffer_len);
+	IOH_GBE_TESTOUT("hw->mac.max_frame_size : %d\n",
+			hw->mac.max_frame_size);
+	IOH_GBE_TESTOUT("hw->mac.min_frame_size : %d\n",
+			hw->mac.min_frame_size);
+#endif
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static int ioh_gbe_alloc_queues(struct ioh_gbe_adapter *adapter)
+ * @brief   Allocate memory for all rings
+ * @param   adapter  [INOUT] Board private structure to initialize
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *   We allocate one ring per queue at run-time since we don't know the
+ *   number of queues at compile-time.  The polling_netdev array is
+ *   intended for Multiqueue, but should work fine with a single queue.
+ */
+static int ioh_gbe_alloc_queues(struct ioh_gbe_adapter *adapter)
+{
+	int size;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	size = (int)sizeof(struct ioh_gbe_tx_ring);
+	adapter->tx_ring = kmalloc(size, GFP_KERNEL);
+	if (!adapter->tx_ring)
+		return -ENOMEM;
+	memset(adapter->tx_ring, 0, size);
+
+	size = (int)sizeof(struct ioh_gbe_rx_ring);
+	adapter->rx_ring = kmalloc(size, GFP_KERNEL);
+	if (!adapter->rx_ring) {
+		kfree(adapter->tx_ring);
+		return -ENOMEM;
+	}
+	memset(adapter->rx_ring, 0, size);
+
+	size = (int)sizeof(struct net_device);
+	adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
+	if (!adapter->polling_netdev) {
+		kfree(adapter->tx_ring);
+		kfree(adapter->rx_ring);
+		return -ENOMEM;
+	}
+	memset(adapter->polling_netdev, 0, size);
+
+#ifdef DEBUG_TEST
+	{
+		u32 *st_area, *sp_area;
+		st_area = (u32 *) adapter->tx_ring;
+		sp_area = (u32 *) (adapter->tx_ring +
+			(int)sizeof(struct ioh_gbe_tx_ring) - 1);
+		IOH_GBE_TESTOUT("tx_ring : 0x%08x - 0x%08x\n", *st_area,
+				*sp_area);
+		st_area = (u32 *) adapter->rx_ring;
+		sp_area = (u32 *) (adapter->rx_ring +
+			(int)sizeof(struct ioh_gbe_rx_ring) - 1);
+		IOH_GBE_TESTOUT("rx_ring : 0x%08x - 0x%08x\n", *st_area,
+				*sp_area);
+		st_area = (u32 *) adapter->polling_netdev;
+		sp_area = (u32 *) (adapter->polling_netdev +
+			(int)sizeof(struct net_device) - 1);
+		IOH_GBE_TESTOUT("polling_netdev : 0x%08x - 0x%08x\n",
+				*st_area, *sp_area);
+	}
+#endif
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_init_stats(struct ioh_gbe_adapter *adapter)
+ * @brief   Initialize status
+ * @param   adapter  [INOUT] Board private structure to initialize
+ * @return  None
+ */
+static void ioh_gbe_init_stats(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw_stats *stats = &adapter->stats;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	stats->rx_packets = 0;
+	stats->tx_packets = 0;
+	stats->rx_bytes = 0;
+	stats->tx_bytes = 0;
+	stats->rx_errors = 0;
+	stats->tx_errors = 0;
+	stats->rx_dropped = 0;
+	stats->tx_dropped = 0;
+	stats->multicast = 0;
+	stats->collisions = 0;
+	stats->rx_crc_errors = 0;
+	stats->rx_frame_errors = 0;
+	stats->rx_alloc_buff_failed = 0;
+	stats->tx_length_errors = 0;
+	stats->tx_aborted_errors = 0;
+	stats->tx_carrier_errors = 0;
+	stats->tx_timeout_count = 0;
+	stats->tx_restart_count = 0;
+	stats->intr_rx_dsc_empty_count = 0;
+	stats->intr_rx_frame_err_count = 0;
+	stats->intr_rx_fifo_err_count = 0;
+	stats->intr_rx_dma_err_count = 0;
+	stats->intr_tx_fifo_err_count = 0;
+	stats->intr_tx_dma_err_count = 0;
+	stats->intr_tcpip_err_count = 0;
+	return;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static int ioh_gbe_init_nvm(struct ioh_gbe_adapter *adapter)
+ * @brief   Initialize NVM
+ * @param   adapter  [INOUT] Board private structure to initialize
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ */
+static int ioh_gbe_init_nvm(struct ioh_gbe_adapter *adapter)
+{
+	DPRINTK(PROBE, DEBUG, "\n");
+
+#ifdef CONFIG_PCH_PCIEQOS
+	/* make sure the NVM is good */
+	if ((ioh_gbe_hal_validate_nvm_checksum(&adapter->hw) < 0)) {
+		DPRINTK(PROBE, ERR, "The NVM Checksum Is Not Valid\n");
+		return -EIO;
+	}
+#endif
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static int ioh_gbe_init_phy(struct ioh_gbe_adapter *adapter)
+ * @brief   Initialize PHY
+ * @param   adapter  [INOUT] Board private structure to initialize
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ */
+static int ioh_gbe_init_phy(struct ioh_gbe_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	u32 addr;
+	u16 bmcr, stat;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	/* Discover phy addr by searching addrs in order {1,0,2,..., 31} */
+	for (addr = 0; addr <= PHY_MAX_REG_ADDRESS; addr++) {
+		adapter->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr;
+		bmcr = ioh_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMCR);
+		stat = ioh_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);
+		stat = ioh_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR);
+		if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
+			break;
+	}
+	adapter->hw.phy.addr = adapter->mii.phy_id;
+	DPRINTK(PROBE, DEBUG, "phy_addr = %d\n", adapter->mii.phy_id);
+	if (addr == 32)
+		return -EAGAIN;
+	/* Selected the phy and isolate the rest */
+	for (addr = 0; addr <= PHY_MAX_REG_ADDRESS; addr++) {
+		if (addr != adapter->mii.phy_id) {
+			ioh_gbe_mdio_write(netdev, addr, MII_BMCR,
+						BMCR_ISOLATE);
+		} else {
+			bmcr = ioh_gbe_mdio_read(netdev, addr, MII_BMCR);
+			ioh_gbe_mdio_write(netdev, addr, MII_BMCR,
+						bmcr & ~BMCR_ISOLATE);
+		}
+	}
+
+	/* MII setup */
+	adapter->mii.phy_id_mask = 0x1F;
+	adapter->mii.reg_num_mask = 0x1F;
+	adapter->mii.dev = adapter->netdev;
+	adapter->mii.mdio_read = ioh_gbe_mdio_read;
+	adapter->mii.mdio_write = ioh_gbe_mdio_write;
+	adapter->mii.supports_gmii = mii_check_gmii_support(&adapter->mii);
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      int ioh_gbe_mdio_read(struct net_device *netdev, int addr, int reg)
+ * @brief   The read function for mii
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   addr   [IN] Phy ID
+ * @param   reg    [IN] Access location
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+int ioh_gbe_mdio_read(struct net_device *netdev, int addr, int reg)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+
+	IOH_GBE_DBGOUT2("ioh_gbe_mdio_read\n");
+	return ioh_gbe_hal_ctrl_miim(hw, addr, IOH_GBE_HAL_MIIM_READ,
+					reg, (u16) 0);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_mdio_write(struct net_device *netdev,
+ *                                  int addr, int reg, int data)
+ * @brief   TThe write function for mii
+ * @param   netdev [INOUT] Network interface device structure
+ * @param   addr   [IN] Phy ID (not used)
+ * @param   reg    [IN]Access location
+ * @param   data   [IN] Write data
+ * @return  None
+ */
+void ioh_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data)
+{
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+
+	IOH_GBE_DBGOUT2("ioh_gbe_mdio_write\n");
+	ioh_gbe_hal_ctrl_miim(hw, addr, IOH_GBE_HAL_MIIM_WRITE, reg, data);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_reset_task(struct work_struct *work)
+ * @brief   Reset processing at the time of transmission timeout
+ * @param   work  [INOUT] Pointer of board private structure
+ * @return  None
+ */
+static void ioh_gbe_reset_task(struct work_struct *work)
+{
+	struct ioh_gbe_adapter *adapter;
+	adapter = container_of(work, struct ioh_gbe_adapter, reset_task);
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	ioh_gbe_reinit_locked(adapter);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_reinit_locked(struct ioh_gbe_adapter *adapter)
+ * @brief   Re-initialization
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+void ioh_gbe_reinit_locked(struct ioh_gbe_adapter *adapter)
+{
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	while ((test_and_set_bit(__IOH_GBE_RESETTING, &adapter->flags)) != 0)
+		msleep(1);
+	ioh_gbe_down(adapter);
+	ioh_gbe_up(adapter);
+	clear_bit(__IOH_GBE_RESETTING, &adapter->flags);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_reset(struct ioh_gbe_adapter *adapter)
+ * @brief   Reset GbE
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+void ioh_gbe_reset(struct ioh_gbe_adapter *adapter)
+{
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	ioh_gbe_hal_reset_hw(&adapter->hw);
+
+	if (ioh_gbe_hal_init_hw(&adapter->hw) != 0)
+		DPRINTK(PROBE, ERR, "Hardware Error\n");
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static int ioh_gbe_request_irq(struct ioh_gbe_adapter *adapter)
+ * @brief   Allocate an interrupt line
+ * @param   adapter  [INOUT] Board private structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ */
+static int ioh_gbe_request_irq(struct ioh_gbe_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int err;
+	int flags;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	flags = IRQF_SHARED;
+	adapter->have_msi = FALSE;
+	err = pci_enable_msi(adapter->pdev);
+	IOH_GBE_DBGOUT("call pci_enable_msi\n");
+	if (err != 0) {
+		DPRINTK(PROBE, ERR,
+			"Unable to allocate MSI interrupt Error: %d\n", err);
+	} else {
+		flags = 0;
+		adapter->have_msi = TRUE;
+	}
+	err = request_irq(adapter->pdev->irq, &ioh_gbe_intr,
+			  flags, netdev->name, netdev);
+	if (err != 0) {
+		DPRINTK(PROBE, ERR, "Unable to allocate interrupt Error: %d\n",
+			err);
+	}
+
+	IOH_GBE_TESTOUT
+	("adapter->have_msi : %d  flags : 0x%04x  return : 0x%04x\n",
+	adapter->have_msi, flags, err);
+	return err;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_free_irq(struct ioh_gbe_adapter *adapter)
+ * @brief   Free an interrupt
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+static void ioh_gbe_free_irq(struct ioh_gbe_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	free_irq(adapter->pdev->irq, netdev);
+	if (adapter->have_msi != 0) {
+		pci_disable_msi(adapter->pdev);
+		IOH_GBE_DBGOUT("call pci_disable_msi");
+	}
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_irq_disable(struct ioh_gbe_adapter *adapter)
+ * @brief   Mask off interrupt generation on the NIC
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+static void ioh_gbe_irq_disable(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	atomic_inc(&adapter->irq_sem);
+	IOH_GBE_WRITE_REG(hw, INT_EN, 0);
+	synchronize_irq(adapter->pdev->irq);
+
+	IOH_GBE_TESTOUT("INT_EN reg : 0x%08x\n", IOH_GBE_READ_REG(hw, INT_EN));
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_irq_enable(struct ioh_gbe_adapter *adapter)
+ * @brief   Enable default interrupt generation settings
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+static void ioh_gbe_irq_enable(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	if (likely(atomic_dec_and_test(&adapter->irq_sem)))
+		IOH_GBE_WRITE_REG(hw, INT_EN, IOH_GBE_INT_ENABLE_MASK);
+	IOH_GBE_TESTOUT("INT_EN reg : 0x%08x\n", IOH_GBE_READ_REG(hw, INT_EN));
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      int ioh_gbe_up(struct ioh_gbe_adapter *adapter)
+ * @brief   Up GbE network device
+ * @param   adapter  [INOUT] Board private structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ */
+int ioh_gbe_up(struct ioh_gbe_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct ioh_gbe_tx_ring *tx_ring = adapter->tx_ring;
+	struct ioh_gbe_rx_ring *rx_ring = adapter->rx_ring;
+	int err;
+
+	DPRINTK(IFUP, DEBUG, "\n");
+
+	/* hardware has been reset, we need to reload some things */
+	ioh_gbe_set_multi(netdev);
+
+	ioh_gbe_setup_tctl(adapter);
+	ioh_gbe_configure_tx(adapter);
+	ioh_gbe_setup_rctl(adapter);
+	ioh_gbe_configure_rx(adapter);
+
+	err = ioh_gbe_request_irq(adapter);
+	if (err != 0) {
+		IOH_GBE_ERR("Error: can't bring device up\n");
+		return err;
+	}
+	ioh_gbe_alloc_tx_buffers(adapter, tx_ring);
+	ioh_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
+	adapter->tx_queue_len = netdev->tx_queue_len;
+
+	mod_timer(&adapter->watchdog_timer, jiffies);
+
+	napi_enable(&adapter->napi);
+	ioh_gbe_irq_enable(adapter);
+	netif_start_queue(adapter->netdev);
+
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_down(struct ioh_gbe_adapter *adapter)
+ * @brief   Down GbE network device
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+void ioh_gbe_down(struct ioh_gbe_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+
+	DPRINTK(IFDOWN, DEBUG, "\n");
+
+	/* signal that we're down so the interrupt handler does not
+	 * reschedule our watchdog timer */
+	napi_disable(&adapter->napi);
+	atomic_set(&adapter->irq_sem, 0);
+
+	ioh_gbe_irq_disable(adapter);
+	ioh_gbe_free_irq(adapter);
+
+	del_timer_sync(&adapter->watchdog_timer);
+
+	netdev->tx_queue_len = adapter->tx_queue_len;
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	ioh_gbe_reset(adapter);
+	ioh_gbe_clean_tx_ring(adapter, adapter->tx_ring);
+	ioh_gbe_clean_rx_ring(adapter, adapter->rx_ring);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      int ioh_gbe_setup_tx_resources(struct ioh_gbe_adapter *adapter,
+ *                                         struct ioh_gbe_tx_ring *tx_ring)
+ * @brief   Allocate Tx resources (Descriptors)
+ * @param   adapter  [INOUT] Board private structure
+ * @param   tx_ring  [OUT] Tx descriptor ring (for a specific queue) to setup
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ */
+int
+ioh_gbe_setup_tx_resources(struct ioh_gbe_adapter *adapter,
+			   struct ioh_gbe_tx_ring *tx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	struct ioh_gbe_tx_desc *tx_desc;
+	int size;
+	int desNo;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	size = (int)sizeof(struct ioh_gbe_buffer) * tx_ring->count;
+	tx_ring->buffer_info = vmalloc(size);
+	if (!tx_ring->buffer_info) {
+		DPRINTK(PROBE, ERR,
+			"Unable to allocate memory "
+			"for the buffer infomation\n");
+		return -ENOMEM;
+	}
+	memset(tx_ring->buffer_info, 0, size);
+
+	tx_ring->size = tx_ring->count * (int)sizeof(struct ioh_gbe_tx_desc);
+
+	tx_ring->desc =
+		pci_alloc_consistent(pdev, tx_ring->size, &tx_ring->dma);
+	if (!tx_ring->desc) {
+		vfree(tx_ring->buffer_info);
+		DPRINTK(PROBE, ERR,
+			"Unable to allocate memory "
+			"for the transmit descriptor ring\n");
+		return -ENOMEM;
+	}
+	memset(tx_ring->desc, 0, tx_ring->size);
+
+	tx_ring->next_to_use = 0;
+	tx_ring->next_to_clean = 0;
+	spin_lock_init(&tx_ring->tx_lock);
+
+	for (desNo = 0; desNo < tx_ring->count; desNo++) {
+		tx_desc = IOH_GBE_TX_DESC(*tx_ring, desNo);
+		tx_desc->gbec_status = DSC_INIT16;
+	}
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("tx_ring->desc = 0x%08x  tx_ring->dma = 0x%08x\n",
+			(u32) tx_ring->desc, tx_ring->dma);
+	IOH_GBE_TESTOUT("next_to_clean = 0x%08x  next_to_use = 0x%08x\n",
+			tx_ring->next_to_clean, tx_ring->next_to_use);
+#endif
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      int ioh_gbe_setup_rx_resources(struct ioh_gbe_adapter *adapter,
+ *                                         struct ioh_gbe_rx_ring *rx_ring)
+ * @brief   Allocate Rx resources (Descriptors)
+ * @param   adapter  [INOUT] Board private structure
+ * @param   rx_ring  [OUT] Rx descriptor ring (for a specific queue) to setup
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ */
+int
+ioh_gbe_setup_rx_resources(struct ioh_gbe_adapter *adapter,
+				struct ioh_gbe_rx_ring *rx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	struct ioh_gbe_rx_desc *rx_desc;
+	int size;
+	int desNo;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	size = (int)sizeof(struct ioh_gbe_buffer) * rx_ring->count;
+	rx_ring->buffer_info = vmalloc(size);
+	if (!rx_ring->buffer_info) {
+		DPRINTK(PROBE, ERR,
+			"Unable to allocate memory "
+			"for the receive descriptor ring\n");
+		return -ENOMEM;
+	}
+	memset(rx_ring->buffer_info, 0, size);
+
+	rx_ring->size = rx_ring->count * (int)sizeof(struct ioh_gbe_rx_desc);
+
+	rx_ring->desc =
+		pci_alloc_consistent(pdev, rx_ring->size, &rx_ring->dma);
+
+	if (!rx_ring->desc) {
+		DPRINTK(PROBE, ERR,
+			"Unable to allocate memory "
+			"for the receive descriptor ring\n");
+		vfree(rx_ring->buffer_info);
+		return -ENOMEM;
+	}
+
+	memset(rx_ring->desc, 0, rx_ring->size);
+
+	rx_ring->next_to_clean = 0;
+	rx_ring->next_to_use = 0;
+
+	for (desNo = 0; desNo < rx_ring->count; desNo++) {
+		rx_desc = IOH_GBE_RX_DESC(*rx_ring, desNo);
+		rx_desc->gbec_status = DSC_INIT16;
+	}
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("rx_ring->desc = 0x%08x  rx_ring->dma = 0x%08x\n",
+			(u32) rx_ring->desc, rx_ring->dma);
+	IOH_GBE_TESTOUT("next_to_clean = 0x%08x  next_to_use = 0x%08x\n",
+			rx_ring->next_to_clean, rx_ring->next_to_use);
+#endif
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_free_tx_resources(struct ioh_gbe_adapter *adapter,
+ *                                         struct ioh_gbe_tx_ring *tx_ring)
+ * @brief   Free Tx Resources
+ * @param   adapter  [INOUT] Board private structure
+ * @param   tx_ring  [OUT] Tx descriptor ring for a specific queue
+ * @return  None
+ * @remarks
+ *    Free all transmit software resources
+ */
+void
+ioh_gbe_free_tx_resources(struct ioh_gbe_adapter *adapter,
+			  struct ioh_gbe_tx_ring *tx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	ioh_gbe_clean_tx_ring(adapter, tx_ring);
+	vfree(tx_ring->buffer_info);
+	tx_ring->buffer_info = NULL;
+	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+	tx_ring->desc = NULL;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_free_rx_resources(struct ioh_gbe_adapter *adapter,
+ *                                         struct ioh_gbe_rx_ring *rx_ring)
+ * @brief   Free Rx Resources
+ * @param   adapter  [INOUT] Board private structure
+ * @param   rx_ring  [OUT] ring to clean the resources from
+ * @return  None
+ * @remarks
+ *   Free all receive software resources
+ */
+void
+ioh_gbe_free_rx_resources(struct ioh_gbe_adapter *adapter,
+			  struct ioh_gbe_rx_ring *rx_ring)
+{
+	struct pci_dev *pdev = adapter->pdev;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	ioh_gbe_clean_rx_ring(adapter, rx_ring);
+	vfree(rx_ring->buffer_info);
+	rx_ring->buffer_info = NULL;
+	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+	rx_ring->desc = NULL;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_setup_tctl(struct ioh_gbe_adapter *adapter)
+ * @brief   configure the Transmit control registers
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+static void ioh_gbe_setup_tctl(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 tx_mode, tcpip;
+
+	DPRINTK(IFUP, DEBUG, "\n");
+
+	tx_mode = IOH_GBE_TM_LONG_PKT |
+		IOH_GBE_TM_ST_AND_FD |
+		IOH_GBE_TM_SHORT_PKT |
+		IOH_GBE_TM_TH_TX_STRT_8 |
+		IOH_GBE_TM_TH_ALM_EMP_4 | IOH_GBE_TM_TH_ALM_FULL_8;
+
+	IOH_GBE_WRITE_REG(hw, TX_MODE, tx_mode);
+
+	tcpip = IOH_GBE_READ_REG(hw, TCPIP_ACC);
+	tcpip |= IOH_GBE_TX_TCPIPACC_EN;
+	IOH_GBE_WRITE_REG(hw, TCPIP_ACC, tcpip);
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("TX_MODE reg = 0x%08x  TCPIP_ACC reg = 0x%08x\n",
+			IOH_GBE_READ_REG(hw, TX_MODE),
+			IOH_GBE_READ_REG(hw, TCPIP_ACC));
+#endif
+	return;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_configure_tx(struct ioh_gbe_adapter *adapter)
+ * @brief   Configure Transmit Unit after Reset
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ * @remarks
+ *   Configure the Tx unit of the MAC after a reset.
+ */
+static void ioh_gbe_configure_tx(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 tdba, tdlen, dctrl;
+
+	DPRINTK(IFUP, DEBUG, "\n");
+	IOH_GBE_TESTOUT("dma adr = 0x%08x  size = 0x%08x\n",
+			adapter->tx_ring->dma, adapter->tx_ring->size);
+
+	/* Setup the HW Tx Head and Tail descriptor pointers */
+	tdba = adapter->tx_ring->dma;
+	tdlen = adapter->tx_ring->size - 0x10;
+	IOH_GBE_WRITE_REG(hw, TX_DSC_BASE, tdba);
+	IOH_GBE_WRITE_REG(hw, TX_DSC_SIZE, tdlen);
+	IOH_GBE_WRITE_REG(hw, TX_DSC_SW_P, tdba);
+
+	/* Enables Transmission DMA */
+	dctrl = IOH_GBE_READ_REG(hw, DMA_CTRL);
+	dctrl |= IOH_GBE_TX_DMA_EN;
+	IOH_GBE_WRITE_REG(hw, DMA_CTRL, dctrl);
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT
+	("BASE = 0x%08x  HW_P = 0x%08x  SIZE = 0x%08x  SW_P = 0x%08x\n",
+	IOH_GBE_READ_REG(hw, TX_DSC_BASE),
+	IOH_GBE_READ_REG(hw, TX_DSC_HW_P),
+	IOH_GBE_READ_REG(hw, TX_DSC_SIZE),
+	IOH_GBE_READ_REG(hw, TX_DSC_SW_P));
+	IOH_GBE_TESTOUT("DMA_CTRL reg[bit0] = 0x%08x\n",
+			IOH_GBE_READ_REG(hw, DMA_CTRL));
+#endif
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_setup_rctl(struct ioh_gbe_adapter *adapter)
+ * @brief   Configure the receive control registers
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ * @remarks
+ *   Configure the Tx unit of the MAC after a reset.
+ */
+static void ioh_gbe_setup_rctl(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 rx_mode, tcpip;
+
+	DPRINTK(IFUP, DEBUG, "\n");
+
+	rx_mode = IOH_GBE_ADD_FIL_EN | IOH_GBE_MLT_FIL_EN |
+	IOH_GBE_RH_ALM_EMP_4 | IOH_GBE_RH_ALM_FULL_4 | IOH_GBE_RH_RD_TRG_8;
+
+	IOH_GBE_WRITE_REG(hw, RX_MODE, rx_mode);
+
+	tcpip = IOH_GBE_READ_REG(hw, TCPIP_ACC);
+
+	if (adapter->rx_csum == TRUE) {
+		tcpip &= ~IOH_GBE_RX_TCPIPACC_OFF;
+		tcpip |= IOH_GBE_RX_TCPIPACC_EN;
+	} else {
+		tcpip |= IOH_GBE_RX_TCPIPACC_OFF;
+		tcpip &= ~IOH_GBE_RX_TCPIPACC_EN;
+	}
+	IOH_GBE_WRITE_REG(hw, TCPIP_ACC, tcpip);
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("RX_MODE reg = 0x%08x  TCPIP_ACC reg = 0x%08x\n",
+			IOH_GBE_READ_REG(hw, RX_MODE),
+			IOH_GBE_READ_REG(hw, TCPIP_ACC));
+#endif
+	return;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_configure_rx(struct ioh_gbe_adapter *adapter)
+ * @brief   Configure Receive Unit after Reset
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ * @remarks
+ *   Configure the Rx unit of the MAC after a reset.
+ */
+static void ioh_gbe_configure_rx(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 rdba, rdlen, rctl, rxdma;
+
+	DPRINTK(IFUP, DEBUG, "\n");
+	IOH_GBE_TESTOUT("dma adr = 0x%08x  size = 0x%08x\n",
+			adapter->rx_ring->dma, adapter->rx_ring->size);
+
+	ioh_gbe_hal_force_mac_fc(hw);
+
+	/* Disables Receive MAC */
+	rctl = IOH_GBE_READ_REG(hw, MAC_RX_EN);
+	IOH_GBE_WRITE_REG(hw, MAC_RX_EN, (rctl & ~IOH_GBE_MRE_MAC_RX_EN));
+
+	/* Disables Receive DMA */
+	rxdma = IOH_GBE_READ_REG(hw, DMA_CTRL);
+	rxdma &= ~IOH_GBE_RX_DMA_EN;
+	IOH_GBE_WRITE_REG(hw, DMA_CTRL, rxdma);
+
+	IOH_GBE_TESTOUT("MAC_RX_EN reg = 0x%08x  DMA_CTRL reg = 0x%08x\n",
+			IOH_GBE_READ_REG(hw, MAC_RX_EN),
+			IOH_GBE_READ_REG(hw, DMA_CTRL));
+
+	/* Setup the HW Rx Head and Tail Descriptor Pointers and
+	 * the Base and Length of the Rx Descriptor Ring */
+	rdba = adapter->rx_ring->dma;
+	rdlen = adapter->rx_ring->size - 0x10;
+	IOH_GBE_WRITE_REG(hw, RX_DSC_BASE, rdba);
+	IOH_GBE_WRITE_REG(hw, RX_DSC_SIZE, rdlen);
+	IOH_GBE_WRITE_REG(hw, RX_DSC_SW_P, rdba + rdlen);
+
+	/* Enables Receive DMA */
+	rxdma = IOH_GBE_READ_REG(hw, DMA_CTRL);
+	rxdma |= IOH_GBE_RX_DMA_EN;
+	IOH_GBE_WRITE_REG(hw, DMA_CTRL, rxdma);
+	/* Enables Receive */
+	IOH_GBE_WRITE_REG(hw, MAC_RX_EN, IOH_GBE_MRE_MAC_RX_EN);
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT
+	("BASE = 0x%08x  HW_P = 0x%08x  SIZE = 0x%08x  SW_P = 0x%08x\n",
+	IOH_GBE_READ_REG(hw, RX_DSC_BASE),
+	IOH_GBE_READ_REG(hw, RX_DSC_HW_P),
+	IOH_GBE_READ_REG(hw, RX_DSC_SIZE),
+	IOH_GBE_READ_REG(hw, RX_DSC_SW_P));
+	IOH_GBE_TESTOUT("MAC_RX_EN reg = 0x%08x  DMA_CTRL reg = 0x%08x\n",
+			IOH_GBE_READ_REG(hw, MAC_RX_EN),
+			IOH_GBE_READ_REG(hw, DMA_CTRL));
+#endif
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_unmap_and_free_tx_resource(
+ *                                          struct ioh_gbe_adapter *adapter,
+ *                                          struct ioh_gbe_buffer *buffer_info)
+ * @brief   Unmap and free tx socket buffer
+ * @param   adapter     [INOUT] Board private structure
+ * @param   buffer_info [OUT] Buffer information structure
+ * @return  None
+ */
+static void
+ioh_gbe_unmap_and_free_tx_resource(struct ioh_gbe_adapter *adapter,
+					struct ioh_gbe_buffer *buffer_info)
+{
+	IOH_GBE_DBGOUT2("ioh_gbe_unmap_and_free_tx_resource\n");
+
+	if (buffer_info->dma != 0) {
+		pci_unmap_page(adapter->pdev, buffer_info->dma,
+				buffer_info->length, PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
+	if (buffer_info->skb != 0) {
+		dev_kfree_skb_any(buffer_info->skb);
+		buffer_info->skb = NULL;
+	}
+	if (buffer_info->kernel_skb != 0) {
+		dev_kfree_skb_any(buffer_info->kernel_skb);
+		buffer_info->kernel_skb = NULL;
+	}
+	IOH_GBE_TESTOUT2
+		("buffer_info->dma : 0x%08x  buffer_info->skb : 0x%08x\n",
+		buffer_info->dma, buffer_info->skb);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_unmap_and_free_rx_resource(
+ *                                          struct ioh_gbe_adapter *adapter,
+ *                                          struct ioh_gbe_buffer *buffer_info)
+ * @brief   Unmap and free rx socket buffer
+ * @param   adapter      [INOUT] Board private structure
+ * @param   buffer_info  [OUT] Buffer information structure
+ * @return  None
+ */
+static void
+ioh_gbe_unmap_and_free_rx_resource(struct ioh_gbe_adapter *adapter,
+				   struct ioh_gbe_buffer *buffer_info)
+{
+	IOH_GBE_DBGOUT2("ioh_gbe_unmap_and_free_rx_resource\n");
+
+	if (buffer_info->dma != 0) {
+		pci_unmap_single(adapter->pdev, buffer_info->dma,
+				 buffer_info->length, PCI_DMA_FROMDEVICE);
+		buffer_info->dma = 0;
+	}
+	if (buffer_info->skb != 0) {
+		dev_kfree_skb_any(buffer_info->skb);
+		buffer_info->skb = NULL;
+	}
+	IOH_GBE_TESTOUT2
+		("buffer_info->dma : 0x%08x  buffer_info->skb : 0x%08x\n",
+		buffer_info->dma, buffer_info->skb);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_clean_tx_ring(struct ioh_gbe_adapter *adapter,
+ *                                            struct ioh_gbe_tx_ring *tx_ring)
+ * @brief   Free Tx Buffers
+ * @param   adapter  [INOUT] Board private structure
+ * @param   tx_ring  [OUT] Ring to be cleaned
+ * @return  None
+ */
+static void
+ioh_gbe_clean_tx_ring(struct ioh_gbe_adapter *adapter,
+			struct ioh_gbe_tx_ring *tx_ring)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	struct ioh_gbe_buffer *buffer_info;
+	unsigned long size;
+	unsigned int i;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	/* Free all the Tx ring sk_buffs */
+	for (i = 0; i < tx_ring->count; i++) {
+		buffer_info = &tx_ring->buffer_info[i];
+		ioh_gbe_unmap_and_free_tx_resource(adapter, buffer_info);
+	}
+	IOH_GBE_TESTOUT("call ioh_gbe_unmap_and_free_tx_resource() %d count\n",
+			i);
+
+	size = (unsigned long)sizeof(struct ioh_gbe_buffer) * tx_ring->count;
+	memset(tx_ring->buffer_info, 0, size);
+
+	/* Zero out the descriptor ring */
+	memset(tx_ring->desc, 0, tx_ring->size);
+
+	tx_ring->next_to_use = 0;
+	tx_ring->next_to_clean = 0;
+
+	IOH_GBE_WRITE_REG(hw, TX_DSC_HW_P, tx_ring->dma);
+	IOH_GBE_WRITE_REG(hw, TX_DSC_SIZE, (tx_ring->size - 0x10));
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("next_to_use : %d  next_to_clean : %d\n",
+			tx_ring->next_to_use, tx_ring->next_to_clean);
+	IOH_GBE_TESTOUT("TX_DSC_HW_P reg : 0x%08x  TX_DSC_SIZE reg : 0x%08x\n",
+			IOH_GBE_READ_REG(hw, TX_DSC_HW_P),
+			IOH_GBE_READ_REG(hw, TX_DSC_SIZE));
+#endif
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_clean_rx_ring(struct ioh_gbe_adapter *adapter,
+ *                                            struct ioh_gbe_rx_ring *rx_ring)
+ * @brief   Free Rx Buffers
+ * @param   adapter  [INOUT] Board private structure
+ * @param   rx_ring  [OUT] Ring to free buffers from
+ * @return  None
+ */
+static void
+ioh_gbe_clean_rx_ring(struct ioh_gbe_adapter *adapter,
+		      struct ioh_gbe_rx_ring *rx_ring)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	struct ioh_gbe_buffer *buffer_info;
+	unsigned long size;
+	unsigned int i;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	/* Free all the Rx ring sk_buffs */
+	for (i = 0; i < rx_ring->count; i++) {
+		buffer_info = &rx_ring->buffer_info[i];
+		ioh_gbe_unmap_and_free_rx_resource(adapter, buffer_info);
+	}
+	IOH_GBE_TESTOUT("call ioh_gbe_unmap_and_free_rx_resource() %d count\n",
+			i);
+
+	size = (unsigned long)sizeof(struct ioh_gbe_buffer) * rx_ring->count;
+	memset(rx_ring->buffer_info, 0, size);
+
+	/* Zero out the descriptor ring */
+	memset(rx_ring->desc, 0, rx_ring->size);
+
+	rx_ring->next_to_clean = 0;
+	rx_ring->next_to_use = 0;
+
+	IOH_GBE_WRITE_REG(hw, RX_DSC_HW_P, rx_ring->dma);
+	IOH_GBE_WRITE_REG(hw, RX_DSC_SIZE, (rx_ring->size - 0x10));
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("next_to_use : %d  next_to_clean : %d\n",
+			rx_ring->next_to_use, rx_ring->next_to_clean);
+	IOH_GBE_TESTOUT("RX_DSC_HW_P reg : 0x%08x  RX_DSC_SIZE reg : 0x%08x\n",
+			IOH_GBE_READ_REG(hw, RX_DSC_HW_P),
+			IOH_GBE_READ_REG(hw, RX_DSC_SIZE));
+#endif
+}
+
+static void
+ioh_gbe_set_rgmii_ctrl(struct ioh_gbe_adapter *adapter, u16 speed, u16 duplex)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	unsigned long rgmii = 0;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	/* Set the RGMII control. */
+#ifdef IOH_GBE_MAC_IFOP_RGMII
+	switch (speed) {
+	case SPEED_10:
+		rgmii = (IOH_GBE_RGMII_RATE_2_5M |
+			 IOH_GBE_MAC_RGMII_CTRL_SETTING);
+		break;
+	case SPEED_100:
+		rgmii = (IOH_GBE_RGMII_RATE_25M |
+			 IOH_GBE_MAC_RGMII_CTRL_SETTING);
+		break;
+	case SPEED_1000:
+		rgmii = (IOH_GBE_RGMII_RATE_125M |
+			 IOH_GBE_MAC_RGMII_CTRL_SETTING);
+		break;
+	}
+	IOH_GBE_WRITE_REG(hw, RGMII_CTRL, rgmii);
+#else	/* GMII */
+	rgmii = 0;
+	IOH_GBE_WRITE_REG(hw, RGMII_CTRL, rgmii);
+#endif
+}
+static void
+ioh_gbe_set_mode(struct ioh_gbe_adapter *adapter, u16 speed, u16 duplex)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	unsigned long mode = 0;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	/* Set the communication mode */
+	switch (speed) {
+	case SPEED_10:
+		mode = IOH_GBE_MODE_MII_ETHER;
+		netdev->tx_queue_len = 10;
+		break;
+	case SPEED_100:
+		mode = IOH_GBE_MODE_MII_ETHER;
+		netdev->tx_queue_len = 100;
+		break;
+	case SPEED_1000:
+		mode = IOH_GBE_MODE_GMII_ETHER;
+		break;
+	}
+	if (duplex == DUPLEX_FULL)
+		mode |= IOH_GBE_MODE_FULL_DUPLEX;
+	else
+		mode |= IOH_GBE_MODE_HALF_DUPLEX;
+	IOH_GBE_WRITE_REG(hw, MODE, mode);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_watchdog(unsigned long data)
+ * @brief   Watchdog process
+ * @param   data  [INOUT] Board private structure
+ * @return  None
+ */
+static void ioh_gbe_watchdog(unsigned long data)
+{
+	struct ioh_gbe_adapter *adapter = (struct ioh_gbe_adapter *)data;
+	struct net_device *netdev = adapter->netdev;
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	struct ethtool_cmd cmd;
+
+	DPRINTK(TIMER, DEBUG, "right now = %ld\n", jiffies);
+
+	ioh_gbe_update_stats(adapter);
+	if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {
+		netdev->tx_queue_len = adapter->tx_queue_len;
+		/* mii library handles link maintenance tasks */
+		if (mii_ethtool_gset(&adapter->mii, &cmd) != 0) {
+			DPRINTK(PROBE, ERR, "ethtool get setting Error\n");
+			mod_timer(&adapter->watchdog_timer,
+				  round_jiffies(jiffies +
+						IOH_GBE_WATCHDOG_PERIOD));
+			return;
+		}
+		hw->mac.link_speed = cmd.speed;
+		hw->mac.link_duplex = cmd.duplex;
+		/* Set the RGMII control. */
+		ioh_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
+						hw->mac.link_duplex);
+		/* Set the communication mode */
+		ioh_gbe_set_mode(adapter, hw->mac.link_speed,
+						hw->mac.link_duplex);
+		DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s-Duplex\n",
+			cmd.speed, cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
+		netif_carrier_on(netdev);
+		netif_wake_queue(netdev);
+	} else if ((!mii_link_ok(&adapter->mii)) &&
+					(netif_carrier_ok(netdev))) {
+		DPRINTK(LINK, INFO, "NIC Link is Down\n");
+		hw->mac.link_speed = SPEED_10;
+		hw->mac.link_duplex = DUPLEX_HALF;
+		netif_carrier_off(netdev);
+		netif_stop_queue(netdev);
+	}
+	mod_timer(&adapter->watchdog_timer,
+		  round_jiffies(jiffies + IOH_GBE_WATCHDOG_PERIOD));
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT
+		("RGMII_CTRL reg : 0x%08x  RGMII_ST reg : 0x%08x "
+		" MODE reg : 0x%08x\n",
+		IOH_GBE_READ_REG(hw, RGMII_CTRL),
+		IOH_GBE_READ_REG(hw, RGMII_ST),
+		IOH_GBE_READ_REG(hw, MODE));
+	IOH_GBE_TESTOUT
+		("link_speed : %d  link_duplex : %d  tx_queue_len : %d\n",
+		hw->mac.link_speed, hw->mac.link_duplex,
+		(u32) netdev->tx_queue_len);
+#endif
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_tx_queue(struct ioh_gbe_adapter *adapter,
+ *                    struct ioh_gbe_tx_ring *tx_ring, struct sk_buff *skb)
+ * @brief   Carry out queuing of the transmission data
+ * @param   adapter  [INOUT] Board private structure
+ * @param   tx_ring  [OUT] Tx descriptor ring structure
+ * @param   skb      [IN] Sockt buffer structure
+ * @return  None
+ */
+static void
+ioh_gbe_tx_queue(struct ioh_gbe_adapter *adapter,
+		 struct ioh_gbe_tx_ring *tx_ring, struct sk_buff *skb)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	struct ioh_gbe_tx_desc *tx_desc;
+	struct ioh_gbe_buffer *buffer_info;
+	struct sk_buff *tmp_skb;
+	unsigned int frame_ctrl;
+	unsigned int ring_num;
+	unsigned long flags;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	/*-- Set frame control --*/
+	frame_ctrl = 0;
+	if (unlikely(skb->len < IOH_GBE_SHORT_PKT))
+		frame_ctrl |= IOH_GBE_TXD_CTRL_APAD;
+	if (unlikely(adapter->tx_csum == FALSE))
+		frame_ctrl |= IOH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
+
+	/* Performs checksum processing */
+	/*
+	 * It is because the hardware accelerator does not support a checksum,
+	 * when the received data size is less than 64 bytes.
+	 */
+	if ((skb->len < IOH_GBE_SHORT_PKT) && (adapter->tx_csum == TRUE)) {
+		frame_ctrl |=
+			IOH_GBE_TXD_CTRL_APAD | IOH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
+		if (skb->protocol == htons(ETH_P_IP)) {
+			struct iphdr *iph = ip_hdr(skb);
+			unsigned int offset;
+			iph->check = 0;
+			iph->check = ip_fast_csum((u8 *) iph, iph->ihl);
+			offset = skb_transport_offset(skb);
+			if (iph->protocol == IPPROTO_TCP) {
+				skb->csum = 0;
+				tcp_hdr(skb)->check = 0;
+				skb->csum =
+					skb_checksum(skb, offset,
+						skb->len - offset, 0);
+				tcp_hdr(skb)->check =
+					csum_tcpudp_magic(iph->saddr,
+							iph->daddr,
+							skb->len - offset,
+							IPPROTO_TCP, skb->csum);
+			} else if (iph->protocol == IPPROTO_UDP) {
+				skb->csum = 0;
+				udp_hdr(skb)->check = 0;
+				skb->csum =
+					skb_checksum(skb, offset,
+						skb->len - offset, 0);
+				udp_hdr(skb)->check =
+					csum_tcpudp_magic(iph->saddr,
+							iph->daddr,
+							skb->len - offset,
+							IPPROTO_UDP, skb->csum);
+			}
+		}
+	}
+
+	spin_lock_irqsave(&tx_ring->tx_lock, flags);
+	ring_num = tx_ring->next_to_use;
+	if (unlikely((ring_num + 1) == tx_ring->count))
+		tx_ring->next_to_use = 0;
+	else
+		tx_ring->next_to_use = ring_num + 1;
+
+	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+	buffer_info = &tx_ring->buffer_info[ring_num];
+	tmp_skb = buffer_info->skb;
+
+	/* [Header:14][payload] ---> [Header:14][paddong:2][payload]    */
+	memcpy(tmp_skb->data, skb->data, ETH_HLEN);
+	tmp_skb->data[ETH_HLEN] = 0x00;
+	tmp_skb->data[ETH_HLEN + 1] = 0x00;
+	tmp_skb->len = skb->len;
+	memcpy(&tmp_skb->data[ETH_HLEN + 2], &skb->data[ETH_HLEN],
+	       (skb->len - ETH_HLEN));
+	buffer_info->kernel_skb = skb;
+	skb = tmp_skb;
+
+	/*-- Set Buffer infomation --*/
+	buffer_info->length = skb->len;
+	buffer_info->dma =
+	    pci_map_single(adapter->pdev, skb->data, buffer_info->length,
+			   PCI_DMA_TODEVICE);
+	buffer_info->time_stamp = jiffies;
+
+	/*-- Set Tx descriptor --*/
+	tx_desc = IOH_GBE_TX_DESC(*tx_ring, ring_num);
+	tx_desc->buffer_addr = (buffer_info->dma);
+	tx_desc->length = (skb->len);
+	tx_desc->tx_words_eob = ((skb->len + 3));
+	tx_desc->tx_frame_ctrl = (frame_ctrl);
+	tx_desc->gbec_status = (DSC_INIT16);
+
+	if (unlikely(++ring_num == tx_ring->count))
+		ring_num = 0;
+
+#ifdef DEBUG_TEST
+	{
+		unsigned char *rd_data;
+
+		rd_data = (unsigned char *)tx_desc;
+		IOH_GBE_TESTOUT
+		    ("buffer_info->dma : 0x%08x  skb->len : 0x%08x  "
+		     "frame_ctrl : 0x%08x\n",
+		     buffer_info->dma, skb->len, frame_ctrl);
+		IOH_GBE_TESTOUT
+		    ("tx_desc: \n 0x%02x 0x%02x 0x%02x 0x%02x\n 0x%02x "
+		     "0x%02x 0x%02x 0x%02x\n 0x%02x 0x%02x 0x%02x 0x%02x\n "
+		     "0x%02x 0x%02x 0x%02x 0x%02x\n",
+		     rd_data[0], rd_data[1], rd_data[2], rd_data[3], rd_data[4],
+		     rd_data[5], rd_data[6], rd_data[7], rd_data[8], rd_data[9],
+		     rd_data[10], rd_data[11], rd_data[12], rd_data[13],
+		     rd_data[14], rd_data[15]);
+	}
+#endif
+
+	/* Update software pointer of TX descriptor */
+	IOH_GBE_WRITE_REG(hw, TX_DSC_SW_P,
+			  tx_ring->dma +
+			  (int)sizeof(struct ioh_gbe_tx_desc) * ring_num);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_update_stats(struct ioh_gbe_adapter *adapter)
+ * @brief   Update the board statistics counters
+ * @param   adapter  [INOUT] Board private structure
+ * @return  None
+ */
+void ioh_gbe_update_stats(struct ioh_gbe_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	struct ioh_gbe_hw_stats *stats = &adapter->stats;
+	struct net_device_stats *net_stats = &adapter->net_stats;
+	unsigned long flags;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	/*
+	 * Prevent stats update while adapter is being reset, or if the pci
+	 * connection is down.
+	 */
+	if ((pdev->error_state) && (pdev->error_state != pci_channel_io_normal))
+		return;
+
+	spin_lock_irqsave(&adapter->stats_lock, flags);
+
+	/* Update device status "adapter->stats" */
+	stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors;
+	stats->tx_errors = stats->tx_length_errors +
+	    stats->tx_aborted_errors +
+	    stats->tx_carrier_errors + stats->tx_timeout_count;
+
+	/* Update network device status "adapter->net_stats" */
+	net_stats->rx_packets = stats->rx_packets;
+	net_stats->tx_packets = stats->tx_packets;
+	net_stats->rx_bytes = stats->rx_bytes;
+	net_stats->tx_bytes = stats->tx_bytes;
+	net_stats->rx_errors = stats->rx_errors;
+	net_stats->tx_errors = stats->tx_errors;
+	net_stats->rx_dropped = stats->rx_dropped;
+	net_stats->tx_dropped = stats->tx_dropped;
+	net_stats->multicast = stats->multicast;
+	net_stats->collisions = stats->collisions;
+	net_stats->rx_crc_errors = stats->rx_crc_errors;
+	net_stats->rx_frame_errors = stats->rx_frame_errors;
+	net_stats->tx_aborted_errors = stats->tx_aborted_errors;
+	net_stats->tx_carrier_errors = stats->tx_carrier_errors;
+
+	spin_unlock_irqrestore(&adapter->stats_lock, flags);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static irqreturn_t ioh_gbe_intr(int irq, void *data)
+ * @brief   Interrupt Handler
+ * @param   irq   [IN] Interrupt number
+ * @param   data  [INOUT] Pointer to a network interface device structure
+ * @return  None
+ */
+static irqreturn_t ioh_gbe_intr(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct ioh_gbe_adapter *adapter = netdev_priv(netdev);
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	u32 int_st;
+	u32 int_en;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	/* Check request status */
+	int_st = IOH_GBE_READ_REG(hw, INT_ST);
+	IOH_GBE_TESTOUT("int_st = 0x%08x\n", int_st);
+
+	int_st = int_st & IOH_GBE_READ_REG(hw, INT_EN);
+	/* When request status is no interruption factor */
+	if (unlikely(!int_st)) {
+		/* End processing. */
+		IOH_GBE_TESTOUT("return = 0x%08x\n", IRQ_NONE);
+		return IRQ_NONE;	/* Not our interrupt */
+	}
+	if (int_st & IOH_GBE_INT_RX_FRAME_ERR)
+		adapter->stats.intr_rx_frame_err_count++;
+	if (int_st & IOH_GBE_INT_RX_FIFO_ERR)
+		adapter->stats.intr_rx_fifo_err_count++;
+	if (int_st & IOH_GBE_INT_RX_DMA_ERR)
+		adapter->stats.intr_rx_dma_err_count++;
+	if (int_st & IOH_GBE_INT_TX_FIFO_ERR)
+		adapter->stats.intr_tx_fifo_err_count++;
+	if (int_st & IOH_GBE_INT_TX_DMA_ERR)
+		adapter->stats.intr_tx_dma_err_count++;
+	if (int_st & IOH_GBE_INT_TCPIP_ERR)
+		adapter->stats.intr_tcpip_err_count++;
+	/* When Rx descriptor is empty  */
+	if ((int_st & IOH_GBE_INT_RX_DSC_EMP) != 0) {
+		adapter->stats.intr_rx_dsc_empty_count++;
+		DPRINTK(PROBE, ERR, "Rx descriptor is empty\n");
+		int_en = IOH_GBE_READ_REG(hw, INT_EN);
+		IOH_GBE_WRITE_REG(hw, INT_EN,
+				  (int_en & ~IOH_GBE_INT_RX_DSC_EMP));
+		if (hw->mac.tx_fc_enable == TRUE) {
+			/* Set Pause packet */
+			ioh_gbe_hal_set_pause_packet(hw);
+		}
+		if ((int_en & (IOH_GBE_INT_RX_DMA_CMPLT | IOH_GBE_INT_TX_CMPLT))
+		    == 0) {
+			return IRQ_HANDLED;
+		}
+	}
+
+	/* When request status is Receive interruption */
+	if ((int_st & (IOH_GBE_INT_RX_DMA_CMPLT | IOH_GBE_INT_TX_CMPLT)) != 0) {
+		if (likely(napi_schedule_prep(&adapter->napi))) {
+			/* Enable only Rx Descriptor empty */
+			atomic_inc(&adapter->irq_sem);
+			int_en = IOH_GBE_READ_REG(hw, INT_EN);
+			int_en &=
+			    ~(IOH_GBE_INT_RX_DMA_CMPLT | IOH_GBE_INT_TX_CMPLT);
+			IOH_GBE_WRITE_REG(hw, INT_EN, int_en);
+			/* Start polling for NAPI */
+			__napi_schedule(&adapter->napi);
+		}
+	}
+	IOH_GBE_TESTOUT("return = 0x%08x  INT_EN reg = 0x%08x\n",
+			IRQ_HANDLED, IOH_GBE_READ_REG(hw, INT_EN));
+	return IRQ_HANDLED;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static unsigned char ioh_gbe_clean_tx(struct ioh_gbe_adapter *adapter,
+ *                                            struct ioh_gbe_tx_ring *tx_ring)
+ * @brief   Reclaim resources after transmit completes
+ * @param   adapter   [INOUT] Board private structure
+ * @param   tx_ring   [OUT] Tx descriptor ring
+ * @return  TRUE:  Cleaned the descriptor
+ * @return  FALSE: Not cleaned the descriptor
+ */
+static unsigned char
+ioh_gbe_clean_tx(struct ioh_gbe_adapter *adapter,
+		 struct ioh_gbe_tx_ring *tx_ring)
+{
+	struct ioh_gbe_tx_desc *tx_desc;
+	struct ioh_gbe_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	unsigned int cleaned_count = 0;
+	unsigned char cleaned = FALSE;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+	IOH_GBE_TESTOUT("next_to_clean : %d\n", tx_ring->next_to_clean);
+
+	i = tx_ring->next_to_clean;
+	tx_desc = IOH_GBE_TX_DESC(*tx_ring, i);
+	IOH_GBE_TESTOUT("gbec_status:0x%04x  dma_status:0x%04x\n",
+			tx_desc->gbec_status, tx_desc->dma_status);
+
+	while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {
+		IOH_GBE_TESTOUT("gbec_status:0x%04x\n", tx_desc->gbec_status);
+		cleaned = TRUE;
+		buffer_info = &tx_ring->buffer_info[i];
+		skb = buffer_info->skb;
+
+		if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_ABT) != 0) {
+			adapter->stats.tx_aborted_errors++;
+			DPRINTK(PROBE, ERR, "Transfer Aboat Error\n");
+		} else if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_CRSER)
+			   != 0) {
+			adapter->stats.tx_carrier_errors++;
+			DPRINTK(PROBE, ERR, "Transfer Carrier Sense Error\n");
+		} else if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_EXCOL)
+			   != 0) {
+			adapter->stats.tx_aborted_errors++;
+			DPRINTK(PROBE, ERR, "Transfer Collision Abort Error\n");
+		} else if ((tx_desc->gbec_status &
+			    (IOH_GBE_TXD_GMAC_STAT_SNGCOL |
+			     IOH_GBE_TXD_GMAC_STAT_MLTCOL)) != 0) {
+			adapter->stats.collisions++;
+			adapter->stats.tx_packets++;
+			adapter->stats.tx_bytes += skb->len;
+			DPRINTK(PROBE, DEBUG, "Transfer Collision\n");
+		} else if ((tx_desc->gbec_status & IOH_GBE_TXD_GMAC_STAT_CMPLT)
+			   != 0) {
+			adapter->stats.tx_packets++;
+			adapter->stats.tx_bytes += skb->len;
+		}
+		if (buffer_info->dma != 0) {
+			IOH_GBE_TESTOUT("unmap buffer_info->dma : %d\n", i);
+			pci_unmap_page(adapter->pdev, buffer_info->dma,
+				       buffer_info->length, PCI_DMA_TODEVICE);
+			buffer_info->dma = 0;
+		}
+		if (buffer_info->skb != 0) {
+			IOH_GBE_TESTOUT("trim buffer_info->skb : %d\n", i);
+			skb_trim(buffer_info->skb, 0);
+		}
+		if (buffer_info->kernel_skb != 0) {
+			IOH_GBE_TESTOUT
+			    ("free buffer_info->kernel_skb adr: 0x%x\n",
+			     (u32)(buffer_info->kernel_skb));
+			dev_kfree_skb(buffer_info->kernel_skb);
+			buffer_info->kernel_skb = NULL;
+		}
+		tx_desc->gbec_status = DSC_INIT16;
+		if (unlikely(++i == tx_ring->count))
+			i = 0;
+		tx_desc = IOH_GBE_TX_DESC(*tx_ring, i);
+
+		/* weight of a sort for tx, to avoid endless transmit cleanup */
+		if (cleaned_count++ == IOH_GBE_TX_WEIGHT)
+			break;
+	}
+	IOH_GBE_TESTOUT("called ioh_gbe_unmap_and_free_tx_resource() %dcount\n",
+			cleaned_count);
+	/* Recover from running out of Tx resources in xmit_frame */
+	if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) {
+		netif_wake_queue(adapter->netdev);
+		adapter->stats.tx_restart_count++;
+		DPRINTK(HW, DEBUG, "Tx wake queue\n");
+	}
+	spin_lock(&adapter->tx_queue_lock);
+	tx_ring->next_to_clean = i;
+	spin_unlock(&adapter->tx_queue_lock);
+	IOH_GBE_TESTOUT("next_to_clean : %d\n", tx_ring->next_to_clean);
+	return cleaned;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static unsigned char ioh_gbe_clean_rx(struct ioh_gbe_adapter *adapter,
+ *                                            struct ioh_gbe_rx_ring *rx_ring,
+ *                                            int *work_done, int work_to_do)
+ * @brief   Send received data up the network stack; legacy
+ * @param   adapter     [INOUT] Board private structure
+ * @param   rx_ring     [OUT] Rx descriptor ring
+ * @param   work_done   [OUT] Completed count
+ * @param   work_to_do  [IN] Request count
+ * @return  TRUE:  Cleaned the descriptor
+ * @return  FALSE: Not cleaned the descriptor
+ */
+static unsigned char
+ioh_gbe_clean_rx(struct ioh_gbe_adapter *adapter,
+		 struct ioh_gbe_rx_ring *rx_ring,
+		 int *work_done, int work_to_do)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct ioh_gbe_buffer *buffer_info;
+	struct ioh_gbe_rx_desc *rx_desc;
+	u32 length;
+	unsigned char tmp_packet[ETH_HLEN];
+	unsigned int i;
+	unsigned int cleaned_count = 0;
+	unsigned char cleaned = FALSE;
+	struct sk_buff *skb;
+	u8 dma_status;
+	u16 gbec_status;
+	u32 tcp_ip_status;
+	u8 skb_copy_flag = 0;
+	u8 skb_padding_flag = 0;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	i = rx_ring->next_to_clean;
+
+	while (*work_done < work_to_do) {
+		/* Check Rx descriptor status */
+		rx_desc = IOH_GBE_RX_DESC(*rx_ring, i);
+		if (rx_desc->gbec_status == DSC_INIT16)
+			break;
+		cleaned = TRUE;
+		cleaned_count++;
+
+		dma_status = rx_desc->dma_status;
+		gbec_status = rx_desc->gbec_status;
+		tcp_ip_status = rx_desc->tcp_ip_status;
+		rx_desc->gbec_status = DSC_INIT16;
+		buffer_info = &rx_ring->buffer_info[i];
+		skb = buffer_info->skb;
+
+		/* unmap dma */
+		pci_unmap_single(pdev, buffer_info->dma, buffer_info->length,
+				 PCI_DMA_FROMDEVICE);
+		buffer_info->dma = 0;
+		/* Prefetch the packet */
+		prefetch(skb->data);
+
+		IOH_GBE_TESTOUT
+			("RxDecNo = 0x%04x  Status[DMA:0x%02x GBE:0x%04x "
+			 "TCP:0x%08x]  BufInf = 0x%08x\n",
+			 i, dma_status, gbec_status, tcp_ip_status,
+			 (u32) (buffer_info));
+		/* Error check */
+		if (unlikely(gbec_status & IOH_GBE_RXD_GMAC_STAT_NOTOCTAL)) {
+			adapter->stats.rx_frame_errors++;
+			DPRINTK(PROBE, ERR, "Receive Not Octal Error\n");
+		} else if (unlikely(gbec_status &
+				IOH_GBE_RXD_GMAC_STAT_NBLERR)) {
+			adapter->stats.rx_frame_errors++;
+			DPRINTK(PROBE, ERR, "Receive Nibble Error\n");
+		} else if (unlikely(gbec_status &
+				IOH_GBE_RXD_GMAC_STAT_CRCERR)) {
+			adapter->stats.rx_crc_errors++;
+			DPRINTK(PROBE, ERR, "Receive CRC Error\n");
+		} else {
+			/* get receive length */
+			/* length convert[-3], padding[-2] */
+			length = (rx_desc->rx_words_eob) - 3 - 2;
+
+			/* Decide the data conversion method */
+			if (adapter->rx_csum != TRUE) {
+				/* [Header:14][payload] */
+				skb_padding_flag = 0;
+				skb_copy_flag = 1;
+			} else {
+				/* [Header:14][padding:2][payload] */
+				skb_padding_flag = 1;
+				if (length < copybreak)
+					skb_copy_flag = 1;
+				else
+					skb_copy_flag = 0;
+			}
+
+			/* Data conversion */
+			if (skb_copy_flag != 0) {	/* recycle  skb */
+				struct sk_buff *new_skb;
+				new_skb =
+				    netdev_alloc_skb(netdev,
+						     length + NET_IP_ALIGN);
+				if (new_skb != 0) {
+					if (!skb_padding_flag) {
+						skb_reserve(new_skb,
+								NET_IP_ALIGN);
+					}
+					memcpy(new_skb->data, skb->data,
+						length);
+					/* save the skb
+					 * in buffer_info as good */
+					skb = new_skb;
+				} else if (!skb_padding_flag) {
+					/* dorrop error */
+					DPRINTK(PROBE, ERR,
+						"New skb allocation Error\n");
+					goto dorrop;
+				}
+			} else {
+				buffer_info->skb = NULL;
+			}
+			if (skb_padding_flag != 0) {
+				memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN);
+				memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0],
+					ETH_HLEN);
+				skb_reserve(skb, NET_IP_ALIGN);
+
+			}
+
+			/* update status of driver */
+			adapter->stats.rx_bytes += length;
+			adapter->stats.rx_packets++;
+			if ((gbec_status & IOH_GBE_RXD_GMAC_STAT_MARMLT) != 0)
+				adapter->stats.multicast++;
+			/* Write meta date of skb */
+			skb_put(skb, length);
+			skb->protocol = eth_type_trans(skb, netdev);
+			if ((tcp_ip_status & IOH_GBE_RXD_ACC_STAT_TCPIPOK) ==
+			    IOH_GBE_RXD_ACC_STAT_TCPIPOK) {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+			} else {
+				skb->ip_summed = CHECKSUM_NONE;
+			}
+
+			if (netif_receive_skb(skb) == NET_RX_DROP) {
+				adapter->stats.rx_dropped++;
+				DPRINTK(PROBE, ERR,
+				 "Receive Netif Receive Dropped Error\n");
+			}
+			(*work_done)++;
+			netdev->last_rx = jiffies;
+			IOH_GBE_TESTOUT
+			    ("Receive skb->ip_summed: %d length: %d\n",
+			     skb->ip_summed, length);
+		}
+dorrop:
+		/* return some buffers to hardware, one at a time is too slow */
+		if (unlikely(cleaned_count >= IOH_GBE_RX_BUFFER_WRITE)) {
+			ioh_gbe_alloc_rx_buffers(adapter, rx_ring,
+						 cleaned_count);
+			cleaned_count = 0;
+		}
+		if (++i == rx_ring->count)
+			i = 0;
+	}
+	rx_ring->next_to_clean = i;
+	if (cleaned_count != 0)
+		ioh_gbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
+#ifdef DEBUG_TEST
+	{
+		u32 tmp1, tmp2, tmp3, tmp4;
+		struct ioh_gbe_hw *hw = &adapter->hw;
+
+		IOH_GBE_TESTOUT
+			("cleaned_count = %d  next_to_clean = %d  "
+			 "next_to_use = %d\n",
+			 cleaned_count, rx_ring->next_to_clean,
+			 rx_ring->next_to_use);
+		tmp1 = IOH_GBE_READ_REG(hw, RX_DSC_BASE);
+		tmp2 = IOH_GBE_READ_REG(hw, RX_DSC_HW_P);
+		tmp3 = IOH_GBE_READ_REG(hw, RX_DSC_SIZE);
+		tmp4 = IOH_GBE_READ_REG(hw, RX_DSC_SW_P);
+		IOH_GBE_TESTOUT
+			("BASE = 0x%08x  HW_P = 0x%08x  "
+			 "SIZE = 0x%08x  SW_P = 0x%08x\n",
+			 tmp1, tmp2, tmp3, tmp4);
+		tmp1 = IOH_GBE_READ_REG(hw, DMA_CTRL);
+		tmp2 = IOH_GBE_READ_REG(hw, MAC_RX_EN);
+		IOH_GBE_TESTOUT("DMA_CTRL = 0x%08x  MAC_RX_EN = 0x%08x\n", tmp1,
+				tmp2);
+		tmp1 = IOH_GBE_READ_REG(hw, RX_MODE);
+		tmp2 = IOH_GBE_READ_REG(hw, ADDR_MASK);
+		tmp3 = IOH_GBE_READ_REG(hw, MAC_ADR1A);
+		tmp4 = IOH_GBE_READ_REG(hw, MAC_ADR1B);
+		IOH_GBE_TESTOUT
+			("RX_MODE = 0x%08x  ADDR_MASK = 0x%08x  "
+			 "MAC_ADR1A = 0x%08x  MAC_ADR1B = 0x%08x\n",
+			 tmp1, tmp2, tmp3, tmp4);
+	}
+#endif
+	return cleaned;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_alloc_rx_buffers(
+ *                      struct ioh_gbe_adapter *adapter,
+ *                      struct ioh_gbe_rx_ring *rx_ring, int cleaned_count)
+ * @brief   Replace used receive buffers; legacy & extended
+ * @param   adapter       [INOUT] Board private structure
+ * @param   rx_ring       [OUT] Rx descriptor ring
+ * @param   cleaned_count [IN] Cleaned count
+ * @return  None
+ */
+static void
+ioh_gbe_alloc_rx_buffers(struct ioh_gbe_adapter *adapter,
+			 struct ioh_gbe_rx_ring *rx_ring, int cleaned_count)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	struct ioh_gbe_rx_desc *rx_desc;
+	struct ioh_gbe_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	unsigned int bufsz;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	bufsz = adapter->rx_buffer_len + IOH_GBE_DMA_ALIGN;
+	i = rx_ring->next_to_use;
+
+	while ((cleaned_count--) != 0) {
+		buffer_info = &rx_ring->buffer_info[i];
+		skb = buffer_info->skb;
+		if (skb != 0) {
+			skb_trim(skb, 0);
+		} else {
+			skb = netdev_alloc_skb(netdev, bufsz);
+			if (unlikely(!skb)) {
+				/* Better luck next round */
+				adapter->stats.rx_alloc_buff_failed++;
+				break;
+			}
+			/* 64byte align */
+			skb_reserve(skb, IOH_GBE_DMA_ALIGN);
+
+			buffer_info->skb = skb;
+			buffer_info->length = adapter->rx_buffer_len;
+		}
+
+		buffer_info->dma = pci_map_single(pdev,
+						  skb->data,
+						  buffer_info->length,
+						  PCI_DMA_FROMDEVICE);
+
+		rx_desc = IOH_GBE_RX_DESC(*rx_ring, i);
+		rx_desc->buffer_addr = (buffer_info->dma);
+		rx_desc->gbec_status = DSC_INIT16;
+
+		IOH_GBE_DBGOUT1
+			("i = %d  buffer_info->dma = 0x%x  "
+			 "buffer_info->length = 0x%x\n",
+			 i, buffer_info->dma, buffer_info->length);
+
+		if (unlikely(++i == rx_ring->count))
+			i = 0;
+	}
+	if (likely(rx_ring->next_to_use != i)) {
+		rx_ring->next_to_use = i;
+		if (unlikely(i-- == 0))
+			i = (rx_ring->count - 1);
+		wmb();
+		IOH_GBE_WRITE_REG(hw, RX_DSC_SW_P,
+				  rx_ring->dma +
+				  (int)sizeof(struct ioh_gbe_rx_desc) * i);
+	}
+	return;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_alloc_tx_buffers(
+ *                                   struct ioh_gbe_adapter *adapter,
+ *                                   struct ioh_gbe_tx_ring *tx_ring)
+ * @brief   Allocate transmit buffers
+ * @param   adapter   [INOUT] Board private structure
+ * @param   tx_ring   [OUT] Tx descriptor ring
+ * @return  None
+ */
+static void
+ioh_gbe_alloc_tx_buffers(struct ioh_gbe_adapter *adapter,
+			 struct ioh_gbe_tx_ring *tx_ring)
+{
+	struct ioh_gbe_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	unsigned int bufsz;
+	struct ioh_gbe_tx_desc *tx_desc;
+
+	DPRINTK(PROBE, DEBUG, "\n");
+
+	bufsz =
+	    adapter->hw.mac.max_frame_size + IOH_GBE_DMA_ALIGN + NET_IP_ALIGN;
+
+	for (i = 0; i < tx_ring->count; i++) {
+		buffer_info = &tx_ring->buffer_info[i];
+		skb = netdev_alloc_skb(adapter->netdev, bufsz);
+		skb_reserve(skb, IOH_GBE_DMA_ALIGN);
+		buffer_info->skb = skb;
+		tx_desc = IOH_GBE_TX_DESC(*tx_ring, i);
+		tx_desc->gbec_status = (DSC_INIT16);
+	}
+
+	return;
+}
+/* ioh_gbe_main.c */
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.c	2010-03-11 15:12:00.000000000 +0900
@@ -0,0 +1,129 @@
+/*!
+ * @file ioh_gbe_nvm.c
+ * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (NVM) source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_nvm.h"
+
+#ifdef CONFIG_PCH_PCIEQOS
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw,
+ *                                   u32 offset, u8 *data)
+ * @brief   Read EEPROM
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   offset [IN] Offset of word in the EEPROM to read
+ * @param   data   [OUT] Word read from the EEPROM
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw, u32 offset, u8 *data)
+{
+	s32 ret;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_nvm_read_mem");
+	IOH_GBE_TESTOUT("offset : 0x%04x\n", offset);
+	ret = ioh_pcieqos_read_gbe_mac_addr(offset, data);
+	return ret;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw,
+ *                                    u32 offset, u8 *data)
+ * @brief   Write EEPROM
+ * @param   hw     [INOUT] Pointer to the HW structure
+ * @param   offset [IN] Offset of word in the EEPROM to read
+ * @param   data   [IN] 8bit word(s) to be written to the EEPROM
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw, u32 offset, u8 *data)
+{
+	s32 ret;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_nvm_write_mem");
+	IOH_GBE_TESTOUT("offset : 0x%04x\n", offset);
+	ret = ioh_pcieqos_write_gbe_mac_addr(offset, *data);
+	return ret;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw)
+ * @brief   Read device MAC address
+ * @param   hw  [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw)
+{
+	s32 ret;
+	u8 i;
+	u8 *data;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_nvm_read_mac_addr");
+
+#ifdef NVM_MAC_FIX
+	hw->mac.addr[0] = (u8) (0x00);
+	hw->mac.addr[1] = (u8) (0x21);
+	hw->mac.addr[2] = (u8) (0x97);
+	hw->mac.addr[3] = (u8) (0x77);
+	hw->mac.addr[4] = (u8) (0x65);
+	hw->mac.addr[5] = (u8) (0x13);
+#else
+	data = hw->mac.addr;
+	for (i = 0; i < (hw->nvm.word_size * 2); i++) {
+		ret = ioh_pcieqos_read_gbe_mac_addr((u32) i, (data + i));
+		if (ret != 0)
+			break;
+	}
+#endif
+
+	IOH_GBE_TESTOUT("hw->mac.addr : 0x%02x %02x %02x %02x %02x %02x\n",
+			hw->mac.addr[0], hw->mac.addr[1], hw->mac.addr[2],
+			hw->mac.addr[3], hw->mac.addr[4], hw->mac.addr[5]);
+	return ret;
+}
+#endif
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw)
+ * @brief   Validate EEPROM checksum
+ * @param   hw  [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ */
+s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_nvm_validate_checksum");
+	return IOH_GBE_SUCCESS;
+}
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_nvm.h	2010-03-11 15:12:18.000000000 +0900
@@ -0,0 +1,85 @@
+/*!
+ * @file ioh_gbe_nvm.h
+ * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (NVM) header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_NVM_H_
+#define _IOH_GBE_NVM_H_
+
+#ifdef CONFIG_PCH_PCIEQOS
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw,
+ *                                   u32 offset, u8 *data)
+ * @brief   Read EEPROM
+ */
+s32 ioh_gbe_nvm_read_mem(struct ioh_gbe_hw *hw, u32 offset, u8 * data);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw,
+ *                                    u32 offset, u8 *data)
+ * @brief   Write EEPROM
+ */
+s32 ioh_gbe_nvm_write_mem(struct ioh_gbe_hw *hw, u32 offset, u8 * data);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw)
+ * @brief   Read device MAC address
+ */
+s32 ioh_gbe_nvm_read_mac_addr(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw)
+ * @brief   Validate EEPROM checksum
+ */
+s32 ioh_gbe_nvm_validate_checksum(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup PCIe QoS Driver function
+ * @fn      int ioh_pcieqos_read_gbe_mac_addr (unsigned long offset_address,
+ *                                              unsigned char *data);
+ * @brief   Read MAC address from NVM
+ */
+int ioh_pcieqos_read_gbe_mac_addr(unsigned long offset_address,
+						unsigned char *data);
+
+/*!
+ * @ingroup PCIe QoS Driver function
+ * @fn      int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address,
+ *                                              unsigned char data);
+ * @brief   Write MAC address from NVM
+ */
+int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address,
+						unsigned char data);
+#endif /* CONFIG_PCH_PCIEQOS */
+
+#endif /* _IOH_GBE_NVM_H_ */
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_osdep.h	2010-03-09 09:27:26.000000000 +0900
@@ -0,0 +1,74 @@
+/*!
+ * @file ioh_gbe_osdep.h
+ * @brief Linux IOH Gigabit Ethernet Driver OS independent header file
+ *
+ *        glue for the OS independent part of ioh
+ *        includes register access macros
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_OSDEP_H_
+#define _IOH_GBE_OSDEP_H_
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#define usec_delay(x) udelay(x)
+#ifndef msec_delay
+#define msec_delay(x)	do {if (in_interrupt()) { \
+				/* Don't mdelay in interrupt context! */ \
+				BUG(); \
+			} else { \
+				msleep(x); \
+			} } while (0)
+
+/* Some workarounds require millisecond delays and are run during interrupt
+ * context.  Most notably, when establishing link, the phy may need tweaking
+ * but cannot process phy register reads/writes faster than millisecond
+ * intervals...and we establish link due to a "link status change" interrupt.
+ */
+#define msec_delay_irq(x) mdelay(x)
+#endif
+
+#undef FALSE
+#define FALSE	0
+#undef TRUE
+#define TRUE	1
+
+
+#define IOH_GBE_WRITE_REG(a, reg, value) ( \
+		writel((value), ((a)->hw_addr + IOH_GBE_##reg)))
+
+#define IOH_GBE_READ_REG(a, reg) ( \
+		readl((a)->hw_addr + IOH_GBE_##reg))
+
+#define IOH_GBE_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+		writel((value), \
+		((a)->hw_addr + IOH_GBE_##reg + ((offset) << 2))))
+
+#endif /* _IOH_GBE_OSDEP_H_ */
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_param.c	2010-03-09 09:39:22.000000000 +0900
@@ -0,0 +1,594 @@
+/*!
+ * @file ioh_gbe_param.c
+ * @brief Linux IOH Gigabit Ethernet Driver parameter check source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe.h"
+
+/* This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+
+#define IOH_GBE_MAX_NIC 1
+
+#define OPTION_UNSET   -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED  1
+
+/* All parameters are treated the same, as an integer array of values.
+ * This macro just reduces the need to repeat the same declaration code
+ * over and over (plus this helps to avoid typo bugs).
+ */
+
+#define IOH_GBE_PARAM_INIT { [0 ... IOH_GBE_MAX_NIC] = OPTION_UNSET }
+#ifdef IOH_GBE_QAC
+#define IOH_GBE_PARAM(X, desc)
+#else
+#define IOH_GBE_PARAM(X, desc) \
+		static int X[IOH_GBE_MAX_NIC+1] = IOH_GBE_PARAM_INIT; \
+		static int num_##X; \
+		module_param_array_named(X, X, int, &num_##X, 0); \
+		MODULE_PARM_DESC(X, desc);
+#endif
+
+/*
+ * Transmit Descriptor Count
+ *    Valid Range:   IOH_GBE_MIN_TXD - IOH_GBE_MAX_TXD
+ *    Default Value: IOH_GBE_DEFAULT_TXD
+ */
+IOH_GBE_PARAM(TxDescriptors, "Number of transmit descriptors");
+
+/*
+ * Receive Descriptor Count
+ *    Valid Range:   IOH_GBE_MIN_RXD - IOH_GBE_MAX_RXD
+ *    Default Value: IOH_GBE_DEFAULT_RXD
+ */
+IOH_GBE_PARAM(RxDescriptors, "Number of receive descriptors");
+
+/* User Specified Speed Override
+ *
+ * Valid Range: 0, 10, 100, 1000
+ *  - 0    - auto-negotiate at all supported speeds
+ *  - 10   - only link at 10 Mbps
+ *  - 100  - only link at 100 Mbps
+ *  - 1000 - only link at 1000 Mbps
+ *
+ * Default Value: 0
+ */
+IOH_GBE_PARAM(Speed, "Speed setting");
+
+/* User Specified Duplex Override
+ *
+ * Valid Range: 0-2
+ *  - 0 - auto-negotiate for duplex
+ *  - 1 - only link at half duplex
+ *  - 2 - only link at full duplex
+ *
+ * Default Value: 0
+ */
+IOH_GBE_PARAM(Duplex, "Duplex setting");
+
+/*
+ * Auto-negotiation Advertisement Override
+ *    Valid Range: 0x01-0x0F, 0x20-0x2F
+ *
+ *       The AutoNeg value is a bit mask describing which speed and duplex
+ *       combinations should be advertised during auto-negotiation.
+ *       The supported speed and duplex modes are listed below
+ *
+ *       Bit           7     6     5      4      3     2     1      0
+ *       Speed (Mbps)  N/A   N/A   1000   N/A    100   100   10     10
+ *       Duplex                    Full          Full  Half  Full   Half
+ *
+ *    Default Value: 0x2F (copper)
+ */
+IOH_GBE_PARAM(AutoNeg, "Advertised auto-negotiation setting");
+#define AUTONEG_ADV_DEFAULT  0x2F
+
+/*
+ * User Specified Flow Control Override
+ *    Valid Range: 0-3
+ *     - 0 - No Flow Control
+ *     - 1 - Rx only, respond to PAUSE frames but do not generate them
+ *     - 2 - Tx only, generate PAUSE frames but ignore them on receive
+ *     - 3 - Full Flow Control Support
+ *    Default Value: Read flow control settings from the EEPROM
+ */
+IOH_GBE_PARAM(FlowControl, "Flow Control setting");
+
+/*
+ * XsumRX - Receive Checksum Offload Enable/Disable
+ *    Valid Range: 0, 1
+ *     - 0 - disables all checksum offload
+ *     - 1 - enables receive IP/TCP/UDP checksum offload
+ *    Default Value: IOH_GBE_DEFAULT_RX_CSUM
+ */
+IOH_GBE_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
+
+/*
+ * XsumTX - Transmit Checksum Offload Enable/Disable
+ *    Valid Range: 0, 1
+ *     - 0 - disables all checksum offload
+ *     - 1 - enables transmit IP/TCP/UDP checksum offload
+ *    Default Value: IOH_GBE_DEFAULT_TX_CSUM
+ */
+IOH_GBE_PARAM(XsumTX, "Disable or enable Transmit Checksum offload");
+
+struct ioh_gbe_option {
+	enum { enable_option, range_option, list_option } type;
+	signed char *name;
+	signed char *err;
+	int  def;
+	union {
+		struct { /* range_option info */
+			int min;
+			int max;
+		} r;
+		struct { /* list_option info */
+			int nr;
+			struct ioh_gbe_opt_list { int i; signed char *str; } *p;
+		} l;
+	} arg;
+};
+
+/* ----------------------------------------------------------------------------
+	Function prototype
+---------------------------------------------------------------------------- */
+static void ioh_gbe_check_copper_options(struct ioh_gbe_adapter *adapter);
+static int ioh_gbe_validate_option(int *value,
+					struct ioh_gbe_option *opt,
+					struct ioh_gbe_adapter *adapter);
+
+/* ----------------------------------------------------------------------------
+	Function
+---------------------------------------------------------------------------- */
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static int ioh_gbe_validate_option(int *value,
+ *                                             struct ioh_gbe_option *opt,
+ *                                             struct ioh_gbe_adapter *adapter)
+ * @brief   Validate option
+ * @param   value   [IN] value
+ * @param   opt     [IN] option
+ * @param   adapter [IN] Board private structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ */
+static int
+ioh_gbe_validate_option(int *value, struct ioh_gbe_option *opt,
+		struct ioh_gbe_adapter *adapter)
+{
+	if (*value == OPTION_UNSET) {
+		*value = opt->def;
+		return 0;
+	}
+
+	switch (opt->type) {
+	case enable_option:
+		switch (*value) {
+		case OPTION_ENABLED:
+			DPRINTK(PROBE, INFO, "%s Enabled\n", opt->name);
+			return 0;
+		case OPTION_DISABLED:
+			DPRINTK(PROBE, INFO, "%s Disabled\n", opt->name);
+			return 0;
+		}
+		break;
+	case range_option:
+		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+			DPRINTK(PROBE, INFO,
+					"%s set to %i\n", opt->name, *value);
+			return 0;
+		}
+		break;
+	case list_option: {
+		int i;
+		struct ioh_gbe_opt_list *ent;
+
+		for (i = 0; i < opt->arg.l.nr; i++) {
+			ent = &opt->arg.l.p[i];
+			if (*value == ent->i) {
+				if (ent->str[0] != '\0')
+					DPRINTK(PROBE, INFO, "%s\n", ent->str);
+				return 0;
+			}
+		}
+	}
+		break;
+	default:
+		BUG();
+	}
+
+	DPRINTK(PROBE, INFO, "Invalid %s value specified (%i) %s\n",
+			opt->name, *value, opt->err);
+	*value = opt->def;
+	return -1;
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      void ioh_gbe_check_options(struct ioh_gbe_adapter *adapter)
+ * @brief   Range Checking for Command Line Parameters
+ * @param   adapter  [IN] Board private structure
+ * @return  None
+ * @remarks
+ *  This routine checks all command line parameters for valid user
+ *  input.  If an invalid value is given, or if no user specified
+ *  value exists, a default value is used.  The final value is stored
+ *  in a variable in the adapter structure.
+ */
+void
+ioh_gbe_check_options(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	int bd = adapter->bd_number;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_check_options");
+
+	if (bd >= IOH_GBE_MAX_NIC) {
+		DPRINTK(PROBE, NOTICE,
+		       "Warning: no configuration for board #%i\n", bd);
+		DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
+	}
+
+	{ /* Transmit Descriptor Count */
+		struct ioh_gbe_option opt = {
+			.type = range_option,
+			.name = "Transmit Descriptors",
+			.err  = "using default of "
+				__MODULE_STRING(IOH_GBE_DEFAULT_TXD),
+			.def  = IOH_GBE_DEFAULT_TXD,
+			.arg  = { .r = { .min = IOH_GBE_MIN_TXD } },
+			.arg  = { .r = { .max = IOH_GBE_MAX_TXD } }
+		};
+		struct ioh_gbe_tx_ring *tx_ring = adapter->tx_ring;
+		if (num_TxDescriptors > bd) {
+			tx_ring->count = TxDescriptors[bd];
+			ioh_gbe_validate_option(&tx_ring->count, &opt, adapter);
+			IOH_GBE_ROUNDUP(tx_ring->count,
+					IOH_GBE_TX_DESC_MULTIPLE);
+		} else {
+			tx_ring->count = opt.def;
+		}
+	}
+	{ /* Receive Descriptor Count */
+		struct ioh_gbe_option opt = {
+			.type = range_option,
+			.name = "Receive Descriptors",
+			.err  = "using default of "
+				__MODULE_STRING(IOH_GBE_DEFAULT_RXD),
+			.def  = IOH_GBE_DEFAULT_RXD,
+			.arg  = { .r = { .min = IOH_GBE_MIN_RXD } },
+			.arg  = { .r = { .max = IOH_GBE_MAX_RXD } }
+		};
+		struct ioh_gbe_rx_ring *rx_ring = adapter->rx_ring;
+		if (num_RxDescriptors > bd) {
+			rx_ring->count = RxDescriptors[bd];
+			ioh_gbe_validate_option(&rx_ring->count, &opt, adapter);
+			IOH_GBE_ROUNDUP(rx_ring->count,
+					IOH_GBE_RX_DESC_MULTIPLE);
+		} else {
+			rx_ring->count = opt.def;
+		}
+	}
+	{ /* Checksum Offload Enable/Disable */
+		struct ioh_gbe_option opt = {
+			.type = enable_option,
+			.name = "Checksum Offload",
+			.err  = "defaulting to Enabled",
+			.def  = IOH_GBE_DEFAULT_RX_CSUM
+		};
+
+		if (num_XsumRX > bd) {
+			adapter->rx_csum = XsumRX[bd];
+			ioh_gbe_validate_option((int *)(&adapter->rx_csum),
+						&opt, adapter);
+		} else {
+			adapter->rx_csum = opt.def;
+		}
+	}
+	{ /* Checksum Offload Enable/Disable */
+		struct ioh_gbe_option opt = {
+			.type = enable_option,
+			.name = "Checksum Offload",
+			.err  = "defaulting to Enabled",
+			.def  = IOH_GBE_DEFAULT_TX_CSUM
+		};
+
+		if (num_XsumTX > bd) {
+			adapter->tx_csum = XsumTX[bd];
+			ioh_gbe_validate_option((int *)(&adapter->tx_csum),
+						&opt, adapter);
+		} else {
+			adapter->tx_csum = opt.def;
+		}
+	}
+	{ /* Flow Control */
+
+		struct ioh_gbe_opt_list fc_list[] = {
+			{ioh_gbe_fc_none, "Flow Control Disabled"},
+			{ioh_gbe_fc_rx_pause, "Flow Control Receive Only"},
+			{ioh_gbe_fc_tx_pause, "Flow Control Transmit Only"},
+			{ioh_gbe_fc_full, "Flow Control Enabled"} };
+
+		struct ioh_gbe_option opt = {
+			.type = list_option,
+			.name = "Flow Control",
+			.err  = "reading default settings from EEPROM",
+			.def  = IOH_GBE_FC_DEFAULT,
+			.arg  = { .l = { .nr = (int)ARRAY_SIZE(fc_list),
+					 .p = fc_list } }
+		};
+
+		if (num_FlowControl > bd) {
+			hw->mac.fc = FlowControl[bd];
+			ioh_gbe_validate_option((int *)(&hw->mac.fc),
+							&opt, adapter);
+		} else {
+			hw->mac.fc = opt.def;
+		}
+	}
+
+	ioh_gbe_check_copper_options(adapter);
+}
+
+/*!
+ * @ingroup Linux driver internal function
+ * @fn      static void ioh_gbe_check_copper_options(
+ *                      struct ioh_gbe_adapter *adapter)
+ * @brief   Range Checking for Link Options, Copper Version
+ * @param   adapter  [IN] Board private structure
+ * @return  None
+ * @remarks
+ *  Handles speed and duplex options on copper adapters
+ */
+static void
+ioh_gbe_check_copper_options(struct ioh_gbe_adapter *adapter)
+{
+	struct ioh_gbe_hw *hw = &adapter->hw;
+	int speed, dplx;
+	int bd = adapter->bd_number;
+
+	{ /* Speed */
+		struct ioh_gbe_opt_list speed_list[] = {
+				{0, "" },
+				{SPEED_10, ""},
+				{SPEED_100, ""},
+				{SPEED_1000, ""} };
+
+		struct ioh_gbe_option opt = {
+			.type = list_option,
+			.name = "Speed",
+			.err  = "parameter ignored",
+			.def  = 0,
+			.arg  = { .l = { .nr = (int)ARRAY_SIZE(speed_list),
+					 .p = speed_list } }
+		};
+
+		if (num_Speed > bd) {
+			speed = Speed[bd];
+			ioh_gbe_validate_option(&speed, &opt, adapter);
+		} else {
+			speed = opt.def;
+		}
+	}
+	{ /* Duplex */
+		struct ioh_gbe_opt_list dplx_list[] = {
+				{0, ""},
+				{PHY_HALF_DUPLEX, ""},
+				{PHY_FULL_DUPLEX, ""} };
+
+		struct ioh_gbe_option opt = {
+			.type = list_option,
+			.name = "Duplex",
+			.err  = "parameter ignored",
+			.def  = 0,
+			.arg  = { .l = { .nr = (int)ARRAY_SIZE(dplx_list),
+					 .p = dplx_list } }
+		};
+
+		if (num_Duplex > bd) {
+			dplx = Duplex[bd];
+			ioh_gbe_validate_option(&dplx, &opt, adapter);
+		} else {
+			dplx = opt.def;
+		}
+	}
+
+	{ /* Autoneg */
+		struct ioh_gbe_opt_list an_list[] =
+			#define AA "AutoNeg advertising "
+			{{ 0x01, AA "10/HD" },
+			 { 0x02, AA "10/FD" },
+			 { 0x03, AA "10/FD, 10/HD" },
+			 { 0x04, AA "100/HD" },
+			 { 0x05, AA "100/HD, 10/HD" },
+			 { 0x06, AA "100/HD, 10/FD" },
+			 { 0x07, AA "100/HD, 10/FD, 10/HD" },
+			 { 0x08, AA "100/FD" },
+			 { 0x09, AA "100/FD, 10/HD" },
+			 { 0x0a, AA "100/FD, 10/FD" },
+			 { 0x0b, AA "100/FD, 10/FD, 10/HD" },
+			 { 0x0c, AA "100/FD, 100/HD" },
+			 { 0x0d, AA "100/FD, 100/HD, 10/HD" },
+			 { 0x0e, AA "100/FD, 100/HD, 10/FD" },
+			 { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" },
+			 { 0x20, AA "1000/FD" },
+			 { 0x21, AA "1000/FD, 10/HD" },
+			 { 0x22, AA "1000/FD, 10/FD" },
+			 { 0x23, AA "1000/FD, 10/FD, 10/HD" },
+			 { 0x24, AA "1000/FD, 100/HD" },
+			 { 0x25, AA "1000/FD, 100/HD, 10/HD" },
+			 { 0x26, AA "1000/FD, 100/HD, 10/FD" },
+			 { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" },
+			 { 0x28, AA "1000/FD, 100/FD" },
+			 { 0x29, AA "1000/FD, 100/FD, 10/HD" },
+			 { 0x2a, AA "1000/FD, 100/FD, 10/FD" },
+			 { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" },
+			 { 0x2c, AA "1000/FD, 100/FD, 100/HD" },
+			 { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" },
+			 { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
+			 { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" } };
+
+		struct ioh_gbe_option opt = {
+			.type = list_option,
+			.name = "AutoNeg",
+			.err  = "parameter ignored",
+			.def  = AUTONEG_ADV_DEFAULT,
+			.arg  = { .l = { .nr = (int)ARRAY_SIZE(an_list),
+					 .p = an_list} }
+		};
+
+		if (num_AutoNeg > bd) {
+			if (speed != 0 || dplx != 0) {
+				DPRINTK(PROBE, INFO,
+				"AutoNeg specified along with Speed or Duplex, "
+				"parameter ignored\n");
+				hw->phy.autoneg_advertised = opt.def;
+			} else {
+				hw->phy.autoneg_advertised = AutoNeg[bd];
+				ioh_gbe_validate_option(
+					(int *)(&hw->phy.autoneg_advertised),
+					&opt, adapter);
+			}
+		} else {
+			hw->phy.autoneg_advertised = opt.def;
+		}
+	}
+
+	switch (speed + dplx) {
+	case 0:
+		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+		if ((num_Speed > bd) && (speed != 0 || dplx != 0))
+			DPRINTK(PROBE, INFO,
+				"Speed and duplex autonegotiation enabled\n");
+		hw->mac.link_speed = SPEED_10;
+		hw->mac.link_duplex = DUPLEX_HALF;
+		break;
+	case PHY_HALF_DUPLEX:
+		DPRINTK(PROBE, INFO, "Half Duplex specified without Speed\n");
+		DPRINTK(PROBE, INFO, "Using Autonegotiation at "
+			"Half Duplex only\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+		hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
+						PHY_ADVERTISE_100_HALF;
+		hw->mac.link_speed = SPEED_10;
+		hw->mac.link_duplex = DUPLEX_HALF;
+		break;
+	case PHY_FULL_DUPLEX:
+		DPRINTK(PROBE, INFO, "Full Duplex specified without Speed\n");
+		DPRINTK(PROBE, INFO, "Using Autonegotiation at "
+			"Full Duplex only\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+		hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL |
+						PHY_ADVERTISE_100_FULL |
+						PHY_ADVERTISE_1000_FULL;
+		hw->mac.link_speed = SPEED_10;
+		hw->mac.link_duplex = DUPLEX_FULL;
+		break;
+	case PHY_SPEED_10:
+		DPRINTK(PROBE, INFO, "10 Mbps Speed specified "
+			"without Duplex\n");
+		DPRINTK(PROBE, INFO, "Using Autonegotiation at 10 Mbps only\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+		hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
+						PHY_ADVERTISE_10_FULL;
+		hw->mac.link_speed = SPEED_10;
+		hw->mac.link_duplex = DUPLEX_HALF;
+		break;
+	case PHY_SPEED_10 + PHY_HALF_DUPLEX:
+		DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Half Duplex\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+		hw->phy.autoneg_advertised = 0;
+		hw->mac.link_speed = SPEED_10;
+		hw->mac.link_duplex = DUPLEX_HALF;
+		break;
+	case PHY_SPEED_10 + PHY_FULL_DUPLEX:
+		DPRINTK(PROBE, INFO, "Forcing to 10 Mbps Full Duplex\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+		hw->phy.autoneg_advertised = 0;
+		hw->mac.link_speed = SPEED_10;
+		hw->mac.link_duplex = DUPLEX_FULL;
+		break;
+	case PHY_SPEED_100:
+		DPRINTK(PROBE, INFO, "100 Mbps Speed specified "
+			"without Duplex\n");
+		DPRINTK(PROBE, INFO, "Using Autonegotiation at "
+			"100 Mbps only\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+		hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF |
+						PHY_ADVERTISE_100_FULL;
+		hw->mac.link_speed = SPEED_100;
+		hw->mac.link_duplex = DUPLEX_HALF;
+		break;
+	case PHY_SPEED_100 + PHY_HALF_DUPLEX:
+		DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Half Duplex\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+		hw->phy.autoneg_advertised = 0;
+		hw->mac.link_speed = SPEED_100;
+		hw->mac.link_duplex = DUPLEX_HALF;
+		break;
+	case PHY_SPEED_100 + PHY_FULL_DUPLEX:
+		DPRINTK(PROBE, INFO, "Forcing to 100 Mbps Full Duplex\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
+		hw->phy.autoneg_advertised = 0;
+		hw->mac.link_speed = SPEED_100;
+		hw->mac.link_duplex = DUPLEX_FULL;
+		break;
+	case PHY_SPEED_1000:
+		DPRINTK(PROBE, INFO, "1000 Mbps Speed specified without "
+			"Duplex\n");
+		goto full_duplex_only;
+	case PHY_SPEED_1000 + PHY_HALF_DUPLEX:
+		DPRINTK(PROBE, INFO,
+			"Half Duplex is not supported at 1000 Mbps\n");
+		/* fall through */
+	case PHY_SPEED_1000 + PHY_FULL_DUPLEX:
+full_duplex_only:
+		DPRINTK(PROBE, INFO,
+		       "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
+		hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL;
+		hw->mac.link_speed = SPEED_1000;
+		hw->mac.link_duplex = DUPLEX_FULL;
+		break;
+	default:
+		BUG();
+	}
+}
+
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_pci_ids.h	2010-03-09 09:27:26.000000000 +0900
@@ -0,0 +1,38 @@
+/*!
+ * @file ioh_gbe_pci_ids.h
+ * @brief Linux IOH Gigabit Ethernet Driver PCI ID header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_PCI_IDS_H_
+#define _IOH_GBE_PCI_IDS_H_
+
+/* Pci vender/device ID */
+#define PCI_DEVICE_ID_INTEL_IOH1_GBE    (u16)(0x8802)
+
+#endif
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.c	2010-03-09 09:27:26.000000000 +0900
@@ -0,0 +1,493 @@
+/*!
+ * @file ioh_gbe_phy.c
+ * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (PHY) source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_phy.h"
+#include "pch_gbe_api.h"
+#include "pch_gbe_regs.h"
+#include "pch_gbe.h"
+
+
+/*!
+ * @ingroup  HAL internal function
+ * @def      PHY_CONTROL_DEFAULT
+ * @brief    Default value of CONTROL register of PHY
+ */
+#define PHY_CONTROL_DEFAULT           0x1140 /* Control Register */
+
+/*!
+ * @ingroup  HAL internal function
+ * @def      PHY_AUTONEG_ADV_DEFAULT
+ * @brief    Default value of AUTONEG_ADV register of PHY
+ */
+#define PHY_AUTONEG_ADV_DEFAULT       0x01e0 /* Autoneg Advertisement */
+
+/*!
+ * @ingroup  HAL internal function
+ * @def      PHY_NEXT_PAGE_TX_DEFAULT
+ * @brief    Default value of NEXT_PAGE_TX register of PHY
+ */
+#define PHY_NEXT_PAGE_TX_DEFAULT      0x2001 /* Next Page TX */
+
+/*!
+ * @ingroup  HAL internal function
+ * @def      PHY_1000T_CTRL_DEFAULT
+ * @brief    Default value of 1000T_CTRL register of PHY
+ */
+#define PHY_1000T_CTRL_DEFAULT        0x0300 /* 1000Base-T Control Register */
+
+/*!
+ * @ingroup  HAL internal function
+ * @def      PHY_PHYSP_CONTROL_DEFAULT
+ * @brief    Default value of PHYSP_CONTROL register of PHY
+ */
+#ifdef FPGA
+#define PHY_PHYSP_CONTROL_DEFAULT     0x0078 /* PHY Specific Control Register */
+#else
+#define PHY_PHYSP_CONTROL_DEFAULT     0x01EE /* PHY Specific Control Register */
+#endif
+
+/*!
+ * @ingroup  HAL internal function
+ * @def      PHY_EXT_PHYSP_CONTROL_DEFAULT
+ * @brief    Default value of EXT_PHYSP_CONTROL register of PHY
+ */
+#define PHY_EXT_PHYSP_CONTROL_DEFAULT 0x0c60
+
+/*!
+ * @ingroup  HAL internal function
+ * @def      PHY_LED_CONTROL_DEFAULT
+ * @brief    Default value of LED_CONTROL register of PHY
+ */
+#define PHY_LED_CONTROL_DEFAULT       0x4100
+
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw)
+ * @brief   Retrieve the PHY ID and revision
+ * @param   hw   [IN] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ * @remarks
+ *  Reads the PHY registers and stores the PHY ID and possibly the PHY
+ *  revision in the hardware structure.
+ */
+s32
+ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw)
+{
+	struct ioh_gbe_phy_info *phy = &hw->phy;
+	s32 ret;
+	u16 phy_id1;
+	u16 phy_id2;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_get_id");
+
+	ret = ioh_gbe_hal_read_phy_reg(hw, PHY_ID1, &phy_id1);
+	if (ret != 0)
+		return ret;
+	ret = ioh_gbe_hal_read_phy_reg(hw, PHY_ID2, &phy_id2);
+	if (ret != 0)
+		return ret;
+	/*
+	 * PHY_ID1: [bit15-0:ID(21-6)]
+	 * PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision]
+	 */
+	phy->id = (u32)phy_id1;
+	phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10));
+	phy->revision = (u32) (phy_id2 & 0x000F);
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("phy->id : 0x%08x  phy->revision : 0x%08x\n",
+			phy->id, phy->revision);
+#endif
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw,
+ *                                        u32 offset, u16 *data)
+ * @brief   Read MII control register
+ * @param   hw      [IN] Pointer to the HW structure
+ * @param   offset  [IN] Register offset to be read
+ * @param   data    [OUT] Pointer to the read data
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ * @remarks
+ *  Reads the PHY registers and stores the PHY ID and possibly the PHY
+ *  revision in the hardware structure.
+ */
+s32
+ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 *data)
+{
+	struct ioh_gbe_phy_info *phy = &hw->phy;
+	s32 ret_val = IOH_GBE_SUCCESS;
+
+	if (offset > PHY_MAX_REG_ADDRESS) {
+		IOH_GBE_DBGOUT1("PHY Address %d is out of range\n", offset);
+		ret_val = -IOH_GBE_ERR_PARAM;
+	} else {
+		*data = ioh_gbe_hal_ctrl_miim(hw, phy->addr,
+					IOH_GBE_HAL_MIIM_READ, offset, (u16)0);
+	}
+	return ret_val;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw,
+ *                                         u32 offset, u16 data)
+ * @brief   Write MII control register
+ * @param   hw      [IN] Pointer to the HW structure
+ * @param   offset  [IN] Register offset to be read
+ * @param   data    [IN] data to write to register at offset
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ * @remarks
+ *  Writes data to MDI control register in the PHY at offset.
+ */
+s32
+ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 data)
+{
+	struct ioh_gbe_phy_info *phy = &hw->phy;
+	s32 ret_val = IOH_GBE_SUCCESS;
+
+	if (offset > PHY_MAX_REG_ADDRESS) {
+		IOH_GBE_DBGOUT1("PHY Address %d is out of range\n", offset);
+		ret_val = -IOH_GBE_ERR_PARAM;
+	} else {
+		ioh_gbe_hal_ctrl_miim(hw, phy->addr,
+					IOH_GBE_HAL_MIIM_WRITE, offset, data);
+	}
+	return ret_val;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw)
+ * @brief   Configure link settings for FPGA
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:   Failed
+ * @remarks
+ *  Calls the appropriate function to configure the link for auto-neg or forced
+ *  speed and duplex.  Then we check for link, once link is established calls
+ *  to configure collision distance and flow control are called.  If link is
+ *  not established, we return -IOH_GBE_ERR_PHY (-2).
+ */
+s32
+ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw)
+{
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_setup_link_fpga");
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw)
+ * @brief   PHY software reset
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  None
+ * @remarks
+ *  Does a software reset of the PHY by reading the PHY control register and
+ *  setting/write the control register reset bit to the PHY.
+ */
+void
+ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw)
+{
+	u16 phy_ctrl;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_sw_reset");
+
+	ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+	phy_ctrl |= MII_CR_RESET;
+	ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+	usec_delay(1);
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw)
+ * @brief   PHY hardware reset
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  None
+ * @remarks
+ *  Verify the reset block is not blocking us from resetting.  Acquire
+ *  semaphore (if necessary) and read/set/write the device control reset
+ *  bit in the PHY.  Wait the appropriate delay time for the device to
+ *  reset and relase the semaphore (if necessary).
+ */
+void
+ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw)
+{
+#ifndef PHY_RESET_REG_INIT
+	struct ioh_gbe_phy_info *phy = &hw->phy;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_hw_reset");
+
+	/* ISSUE: reset used GPIO driver */
+	usec_delay(phy->reset_delay_us);
+	/* ISSUE: release reset used GPIO driver */
+#else
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_hw_reset");
+
+	ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT);
+	ioh_gbe_hal_write_phy_reg(hw, PHY_AUTONEG_ADV,
+					PHY_AUTONEG_ADV_DEFAULT);
+	ioh_gbe_hal_write_phy_reg(hw, PHY_NEXT_PAGE_TX,
+					PHY_NEXT_PAGE_TX_DEFAULT);
+	ioh_gbe_hal_write_phy_reg(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT);
+	ioh_gbe_hal_write_phy_reg(hw, PHY_PHYSP_CONTROL,
+					PHY_PHYSP_CONTROL_DEFAULT);
+#ifdef FPGA
+	ioh_gbe_hal_write_phy_reg(hw, PHY_EXT_PHYSP_CONTROL,
+					PHY_EXT_PHYSP_CONTROL_DEFAULT);
+	ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CONTROL_DEFAULT);
+#endif
+
+#endif
+
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw)
+ * @brief   Set ting of led on
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ */
+s32
+ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_led_on");
+
+	ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CTRL_ON);
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw)
+ * @brief   Set ting of led off
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ */
+s32
+ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_led_off");
+
+	ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CTRL_OFF);
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw)
+ * @brief   Cleanup led control
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ */
+s32
+ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_led_cleanup");
+
+	ioh_gbe_hal_write_phy_reg(hw, PHY_LED_CONTROL, PHY_LED_CTRL_CLEANUP);
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw)
+ * @brief   Setup led control
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ */
+s32
+ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_led_setup");
+
+	return IOH_GBE_SUCCESS;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw)
+ * @brief   restore link in case the phy was powered down
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  None
+ * @remarks
+ *  The phy may be powered down to save power and turn off link when the
+ *  driver is unloaded and wake on lan is not enabled (among others)
+ *  *** this routine MUST be followed by a call to ioh_gbe_reset ***
+ */
+void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw)
+{
+	u16 mii_reg;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_power_up");
+
+	mii_reg = 0;
+	/* Just clear the power down bit to wake the phy back up */
+	/* according to the manual, the phy will retain its
+	 * settings across a power-down/up cycle */
+	ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
+	mii_reg &= ~MII_CR_POWER_DOWN;
+	ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, mii_reg);
+
+#ifdef DEBUG_TEST
+	ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
+	IOH_GBE_TESTOUT("PHY_CONTROL reg : 0x%08x\n", mii_reg);
+#endif
+	return;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw)
+ * @brief   Power down PHY
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  None
+ */
+void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw)
+{
+	u16 mii_reg;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_power_down");
+
+	mii_reg = 0;
+	/* Power down the PHY so no link is implied when interface is down *
+	 * The PHY cannot be powered down if any of the following is TRUE *
+	 * (a) WoL is enabled
+	 * (b) AMT is active
+	 */
+	ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
+	mii_reg |= MII_CR_POWER_DOWN;
+	ioh_gbe_hal_write_phy_reg(hw, PHY_CONTROL, mii_reg);
+	mdelay(1);
+
+#ifdef DEBUG_TEST
+	ioh_gbe_hal_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
+	IOH_GBE_TESTOUT("PHY_CONTROL reg : 0x%08x\n", mii_reg);
+#endif
+	return;
+}
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw)
+ * @brief   RGMII interface setting
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  None
+ */
+#ifdef FPGA
+void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw)
+{
+	u16 mii_reg;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_set_rgmii");
+
+	ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_STATUS, &mii_reg);
+	mii_reg &= ~HWCFG_MODE_MASK;
+	mii_reg |= HWCFG_MODE_RGMII_COPPER;
+	ioh_gbe_hal_write_phy_reg(hw, PHY_EXT_PHYSP_STATUS, mii_reg);
+	ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_CONTROL, &mii_reg);
+	mii_reg |= 0x01;	/* Transfer enable */
+	mii_reg |= 0x02;	/* add delay to GTX_CLK */
+	mii_reg |= 0x80;	/* add delay to RX_CLK */
+	ioh_gbe_hal_write_phy_reg(hw, PHY_EXT_PHYSP_CONTROL, mii_reg);
+	ioh_gbe_hal_phy_sw_reset(hw);
+
+#ifdef DEBUG_TEST
+	ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_STATUS, &mii_reg);
+	IOH_GBE_TESTOUT("PHY_EXT_PHYSP_STATUS reg : 0x%08x\n", mii_reg);
+	ioh_gbe_hal_read_phy_reg(hw, PHY_EXT_PHYSP_CONTROL, &mii_reg);
+	IOH_GBE_TESTOUT("PHY_EXT_PHYSP_CONTROL reg : 0x%08x\n", mii_reg);
+#endif
+	return;
+}
+#else
+void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_set_rgmii");
+
+	ioh_gbe_hal_phy_sw_reset(hw);
+	return;
+}
+#endif
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw)
+ * @brief   PHY initial setting
+ * @param   hw      [IN] Pointer to the HW structure
+ * @return  None
+ */
+void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw)
+{
+	struct ioh_gbe_adapter *adapter;
+	struct ethtool_cmd     cmd;
+	int ret;
+	u16 mii_reg;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_phy_init_setting");
+
+	adapter = container_of(hw, struct ioh_gbe_adapter, hw);
+	ret = mii_ethtool_gset(&adapter->mii, &cmd);
+	if (ret != 0)
+		IOH_GBE_ERR("Error: mii_ethtool_gset\n");
+
+	cmd.speed = hw->mac.link_speed;
+	cmd.duplex = hw->mac.link_duplex;
+	cmd.advertising = hw->phy.autoneg_advertised;
+	cmd.autoneg = hw->mac.autoneg;
+	ioh_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
+	ret = mii_ethtool_sset(&adapter->mii, &cmd);
+	if (ret != 0)
+		IOH_GBE_ERR("Error: mii_ethtool_sset\n");
+
+	ioh_gbe_hal_phy_sw_reset(hw);
+
+	ioh_gbe_hal_read_phy_reg(hw, PHY_PHYSP_CONTROL, &mii_reg);
+	mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;
+	ioh_gbe_hal_write_phy_reg(hw, PHY_PHYSP_CONTROL, mii_reg);
+
+}
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_phy.h	2010-03-09 09:27:26.000000000 +0900
@@ -0,0 +1,136 @@
+/*!
+ * @file ioh_gbe_phy.h
+ * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (PHY) header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_PHY_H_
+#define _IOH_GBE_PHY_H_
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw)
+ * @brief   Retrieve the PHY ID and revision
+ */
+s32  ioh_gbe_phy_get_id(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw,
+ *                                        u32 offset, u16 *data)
+ * @brief   Read MII control register
+ */
+s32 ioh_gbe_phy_read_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 *data);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw,
+ *                                         u32 offset, u16 data)
+ * @brief   Write MII control register
+ */
+s32 ioh_gbe_phy_write_reg_miic(struct ioh_gbe_hw *hw, u32 offset, u16 data);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw)
+ * @brief   Configure link settings for FPGA
+ */
+s32  ioh_gbe_phy_setup_link_fpga(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw)
+ * @brief   PHY software reset
+ */
+void ioh_gbe_phy_sw_reset(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw)
+ * @brief   PHY hardware reset
+ */
+void ioh_gbe_phy_hw_reset(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw)
+ * @brief   Set ting of led on
+ */
+s32 ioh_gbe_phy_led_on(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw)
+ * @brief   Set ting of led off
+ */
+s32 ioh_gbe_phy_led_off(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw)
+ * @brief   Cleanup led control
+ */
+s32 ioh_gbe_phy_led_cleanup(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      s32 ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw)
+ * @brief   Setup led control
+ */
+s32 ioh_gbe_phy_led_setup(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw)
+ * @brief   restore link in case the phy was powered down
+ */
+void ioh_gbe_phy_power_up(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw)
+ * @brief   Power down PHY
+ */
+void ioh_gbe_phy_power_down(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw)
+ * @brief   RGMII interface setting
+ */
+void ioh_gbe_phy_set_rgmii(struct ioh_gbe_hw *hw);
+
+/*!
+ * @ingroup HAL internal function
+ * @fn      void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw)
+ * @brief   PHY initial setting
+ */
+void ioh_gbe_phy_init_setting(struct ioh_gbe_hw *hw);
+
+
+#endif /* _IOH_GBE_PHY_H_ */
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_plat.c	2010-03-11 15:11:52.000000000 +0900
@@ -0,0 +1,175 @@
+/*!
+ * @file ioh_gbe_plat.c
+ * @brief Linux IOH Gigabit Ethernet Driver HAL internal function (platform) source file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+
+#include "pch_gbe_osdep.h"
+#include "pch_gbe_defines.h"
+#include "pch_gbe_hw.h"
+#include "pch_gbe_mac.h"
+#include "pch_gbe_nvm.h"
+#include "pch_gbe_phy.h"
+#include "pch_gbe_api.h"
+
+
+static void ioh_gbe_plat_get_bus_info(struct ioh_gbe_hw *hw);
+static s32 ioh_gbe_plat_init_hw(struct ioh_gbe_hw *hw);
+
+
+/*!
+ * @ingroup HAL internal functions
+ * @fn      void ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw)
+ * @brief   Init func ptrs.
+ * @param   hw  [OUT] Pointer to the HW structure
+ * @return  None
+ * @remarks
+ *  The only function explicitly called by the api module to initialize
+ *  all function pointers and parameters.
+ */
+void
+ioh_gbe_plat_init_function_pointers(struct ioh_gbe_hw *hw)
+{
+	struct ioh_gbe_mac_info *mac = &hw->mac;
+	struct ioh_gbe_phy_info *phy = &hw->phy;
+	struct ioh_gbe_nvm_info *nvm = &hw->nvm;
+	struct ioh_gbe_functions *func = &hw->func;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_plat_init_function_pointers");
+
+	/* Set MAC address registers entry count */
+	mac->mar_entry_count    = IOH_GBE_MAR_ENTRIES;
+	/* Set PHY parameter */
+	phy->reset_delay_us     = IOH_GBE_PHY_RESET_DELAY_US;
+	/* Set NVM parameter */
+	nvm->word_size          = IOH_GBE_NVM_WORD_SIZE;
+
+	/* Set function pointers */
+	func->get_bus_info             = ioh_gbe_plat_get_bus_info;
+	func->reset_hw                 = ioh_gbe_mac_reset_hw;
+	func->init_hw                  = ioh_gbe_plat_init_hw;
+	func->setup_link               = ioh_gbe_mac_setup_link;
+	func->setup_physical_interface = ioh_gbe_phy_setup_link_fpga;
+	func->mc_addr_list_update      = ioh_gbe_mac_mc_addr_list_update;
+	func->setup_led                = ioh_gbe_phy_led_setup;
+	func->cleanup_led              = ioh_gbe_phy_led_cleanup;
+	func->led_on                   = ioh_gbe_phy_led_on;
+	func->led_off                  = ioh_gbe_phy_led_off;
+	func->read_phy_reg             = ioh_gbe_phy_read_reg_miic;
+	func->write_phy_reg            = ioh_gbe_phy_write_reg_miic;
+	func->reset_phy                = ioh_gbe_phy_hw_reset;
+	func->sw_reset_phy             = ioh_gbe_phy_sw_reset;
+	func->power_up_phy             = ioh_gbe_phy_power_up;
+	func->power_down_phy           = ioh_gbe_phy_power_down;
+#ifdef CONFIG_PCH_PCIEQOS
+	func->read_nvm                 = ioh_gbe_nvm_read_mem;
+	func->write_nvm                = ioh_gbe_nvm_write_mem;
+	func->validate_nvm             = ioh_gbe_nvm_validate_checksum;
+	func->read_mac_addr            = ioh_gbe_nvm_read_mac_addr;
+#else
+	func->read_mac_addr            = ioh_gbe_mac_read_mac_addr;
+#endif
+	func->ctrl_miim                = ioh_gbe_mac_ctrl_miim;
+	func->pause_packet             = ioh_gbe_mac_set_pause_packet;
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("[MAC]mar_entry_count:%d /[PHY] reset_delay_us:%d\n",
+			mac->mar_entry_count, phy->reset_delay_us);
+	IOH_GBE_TESTOUT("[NVM] word_size:0x%08x\n", nvm->word_size);
+#endif
+}
+
+
+/*!
+ * @ingroup HAL internal functions
+ * @fn      static void ioh_gbe_plat_get_bus_info(struct ioh_gbe_hw *hw)
+ * @brief   Obtain bus information for adapter
+ * @param   hw  [OUT] Pointer to the HW structure
+ * @return  None
+ * @remarks
+ *  This will obtain information about the HW bus for which the
+ *  adaper is attached and stores it in the hw structure.  This is a function
+ *  pointer entry point called by the api module.
+ */
+static void
+ioh_gbe_plat_get_bus_info(struct ioh_gbe_hw *hw)
+{
+	IOH_GBE_DBGFUNC("ioh_gbe_plat_get_bus_info");
+
+	hw->bus.type  = ioh_gbe_bus_type_pci_express;
+	hw->bus.speed = ioh_gbe_bus_speed_2500;
+	hw->bus.width = ioh_gbe_bus_width_pcie_x1;
+
+#ifdef DEBUG_TEST
+	IOH_GBE_TESTOUT("[BUS] type:0x%08x  speed:0x%08x  width:0x%08x\n",
+			hw->bus.type, hw->bus.speed, hw->bus.width);
+#endif
+}
+
+/*!
+ * @ingroup HAL internal functions
+ * @fn      static s32 ioh_gbe_plat_init_hw(struct ioh_gbe_hw *hw)
+ * @brief   Initialize hardware
+ * @param   hw  [INOUT] Pointer to the HW structure
+ * @return  IOH_GBE_SUCCESS:  Successfully
+ * @return  Negative value:  Failed
+ * @remarks
+ *  This inits the hardware readying it for operation.  This is a
+ *  function pointer entry point called by the api module.
+ */
+static s32
+ioh_gbe_plat_init_hw(struct ioh_gbe_hw *hw)
+{
+	struct ioh_gbe_mac_info *mac = &hw->mac;
+	s32 ret_val;
+
+	IOH_GBE_DBGFUNC("ioh_gbe_plat_init_hw");
+
+	/* Setup the receive address. */
+	ioh_gbe_mac_init_rx_addrs(hw, mac->mar_entry_count);
+
+	ret_val = ioh_gbe_phy_get_id(hw);
+	if (ret_val) {
+		IOH_GBE_ERR("ioh_gbe_phy_get_id error\n");
+		return ret_val;
+	}
+	ioh_gbe_phy_init_setting(hw);
+	/* Setup Mac interface option RGMII */
+#ifdef IOH_GBE_MAC_IFOP_RGMII
+	ioh_gbe_phy_set_rgmii(hw);
+#endif
+	/* Setup link and flow control */
+	ret_val = ioh_gbe_hal_setup_link(hw);
+#ifdef DEBUG_TEST
+	if (ret_val)
+		IOH_GBE_ERR("ioh_gbe_phy_get_id error\n");
+#endif
+	return ret_val;
+}
+
diff -urN linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h
--- linux-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/pch_gbe/pch_gbe_regs.h	2010-03-09 09:27:26.000000000 +0900
@@ -0,0 +1,351 @@
+/*!
+ * @file ioh_gbe_regs.h
+ * @brief Linux IOH Gigabit Ethernet Driver register macro header file
+ *
+ * @version 0.90
+ *
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR CO., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *   OKI SEMICONDUCTOR 09/21/2009
+ * modified:
+ *
+ */
+#ifndef _IOH_GBE_REGS_H_
+#define _IOH_GBE_REGS_H_
+
+/* MAC registers */
+#define IOH_GBE_INT_ST		0x0000	/* Interrupt Status */
+#define IOH_GBE_INT_EN		0x0004	/* Interrupt Enable */
+#define IOH_GBE_MODE		0x0008	/* Mode */
+#define IOH_GBE_RESET		0x000C	/* Reset */
+#define IOH_GBE_TCPIP_ACC	0x0010	/* TCP/IP Accelerator Control */
+#define IOH_GBE_EX_LIST		0x0014	/* External List */
+#define IOH_GBE_INT_ST_HOLD	0x0018	/* Interrupt Status Hold */
+#define IOH_GBE_PHY_INT_CTRL	0x001C	/* PHY Interrupt Control */
+#define IOH_GBE_MAC_RX_EN	0x0020	/* MAC RX Enable */
+#define IOH_GBE_RX_FCTRL	0x0024	/* RX Flow Control */
+#define IOH_GBE_PAUSE_REQ	0x0028	/* Pause Packet Request */
+#define IOH_GBE_RX_MODE		0x002C	/* RX Mode */
+#define IOH_GBE_TX_MODE		0x0030	/* TX Mode */
+#define IOH_GBE_RX_FIFO_ST	0x0034	/* RX FIFO Status */
+#define IOH_GBE_TX_FIFO_ST	0x0038	/* TX FIFO Status */
+#define IOH_GBE_TX_FID		0x003C	/* TX Frame ID */
+#define IOH_GBE_TX_RESULT	0x0040	/* TX Result */
+#define IOH_GBE_PAUSE_PKT1	0x0044	/* Pause Packet1 */
+#define IOH_GBE_PAUSE_PKT2	0x0048	/* Pause Packet2 */
+#define IOH_GBE_PAUSE_PKT3	0x004C	/* Pause Packet3 */
+#define IOH_GBE_PAUSE_PKT4	0x0050	/* Pause Packet4 */
+#define IOH_GBE_PAUSE_PKT5	0x0054	/* Pause Packet5 */
+#define IOH_GBE_MAC_ADR		0x0060	/* MAC Address */
+#define IOH_GBE_MAC_ADR1A	0x0060	/* MAC Address 1A */
+#define IOH_GBE_MAC_ADR1B	0x0064	/* MAC Address 1B */
+#define IOH_GBE_MAC_ADR2A	0x0068	/* MAC Address 2A */
+#define IOH_GBE_MAC_ADR2B	0x006C	/* MAC Address 2B */
+#define IOH_GBE_MAC_ADR3A	0x0070	/* MAC Address 3A */
+#define IOH_GBE_MAC_ADR3B	0x0074	/* MAC Address 3B */
+#define IOH_GBE_MAC_ADR4A	0x0078	/* MAC Address 4A */
+#define IOH_GBE_MAC_ADR4B	0x007C	/* MAC Address 4B */
+#define IOH_GBE_MAC_ADR5A	0x0080	/* MAC Address 5A */
+#define IOH_GBE_MAC_ADR5B	0x0084	/* MAC Address 5B */
+#define IOH_GBE_MAC_ADR6A	0x0088	/* MAC Address 6A */
+#define IOH_GBE_MAC_ADR6B	0x008C	/* MAC Address 6B */
+#define IOH_GBE_MAC_ADR7A	0x0090	/* MAC Address 7A */
+#define IOH_GBE_MAC_ADR7B	0x0094	/* MAC Address 7B */
+#define IOH_GBE_MAC_ADR8A	0x0098	/* MAC Address 8A */
+#define IOH_GBE_MAC_ADR8B	0x009C	/* MAC Address 8B */
+#define IOH_GBE_MAC_ADR9A	0x00A0	/* MAC Address 9A */
+#define IOH_GBE_MAC_ADR9B	0x00A4	/* MAC Address 9B */
+#define IOH_GBE_MAC_ADR10A	0x00A8	/* MAC Address 10A */
+#define IOH_GBE_MAC_ADR10B	0x00AC	/* MAC Address 10B */
+#define IOH_GBE_MAC_ADR11A	0x00B0	/* MAC Address 11A */
+#define IOH_GBE_MAC_ADR11B	0x00B4	/* MAC Address 11B */
+#define IOH_GBE_MAC_ADR12A	0x00B8	/* MAC Address 12A */
+#define IOH_GBE_MAC_ADR12B	0x00BC	/* MAC Address 12B */
+#define IOH_GBE_MAC_ADR13A	0x00C0	/* MAC Address 13A */
+#define IOH_GBE_MAC_ADR13B	0x00C4	/* MAC Address 13B */
+#define IOH_GBE_MAC_ADR14A	0x00C8	/* MAC Address 14A */
+#define IOH_GBE_MAC_ADR14B	0x0CC	/* MAC Address 14B */
+#define IOH_GBE_MAC_ADR15A	0x00D0	/* MAC Address 15A */
+#define IOH_GBE_MAC_ADR15B	0x00D4	/* MAC Address 15B */
+#define IOH_GBE_MAC_ADR16A	0x00D8	/* MAC Address 16A */
+#define IOH_GBE_MAC_ADR16B	0x00DC	/* MAC Address 16B */
+#define IOH_GBE_ADDR_MASK	0x00E0	/* MAC Address Mask */
+#define IOH_GBE_MIIM		0x00E4	/* MIIM  */
+#define IOH_GBE_RGMII_ST	0x00EC	/* RGMII Status */
+#define IOH_GBE_RGMII_CTRL	0x00F0	/* RGMII Control */
+#define IOH_GBE_DMA_CTRL	0x0100	/* DMA Control */
+#define IOH_GBE_RX_DSC_BASE	0x0110	/* RX Descriptor Base Address */
+#define IOH_GBE_RX_DSC_SIZE	0x0114	/* RX Descriptor Size */
+#define IOH_GBE_RX_DSC_HW_P	0x0118	/* RX Descriptor Hard Pointer  */
+#define IOH_GBE_RX_DSC_HW_P_HLD	0x011C	/* RX Descriptor Hard Pointer Hold */
+#define IOH_GBE_RX_DSC_SW_P	0x0120	/* RX Descriptor Soft Pointer  */
+#define IOH_GBE_TX_DSC_BASE	0x0130	/* TX Descriptor Base Address */
+#define IOH_GBE_TX_DSC_SIZE	0x0134	/* TX Descriptor Size */
+#define IOH_GBE_TX_DSC_HW_P	0x0138	/* TX Descriptor Hard Pointer  */
+#define IOH_GBE_TX_DSC_HW_P_HLD	0x013C	/* TX Descriptor Hard Pointer Hold */
+#define IOH_GBE_TX_DSC_SW_P	0x0140	/* TX Descriptor Soft Pointer  */
+#define IOH_GBE_RX_DMA_ST	0x0150	/* RX DMA Status */
+#define IOH_GBE_TX_DMA_ST	0x0154	/* TX DMA Status */
+#define IOH_GBE_WOL_ST		0x0160	/* Wake On LAN Status */
+#define IOH_GBE_WOL_CTRL	0x0164	/* Wake On LAN Control */
+#define IOH_GBE_WOL_ADDR_MASK	0x0168	/* Wake On LAN Address Mask */
+
+
+/* Definitions for MAC registers */
+
+/* Interrupt Status */
+/* Interrupt Status Hold */
+/* Interrupt Enable */
+#define IOH_GBE_INT_RX_DMA_CMPLT  0x00000001 /* Receive DMA Transfer Complete */
+#define IOH_GBE_INT_RX_VALID      0x00000002 /* MAC Normal Receive Complete */
+#define IOH_GBE_INT_RX_FRAME_ERR  0x00000004 /* Receive frame error */
+#define IOH_GBE_INT_RX_FIFO_ERR   0x00000008 /* Receive FIFO Overflow */
+#define IOH_GBE_INT_RX_DMA_ERR    0x00000010 /* Receive DMA Transfer Error */
+#define IOH_GBE_INT_RX_DSC_EMP    0x00000020 /* Receive Descriptor Empty */
+#define IOH_GBE_INT_TX_CMPLT      0x00000100 /* MAC Transmission Complete */
+#define IOH_GBE_INT_TX_DMA_CMPLT  0x00000200 /* DMA Transfer Complete */
+#define IOH_GBE_INT_TX_FIFO_ERR   0x00000400 /* Transmission FIFO underflow. */
+#define IOH_GBE_INT_TX_DMA_ERR    0x00000800 /* Transmission DMA Error */
+#define IOH_GBE_INT_PAUSE_CMPLT   0x00001000 /* Pause Transmission complete */
+#define IOH_GBE_INT_MIIM_CMPLT    0x00010000 /* MIIM I/F Read completion */
+#define IOH_GBE_INT_PHY_INT       0x00100000 /* Interruption from PHY */
+#define IOH_GBE_INT_WOL_DET       0x01000000 /* Wake On LAN Event detection. */
+#define IOH_GBE_INT_TCPIP_ERR     0x10000000 /* TCP/IP Accelerator Error */
+
+/* Mode */
+#define IOH_GBE_MODE_MII_ETHER      0x00000000  /* GIGA Ethernet Mode [MII] */
+#define IOH_GBE_MODE_GMII_ETHER     0x80000000  /* GIGA Ethernet Mode [GMII] */
+#define IOH_GBE_MODE_HALF_DUPLEX    0x00000000  /* Duplex Mode [half duplex] */
+#define IOH_GBE_MODE_FULL_DUPLEX    0x40000000  /* Duplex Mode [full duplex] */
+#define IOH_GBE_MODE_FR_BST         0x04000000  /* Frame bursting is done */
+
+/* Reset */
+#define IOH_GBE_ALL_RST         0x80000000  /* All reset */
+#define IOH_GBE_TX_RST          0x40000000  /* TX MAC, TX FIFO, TX DMA reset */
+#define IOH_GBE_RX_RST          0x04000000  /* RX MAC, RX FIFO, RX DMA reset */
+
+/* TCP/IP Accelerator Control */
+/* External List Enable */
+#define IOH_GBE_EX_LIST_EN      0x00000008
+/* RX TCP/IP accelerator Disabled (Padding Enable) */
+#define IOH_GBE_RX_TCPIPACC_OFF 0x00000004
+/* TX TCP/IP accelerator and Padding Enable */
+#define IOH_GBE_TX_TCPIPACC_EN  0x00000002
+/* RX TCP/IP accelerator and Padding Enable */
+#define IOH_GBE_RX_TCPIPACC_EN  0x00000001
+
+/* External List */
+/* Interrupt Status Hold */
+/* PHY Interrupt Control */
+
+/* MAC RX Enable */
+#define IOH_GBE_MRE_MAC_RX_EN   0x00000001      /* MAC Receive Enable */
+
+/* RX Flow Control */
+/* Pause packet and Transmission Pause are enabled */
+#define IOH_GBE_FL_CTRL_EN      0x80000000
+
+/* Pause Packet Request */
+#define IOH_GBE_PS_PKT_RQ       0x80000000      /* Pause packet Request */
+
+/* RX Mode */
+/* Address Filtering Enable */
+#define IOH_GBE_ADD_FIL_EN      0x80000000
+/* Multicast Filtering Enable */
+#define IOH_GBE_MLT_FIL_EN      0x40000000
+/* Receive Almost Empty Threshold */
+#define IOH_GBE_RH_ALM_EMP_4    0x00000000      /* 4 words */
+#define IOH_GBE_RH_ALM_EMP_8    0x00004000      /* 8 words */
+#define IOH_GBE_RH_ALM_EMP_16   0x00008000      /* 16 words */
+#define IOH_GBE_RH_ALM_EMP_32   0x0000C000      /* 32 words */
+/* Receive Almost Full Threshold */
+#define IOH_GBE_RH_ALM_FULL_4   0x00000000      /* 4 words */
+#define IOH_GBE_RH_ALM_FULL_8   0x00001000      /* 8 words */
+#define IOH_GBE_RH_ALM_FULL_16  0x00002000      /* 16 words */
+#define IOH_GBE_RH_ALM_FULL_32  0x00003000      /* 32 words */
+/* RX FIFO Read Triger Threshold */
+#define IOH_GBE_RH_RD_TRG_4     0x00000000      /* 4 words */
+#define IOH_GBE_RH_RD_TRG_8     0x00000200      /* 8 words */
+#define IOH_GBE_RH_RD_TRG_16    0x00000400      /* 16 words */
+#define IOH_GBE_RH_RD_TRG_32    0x00000600      /* 32 words */
+#define IOH_GBE_RH_RD_TRG_64    0x00000800      /* 64 words */
+#define IOH_GBE_RH_RD_TRG_128   0x00000A00      /* 128 words */
+#define IOH_GBE_RH_RD_TRG_256   0x00000C00      /* 256 words */
+#define IOH_GBE_RH_RD_TRG_512   0x00000E00      /* 512 words */
+
+	/* Receive Descriptor bit definitions */
+	#define IOH_GBE_RXD_ACC_STAT_BCAST          0x00000400
+	#define IOH_GBE_RXD_ACC_STAT_MCAST          0x00000200
+	#define IOH_GBE_RXD_ACC_STAT_UCAST          0x00000100
+	#define IOH_GBE_RXD_ACC_STAT_TCPIPOK        0x000000C0
+	#define IOH_GBE_RXD_ACC_STAT_IPOK           0x00000080
+	#define IOH_GBE_RXD_ACC_STAT_TCPOK          0x00000040
+	#define IOH_GBE_RXD_ACC_STAT_IP6ERR         0x00000020
+	#define IOH_GBE_RXD_ACC_STAT_OFLIST         0x00000010
+	#define IOH_GBE_RXD_ACC_STAT_TYPEIP         0x00000008
+	#define IOH_GBE_RXD_ACC_STAT_MACL           0x00000004
+	#define IOH_GBE_RXD_ACC_STAT_PPPOE          0x00000002
+	#define IOH_GBE_RXD_ACC_STAT_VTAGT          0x00000001
+	#define IOH_GBE_RXD_GMAC_STAT_PAUSE         0x0200
+	#define IOH_GBE_RXD_GMAC_STAT_MARBR         0x0100
+	#define IOH_GBE_RXD_GMAC_STAT_MARMLT        0x0080
+	#define IOH_GBE_RXD_GMAC_STAT_MARIND        0x0040
+	#define IOH_GBE_RXD_GMAC_STAT_MARNOTMT      0x0020
+	#define IOH_GBE_RXD_GMAC_STAT_TLONG         0x0010
+	#define IOH_GBE_RXD_GMAC_STAT_TSHRT         0x0008
+	#define IOH_GBE_RXD_GMAC_STAT_NOTOCTAL      0x0004
+	#define IOH_GBE_RXD_GMAC_STAT_NBLERR        0x0002
+	#define IOH_GBE_RXD_GMAC_STAT_CRCERR        0x0001
+
+	/* Transmit Descriptor bit definitions */
+	#define IOH_GBE_TXD_CTRL_TCPIP_ACC_OFF      0x0008
+	#define IOH_GBE_TXD_CTRL_ITAG               0x0004
+	#define IOH_GBE_TXD_CTRL_ICRC               0x0002
+	#define IOH_GBE_TXD_CTRL_APAD               0x0001
+	#define IOH_GBE_TXD_WORDS_SHIFT             2
+	#define IOH_GBE_TXD_GMAC_STAT_CMPLT         0x2000
+	#define IOH_GBE_TXD_GMAC_STAT_ABT           0x1000
+	#define IOH_GBE_TXD_GMAC_STAT_EXCOL         0x0800
+	#define IOH_GBE_TXD_GMAC_STAT_SNGCOL        0x0400
+	#define IOH_GBE_TXD_GMAC_STAT_MLTCOL        0x0200
+	#define IOH_GBE_TXD_GMAC_STAT_CRSER         0x0100
+	#define IOH_GBE_TXD_GMAC_STAT_TLNG          0x0080
+	#define IOH_GBE_TXD_GMAC_STAT_TSHRT         0x0040
+	#define IOH_GBE_TXD_GMAC_STAT_LTCOL         0x0020
+	#define IOH_GBE_TXD_GMAC_STAT_TFUNDFLW      0x0010
+	#define IOH_GBE_TXD_GMAC_STAT_RTYCNT_MASK   0x000F
+
+/* TX Mode */
+#define IOH_GBE_TM_NO_RTRY     0x80000000 /* No Retransmission */
+#define IOH_GBE_TM_LONG_PKT    0x40000000 /* Long Packt TX Enable */
+#define IOH_GBE_TM_ST_AND_FD   0x20000000 /* Stare and Forward */
+#define IOH_GBE_TM_SHORT_PKT   0x10000000 /* Short Packet TX Enable */
+#define IOH_GBE_TM_LTCOL_RETX  0x08000000 /* Retransmission at Late Collision */
+/* Frame Start Threshold */
+#define IOH_GBE_TM_TH_TX_STRT_4    0x00000000    /* 4 words */
+#define IOH_GBE_TM_TH_TX_STRT_8    0x00004000    /* 8 words */
+#define IOH_GBE_TM_TH_TX_STRT_16   0x00008000    /* 16 words */
+#define IOH_GBE_TM_TH_TX_STRT_32   0x0000C000    /* 32 words */
+/* Transmit Almost Empty Threshold */
+#define IOH_GBE_TM_TH_ALM_EMP_4    0x00000000    /* 4 words */
+#define IOH_GBE_TM_TH_ALM_EMP_8    0x00000800    /* 8 words */
+#define IOH_GBE_TM_TH_ALM_EMP_16   0x00001000    /* 16 words */
+#define IOH_GBE_TM_TH_ALM_EMP_32   0x00001800    /* 32 words */
+#define IOH_GBE_TM_TH_ALM_EMP_64   0x00002000    /* 64 words */
+#define IOH_GBE_TM_TH_ALM_EMP_128  0x00002800    /* 128 words */
+#define IOH_GBE_TM_TH_ALM_EMP_256  0x00003000    /* 256 words */
+#define IOH_GBE_TM_TH_ALM_EMP_512  0x00003800    /* 512 words */
+/* Transmit Almost Full Threshold */
+#define IOH_GBE_TM_TH_ALM_FULL_4   0x00000000    /* 4 words */
+#define IOH_GBE_TM_TH_ALM_FULL_8   0x00000200    /* 8 words */
+#define IOH_GBE_TM_TH_ALM_FULL_16  0x00000400    /* 16 words */
+#define IOH_GBE_TM_TH_ALM_FULL_32  0x00000600    /* 32 words */
+
+/* RX FIFO Status */
+/* RX FIFO is almost full. */
+#define IOH_GBE_RF_ALM_FULL     0x80000000
+/* RX FIFO is almost empty. */
+#define IOH_GBE_RF_ALM_EMP      0x40000000
+/* that the data within RX FIFO has become more than RH_RD_TRG. */
+#define IOH_GBE_RF_RD_TRG       0x20000000
+/* The word count of the data existing within RX FIFO. */
+#define IOH_GBE_RF_STRWD        0x1FFE0000
+/* that frame which is currently valid/enabled is stored in RX FIFO. */
+#define IOH_GBE_RF_RCVING       0x00010000
+
+/* TX FIFO Status */
+/* TX Frame ID */
+/* TX Result */
+/* Pause Packet1-5 */
+/* MAC Address 1(A/B)- 16*/
+/* MAC Address Mask */
+#define IOH_GBE_BUSY                0x80000000
+
+/* MIIM  */
+#define IOH_GBE_MIIM_OPER_WRITE     0x04000000
+#define IOH_GBE_MIIM_OPER_READ      0x00000000
+#define IOH_GBE_MIIM_OPER_READY     0x04000000
+#define IOH_GBE_MIIM_PHY_ADDR_SHIFT 21
+#define IOH_GBE_MIIM_REG_ADDR_SHIFT 16
+
+/* RGMII Status */
+#define IOH_GBE_LINK_UP             0x80000008
+#define IOH_GBE_RXC_SPEED_MSK       0x00000006
+#define IOH_GBE_RXC_SPEED_2_5M      0x00000000    /* 2.5MHz */
+#define IOH_GBE_RXC_SPEED_25M       0x00000002    /* 25MHz  */
+#define IOH_GBE_RXC_SPEED_125M      0x00000004    /* 100MHz */
+#define IOH_GBE_DUPLEX_FULL         0x00000001
+
+/* RGMII Control */
+#define IOH_GBE_CRS_SEL             0x00000010
+#define IOH_GBE_RGMII_RATE_125M     0x00000000
+#define IOH_GBE_RGMII_RATE_25M      0x00000008
+#define IOH_GBE_RGMII_RATE_2_5M     0x0000000C
+#define IOH_GBE_RGMII_MODE_GMII     0x00000000
+#define IOH_GBE_RGMII_MODE_RGMII    0x00000002
+#define IOH_GBE_CHIP_TYPE_EXTERNAL  0x00000000
+#define IOH_GBE_CHIP_TYPE_INTERNAL  0x00000001
+
+/* DMA Control */
+#define IOH_GBE_RX_DMA_EN           0x00000002   /* Enables Receive DMA */
+#define IOH_GBE_TX_DMA_EN           0x00000001   /* Enables Transmission DMA */
+
+
+
+/* RX Descriptor Base Address */
+/* RX Descriptor Size */
+/* RX Descriptor Hard Pointer  */
+/* RX Descriptor Hard Pointer Hold */
+/* RX Descriptor Soft Pointer  */
+/* TX Descriptor Base Address */
+/* TX Descriptor Size */
+/* TX Descriptor Hard Pointer  */
+/* TX Descriptor Hard Pointer Hold */
+/* TX Descriptor Soft Pointer  */
+
+/* RX DMA Status */
+/* TX DMA Status */
+
+
+/* Wake On LAN Status */
+#define IOH_GBE_WLS_BR          0x00000008 /* Broadcas Address */
+#define IOH_GBE_WLS_MLT         0x00000004 /* Multicast Address */
+/* The Frame registered in Address Recognizer */
+#define IOH_GBE_WLS_IND         0x00000002
+#define IOH_GBE_WLS_MP          0x00000001 /* Magic packet Address */
+
+/* Wake On LAN Control */
+#define IOH_GBE_WLC_WOL_MODE    0x00010000
+#define IOH_GBE_WLC_IGN_TLONG   0x00000100
+#define IOH_GBE_WLC_IGN_TSHRT   0x00000080
+#define IOH_GBE_WLC_IGN_OCTER   0x00000040
+#define IOH_GBE_WLC_IGN_NBLER   0x00000020
+#define IOH_GBE_WLC_IGN_CRCER   0x00000010
+#define IOH_GBE_WLC_BR          0x00000008
+#define IOH_GBE_WLC_MLT         0x00000004
+#define IOH_GBE_WLC_IND         0x00000002
+#define IOH_GBE_WLC_MP          0x00000001
+
+/* Wake On LAN Address Mask */
+#define IOH_GBE_WLA_BUSY        0x80000000
+
+#endif
