[PATCH 02/26] atl1: move common functions to atlx files

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: jacliburn
Date: Monday, December 31, 2007 - 6:59 pm

From: Jay Cliburn <jacliburn@bellsouth.net>

The future atl2 driver and the existing atl1 driver can share certain
functions and definitions.  Move these shareable functions and definitions
out of atl1-specific files and into atlx.c and atlx.h.  Some transitory
hackery will be present until atl2 is merged.

Reduce the number of source files by moving ethtool, hw, and param
functions from separate files into atl1_main.c, then rename it to just
atl1.c.

Move all atl1-specific definitions from atl1_hw.h to atl1.h.

Finally, clean up to make checkpatch.pl happy.

Signed-off-by: Chris Snook <csnook@redhat.com>
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
 drivers/net/atlx/Makefile                |    1 -
 drivers/net/atlx/{atl1_main.c => atl1.c} | 1544 ++++++++++++++++++++++++------
 drivers/net/atlx/atl1.h                  |  603 +++++++++++-
 drivers/net/atlx/atl1_ethtool.c          |  505 ----------
 drivers/net/atlx/atl1_hw.c               |  720 --------------
 drivers/net/atlx/atl1_hw.h               |  946 ------------------
 drivers/net/atlx/atl1_param.c            |  203 ----
 drivers/net/atlx/atlx.c                  |  433 +++++++++
 drivers/net/atlx/atlx.h                  |  506 ++++++++++
 9 files changed, 2751 insertions(+), 2710 deletions(-)
 rename drivers/net/atlx/{atl1_main.c => atl1.c} (65%)
 delete mode 100644 drivers/net/atlx/atl1_ethtool.c
 delete mode 100644 drivers/net/atlx/atl1_hw.c
 delete mode 100644 drivers/net/atlx/atl1_hw.h
 delete mode 100644 drivers/net/atlx/atl1_param.c
 create mode 100644 drivers/net/atlx/atlx.c
 create mode 100644 drivers/net/atlx/atlx.h

diff --git a/drivers/net/atlx/Makefile b/drivers/net/atlx/Makefile
index a6b707e..ca45553 100644
--- a/drivers/net/atlx/Makefile
+++ b/drivers/net/atlx/Makefile
@@ -1,2 +1 @@
 obj-$(CONFIG_ATL1)	+= atl1.o
-atl1-y			+= atl1_main.o atl1_hw.o atl1_ethtool.o atl1_param.o
diff --git a/drivers/net/atlx/atl1_main.c b/drivers/net/atlx/atl1.c
similarity index 65%
rename from drivers/net/atlx/atl1_main.c
rename to drivers/net/atlx/atl1.c
index 35b0a7d..0df3f32 100644
--- a/drivers/net/atlx/atl1_main.c
+++ b/drivers/net/atlx/atl1.c
@@ -1,6 +1,6 @@
 /*
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
- * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
+ * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
  * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
  *
  * Derived from Intel e1000 driver
@@ -50,51 +50,46 @@
  * SMP torture testing
  */
 
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/skbuff.h>
+#include <asm/atomic.h>
+#include <asm/byteorder.h>
+
+#include <linux/compiler.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
-#include <linux/if_vlan.h>
-#include <linux/if_ether.h>
-#include <linux/irqreturn.h>
-#include <linux/workqueue.h>
-#include <linux/timer.h>
-#include <linux/jiffies.h>
 #include <linux/hardirq.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/in.h>
 #include <linux/interrupt.h>
+#include <linux/ip.h>
 #include <linux/irqflags.h>
-#include <linux/dma-mapping.h>
+#include <linux/irqreturn.h>
+#include <linux/jiffies.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <linux/pm.h>
-#include <linux/in.h>
-#include <linux/ip.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
 #include <linux/tcp.h>
-#include <linux/compiler.h>
-#include <linux/delay.h>
-#include <linux/mii.h>
-#include <net/checksum.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
 
-#include <asm/atomic.h>
-#include <asm/byteorder.h>
+#include <net/checksum.h>
 
 #include "atl1.h"
 
-#define DRIVER_VERSION "2.0.7"
-
-char atl1_driver_name[] = "atl1";
-static const char atl1_driver_string[] = "Attansic L1 Ethernet Network Driver";
-static const char atl1_copyright[] = "Copyright(c) 2005-2006 Attansic Corporation.";
-char atl1_driver_version[] = DRIVER_VERSION;
-
-MODULE_AUTHOR
-    ("Attansic Corporation <xiong_huang@attansic.com>, Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
-MODULE_DESCRIPTION("Attansic 1000M Ethernet Network Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
+/* Temporary hack for merging atl1 and atl2 */
+#include "atlx.c"
 
 /*
  * atl1_pci_tbl - PCI Device ID Table
@@ -104,7 +99,6 @@ static const struct pci_device_id atl1_pci_tbl[] = {
 	/* required last entry */
 	{0,}
 };
-
 MODULE_DEVICE_TABLE(pci, atl1_pci_tbl);
 
 /*
@@ -125,7 +119,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
 
 	adapter->wol = 0;
 	adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
-	adapter->ict = 50000;	/* 100ms */
+	adapter->ict = 50000;		/* 100ms */
 	adapter->link_speed = SPEED_0;	/* hardware init */
 	adapter->link_duplex = FULL_DUPLEX;
 
@@ -206,24 +200,6 @@ static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 }
 
 /*
- * atl1_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-	switch (cmd) {
-	case SIOCGMIIPHY:
-	case SIOCGMIIREG:
-	case SIOCSMIIREG:
-		return atl1_mii_ioctl(netdev, ifr, cmd);
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
-/*
  * atl1_setup_mem_resources - allocate Tx / RX descriptor resources
  * @adapter: board private structure
  *
@@ -248,7 +224,8 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 	rfd_ring->buffer_info =
 		(struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
 
-	/* real ring DMA buffer
+	/*
+	 * real ring DMA buffer
 	 * each ring/block may need up to 8 bytes for alignment, hence the
 	 * additional 40 bytes tacked onto the end.
 	 */
@@ -307,7 +284,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 		((u8 *) adapter->cmb.cmb +
 		(sizeof(struct coals_msg_block) + offset));
 
-	return ATL1_SUCCESS;
+	return 0;
 
 err_nomem:
 	kfree(tpd_ring->buffer_info);
@@ -481,31 +458,6 @@ static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
 	iowrite32(value, hw->hw_addr + REG_MAC_CTRL);
 }
 
-/*
- * atl1_set_mac - Change the Ethernet Address of the NIC
- * @netdev: network interface device structure
- * @p: pointer to an address structure
- *
- * Returns 0 on success, negative on failure
- */
-static int atl1_set_mac(struct net_device *netdev, void *p)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	struct sockaddr *addr = p;
-
-	if (netif_running(netdev))
-		return -EBUSY;
-
-	if (!is_valid_ether_addr(addr->sa_data))
-		return -EADDRNOTAVAIL;
-
-	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
-
-	atl1_set_mac_addr(&adapter->hw);
-	return 0;
-}
-
 static u32 atl1_check_link(struct atl1_adapter *adapter)
 {
 	struct atl1_hw *hw = &adapter->hw;
@@ -517,14 +469,16 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
 	/* MII_BMSR must read twice */
 	atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
 	atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
-	if (!(phy_data & BMSR_LSTATUS)) {	/* link down */
-		if (netif_carrier_ok(netdev)) {	/* old link state: Up */
+	if (!(phy_data & BMSR_LSTATUS)) {
+		/* link down */
+		if (netif_carrier_ok(netdev)) {
+			/* old link state: Up */
 			dev_info(&adapter->pdev->dev, "link is down\n");
 			adapter->link_speed = SPEED_0;
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 		}
-		return ATL1_SUCCESS;
+		return 0;
 	}
 
 	/* Link Up */
@@ -568,14 +522,15 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
 				adapter->link_duplex == FULL_DUPLEX ?
 				"full duplex" : "half duplex");
 		}
-		if (!netif_carrier_ok(netdev)) {	/* Link down -> Up */
+		if (!netif_carrier_ok(netdev)) {
+			/* Link down -> Up */
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
 		}
-		return ATL1_SUCCESS;
+		return 0;
 	}
 
-	/* change orignal link status */
+	/* change original link status */
 	if (netif_carrier_ok(netdev)) {
 		adapter->link_speed = SPEED_0;
 		netif_carrier_off(netdev);
@@ -596,12 +551,13 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
 			phy_data =
 			    MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
 			break;
-		default:	/* MEDIA_TYPE_10M_HALF: */
+		default:
+			/* MEDIA_TYPE_10M_HALF: */
 			phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
 			break;
 		}
 		atl1_write_phy_reg(hw, MII_BMCR, phy_data);
-		return ATL1_SUCCESS;
+		return 0;
 	}
 
 	/* auto-neg, insert timer to re-config phy */
@@ -610,71 +566,7 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
 		mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ);
 	}
 
-	return ATL1_SUCCESS;
-}
-
-static void atl1_check_for_link(struct atl1_adapter *adapter)
-{
-	struct net_device *netdev = adapter->netdev;
-	u16 phy_data = 0;
-
-	spin_lock(&adapter->lock);
-	adapter->phy_timer_pending = false;
-	atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-	atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-	spin_unlock(&adapter->lock);
-
-	/* notify upper layer link down ASAP */
-	if (!(phy_data & BMSR_LSTATUS)) {	/* Link Down */
-		if (netif_carrier_ok(netdev)) {	/* old link state: Up */
-			dev_info(&adapter->pdev->dev, "%s link is down\n",
-				netdev->name);
-			adapter->link_speed = SPEED_0;
-			netif_carrier_off(netdev);
-			netif_stop_queue(netdev);
-		}
-	}
-	schedule_work(&adapter->link_chg_task);
-}
-
-/*
- * atl1_set_multi - Multicast and Promiscuous mode set
- * @netdev: network interface device structure
- *
- * 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 atl1_set_multi(struct net_device *netdev)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	struct atl1_hw *hw = &adapter->hw;
-	struct dev_mc_list *mc_ptr;
-	u32 rctl;
-	u32 hash_value;
-
-	/* Check for Promiscuous and All Multicast modes */
-	rctl = ioread32(hw->hw_addr + REG_MAC_CTRL);
-	if (netdev->flags & IFF_PROMISC)
-		rctl |= MAC_CTRL_PROMIS_EN;
-	else if (netdev->flags & IFF_ALLMULTI) {
-		rctl |= MAC_CTRL_MC_ALL_EN;
-		rctl &= ~MAC_CTRL_PROMIS_EN;
-	} else
-		rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
-
-	iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL);
-
-	/* clear the old settings from the multicast hash table */
-	iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
-	iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
-
-	/* compute mc addresses' hash value ,and put it into hash table */
-	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
-		hash_value = atl1_hash_mc_addr(hw, mc_ptr->dmi_addr);
-		atl1_hash_set(hw, hash_value);
-	}
+	return 0;
 }
 
 /*
@@ -974,37 +866,6 @@ static void atl1_via_workaround(struct atl1_adapter *adapter)
 	iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
 }
 
-/*
- * atl1_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- */
-static void atl1_irq_enable(struct atl1_adapter *adapter)
-{
-	iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
-	ioread32(adapter->hw.hw_addr + REG_IMR);
-}
-
-/*
- * atl1_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- */
-static void atl1_irq_disable(struct atl1_adapter *adapter)
-{
-	iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-	ioread32(adapter->hw.hw_addr + REG_IMR);
-	synchronize_irq(adapter->pdev->irq);
-}
-
-static void atl1_clear_phy_int(struct atl1_adapter *adapter)
-{
-	u16 phy_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	atl1_read_phy_reg(&adapter->hw, 19, &phy_data);
-	spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
 static void atl1_inc_smb(struct atl1_adapter *adapter)
 {
 	struct stats_msg_block *smb = adapter->smb.smb;
@@ -1076,19 +937,6 @@ static void atl1_inc_smb(struct atl1_adapter *adapter)
 		adapter->soft_stats.tx_carrier_errors;
 }
 
-/*
- * atl1_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- */
-static struct net_device_stats *atl1_get_stats(struct net_device *netdev)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	return &adapter->net_stats;
-}
-
 static void atl1_update_mailbox(struct atl1_adapter *adapter)
 {
 	unsigned long flags;
@@ -1210,7 +1058,8 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
 		rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
 
 		skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
-		if (unlikely(!skb)) {	/* Better luck next round */
+		if (unlikely(!skb)) {
+			/* Better luck next round */
 			adapter->net_stats.rx_dropped++;
 			break;
 		}
@@ -1519,7 +1368,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
 	buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
 	if (unlikely(buffer_info->skb))
 		BUG();
-	buffer_info->skb = NULL;	/* put skb in last TPD */
+	/* put skb in last TPD */
+	buffer_info->skb = NULL;
 
 	if (tcp_seg) {
 		/* TSO/GSO */
@@ -1779,7 +1629,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
 		adapter->cmb.cmb->int_stats = 0;
 
 		if (status & ISR_GPHY)	/* clear phy status */
-			atl1_clear_phy_int(adapter);
+			atlx_clear_phy_int(adapter);
 
 		/* clear ISR status, and Enable CMB DMA/Disable Interrupt */
 		iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
@@ -1866,23 +1716,12 @@ static void atl1_phy_config(unsigned long data)
 	spin_lock_irqsave(&adapter->lock, flags);
 	adapter->phy_timer_pending = false;
 	atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
-	atl1_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg);
+	atl1_write_phy_reg(hw, MII_ATLX_CR, hw->mii_1000t_ctrl_reg);
 	atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN);
 	spin_unlock_irqrestore(&adapter->lock, flags);
 }
 
 /*
- * atl1_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- */
-static void atl1_tx_timeout(struct net_device *netdev)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	/* Do the reset outside of interrupt context */
-	schedule_work(&adapter->tx_timeout_task);
-}
-
-/*
  * Orphaned vendor comment left intact here:
  * <vendor comment>
  * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
@@ -1904,58 +1743,11 @@ static void atl1_tx_timeout_task(struct work_struct *work)
 	netif_device_attach(netdev);
 }
 
-/*
- * atl1_link_chg_task - deal with link change event Out of interrupt context
- */
-static void atl1_link_chg_task(struct work_struct *work)
-{
-	struct atl1_adapter *adapter =
-               container_of(work, struct atl1_adapter, link_chg_task);
-	unsigned long flags;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	atl1_check_link(adapter);
-	spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static void atl1_vlan_rx_register(struct net_device *netdev,
-	struct vlan_group *grp)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	unsigned long flags;
-	u32 ctrl;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	/* atl1_irq_disable(adapter); */
-	adapter->vlgrp = grp;
-
-	if (grp) {
-		/* enable VLAN tag insert/strip */
-		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
-		ctrl |= MAC_CTRL_RMV_VLAN;
-		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
-	} else {
-		/* disable VLAN tag insert/strip */
-		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
-		ctrl &= ~MAC_CTRL_RMV_VLAN;
-		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
-	}
-
-	/* atl1_irq_enable(adapter); */
-	spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static void atl1_restore_vlan(struct atl1_adapter *adapter)
-{
-	atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-}
-
 int atl1_reset(struct atl1_adapter *adapter)
 {
 	int ret;
-
 	ret = atl1_reset_hw(&adapter->hw);
-	if (ret != ATL1_SUCCESS)
+	if (ret)
 		return ret;
 	return atl1_init_hw(&adapter->hw);
 }
@@ -1967,11 +1759,12 @@ s32 atl1_up(struct atl1_adapter *adapter)
 	int irq_flags = IRQF_SAMPLE_RANDOM;
 
 	/* hardware has been reset, we need to reload some things */
-	atl1_set_multi(netdev);
+	atlx_set_multi(netdev);
 	atl1_init_ring_ptrs(adapter);
-	atl1_restore_vlan(adapter);
+	atlx_restore_vlan(adapter);
 	err = atl1_alloc_rx_buffers(adapter);
-	if (unlikely(!err))		/* no RX BUFFER allocated */
+	if (unlikely(!err))
+		/* no RX BUFFER allocated */
 		return -ENOMEM;
 
 	if (unlikely(atl1_configure(adapter))) {
@@ -1992,7 +1785,7 @@ s32 atl1_up(struct atl1_adapter *adapter)
 		goto err_up;
 
 	mod_timer(&adapter->watchdog_timer, jiffies);
-	atl1_irq_enable(adapter);
+	atlx_irq_enable(adapter);
 	atl1_check_link(adapter);
 	return 0;
 
@@ -2011,7 +1804,7 @@ void atl1_down(struct atl1_adapter *adapter)
 	del_timer_sync(&adapter->phy_config_timer);
 	adapter->phy_timer_pending = false;
 
-	atl1_irq_disable(adapter);
+	atlx_irq_disable(adapter);
 	free_irq(adapter->pdev->irq, netdev);
 	pci_disable_msi(adapter->pdev);
 	atl1_reset_hw(&adapter->hw);
@@ -2094,7 +1887,7 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
 	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
 	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
 	if (ctrl & BMSR_LSTATUS)
-		wufc &= ~ATL1_WUFC_LNKC;
+		wufc &= ~ATLX_WUFC_LNKC;
 
 	/* reduce speed to 10/100M */
 	if (wufc) {
@@ -2102,15 +1895,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
 		/* if resume, let driver to re- setup link */
 		hw->phy_configured = false;
 		atl1_set_mac_addr(hw);
-		atl1_set_multi(netdev);
+		atlx_set_multi(netdev);
 
 		ctrl = 0;
 		/* turn on magic packet wol */
-		if (wufc & ATL1_WUFC_MAG)
+		if (wufc & ATLX_WUFC_MAG)
 			ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
 
 		/* turn on Link change WOL */
-		if (wufc & ATL1_WUFC_LNKC)
+		if (wufc & ATLX_WUFC_LNKC)
 			ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
 		iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
 
@@ -2118,13 +1911,13 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
 		ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL);
 		ctrl &= ~MAC_CTRL_DBG;
 		ctrl &= ~MAC_CTRL_PROMIS_EN;
-		if (wufc & ATL1_WUFC_MC)
+		if (wufc & ATLX_WUFC_MC)
 			ctrl |= MAC_CTRL_MC_ALL_EN;
 		else
 			ctrl &= ~MAC_CTRL_MC_ALL_EN;
 
 		/* turn on broadcast mode if wake on-BC is enabled */
-		if (wufc & ATL1_WUFC_BC)
+		if (wufc & ATLX_WUFC_BC)
 			ctrl |= MAC_CTRL_BC_EN;
 		else
 			ctrl &= ~MAC_CTRL_BC_EN;
@@ -2152,12 +1945,13 @@ static int atl1_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct atl1_adapter *adapter = netdev_priv(netdev);
-	u32 ret_val;
+	u32 err;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
-	ret_val = pci_enable_device(pdev);
+	/* FIXME: check and handle */
+	err = pci_enable_device(pdev);
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
 
@@ -2224,14 +2018,16 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 		dev_err(&pdev->dev, "no usable DMA configuration\n");
 		goto err_dma;
 	}
-	/* Mark all PCI regions associated with PCI device
+	/*
+	 * Mark all PCI regions associated with PCI device
 	 * pdev as being reserved by owner atl1_driver_name
 	 */
-	err = pci_request_regions(pdev, atl1_driver_name);
+	err = pci_request_regions(pdev, ATLX_DRIVER_NAME);
 	if (err)
 		goto err_request_regions;
 
-	/* Enables bus-mastering on the device and calls
+	/*
+	 * Enables bus-mastering on the device and calls
 	 * pcibios_set_master to do the needed arch specific settings
 	 */
 	pci_set_master(pdev);
@@ -2257,7 +2053,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	/* get device revision number */
 	adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
 		(REG_MASTER_CTRL + 2));
-	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
+	dev_info(&pdev->dev, "version %s\n", ATLX_DRIVER_VERSION);
 
 	/* set default ring resource counts */
 	adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD;
@@ -2272,17 +2068,17 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	netdev->open = &atl1_open;
 	netdev->stop = &atl1_close;
 	netdev->hard_start_xmit = &atl1_xmit_frame;
-	netdev->get_stats = &atl1_get_stats;
-	netdev->set_multicast_list = &atl1_set_multi;
+	netdev->get_stats = &atlx_get_stats;
+	netdev->set_multicast_list = &atlx_set_multi;
 	netdev->set_mac_address = &atl1_set_mac;
 	netdev->change_mtu = &atl1_change_mtu;
-	netdev->do_ioctl = &atl1_ioctl;
-	netdev->tx_timeout = &atl1_tx_timeout;
+	netdev->do_ioctl = &atlx_ioctl;
+	netdev->tx_timeout = &atlx_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	netdev->poll_controller = atl1_poll_controller;
 #endif
-	netdev->vlan_rx_register = atl1_vlan_rx_register;
+	netdev->vlan_rx_register = atlx_vlan_rx_register;
 
 	netdev->ethtool_ops = &atl1_ethtool_ops;
 	adapter->bd_number = cards_found;
@@ -2312,7 +2108,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	/* atl1_pcie_patch(adapter); */
 
 	/* really reset GPHY core */
-	iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE);
+	iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
 
 	/*
 	 * reset the controller to
@@ -2357,7 +2153,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 
 	INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
 
-	INIT_WORK(&adapter->link_chg_task, atl1_link_chg_task);
+	INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
 
 	INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
 
@@ -2400,7 +2196,8 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
 
 	adapter = netdev_priv(netdev);
 
-	/* Some atl1 boards lack persistent storage for their MAC, and get it
+	/*
+	 * Some atl1 boards lack persistent storage for their MAC, and get it
 	 * from the BIOS during POST.  If we've been messing with the MAC
 	 * address, we need to save the permanent one.
 	 */
@@ -2410,7 +2207,7 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
 		atl1_set_mac_addr(&adapter->hw);
 	}
 
-	iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE);
+	iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
 	unregister_netdev(netdev);
 	pci_iounmap(pdev, adapter->hw.hw_addr);
 	pci_release_regions(pdev);
@@ -2419,7 +2216,7 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
 }
 
 static struct pci_driver atl1_driver = {
-	.name = atl1_driver_name,
+	.name = ATLX_DRIVER_NAME,
 	.id_table = atl1_pci_tbl,
 	.probe = atl1_probe,
 	.remove = __devexit_p(atl1_remove),
@@ -2451,3 +2248,1170 @@ static int __init atl1_init_module(void)
 
 module_init(atl1_init_module);
 module_exit(atl1_exit_module);
+
+struct atl1_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+};
+
+#define ATL1_STAT(m) \
+	sizeof(((struct atl1_adapter *)0)->m), offsetof(struct atl1_adapter, m)
+
+static struct atl1_stats atl1_gstrings_stats[] = {
+	{"rx_packets", ATL1_STAT(soft_stats.rx_packets)},
+	{"tx_packets", ATL1_STAT(soft_stats.tx_packets)},
+	{"rx_bytes", ATL1_STAT(soft_stats.rx_bytes)},
+	{"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)},
+	{"rx_errors", ATL1_STAT(soft_stats.rx_errors)},
+	{"tx_errors", ATL1_STAT(soft_stats.tx_errors)},
+	{"rx_dropped", ATL1_STAT(net_stats.rx_dropped)},
+	{"tx_dropped", ATL1_STAT(net_stats.tx_dropped)},
+	{"multicast", ATL1_STAT(soft_stats.multicast)},
+	{"collisions", ATL1_STAT(soft_stats.collisions)},
+	{"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)},
+	{"rx_over_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
+	{"rx_crc_errors", ATL1_STAT(soft_stats.rx_crc_errors)},
+	{"rx_frame_errors", ATL1_STAT(soft_stats.rx_frame_errors)},
+	{"rx_fifo_errors", ATL1_STAT(soft_stats.rx_fifo_errors)},
+	{"rx_missed_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
+	{"tx_aborted_errors", ATL1_STAT(soft_stats.tx_aborted_errors)},
+	{"tx_carrier_errors", ATL1_STAT(soft_stats.tx_carrier_errors)},
+	{"tx_fifo_errors", ATL1_STAT(soft_stats.tx_fifo_errors)},
+	{"tx_window_errors", ATL1_STAT(soft_stats.tx_window_errors)},
+	{"tx_abort_exce_coll", ATL1_STAT(soft_stats.excecol)},
+	{"tx_abort_late_coll", ATL1_STAT(soft_stats.latecol)},
+	{"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)},
+	{"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)},
+	{"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)},
+	{"tx_underun", ATL1_STAT(soft_stats.tx_underun)},
+	{"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)},
+	{"tx_pause", ATL1_STAT(soft_stats.tx_pause)},
+	{"rx_pause", ATL1_STAT(soft_stats.rx_pause)},
+	{"rx_rrd_ov", ATL1_STAT(soft_stats.rx_rrd_ov)},
+	{"rx_trunc", ATL1_STAT(soft_stats.rx_trunc)}
+};
+
+static void atl1_get_ethtool_stats(struct net_device *netdev,
+	struct ethtool_stats *stats, u64 *data)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	int i;
+	char *p;
+
+	for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
+		p = (char *)adapter+atl1_gstrings_stats[i].stat_offset;
+		data[i] = (atl1_gstrings_stats[i].sizeof_stat ==
+			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+	}
+
+}
+
+static int atl1_get_sset_count(struct net_device *netdev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(atl1_gstrings_stats);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int atl1_get_settings(struct net_device *netdev,
+	struct ethtool_cmd *ecmd)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+
+	ecmd->supported = (SUPPORTED_10baseT_Half |
+			   SUPPORTED_10baseT_Full |
+			   SUPPORTED_100baseT_Half |
+			   SUPPORTED_100baseT_Full |
+			   SUPPORTED_1000baseT_Full |
+			   SUPPORTED_Autoneg | SUPPORTED_TP);
+	ecmd->advertising = ADVERTISED_TP;
+	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+	    hw->media_type == MEDIA_TYPE_1000M_FULL) {
+		ecmd->advertising |= ADVERTISED_Autoneg;
+		if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR) {
+			ecmd->advertising |= ADVERTISED_Autoneg;
+			ecmd->advertising |=
+			    (ADVERTISED_10baseT_Half |
+			     ADVERTISED_10baseT_Full |
+			     ADVERTISED_100baseT_Half |
+			     ADVERTISED_100baseT_Full |
+			     ADVERTISED_1000baseT_Full);
+		} else
+			ecmd->advertising |= (ADVERTISED_1000baseT_Full);
+	}
+	ecmd->port = PORT_TP;
+	ecmd->phy_address = 0;
+	ecmd->transceiver = XCVR_INTERNAL;
+
+	if (netif_carrier_ok(adapter->netdev)) {
+		u16 link_speed, link_duplex;
+		atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
+		ecmd->speed = link_speed;
+		if (link_duplex == FULL_DUPLEX)
+			ecmd->duplex = DUPLEX_FULL;
+		else
+			ecmd->duplex = DUPLEX_HALF;
+	} else {
+		ecmd->speed = -1;
+		ecmd->duplex = -1;
+	}
+	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+	    hw->media_type == MEDIA_TYPE_1000M_FULL)
+		ecmd->autoneg = AUTONEG_ENABLE;
+	else
+		ecmd->autoneg = AUTONEG_DISABLE;
+
+	return 0;
+}
+
+static int atl1_set_settings(struct net_device *netdev,
+	struct ethtool_cmd *ecmd)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+	u16 phy_data;
+	int ret_val = 0;
+	u16 old_media_type = hw->media_type;
+
+	if (netif_running(adapter->netdev)) {
+		dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n");
+		atl1_down(adapter);
+	}
+
+	if (ecmd->autoneg == AUTONEG_ENABLE)
+		hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
+	else {
+		if (ecmd->speed == SPEED_1000) {
+			if (ecmd->duplex != DUPLEX_FULL) {
+				dev_warn(&adapter->pdev->dev,
+					"can't force to 1000M half duplex\n");
+				ret_val = -EINVAL;
+				goto exit_sset;
+			}
+			hw->media_type = MEDIA_TYPE_1000M_FULL;
+		} else if (ecmd->speed == SPEED_100) {
+			if (ecmd->duplex == DUPLEX_FULL)
+				hw->media_type = MEDIA_TYPE_100M_FULL;
+			else
+				hw->media_type = MEDIA_TYPE_100M_HALF;
+		} else {
+			if (ecmd->duplex == DUPLEX_FULL)
+				hw->media_type = MEDIA_TYPE_10M_FULL;
+			else
+				hw->media_type = MEDIA_TYPE_10M_HALF;
+		}
+	}
+	switch (hw->media_type) {
+	case MEDIA_TYPE_AUTO_SENSOR:
+		ecmd->advertising =
+		    ADVERTISED_10baseT_Half |
+		    ADVERTISED_10baseT_Full |
+		    ADVERTISED_100baseT_Half |
+		    ADVERTISED_100baseT_Full |
+		    ADVERTISED_1000baseT_Full |
+		    ADVERTISED_Autoneg | ADVERTISED_TP;
+		break;
+	case MEDIA_TYPE_1000M_FULL:
+		ecmd->advertising =
+		    ADVERTISED_1000baseT_Full |
+		    ADVERTISED_Autoneg | ADVERTISED_TP;
+		break;
+	default:
+		ecmd->advertising = 0;
+		break;
+	}
+	if (atl1_phy_setup_autoneg_adv(hw)) {
+		ret_val = -EINVAL;
+		dev_warn(&adapter->pdev->dev,
+			"invalid ethtool speed/duplex setting\n");
+		goto exit_sset;
+	}
+	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+	    hw->media_type == MEDIA_TYPE_1000M_FULL)
+		phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
+	else {
+		switch (hw->media_type) {
+		case MEDIA_TYPE_100M_FULL:
+			phy_data =
+			    MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
+			    MII_CR_RESET;
+			break;
+		case MEDIA_TYPE_100M_HALF:
+			phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
+			break;
+		case MEDIA_TYPE_10M_FULL:
+			phy_data =
+			    MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
+			break;
+		default:
+			/* MEDIA_TYPE_10M_HALF: */
+			phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
+			break;
+		}
+	}
+	atl1_write_phy_reg(hw, MII_BMCR, phy_data);
+exit_sset:
+	if (ret_val)
+		hw->media_type = old_media_type;
+
+	if (netif_running(adapter->netdev)) {
+		dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n");
+		atl1_up(adapter);
+	} else if (!ret_val) {
+		dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n");
+		atl1_reset(adapter);
+	}
+	return ret_val;
+}
+
+static void atl1_get_drvinfo(struct net_device *netdev,
+	struct ethtool_drvinfo *drvinfo)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+
+	strncpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
+	strncpy(drvinfo->version, ATLX_DRIVER_VERSION,
+		sizeof(drvinfo->version));
+	strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+	strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+		sizeof(drvinfo->bus_info));
+	drvinfo->eedump_len = ATL1_EEDUMP_LEN;
+}
+
+static void atl1_get_wol(struct net_device *netdev,
+	struct ethtool_wolinfo *wol)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+
+	wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+	wol->wolopts = 0;
+	if (adapter->wol & ATLX_WUFC_EX)
+		wol->wolopts |= WAKE_UCAST;
+	if (adapter->wol & ATLX_WUFC_MC)
+		wol->wolopts |= WAKE_MCAST;
+	if (adapter->wol & ATLX_WUFC_BC)
+		wol->wolopts |= WAKE_BCAST;
+	if (adapter->wol & ATLX_WUFC_MAG)
+		wol->wolopts |= WAKE_MAGIC;
+	return;
+}
+
+static int atl1_set_wol(struct net_device *netdev,
+	struct ethtool_wolinfo *wol)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+
+	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+		return -EOPNOTSUPP;
+	adapter->wol = 0;
+	if (wol->wolopts & WAKE_UCAST)
+		adapter->wol |= ATLX_WUFC_EX;
+	if (wol->wolopts & WAKE_MCAST)
+		adapter->wol |= ATLX_WUFC_MC;
+	if (wol->wolopts & WAKE_BCAST)
+		adapter->wol |= ATLX_WUFC_BC;
+	if (wol->wolopts & WAKE_MAGIC)
+		adapter->wol |= ATLX_WUFC_MAG;
+	return 0;
+}
+
+static void atl1_get_ringparam(struct net_device *netdev,
+	struct ethtool_ringparam *ring)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_tpd_ring *txdr = &adapter->tpd_ring;
+	struct atl1_rfd_ring *rxdr = &adapter->rfd_ring;
+
+	ring->rx_max_pending = ATL1_MAX_RFD;
+	ring->tx_max_pending = ATL1_MAX_TPD;
+	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;
+}
+
+static int atl1_set_ringparam(struct net_device *netdev,
+	struct ethtool_ringparam *ring)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_tpd_ring *tpdr = &adapter->tpd_ring;
+	struct atl1_rrd_ring *rrdr = &adapter->rrd_ring;
+	struct atl1_rfd_ring *rfdr = &adapter->rfd_ring;
+
+	struct atl1_tpd_ring tpd_old, tpd_new;
+	struct atl1_rfd_ring rfd_old, rfd_new;
+	struct atl1_rrd_ring rrd_old, rrd_new;
+	struct atl1_ring_header rhdr_old, rhdr_new;
+	int err;
+
+	tpd_old = adapter->tpd_ring;
+	rfd_old = adapter->rfd_ring;
+	rrd_old = adapter->rrd_ring;
+	rhdr_old = adapter->ring_header;
+
+	if (netif_running(adapter->netdev))
+		atl1_down(adapter);
+
+	rfdr->count = (u16) max(ring->rx_pending, (u32) ATL1_MIN_RFD);
+	rfdr->count = rfdr->count > ATL1_MAX_RFD ? ATL1_MAX_RFD :
+			rfdr->count;
+	rfdr->count = (rfdr->count + 3) & ~3;
+	rrdr->count = rfdr->count;
+
+	tpdr->count = (u16) max(ring->tx_pending, (u32) ATL1_MIN_TPD);
+	tpdr->count = tpdr->count > ATL1_MAX_TPD ? ATL1_MAX_TPD :
+			tpdr->count;
+	tpdr->count = (tpdr->count + 3) & ~3;
+
+	if (netif_running(adapter->netdev)) {
+		/* try to get new resources before deleting old */
+		err = atl1_setup_ring_resources(adapter);
+		if (err)
+			goto err_setup_ring;
+
+		/*
+		 * save the new, restore the old in order to free it,
+		 * then restore the new back again
+		 */
+
+		rfd_new = adapter->rfd_ring;
+		rrd_new = adapter->rrd_ring;
+		tpd_new = adapter->tpd_ring;
+		rhdr_new = adapter->ring_header;
+		adapter->rfd_ring = rfd_old;
+		adapter->rrd_ring = rrd_old;
+		adapter->tpd_ring = tpd_old;
+		adapter->ring_header = rhdr_old;
+		atl1_free_ring_resources(adapter);
+		adapter->rfd_ring = rfd_new;
+		adapter->rrd_ring = rrd_new;
+		adapter->tpd_ring = tpd_new;
+		adapter->ring_header = rhdr_new;
+
+		err = atl1_up(adapter);
+		if (err)
+			return err;
+	}
+	return 0;
+
+err_setup_ring:
+	adapter->rfd_ring = rfd_old;
+	adapter->rrd_ring = rrd_old;
+	adapter->tpd_ring = tpd_old;
+	adapter->ring_header = rhdr_old;
+	atl1_up(adapter);
+	return err;
+}
+
+static void atl1_get_pauseparam(struct net_device *netdev,
+	struct ethtool_pauseparam *epause)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+
+	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+	    hw->media_type == MEDIA_TYPE_1000M_FULL) {
+		epause->autoneg = AUTONEG_ENABLE;
+	} else {
+		epause->autoneg = AUTONEG_DISABLE;
+	}
+	epause->rx_pause = 1;
+	epause->tx_pause = 1;
+}
+
+static int atl1_set_pauseparam(struct net_device *netdev,
+	struct ethtool_pauseparam *epause)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+
+	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+	    hw->media_type == MEDIA_TYPE_1000M_FULL) {
+		epause->autoneg = AUTONEG_ENABLE;
+	} else {
+		epause->autoneg = AUTONEG_DISABLE;
+	}
+
+	epause->rx_pause = 1;
+	epause->tx_pause = 1;
+
+	return 0;
+}
+
+/* FIXME: is this right? -- CHS */
+static u32 atl1_get_rx_csum(struct net_device *netdev)
+{
+	return 1;
+}
+
+static void atl1_get_strings(struct net_device *netdev, u32 stringset,
+	u8 *data)
+{
+	u8 *p = data;
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
+			memcpy(p, atl1_gstrings_stats[i].stat_string,
+				ETH_GSTRING_LEN);
+			p += ETH_GSTRING_LEN;
+		}
+		break;
+	}
+}
+
+static int atl1_nway_reset(struct net_device *netdev)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+
+	if (netif_running(netdev)) {
+		u16 phy_data;
+		atl1_down(adapter);
+
+		if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+			hw->media_type == MEDIA_TYPE_1000M_FULL) {
+			phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
+		} else {
+			switch (hw->media_type) {
+			case MEDIA_TYPE_100M_FULL:
+				phy_data = MII_CR_FULL_DUPLEX |
+					MII_CR_SPEED_100 | MII_CR_RESET;
+				break;
+			case MEDIA_TYPE_100M_HALF:
+				phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
+				break;
+			case MEDIA_TYPE_10M_FULL:
+				phy_data = MII_CR_FULL_DUPLEX |
+					MII_CR_SPEED_10 | MII_CR_RESET;
+				break;
+			default:
+				/* MEDIA_TYPE_10M_HALF */
+				phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
+			}
+		}
+		atl1_write_phy_reg(hw, MII_BMCR, phy_data);
+		atl1_up(adapter);
+	}
+	return 0;
+}
+
+const struct ethtool_ops atl1_ethtool_ops = {
+	.get_settings		= atl1_get_settings,
+	.set_settings		= atl1_set_settings,
+	.get_drvinfo		= atl1_get_drvinfo,
+	.get_wol		= atl1_get_wol,
+	.set_wol		= atl1_set_wol,
+	.get_ringparam		= atl1_get_ringparam,
+	.set_ringparam		= atl1_set_ringparam,
+	.get_pauseparam		= atl1_get_pauseparam,
+	.set_pauseparam 	= atl1_set_pauseparam,
+	.get_rx_csum		= atl1_get_rx_csum,
+	.set_tx_csum		= ethtool_op_set_tx_hw_csum,
+	.get_link		= ethtool_op_get_link,
+	.set_sg			= ethtool_op_set_sg,
+	.get_strings		= atl1_get_strings,
+	.nway_reset		= atl1_nway_reset,
+	.get_ethtool_stats	= atl1_get_ethtool_stats,
+	.get_sset_count		= atl1_get_sset_count,
+	.set_tso		= ethtool_op_set_tso,
+};
+
+/*
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ * hw - Struct containing variables accessed by shared code
+ * return : 0  or  idle status (if error)
+ */
+s32 atl1_reset_hw(struct atl1_hw *hw)
+{
+	struct pci_dev *pdev = hw->back->pdev;
+	u32 icr;
+	int i;
+
+	/*
+	 * Clear Interrupt mask to stop board from generating
+	 * interrupts & Clear any pending interrupt events
+	 */
+	/*
+	 * iowrite32(0, hw->hw_addr + REG_IMR);
+	 * iowrite32(0xffffffff, hw->hw_addr + REG_ISR);
+	 */
+
+	/*
+	 * Issue Soft Reset to the MAC.  This will reset the chip's
+	 * transmit, receive, DMA.  It will not effect
+	 * the current PCI configuration.  The global reset bit is self-
+	 * clearing, and should clear within a microsecond.
+	 */
+	iowrite32(MASTER_CTRL_SOFT_RST, hw->hw_addr + REG_MASTER_CTRL);
+	ioread32(hw->hw_addr + REG_MASTER_CTRL);
+
+	iowrite16(1, hw->hw_addr + REG_PHY_ENABLE);
+	ioread16(hw->hw_addr + REG_PHY_ENABLE);
+
+	/* delay about 1ms */
+	msleep(1);
+
+	/* Wait at least 10ms for All module to be Idle */
+	for (i = 0; i < 10; i++) {
+		icr = ioread32(hw->hw_addr + REG_IDLE_STATUS);
+		if (!icr)
+			break;
+		/* delay 1 ms */
+		msleep(1);
+		/* FIXME: still the right way to do this? */
+		cpu_relax();
+	}
+
+	if (icr) {
+		dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
+		return icr;
+	}
+
+	return 0;
+}
+
+/* function about EEPROM
+ *
+ * check_eeprom_exist
+ * return 0 if eeprom exist
+ */
+static int atl1_check_eeprom_exist(struct atl1_hw *hw)
+{
+	u32 value;
+	value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
+	if (value & SPI_FLASH_CTRL_EN_VPD) {
+		value &= ~SPI_FLASH_CTRL_EN_VPD;
+		iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
+	}
+
+	value = ioread16(hw->hw_addr + REG_PCIE_CAP_LIST);
+	return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
+}
+
+static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value)
+{
+	int i;
+	u32 control;
+
+	if (offset & 3)
+		/* address do not align */
+		return false;
+
+	iowrite32(0, hw->hw_addr + REG_VPD_DATA);
+	control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
+	iowrite32(control, hw->hw_addr + REG_VPD_CAP);
+	ioread32(hw->hw_addr + REG_VPD_CAP);
+
+	for (i = 0; i < 10; i++) {
+		msleep(2);
+		control = ioread32(hw->hw_addr + REG_VPD_CAP);
+		if (control & VPD_CAP_VPD_FLAG)
+			break;
+	}
+	if (control & VPD_CAP_VPD_FLAG) {
+		*p_value = ioread32(hw->hw_addr + REG_VPD_DATA);
+		return true;
+	}
+	/* timeout */
+	return false;
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+	u32 val;
+	int i;
+
+	val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
+		MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
+		MDIO_CLK_SEL_SHIFT;
+	iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
+	ioread32(hw->hw_addr + REG_MDIO_CTRL);
+
+	for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+		udelay(2);
+		val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
+		if (!(val & (MDIO_START | MDIO_BUSY)))
+			break;
+	}
+	if (!(val & (MDIO_START | MDIO_BUSY))) {
+		*phy_data = (u16) val;
+		return 0;
+	}
+	return ATLX_ERR_PHY;
+}
+
+#define CUSTOM_SPI_CS_SETUP	2
+#define CUSTOM_SPI_CLK_HI	2
+#define CUSTOM_SPI_CLK_LO	2
+#define CUSTOM_SPI_CS_HOLD	2
+#define CUSTOM_SPI_CS_HI	3
+
+static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
+{
+	int i;
+	u32 value;
+
+	iowrite32(0, hw->hw_addr + REG_SPI_DATA);
+	iowrite32(addr, hw->hw_addr + REG_SPI_ADDR);
+
+	value = SPI_FLASH_CTRL_WAIT_READY |
+	    (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) <<
+	    SPI_FLASH_CTRL_CS_SETUP_SHIFT | (CUSTOM_SPI_CLK_HI &
+					     SPI_FLASH_CTRL_CLK_HI_MASK) <<
+	    SPI_FLASH_CTRL_CLK_HI_SHIFT | (CUSTOM_SPI_CLK_LO &
+					   SPI_FLASH_CTRL_CLK_LO_MASK) <<
+	    SPI_FLASH_CTRL_CLK_LO_SHIFT | (CUSTOM_SPI_CS_HOLD &
+					   SPI_FLASH_CTRL_CS_HOLD_MASK) <<
+	    SPI_FLASH_CTRL_CS_HOLD_SHIFT | (CUSTOM_SPI_CS_HI &
+					    SPI_FLASH_CTRL_CS_HI_MASK) <<
+	    SPI_FLASH_CTRL_CS_HI_SHIFT | (1 & SPI_FLASH_CTRL_INS_MASK) <<
+	    SPI_FLASH_CTRL_INS_SHIFT;
+
+	iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
+
+	value |= SPI_FLASH_CTRL_START;
+	iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
+	ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
+
+	for (i = 0; i < 10; i++) {
+		msleep(1);
+		value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL);
+		if (!(value & SPI_FLASH_CTRL_START))
+			break;
+	}
+
+	if (value & SPI_FLASH_CTRL_START)
+		return false;
+
+	*buf = ioread32(hw->hw_addr + REG_SPI_DATA);
+
+	return true;
+}
+
+/*
+ * get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int atl1_get_permanent_address(struct atl1_hw *hw)
+{
+	u32 addr[2];
+	u32 i, control;
+	u16 reg;
+	u8 eth_addr[ETH_ALEN];
+	bool key_valid;
+
+	if (is_valid_ether_addr(hw->perm_mac_addr))
+		return 0;
+
+	/* init */
+	addr[0] = addr[1] = 0;
+
+	if (!atl1_check_eeprom_exist(hw)) {
+		reg = 0;
+		key_valid = false;
+		/* Read out all EEPROM content */
+		i = 0;
+		while (1) {
+			if (atl1_read_eeprom(hw, i + 0x100, &control)) {
+				if (key_valid) {
+					if (reg == REG_MAC_STA_ADDR)
+						addr[0] = control;
+					else if (reg == (REG_MAC_STA_ADDR + 4))
+						addr[1] = control;
+					key_valid = false;
+				} else if ((control & 0xff) == 0x5A) {
+					key_valid = true;
+					reg = (u16) (control >> 16);
+				} else
+					break;
+			} else
+				/* read error */
+				break;
+			i += 4;
+		}
+
+		*(u32 *) &eth_addr[2] = swab32(addr[0]);
+		*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
+		if (is_valid_ether_addr(eth_addr)) {
+			memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+			return 0;
+		}
+		return 1;
+	}
+
+	/* see if SPI FLAGS exist ? */
+	addr[0] = addr[1] = 0;
+	reg = 0;
+	key_valid = false;
+	i = 0;
+	while (1) {
+		if (atl1_spi_read(hw, i + 0x1f000, &control)) {
+			if (key_valid) {
+				if (reg == REG_MAC_STA_ADDR)
+					addr[0] = control;
+				else if (reg == (REG_MAC_STA_ADDR + 4))
+					addr[1] = control;
+				key_valid = false;
+			} else if ((control & 0xff) == 0x5A) {
+				key_valid = true;
+				reg = (u16) (control >> 16);
+			} else
+				/* data end */
+				break;
+		} else
+			/* read error */
+			break;
+		i += 4;
+	}
+
+	*(u32 *) &eth_addr[2] = swab32(addr[0]);
+	*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
+	if (is_valid_ether_addr(eth_addr)) {
+		memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+		return 0;
+	}
+
+	/*
+	 * On some motherboards, the MAC address is written by the
+	 * BIOS directly to the MAC register during POST, and is
+	 * not stored in eeprom.  If all else thus far has failed
+	 * to fetch the permanent MAC address, try reading it directly.
+	 */
+	addr[0] = ioread32(hw->hw_addr + REG_MAC_STA_ADDR);
+	addr[1] = ioread16(hw->hw_addr + (REG_MAC_STA_ADDR + 4));
+	*(u32 *) &eth_addr[2] = swab32(addr[0]);
+	*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
+	if (is_valid_ether_addr(eth_addr)) {
+		memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+		return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ * hw - Struct containing variables accessed by shared code
+ */
+s32 atl1_read_mac_addr(struct atl1_hw *hw)
+{
+	u16 i;
+
+	if (atl1_get_permanent_address(hw))
+		random_ether_addr(hw->perm_mac_addr);
+
+	for (i = 0; i < ETH_ALEN; i++)
+		hw->mac_addr[i] = hw->perm_mac_addr[i];
+	return 0;
+}
+
+/*
+ * Hashes an address to determine its location in the multicast table
+ * hw - Struct containing variables accessed by shared code
+ * mc_addr - the multicast address to hash
+ *
+ * atl1_hash_mc_addr
+ *  purpose
+ *      set hash value for a multicast address
+ *      hash calcu processing :
+ *          1. calcu 32bit CRC for multicast address
+ *          2. reverse crc with MSB to LSB
+ */
+u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
+{
+	u32 crc32, value = 0;
+	int i;
+
+	crc32 = ether_crc_le(6, mc_addr);
+	for (i = 0; i < 32; i++)
+		value |= (((crc32 >> i) & 1) << (31 - i));
+
+	return value;
+}
+
+/*
+ * Sets the bit in the multicast table corresponding to the hash value.
+ * hw - Struct containing variables accessed by shared code
+ * hash_value - Multicast address hash value
+ */
+void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
+{
+	u32 hash_bit, hash_reg;
+	u32 mta;
+
+	/*
+	 * The HASH Table  is a register array of 2 32-bit registers.
+	 * It is treated like an array of 64 bits.  We want to set
+	 * bit BitArray[hash_value]. So we figure out what register
+	 * the bit is in, read it, OR in the new bit, then write
+	 * back the new value.  The register is determined by the
+	 * upper 7 bits of the hash value and the bit within that
+	 * register are determined by the lower 5 bits of the value.
+	 */
+	hash_reg = (hash_value >> 31) & 0x1;
+	hash_bit = (hash_value >> 26) & 0x1F;
+	mta = ioread32((hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
+	mta |= (1 << hash_bit);
+	iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
+}
+
+/*
+ * Writes a value to a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to write
+ * data - data to write to the PHY
+ */
+s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data)
+{
+	int i;
+	u32 val;
+
+	val = ((u32) (phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
+	    (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
+	    MDIO_SUP_PREAMBLE |
+	    MDIO_START | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+	iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
+	ioread32(hw->hw_addr + REG_MDIO_CTRL);
+
+	for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+		udelay(2);
+		val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
+		if (!(val & (MDIO_START | MDIO_BUSY)))
+			break;
+	}
+
+	if (!(val & (MDIO_START | MDIO_BUSY)))
+		return 0;
+
+	return ATLX_ERR_PHY;
+}
+
+/*
+ * Make L001's PHY out of Power Saving State (bug)
+ * hw - Struct containing variables accessed by shared code
+ * when power on, L001's PHY always on Power saving State
+ * (Gigabit Link forbidden)
+ */
+static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw)
+{
+	s32 ret;
+	ret = atl1_write_phy_reg(hw, 29, 0x0029);
+	if (ret)
+		return ret;
+	return atl1_write_phy_reg(hw, 30, 0);
+}
+
+/*
+ *TODO: do something or get rid of this
+ */
+s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
+{
+/*    s32 ret_val;
+ *    u16 phy_data;
+ */
+
+/*
+    ret_val = atl1_write_phy_reg(hw, ...);
+    ret_val = atl1_write_phy_reg(hw, ...);
+    ....
+*/
+	return 0;
+}
+
+/*
+ * Resets the PHY and make all config validate
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sets bit 15 and 12 of the MII Control regiser (for F001 bug)
+ */
+static s32 atl1_phy_reset(struct atl1_hw *hw)
+{
+	struct pci_dev *pdev = hw->back->pdev;
+	s32 ret_val;
+	u16 phy_data;
+
+	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+	    hw->media_type == MEDIA_TYPE_1000M_FULL)
+		phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
+	else {
+		switch (hw->media_type) {
+		case MEDIA_TYPE_100M_FULL:
+			phy_data =
+			    MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
+			    MII_CR_RESET;
+			break;
+		case MEDIA_TYPE_100M_HALF:
+			phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
+			break;
+		case MEDIA_TYPE_10M_FULL:
+			phy_data =
+			    MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
+			break;
+		default:
+			/* MEDIA_TYPE_10M_HALF: */
+			phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
+			break;
+		}
+	}
+
+	ret_val = atl1_write_phy_reg(hw, MII_BMCR, phy_data);
+	if (ret_val) {
+		u32 val;
+		int i;
+		/* pcie serdes link may be down! */
+		dev_dbg(&pdev->dev, "pcie phy link down\n");
+
+		for (i = 0; i < 25; i++) {
+			msleep(1);
+			val = ioread32(hw->hw_addr + REG_MDIO_CTRL);
+			if (!(val & (MDIO_START | MDIO_BUSY)))
+				break;
+		}
+
+		if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
+			dev_warn(&pdev->dev, "pcie link down at least 25ms\n");
+			return ret_val;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ * hw - Struct containing variables accessed by shared code
+ */
+s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
+{
+	s32 ret_val;
+	s16 mii_autoneg_adv_reg;
+	s16 mii_1000t_ctrl_reg;
+
+	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
+	mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
+
+	/* Read the MII 1000Base-T Control Register (Address 9). */
+	mii_1000t_ctrl_reg = MII_ATLX_CR_1000T_DEFAULT_CAP_MASK;
+
+	/*
+	 * First we clear all the 10/100 mb speed bits in the Auto-Neg
+	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
+	 * the  1000Base-T Control Register (Address 9).
+	 */
+	mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
+	mii_1000t_ctrl_reg &= ~MII_ATLX_CR_1000T_SPEED_MASK;
+
+	/*
+	 * Need to parse media_type  and set up
+	 * the appropriate PHY registers.
+	 */
+	switch (hw->media_type) {
+	case MEDIA_TYPE_AUTO_SENSOR:
+		mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS |
+					MII_AR_10T_FD_CAPS |
+					MII_AR_100TX_HD_CAPS |
+					MII_AR_100TX_FD_CAPS);
+		mii_1000t_ctrl_reg |= MII_ATLX_CR_1000T_FD_CAPS;
+		break;
+
+	case MEDIA_TYPE_1000M_FULL:
+		mii_1000t_ctrl_reg |= MII_ATLX_CR_1000T_FD_CAPS;
+		break;
+
+	case MEDIA_TYPE_100M_FULL:
+		mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
+		break;
+
+	case MEDIA_TYPE_100M_HALF:
+		mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
+		break;
+
+	case MEDIA_TYPE_10M_FULL:
+		mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
+		break;
+
+	default:
+		mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
+		break;
+	}
+
+	/* flow control fixed to enable all */
+	mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
+
+	hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
+	hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg;
+
+	ret_val = atl1_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
+	if (ret_val)
+		return ret_val;
+
+	ret_val = atl1_write_phy_reg(hw, MII_ATLX_CR, mii_1000t_ctrl_reg);
+	if (ret_val)
+		return ret_val;
+
+	return 0;
+}
+
+/*
+ * Configures link settings.
+ * hw - Struct containing variables accessed by shared code
+ * Assumes the hardware has previously been reset and the
+ * transmitter and receiver are not enabled.
+ */
+static s32 atl1_setup_link(struct atl1_hw *hw)
+{
+	struct pci_dev *pdev = hw->back->pdev;
+	s32 ret_val;
+
+	/*
+	 * Options:
+	 *  PHY will advertise value(s) parsed from
+	 *  autoneg_advertised and fc
+	 *  no matter what autoneg is , We will not wait link result.
+	 */
+	ret_val = atl1_phy_setup_autoneg_adv(hw);
+	if (ret_val) {
+		dev_dbg(&pdev->dev, "error setting up autonegotiation\n");
+		return ret_val;
+	}
+	/* SW.Reset , En-Auto-Neg if needed */
+	ret_val = atl1_phy_reset(hw);
+	if (ret_val) {
+		dev_dbg(&pdev->dev, "error resetting phy\n");
+		return ret_val;
+	}
+	hw->phy_configured = true;
+	return ret_val;
+}
+
+static void atl1_init_flash_opcode(struct atl1_hw *hw)
+{
+	if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
+		/* Atmel */
+		hw->flash_vendor = 0;
+
+	/* Init OP table */
+	iowrite8(flash_table[hw->flash_vendor].cmd_program,
+		hw->hw_addr + REG_SPI_FLASH_OP_PROGRAM);
+	iowrite8(flash_table[hw->flash_vendor].cmd_sector_erase,
+		hw->hw_addr + REG_SPI_FLASH_OP_SC_ERASE);
+	iowrite8(flash_table[hw->flash_vendor].cmd_chip_erase,
+		hw->hw_addr + REG_SPI_FLASH_OP_CHIP_ERASE);
+	iowrite8(flash_table[hw->flash_vendor].cmd_rdid,
+		hw->hw_addr + REG_SPI_FLASH_OP_RDID);
+	iowrite8(flash_table[hw->flash_vendor].cmd_wren,
+		hw->hw_addr + REG_SPI_FLASH_OP_WREN);
+	iowrite8(flash_table[hw->flash_vendor].cmd_rdsr,
+		hw->hw_addr + REG_SPI_FLASH_OP_RDSR);
+	iowrite8(flash_table[hw->flash_vendor].cmd_wrsr,
+		hw->hw_addr + REG_SPI_FLASH_OP_WRSR);
+	iowrite8(flash_table[hw->flash_vendor].cmd_read,
+		hw->hw_addr + REG_SPI_FLASH_OP_READ);
+}
+
+/*
+ * Performs basic configuration of the adapter.
+ * hw - Struct containing variables accessed by shared code
+ * Assumes that the controller has previously been reset and is in a
+ * post-reset uninitialized state. Initializes multicast table,
+ * and  Calls routines to setup link
+ * Leaves the transmit and receive units disabled and uninitialized.
+ */
+s32 atl1_init_hw(struct atl1_hw *hw)
+{
+	u32 ret_val = 0;
+
+	/* Zero out the Multicast HASH table */
+	iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
+	/* clear the old settings from the multicast hash table */
+	iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
+
+	atl1_init_flash_opcode(hw);
+
+	if (!hw->phy_configured) {
+		/* enable GPHY LinkChange Interrrupt */
+		ret_val = atl1_write_phy_reg(hw, 18, 0xC00);
+		if (ret_val)
+			return ret_val;
+		/* make PHY out of power-saving state */
+		ret_val = atl1_phy_leave_power_saving(hw);
+		if (ret_val)
+			return ret_val;
+		/* Call a subroutine to configure the link */
+		ret_val = atl1_setup_link(hw);
+	}
+	return ret_val;
+}
+
+/*
+ * Detects the current speed and duplex settings of the hardware.
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ */
+s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
+{
+	struct pci_dev *pdev = hw->back->pdev;
+	s32 ret_val;
+	u16 phy_data;
+
+	/* ; --- Read   PHY Specific Status Register (17) */
+	ret_val = atl1_read_phy_reg(hw, MII_ATLX_PSSR, &phy_data);
+	if (ret_val)
+		return ret_val;
+
+	if (!(phy_data & MII_ATLX_PSSR_SPD_DPLX_RESOLVED))
+		return ATLX_ERR_PHY_RES;
+
+	switch (phy_data & MII_ATLX_PSSR_SPEED) {
+	case MII_ATLX_PSSR_1000MBS:
+		*speed = SPEED_1000;
+		break;
+	case MII_ATLX_PSSR_100MBS:
+		*speed = SPEED_100;
+		break;
+	case MII_ATLX_PSSR_10MBS:
+		*speed = SPEED_10;
+		break;
+	default:
+		dev_dbg(&pdev->dev, "error getting speed\n");
+		return ATLX_ERR_PHY_SPEED;
+		break;
+	}
+	if (phy_data & MII_ATLX_PSSR_DPLX)
+		*duplex = FULL_DUPLEX;
+	else
+		*duplex = HALF_DUPLEX;
+
+	return 0;
+}
+
+void atl1_set_mac_addr(struct atl1_hw *hw)
+{
+	u32 value;
+	/*
+	 * 00-0B-6A-F6-00-DC
+	 * 0:  6AF600DC   1: 000B
+	 * low dword
+	 */
+	value = (((u32) hw->mac_addr[2]) << 24) |
+	    (((u32) hw->mac_addr[3]) << 16) |
+	    (((u32) hw->mac_addr[4]) << 8) | (((u32) hw->mac_addr[5]));
+	iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR);
+	/* high dword */
+	value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1]));
+	iowrite32(value, (hw->hw_addr + REG_MAC_STA_ADDR) + (1 << 2));
+}
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index ff4765f..538948d 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -1,6 +1,6 @@
 /*
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
- * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
+ * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
  * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
  *
  * Derived from Intel e1000 driver
@@ -21,26 +21,559 @@
  * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#ifndef _ATL1_H_
-#define _ATL1_H_
+#ifndef ATL1_H
+#define ATL1_H
 
-#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "atlx.h"
+
+#define ATLX_DRIVER_NAME "atl1"
 
-#include "atl1_hw.h"
+MODULE_DESCRIPTION("Atheros L1 Gigabit Ethernet Driver");
+
+#define atlx_adapter		atl1_adapter
+#define atlx_check_for_link	atl1_check_for_link
+#define atlx_check_link		atl1_check_link
+#define atlx_hash_mc_addr	atl1_hash_mc_addr
+#define atlx_hash_set		atl1_hash_set
+#define atlx_hw			atl1_hw
+#define atlx_mii_ioctl		atl1_mii_ioctl
+#define atlx_read_phy_reg	atl1_read_phy_reg
+#define atlx_set_mac		atl1_set_mac
+#define atlx_set_mac_addr	atl1_set_mac_addr
+
+struct atl1_adapter;
+struct atl1_hw;
 
 /* function prototypes needed by multiple files */
+s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw);
+s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data);
+s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex);
+s32 atl1_read_mac_addr(struct atl1_hw *hw);
+s32 atl1_init_hw(struct atl1_hw *hw);
+s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex);
+s32 atl1_set_speed_and_duplex(struct atl1_hw *hw, u16 speed, u16 duplex);
+u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
+void atl1_hash_set(struct atl1_hw *hw, u32 hash_value);
+s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data);
+void atl1_set_mac_addr(struct atl1_hw *hw);
+s32 atl1_phy_enter_power_saving(struct atl1_hw *hw);
+s32 atl1_reset_hw(struct atl1_hw *hw);
+void atl1_check_options(struct atl1_adapter *adapter);
+static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
+	int cmd);
+static u32 atl1_check_link(struct atl1_adapter *adapter);
 s32 atl1_up(struct atl1_adapter *adapter);
 void atl1_down(struct atl1_adapter *adapter);
 int atl1_reset(struct atl1_adapter *adapter);
-s32 atl1_setup_ring_resources(struct atl1_adapter *adapter);
-void atl1_free_ring_resources(struct atl1_adapter *adapter);
 
-extern char atl1_driver_name[];
-extern char atl1_driver_version[];
 extern const struct ethtool_ops atl1_ethtool_ops;
 
-struct atl1_adapter;
+/* hardware definitions specific to L1 */
+
+/* Block IDLE Status Register */
+#define IDLE_STATUS_RXMAC			0x1
+#define IDLE_STATUS_TXMAC			0x2
+#define IDLE_STATUS_RXQ				0x4
+#define IDLE_STATUS_TXQ				0x8
+#define IDLE_STATUS_DMAR			0x10
+#define IDLE_STATUS_DMAW			0x20
+#define IDLE_STATUS_SMB				0x40
+#define IDLE_STATUS_CMB				0x80
+
+/* MDIO Control Register */
+#define MDIO_WAIT_TIMES				30
+
+/* MAC Control Register */
+#define MAC_CTRL_TX_PAUSE			0x10000
+#define MAC_CTRL_SCNT				0x20000
+#define MAC_CTRL_SRST_TX			0x40000
+#define MAC_CTRL_TX_SIMURST			0x80000
+#define MAC_CTRL_SPEED_SHIFT			20
+#define MAC_CTRL_SPEED_MASK			0x300000
+#define MAC_CTRL_SPEED_1000			0x2
+#define MAC_CTRL_SPEED_10_100			0x1
+#define MAC_CTRL_DBG_TX_BKPRESURE		0x400000
+#define MAC_CTRL_TX_HUGE			0x800000
+#define MAC_CTRL_RX_CHKSUM_EN			0x1000000
+#define MAC_CTRL_DBG				0x8000000
+
+/* Wake-On-Lan control register */
+#define WOL_CLK_SWITCH_EN			0x8000
+#define WOL_PT5_EN				0x200000
+#define WOL_PT6_EN				0x400000
+#define WOL_PT5_MATCH				0x8000000
+#define WOL_PT6_MATCH				0x10000000
+
+/* WOL Length ( 2 DWORD ) */
+#define REG_WOL_PATTERN_LEN			0x14A4
+#define WOL_PT_LEN_MASK				0x7F
+#define WOL_PT0_LEN_SHIFT			0
+#define WOL_PT1_LEN_SHIFT			8
+#define WOL_PT2_LEN_SHIFT			16
+#define WOL_PT3_LEN_SHIFT			24
+#define WOL_PT4_LEN_SHIFT			0
+#define WOL_PT5_LEN_SHIFT			8
+#define WOL_PT6_LEN_SHIFT			16
+
+/* Internal SRAM Partition Registers, low 32 bits */
+#define REG_SRAM_RFD_LEN			0x1504
+#define REG_SRAM_RRD_ADDR			0x1508
+#define REG_SRAM_RRD_LEN			0x150C
+#define REG_SRAM_TPD_ADDR			0x1510
+#define REG_SRAM_TPD_LEN			0x1514
+#define REG_SRAM_TRD_ADDR			0x1518
+#define REG_SRAM_TRD_LEN			0x151C
+#define REG_SRAM_RXF_ADDR			0x1520
+#define REG_SRAM_RXF_LEN			0x1524
+#define REG_SRAM_TXF_ADDR			0x1528
+#define REG_SRAM_TXF_LEN			0x152C
+#define REG_SRAM_TCPH_PATH_ADDR			0x1530
+#define SRAM_TCPH_ADDR_MASK			0xFFF
+#define SRAM_TCPH_ADDR_SHIFT			0
+#define SRAM_PATH_ADDR_MASK			0xFFF
+#define SRAM_PATH_ADDR_SHIFT			16
+
+/* Load Ptr Register */
+#define REG_LOAD_PTR				0x1534
+
+/* Descriptor Control registers, low 32 bits */
+#define REG_DESC_RFD_ADDR_LO			0x1544
+#define REG_DESC_RRD_ADDR_LO			0x1548
+#define REG_DESC_TPD_ADDR_LO			0x154C
+#define REG_DESC_CMB_ADDR_LO			0x1550
+#define REG_DESC_SMB_ADDR_LO			0x1554
+#define REG_DESC_RFD_RRD_RING_SIZE		0x1558
+#define DESC_RFD_RING_SIZE_MASK			0x7FF
+#define DESC_RFD_RING_SIZE_SHIFT		0
+#define DESC_RRD_RING_SIZE_MASK			0x7FF
+#define DESC_RRD_RING_SIZE_SHIFT		16
+#define REG_DESC_TPD_RING_SIZE			0x155C
+#define DESC_TPD_RING_SIZE_MASK			0x3FF
+#define DESC_TPD_RING_SIZE_SHIFT		0
+
+/* TXQ Control Register */
+#define REG_TXQ_CTRL				0x1580
+#define TXQ_CTRL_TPD_BURST_NUM_SHIFT		0
+#define TXQ_CTRL_TPD_BURST_NUM_MASK		0x1F
+#define TXQ_CTRL_EN				0x20
+#define TXQ_CTRL_ENH_MODE			0x40
+#define TXQ_CTRL_TPD_FETCH_TH_SHIFT		8
+#define TXQ_CTRL_TPD_FETCH_TH_MASK		0x3F
+#define TXQ_CTRL_TXF_BURST_NUM_SHIFT		16
+#define TXQ_CTRL_TXF_BURST_NUM_MASK		0xFFFF
+
+/* Jumbo packet Threshold for task offload */
+#define REG_TX_JUMBO_TASK_TH_TPD_IPG		0x1584
+#define TX_JUMBO_TASK_TH_MASK			0x7FF
+#define TX_JUMBO_TASK_TH_SHIFT			0
+#define TX_TPD_MIN_IPG_MASK			0x1F
+#define TX_TPD_MIN_IPG_SHIFT			16
+
+/* RXQ Control Register */
+#define REG_RXQ_CTRL				0x15A0
+#define RXQ_CTRL_RFD_BURST_NUM_SHIFT		0
+#define RXQ_CTRL_RFD_BURST_NUM_MASK		0xFF
+#define RXQ_CTRL_RRD_BURST_THRESH_SHIFT		8
+#define RXQ_CTRL_RRD_BURST_THRESH_MASK		0xFF
+#define RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT		16
+#define RXQ_CTRL_RFD_PREF_MIN_IPG_MASK		0x1F
+#define RXQ_CTRL_CUT_THRU_EN			0x40000000
+#define RXQ_CTRL_EN				0x80000000
+
+/* Rx jumbo packet threshold and rrd  retirement timer */
+#define REG_RXQ_JMBOSZ_RRDTIM			0x15A4
+#define RXQ_JMBOSZ_TH_MASK			0x7FF
+#define RXQ_JMBOSZ_TH_SHIFT			0
+#define RXQ_JMBO_LKAH_MASK			0xF
+#define RXQ_JMBO_LKAH_SHIFT			11
+#define RXQ_RRD_TIMER_MASK			0xFFFF
+#define RXQ_RRD_TIMER_SHIFT			16
+
+/* RFD flow control register */
+#define REG_RXQ_RXF_PAUSE_THRESH		0x15A8
+#define RXQ_RXF_PAUSE_TH_HI_SHIFT		16
+#define RXQ_RXF_PAUSE_TH_HI_MASK		0xFFF
+#define RXQ_RXF_PAUSE_TH_LO_SHIFT		0
+#define RXQ_RXF_PAUSE_TH_LO_MASK		0xFFF
+
+/* RRD flow control register */
+#define REG_RXQ_RRD_PAUSE_THRESH		0x15AC
+#define RXQ_RRD_PAUSE_TH_HI_SHIFT		0
+#define RXQ_RRD_PAUSE_TH_HI_MASK		0xFFF
+#define RXQ_RRD_PAUSE_TH_LO_SHIFT		16
+#define RXQ_RRD_PAUSE_TH_LO_MASK		0xFFF
+
+/* DMA Engine Control Register */
+#define REG_DMA_CTRL				0x15C0
+#define DMA_CTRL_DMAR_IN_ORDER			0x1
+#define DMA_CTRL_DMAR_ENH_ORDER			0x2
+#define DMA_CTRL_DMAR_OUT_ORDER			0x4
+#define DMA_CTRL_RCB_VALUE			0x8
+#define DMA_CTRL_DMAR_BURST_LEN_SHIFT		4
+#define DMA_CTRL_DMAR_BURST_LEN_MASK		7
+#define DMA_CTRL_DMAW_BURST_LEN_SHIFT		7
+#define DMA_CTRL_DMAW_BURST_LEN_MASK		7
+#define DMA_CTRL_DMAR_EN			0x400
+#define DMA_CTRL_DMAW_EN			0x8
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 00/26] atl1: divide and modernize, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 02/26] atl1: move common functions to atlx files, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 03/26] atl1: fix broken TSO, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 04/26] atl1: add ethtool register dump, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 05/26] atl1: print debug info if rrd error, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 07/26] atl1: clarify max rx frame size, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 09/26] atl1: refactor tx processing, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 12/26] atl1: refactor atl1_probe, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 13/26] atl1: refactor interrupt handling, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 15/26] atl1: tidy up ring management, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 16/26] atl1: modernize check link function, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 17/26] atl1: update phy config function, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 18/26] atl1: make function static, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 19/26] atl1: modernize down/up functions, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 20/26] atl1: update change mtu, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 21/26] atl1: update atl1_close, jacliburn, (Mon Dec 31, 6:59 pm)
[PATCH 22/26] atl1: update netpoll, jacliburn, (Mon Dec 31, 7:00 pm)
[PATCH 24/26] atl1: update wake-on-lan, jacliburn, (Mon Dec 31, 7:00 pm)
[PATCH 25/26] atl1: add NAPI support, jacliburn, (Mon Dec 31, 7:00 pm)
Re: [PATCH 25/26] atl1: add NAPI support, Joonwoo Park, (Mon Dec 31, 11:09 pm)
Re: [PATCH 25/26] [REVISED] atl1: add NAPI support, Jay Cliburn, (Tue Jan 1, 11:15 am)
RE: [PATCH 25/26] [REVISED] atl1: add NAPI support, Joonwoo Park, (Tue Jan 1, 7:56 pm)
Re: [PATCH 25/26] [REVISED] atl1: add NAPI support, David Miller, (Tue Jan 1, 8:07 pm)
Re: [PATCH 04/26] atl1: add ethtool register dump, Jeff Garzik, (Tue Jan 22, 2:54 am)
Re: [PATCH 05/26] atl1: print debug info if rrd error, Jeff Garzik, (Tue Jan 22, 2:55 am)
Re: [PATCH 09/26] atl1: refactor tx processing, Jeff Garzik, (Tue Jan 22, 2:58 am)
Re: [PATCH 13/26] atl1: refactor interrupt handling, Jeff Garzik, (Tue Jan 22, 2:59 am)
Re: [PATCH 19/26] atl1: modernize down/up functions, Jeff Garzik, (Tue Jan 22, 3:01 am)
Re: [PATCH 09/26] atl1: refactor tx processing, Jay Cliburn, (Tue Jan 22, 5:31 pm)
Re: [PATCH 09/26] atl1: refactor tx processing, Jay Cliburn, (Thu Jan 24, 6:00 pm)
Re: [PATCH 09/26] atl1: refactor tx processing, Chris Snook, (Thu Jan 24, 6:08 pm)
Re: [PATCH 09/26] atl1: refactor tx processing, Jeff Garzik, (Thu Jan 24, 8:01 pm)