atl*: Move the Atheros drivers
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 20 May 2011 13:55:16 +0000 (06:55 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 11 Aug 2011 23:29:59 +0000 (16:29 -0700)
Move the Atheros drivers into drivers/net/ethernet/atheros/ and
make the necessary Kconfig and Makefile changes.

CC: Jay Cliburn <jcliburn@gmail.com>
CC: Chris Snook <chris.snook@gmail.com>
CC: Jie Yang <jie.yang@atheros.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
47 files changed:
MAINTAINERS
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/atl1c/Makefile [deleted file]
drivers/net/atl1c/atl1c.h [deleted file]
drivers/net/atl1c/atl1c_ethtool.c [deleted file]
drivers/net/atl1c/atl1c_hw.c [deleted file]
drivers/net/atl1c/atl1c_hw.h [deleted file]
drivers/net/atl1c/atl1c_main.c [deleted file]
drivers/net/atl1e/Makefile [deleted file]
drivers/net/atl1e/atl1e.h [deleted file]
drivers/net/atl1e/atl1e_ethtool.c [deleted file]
drivers/net/atl1e/atl1e_hw.c [deleted file]
drivers/net/atl1e/atl1e_hw.h [deleted file]
drivers/net/atl1e/atl1e_main.c [deleted file]
drivers/net/atl1e/atl1e_param.c [deleted file]
drivers/net/atlx/Makefile [deleted file]
drivers/net/atlx/atl1.c [deleted file]
drivers/net/atlx/atl1.h [deleted file]
drivers/net/atlx/atl2.c [deleted file]
drivers/net/atlx/atl2.h [deleted file]
drivers/net/atlx/atlx.c [deleted file]
drivers/net/atlx/atlx.h [deleted file]
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/atheros/Kconfig [new file with mode: 0644]
drivers/net/ethernet/atheros/Makefile [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1c/Makefile [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1c/atl1c.h [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1c/atl1c_hw.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1c/atl1c_hw.h [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1c/atl1c_main.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1e/Makefile [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1e/atl1e.h [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1e/atl1e_hw.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1e/atl1e_hw.h [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1e/atl1e_main.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atl1e/atl1e_param.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atlx/Makefile [new file with mode: 0644]
drivers/net/ethernet/atheros/atlx/atl1.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atlx/atl1.h [new file with mode: 0644]
drivers/net/ethernet/atheros/atlx/atl2.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atlx/atl2.h [new file with mode: 0644]
drivers/net/ethernet/atheros/atlx/atlx.c [new file with mode: 0644]
drivers/net/ethernet/atheros/atlx/atlx.h [new file with mode: 0644]

index 88ff9efa9c65dedbcff76e39420bc5d3e68c2574..26fa497e373338845f1f4cabec94b2eb0684aec6 100644 (file)
@@ -1282,7 +1282,7 @@ L:        netdev@vger.kernel.org
 W:     http://sourceforge.net/projects/atl1
 W:     http://atl1.sourceforge.net
 S:     Maintained
-F:     drivers/net/atlx/
+F:     drivers/net/ethernet/atheros/
 
 ATM
 M:     Chas Williams <chas@cmf.nrl.navy.mil>
index 8799caf64c98ba39a7a4dac25ca272658fd649a2..e6be7123f9ca2a17dc4c3afcd2a99441936114e1 100644 (file)
@@ -760,17 +760,6 @@ config FEC_MPC52xx_MDIO
          If not sure, enable.
          If compiled as module, it will be called fec_mpc52xx_phy.
 
-config ATL2
-       tristate "Atheros L2 Fast Ethernet support"
-       depends on PCI
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros L2 fast ethernet adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl2.
-
 config XILINX_EMACLITE
        tristate "Xilinx 10/100 Ethernet Lite support"
        depends on PPC32 || MICROBLAZE
@@ -1031,40 +1020,6 @@ config XILINX_LL_TEMAC
          This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
          core used in Xilinx Spartan and Virtex FPGAs
 
-config ATL1
-       tristate "Atheros/Attansic L1 Gigabit Ethernet support"
-       depends on PCI
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros/Attansic L1 gigabit ethernet
-         adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl1.
-
-config ATL1E
-       tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros L1E gigabit ethernet adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl1e.
-
-config ATL1C
-       tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
-       select CRC32
-       select MII
-       help
-         This driver supports the Atheros L1C gigabit ethernet adapter.
-
-         To compile this driver as a module, choose M here.  The module
-         will be called atl1c.
-
 config JME
        tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
        depends on PCI
index ecd8c9f664d270ac1bbbcf9d9caf290ae047905e..d15107598e6d0f449b8738696b2d5a716ea17858 100644 (file)
@@ -13,10 +13,6 @@ obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
 obj-$(CONFIG_IP1000) += ipg.o
 obj-$(CONFIG_CAN) += can/
 obj-$(CONFIG_BONDING) += bonding/
-obj-$(CONFIG_ATL1) += atlx/
-obj-$(CONFIG_ATL2) += atlx/
-obj-$(CONFIG_ATL1E) += atl1e/
-obj-$(CONFIG_ATL1C) += atl1c/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
 obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
 obj-$(CONFIG_JME) += jme.o
diff --git a/drivers/net/atl1c/Makefile b/drivers/net/atl1c/Makefile
deleted file mode 100644 (file)
index c37d966..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_ATL1C) += atl1c.o
-atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
deleted file mode 100644 (file)
index ca70e16..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#ifndef _ATL1C_H_
-#define _ATL1C_H_
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/udp.h>
-#include <linux/mii.h>
-#include <linux/io.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <linux/tcp.h>
-#include <linux/ethtool.h>
-#include <linux/if_vlan.h>
-#include <linux/workqueue.h>
-#include <net/checksum.h>
-#include <net/ip6_checksum.h>
-
-#include "atl1c_hw.h"
-
-/* Wake Up Filter Control */
-#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
-#define AT_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
-#define AT_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
-#define AT_WUFC_MC   0x00000008 /* Multicast Wakeup Enable */
-#define AT_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
-
-#define AT_VLAN_TO_TAG(_vlan, _tag)       \
-       _tag =  ((((_vlan) >> 8) & 0xFF)  |\
-                (((_vlan) & 0xFF) << 8))
-
-#define AT_TAG_TO_VLAN(_tag, _vlan)     \
-       _vlan = ((((_tag) >> 8) & 0xFF) |\
-               (((_tag) & 0xFF) << 8))
-
-#define SPEED_0                   0xffff
-#define HALF_DUPLEX        1
-#define FULL_DUPLEX        2
-
-#define AT_RX_BUF_SIZE         (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)
-#define MAX_JUMBO_FRAME_SIZE   (6*1024)
-#define MAX_TSO_FRAME_SIZE      (7*1024)
-#define MAX_TX_OFFLOAD_THRESH  (9*1024)
-
-#define AT_MAX_RECEIVE_QUEUE    4
-#define AT_DEF_RECEIVE_QUEUE   1
-#define AT_MAX_TRANSMIT_QUEUE  2
-
-#define AT_DMA_HI_ADDR_MASK     0xffffffff00000000ULL
-#define AT_DMA_LO_ADDR_MASK     0x00000000ffffffffULL
-
-#define AT_TX_WATCHDOG  (5 * HZ)
-#define AT_MAX_INT_WORK                5
-#define AT_TWSI_EEPROM_TIMEOUT         100
-#define AT_HW_MAX_IDLE_DELAY   10
-#define AT_SUSPEND_LINK_TIMEOUT 100
-
-#define AT_ASPM_L0S_TIMER      6
-#define AT_ASPM_L1_TIMER       12
-#define AT_LCKDET_TIMER                12
-
-#define ATL1C_PCIE_L0S_L1_DISABLE      0x01
-#define ATL1C_PCIE_PHY_RESET           0x02
-
-#define ATL1C_ASPM_L0s_ENABLE          0x0001
-#define ATL1C_ASPM_L1_ENABLE           0x0002
-
-#define AT_REGS_LEN    (75 * sizeof(u32))
-#define AT_EEPROM_LEN  512
-
-#define ATL1C_GET_DESC(R, i, type)     (&(((type *)((R)->desc))[i]))
-#define ATL1C_RFD_DESC(R, i)   ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc)
-#define ATL1C_TPD_DESC(R, i)   ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc)
-#define ATL1C_RRD_DESC(R, i)   ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status)
-
-/* tpd word 1 bit 0:7 General Checksum task offload */
-#define TPD_L4HDR_OFFSET_MASK  0x00FF
-#define TPD_L4HDR_OFFSET_SHIFT 0
-
-/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */
-#define TPD_TCPHDR_OFFSET_MASK 0x00FF
-#define TPD_TCPHDR_OFFSET_SHIFT        0
-
-/* tpd word 1 bit 0:7 Custom Checksum task offload */
-#define TPD_PLOADOFFSET_MASK   0x00FF
-#define TPD_PLOADOFFSET_SHIFT  0
-
-/* tpd word 1 bit 8:17 */
-#define TPD_CCSUM_EN_MASK      0x0001
-#define TPD_CCSUM_EN_SHIFT     8
-#define TPD_IP_CSUM_MASK       0x0001
-#define TPD_IP_CSUM_SHIFT      9
-#define TPD_TCP_CSUM_MASK      0x0001
-#define TPD_TCP_CSUM_SHIFT     10
-#define TPD_UDP_CSUM_MASK      0x0001
-#define TPD_UDP_CSUM_SHIFT     11
-#define TPD_LSO_EN_MASK                0x0001  /* TCP Large Send Offload */
-#define TPD_LSO_EN_SHIFT       12
-#define TPD_LSO_VER_MASK       0x0001
-#define TPD_LSO_VER_SHIFT      13      /* 0 : ipv4; 1 : ipv4/ipv6 */
-#define TPD_CON_VTAG_MASK      0x0001
-#define TPD_CON_VTAG_SHIFT     14
-#define TPD_INS_VTAG_MASK      0x0001
-#define TPD_INS_VTAG_SHIFT     15
-#define TPD_IPV4_PACKET_MASK   0x0001  /* valid when LSO VER  is 1 */
-#define TPD_IPV4_PACKET_SHIFT  16
-#define TPD_ETH_TYPE_MASK      0x0001
-#define TPD_ETH_TYPE_SHIFT     17      /* 0 : 802.3 frame; 1 : Ethernet */
-
-/* tpd word 18:25 Custom Checksum task offload */
-#define TPD_CCSUM_OFFSET_MASK  0x00FF
-#define TPD_CCSUM_OFFSET_SHIFT 18
-#define TPD_CCSUM_EPAD_MASK    0x0001
-#define TPD_CCSUM_EPAD_SHIFT   30
-
-/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */
-#define TPD_MSS_MASK            0x1FFF
-#define TPD_MSS_SHIFT          18
-
-#define TPD_EOP_MASK           0x0001
-#define TPD_EOP_SHIFT          31
-
-struct atl1c_tpd_desc {
-       __le16  buffer_len; /* include 4-byte CRC */
-       __le16  vlan_tag;
-       __le32  word1;
-       __le64  buffer_addr;
-};
-
-struct atl1c_tpd_ext_desc {
-       u32 reservd_0;
-       __le32 word1;
-       __le32 pkt_len;
-       u32 reservd_1;
-};
-/* rrs word 0 bit 0:31 */
-#define RRS_RX_CSUM_MASK       0xFFFF
-#define RRS_RX_CSUM_SHIFT      0
-#define RRS_RX_RFD_CNT_MASK    0x000F
-#define RRS_RX_RFD_CNT_SHIFT   16
-#define RRS_RX_RFD_INDEX_MASK  0x0FFF
-#define RRS_RX_RFD_INDEX_SHIFT 20
-
-/* rrs flag bit 0:16 */
-#define RRS_HEAD_LEN_MASK      0x00FF
-#define RRS_HEAD_LEN_SHIFT     0
-#define RRS_HDS_TYPE_MASK      0x0003
-#define RRS_HDS_TYPE_SHIFT     8
-#define RRS_CPU_NUM_MASK       0x0003
-#define        RRS_CPU_NUM_SHIFT       10
-#define RRS_HASH_FLG_MASK      0x000F
-#define RRS_HASH_FLG_SHIFT     12
-
-#define RRS_HDS_TYPE_HEAD      1
-#define RRS_HDS_TYPE_DATA      2
-
-#define RRS_IS_NO_HDS_TYPE(flag) \
-       ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0)
-
-#define RRS_IS_HDS_HEAD(flag) \
-       ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
-                       RRS_HDS_TYPE_HEAD)
-
-#define RRS_IS_HDS_DATA(flag) \
-       ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
-                       RRS_HDS_TYPE_DATA)
-
-/* rrs word 3 bit 0:31 */
-#define RRS_PKT_SIZE_MASK      0x3FFF
-#define RRS_PKT_SIZE_SHIFT     0
-#define RRS_ERR_L4_CSUM_MASK   0x0001
-#define RRS_ERR_L4_CSUM_SHIFT  14
-#define RRS_ERR_IP_CSUM_MASK   0x0001
-#define RRS_ERR_IP_CSUM_SHIFT  15
-#define RRS_VLAN_INS_MASK      0x0001
-#define RRS_VLAN_INS_SHIFT     16
-#define RRS_PROT_ID_MASK       0x0007
-#define RRS_PROT_ID_SHIFT      17
-#define RRS_RX_ERR_SUM_MASK    0x0001
-#define RRS_RX_ERR_SUM_SHIFT   20
-#define RRS_RX_ERR_CRC_MASK    0x0001
-#define RRS_RX_ERR_CRC_SHIFT   21
-#define RRS_RX_ERR_FAE_MASK    0x0001
-#define RRS_RX_ERR_FAE_SHIFT   22
-#define RRS_RX_ERR_TRUNC_MASK  0x0001
-#define RRS_RX_ERR_TRUNC_SHIFT 23
-#define RRS_RX_ERR_RUNC_MASK   0x0001
-#define RRS_RX_ERR_RUNC_SHIFT  24
-#define RRS_RX_ERR_ICMP_MASK   0x0001
-#define RRS_RX_ERR_ICMP_SHIFT  25
-#define RRS_PACKET_BCAST_MASK  0x0001
-#define RRS_PACKET_BCAST_SHIFT 26
-#define RRS_PACKET_MCAST_MASK  0x0001
-#define RRS_PACKET_MCAST_SHIFT 27
-#define RRS_PACKET_TYPE_MASK   0x0001
-#define RRS_PACKET_TYPE_SHIFT  28
-#define RRS_FIFO_FULL_MASK     0x0001
-#define RRS_FIFO_FULL_SHIFT    29
-#define RRS_802_3_LEN_ERR_MASK         0x0001
-#define RRS_802_3_LEN_ERR_SHIFT 30
-#define RRS_RXD_UPDATED_MASK   0x0001
-#define RRS_RXD_UPDATED_SHIFT  31
-
-#define RRS_ERR_L4_CSUM         0x00004000
-#define RRS_ERR_IP_CSUM         0x00008000
-#define RRS_VLAN_INS            0x00010000
-#define RRS_RX_ERR_SUM          0x00100000
-#define RRS_RX_ERR_CRC          0x00200000
-#define RRS_802_3_LEN_ERR      0x40000000
-#define RRS_RXD_UPDATED                0x80000000
-
-#define RRS_PACKET_TYPE_802_3          1
-#define RRS_PACKET_TYPE_ETH    0
-#define RRS_PACKET_IS_ETH(word) \
-       ((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \
-                       RRS_PACKET_TYPE_ETH)
-#define RRS_RXD_IS_VALID(word) \
-       ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
-
-#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \
-       ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1)
-#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \
-       ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6)
-
-struct atl1c_recv_ret_status {
-       __le32  word0;
-       __le32  rss_hash;
-       __le16  vlan_tag;
-       __le16  flag;
-       __le32  word3;
-};
-
-/* RFD descriptor */
-struct atl1c_rx_free_desc {
-       __le64  buffer_addr;
-};
-
-/* DMA Order Settings */
-enum atl1c_dma_order {
-       atl1c_dma_ord_in = 1,
-       atl1c_dma_ord_enh = 2,
-       atl1c_dma_ord_out = 4
-};
-
-enum atl1c_dma_rcb {
-       atl1c_rcb_64 = 0,
-       atl1c_rcb_128 = 1
-};
-
-enum atl1c_mac_speed {
-       atl1c_mac_speed_0 = 0,
-       atl1c_mac_speed_10_100 = 1,
-       atl1c_mac_speed_1000 = 2
-};
-
-enum atl1c_dma_req_block {
-       atl1c_dma_req_128 = 0,
-       atl1c_dma_req_256 = 1,
-       atl1c_dma_req_512 = 2,
-       atl1c_dma_req_1024 = 3,
-       atl1c_dma_req_2048 = 4,
-       atl1c_dma_req_4096 = 5
-};
-
-enum atl1c_rss_mode {
-       atl1c_rss_mode_disable = 0,
-       atl1c_rss_sig_que = 1,
-       atl1c_rss_mul_que_sig_int = 2,
-       atl1c_rss_mul_que_mul_int = 4,
-};
-
-enum atl1c_rss_type {
-       atl1c_rss_disable = 0,
-       atl1c_rss_ipv4 = 1,
-       atl1c_rss_ipv4_tcp = 2,
-       atl1c_rss_ipv6 = 4,
-       atl1c_rss_ipv6_tcp = 8
-};
-
-enum atl1c_nic_type {
-       athr_l1c = 0,
-       athr_l2c = 1,
-       athr_l2c_b,
-       athr_l2c_b2,
-       athr_l1d,
-       athr_l1d_2,
-};
-
-enum atl1c_trans_queue {
-       atl1c_trans_normal = 0,
-       atl1c_trans_high = 1
-};
-
-struct atl1c_hw_stats {
-       /* rx */
-       unsigned long rx_ok;            /* The number of good packet received. */
-       unsigned long rx_bcast;         /* The number of good broadcast packet received. */
-       unsigned long rx_mcast;         /* The number of good multicast packet received. */
-       unsigned long rx_pause;         /* The number of Pause packet received. */
-       unsigned long rx_ctrl;          /* The number of Control packet received other than Pause frame. */
-       unsigned long rx_fcs_err;       /* The number of packets with bad FCS. */
-       unsigned long rx_len_err;       /* The number of packets with mismatch of length field and actual size. */
-       unsigned long rx_byte_cnt;      /* The number of bytes of good packet received. FCS is NOT included. */
-       unsigned long rx_runt;          /* The number of packets received that are less than 64 byte long and with good FCS. */
-       unsigned long rx_frag;          /* The number of packets received that are less than 64 byte long and with bad FCS. */
-       unsigned long rx_sz_64;         /* The number of good and bad packets received that are 64 byte long. */
-       unsigned long rx_sz_65_127;     /* The number of good and bad packets received that are between 65 and 127-byte long. */
-       unsigned long rx_sz_128_255;    /* The number of good and bad packets received that are between 128 and 255-byte long. */
-       unsigned long rx_sz_256_511;    /* The number of good and bad packets received that are between 256 and 511-byte long. */
-       unsigned long rx_sz_512_1023;   /* The number of good and bad packets received that are between 512 and 1023-byte long. */
-       unsigned long rx_sz_1024_1518;  /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
-       unsigned long rx_sz_1519_max;   /* The number of good and bad packets received that are between 1519-byte and MTU. */
-       unsigned long rx_sz_ov;         /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
-       unsigned long rx_rxf_ov;        /* The number of frame dropped due to occurrence of RX FIFO overflow. */
-       unsigned long rx_rrd_ov;        /* The number of frame dropped due to occurrence of RRD overflow. */
-       unsigned long rx_align_err;     /* Alignment Error */
-       unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
-       unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
-       unsigned long rx_err_addr;      /* The number of packets dropped due to address filtering. */
-
-       /* tx */
-       unsigned long tx_ok;            /* The number of good packet transmitted. */
-       unsigned long tx_bcast;         /* The number of good broadcast packet transmitted. */
-       unsigned long tx_mcast;         /* The number of good multicast packet transmitted. */
-       unsigned long tx_pause;         /* The number of Pause packet transmitted. */
-       unsigned long tx_exc_defer;     /* The number of packets transmitted with excessive deferral. */
-       unsigned long tx_ctrl;          /* The number of packets transmitted is a control frame, excluding Pause frame. */
-       unsigned long tx_defer;         /* The number of packets transmitted that is deferred. */
-       unsigned long tx_byte_cnt;      /* The number of bytes of data transmitted. FCS is NOT included. */
-       unsigned long tx_sz_64;         /* The number of good and bad packets transmitted that are 64 byte long. */
-       unsigned long tx_sz_65_127;     /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
-       unsigned long tx_sz_128_255;    /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
-       unsigned long tx_sz_256_511;    /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
-       unsigned long tx_sz_512_1023;   /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
-       unsigned long tx_sz_1024_1518;  /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
-       unsigned long tx_sz_1519_max;   /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
-       unsigned long tx_1_col;         /* The number of packets subsequently transmitted successfully with a single prior collision. */
-       unsigned long tx_2_col;         /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
-       unsigned long tx_late_col;      /* The number of packets transmitted with late collisions. */
-       unsigned long tx_abort_col;     /* The number of transmit packets aborted due to excessive collisions. */
-       unsigned long tx_underrun;      /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
-       unsigned long tx_rd_eop;        /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
-       unsigned long tx_len_err;       /* The number of transmit packets with length field does NOT match the actual frame size. */
-       unsigned long tx_trunc;         /* The number of transmit packets truncated due to size exceeding MTU. */
-       unsigned long tx_bcast_byte;    /* The byte count of broadcast packet transmitted, excluding FCS. */
-       unsigned long tx_mcast_byte;    /* The byte count of multicast packet transmitted, excluding FCS. */
-};
-
-struct atl1c_hw {
-       u8 __iomem      *hw_addr;            /* inner register address */
-       struct atl1c_adapter *adapter;
-       enum atl1c_nic_type  nic_type;
-       enum atl1c_dma_order dma_order;
-       enum atl1c_dma_rcb   rcb_value;
-       enum atl1c_dma_req_block dmar_block;
-       enum atl1c_dma_req_block dmaw_block;
-
-       u16 device_id;
-       u16 vendor_id;
-       u16 subsystem_id;
-       u16 subsystem_vendor_id;
-       u8 revision_id;
-       u16 phy_id1;
-       u16 phy_id2;
-
-       u32 intr_mask;
-       u8 dmaw_dly_cnt;
-       u8 dmar_dly_cnt;
-
-       u8 preamble_len;
-       u16 max_frame_size;
-       u16 min_frame_size;
-
-       enum atl1c_mac_speed mac_speed;
-       bool mac_duplex;
-       bool hibernate;
-       u16 media_type;
-#define MEDIA_TYPE_AUTO_SENSOR  0
-#define MEDIA_TYPE_100M_FULL    1
-#define MEDIA_TYPE_100M_HALF    2
-#define MEDIA_TYPE_10M_FULL     3
-#define MEDIA_TYPE_10M_HALF     4
-
-       u16 autoneg_advertised;
-       u16 mii_autoneg_adv_reg;
-       u16 mii_1000t_ctrl_reg;
-
-       u16 tx_imt;     /* TX Interrupt Moderator timer ( 2us resolution) */
-       u16 rx_imt;     /* RX Interrupt Moderator timer ( 2us resolution) */
-       u16 ict;        /* Interrupt Clear timer (2us resolution) */
-       u16 ctrl_flags;
-#define ATL1C_INTR_CLEAR_ON_READ       0x0001
-#define ATL1C_INTR_MODRT_ENABLE                0x0002
-#define ATL1C_CMB_ENABLE               0x0004
-#define ATL1C_SMB_ENABLE               0x0010
-#define ATL1C_TXQ_MODE_ENHANCE         0x0020
-#define ATL1C_RX_IPV6_CHKSUM           0x0040
-#define ATL1C_ASPM_L0S_SUPPORT         0x0080
-#define ATL1C_ASPM_L1_SUPPORT          0x0100
-#define ATL1C_ASPM_CTRL_MON            0x0200
-#define ATL1C_HIB_DISABLE              0x0400
-#define ATL1C_APS_MODE_ENABLE           0x0800
-#define ATL1C_LINK_EXT_SYNC             0x1000
-#define ATL1C_CLK_GATING_EN             0x2000
-#define ATL1C_FPGA_VERSION              0x8000
-       u16 link_cap_flags;
-#define ATL1C_LINK_CAP_1000M           0x0001
-       u16 cmb_tpd;
-       u16 cmb_rrd;
-       u16 cmb_rx_timer; /* 2us resolution */
-       u16 cmb_tx_timer;
-       u32 smb_timer;
-
-       u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
-                         interrupt request */
-       u16 tpd_thresh;
-       u8 tpd_burst;   /* Number of TPD to prefetch in cache-aligned burst. */
-       u8 rfd_burst;
-       enum atl1c_rss_type rss_type;
-       enum atl1c_rss_mode rss_mode;
-       u8 rss_hash_bits;
-       u32 base_cpu;
-       u32 indirect_tab;
-       u8 mac_addr[ETH_ALEN];
-       u8 perm_mac_addr[ETH_ALEN];
-
-       bool phy_configured;
-       bool re_autoneg;
-       bool emi_ca;
-};
-
-/*
- * atl1c_ring_header represents a single, contiguous block of DMA space
- * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
- * message blocks (cmb, smb) described below
- */
-struct atl1c_ring_header {
-       void *desc;             /* virtual address */
-       dma_addr_t dma;         /* physical address*/
-       unsigned int size;      /* length in bytes */
-};
-
-/*
- * atl1c_buffer is wrapper around a pointer to a socket buffer
- * so a DMA handle can be stored along with the skb
- */
-struct atl1c_buffer {
-       struct sk_buff *skb;    /* socket buffer */
-       u16 length;             /* rx buffer length */
-       u16 flags;              /* information of buffer */
-#define ATL1C_BUFFER_FREE              0x0001
-#define ATL1C_BUFFER_BUSY              0x0002
-#define ATL1C_BUFFER_STATE_MASK                0x0003
-
-#define ATL1C_PCIMAP_SINGLE            0x0004
-#define ATL1C_PCIMAP_PAGE              0x0008
-#define ATL1C_PCIMAP_TYPE_MASK         0x000C
-
-#define ATL1C_PCIMAP_TODEVICE          0x0010
-#define ATL1C_PCIMAP_FROMDEVICE                0x0020
-#define ATL1C_PCIMAP_DIRECTION_MASK    0x0030
-       dma_addr_t dma;
-};
-
-#define ATL1C_SET_BUFFER_STATE(buff, state) do {       \
-       ((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK;    \
-       ((buff)->flags) |= (state);                     \
-       } while (0)
-
-#define ATL1C_SET_PCIMAP_TYPE(buff, type, direction) do {      \
-       ((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK;             \
-       ((buff)->flags) |= (type);                              \
-       ((buff)->flags) &= ~ATL1C_PCIMAP_DIRECTION_MASK;        \
-       ((buff)->flags) |= (direction);                         \
-       } while (0)
-
-/* transimit packet descriptor (tpd) ring */
-struct atl1c_tpd_ring {
-       void *desc;             /* descriptor ring virtual address */
-       dma_addr_t dma;         /* descriptor ring physical address */
-       u16 size;               /* descriptor ring length in bytes */
-       u16 count;              /* number of descriptors in the ring */
-       u16 next_to_use;        /* this is protectd by adapter->tx_lock */
-       atomic_t next_to_clean;
-       struct atl1c_buffer *buffer_info;
-};
-
-/* receive free descriptor (rfd) ring */
-struct atl1c_rfd_ring {
-       void *desc;             /* descriptor ring virtual address */
-       dma_addr_t dma;         /* descriptor ring physical address */
-       u16 size;               /* descriptor ring length in bytes */
-       u16 count;              /* number of descriptors in the ring */
-       u16 next_to_use;
-       u16 next_to_clean;
-       struct atl1c_buffer *buffer_info;
-};
-
-/* receive return descriptor (rrd) ring */
-struct atl1c_rrd_ring {
-       void *desc;             /* descriptor ring virtual address */
-       dma_addr_t dma;         /* descriptor ring physical address */
-       u16 size;               /* descriptor ring length in bytes */
-       u16 count;              /* number of descriptors in the ring */
-       u16 next_to_use;
-       u16 next_to_clean;
-};
-
-struct atl1c_cmb {
-       void *cmb;
-       dma_addr_t dma;
-};
-
-struct atl1c_smb {
-       void *smb;
-       dma_addr_t dma;
-};
-
-/* board specific private data structure */
-struct atl1c_adapter {
-       struct net_device   *netdev;
-       struct pci_dev      *pdev;
-       struct napi_struct  napi;
-       struct atl1c_hw        hw;
-       struct atl1c_hw_stats  hw_stats;
-       struct mii_if_info  mii;    /* MII interface info */
-       u16 rx_buffer_len;
-
-       unsigned long flags;
-#define __AT_TESTING        0x0001
-#define __AT_RESETTING      0x0002
-#define __AT_DOWN           0x0003
-       unsigned long work_event;
-#define        ATL1C_WORK_EVENT_RESET          0
-#define        ATL1C_WORK_EVENT_LINK_CHANGE    1
-       u32 msg_enable;
-
-       bool have_msi;
-       u32 wol;
-       u16 link_speed;
-       u16 link_duplex;
-
-       spinlock_t mdio_lock;
-       spinlock_t tx_lock;
-       atomic_t irq_sem;
-
-       struct work_struct common_task;
-       struct timer_list watchdog_timer;
-       struct timer_list phy_config_timer;
-
-       /* All Descriptor memory */
-       struct atl1c_ring_header ring_header;
-       struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE];
-       struct atl1c_rfd_ring rfd_ring[AT_MAX_RECEIVE_QUEUE];
-       struct atl1c_rrd_ring rrd_ring[AT_MAX_RECEIVE_QUEUE];
-       struct atl1c_cmb cmb;
-       struct atl1c_smb smb;
-       int num_rx_queues;
-       u32 bd_number;     /* board number;*/
-};
-
-#define AT_WRITE_REG(a, reg, value) ( \
-               writel((value), ((a)->hw_addr + reg)))
-
-#define AT_WRITE_FLUSH(a) (\
-               readl((a)->hw_addr))
-
-#define AT_READ_REG(a, reg, pdata) do {                                        \
-               if (unlikely((a)->hibernate)) {                         \
-                       readl((a)->hw_addr + reg);                      \
-                       *(u32 *)pdata = readl((a)->hw_addr + reg);      \
-               } else {                                                \
-                       *(u32 *)pdata = readl((a)->hw_addr + reg);      \
-               }                                                       \
-       } while (0)
-
-#define AT_WRITE_REGB(a, reg, value) (\
-               writeb((value), ((a)->hw_addr + reg)))
-
-#define AT_READ_REGB(a, reg) (\
-               readb((a)->hw_addr + reg))
-
-#define AT_WRITE_REGW(a, reg, value) (\
-               writew((value), ((a)->hw_addr + reg)))
-
-#define AT_READ_REGW(a, reg) (\
-               readw((a)->hw_addr + reg))
-
-#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
-               writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
-
-#define AT_READ_REG_ARRAY(a, reg, offset) ( \
-               readl(((a)->hw_addr + reg) + ((offset) << 2)))
-
-extern char atl1c_driver_name[];
-extern char atl1c_driver_version[];
-
-extern void atl1c_reinit_locked(struct atl1c_adapter *adapter);
-extern s32 atl1c_reset_hw(struct atl1c_hw *hw);
-extern void atl1c_set_ethtool_ops(struct net_device *netdev);
-#endif /* _ATL1C_H_ */
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
deleted file mode 100644 (file)
index 7be884d..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- *
- */
-
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/slab.h>
-
-#include "atl1c.h"
-
-static int atl1c_get_settings(struct net_device *netdev,
-                             struct ethtool_cmd *ecmd)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct atl1c_hw *hw = &adapter->hw;
-
-       ecmd->supported = (SUPPORTED_10baseT_Half  |
-                          SUPPORTED_10baseT_Full  |
-                          SUPPORTED_100baseT_Half |
-                          SUPPORTED_100baseT_Full |
-                          SUPPORTED_Autoneg       |
-                          SUPPORTED_TP);
-       if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M)
-               ecmd->supported |= SUPPORTED_1000baseT_Full;
-
-       ecmd->advertising = ADVERTISED_TP;
-
-       ecmd->advertising |= hw->autoneg_advertised;
-
-       ecmd->port = PORT_TP;
-       ecmd->phy_address = 0;
-       ecmd->transceiver = XCVR_INTERNAL;
-
-       if (adapter->link_speed != SPEED_0) {
-               ethtool_cmd_speed_set(ecmd, adapter->link_speed);
-               if (adapter->link_duplex == FULL_DUPLEX)
-                       ecmd->duplex = DUPLEX_FULL;
-               else
-                       ecmd->duplex = DUPLEX_HALF;
-       } else {
-               ethtool_cmd_speed_set(ecmd, -1);
-               ecmd->duplex = -1;
-       }
-
-       ecmd->autoneg = AUTONEG_ENABLE;
-       return 0;
-}
-
-static int atl1c_set_settings(struct net_device *netdev,
-                             struct ethtool_cmd *ecmd)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct atl1c_hw *hw = &adapter->hw;
-       u16  autoneg_advertised;
-
-       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
-               msleep(1);
-
-       if (ecmd->autoneg == AUTONEG_ENABLE) {
-               autoneg_advertised = ADVERTISED_Autoneg;
-       } else {
-               u32 speed = ethtool_cmd_speed(ecmd);
-               if (speed == SPEED_1000) {
-                       if (ecmd->duplex != DUPLEX_FULL) {
-                               if (netif_msg_link(adapter))
-                                       dev_warn(&adapter->pdev->dev,
-                                               "1000M half is invalid\n");
-                               clear_bit(__AT_RESETTING, &adapter->flags);
-                               return -EINVAL;
-                       }
-                       autoneg_advertised = ADVERTISED_1000baseT_Full;
-               } else if (speed == SPEED_100) {
-                       if (ecmd->duplex == DUPLEX_FULL)
-                               autoneg_advertised = ADVERTISED_100baseT_Full;
-                       else
-                               autoneg_advertised = ADVERTISED_100baseT_Half;
-               } else {
-                       if (ecmd->duplex == DUPLEX_FULL)
-                               autoneg_advertised = ADVERTISED_10baseT_Full;
-                       else
-                               autoneg_advertised = ADVERTISED_10baseT_Half;
-               }
-       }
-
-       if (hw->autoneg_advertised != autoneg_advertised) {
-               hw->autoneg_advertised = autoneg_advertised;
-               if (atl1c_restart_autoneg(hw) != 0) {
-                       if (netif_msg_link(adapter))
-                               dev_warn(&adapter->pdev->dev,
-                                       "ethtool speed/duplex setting failed\n");
-                       clear_bit(__AT_RESETTING, &adapter->flags);
-                       return -EINVAL;
-               }
-       }
-       clear_bit(__AT_RESETTING, &adapter->flags);
-       return 0;
-}
-
-static u32 atl1c_get_msglevel(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       return adapter->msg_enable;
-}
-
-static void atl1c_set_msglevel(struct net_device *netdev, u32 data)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       adapter->msg_enable = data;
-}
-
-static int atl1c_get_regs_len(struct net_device *netdev)
-{
-       return AT_REGS_LEN;
-}
-
-static void atl1c_get_regs(struct net_device *netdev,
-                          struct ethtool_regs *regs, void *p)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct atl1c_hw *hw = &adapter->hw;
-       u32 *regs_buff = p;
-       u16 phy_data;
-
-       memset(p, 0, AT_REGS_LEN);
-
-       regs->version = 0;
-       AT_READ_REG(hw, REG_VPD_CAP,              p++);
-       AT_READ_REG(hw, REG_PM_CTRL,              p++);
-       AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL,  p++);
-       AT_READ_REG(hw, REG_TWSI_CTRL,            p++);
-       AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL,   p++);
-       AT_READ_REG(hw, REG_MASTER_CTRL,          p++);
-       AT_READ_REG(hw, REG_MANUAL_TIMER_INIT,    p++);
-       AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++);
-       AT_READ_REG(hw, REG_GPHY_CTRL,            p++);
-       AT_READ_REG(hw, REG_LINK_CTRL,            p++);
-       AT_READ_REG(hw, REG_IDLE_STATUS,          p++);
-       AT_READ_REG(hw, REG_MDIO_CTRL,            p++);
-       AT_READ_REG(hw, REG_SERDES_LOCK,          p++);
-       AT_READ_REG(hw, REG_MAC_CTRL,             p++);
-       AT_READ_REG(hw, REG_MAC_IPG_IFG,          p++);
-       AT_READ_REG(hw, REG_MAC_STA_ADDR,         p++);
-       AT_READ_REG(hw, REG_MAC_STA_ADDR+4,       p++);
-       AT_READ_REG(hw, REG_RX_HASH_TABLE,        p++);
-       AT_READ_REG(hw, REG_RX_HASH_TABLE+4,      p++);
-       AT_READ_REG(hw, REG_RXQ_CTRL,             p++);
-       AT_READ_REG(hw, REG_TXQ_CTRL,             p++);
-       AT_READ_REG(hw, REG_MTU,                  p++);
-       AT_READ_REG(hw, REG_WOL_CTRL,             p++);
-
-       atl1c_read_phy_reg(hw, MII_BMCR, &phy_data);
-       regs_buff[73] = (u32) phy_data;
-       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
-       regs_buff[74] = (u32) phy_data;
-}
-
-static int atl1c_get_eeprom_len(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       if (atl1c_check_eeprom_exist(&adapter->hw))
-               return AT_EEPROM_LEN;
-       else
-               return 0;
-}
-
-static int atl1c_get_eeprom(struct net_device *netdev,
-               struct ethtool_eeprom *eeprom, u8 *bytes)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct atl1c_hw *hw = &adapter->hw;
-       u32 *eeprom_buff;
-       int first_dword, last_dword;
-       int ret_val = 0;
-       int i;
-
-       if (eeprom->len == 0)
-               return -EINVAL;
-
-       if (!atl1c_check_eeprom_exist(hw)) /* not exist */
-               return -EINVAL;
-
-       eeprom->magic = adapter->pdev->vendor |
-                       (adapter->pdev->device << 16);
-
-       first_dword = eeprom->offset >> 2;
-       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
-
-       eeprom_buff = kmalloc(sizeof(u32) *
-                       (last_dword - first_dword + 1), GFP_KERNEL);
-       if (eeprom_buff == NULL)
-               return -ENOMEM;
-
-       for (i = first_dword; i < last_dword; i++) {
-               if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
-                       kfree(eeprom_buff);
-                       return -EIO;
-               }
-       }
-
-       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
-                       eeprom->len);
-       kfree(eeprom_buff);
-
-       return ret_val;
-       return 0;
-}
-
-static void atl1c_get_drvinfo(struct net_device *netdev,
-               struct ethtool_drvinfo *drvinfo)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       strlcpy(drvinfo->driver,  atl1c_driver_name, sizeof(drvinfo->driver));
-       strlcpy(drvinfo->version, atl1c_driver_version,
-               sizeof(drvinfo->version));
-       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-       strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
-               sizeof(drvinfo->bus_info));
-       drvinfo->n_stats = 0;
-       drvinfo->testinfo_len = 0;
-       drvinfo->regdump_len = atl1c_get_regs_len(netdev);
-       drvinfo->eedump_len = atl1c_get_eeprom_len(netdev);
-}
-
-static void atl1c_get_wol(struct net_device *netdev,
-                         struct ethtool_wolinfo *wol)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       wol->supported = WAKE_MAGIC | WAKE_PHY;
-       wol->wolopts = 0;
-
-       if (adapter->wol & AT_WUFC_EX)
-               wol->wolopts |= WAKE_UCAST;
-       if (adapter->wol & AT_WUFC_MC)
-               wol->wolopts |= WAKE_MCAST;
-       if (adapter->wol & AT_WUFC_BC)
-               wol->wolopts |= WAKE_BCAST;
-       if (adapter->wol & AT_WUFC_MAG)
-               wol->wolopts |= WAKE_MAGIC;
-       if (adapter->wol & AT_WUFC_LNKC)
-               wol->wolopts |= WAKE_PHY;
-}
-
-static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-                           WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
-               return -EOPNOTSUPP;
-       /* these settings will always override what we currently have */
-       adapter->wol = 0;
-
-       if (wol->wolopts & WAKE_MAGIC)
-               adapter->wol |= AT_WUFC_MAG;
-       if (wol->wolopts & WAKE_PHY)
-               adapter->wol |= AT_WUFC_LNKC;
-
-       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
-
-       return 0;
-}
-
-static int atl1c_nway_reset(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       if (netif_running(netdev))
-               atl1c_reinit_locked(adapter);
-       return 0;
-}
-
-static const struct ethtool_ops atl1c_ethtool_ops = {
-       .get_settings           = atl1c_get_settings,
-       .set_settings           = atl1c_set_settings,
-       .get_drvinfo            = atl1c_get_drvinfo,
-       .get_regs_len           = atl1c_get_regs_len,
-       .get_regs               = atl1c_get_regs,
-       .get_wol                = atl1c_get_wol,
-       .set_wol                = atl1c_set_wol,
-       .get_msglevel           = atl1c_get_msglevel,
-       .set_msglevel           = atl1c_set_msglevel,
-       .nway_reset             = atl1c_nway_reset,
-       .get_link               = ethtool_op_get_link,
-       .get_eeprom_len         = atl1c_get_eeprom_len,
-       .get_eeprom             = atl1c_get_eeprom,
-};
-
-void atl1c_set_ethtool_ops(struct net_device *netdev)
-{
-       SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops);
-}
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c
deleted file mode 100644 (file)
index 23f2ab0..0000000
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mii.h>
-#include <linux/crc32.h>
-
-#include "atl1c.h"
-
-/*
- * check_eeprom_exist
- * return 1 if eeprom exist
- */
-int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
-{
-       u32 data;
-
-       AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
-       if (data & TWSI_DEBUG_DEV_EXIST)
-               return 1;
-
-       AT_READ_REG(hw, REG_MASTER_CTRL, &data);
-       if (data & MASTER_CTRL_OTP_SEL)
-               return 1;
-       return 0;
-}
-
-void atl1c_hw_set_mac_addr(struct atl1c_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])) ;
-       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
-       /* hight dword */
-       value = (((u32)hw->mac_addr[0]) << 8) |
-               (((u32)hw->mac_addr[1])) ;
-       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
-}
-
-/*
- * atl1c_get_permanent_address
- * return 0 if get valid mac address,
- */
-static int atl1c_get_permanent_address(struct atl1c_hw *hw)
-{
-       u32 addr[2];
-       u32 i;
-       u32 otp_ctrl_data;
-       u32 twsi_ctrl_data;
-       u32 ltssm_ctrl_data;
-       u32 wol_data;
-       u8  eth_addr[ETH_ALEN];
-       u16 phy_data;
-       bool raise_vol = false;
-
-       /* init */
-       addr[0] = addr[1] = 0;
-       AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
-       if (atl1c_check_eeprom_exist(hw)) {
-               if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
-                       /* Enable OTP CLK */
-                       if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
-                               otp_ctrl_data |= OTP_CTRL_CLK_EN;
-                               AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
-                               AT_WRITE_FLUSH(hw);
-                               msleep(1);
-                       }
-               }
-
-               if (hw->nic_type == athr_l2c_b ||
-                   hw->nic_type == athr_l2c_b2 ||
-                   hw->nic_type == athr_l1d) {
-                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
-                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
-                               goto out;
-                       phy_data &= 0xFF7F;
-                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
-
-                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
-                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
-                               goto out;
-                       phy_data |= 0x8;
-                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
-                       udelay(20);
-                       raise_vol = true;
-               }
-               /* close open bit of ReadOnly*/
-               AT_READ_REG(hw, REG_LTSSM_ID_CTRL, &ltssm_ctrl_data);
-               ltssm_ctrl_data &= ~LTSSM_ID_EN_WRO;
-               AT_WRITE_REG(hw, REG_LTSSM_ID_CTRL, ltssm_ctrl_data);
-
-               /* clear any WOL settings */
-               AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
-               AT_READ_REG(hw, REG_WOL_CTRL, &wol_data);
-
-
-               AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
-               twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
-               AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
-               for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
-                       msleep(10);
-                       AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
-                       if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
-                               break;
-               }
-               if (i >= AT_TWSI_EEPROM_TIMEOUT)
-                       return -1;
-       }
-       /* Disable OTP_CLK */
-       if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
-               otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
-               AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
-               msleep(1);
-       }
-       if (raise_vol) {
-               if (hw->nic_type == athr_l2c_b ||
-                   hw->nic_type == athr_l2c_b2 ||
-                   hw->nic_type == athr_l1d ||
-                   hw->nic_type == athr_l1d_2) {
-                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
-                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
-                               goto out;
-                       phy_data |= 0x80;
-                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
-
-                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
-                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
-                               goto out;
-                       phy_data &= 0xFFF7;
-                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
-                       udelay(20);
-               }
-       }
-
-       /* maybe MAC-address is from BIOS */
-       AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
-       AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
-       *(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;
-       }
-
-out:
-       return -1;
-}
-
-bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
-{
-       int i;
-       int ret = false;
-       u32 otp_ctrl_data;
-       u32 control;
-       u32 data;
-
-       if (offset & 3)
-               return ret; /* address do not align */
-
-       AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
-       if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
-               AT_WRITE_REG(hw, REG_OTP_CTRL,
-                               (otp_ctrl_data | OTP_CTRL_CLK_EN));
-
-       AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
-       control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
-       AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
-
-       for (i = 0; i < 10; i++) {
-               udelay(100);
-               AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
-               if (control & EEPROM_CTRL_RW)
-                       break;
-       }
-       if (control & EEPROM_CTRL_RW) {
-               AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
-               AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
-               data = data & 0xFFFF;
-               *p_value = swab32((data << 16) | (*p_value >> 16));
-               ret = true;
-       }
-       if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
-               AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
-
-       return ret;
-}
-/*
- * Reads the adapter's MAC address from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- */
-int atl1c_read_mac_addr(struct atl1c_hw *hw)
-{
-       int err = 0;
-
-       err = atl1c_get_permanent_address(hw);
-       if (err)
-               random_ether_addr(hw->perm_mac_addr);
-
-       memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
-       return 0;
-}
-
-/*
- * atl1c_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 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
-{
-       u32 crc32;
-       u32 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 atl1c_hash_set(struct atl1c_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 bit 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 = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
-
-       mta |= (1 << hash_bit);
-
-       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
-}
-
-/*
- * Reads the value from a PHY register
- * hw - Struct containing variables accessed by shared code
- * reg_addr - address of the PHY register to read
- */
-int atl1c_read_phy_reg(struct atl1c_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;
-
-       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
-
-       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
-               udelay(2);
-               AT_READ_REG(hw, REG_MDIO_CTRL, &val);
-               if (!(val & (MDIO_START | MDIO_BUSY)))
-                       break;
-       }
-       if (!(val & (MDIO_START | MDIO_BUSY))) {
-               *phy_data = (u16)val;
-               return 0;
-       }
-
-       return -1;
-}
-
-/*
- * 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
- */
-int atl1c_write_phy_reg(struct atl1c_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;
-
-       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
-
-       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
-               udelay(2);
-               AT_READ_REG(hw, REG_MDIO_CTRL, &val);
-               if (!(val & (MDIO_START | MDIO_BUSY)))
-                       break;
-       }
-
-       if (!(val & (MDIO_START | MDIO_BUSY)))
-               return 0;
-
-       return -1;
-}
-
-/*
- * Configures PHY autoneg and flow control advertisement settings
- *
- * hw - Struct containing variables accessed by shared code
- */
-static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
-{
-       u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_ALL;
-       u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
-                               ~GIGA_CR_1000T_SPEED_MASK;
-
-       if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
-               mii_adv_data |= ADVERTISE_10HALF;
-       if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
-               mii_adv_data |= ADVERTISE_10FULL;
-       if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
-               mii_adv_data |= ADVERTISE_100HALF;
-       if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
-               mii_adv_data |= ADVERTISE_100FULL;
-
-       if (hw->autoneg_advertised & ADVERTISED_Autoneg)
-               mii_adv_data |= ADVERTISE_10HALF  | ADVERTISE_10FULL |
-                               ADVERTISE_100HALF | ADVERTISE_100FULL;
-
-       if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
-               if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
-                       mii_giga_ctrl_data |= ADVERTISE_1000HALF;
-               if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
-                       mii_giga_ctrl_data |= ADVERTISE_1000FULL;
-               if (hw->autoneg_advertised & ADVERTISED_Autoneg)
-                       mii_giga_ctrl_data |= ADVERTISE_1000HALF |
-                                       ADVERTISE_1000FULL;
-       }
-
-       if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
-           atl1c_write_phy_reg(hw, MII_CTRL1000, mii_giga_ctrl_data) != 0)
-               return -1;
-       return 0;
-}
-
-void atl1c_phy_disable(struct atl1c_hw *hw)
-{
-       AT_WRITE_REGW(hw, REG_GPHY_CTRL,
-                       GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
-}
-
-static void atl1c_phy_magic_data(struct atl1c_hw *hw)
-{
-       u16 data;
-
-       data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
-               ((1 & ANA_INTERVAL_SEL_TIMER_MASK) <<
-               ANA_INTERVAL_SEL_TIMER_SHIFT);
-
-       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_18);
-       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
-       data = (2 & ANA_SERDES_CDR_BW_MASK) | ANA_MS_PAD_DBG |
-               ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | ANA_SERDES_EN_PLL |
-               ANA_SERDES_EN_LCKDT;
-
-       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_5);
-       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
-       data = (44 & ANA_LONG_CABLE_TH_100_MASK) |
-               ((33 & ANA_SHORT_CABLE_TH_100_MASK) <<
-               ANA_SHORT_CABLE_TH_100_SHIFT) | ANA_BP_BAD_LINK_ACCUM |
-               ANA_BP_SMALL_BW;
-
-       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_54);
-       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
-       data = (11 & ANA_IECHO_ADJ_MASK) | ((11 & ANA_IECHO_ADJ_MASK) <<
-               ANA_IECHO_ADJ_2_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
-               ANA_IECHO_ADJ_1_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
-               ANA_IECHO_ADJ_0_SHIFT);
-
-       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_4);
-       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
-       data = ANA_RESTART_CAL | ((7 & ANA_MANUL_SWICH_ON_MASK) <<
-               ANA_MANUL_SWICH_ON_SHIFT) | ANA_MAN_ENABLE |
-               ANA_SEL_HSP | ANA_EN_HB | ANA_OEN_125M;
-
-       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_0);
-       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
-       if (hw->ctrl_flags & ATL1C_HIB_DISABLE) {
-               atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_41);
-               if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
-                       return;
-               data &= ~ANA_TOP_PS_EN;
-               atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-
-               atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_11);
-               if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
-                       return;
-               data &= ~ANA_PS_HIB_EN;
-               atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
-       }
-}
-
-int atl1c_phy_reset(struct atl1c_hw *hw)
-{
-       struct atl1c_adapter *adapter = hw->adapter;
-       struct pci_dev *pdev = adapter->pdev;
-       u16 phy_data;
-       u32 phy_ctrl_data = GPHY_CTRL_DEFAULT;
-       u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN;
-       int err;
-
-       if (hw->ctrl_flags & ATL1C_HIB_DISABLE)
-               phy_ctrl_data &= ~GPHY_CTRL_HIB_EN;
-
-       AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
-       AT_WRITE_FLUSH(hw);
-       msleep(40);
-       phy_ctrl_data |= GPHY_CTRL_EXT_RESET;
-       AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
-       AT_WRITE_FLUSH(hw);
-       msleep(10);
-
-       if (hw->nic_type == athr_l2c_b) {
-               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x0A);
-               atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
-               atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xDFFF);
-       }
-
-       if (hw->nic_type == athr_l2c_b ||
-           hw->nic_type == athr_l2c_b2 ||
-           hw->nic_type == athr_l1d ||
-           hw->nic_type == athr_l1d_2) {
-               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
-               atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
-               atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7);
-               msleep(20);
-       }
-       if (hw->nic_type == athr_l1d) {
-               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
-               atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D);
-       }
-       if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2
-               || hw->nic_type == athr_l2c) {
-               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
-               atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD);
-       }
-       err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data);
-       if (err) {
-               if (netif_msg_hw(adapter))
-                       dev_err(&pdev->dev,
-                               "Error enable PHY linkChange Interrupt\n");
-               return err;
-       }
-       if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
-               atl1c_phy_magic_data(hw);
-       return 0;
-}
-
-int atl1c_phy_init(struct atl1c_hw *hw)
-{
-       struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
-       struct pci_dev *pdev = adapter->pdev;
-       int ret_val;
-       u16 mii_bmcr_data = BMCR_RESET;
-
-       if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) ||
-               (atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) {
-               dev_err(&pdev->dev, "Error get phy ID\n");
-               return -1;
-       }
-       switch (hw->media_type) {
-       case MEDIA_TYPE_AUTO_SENSOR:
-               ret_val = atl1c_phy_setup_adv(hw);
-               if (ret_val) {
-                       if (netif_msg_link(adapter))
-                               dev_err(&pdev->dev,
-                                       "Error Setting up Auto-Negotiation\n");
-                       return ret_val;
-               }
-               mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
-               break;
-       case MEDIA_TYPE_100M_FULL:
-               mii_bmcr_data |= BMCR_SPEED100 | BMCR_FULLDPLX;
-               break;
-       case MEDIA_TYPE_100M_HALF:
-               mii_bmcr_data |= BMCR_SPEED100;
-               break;
-       case MEDIA_TYPE_10M_FULL:
-               mii_bmcr_data |= BMCR_FULLDPLX;
-               break;
-       case MEDIA_TYPE_10M_HALF:
-               break;
-       default:
-               if (netif_msg_link(adapter))
-                       dev_err(&pdev->dev, "Wrong Media type %d\n",
-                               hw->media_type);
-               return -1;
-               break;
-       }
-
-       ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
-       if (ret_val)
-               return ret_val;
-       hw->phy_configured = true;
-
-       return 0;
-}
-
-/*
- * 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
- */
-int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
-{
-       int err;
-       u16 phy_data;
-
-       /* Read   PHY Specific Status Register (17) */
-       err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
-       if (err)
-               return err;
-
-       if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
-               return -1;
-
-       switch (phy_data & GIGA_PSSR_SPEED) {
-       case GIGA_PSSR_1000MBS:
-               *speed = SPEED_1000;
-               break;
-       case GIGA_PSSR_100MBS:
-               *speed = SPEED_100;
-               break;
-       case  GIGA_PSSR_10MBS:
-               *speed = SPEED_10;
-               break;
-       default:
-               return -1;
-               break;
-       }
-
-       if (phy_data & GIGA_PSSR_DPLX)
-               *duplex = FULL_DUPLEX;
-       else
-               *duplex = HALF_DUPLEX;
-
-       return 0;
-}
-
-int atl1c_phy_power_saving(struct atl1c_hw *hw)
-{
-       struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
-       struct pci_dev *pdev = adapter->pdev;
-       int ret = 0;
-       u16 autoneg_advertised = ADVERTISED_10baseT_Half;
-       u16 save_autoneg_advertised;
-       u16 phy_data;
-       u16 mii_lpa_data;
-       u16 speed = SPEED_0;
-       u16 duplex = FULL_DUPLEX;
-       int i;
-
-       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
-       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
-       if (phy_data & BMSR_LSTATUS) {
-               atl1c_read_phy_reg(hw, MII_LPA, &mii_lpa_data);
-               if (mii_lpa_data & LPA_10FULL)
-                       autoneg_advertised = ADVERTISED_10baseT_Full;
-               else if (mii_lpa_data & LPA_10HALF)
-                       autoneg_advertised = ADVERTISED_10baseT_Half;
-               else if (mii_lpa_data & LPA_100HALF)
-                       autoneg_advertised = ADVERTISED_100baseT_Half;
-               else if (mii_lpa_data & LPA_100FULL)
-                       autoneg_advertised = ADVERTISED_100baseT_Full;
-
-               save_autoneg_advertised = hw->autoneg_advertised;
-               hw->phy_configured = false;
-               hw->autoneg_advertised = autoneg_advertised;
-               if (atl1c_restart_autoneg(hw) != 0) {
-                       dev_dbg(&pdev->dev, "phy autoneg failed\n");
-                       ret = -1;
-               }
-               hw->autoneg_advertised = save_autoneg_advertised;
-
-               if (mii_lpa_data) {
-                       for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
-                               mdelay(100);
-                               atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
-                               atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
-                               if (phy_data & BMSR_LSTATUS) {
-                                       if (atl1c_get_speed_and_duplex(hw, &speed,
-                                                                       &duplex) != 0)
-                                               dev_dbg(&pdev->dev,
-                                                       "get speed and duplex failed\n");
-                                       break;
-                               }
-                       }
-               }
-       } else {
-               speed = SPEED_10;
-               duplex = HALF_DUPLEX;
-       }
-       adapter->link_speed = speed;
-       adapter->link_duplex = duplex;
-
-       return ret;
-}
-
-int atl1c_restart_autoneg(struct atl1c_hw *hw)
-{
-       int err = 0;
-       u16 mii_bmcr_data = BMCR_RESET;
-
-       err = atl1c_phy_setup_adv(hw);
-       if (err)
-               return err;
-       mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
-
-       return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
-}
diff --git a/drivers/net/atl1c/atl1c_hw.h b/drivers/net/atl1c/atl1c_hw.h
deleted file mode 100644 (file)
index 655fc6c..0000000
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#ifndef _ATL1C_HW_H_
-#define _ATL1C_HW_H_
-
-#include <linux/types.h>
-#include <linux/mii.h>
-
-struct atl1c_adapter;
-struct atl1c_hw;
-
-/* function prototype */
-void atl1c_phy_disable(struct atl1c_hw *hw);
-void atl1c_hw_set_mac_addr(struct atl1c_hw *hw);
-int atl1c_phy_reset(struct atl1c_hw *hw);
-int atl1c_read_mac_addr(struct atl1c_hw *hw);
-int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex);
-u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr);
-void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value);
-int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data);
-int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data);
-bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value);
-int atl1c_phy_init(struct atl1c_hw *hw);
-int atl1c_check_eeprom_exist(struct atl1c_hw *hw);
-int atl1c_restart_autoneg(struct atl1c_hw *hw);
-int atl1c_phy_power_saving(struct atl1c_hw *hw);
-/* register definition */
-#define REG_DEVICE_CAP                 0x5C
-#define DEVICE_CAP_MAX_PAYLOAD_MASK     0x7
-#define DEVICE_CAP_MAX_PAYLOAD_SHIFT    0
-
-#define REG_DEVICE_CTRL                        0x60
-#define DEVICE_CTRL_MAX_PAYLOAD_MASK    0x7
-#define DEVICE_CTRL_MAX_PAYLOAD_SHIFT   5
-#define DEVICE_CTRL_MAX_RREQ_SZ_MASK    0x7
-#define DEVICE_CTRL_MAX_RREQ_SZ_SHIFT   12
-
-#define REG_LINK_CTRL                  0x68
-#define LINK_CTRL_L0S_EN               0x01
-#define LINK_CTRL_L1_EN                        0x02
-#define LINK_CTRL_EXT_SYNC             0x80
-
-#define REG_VPD_CAP                    0x6C
-#define VPD_CAP_ID_MASK                 0xff
-#define VPD_CAP_ID_SHIFT                0
-#define VPD_CAP_NEXT_PTR_MASK           0xFF
-#define VPD_CAP_NEXT_PTR_SHIFT          8
-#define VPD_CAP_VPD_ADDR_MASK           0x7FFF
-#define VPD_CAP_VPD_ADDR_SHIFT          16
-#define VPD_CAP_VPD_FLAG                0x80000000
-
-#define REG_VPD_DATA                   0x70
-
-#define REG_PCIE_UC_SEVERITY           0x10C
-#define PCIE_UC_SERVRITY_TRN           0x00000001
-#define PCIE_UC_SERVRITY_DLP           0x00000010
-#define PCIE_UC_SERVRITY_PSN_TLP       0x00001000
-#define PCIE_UC_SERVRITY_FCP           0x00002000
-#define PCIE_UC_SERVRITY_CPL_TO                0x00004000
-#define PCIE_UC_SERVRITY_CA            0x00008000
-#define PCIE_UC_SERVRITY_UC            0x00010000
-#define PCIE_UC_SERVRITY_ROV           0x00020000
-#define PCIE_UC_SERVRITY_MLFP          0x00040000
-#define PCIE_UC_SERVRITY_ECRC          0x00080000
-#define PCIE_UC_SERVRITY_UR            0x00100000
-
-#define REG_DEV_SERIALNUM_CTRL         0x200
-#define REG_DEV_MAC_SEL_MASK           0x0 /* 0:EUI; 1:MAC */
-#define REG_DEV_MAC_SEL_SHIFT          0
-#define REG_DEV_SERIAL_NUM_EN_MASK     0x1
-#define REG_DEV_SERIAL_NUM_EN_SHIFT    1
-
-#define REG_TWSI_CTRL                  0x218
-#define TWSI_CTRL_LD_OFFSET_MASK        0xFF
-#define TWSI_CTRL_LD_OFFSET_SHIFT       0
-#define TWSI_CTRL_LD_SLV_ADDR_MASK      0x7
-#define TWSI_CTRL_LD_SLV_ADDR_SHIFT     8
-#define TWSI_CTRL_SW_LDSTART            0x800
-#define TWSI_CTRL_HW_LDSTART            0x1000
-#define TWSI_CTRL_SMB_SLV_ADDR_MASK     0x7F
-#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT    15
-#define TWSI_CTRL_LD_EXIST              0x400000
-#define TWSI_CTRL_READ_FREQ_SEL_MASK    0x3
-#define TWSI_CTRL_READ_FREQ_SEL_SHIFT   23
-#define TWSI_CTRL_FREQ_SEL_100K         0
-#define TWSI_CTRL_FREQ_SEL_200K         1
-#define TWSI_CTRL_FREQ_SEL_300K         2
-#define TWSI_CTRL_FREQ_SEL_400K         3
-#define TWSI_CTRL_SMB_SLV_ADDR
-#define TWSI_CTRL_WRITE_FREQ_SEL_MASK   0x3
-#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT  24
-
-
-#define REG_PCIE_DEV_MISC_CTRL         0x21C
-#define PCIE_DEV_MISC_EXT_PIPE         0x2
-#define PCIE_DEV_MISC_RETRY_BUFDIS     0x1
-#define PCIE_DEV_MISC_SPIROM_EXIST     0x4
-#define PCIE_DEV_MISC_SERDES_ENDIAN            0x8
-#define PCIE_DEV_MISC_SERDES_SEL_DIN           0x10
-
-#define REG_PCIE_PHYMISC               0x1000
-#define PCIE_PHYMISC_FORCE_RCV_DET     0x4
-
-#define REG_PCIE_PHYMISC2              0x1004
-#define PCIE_PHYMISC2_SERDES_CDR_MASK  0x3
-#define PCIE_PHYMISC2_SERDES_CDR_SHIFT 16
-#define PCIE_PHYMISC2_SERDES_TH_MASK   0x3
-#define PCIE_PHYMISC2_SERDES_TH_SHIFT  18
-
-#define REG_TWSI_DEBUG                 0x1108
-#define TWSI_DEBUG_DEV_EXIST           0x20000000
-
-#define REG_EEPROM_CTRL                        0x12C0
-#define EEPROM_CTRL_DATA_HI_MASK       0xFFFF
-#define EEPROM_CTRL_DATA_HI_SHIFT      0
-#define EEPROM_CTRL_ADDR_MASK          0x3FF
-#define EEPROM_CTRL_ADDR_SHIFT         16
-#define EEPROM_CTRL_ACK                        0x40000000
-#define EEPROM_CTRL_RW                 0x80000000
-
-#define REG_EEPROM_DATA_LO             0x12C4
-
-#define REG_OTP_CTRL                   0x12F0
-#define OTP_CTRL_CLK_EN                        0x0002
-
-#define REG_PM_CTRL                    0x12F8
-#define PM_CTRL_SDES_EN                        0x00000001
-#define PM_CTRL_RBER_EN                        0x00000002
-#define PM_CTRL_CLK_REQ_EN             0x00000004
-#define PM_CTRL_ASPM_L1_EN             0x00000008
-#define PM_CTRL_SERDES_L1_EN           0x00000010
-#define PM_CTRL_SERDES_PLL_L1_EN       0x00000020
-#define PM_CTRL_SERDES_PD_EX_L1                0x00000040
-#define PM_CTRL_SERDES_BUDS_RX_L1_EN   0x00000080
-#define PM_CTRL_L0S_ENTRY_TIMER_MASK   0xF
-#define PM_CTRL_L0S_ENTRY_TIMER_SHIFT  8
-#define PM_CTRL_ASPM_L0S_EN            0x00001000
-#define PM_CTRL_CLK_SWH_L1             0x00002000
-#define PM_CTRL_CLK_PWM_VER1_1         0x00004000
-#define PM_CTRL_RCVR_WT_TIMER          0x00008000
-#define PM_CTRL_L1_ENTRY_TIMER_MASK    0xF
-#define PM_CTRL_L1_ENTRY_TIMER_SHIFT   16
-#define PM_CTRL_PM_REQ_TIMER_MASK      0xF
-#define PM_CTRL_PM_REQ_TIMER_SHIFT     20
-#define PM_CTRL_LCKDET_TIMER_MASK      0xF
-#define PM_CTRL_LCKDET_TIMER_SHIFT     24
-#define PM_CTRL_EN_BUFS_RX_L0S         0x10000000
-#define PM_CTRL_SA_DLY_EN              0x20000000
-#define PM_CTRL_MAC_ASPM_CHK           0x40000000
-#define PM_CTRL_HOTRST                 0x80000000
-
-#define REG_LTSSM_ID_CTRL              0x12FC
-#define LTSSM_ID_EN_WRO                        0x1000
-/* Selene Master Control Register */
-#define REG_MASTER_CTRL                        0x1400
-#define MASTER_CTRL_SOFT_RST            0x1
-#define MASTER_CTRL_TEST_MODE_MASK     0x3
-#define MASTER_CTRL_TEST_MODE_SHIFT    2
-#define MASTER_CTRL_BERT_START         0x10
-#define MASTER_CTRL_OOB_DIS_OFF                0x40
-#define MASTER_CTRL_SA_TIMER_EN                0x80
-#define MASTER_CTRL_MTIMER_EN           0x100
-#define MASTER_CTRL_MANUAL_INT          0x200
-#define MASTER_CTRL_TX_ITIMER_EN       0x400
-#define MASTER_CTRL_RX_ITIMER_EN       0x800
-#define MASTER_CTRL_CLK_SEL_DIS                0x1000
-#define MASTER_CTRL_CLK_SWH_MODE       0x2000
-#define MASTER_CTRL_INT_RDCLR          0x4000
-#define MASTER_CTRL_REV_NUM_SHIFT      16
-#define MASTER_CTRL_REV_NUM_MASK       0xff
-#define MASTER_CTRL_DEV_ID_SHIFT       24
-#define MASTER_CTRL_DEV_ID_MASK                0x7f
-#define MASTER_CTRL_OTP_SEL            0x80000000
-
-/* Timer Initial Value Register */
-#define REG_MANUAL_TIMER_INIT          0x1404
-
-/* IRQ ModeratorTimer Initial Value Register */
-#define REG_IRQ_MODRT_TIMER_INIT       0x1408
-#define IRQ_MODRT_TIMER_MASK           0xffff
-#define IRQ_MODRT_TX_TIMER_SHIFT       0
-#define IRQ_MODRT_RX_TIMER_SHIFT       16
-
-#define REG_GPHY_CTRL                  0x140C
-#define GPHY_CTRL_EXT_RESET            0x1
-#define GPHY_CTRL_RTL_MODE             0x2
-#define GPHY_CTRL_LED_MODE             0x4
-#define GPHY_CTRL_ANEG_NOW             0x8
-#define GPHY_CTRL_REV_ANEG             0x10
-#define GPHY_CTRL_GATE_25M_EN          0x20
-#define GPHY_CTRL_LPW_EXIT             0x40
-#define GPHY_CTRL_PHY_IDDQ             0x80
-#define GPHY_CTRL_PHY_IDDQ_DIS         0x100
-#define GPHY_CTRL_GIGA_DIS             0x200
-#define GPHY_CTRL_HIB_EN               0x400
-#define GPHY_CTRL_HIB_PULSE            0x800
-#define GPHY_CTRL_SEL_ANA_RST          0x1000
-#define GPHY_CTRL_PHY_PLL_ON           0x2000
-#define GPHY_CTRL_PWDOWN_HW            0x4000
-#define GPHY_CTRL_PHY_PLL_BYPASS       0x8000
-
-#define GPHY_CTRL_DEFAULT (             \
-               GPHY_CTRL_SEL_ANA_RST   |\
-               GPHY_CTRL_HIB_PULSE     |\
-               GPHY_CTRL_HIB_EN)
-
-#define GPHY_CTRL_PW_WOL_DIS (          \
-               GPHY_CTRL_SEL_ANA_RST   |\
-               GPHY_CTRL_HIB_PULSE     |\
-               GPHY_CTRL_HIB_EN        |\
-               GPHY_CTRL_PWDOWN_HW     |\
-               GPHY_CTRL_PHY_IDDQ)
-
-#define GPHY_CTRL_POWER_SAVING (       \
-               GPHY_CTRL_SEL_ANA_RST   |\
-               GPHY_CTRL_HIB_EN        |\
-               GPHY_CTRL_HIB_PULSE     |\
-               GPHY_CTRL_PWDOWN_HW     |\
-               GPHY_CTRL_PHY_IDDQ)
-/* Block IDLE Status Register */
-#define REG_IDLE_STATUS                0x1410
-#define IDLE_STATUS_MASK               0x00FF
-#define IDLE_STATUS_RXMAC_NO_IDLE              0x1
-#define IDLE_STATUS_TXMAC_NO_IDLE              0x2
-#define IDLE_STATUS_RXQ_NO_IDLE                0x4
-#define IDLE_STATUS_TXQ_NO_IDLE                0x8
-#define IDLE_STATUS_DMAR_NO_IDLE               0x10
-#define IDLE_STATUS_DMAW_NO_IDLE               0x20
-#define IDLE_STATUS_SMB_NO_IDLE                0x40
-#define IDLE_STATUS_CMB_NO_IDLE                0x80
-
-/* MDIO Control Register */
-#define REG_MDIO_CTRL                  0x1414
-#define MDIO_DATA_MASK                 0xffff  /* On MDIO write, the 16-bit
-                                                * control data to write to PHY
-                                                * MII management register */
-#define MDIO_DATA_SHIFT                0       /* On MDIO read, the 16-bit
-                                                * status data that was read
-                                                * from the PHY MII management register */
-#define MDIO_REG_ADDR_MASK             0x1f    /* MDIO register address */
-#define MDIO_REG_ADDR_SHIFT            16
-#define MDIO_RW                        0x200000  /* 1: read, 0: write */
-#define MDIO_SUP_PREAMBLE              0x400000  /* Suppress preamble */
-#define MDIO_START                     0x800000  /* Write 1 to initiate the MDIO
-                                                  * master. And this bit is self
-                                                  * cleared after one cycle */
-#define MDIO_CLK_SEL_SHIFT             24
-#define MDIO_CLK_25_4                  0
-#define MDIO_CLK_25_6                  2
-#define MDIO_CLK_25_8                  3
-#define MDIO_CLK_25_10                 4
-#define MDIO_CLK_25_14                 5
-#define MDIO_CLK_25_20                 6
-#define MDIO_CLK_25_28                 7
-#define MDIO_BUSY                      0x8000000
-#define MDIO_AP_EN                     0x10000000
-#define MDIO_WAIT_TIMES                10
-
-/* MII PHY Status Register */
-#define REG_PHY_STATUS                 0x1418
-#define PHY_GENERAL_STATUS_MASK                0xFFFF
-#define PHY_STATUS_RECV_ENABLE         0x0001
-#define PHY_OE_PWSP_STATUS_MASK                0x07FF
-#define PHY_OE_PWSP_STATUS_SHIFT       16
-#define PHY_STATUS_LPW_STATE           0x80000000
-/* BIST Control and Status Register0 (for the Packet Memory) */
-#define REG_BIST0_CTRL                 0x141c
-#define BIST0_NOW                      0x1
-#define BIST0_SRAM_FAIL                0x2 /* 1: The SRAM failure is
-                                            * un-repairable  because
-                                            * it has address decoder
-                                            * failure or more than 1 cell
-                                            * stuck-to-x failure */
-#define BIST0_FUSE_FLAG                0x4
-
-/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
-#define REG_BIST1_CTRL                 0x1420
-#define BIST1_NOW                      0x1
-#define BIST1_SRAM_FAIL                0x2
-#define BIST1_FUSE_FLAG                0x4
-
-/* SerDes Lock Detect Control and Status Register */
-#define REG_SERDES_LOCK                0x1424
-#define SERDES_LOCK_DETECT             0x1  /* SerDes lock detected. This signal
-                                             * comes from Analog SerDes */
-#define SERDES_LOCK_DETECT_EN          0x2  /* 1: Enable SerDes Lock detect function */
-#define SERDES_LOCK_STS_SELFB_PLL_SHIFT 0xE
-#define SERDES_LOCK_STS_SELFB_PLL_MASK  0x3
-#define SERDES_OVCLK_18_25             0x0
-#define SERDES_OVCLK_12_18             0x1
-#define SERDES_OVCLK_0_4               0x2
-#define SERDES_OVCLK_4_12              0x3
-#define SERDES_MAC_CLK_SLOWDOWN                0x20000
-#define SERDES_PYH_CLK_SLOWDOWN                0x40000
-
-/* MAC Control Register  */
-#define REG_MAC_CTRL                   0x1480
-#define MAC_CTRL_TX_EN                 0x1
-#define MAC_CTRL_RX_EN                 0x2
-#define MAC_CTRL_TX_FLOW               0x4
-#define MAC_CTRL_RX_FLOW               0x8
-#define MAC_CTRL_LOOPBACK              0x10
-#define MAC_CTRL_DUPLX                 0x20
-#define MAC_CTRL_ADD_CRC               0x40
-#define MAC_CTRL_PAD                   0x80
-#define MAC_CTRL_LENCHK                0x100
-#define MAC_CTRL_HUGE_EN               0x200
-#define MAC_CTRL_PRMLEN_SHIFT          10
-#define MAC_CTRL_PRMLEN_MASK           0xf
-#define MAC_CTRL_RMV_VLAN              0x4000
-#define MAC_CTRL_PROMIS_EN             0x8000
-#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            0x3
-#define MAC_CTRL_DBG_TX_BKPRESURE      0x400000
-#define MAC_CTRL_TX_HUGE               0x800000
-#define MAC_CTRL_RX_CHKSUM_EN          0x1000000
-#define MAC_CTRL_MC_ALL_EN             0x2000000
-#define MAC_CTRL_BC_EN                 0x4000000
-#define MAC_CTRL_DBG                   0x8000000
-#define MAC_CTRL_SINGLE_PAUSE_EN       0x10000000
-#define MAC_CTRL_HASH_ALG_CRC32                0x20000000
-#define MAC_CTRL_SPEED_MODE_SW         0x40000000
-
-/* MAC IPG/IFG Control Register  */
-#define REG_MAC_IPG_IFG                0x1484
-#define MAC_IPG_IFG_IPGT_SHIFT         0       /* Desired back to back
-                                                * inter-packet gap. The
-                                                * default is 96-bit time */
-#define MAC_IPG_IFG_IPGT_MASK          0x7f
-#define MAC_IPG_IFG_MIFG_SHIFT         8       /* Minimum number of IFG to
-                                                * enforce in between RX frames */
-#define MAC_IPG_IFG_MIFG_MASK          0xff    /* Frame gap below such IFP is dropped */
-#define MAC_IPG_IFG_IPGR1_SHIFT        16      /* 64bit Carrier-Sense window */
-#define MAC_IPG_IFG_IPGR1_MASK         0x7f
-#define MAC_IPG_IFG_IPGR2_SHIFT        24      /* 96-bit IPG window */
-#define MAC_IPG_IFG_IPGR2_MASK         0x7f
-
-/* MAC STATION ADDRESS  */
-#define REG_MAC_STA_ADDR               0x1488
-
-/* Hash table for multicast address */
-#define REG_RX_HASH_TABLE              0x1490
-
-/* MAC Half-Duplex Control Register */
-#define REG_MAC_HALF_DUPLX_CTRL        0x1498
-#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT  0      /* Collision Window */
-#define MAC_HALF_DUPLX_CTRL_LCOL_MASK   0x3ff
-#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
-#define MAC_HALF_DUPLX_CTRL_RETRY_MASK  0xf
-#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN  0x10000
-#define MAC_HALF_DUPLX_CTRL_NO_BACK_C   0x20000
-#define MAC_HALF_DUPLX_CTRL_NO_BACK_P   0x40000 /* No back-off on backpressure,
-                                                * immediately start the
-                                                * transmission after back pressure */
-#define MAC_HALF_DUPLX_CTRL_ABEBE        0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
-#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT  20      /* Maximum binary exponential number */
-#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK   0xf
-#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24      /* IPG to start JAM for collision based flow control in half-duplex */
-#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK  0xf     /* mode. In unit of 8-bit time */
-
-/* Maximum Frame Length Control Register   */
-#define REG_MTU                        0x149c
-
-/* Wake-On-Lan control register */
-#define REG_WOL_CTRL                   0x14a0
-#define WOL_PATTERN_EN                 0x00000001
-#define WOL_PATTERN_PME_EN              0x00000002
-#define WOL_MAGIC_EN                    0x00000004
-#define WOL_MAGIC_PME_EN                0x00000008
-#define WOL_LINK_CHG_EN                 0x00000010
-#define WOL_LINK_CHG_PME_EN             0x00000020
-#define WOL_PATTERN_ST                  0x00000100
-#define WOL_MAGIC_ST                    0x00000200
-#define WOL_LINKCHG_ST                  0x00000400
-#define WOL_CLK_SWITCH_EN               0x00008000
-#define WOL_PT0_EN                      0x00010000
-#define WOL_PT1_EN                      0x00020000
-#define WOL_PT2_EN                      0x00040000
-#define WOL_PT3_EN                      0x00080000
-#define WOL_PT4_EN                      0x00100000
-#define WOL_PT5_EN                      0x00200000
-#define WOL_PT6_EN                      0x00400000
-
-/* 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 Register */
-#define RFDX_HEAD_ADDR_MASK            0x03FF
-#define RFDX_HARD_ADDR_SHIFT           0
-#define RFDX_TAIL_ADDR_MASK            0x03FF
-#define RFDX_TAIL_ADDR_SHIFT            16
-
-#define REG_SRAM_RFD0_INFO             0x1500
-#define REG_SRAM_RFD1_INFO             0x1504
-#define REG_SRAM_RFD2_INFO             0x1508
-#define        REG_SRAM_RFD3_INFO              0x150C
-
-#define REG_RFD_NIC_LEN                        0x1510 /* In 8-bytes */
-#define RFD_NIC_LEN_MASK               0x03FF
-
-#define REG_SRAM_TRD_ADDR              0x1518
-#define TPD_HEAD_ADDR_MASK             0x03FF
-#define TPD_HEAD_ADDR_SHIFT            0
-#define TPD_TAIL_ADDR_MASK             0x03FF
-#define TPD_TAIL_ADDR_SHIFT            16
-
-#define REG_SRAM_TRD_LEN               0x151C /* In 8-bytes */
-#define TPD_NIC_LEN_MASK               0x03FF
-
-#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_ADDR             0x1530
-#define REG_SRAM_PKTH_ADDR             0x1532
-
-/*
- * Load Ptr Register
- * Software sets this bit after the initialization of the head and tail */
-#define REG_LOAD_PTR                   0x1534
-
-/*
- * addresses of all descriptors, as well as the following descriptor
- * control register, which triggers each function block to load the head
- * pointer to prepare for the operation. This bit is then self-cleared
- * after one cycle.
- */
-#define REG_RX_BASE_ADDR_HI            0x1540
-#define REG_TX_BASE_ADDR_HI            0x1544
-#define REG_SMB_BASE_ADDR_HI           0x1548
-#define REG_SMB_BASE_ADDR_LO           0x154C
-#define REG_RFD0_HEAD_ADDR_LO          0x1550
-#define REG_RFD1_HEAD_ADDR_LO          0x1554
-#define REG_RFD2_HEAD_ADDR_LO          0x1558
-#define REG_RFD3_HEAD_ADDR_LO          0x155C
-#define REG_RFD_RING_SIZE              0x1560
-#define RFD_RING_SIZE_MASK             0x0FFF
-#define REG_RX_BUF_SIZE                        0x1564
-#define RX_BUF_SIZE_MASK               0xFFFF
-#define REG_RRD0_HEAD_ADDR_LO          0x1568
-#define REG_RRD1_HEAD_ADDR_LO          0x156C
-#define REG_RRD2_HEAD_ADDR_LO          0x1570
-#define REG_RRD3_HEAD_ADDR_LO          0x1574
-#define REG_RRD_RING_SIZE              0x1578
-#define RRD_RING_SIZE_MASK             0x0FFF
-#define REG_HTPD_HEAD_ADDR_LO          0x157C
-#define REG_NTPD_HEAD_ADDR_LO          0x1580
-#define REG_TPD_RING_SIZE              0x1584
-#define TPD_RING_SIZE_MASK             0xFFFF
-#define REG_CMB_BASE_ADDR_LO           0x1588
-
-/* RSS about */
-#define REG_RSS_KEY0                    0x14B0
-#define REG_RSS_KEY1                    0x14B4
-#define REG_RSS_KEY2                    0x14B8
-#define REG_RSS_KEY3                    0x14BC
-#define REG_RSS_KEY4                    0x14C0
-#define REG_RSS_KEY5                    0x14C4
-#define REG_RSS_KEY6                    0x14C8
-#define REG_RSS_KEY7                    0x14CC
-#define REG_RSS_KEY8                    0x14D0
-#define REG_RSS_KEY9                    0x14D4
-#define REG_IDT_TABLE0                 0x14E0
-#define REG_IDT_TABLE1                  0x14E4
-#define REG_IDT_TABLE2                  0x14E8
-#define REG_IDT_TABLE3                  0x14EC
-#define REG_IDT_TABLE4                  0x14F0
-#define REG_IDT_TABLE5                  0x14F4
-#define REG_IDT_TABLE6                  0x14F8
-#define REG_IDT_TABLE7                  0x14FC
-#define REG_IDT_TABLE                   REG_IDT_TABLE0
-#define REG_RSS_HASH_VALUE              0x15B0
-#define REG_RSS_HASH_FLAG               0x15B4
-#define REG_BASE_CPU_NUMBER             0x15B8
-
-/* TXQ Control Register */
-#define REG_TXQ_CTRL                   0x1590
-#define        TXQ_NUM_TPD_BURST_MASK          0xF
-#define TXQ_NUM_TPD_BURST_SHIFT        0
-#define TXQ_CTRL_IP_OPTION_EN          0x10
-#define TXQ_CTRL_EN                     0x20
-#define TXQ_CTRL_ENH_MODE               0x40
-#define TXQ_CTRL_LS_8023_EN            0x80
-#define TXQ_TXF_BURST_NUM_SHIFT        16
-#define TXQ_TXF_BURST_NUM_MASK         0xFFFF
-
-/* Jumbo packet Threshold for task offload */
-#define REG_TX_TSO_OFFLOAD_THRESH      0x1594 /* In 8-bytes */
-#define TX_TSO_OFFLOAD_THRESH_MASK     0x07FF
-
-#define        REG_TXF_WATER_MARK              0x1598 /* In 8-bytes */
-#define TXF_WATER_MARK_MASK            0x0FFF
-#define TXF_LOW_WATER_MARK_SHIFT       0
-#define TXF_HIGH_WATER_MARK_SHIFT      16
-#define TXQ_CTRL_BURST_MODE_EN         0x80000000
-
-#define REG_THRUPUT_MON_CTRL           0x159C
-#define THRUPUT_MON_RATE_MASK          0x3
-#define THRUPUT_MON_RATE_SHIFT         0
-#define THRUPUT_MON_EN                 0x80
-
-/* RXQ Control Register */
-#define REG_RXQ_CTRL                   0x15A0
-#define ASPM_THRUPUT_LIMIT_MASK                0x3
-#define ASPM_THRUPUT_LIMIT_SHIFT       0
-#define ASPM_THRUPUT_LIMIT_NO          0x00
-#define ASPM_THRUPUT_LIMIT_1M          0x01
-#define ASPM_THRUPUT_LIMIT_10M         0x02
-#define ASPM_THRUPUT_LIMIT_100M                0x04
-#define RXQ1_CTRL_EN                   0x10
-#define RXQ2_CTRL_EN                   0x20
-#define RXQ3_CTRL_EN                   0x40
-#define IPV6_CHKSUM_CTRL_EN            0x80
-#define RSS_HASH_BITS_MASK             0x00FF
-#define RSS_HASH_BITS_SHIFT            8
-#define RSS_HASH_IPV4                  0x10000
-#define RSS_HASH_IPV4_TCP              0x20000
-#define RSS_HASH_IPV6                  0x40000
-#define RSS_HASH_IPV6_TCP              0x80000
-#define RXQ_RFD_BURST_NUM_MASK         0x003F
-#define RXQ_RFD_BURST_NUM_SHIFT                20
-#define RSS_MODE_MASK                  0x0003
-#define RSS_MODE_SHIFT                 26
-#define RSS_NIP_QUEUE_SEL_MASK         0x1
-#define RSS_NIP_QUEUE_SEL_SHIFT                28
-#define RRS_HASH_CTRL_EN               0x20000000
-#define RX_CUT_THRU_EN                 0x40000000
-#define RXQ_CTRL_EN                    0x80000000
-
-#define REG_RFD_FREE_THRESH            0x15A4
-#define RFD_FREE_THRESH_MASK           0x003F
-#define RFD_FREE_HI_THRESH_SHIFT       0
-#define RFD_FREE_LO_THRESH_SHIFT       6
-
-/* RXF flow control register */
-#define REG_RXQ_RXF_PAUSE_THRESH       0x15A8
-#define RXQ_RXF_PAUSE_TH_HI_SHIFT       0
-#define RXQ_RXF_PAUSE_TH_HI_MASK        0x0FFF
-#define RXQ_RXF_PAUSE_TH_LO_SHIFT       16
-#define RXQ_RXF_PAUSE_TH_LO_MASK        0x0FFF
-
-#define REG_RXD_DMA_CTRL               0x15AC
-#define RXD_DMA_THRESH_MASK            0x0FFF  /* In 8-bytes */
-#define RXD_DMA_THRESH_SHIFT           0
-#define RXD_DMA_DOWN_TIMER_MASK                0xFFFF
-#define RXD_DMA_DOWN_TIMER_SHIFT       16
-
-/* 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_MASK    0x0007
-#define DMA_CTRL_DMAR_BURST_LEN_SHIFT   4
-#define DMA_CTRL_DMAW_BURST_LEN_MASK    0x0007
-#define DMA_CTRL_DMAW_BURST_LEN_SHIFT   7
-#define DMA_CTRL_DMAR_REQ_PRI           0x400
-#define DMA_CTRL_DMAR_DLY_CNT_MASK      0x001F
-#define DMA_CTRL_DMAR_DLY_CNT_SHIFT     11
-#define DMA_CTRL_DMAW_DLY_CNT_MASK      0x000F
-#define DMA_CTRL_DMAW_DLY_CNT_SHIFT     16
-#define DMA_CTRL_CMB_EN                0x100000
-#define DMA_CTRL_SMB_EN                        0x200000
-#define DMA_CTRL_CMB_NOW               0x400000
-#define MAC_CTRL_SMB_DIS               0x1000000
-#define DMA_CTRL_SMB_NOW               0x80000000
-
-/* CMB/SMB Control Register */
-#define REG_SMB_STAT_TIMER             0x15C4  /* 2us resolution */
-#define SMB_STAT_TIMER_MASK            0xFFFFFF
-#define REG_CMB_TPD_THRESH             0x15C8
-#define CMB_TPD_THRESH_MASK            0xFFFF
-#define REG_CMB_TX_TIMER               0x15CC  /* 2us resolution */
-#define CMB_TX_TIMER_MASK              0xFFFF
-
-/* Mail box */
-#define MB_RFDX_PROD_IDX_MASK          0xFFFF
-#define REG_MB_RFD0_PROD_IDX           0x15E0
-#define REG_MB_RFD1_PROD_IDX           0x15E4
-#define REG_MB_RFD2_PROD_IDX           0x15E8
-#define REG_MB_RFD3_PROD_IDX           0x15EC
-
-#define MB_PRIO_PROD_IDX_MASK          0xFFFF
-#define REG_MB_PRIO_PROD_IDX           0x15F0
-#define MB_HTPD_PROD_IDX_SHIFT         0
-#define MB_NTPD_PROD_IDX_SHIFT         16
-
-#define MB_PRIO_CONS_IDX_MASK          0xFFFF
-#define REG_MB_PRIO_CONS_IDX           0x15F4
-#define MB_HTPD_CONS_IDX_SHIFT         0
-#define MB_NTPD_CONS_IDX_SHIFT         16
-
-#define REG_MB_RFD01_CONS_IDX          0x15F8
-#define MB_RFD0_CONS_IDX_MASK          0x0000FFFF
-#define MB_RFD1_CONS_IDX_MASK          0xFFFF0000
-#define REG_MB_RFD23_CONS_IDX          0x15FC
-#define MB_RFD2_CONS_IDX_MASK          0x0000FFFF
-#define MB_RFD3_CONS_IDX_MASK          0xFFFF0000
-
-/* Interrupt Status Register */
-#define REG_ISR                        0x1600
-#define ISR_SMB                                0x00000001
-#define ISR_TIMER                      0x00000002
-/*
- * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
- * in Table 51 Selene Master Control Register (Offset 0x1400).
- */
-#define ISR_MANUAL                     0x00000004
-#define ISR_HW_RXF_OV                          0x00000008 /* RXF overflow interrupt */
-#define ISR_RFD0_UR                    0x00000010 /* RFD0 under run */
-#define ISR_RFD1_UR                    0x00000020
-#define ISR_RFD2_UR                    0x00000040
-#define ISR_RFD3_UR                    0x00000080
-#define ISR_TXF_UR                     0x00000100
-#define ISR_DMAR_TO_RST                        0x00000200
-#define ISR_DMAW_TO_RST                        0x00000400
-#define ISR_TX_CREDIT                  0x00000800
-#define ISR_GPHY                       0x00001000
-/* GPHY low power state interrupt */
-#define ISR_GPHY_LPW                           0x00002000
-#define ISR_TXQ_TO_RST                 0x00004000
-#define ISR_TX_PKT                     0x00008000
-#define ISR_RX_PKT_0                   0x00010000
-#define ISR_RX_PKT_1                   0x00020000
-#define ISR_RX_PKT_2                   0x00040000
-#define ISR_RX_PKT_3                   0x00080000
-#define ISR_MAC_RX                     0x00100000
-#define ISR_MAC_TX                     0x00200000
-#define ISR_UR_DETECTED                        0x00400000
-#define ISR_FERR_DETECTED              0x00800000
-#define ISR_NFERR_DETECTED             0x01000000
-#define ISR_CERR_DETECTED              0x02000000
-#define ISR_PHY_LINKDOWN               0x04000000
-#define ISR_DIS_INT                    0x80000000
-
-/* Interrupt Mask Register */
-#define REG_IMR                                0x1604
-
-#define IMR_NORMAL_MASK                (\
-               ISR_MANUAL      |\
-               ISR_HW_RXF_OV   |\
-               ISR_RFD0_UR     |\
-               ISR_TXF_UR      |\
-               ISR_DMAR_TO_RST |\
-               ISR_TXQ_TO_RST  |\
-               ISR_DMAW_TO_RST |\
-               ISR_GPHY        |\
-               ISR_TX_PKT      |\
-               ISR_RX_PKT_0    |\
-               ISR_GPHY_LPW    |\
-               ISR_PHY_LINKDOWN)
-
-#define ISR_RX_PKT     (\
-       ISR_RX_PKT_0    |\
-       ISR_RX_PKT_1    |\
-       ISR_RX_PKT_2    |\
-       ISR_RX_PKT_3)
-
-#define ISR_OVER       (\
-       ISR_RFD0_UR     |\
-       ISR_RFD1_UR     |\
-       ISR_RFD2_UR     |\
-       ISR_RFD3_UR     |\
-       ISR_HW_RXF_OV   |\
-       ISR_TXF_UR)
-
-#define ISR_ERROR      (\
-       ISR_DMAR_TO_RST |\
-       ISR_TXQ_TO_RST  |\
-       ISR_DMAW_TO_RST |\
-       ISR_PHY_LINKDOWN)
-
-#define REG_INT_RETRIG_TIMER           0x1608
-#define INT_RETRIG_TIMER_MASK          0xFFFF
-
-#define REG_HDS_CTRL                   0x160C
-#define HDS_CTRL_EN                    0x0001
-#define HDS_CTRL_BACKFILLSIZE_SHIFT    8
-#define HDS_CTRL_BACKFILLSIZE_MASK     0x0FFF
-#define HDS_CTRL_MAX_HDRSIZE_SHIFT     20
-#define HDS_CTRL_MAC_HDRSIZE_MASK      0x0FFF
-
-#define REG_MAC_RX_STATUS_BIN          0x1700
-#define REG_MAC_RX_STATUS_END          0x175c
-#define REG_MAC_TX_STATUS_BIN          0x1760
-#define REG_MAC_TX_STATUS_END          0x17c0
-
-#define REG_CLK_GATING_CTRL            0x1814
-#define CLK_GATING_DMAW_EN             0x0001
-#define CLK_GATING_DMAR_EN             0x0002
-#define CLK_GATING_TXQ_EN              0x0004
-#define CLK_GATING_RXQ_EN              0x0008
-#define CLK_GATING_TXMAC_EN            0x0010
-#define CLK_GATING_RXMAC_EN            0x0020
-
-#define CLK_GATING_EN_ALL      (CLK_GATING_DMAW_EN |\
-                                CLK_GATING_DMAR_EN |\
-                                CLK_GATING_TXQ_EN  |\
-                                CLK_GATING_RXQ_EN  |\
-                                CLK_GATING_TXMAC_EN|\
-                                CLK_GATING_RXMAC_EN)
-
-/* DEBUG ADDR */
-#define REG_DEBUG_DATA0                0x1900
-#define REG_DEBUG_DATA1                0x1904
-
-#define L1D_MPW_PHYID1                 0xD01C  /* V7 */
-#define L1D_MPW_PHYID2                 0xD01D  /* V1-V6 */
-#define L1D_MPW_PHYID3                 0xD01E  /* V8 */
-
-
-/* Autoneg Advertisement Register */
-#define ADVERTISE_DEFAULT_CAP \
-       (ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)
-
-/* 1000BASE-T Control Register */
-#define GIGA_CR_1000T_REPEATER_DTE     0x0400  /* 1=Repeater/switch device port 0=DTE device */
-
-#define GIGA_CR_1000T_MS_VALUE         0x0800  /* 1=Configure PHY as Master 0=Configure PHY as Slave */
-#define GIGA_CR_1000T_MS_ENABLE                0x1000  /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
-#define GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000  /* Normal Operation */
-#define GIGA_CR_1000T_TEST_MODE_1      0x2000  /* Transmit Waveform test */
-#define GIGA_CR_1000T_TEST_MODE_2      0x4000  /* Master Transmit Jitter test */
-#define GIGA_CR_1000T_TEST_MODE_3      0x6000  /* Slave Transmit Jitter test */
-#define GIGA_CR_1000T_TEST_MODE_4      0x8000  /* Transmitter Distortion test */
-#define GIGA_CR_1000T_SPEED_MASK       0x0300
-#define GIGA_CR_1000T_DEFAULT_CAP      0x0300
-
-/* PHY Specific Status Register */
-#define MII_GIGA_PSSR                  0x11
-#define GIGA_PSSR_SPD_DPLX_RESOLVED    0x0800  /* 1=Speed & Duplex resolved */
-#define GIGA_PSSR_DPLX                 0x2000  /* 1=Duplex 0=Half Duplex */
-#define GIGA_PSSR_SPEED                        0xC000  /* Speed, bits 14:15 */
-#define GIGA_PSSR_10MBS                        0x0000  /* 00=10Mbs */
-#define GIGA_PSSR_100MBS               0x4000  /* 01=100Mbs */
-#define GIGA_PSSR_1000MBS              0x8000  /* 10=1000Mbs */
-
-/* PHY Interrupt Enable Register */
-#define MII_IER                                0x12
-#define IER_LINK_UP                    0x0400
-#define IER_LINK_DOWN                  0x0800
-
-/* PHY Interrupt Status Register */
-#define MII_ISR                                0x13
-#define ISR_LINK_UP                    0x0400
-#define ISR_LINK_DOWN                  0x0800
-
-/* Cable-Detect-Test Control Register */
-#define MII_CDTC                       0x16
-#define CDTC_EN_OFF                    0   /* sc */
-#define CDTC_EN_BITS                   1
-#define CDTC_PAIR_OFF                  8
-#define CDTC_PAIR_BIT                  2
-
-/* Cable-Detect-Test Status Register */
-#define MII_CDTS                       0x1C
-#define CDTS_STATUS_OFF                        8
-#define CDTS_STATUS_BITS               2
-#define CDTS_STATUS_NORMAL             0
-#define CDTS_STATUS_SHORT              1
-#define CDTS_STATUS_OPEN               2
-#define CDTS_STATUS_INVALID            3
-
-#define MII_DBG_ADDR                   0x1D
-#define MII_DBG_DATA                   0x1E
-
-#define MII_ANA_CTRL_0                 0x0
-#define ANA_RESTART_CAL                        0x0001
-#define ANA_MANUL_SWICH_ON_SHIFT       0x1
-#define ANA_MANUL_SWICH_ON_MASK                0xF
-#define ANA_MAN_ENABLE                 0x0020
-#define ANA_SEL_HSP                    0x0040
-#define ANA_EN_HB                      0x0080
-#define ANA_EN_HBIAS                   0x0100
-#define ANA_OEN_125M                   0x0200
-#define ANA_EN_LCKDT                   0x0400
-#define ANA_LCKDT_PHY                  0x0800
-#define ANA_AFE_MODE                   0x1000
-#define ANA_VCO_SLOW                   0x2000
-#define ANA_VCO_FAST                   0x4000
-#define ANA_SEL_CLK125M_DSP            0x8000
-
-#define MII_ANA_CTRL_4                 0x4
-#define ANA_IECHO_ADJ_MASK             0xF
-#define ANA_IECHO_ADJ_3_SHIFT          0
-#define ANA_IECHO_ADJ_2_SHIFT          4
-#define ANA_IECHO_ADJ_1_SHIFT          8
-#define ANA_IECHO_ADJ_0_SHIFT          12
-
-#define MII_ANA_CTRL_5                 0x5
-#define ANA_SERDES_CDR_BW_SHIFT                0
-#define ANA_SERDES_CDR_BW_MASK         0x3
-#define ANA_MS_PAD_DBG                 0x0004
-#define ANA_SPEEDUP_DBG                        0x0008
-#define ANA_SERDES_TH_LOS_SHIFT                4
-#define ANA_SERDES_TH_LOS_MASK         0x3
-#define ANA_SERDES_EN_DEEM             0x0040
-#define ANA_SERDES_TXELECIDLE          0x0080
-#define ANA_SERDES_BEACON              0x0100
-#define ANA_SERDES_HALFTXDR            0x0200
-#define ANA_SERDES_SEL_HSP             0x0400
-#define ANA_SERDES_EN_PLL              0x0800
-#define ANA_SERDES_EN                  0x1000
-#define ANA_SERDES_EN_LCKDT            0x2000
-
-#define MII_ANA_CTRL_11                        0xB
-#define ANA_PS_HIB_EN                  0x8000
-
-#define MII_ANA_CTRL_18                        0x12
-#define ANA_TEST_MODE_10BT_01SHIFT     0
-#define ANA_TEST_MODE_10BT_01MASK      0x3
-#define ANA_LOOP_SEL_10BT              0x0004
-#define ANA_RGMII_MODE_SW              0x0008
-#define ANA_EN_LONGECABLE              0x0010
-#define ANA_TEST_MODE_10BT_2           0x0020
-#define ANA_EN_10BT_IDLE               0x0400
-#define ANA_EN_MASK_TB                 0x0800
-#define ANA_TRIGGER_SEL_TIMER_SHIFT    12
-#define ANA_TRIGGER_SEL_TIMER_MASK     0x3
-#define ANA_INTERVAL_SEL_TIMER_SHIFT   14
-#define ANA_INTERVAL_SEL_TIMER_MASK    0x3
-
-#define MII_ANA_CTRL_41                        0x29
-#define ANA_TOP_PS_EN                  0x8000
-
-#define MII_ANA_CTRL_54                        0x36
-#define ANA_LONG_CABLE_TH_100_SHIFT    0
-#define ANA_LONG_CABLE_TH_100_MASK     0x3F
-#define ANA_DESERVED                   0x0040
-#define ANA_EN_LIT_CH                  0x0080
-#define ANA_SHORT_CABLE_TH_100_SHIFT   8
-#define ANA_SHORT_CABLE_TH_100_MASK    0x3F
-#define ANA_BP_BAD_LINK_ACCUM          0x4000
-#define ANA_BP_SMALL_BW                        0x8000
-
-#endif /*_ATL1C_HW_H_*/
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
deleted file mode 100644 (file)
index 9722442..0000000
+++ /dev/null
@@ -1,2934 +0,0 @@
-/*
- * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#include "atl1c.h"
-
-#define ATL1C_DRV_VERSION "1.0.1.0-NAPI"
-char atl1c_driver_name[] = "atl1c";
-char atl1c_driver_version[] = ATL1C_DRV_VERSION;
-#define PCI_DEVICE_ID_ATTANSIC_L2C      0x1062
-#define PCI_DEVICE_ID_ATTANSIC_L1C      0x1063
-#define PCI_DEVICE_ID_ATHEROS_L2C_B    0x2060 /* AR8152 v1.1 Fast 10/100 */
-#define PCI_DEVICE_ID_ATHEROS_L2C_B2   0x2062 /* AR8152 v2.0 Fast 10/100 */
-#define PCI_DEVICE_ID_ATHEROS_L1D      0x1073 /* AR8151 v1.0 Gigabit 1000 */
-#define PCI_DEVICE_ID_ATHEROS_L1D_2_0  0x1083 /* AR8151 v2.0 Gigabit 1000 */
-#define L2CB_V10                       0xc0
-#define L2CB_V11                       0xc1
-
-/*
- * atl1c_pci_tbl - PCI Device ID Table
- *
- * Wildcard entries (PCI_ANY_ID) should come last
- * Last entry must be all 0s
- *
- * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
- *   Class, Class Mask, private data (not used) }
- */
-static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = {
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)},
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)},
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)},
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)},
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)},
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D_2_0)},
-       /* required last entry */
-       { 0 }
-};
-MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl);
-
-MODULE_AUTHOR("Jie Yang <jie.yang@atheros.com>");
-MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ATL1C_DRV_VERSION);
-
-static int atl1c_stop_mac(struct atl1c_hw *hw);
-static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw);
-static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw);
-static void atl1c_disable_l0s_l1(struct atl1c_hw *hw);
-static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup);
-static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter);
-static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
-                  int *work_done, int work_to_do);
-static int atl1c_up(struct atl1c_adapter *adapter);
-static void atl1c_down(struct atl1c_adapter *adapter);
-
-static const u16 atl1c_pay_load_size[] = {
-       128, 256, 512, 1024, 2048, 4096,
-};
-
-static const u16 atl1c_rfd_prod_idx_regs[AT_MAX_RECEIVE_QUEUE] =
-{
-       REG_MB_RFD0_PROD_IDX,
-       REG_MB_RFD1_PROD_IDX,
-       REG_MB_RFD2_PROD_IDX,
-       REG_MB_RFD3_PROD_IDX
-};
-
-static const u16 atl1c_rfd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
-{
-       REG_RFD0_HEAD_ADDR_LO,
-       REG_RFD1_HEAD_ADDR_LO,
-       REG_RFD2_HEAD_ADDR_LO,
-       REG_RFD3_HEAD_ADDR_LO
-};
-
-static const u16 atl1c_rrd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
-{
-       REG_RRD0_HEAD_ADDR_LO,
-       REG_RRD1_HEAD_ADDR_LO,
-       REG_RRD2_HEAD_ADDR_LO,
-       REG_RRD3_HEAD_ADDR_LO
-};
-
-static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
-       NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
-static void atl1c_pcie_patch(struct atl1c_hw *hw)
-{
-       u32 data;
-
-       AT_READ_REG(hw, REG_PCIE_PHYMISC, &data);
-       data |= PCIE_PHYMISC_FORCE_RCV_DET;
-       AT_WRITE_REG(hw, REG_PCIE_PHYMISC, data);
-
-       if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V10) {
-               AT_READ_REG(hw, REG_PCIE_PHYMISC2, &data);
-
-               data &= ~(PCIE_PHYMISC2_SERDES_CDR_MASK <<
-                       PCIE_PHYMISC2_SERDES_CDR_SHIFT);
-               data |= 3 << PCIE_PHYMISC2_SERDES_CDR_SHIFT;
-               data &= ~(PCIE_PHYMISC2_SERDES_TH_MASK <<
-                       PCIE_PHYMISC2_SERDES_TH_SHIFT);
-               data |= 3 << PCIE_PHYMISC2_SERDES_TH_SHIFT;
-               AT_WRITE_REG(hw, REG_PCIE_PHYMISC2, data);
-       }
-}
-
-/* FIXME: no need any more ? */
-/*
- * atl1c_init_pcie - init PCIE module
- */
-static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
-{
-       u32 data;
-       u32 pci_cmd;
-       struct pci_dev *pdev = hw->adapter->pdev;
-
-       AT_READ_REG(hw, PCI_COMMAND, &pci_cmd);
-       pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
-       pci_cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
-               PCI_COMMAND_IO);
-       AT_WRITE_REG(hw, PCI_COMMAND, pci_cmd);
-
-       /*
-        * Clear any PowerSaveing Settings
-        */
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
-       /*
-        * Mask some pcie error bits
-        */
-       AT_READ_REG(hw, REG_PCIE_UC_SEVERITY, &data);
-       data &= ~PCIE_UC_SERVRITY_DLP;
-       data &= ~PCIE_UC_SERVRITY_FCP;
-       AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data);
-
-       AT_READ_REG(hw, REG_LTSSM_ID_CTRL, &data);
-       data &= ~LTSSM_ID_EN_WRO;
-       AT_WRITE_REG(hw, REG_LTSSM_ID_CTRL, data);
-
-       atl1c_pcie_patch(hw);
-       if (flag & ATL1C_PCIE_L0S_L1_DISABLE)
-               atl1c_disable_l0s_l1(hw);
-       if (flag & ATL1C_PCIE_PHY_RESET)
-               AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
-       else
-               AT_WRITE_REG(hw, REG_GPHY_CTRL,
-                       GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET);
-
-       msleep(5);
-}
-
-/*
- * atl1c_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- */
-static inline void atl1c_irq_enable(struct atl1c_adapter *adapter)
-{
-       if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
-               AT_WRITE_REG(&adapter->hw, REG_ISR, 0x7FFFFFFF);
-               AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
-               AT_WRITE_FLUSH(&adapter->hw);
-       }
-}
-
-/*
- * atl1c_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- */
-static inline void atl1c_irq_disable(struct atl1c_adapter *adapter)
-{
-       atomic_inc(&adapter->irq_sem);
-       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
-       AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT);
-       AT_WRITE_FLUSH(&adapter->hw);
-       synchronize_irq(adapter->pdev->irq);
-}
-
-/*
- * atl1c_irq_reset - reset interrupt confiure on the NIC
- * @adapter: board private structure
- */
-static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
-{
-       atomic_set(&adapter->irq_sem, 1);
-       atl1c_irq_enable(adapter);
-}
-
-/*
- * atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
- * of the idle status register until the device is actually idle
- */
-static u32 atl1c_wait_until_idle(struct atl1c_hw *hw)
-{
-       int timeout;
-       u32 data;
-
-       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
-               AT_READ_REG(hw, REG_IDLE_STATUS, &data);
-               if ((data & IDLE_STATUS_MASK) == 0)
-                       return 0;
-               msleep(1);
-       }
-       return data;
-}
-
-/*
- * atl1c_phy_config - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl1c_phy_config(unsigned long data)
-{
-       struct atl1c_adapter *adapter = (struct atl1c_adapter *) data;
-       struct atl1c_hw *hw = &adapter->hw;
-       unsigned long flags;
-
-       spin_lock_irqsave(&adapter->mdio_lock, flags);
-       atl1c_restart_autoneg(hw);
-       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
-}
-
-void atl1c_reinit_locked(struct atl1c_adapter *adapter)
-{
-       WARN_ON(in_interrupt());
-       atl1c_down(adapter);
-       atl1c_up(adapter);
-       clear_bit(__AT_RESETTING, &adapter->flags);
-}
-
-static void atl1c_check_link_status(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       struct pci_dev    *pdev   = adapter->pdev;
-       int err;
-       unsigned long flags;
-       u16 speed, duplex, phy_data;
-
-       spin_lock_irqsave(&adapter->mdio_lock, flags);
-       /* MII_BMSR must read twise */
-       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
-       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
-       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
-
-       if ((phy_data & BMSR_LSTATUS) == 0) {
-               /* link down */
-               hw->hibernate = true;
-               if (atl1c_stop_mac(hw) != 0)
-                       if (netif_msg_hw(adapter))
-                               dev_warn(&pdev->dev, "stop mac failed\n");
-               atl1c_set_aspm(hw, false);
-               netif_carrier_off(netdev);
-               netif_stop_queue(netdev);
-               atl1c_phy_reset(hw);
-               atl1c_phy_init(&adapter->hw);
-       } else {
-               /* Link Up */
-               hw->hibernate = false;
-               spin_lock_irqsave(&adapter->mdio_lock, flags);
-               err = atl1c_get_speed_and_duplex(hw, &speed, &duplex);
-               spin_unlock_irqrestore(&adapter->mdio_lock, flags);
-               if (unlikely(err))
-                       return;
-               /* link result is our setting */
-               if (adapter->link_speed != speed ||
-                   adapter->link_duplex != duplex) {
-                       adapter->link_speed  = speed;
-                       adapter->link_duplex = duplex;
-                       atl1c_set_aspm(hw, true);
-                       atl1c_enable_tx_ctrl(hw);
-                       atl1c_enable_rx_ctrl(hw);
-                       atl1c_setup_mac_ctrl(adapter);
-                       if (netif_msg_link(adapter))
-                               dev_info(&pdev->dev,
-                                       "%s: %s NIC Link is Up<%d Mbps %s>\n",
-                                       atl1c_driver_name, netdev->name,
-                                       adapter->link_speed,
-                                       adapter->link_duplex == FULL_DUPLEX ?
-                                       "Full Duplex" : "Half Duplex");
-               }
-               if (!netif_carrier_ok(netdev))
-                       netif_carrier_on(netdev);
-       }
-}
-
-static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       struct pci_dev    *pdev   = adapter->pdev;
-       u16 phy_data;
-       u16 link_up;
-
-       spin_lock(&adapter->mdio_lock);
-       atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-       atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-       spin_unlock(&adapter->mdio_lock);
-       link_up = phy_data & BMSR_LSTATUS;
-       /* notify upper layer link down ASAP */
-       if (!link_up) {
-               if (netif_carrier_ok(netdev)) {
-                       /* old link state: Up */
-                       netif_carrier_off(netdev);
-                       if (netif_msg_link(adapter))
-                               dev_info(&pdev->dev,
-                                       "%s: %s NIC Link is Down\n",
-                                       atl1c_driver_name, netdev->name);
-                       adapter->link_speed = SPEED_0;
-               }
-       }
-
-       set_bit(ATL1C_WORK_EVENT_LINK_CHANGE, &adapter->work_event);
-       schedule_work(&adapter->common_task);
-}
-
-static void atl1c_common_task(struct work_struct *work)
-{
-       struct atl1c_adapter *adapter;
-       struct net_device *netdev;
-
-       adapter = container_of(work, struct atl1c_adapter, common_task);
-       netdev = adapter->netdev;
-
-       if (test_and_clear_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event)) {
-               netif_device_detach(netdev);
-               atl1c_down(adapter);
-               atl1c_up(adapter);
-               netif_device_attach(netdev);
-       }
-
-       if (test_and_clear_bit(ATL1C_WORK_EVENT_LINK_CHANGE,
-               &adapter->work_event))
-               atl1c_check_link_status(adapter);
-}
-
-
-static void atl1c_del_timer(struct atl1c_adapter *adapter)
-{
-       del_timer_sync(&adapter->phy_config_timer);
-}
-
-
-/*
- * atl1c_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- */
-static void atl1c_tx_timeout(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       /* Do the reset outside of interrupt context */
-       set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event);
-       schedule_work(&adapter->common_task);
-}
-
-/*
- * atl1c_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 atl1c_set_multi(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct atl1c_hw *hw = &adapter->hw;
-       struct netdev_hw_addr *ha;
-       u32 mac_ctrl_data;
-       u32 hash_value;
-
-       /* Check for Promiscuous and All Multicast modes */
-       AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
-
-       if (netdev->flags & IFF_PROMISC) {
-               mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
-       } else if (netdev->flags & IFF_ALLMULTI) {
-               mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
-               mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
-       } else {
-               mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
-       }
-
-       AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-
-       /* clear the old settings from the multicast hash table */
-       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
-       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
-
-       /* comoute mc addresses' hash value ,and put it into hash table */
-       netdev_for_each_mc_addr(ha, netdev) {
-               hash_value = atl1c_hash_mc_addr(hw, ha->addr);
-               atl1c_hash_set(hw, hash_value);
-       }
-}
-
-static void __atl1c_vlan_mode(u32 features, u32 *mac_ctrl_data)
-{
-       if (features & NETIF_F_HW_VLAN_RX) {
-               /* enable VLAN tag insert/strip */
-               *mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
-       } else {
-               /* disable VLAN tag insert/strip */
-               *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
-       }
-}
-
-static void atl1c_vlan_mode(struct net_device *netdev, u32 features)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct pci_dev *pdev = adapter->pdev;
-       u32 mac_ctrl_data = 0;
-
-       if (netif_msg_pktdata(adapter))
-               dev_dbg(&pdev->dev, "atl1c_vlan_mode\n");
-
-       atl1c_irq_disable(adapter);
-       AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data);
-       __atl1c_vlan_mode(features, &mac_ctrl_data);
-       AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
-       atl1c_irq_enable(adapter);
-}
-
-static void atl1c_restore_vlan(struct atl1c_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-
-       if (netif_msg_pktdata(adapter))
-               dev_dbg(&pdev->dev, "atl1c_restore_vlan\n");
-       atl1c_vlan_mode(adapter->netdev, adapter->netdev->features);
-}
-
-/*
- * atl1c_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 atl1c_set_mac_addr(struct net_device *netdev, void *p)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct sockaddr *addr = p;
-
-       if (!is_valid_ether_addr(addr->sa_data))
-               return -EADDRNOTAVAIL;
-
-       if (netif_running(netdev))
-               return -EBUSY;
-
-       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
-
-       atl1c_hw_set_mac_addr(&adapter->hw);
-
-       return 0;
-}
-
-static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
-                               struct net_device *dev)
-{
-       int mtu = dev->mtu;
-
-       adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
-               roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
-}
-
-static u32 atl1c_fix_features(struct net_device *netdev, u32 features)
-{
-       /*
-        * Since there is no support for separate rx/tx vlan accel
-        * enable/disable make sure tx flag is always in same state as rx.
-        */
-       if (features & NETIF_F_HW_VLAN_RX)
-               features |= NETIF_F_HW_VLAN_TX;
-       else
-               features &= ~NETIF_F_HW_VLAN_TX;
-
-       if (netdev->mtu > MAX_TSO_FRAME_SIZE)
-               features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
-       return features;
-}
-
-static int atl1c_set_features(struct net_device *netdev, u32 features)
-{
-       u32 changed = netdev->features ^ features;
-
-       if (changed & NETIF_F_HW_VLAN_RX)
-               atl1c_vlan_mode(netdev, features);
-
-       return 0;
-}
-
-/*
- * atl1c_change_mtu - Change the Maximum Transfer Unit
- * @netdev: network interface device structure
- * @new_mtu: new value for maximum frame size
- *
- * Returns 0 on success, negative on failure
- */
-static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       int old_mtu   = netdev->mtu;
-       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-
-       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
-                       (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-               if (netif_msg_link(adapter))
-                       dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
-               return -EINVAL;
-       }
-       /* set MTU */
-       if (old_mtu != new_mtu && netif_running(netdev)) {
-               while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
-                       msleep(1);
-               netdev->mtu = new_mtu;
-               adapter->hw.max_frame_size = new_mtu;
-               atl1c_set_rxbufsize(adapter, netdev);
-               atl1c_down(adapter);
-               netdev_update_features(netdev);
-               atl1c_up(adapter);
-               clear_bit(__AT_RESETTING, &adapter->flags);
-               if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
-                       u32 phy_data;
-
-                       AT_READ_REG(&adapter->hw, 0x1414, &phy_data);
-                       phy_data |= 0x10000000;
-                       AT_WRITE_REG(&adapter->hw, 0x1414, phy_data);
-               }
-
-       }
-       return 0;
-}
-
-/*
- *  caller should hold mdio_lock
- */
-static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       u16 result;
-
-       atl1c_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
-       return result;
-}
-
-static void atl1c_mdio_write(struct net_device *netdev, int phy_id,
-                            int reg_num, int val)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       atl1c_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
-}
-
-/*
- * atl1c_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1c_mii_ioctl(struct net_device *netdev,
-                          struct ifreq *ifr, int cmd)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct pci_dev *pdev = adapter->pdev;
-       struct mii_ioctl_data *data = if_mii(ifr);
-       unsigned long flags;
-       int retval = 0;
-
-       if (!netif_running(netdev))
-               return -EINVAL;
-
-       spin_lock_irqsave(&adapter->mdio_lock, flags);
-       switch (cmd) {
-       case SIOCGMIIPHY:
-               data->phy_id = 0;
-               break;
-
-       case SIOCGMIIREG:
-               if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
-                                   &data->val_out)) {
-                       retval = -EIO;
-                       goto out;
-               }
-               break;
-
-       case SIOCSMIIREG:
-               if (data->reg_num & ~(0x1F)) {
-                       retval = -EFAULT;
-                       goto out;
-               }
-
-               dev_dbg(&pdev->dev, "<atl1c_mii_ioctl> write %x %x",
-                               data->reg_num, data->val_in);
-               if (atl1c_write_phy_reg(&adapter->hw,
-                                    data->reg_num, data->val_in)) {
-                       retval = -EIO;
-                       goto out;
-               }
-               break;
-
-       default:
-               retval = -EOPNOTSUPP;
-               break;
-       }
-out:
-       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
-       return retval;
-}
-
-/*
- * atl1c_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1c_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-       switch (cmd) {
-       case SIOCGMIIPHY:
-       case SIOCGMIIREG:
-       case SIOCSMIIREG:
-               return atl1c_mii_ioctl(netdev, ifr, cmd);
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-/*
- * atl1c_alloc_queues - Allocate memory for all rings
- * @adapter: board private structure to initialize
- *
- */
-static int __devinit atl1c_alloc_queues(struct atl1c_adapter *adapter)
-{
-       return 0;
-}
-
-static void atl1c_set_mac_type(struct atl1c_hw *hw)
-{
-       switch (hw->device_id) {
-       case PCI_DEVICE_ID_ATTANSIC_L2C:
-               hw->nic_type = athr_l2c;
-               break;
-       case PCI_DEVICE_ID_ATTANSIC_L1C:
-               hw->nic_type = athr_l1c;
-               break;
-       case PCI_DEVICE_ID_ATHEROS_L2C_B:
-               hw->nic_type = athr_l2c_b;
-               break;
-       case PCI_DEVICE_ID_ATHEROS_L2C_B2:
-               hw->nic_type = athr_l2c_b2;
-               break;
-       case PCI_DEVICE_ID_ATHEROS_L1D:
-               hw->nic_type = athr_l1d;
-               break;
-       case PCI_DEVICE_ID_ATHEROS_L1D_2_0:
-               hw->nic_type = athr_l1d_2;
-               break;
-       default:
-               break;
-       }
-}
-
-static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
-{
-       u32 phy_status_data;
-       u32 link_ctrl_data;
-
-       atl1c_set_mac_type(hw);
-       AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data);
-       AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
-
-       hw->ctrl_flags = ATL1C_INTR_MODRT_ENABLE  |
-                        ATL1C_TXQ_MODE_ENHANCE;
-       if (link_ctrl_data & LINK_CTRL_L0S_EN)
-               hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT;
-       if (link_ctrl_data & LINK_CTRL_L1_EN)
-               hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT;
-       if (link_ctrl_data & LINK_CTRL_EXT_SYNC)
-               hw->ctrl_flags |= ATL1C_LINK_EXT_SYNC;
-       hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON;
-
-       if (hw->nic_type == athr_l1c ||
-           hw->nic_type == athr_l1d ||
-           hw->nic_type == athr_l1d_2)
-               hw->link_cap_flags |= ATL1C_LINK_CAP_1000M;
-       return 0;
-}
-/*
- * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter)
- * @adapter: board private structure to initialize
- *
- * atl1c_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 __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw   = &adapter->hw;
-       struct pci_dev  *pdev = adapter->pdev;
-       u32 revision;
-
-
-       adapter->wol = 0;
-       device_set_wakeup_enable(&pdev->dev, false);
-       adapter->link_speed = SPEED_0;
-       adapter->link_duplex = FULL_DUPLEX;
-       adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE;
-       adapter->tpd_ring[0].count = 1024;
-       adapter->rfd_ring[0].count = 512;
-
-       hw->vendor_id = pdev->vendor;
-       hw->device_id = pdev->device;
-       hw->subsystem_vendor_id = pdev->subsystem_vendor;
-       hw->subsystem_id = pdev->subsystem_device;
-       AT_READ_REG(hw, PCI_CLASS_REVISION, &revision);
-       hw->revision_id = revision & 0xFF;
-       /* before link up, we assume hibernate is true */
-       hw->hibernate = true;
-       hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
-       if (atl1c_setup_mac_funcs(hw) != 0) {
-               dev_err(&pdev->dev, "set mac function pointers failed\n");
-               return -1;
-       }
-       hw->intr_mask = IMR_NORMAL_MASK;
-       hw->phy_configured = false;
-       hw->preamble_len = 7;
-       hw->max_frame_size = adapter->netdev->mtu;
-       if (adapter->num_rx_queues < 2) {
-               hw->rss_type = atl1c_rss_disable;
-               hw->rss_mode = atl1c_rss_mode_disable;
-       } else {
-               hw->rss_type = atl1c_rss_ipv4;
-               hw->rss_mode = atl1c_rss_mul_que_mul_int;
-               hw->rss_hash_bits = 16;
-       }
-       hw->autoneg_advertised = ADVERTISED_Autoneg;
-       hw->indirect_tab = 0xE4E4E4E4;
-       hw->base_cpu = 0;
-
-       hw->ict = 50000;                /* 100ms */
-       hw->smb_timer = 200000;         /* 400ms */
-       hw->cmb_tpd = 4;
-       hw->cmb_tx_timer = 1;           /* 2 us  */
-       hw->rx_imt = 200;
-       hw->tx_imt = 1000;
-
-       hw->tpd_burst = 5;
-       hw->rfd_burst = 8;
-       hw->dma_order = atl1c_dma_ord_out;
-       hw->dmar_block = atl1c_dma_req_1024;
-       hw->dmaw_block = atl1c_dma_req_1024;
-       hw->dmar_dly_cnt = 15;
-       hw->dmaw_dly_cnt = 4;
-
-       if (atl1c_alloc_queues(adapter)) {
-               dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
-               return -ENOMEM;
-       }
-       /* TODO */
-       atl1c_set_rxbufsize(adapter, adapter->netdev);
-       atomic_set(&adapter->irq_sem, 1);
-       spin_lock_init(&adapter->mdio_lock);
-       spin_lock_init(&adapter->tx_lock);
-       set_bit(__AT_DOWN, &adapter->flags);
-
-       return 0;
-}
-
-static inline void atl1c_clean_buffer(struct pci_dev *pdev,
-                               struct atl1c_buffer *buffer_info, int in_irq)
-{
-       u16 pci_driection;
-       if (buffer_info->flags & ATL1C_BUFFER_FREE)
-               return;
-       if (buffer_info->dma) {
-               if (buffer_info->flags & ATL1C_PCIMAP_FROMDEVICE)
-                       pci_driection = PCI_DMA_FROMDEVICE;
-               else
-                       pci_driection = PCI_DMA_TODEVICE;
-
-               if (buffer_info->flags & ATL1C_PCIMAP_SINGLE)
-                       pci_unmap_single(pdev, buffer_info->dma,
-                                       buffer_info->length, pci_driection);
-               else if (buffer_info->flags & ATL1C_PCIMAP_PAGE)
-                       pci_unmap_page(pdev, buffer_info->dma,
-                                       buffer_info->length, pci_driection);
-       }
-       if (buffer_info->skb) {
-               if (in_irq)
-                       dev_kfree_skb_irq(buffer_info->skb);
-               else
-                       dev_kfree_skb(buffer_info->skb);
-       }
-       buffer_info->dma = 0;
-       buffer_info->skb = NULL;
-       ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
-}
-/*
- * atl1c_clean_tx_ring - Free Tx-skb
- * @adapter: board private structure
- */
-static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
-                               enum atl1c_trans_queue type)
-{
-       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
-       struct atl1c_buffer *buffer_info;
-       struct pci_dev *pdev = adapter->pdev;
-       u16 index, ring_count;
-
-       ring_count = tpd_ring->count;
-       for (index = 0; index < ring_count; index++) {
-               buffer_info = &tpd_ring->buffer_info[index];
-               atl1c_clean_buffer(pdev, buffer_info, 0);
-       }
-
-       /* Zero out Tx-buffers */
-       memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
-               ring_count);
-       atomic_set(&tpd_ring->next_to_clean, 0);
-       tpd_ring->next_to_use = 0;
-}
-
-/*
- * atl1c_clean_rx_ring - Free rx-reservation skbs
- * @adapter: board private structure
- */
-static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
-{
-       struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
-       struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
-       struct atl1c_buffer *buffer_info;
-       struct pci_dev *pdev = adapter->pdev;
-       int i, j;
-
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               for (j = 0; j < rfd_ring[i].count; j++) {
-                       buffer_info = &rfd_ring[i].buffer_info[j];
-                       atl1c_clean_buffer(pdev, buffer_info, 0);
-               }
-               /* zero out the descriptor ring */
-               memset(rfd_ring[i].desc, 0, rfd_ring[i].size);
-               rfd_ring[i].next_to_clean = 0;
-               rfd_ring[i].next_to_use = 0;
-               rrd_ring[i].next_to_use = 0;
-               rrd_ring[i].next_to_clean = 0;
-       }
-}
-
-/*
- * Read / Write Ptr Initialize:
- */
-static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
-{
-       struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
-       struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
-       struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
-       struct atl1c_buffer *buffer_info;
-       int i, j;
-
-       for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
-               tpd_ring[i].next_to_use = 0;
-               atomic_set(&tpd_ring[i].next_to_clean, 0);
-               buffer_info = tpd_ring[i].buffer_info;
-               for (j = 0; j < tpd_ring->count; j++)
-                       ATL1C_SET_BUFFER_STATE(&buffer_info[i],
-                                       ATL1C_BUFFER_FREE);
-       }
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               rfd_ring[i].next_to_use = 0;
-               rfd_ring[i].next_to_clean = 0;
-               rrd_ring[i].next_to_use = 0;
-               rrd_ring[i].next_to_clean = 0;
-               for (j = 0; j < rfd_ring[i].count; j++) {
-                       buffer_info = &rfd_ring[i].buffer_info[j];
-                       ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
-               }
-       }
-}
-
-/*
- * atl1c_free_ring_resources - Free Tx / RX descriptor Resources
- * @adapter: board private structure
- *
- * Free all transmit software resources
- */
-static void atl1c_free_ring_resources(struct atl1c_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-
-       pci_free_consistent(pdev, adapter->ring_header.size,
-                                       adapter->ring_header.desc,
-                                       adapter->ring_header.dma);
-       adapter->ring_header.desc = NULL;
-
-       /* Note: just free tdp_ring.buffer_info,
-       *  it contain rfd_ring.buffer_info, do not double free */
-       if (adapter->tpd_ring[0].buffer_info) {
-               kfree(adapter->tpd_ring[0].buffer_info);
-               adapter->tpd_ring[0].buffer_info = NULL;
-       }
-}
-
-/*
- * atl1c_setup_mem_resources - allocate Tx / RX descriptor resources
- * @adapter: board private structure
- *
- * Return 0 on success, negative on failure
- */
-static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
-       struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
-       struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
-       struct atl1c_ring_header *ring_header = &adapter->ring_header;
-       int num_rx_queues = adapter->num_rx_queues;
-       int size;
-       int i;
-       int count = 0;
-       int rx_desc_count = 0;
-       u32 offset = 0;
-
-       rrd_ring[0].count = rfd_ring[0].count;
-       for (i = 1; i < AT_MAX_TRANSMIT_QUEUE; i++)
-               tpd_ring[i].count = tpd_ring[0].count;
-
-       for (i = 1; i < adapter->num_rx_queues; i++)
-               rfd_ring[i].count = rrd_ring[i].count = rfd_ring[0].count;
-
-       /* 2 tpd queue, one high priority queue,
-        * another normal priority queue */
-       size = sizeof(struct atl1c_buffer) * (tpd_ring->count * 2 +
-               rfd_ring->count * num_rx_queues);
-       tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
-       if (unlikely(!tpd_ring->buffer_info)) {
-               dev_err(&pdev->dev, "kzalloc failed, size = %d\n",
-                       size);
-               goto err_nomem;
-       }
-       for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
-               tpd_ring[i].buffer_info =
-                       (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
-               count += tpd_ring[i].count;
-       }
-
-       for (i = 0; i < num_rx_queues; i++) {
-               rfd_ring[i].buffer_info =
-                       (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
-               count += rfd_ring[i].count;
-               rx_desc_count += rfd_ring[i].count;
-       }
-       /*
-        * real ring DMA buffer
-        * each ring/block may need up to 8 bytes for alignment, hence the
-        * additional bytes tacked onto the end.
-        */
-       ring_header->size = size =
-               sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 +
-               sizeof(struct atl1c_rx_free_desc) * rx_desc_count +
-               sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
-               sizeof(struct atl1c_hw_stats) +
-               8 * 4 + 8 * 2 * num_rx_queues;
-
-       ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
-                               &ring_header->dma);
-       if (unlikely(!ring_header->desc)) {
-               dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
-               goto err_nomem;
-       }
-       memset(ring_header->desc, 0, ring_header->size);
-       /* init TPD ring */
-
-       tpd_ring[0].dma = roundup(ring_header->dma, 8);
-       offset = tpd_ring[0].dma - ring_header->dma;
-       for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
-               tpd_ring[i].dma = ring_header->dma + offset;
-               tpd_ring[i].desc = (u8 *) ring_header->desc + offset;
-               tpd_ring[i].size =
-                       sizeof(struct atl1c_tpd_desc) * tpd_ring[i].count;
-               offset += roundup(tpd_ring[i].size, 8);
-       }
-       /* init RFD ring */
-       for (i = 0; i < num_rx_queues; i++) {
-               rfd_ring[i].dma = ring_header->dma + offset;
-               rfd_ring[i].desc = (u8 *) ring_header->desc + offset;
-               rfd_ring[i].size = sizeof(struct atl1c_rx_free_desc) *
-                               rfd_ring[i].count;
-               offset += roundup(rfd_ring[i].size, 8);
-       }
-
-       /* init RRD ring */
-       for (i = 0; i < num_rx_queues; i++) {
-               rrd_ring[i].dma = ring_header->dma + offset;
-               rrd_ring[i].desc = (u8 *) ring_header->desc + offset;
-               rrd_ring[i].size = sizeof(struct atl1c_recv_ret_status) *
-                               rrd_ring[i].count;
-               offset += roundup(rrd_ring[i].size, 8);
-       }
-
-       adapter->smb.dma = ring_header->dma + offset;
-       adapter->smb.smb = (u8 *)ring_header->desc + offset;
-       return 0;
-
-err_nomem:
-       kfree(tpd_ring->buffer_info);
-       return -ENOMEM;
-}
-
-static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-       struct atl1c_rfd_ring *rfd_ring = (struct atl1c_rfd_ring *)
-                               adapter->rfd_ring;
-       struct atl1c_rrd_ring *rrd_ring = (struct atl1c_rrd_ring *)
-                               adapter->rrd_ring;
-       struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
-                               adapter->tpd_ring;
-       struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb;
-       struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb;
-       int i;
-       u32 data;
-
-       /* TPD */
-       AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI,
-                       (u32)((tpd_ring[atl1c_trans_normal].dma &
-                               AT_DMA_HI_ADDR_MASK) >> 32));
-       /* just enable normal priority TX queue */
-       AT_WRITE_REG(hw, REG_NTPD_HEAD_ADDR_LO,
-                       (u32)(tpd_ring[atl1c_trans_normal].dma &
-                               AT_DMA_LO_ADDR_MASK));
-       AT_WRITE_REG(hw, REG_HTPD_HEAD_ADDR_LO,
-                       (u32)(tpd_ring[atl1c_trans_high].dma &
-                               AT_DMA_LO_ADDR_MASK));
-       AT_WRITE_REG(hw, REG_TPD_RING_SIZE,
-                       (u32)(tpd_ring[0].count & TPD_RING_SIZE_MASK));
-
-
-       /* RFD */
-       AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI,
-                       (u32)((rfd_ring[0].dma & AT_DMA_HI_ADDR_MASK) >> 32));
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               AT_WRITE_REG(hw, atl1c_rfd_addr_lo_regs[i],
-                       (u32)(rfd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
-
-       AT_WRITE_REG(hw, REG_RFD_RING_SIZE,
-                       rfd_ring[0].count & RFD_RING_SIZE_MASK);
-       AT_WRITE_REG(hw, REG_RX_BUF_SIZE,
-                       adapter->rx_buffer_len & RX_BUF_SIZE_MASK);
-
-       /* RRD */
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               AT_WRITE_REG(hw, atl1c_rrd_addr_lo_regs[i],
-                       (u32)(rrd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
-       AT_WRITE_REG(hw, REG_RRD_RING_SIZE,
-                       (rrd_ring[0].count & RRD_RING_SIZE_MASK));
-
-       /* CMB */
-       AT_WRITE_REG(hw, REG_CMB_BASE_ADDR_LO, cmb->dma & AT_DMA_LO_ADDR_MASK);
-
-       /* SMB */
-       AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_HI,
-                       (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32));
-       AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO,
-                       (u32)(smb->dma & AT_DMA_LO_ADDR_MASK));
-       if (hw->nic_type == athr_l2c_b) {
-               AT_WRITE_REG(hw, REG_SRAM_RXF_LEN, 0x02a0L);
-               AT_WRITE_REG(hw, REG_SRAM_TXF_LEN, 0x0100L);
-               AT_WRITE_REG(hw, REG_SRAM_RXF_ADDR, 0x029f0000L);
-               AT_WRITE_REG(hw, REG_SRAM_RFD0_INFO, 0x02bf02a0L);
-               AT_WRITE_REG(hw, REG_SRAM_TXF_ADDR, 0x03bf02c0L);
-               AT_WRITE_REG(hw, REG_SRAM_TRD_ADDR, 0x03df03c0L);
-               AT_WRITE_REG(hw, REG_TXF_WATER_MARK, 0);        /* TX watermark, to enter l1 state.*/
-               AT_WRITE_REG(hw, REG_RXD_DMA_CTRL, 0);          /* RXD threshold.*/
-       }
-       if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d_2) {
-                       /* Power Saving for L2c_B */
-               AT_READ_REG(hw, REG_SERDES_LOCK, &data);
-               data |= SERDES_MAC_CLK_SLOWDOWN;
-               data |= SERDES_PYH_CLK_SLOWDOWN;
-               AT_WRITE_REG(hw, REG_SERDES_LOCK, data);
-       }
-       /* Load all of base address above */
-       AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
-}
-
-static void atl1c_configure_tx(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-       u32 dev_ctrl_data;
-       u32 max_pay_load;
-       u16 tx_offload_thresh;
-       u32 txq_ctrl_data;
-       u32 max_pay_load_data;
-
-       tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
-       AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
-               (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
-       AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data);
-       max_pay_load  = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) &
-                       DEVICE_CTRL_MAX_PAYLOAD_MASK;
-       hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
-       max_pay_load  = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) &
-                       DEVICE_CTRL_MAX_RREQ_SZ_MASK;
-       hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
-
-       txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) <<
-                       TXQ_NUM_TPD_BURST_SHIFT;
-       if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE)
-               txq_ctrl_data |= TXQ_CTRL_ENH_MODE;
-       max_pay_load_data = (atl1c_pay_load_size[hw->dmar_block] &
-                       TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT;
-       if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2)
-               max_pay_load_data >>= 1;
-       txq_ctrl_data |= max_pay_load_data;
-
-       AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data);
-}
-
-static void atl1c_configure_rx(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-       u32 rxq_ctrl_data;
-
-       rxq_ctrl_data = (hw->rfd_burst & RXQ_RFD_BURST_NUM_MASK) <<
-                       RXQ_RFD_BURST_NUM_SHIFT;
-
-       if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM)
-               rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN;
-       if (hw->rss_type == atl1c_rss_ipv4)
-               rxq_ctrl_data |= RSS_HASH_IPV4;
-       if (hw->rss_type == atl1c_rss_ipv4_tcp)
-               rxq_ctrl_data |= RSS_HASH_IPV4_TCP;
-       if (hw->rss_type == atl1c_rss_ipv6)
-               rxq_ctrl_data |= RSS_HASH_IPV6;
-       if (hw->rss_type == atl1c_rss_ipv6_tcp)
-               rxq_ctrl_data |= RSS_HASH_IPV6_TCP;
-       if (hw->rss_type != atl1c_rss_disable)
-               rxq_ctrl_data |= RRS_HASH_CTRL_EN;
-
-       rxq_ctrl_data |= (hw->rss_mode & RSS_MODE_MASK) <<
-                       RSS_MODE_SHIFT;
-       rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) <<
-                       RSS_HASH_BITS_SHIFT;
-       if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON)
-               rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_1M &
-                       ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT;
-
-       AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
-}
-
-static void atl1c_configure_rss(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-
-       AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
-       AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
-}
-
-static void atl1c_configure_dma(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-       u32 dma_ctrl_data;
-
-       dma_ctrl_data = DMA_CTRL_DMAR_REQ_PRI;
-       if (hw->ctrl_flags & ATL1C_CMB_ENABLE)
-               dma_ctrl_data |= DMA_CTRL_CMB_EN;
-       if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
-               dma_ctrl_data |= DMA_CTRL_SMB_EN;
-       else
-               dma_ctrl_data |= MAC_CTRL_SMB_DIS;
-
-       switch (hw->dma_order) {
-       case atl1c_dma_ord_in:
-               dma_ctrl_data |= DMA_CTRL_DMAR_IN_ORDER;
-               break;
-       case atl1c_dma_ord_enh:
-               dma_ctrl_data |= DMA_CTRL_DMAR_ENH_ORDER;
-               break;
-       case atl1c_dma_ord_out:
-               dma_ctrl_data |= DMA_CTRL_DMAR_OUT_ORDER;
-               break;
-       default:
-               break;
-       }
-
-       dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
-               << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
-       dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
-               << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
-       dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
-               << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
-       dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
-               << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
-
-       AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
-}
-
-/*
- * Stop the mac, transmit and receive units
- * hw - Struct containing variables accessed by shared code
- * return : 0  or  idle status (if error)
- */
-static int atl1c_stop_mac(struct atl1c_hw *hw)
-{
-       u32 data;
-
-       AT_READ_REG(hw, REG_RXQ_CTRL, &data);
-       data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN |
-                 RXQ3_CTRL_EN | RXQ_CTRL_EN);
-       AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
-
-       AT_READ_REG(hw, REG_TXQ_CTRL, &data);
-       data &= ~TXQ_CTRL_EN;
-       AT_WRITE_REG(hw, REG_TWSI_CTRL, data);
-
-       atl1c_wait_until_idle(hw);
-
-       AT_READ_REG(hw, REG_MAC_CTRL, &data);
-       data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
-       AT_WRITE_REG(hw, REG_MAC_CTRL, data);
-
-       return (int)atl1c_wait_until_idle(hw);
-}
-
-static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
-{
-       u32 data;
-
-       AT_READ_REG(hw, REG_RXQ_CTRL, &data);
-       switch (hw->adapter->num_rx_queues) {
-       case 4:
-               data |= (RXQ3_CTRL_EN | RXQ2_CTRL_EN | RXQ1_CTRL_EN);
-               break;
-       case 3:
-               data |= (RXQ2_CTRL_EN | RXQ1_CTRL_EN);
-               break;
-       case 2:
-               data |= RXQ1_CTRL_EN;
-               break;
-       default:
-               break;
-       }
-       data |= RXQ_CTRL_EN;
-       AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
-}
-
-static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw)
-{
-       u32 data;
-
-       AT_READ_REG(hw, REG_TXQ_CTRL, &data);
-       data |= TXQ_CTRL_EN;
-       AT_WRITE_REG(hw, REG_TXQ_CTRL, data);
-}
-
-/*
- * 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)
- */
-static int atl1c_reset_mac(struct atl1c_hw *hw)
-{
-       struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
-       struct pci_dev *pdev = adapter->pdev;
-       u32 master_ctrl_data = 0;
-
-       AT_WRITE_REG(hw, REG_IMR, 0);
-       AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT);
-
-       atl1c_stop_mac(hw);
-       /*
-        * 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.
-        */
-       AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
-       master_ctrl_data |= MASTER_CTRL_OOB_DIS_OFF;
-       AT_WRITE_REGW(hw, REG_MASTER_CTRL, ((master_ctrl_data | MASTER_CTRL_SOFT_RST)
-                       & 0xFFFF));
-
-       AT_WRITE_FLUSH(hw);
-       msleep(10);
-       /* Wait at least 10ms for All module to be Idle */
-
-       if (atl1c_wait_until_idle(hw)) {
-               dev_err(&pdev->dev,
-                       "MAC state machine can't be idle since"
-                       " disabled for 10ms second\n");
-               return -1;
-       }
-       return 0;
-}
-
-static void atl1c_disable_l0s_l1(struct atl1c_hw *hw)
-{
-       u32 pm_ctrl_data;
-
-       AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
-       pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
-                       PM_CTRL_L1_ENTRY_TIMER_SHIFT);
-       pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
-       pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-       pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
-       pm_ctrl_data &= ~PM_CTRL_MAC_ASPM_CHK;
-       pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
-
-       pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
-       pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
-       pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
-       AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
-}
-
-/*
- * Set ASPM state.
- * Enable/disable L0s/L1 depend on link state.
- */
-static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
-{
-       u32 pm_ctrl_data;
-       u32 link_ctrl_data;
-       u32 link_l1_timer = 0xF;
-
-       AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
-       AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
-
-       pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
-       pm_ctrl_data &=  ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
-                       PM_CTRL_L1_ENTRY_TIMER_SHIFT);
-       pm_ctrl_data &= ~(PM_CTRL_LCKDET_TIMER_MASK <<
-                       PM_CTRL_LCKDET_TIMER_SHIFT);
-       pm_ctrl_data |= AT_LCKDET_TIMER << PM_CTRL_LCKDET_TIMER_SHIFT;
-
-       if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d ||
-               hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) {
-               link_ctrl_data &= ~LINK_CTRL_EXT_SYNC;
-               if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) {
-                       if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V10)
-                               link_ctrl_data |= LINK_CTRL_EXT_SYNC;
-               }
-
-               AT_WRITE_REG(hw, REG_LINK_CTRL, link_ctrl_data);
-
-               pm_ctrl_data |= PM_CTRL_RCVR_WT_TIMER;
-               pm_ctrl_data &= ~(PM_CTRL_PM_REQ_TIMER_MASK <<
-                       PM_CTRL_PM_REQ_TIMER_SHIFT);
-               pm_ctrl_data |= AT_ASPM_L1_TIMER <<
-                       PM_CTRL_PM_REQ_TIMER_SHIFT;
-               pm_ctrl_data &= ~PM_CTRL_SA_DLY_EN;
-               pm_ctrl_data &= ~PM_CTRL_HOTRST;
-               pm_ctrl_data |= 1 << PM_CTRL_L1_ENTRY_TIMER_SHIFT;
-               pm_ctrl_data |= PM_CTRL_SERDES_PD_EX_L1;
-       }
-       pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK;
-       if (linkup) {
-               pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
-               pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-               if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT)
-                       pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
-               if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
-                       pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
-
-               if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d ||
-                       hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) {
-                       if (hw->nic_type == athr_l2c_b)
-                               if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE))
-                                       pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-                       pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
-                       pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
-                       pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
-                       pm_ctrl_data |= PM_CTRL_CLK_SWH_L1;
-               if (hw->adapter->link_speed == SPEED_100 ||
-                               hw->adapter->link_speed == SPEED_1000) {
-                               pm_ctrl_data &=  ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
-                                       PM_CTRL_L1_ENTRY_TIMER_SHIFT);
-                               if (hw->nic_type == athr_l2c_b)
-                                       link_l1_timer = 7;
-                               else if (hw->nic_type == athr_l2c_b2 ||
-                                       hw->nic_type == athr_l1d_2)
-                                       link_l1_timer = 4;
-                               pm_ctrl_data |= link_l1_timer <<
-                                       PM_CTRL_L1_ENTRY_TIMER_SHIFT;
-                       }
-               } else {
-                       pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
-                       pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
-                       pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
-                       pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
-                       pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-                       pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
-
-               }
-       } else {
-               pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
-               pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-               pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
-               pm_ctrl_data |= PM_CTRL_CLK_SWH_L1;
-
-               if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT)
-                       pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
-               else
-                       pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
-       }
-       AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
-
-       return;
-}
-
-static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       u32 mac_ctrl_data;
-
-       mac_ctrl_data = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN;
-       mac_ctrl_data |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
-
-       if (adapter->link_duplex == FULL_DUPLEX) {
-               hw->mac_duplex = true;
-               mac_ctrl_data |= MAC_CTRL_DUPLX;
-       }
-
-       if (adapter->link_speed == SPEED_1000)
-               hw->mac_speed = atl1c_mac_speed_1000;
-       else
-               hw->mac_speed = atl1c_mac_speed_10_100;
-
-       mac_ctrl_data |= (hw->mac_speed & MAC_CTRL_SPEED_MASK) <<
-                       MAC_CTRL_SPEED_SHIFT;
-
-       mac_ctrl_data |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
-       mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) <<
-                       MAC_CTRL_PRMLEN_SHIFT);
-
-       __atl1c_vlan_mode(netdev->features, &mac_ctrl_data);
-
-       mac_ctrl_data |= MAC_CTRL_BC_EN;
-       if (netdev->flags & IFF_PROMISC)
-               mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
-       if (netdev->flags & IFF_ALLMULTI)
-               mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
-
-       mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN;
-       if (hw->nic_type == athr_l1d || hw->nic_type == athr_l2c_b2 ||
-           hw->nic_type == athr_l1d_2) {
-               mac_ctrl_data |= MAC_CTRL_SPEED_MODE_SW;
-               mac_ctrl_data |= MAC_CTRL_HASH_ALG_CRC32;
-       }
-       AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-}
-
-/*
- * atl1c_configure - Configure Transmit&Receive Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx /Rx unit of the MAC after a reset.
- */
-static int atl1c_configure(struct atl1c_adapter *adapter)
-{
-       struct atl1c_hw *hw = &adapter->hw;
-       u32 master_ctrl_data = 0;
-       u32 intr_modrt_data;
-       u32 data;
-
-       /* clear interrupt status */
-       AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF);
-       /*  Clear any WOL status */
-       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
-       /* set Interrupt Clear Timer
-        * HW will enable self to assert interrupt event to system after
-        * waiting x-time for software to notify it accept interrupt.
-        */
-
-       data = CLK_GATING_EN_ALL;
-       if (hw->ctrl_flags & ATL1C_CLK_GATING_EN) {
-               if (hw->nic_type == athr_l2c_b)
-                       data &= ~CLK_GATING_RXMAC_EN;
-       } else
-               data = 0;
-       AT_WRITE_REG(hw, REG_CLK_GATING_CTRL, data);
-
-       AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER,
-               hw->ict & INT_RETRIG_TIMER_MASK);
-
-       atl1c_configure_des_ring(adapter);
-
-       if (hw->ctrl_flags & ATL1C_INTR_MODRT_ENABLE) {
-               intr_modrt_data = (hw->tx_imt & IRQ_MODRT_TIMER_MASK) <<
-                                       IRQ_MODRT_TX_TIMER_SHIFT;
-               intr_modrt_data |= (hw->rx_imt & IRQ_MODRT_TIMER_MASK) <<
-                                       IRQ_MODRT_RX_TIMER_SHIFT;
-               AT_WRITE_REG(hw, REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data);
-               master_ctrl_data |=
-                       MASTER_CTRL_TX_ITIMER_EN | MASTER_CTRL_RX_ITIMER_EN;
-       }
-
-       if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ)
-               master_ctrl_data |= MASTER_CTRL_INT_RDCLR;
-
-       master_ctrl_data |= MASTER_CTRL_SA_TIMER_EN;
-       AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
-
-       if (hw->ctrl_flags & ATL1C_CMB_ENABLE) {
-               AT_WRITE_REG(hw, REG_CMB_TPD_THRESH,
-                       hw->cmb_tpd & CMB_TPD_THRESH_MASK);
-               AT_WRITE_REG(hw, REG_CMB_TX_TIMER,
-                       hw->cmb_tx_timer & CMB_TX_TIMER_MASK);
-       }
-
-       if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
-               AT_WRITE_REG(hw, REG_SMB_STAT_TIMER,
-                       hw->smb_timer & SMB_STAT_TIMER_MASK);
-       /* set MTU */
-       AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
-                       VLAN_HLEN + ETH_FCS_LEN);
-       /* HDS, disable */
-       AT_WRITE_REG(hw, REG_HDS_CTRL, 0);
-
-       atl1c_configure_tx(adapter);
-       atl1c_configure_rx(adapter);
-       atl1c_configure_rss(adapter);
-       atl1c_configure_dma(adapter);
-
-       return 0;
-}
-
-static void atl1c_update_hw_stats(struct atl1c_adapter *adapter)
-{
-       u16 hw_reg_addr = 0;
-       unsigned long *stats_item = NULL;
-       u32 data;
-
-       /* update rx status */
-       hw_reg_addr = REG_MAC_RX_STATUS_BIN;
-       stats_item  = &adapter->hw_stats.rx_ok;
-       while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
-               AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
-               *stats_item += data;
-               stats_item++;
-               hw_reg_addr += 4;
-       }
-/* update tx status */
-       hw_reg_addr = REG_MAC_TX_STATUS_BIN;
-       stats_item  = &adapter->hw_stats.tx_ok;
-       while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
-               AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
-               *stats_item += data;
-               stats_item++;
-               hw_reg_addr += 4;
-       }
-}
-
-/*
- * atl1c_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 *atl1c_get_stats(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct atl1c_hw_stats  *hw_stats = &adapter->hw_stats;
-       struct net_device_stats *net_stats = &netdev->stats;
-
-       atl1c_update_hw_stats(adapter);
-       net_stats->rx_packets = hw_stats->rx_ok;
-       net_stats->tx_packets = hw_stats->tx_ok;
-       net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
-       net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
-       net_stats->multicast  = hw_stats->rx_mcast;
-       net_stats->collisions = hw_stats->tx_1_col +
-                               hw_stats->tx_2_col * 2 +
-                               hw_stats->tx_late_col + hw_stats->tx_abort_col;
-       net_stats->rx_errors  = hw_stats->rx_frag + hw_stats->rx_fcs_err +
-                               hw_stats->rx_len_err + hw_stats->rx_sz_ov +
-                               hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
-       net_stats->rx_fifo_errors   = hw_stats->rx_rxf_ov;
-       net_stats->rx_length_errors = hw_stats->rx_len_err;
-       net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
-       net_stats->rx_frame_errors  = hw_stats->rx_align_err;
-       net_stats->rx_over_errors   = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
-
-       net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
-
-       net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
-                               hw_stats->tx_underrun + hw_stats->tx_trunc;
-       net_stats->tx_fifo_errors    = hw_stats->tx_underrun;
-       net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
-       net_stats->tx_window_errors  = hw_stats->tx_late_col;
-
-       return net_stats;
-}
-
-static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter)
-{
-       u16 phy_data;
-
-       spin_lock(&adapter->mdio_lock);
-       atl1c_read_phy_reg(&adapter->hw, MII_ISR, &phy_data);
-       spin_unlock(&adapter->mdio_lock);
-}
-
-static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
-                               enum atl1c_trans_queue type)
-{
-       struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
-                               &adapter->tpd_ring[type];
-       struct atl1c_buffer *buffer_info;
-       struct pci_dev *pdev = adapter->pdev;
-       u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
-       u16 hw_next_to_clean;
-       u16 shift;
-       u32 data;
-
-       if (type == atl1c_trans_high)
-               shift = MB_HTPD_CONS_IDX_SHIFT;
-       else
-               shift = MB_NTPD_CONS_IDX_SHIFT;
-
-       AT_READ_REG(&adapter->hw, REG_MB_PRIO_CONS_IDX, &data);
-       hw_next_to_clean = (data >> shift) & MB_PRIO_PROD_IDX_MASK;
-
-       while (next_to_clean != hw_next_to_clean) {
-               buffer_info = &tpd_ring->buffer_info[next_to_clean];
-               atl1c_clean_buffer(pdev, buffer_info, 1);
-               if (++next_to_clean == tpd_ring->count)
-                       next_to_clean = 0;
-               atomic_set(&tpd_ring->next_to_clean, next_to_clean);
-       }
-
-       if (netif_queue_stopped(adapter->netdev) &&
-                       netif_carrier_ok(adapter->netdev)) {
-               netif_wake_queue(adapter->netdev);
-       }
-
-       return true;
-}
-
-/*
- * atl1c_intr - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
- */
-static irqreturn_t atl1c_intr(int irq, void *data)
-{
-       struct net_device *netdev  = data;
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct pci_dev *pdev = adapter->pdev;
-       struct atl1c_hw *hw = &adapter->hw;
-       int max_ints = AT_MAX_INT_WORK;
-       int handled = IRQ_NONE;
-       u32 status;
-       u32 reg_data;
-
-       do {
-               AT_READ_REG(hw, REG_ISR, &reg_data);
-               status = reg_data & hw->intr_mask;
-
-               if (status == 0 || (status & ISR_DIS_INT) != 0) {
-                       if (max_ints != AT_MAX_INT_WORK)
-                               handled = IRQ_HANDLED;
-                       break;
-               }
-               /* link event */
-               if (status & ISR_GPHY)
-                       atl1c_clear_phy_int(adapter);
-               /* Ack ISR */
-               AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
-               if (status & ISR_RX_PKT) {
-                       if (likely(napi_schedule_prep(&adapter->napi))) {
-                               hw->intr_mask &= ~ISR_RX_PKT;
-                               AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
-                               __napi_schedule(&adapter->napi);
-                       }
-               }
-               if (status & ISR_TX_PKT)
-                       atl1c_clean_tx_irq(adapter, atl1c_trans_normal);
-
-               handled = IRQ_HANDLED;
-               /* check if PCIE PHY Link down */
-               if (status & ISR_ERROR) {
-                       if (netif_msg_hw(adapter))
-                               dev_err(&pdev->dev,
-                                       "atl1c hardware error (status = 0x%x)\n",
-                                       status & ISR_ERROR);
-                       /* reset MAC */
-                       adapter->work_event |= ATL1C_WORK_EVENT_RESET;
-                       schedule_work(&adapter->common_task);
-                       return IRQ_HANDLED;
-               }
-
-               if (status & ISR_OVER)
-                       if (netif_msg_intr(adapter))
-                               dev_warn(&pdev->dev,
-                                       "TX/RX overflow (status = 0x%x)\n",
-                                       status & ISR_OVER);
-
-               /* link event */
-               if (status & (ISR_GPHY | ISR_MANUAL)) {
-                       netdev->stats.tx_carrier_errors++;
-                       atl1c_link_chg_event(adapter);
-                       break;
-               }
-
-       } while (--max_ints > 0);
-       /* re-enable Interrupt*/
-       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
-       return handled;
-}
-
-static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
-                 struct sk_buff *skb, struct atl1c_recv_ret_status *prrs)
-{
-       /*
-        * The pid field in RRS in not correct sometimes, so we
-        * cannot figure out if the packet is fragmented or not,
-        * so we tell the KERNEL CHECKSUM_NONE
-        */
-       skb_checksum_none_assert(skb);
-}
-
-static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid)
-{
-       struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[ringid];
-       struct pci_dev *pdev = adapter->pdev;
-       struct atl1c_buffer *buffer_info, *next_info;
-       struct sk_buff *skb;
-       void *vir_addr = NULL;
-       u16 num_alloc = 0;
-       u16 rfd_next_to_use, next_next;
-       struct atl1c_rx_free_desc *rfd_desc;
-
-       next_next = rfd_next_to_use = rfd_ring->next_to_use;
-       if (++next_next == rfd_ring->count)
-               next_next = 0;
-       buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
-       next_info = &rfd_ring->buffer_info[next_next];
-
-       while (next_info->flags & ATL1C_BUFFER_FREE) {
-               rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
-
-               skb = dev_alloc_skb(adapter->rx_buffer_len);
-               if (unlikely(!skb)) {
-                       if (netif_msg_rx_err(adapter))
-                               dev_warn(&pdev->dev, "alloc rx buffer failed\n");
-                       break;
-               }
-
-               /*
-                * Make buffer alignment 2 beyond a 16 byte boundary
-                * this will result in a 16 byte aligned IP header after
-                * the 14 byte MAC header is removed
-                */
-               vir_addr = skb->data;
-               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
-               buffer_info->skb = skb;
-               buffer_info->length = adapter->rx_buffer_len;
-               buffer_info->dma = pci_map_single(pdev, vir_addr,
-                                               buffer_info->length,
-                                               PCI_DMA_FROMDEVICE);
-               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
-                       ATL1C_PCIMAP_FROMDEVICE);
-               rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
-               rfd_next_to_use = next_next;
-               if (++next_next == rfd_ring->count)
-                       next_next = 0;
-               buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
-               next_info = &rfd_ring->buffer_info[next_next];
-               num_alloc++;
-       }
-
-       if (num_alloc) {
-               /* TODO: update mailbox here */
-               wmb();
-               rfd_ring->next_to_use = rfd_next_to_use;
-               AT_WRITE_REG(&adapter->hw, atl1c_rfd_prod_idx_regs[ringid],
-                       rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK);
-       }
-
-       return num_alloc;
-}
-
-static void atl1c_clean_rrd(struct atl1c_rrd_ring *rrd_ring,
-                       struct  atl1c_recv_ret_status *rrs, u16 num)
-{
-       u16 i;
-       /* the relationship between rrd and rfd is one map one */
-       for (i = 0; i < num; i++, rrs = ATL1C_RRD_DESC(rrd_ring,
-                                       rrd_ring->next_to_clean)) {
-               rrs->word3 &= ~RRS_RXD_UPDATED;
-               if (++rrd_ring->next_to_clean == rrd_ring->count)
-                       rrd_ring->next_to_clean = 0;
-       }
-}
-
-static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
-       struct atl1c_recv_ret_status *rrs, u16 num)
-{
-       u16 i;
-       u16 rfd_index;
-       struct atl1c_buffer *buffer_info = rfd_ring->buffer_info;
-
-       rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
-                       RRS_RX_RFD_INDEX_MASK;
-       for (i = 0; i < num; i++) {
-               buffer_info[rfd_index].skb = NULL;
-               ATL1C_SET_BUFFER_STATE(&buffer_info[rfd_index],
-                                       ATL1C_BUFFER_FREE);
-               if (++rfd_index == rfd_ring->count)
-                       rfd_index = 0;
-       }
-       rfd_ring->next_to_clean = rfd_index;
-}
-
-static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
-                  int *work_done, int work_to_do)
-{
-       u16 rfd_num, rfd_index;
-       u16 count = 0;
-       u16 length;
-       struct pci_dev *pdev = adapter->pdev;
-       struct net_device *netdev  = adapter->netdev;
-       struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[que];
-       struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[que];
-       struct sk_buff *skb;
-       struct atl1c_recv_ret_status *rrs;
-       struct atl1c_buffer *buffer_info;
-
-       while (1) {
-               if (*work_done >= work_to_do)
-                       break;
-               rrs = ATL1C_RRD_DESC(rrd_ring, rrd_ring->next_to_clean);
-               if (likely(RRS_RXD_IS_VALID(rrs->word3))) {
-                       rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) &
-                               RRS_RX_RFD_CNT_MASK;
-                       if (unlikely(rfd_num != 1))
-                               /* TODO support mul rfd*/
-                               if (netif_msg_rx_err(adapter))
-                                       dev_warn(&pdev->dev,
-                                               "Multi rfd not support yet!\n");
-                       goto rrs_checked;
-               } else {
-                       break;
-               }
-rrs_checked:
-               atl1c_clean_rrd(rrd_ring, rrs, rfd_num);
-               if (rrs->word3 & (RRS_RX_ERR_SUM | RRS_802_3_LEN_ERR)) {
-                       atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
-                               if (netif_msg_rx_err(adapter))
-                                       dev_warn(&pdev->dev,
-                                               "wrong packet! rrs word3 is %x\n",
-                                               rrs->word3);
-                       continue;
-               }
-
-               length = le16_to_cpu((rrs->word3 >> RRS_PKT_SIZE_SHIFT) &
-                               RRS_PKT_SIZE_MASK);
-               /* Good Receive */
-               if (likely(rfd_num == 1)) {
-                       rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
-                                       RRS_RX_RFD_INDEX_MASK;
-                       buffer_info = &rfd_ring->buffer_info[rfd_index];
-                       pci_unmap_single(pdev, buffer_info->dma,
-                               buffer_info->length, PCI_DMA_FROMDEVICE);
-                       skb = buffer_info->skb;
-               } else {
-                       /* TODO */
-                       if (netif_msg_rx_err(adapter))
-                               dev_warn(&pdev->dev,
-                                       "Multi rfd not support yet!\n");
-                       break;
-               }
-               atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
-               skb_put(skb, length - ETH_FCS_LEN);
-               skb->protocol = eth_type_trans(skb, netdev);
-               atl1c_rx_checksum(adapter, skb, rrs);
-               if (rrs->word3 & RRS_VLAN_INS) {
-                       u16 vlan;
-
-                       AT_TAG_TO_VLAN(rrs->vlan_tag, vlan);
-                       vlan = le16_to_cpu(vlan);
-                       __vlan_hwaccel_put_tag(skb, vlan);
-               }
-               netif_receive_skb(skb);
-
-               (*work_done)++;
-               count++;
-       }
-       if (count)
-               atl1c_alloc_rx_buffer(adapter, que);
-}
-
-/*
- * atl1c_clean - NAPI Rx polling callback
- * @adapter: board private structure
- */
-static int atl1c_clean(struct napi_struct *napi, int budget)
-{
-       struct atl1c_adapter *adapter =
-                       container_of(napi, struct atl1c_adapter, napi);
-       int work_done = 0;
-
-       /* Keep link state information with original netdev */
-       if (!netif_carrier_ok(adapter->netdev))
-               goto quit_polling;
-       /* just enable one RXQ */
-       atl1c_clean_rx_irq(adapter, 0, &work_done, budget);
-
-       if (work_done < budget) {
-quit_polling:
-               napi_complete(napi);
-               adapter->hw.intr_mask |= ISR_RX_PKT;
-               AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
-       }
-       return work_done;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void atl1c_netpoll(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       disable_irq(adapter->pdev->irq);
-       atl1c_intr(adapter->pdev->irq, netdev);
-       enable_irq(adapter->pdev->irq);
-}
-#endif
-
-static inline u16 atl1c_tpd_avail(struct atl1c_adapter *adapter, enum atl1c_trans_queue type)
-{
-       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
-       u16 next_to_use = 0;
-       u16 next_to_clean = 0;
-
-       next_to_clean = atomic_read(&tpd_ring->next_to_clean);
-       next_to_use   = tpd_ring->next_to_use;
-
-       return (u16)(next_to_clean > next_to_use) ?
-               (next_to_clean - next_to_use - 1) :
-               (tpd_ring->count + next_to_clean - next_to_use - 1);
-}
-
-/*
- * get next usable tpd
- * Note: should call atl1c_tdp_avail to make sure
- * there is enough tpd to use
- */
-static struct atl1c_tpd_desc *atl1c_get_tpd(struct atl1c_adapter *adapter,
-       enum atl1c_trans_queue type)
-{
-       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
-       struct atl1c_tpd_desc *tpd_desc;
-       u16 next_to_use = 0;
-
-       next_to_use = tpd_ring->next_to_use;
-       if (++tpd_ring->next_to_use == tpd_ring->count)
-               tpd_ring->next_to_use = 0;
-       tpd_desc = ATL1C_TPD_DESC(tpd_ring, next_to_use);
-       memset(tpd_desc, 0, sizeof(struct atl1c_tpd_desc));
-       return  tpd_desc;
-}
-
-static struct atl1c_buffer *
-atl1c_get_tx_buffer(struct atl1c_adapter *adapter, struct atl1c_tpd_desc *tpd)
-{
-       struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
-
-       return &tpd_ring->buffer_info[tpd -
-                       (struct atl1c_tpd_desc *)tpd_ring->desc];
-}
-
-/* Calculate the transmit packet descript needed*/
-static u16 atl1c_cal_tpd_req(const struct sk_buff *skb)
-{
-       u16 tpd_req;
-       u16 proto_hdr_len = 0;
-
-       tpd_req = skb_shinfo(skb)->nr_frags + 1;
-
-       if (skb_is_gso(skb)) {
-               proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-               if (proto_hdr_len < skb_headlen(skb))
-                       tpd_req++;
-               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-                       tpd_req++;
-       }
-       return tpd_req;
-}
-
-static int atl1c_tso_csum(struct atl1c_adapter *adapter,
-                         struct sk_buff *skb,
-                         struct atl1c_tpd_desc **tpd,
-                         enum atl1c_trans_queue type)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       u8 hdr_len;
-       u32 real_len;
-       unsigned short offload_type;
-       int err;
-
-       if (skb_is_gso(skb)) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (unlikely(err))
-                               return -1;
-               }
-               offload_type = skb_shinfo(skb)->gso_type;
-
-               if (offload_type & SKB_GSO_TCPV4) {
-                       real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
-                                       + ntohs(ip_hdr(skb)->tot_len));
-
-                       if (real_len < skb->len)
-                               pskb_trim(skb, real_len);
-
-                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
-                       if (unlikely(skb->len == hdr_len)) {
-                               /* only xsum need */
-                               if (netif_msg_tx_queued(adapter))
-                                       dev_warn(&pdev->dev,
-                                               "IPV4 tso with zero data??\n");
-                               goto check_sum;
-                       } else {
-                               ip_hdr(skb)->check = 0;
-                               tcp_hdr(skb)->check = ~csum_tcpudp_magic(
-                                                       ip_hdr(skb)->saddr,
-                                                       ip_hdr(skb)->daddr,
-                                                       0, IPPROTO_TCP, 0);
-                               (*tpd)->word1 |= 1 << TPD_IPV4_PACKET_SHIFT;
-                       }
-               }
-
-               if (offload_type & SKB_GSO_TCPV6) {
-                       struct atl1c_tpd_ext_desc *etpd =
-                               *(struct atl1c_tpd_ext_desc **)(tpd);
-
-                       memset(etpd, 0, sizeof(struct atl1c_tpd_ext_desc));
-                       *tpd = atl1c_get_tpd(adapter, type);
-                       ipv6_hdr(skb)->payload_len = 0;
-                       /* check payload == 0 byte ? */
-                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
-                       if (unlikely(skb->len == hdr_len)) {
-                               /* only xsum need */
-                               if (netif_msg_tx_queued(adapter))
-                                       dev_warn(&pdev->dev,
-                                               "IPV6 tso with zero data??\n");
-                               goto check_sum;
-                       } else
-                               tcp_hdr(skb)->check = ~csum_ipv6_magic(
-                                               &ipv6_hdr(skb)->saddr,
-                                               &ipv6_hdr(skb)->daddr,
-                                               0, IPPROTO_TCP, 0);
-                       etpd->word1 |= 1 << TPD_LSO_EN_SHIFT;
-                       etpd->word1 |= 1 << TPD_LSO_VER_SHIFT;
-                       etpd->pkt_len = cpu_to_le32(skb->len);
-                       (*tpd)->word1 |= 1 << TPD_LSO_VER_SHIFT;
-               }
-
-               (*tpd)->word1 |= 1 << TPD_LSO_EN_SHIFT;
-               (*tpd)->word1 |= (skb_transport_offset(skb) & TPD_TCPHDR_OFFSET_MASK) <<
-                               TPD_TCPHDR_OFFSET_SHIFT;
-               (*tpd)->word1 |= (skb_shinfo(skb)->gso_size & TPD_MSS_MASK) <<
-                               TPD_MSS_SHIFT;
-               return 0;
-       }
-
-check_sum:
-       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-               u8 css, cso;
-               cso = skb_checksum_start_offset(skb);
-
-               if (unlikely(cso & 0x1)) {
-                       if (netif_msg_tx_err(adapter))
-                               dev_err(&adapter->pdev->dev,
-                                       "payload offset should not an event number\n");
-                       return -1;
-               } else {
-                       css = cso + skb->csum_offset;
-
-                       (*tpd)->word1 |= ((cso >> 1) & TPD_PLOADOFFSET_MASK) <<
-                                       TPD_PLOADOFFSET_SHIFT;
-                       (*tpd)->word1 |= ((css >> 1) & TPD_CCSUM_OFFSET_MASK) <<
-                                       TPD_CCSUM_OFFSET_SHIFT;
-                       (*tpd)->word1 |= 1 << TPD_CCSUM_EN_SHIFT;
-               }
-       }
-       return 0;
-}
-
-static void atl1c_tx_map(struct atl1c_adapter *adapter,
-                     struct sk_buff *skb, struct atl1c_tpd_desc *tpd,
-                       enum atl1c_trans_queue type)
-{
-       struct atl1c_tpd_desc *use_tpd = NULL;
-       struct atl1c_buffer *buffer_info = NULL;
-       u16 buf_len = skb_headlen(skb);
-       u16 map_len = 0;
-       u16 mapped_len = 0;
-       u16 hdr_len = 0;
-       u16 nr_frags;
-       u16 f;
-       int tso;
-
-       nr_frags = skb_shinfo(skb)->nr_frags;
-       tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK;
-       if (tso) {
-               /* TSO */
-               map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-               use_tpd = tpd;
-
-               buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
-               buffer_info->length = map_len;
-               buffer_info->dma = pci_map_single(adapter->pdev,
-                                       skb->data, hdr_len, PCI_DMA_TODEVICE);
-               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
-               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
-                       ATL1C_PCIMAP_TODEVICE);
-               mapped_len += map_len;
-               use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
-               use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
-       }
-
-       if (mapped_len < buf_len) {
-               /* mapped_len == 0, means we should use the first tpd,
-                  which is given by caller  */
-               if (mapped_len == 0)
-                       use_tpd = tpd;
-               else {
-                       use_tpd = atl1c_get_tpd(adapter, type);
-                       memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
-               }
-               buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
-               buffer_info->length = buf_len - mapped_len;
-               buffer_info->dma =
-                       pci_map_single(adapter->pdev, skb->data + mapped_len,
-                                       buffer_info->length, PCI_DMA_TODEVICE);
-               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
-               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
-                       ATL1C_PCIMAP_TODEVICE);
-               use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
-               use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
-       }
-
-       for (f = 0; f < nr_frags; f++) {
-               struct skb_frag_struct *frag;
-
-               frag = &skb_shinfo(skb)->frags[f];
-
-               use_tpd = atl1c_get_tpd(adapter, type);
-               memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
-
-               buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
-               buffer_info->length = frag->size;
-               buffer_info->dma =
-                       pci_map_page(adapter->pdev, frag->page,
-                                       frag->page_offset,
-                                       buffer_info->length,
-                                       PCI_DMA_TODEVICE);
-               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
-               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE,
-                       ATL1C_PCIMAP_TODEVICE);
-               use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
-               use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
-       }
-
-       /* The last tpd */
-       use_tpd->word1 |= 1 << TPD_EOP_SHIFT;
-       /* The last buffer info contain the skb address,
-          so it will be free after unmap */
-       buffer_info->skb = skb;
-}
-
-static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
-                          struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type)
-{
-       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
-       u32 prod_data;
-
-       AT_READ_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, &prod_data);
-       switch (type) {
-       case atl1c_trans_high:
-               prod_data &= 0xFFFF0000;
-               prod_data |= tpd_ring->next_to_use & 0xFFFF;
-               break;
-       case atl1c_trans_normal:
-               prod_data &= 0x0000FFFF;
-               prod_data |= (tpd_ring->next_to_use & 0xFFFF) << 16;
-               break;
-       default:
-               break;
-       }
-       wmb();
-       AT_WRITE_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, prod_data);
-}
-
-static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
-                                         struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       unsigned long flags;
-       u16 tpd_req = 1;
-       struct atl1c_tpd_desc *tpd;
-       enum atl1c_trans_queue type = atl1c_trans_normal;
-
-       if (test_bit(__AT_DOWN, &adapter->flags)) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       tpd_req = atl1c_cal_tpd_req(skb);
-       if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
-               if (netif_msg_pktdata(adapter))
-                       dev_info(&adapter->pdev->dev, "tx locked\n");
-               return NETDEV_TX_LOCKED;
-       }
-       if (skb->mark == 0x01)
-               type = atl1c_trans_high;
-       else
-               type = atl1c_trans_normal;
-
-       if (atl1c_tpd_avail(adapter, type) < tpd_req) {
-               /* no enough descriptor, just stop queue */
-               netif_stop_queue(netdev);
-               spin_unlock_irqrestore(&adapter->tx_lock, flags);
-               return NETDEV_TX_BUSY;
-       }
-
-       tpd = atl1c_get_tpd(adapter, type);
-
-       /* do TSO and check sum */
-       if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) {
-               spin_unlock_irqrestore(&adapter->tx_lock, flags);
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       if (unlikely(vlan_tx_tag_present(skb))) {
-               u16 vlan = vlan_tx_tag_get(skb);
-               __le16 tag;
-
-               vlan = cpu_to_le16(vlan);
-               AT_VLAN_TO_TAG(vlan, tag);
-               tpd->word1 |= 1 << TPD_INS_VTAG_SHIFT;
-               tpd->vlan_tag = tag;
-       }
-
-       if (skb_network_offset(skb) != ETH_HLEN)
-               tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */
-
-       atl1c_tx_map(adapter, skb, tpd, type);
-       atl1c_tx_queue(adapter, skb, tpd, type);
-
-       spin_unlock_irqrestore(&adapter->tx_lock, flags);
-       return NETDEV_TX_OK;
-}
-
-static void atl1c_free_irq(struct atl1c_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       free_irq(adapter->pdev->irq, netdev);
-
-       if (adapter->have_msi)
-               pci_disable_msi(adapter->pdev);
-}
-
-static int atl1c_request_irq(struct atl1c_adapter *adapter)
-{
-       struct pci_dev    *pdev   = adapter->pdev;
-       struct net_device *netdev = adapter->netdev;
-       int flags = 0;
-       int err = 0;
-
-       adapter->have_msi = true;
-       err = pci_enable_msi(adapter->pdev);
-       if (err) {
-               if (netif_msg_ifup(adapter))
-                       dev_err(&pdev->dev,
-                               "Unable to allocate MSI interrupt Error: %d\n",
-                               err);
-               adapter->have_msi = false;
-       } else
-               netdev->irq = pdev->irq;
-
-       if (!adapter->have_msi)
-               flags |= IRQF_SHARED;
-       err = request_irq(adapter->pdev->irq, atl1c_intr, flags,
-                       netdev->name, netdev);
-       if (err) {
-               if (netif_msg_ifup(adapter))
-                       dev_err(&pdev->dev,
-                               "Unable to allocate interrupt Error: %d\n",
-                               err);
-               if (adapter->have_msi)
-                       pci_disable_msi(adapter->pdev);
-               return err;
-       }
-       if (netif_msg_ifup(adapter))
-               dev_dbg(&pdev->dev, "atl1c_request_irq OK\n");
-       return err;
-}
-
-static int atl1c_up(struct atl1c_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       int num;
-       int err;
-       int i;
-
-       netif_carrier_off(netdev);
-       atl1c_init_ring_ptrs(adapter);
-       atl1c_set_multi(netdev);
-       atl1c_restore_vlan(adapter);
-
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               num = atl1c_alloc_rx_buffer(adapter, i);
-               if (unlikely(num == 0)) {
-                       err = -ENOMEM;
-                       goto err_alloc_rx;
-               }
-       }
-
-       if (atl1c_configure(adapter)) {
-               err = -EIO;
-               goto err_up;
-       }
-
-       err = atl1c_request_irq(adapter);
-       if (unlikely(err))
-               goto err_up;
-
-       clear_bit(__AT_DOWN, &adapter->flags);
-       napi_enable(&adapter->napi);
-       atl1c_irq_enable(adapter);
-       atl1c_check_link_status(adapter);
-       netif_start_queue(netdev);
-       return err;
-
-err_up:
-err_alloc_rx:
-       atl1c_clean_rx_ring(adapter);
-       return err;
-}
-
-static void atl1c_down(struct atl1c_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       atl1c_del_timer(adapter);
-       adapter->work_event = 0; /* clear all event */
-       /* signal that we're down so the interrupt handler does not
-        * reschedule our watchdog timer */
-       set_bit(__AT_DOWN, &adapter->flags);
-       netif_carrier_off(netdev);
-       napi_disable(&adapter->napi);
-       atl1c_irq_disable(adapter);
-       atl1c_free_irq(adapter);
-       /* reset MAC to disable all RX/TX */
-       atl1c_reset_mac(&adapter->hw);
-       msleep(1);
-
-       adapter->link_speed = SPEED_0;
-       adapter->link_duplex = -1;
-       atl1c_clean_tx_ring(adapter, atl1c_trans_normal);
-       atl1c_clean_tx_ring(adapter, atl1c_trans_high);
-       atl1c_clean_rx_ring(adapter);
-}
-
-/*
- * atl1c_open - Called when a network interface is made active
- * @netdev: network interface device structure
- *
- * Returns 0 on success, negative value on failure
- *
- * 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 atl1c_open(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       int err;
-
-       /* disallow open during test */
-       if (test_bit(__AT_TESTING, &adapter->flags))
-               return -EBUSY;
-
-       /* allocate rx/tx dma buffer & descriptors */
-       err = atl1c_setup_ring_resources(adapter);
-       if (unlikely(err))
-               return err;
-
-       err = atl1c_up(adapter);
-       if (unlikely(err))
-               goto err_up;
-
-       if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
-               u32 phy_data;
-
-               AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data);
-               phy_data |= MDIO_AP_EN;
-               AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data);
-       }
-       return 0;
-
-err_up:
-       atl1c_free_irq(adapter);
-       atl1c_free_ring_resources(adapter);
-       atl1c_reset_mac(&adapter->hw);
-       return err;
-}
-
-/*
- * atl1c_close - Disables a network interface
- * @netdev: network interface device structure
- *
- * Returns 0, this is not allowed to fail
- *
- * 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 atl1c_close(struct net_device *netdev)
-{
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
-       atl1c_down(adapter);
-       atl1c_free_ring_resources(adapter);
-       return 0;
-}
-
-static int atl1c_suspend(struct device *dev)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-       struct atl1c_hw *hw = &adapter->hw;
-       u32 mac_ctrl_data = 0;
-       u32 master_ctrl_data = 0;
-       u32 wol_ctrl_data = 0;
-       u16 mii_intr_status_data = 0;
-       u32 wufc = adapter->wol;
-
-       atl1c_disable_l0s_l1(hw);
-       if (netif_running(netdev)) {
-               WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
-               atl1c_down(adapter);
-       }
-       netif_device_detach(netdev);
-
-       if (wufc)
-               if (atl1c_phy_power_saving(hw) != 0)
-                       dev_dbg(&pdev->dev, "phy power saving failed");
-
-       AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
-       AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
-
-       master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS;
-       mac_ctrl_data &= ~(MAC_CTRL_PRMLEN_MASK << MAC_CTRL_PRMLEN_SHIFT);
-       mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
-                       MAC_CTRL_PRMLEN_MASK) <<
-                       MAC_CTRL_PRMLEN_SHIFT);
-       mac_ctrl_data &= ~(MAC_CTRL_SPEED_MASK << MAC_CTRL_SPEED_SHIFT);
-       mac_ctrl_data &= ~MAC_CTRL_DUPLX;
-
-       if (wufc) {
-               mac_ctrl_data |= MAC_CTRL_RX_EN;
-               if (adapter->link_speed == SPEED_1000 ||
-                       adapter->link_speed == SPEED_0) {
-                       mac_ctrl_data |= atl1c_mac_speed_1000 <<
-                                       MAC_CTRL_SPEED_SHIFT;
-                       mac_ctrl_data |= MAC_CTRL_DUPLX;
-               } else
-                       mac_ctrl_data |= atl1c_mac_speed_10_100 <<
-                                       MAC_CTRL_SPEED_SHIFT;
-
-               if (adapter->link_duplex == DUPLEX_FULL)
-                       mac_ctrl_data |= MAC_CTRL_DUPLX;
-
-               /* turn on magic packet wol */
-               if (wufc & AT_WUFC_MAG)
-                       wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
-
-               if (wufc & AT_WUFC_LNKC) {
-                       wol_ctrl_data |=  WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
-                       /* only link up can wake up */
-                       if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
-                               dev_dbg(&pdev->dev, "%s: read write phy "
-                                                 "register failed.\n",
-                                                 atl1c_driver_name);
-                       }
-               }
-               /* clear phy interrupt */
-               atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data);
-               /* Config MAC Ctrl register */
-               __atl1c_vlan_mode(netdev->features, &mac_ctrl_data);
-
-               /* magic packet maybe Broadcast&multicast&Unicast frame */
-               if (wufc & AT_WUFC_MAG)
-                       mac_ctrl_data |= MAC_CTRL_BC_EN;
-
-               dev_dbg(&pdev->dev,
-                       "%s: suspend MAC=0x%x\n",
-                       atl1c_driver_name, mac_ctrl_data);
-               AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
-               AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
-               AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-
-               AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
-                       GPHY_CTRL_EXT_RESET);
-       } else {
-               AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING);
-               master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS;
-               mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT;
-               mac_ctrl_data |= MAC_CTRL_DUPLX;
-               AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
-               AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-               AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
-               hw->phy_configured = false; /* re-init PHY when resume */
-       }
-
-       return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int atl1c_resume(struct device *dev)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
-       atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
-                       ATL1C_PCIE_PHY_RESET);
-
-       atl1c_phy_reset(&adapter->hw);
-       atl1c_reset_mac(&adapter->hw);
-       atl1c_phy_init(&adapter->hw);
-
-#if 0
-       AT_READ_REG(&adapter->hw, REG_PM_CTRLSTAT, &pm_data);
-       pm_data &= ~PM_CTRLSTAT_PME_EN;
-       AT_WRITE_REG(&adapter->hw, REG_PM_CTRLSTAT, pm_data);
-#endif
-
-       netif_device_attach(netdev);
-       if (netif_running(netdev))
-               atl1c_up(adapter);
-
-       return 0;
-}
-#endif
-
-static void atl1c_shutdown(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       atl1c_suspend(&pdev->dev);
-       pci_wake_from_d3(pdev, adapter->wol);
-       pci_set_power_state(pdev, PCI_D3hot);
-}
-
-static const struct net_device_ops atl1c_netdev_ops = {
-       .ndo_open               = atl1c_open,
-       .ndo_stop               = atl1c_close,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_start_xmit         = atl1c_xmit_frame,
-       .ndo_set_mac_address    = atl1c_set_mac_addr,
-       .ndo_set_multicast_list = atl1c_set_multi,
-       .ndo_change_mtu         = atl1c_change_mtu,
-       .ndo_fix_features       = atl1c_fix_features,
-       .ndo_set_features       = atl1c_set_features,
-       .ndo_do_ioctl           = atl1c_ioctl,
-       .ndo_tx_timeout         = atl1c_tx_timeout,
-       .ndo_get_stats          = atl1c_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = atl1c_netpoll,
-#endif
-};
-
-static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
-{
-       SET_NETDEV_DEV(netdev, &pdev->dev);
-       pci_set_drvdata(pdev, netdev);
-
-       netdev->irq  = pdev->irq;
-       netdev->netdev_ops = &atl1c_netdev_ops;
-       netdev->watchdog_timeo = AT_TX_WATCHDOG;
-       atl1c_set_ethtool_ops(netdev);
-
-       /* TODO: add when ready */
-       netdev->hw_features =   NETIF_F_SG         |
-                               NETIF_F_HW_CSUM    |
-                               NETIF_F_HW_VLAN_RX |
-                               NETIF_F_TSO        |
-                               NETIF_F_TSO6;
-       netdev->features =      netdev->hw_features |
-                               NETIF_F_HW_VLAN_TX;
-       return 0;
-}
-
-/*
- * atl1c_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in atl1c_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * atl1c_probe 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 __devinit atl1c_probe(struct pci_dev *pdev,
-                                const struct pci_device_id *ent)
-{
-       struct net_device *netdev;
-       struct atl1c_adapter *adapter;
-       static int cards_found;
-
-       int err = 0;
-
-       /* enable device (incl. PCI PM wakeup and hotplug setup) */
-       err = pci_enable_device_mem(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "cannot enable PCI device\n");
-               return err;
-       }
-
-       /*
-        * The atl1c chip can DMA to 64-bit addresses, but it uses a single
-        * shared register for the high 32 bits, so only a single, aligned,
-        * 4 GB physical address range can be used at a time.
-        *
-        * Supporting 64-bit DMA on this hardware is more trouble than it's
-        * worth.  It is far easier to limit to 32-bit DMA than update
-        * various kernel subsystems to support the mechanics required by a
-        * fixed-high-32-bit system.
-        */
-       if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
-           (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
-               dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
-               goto err_dma;
-       }
-
-       err = pci_request_regions(pdev, atl1c_driver_name);
-       if (err) {
-               dev_err(&pdev->dev, "cannot obtain PCI resources\n");
-               goto err_pci_reg;
-       }
-
-       pci_set_master(pdev);
-
-       netdev = alloc_etherdev(sizeof(struct atl1c_adapter));
-       if (netdev == NULL) {
-               err = -ENOMEM;
-               dev_err(&pdev->dev, "etherdev alloc failed\n");
-               goto err_alloc_etherdev;
-       }
-
-       err = atl1c_init_netdev(netdev, pdev);
-       if (err) {
-               dev_err(&pdev->dev, "init netdevice failed\n");
-               goto err_init_netdev;
-       }
-       adapter = netdev_priv(netdev);
-       adapter->bd_number = cards_found;
-       adapter->netdev = netdev;
-       adapter->pdev = pdev;
-       adapter->hw.adapter = adapter;
-       adapter->msg_enable = netif_msg_init(-1, atl1c_default_msg);
-       adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-       if (!adapter->hw.hw_addr) {
-               err = -EIO;
-               dev_err(&pdev->dev, "cannot map device registers\n");
-               goto err_ioremap;
-       }
-       netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
-
-       /* init mii data */
-       adapter->mii.dev = netdev;
-       adapter->mii.mdio_read  = atl1c_mdio_read;
-       adapter->mii.mdio_write = atl1c_mdio_write;
-       adapter->mii.phy_id_mask = 0x1f;
-       adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
-       netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
-       setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
-                       (unsigned long)adapter);
-       /* setup the private structure */
-       err = atl1c_sw_init(adapter);
-       if (err) {
-               dev_err(&pdev->dev, "net device private data init failed\n");
-               goto err_sw_init;
-       }
-       atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
-                       ATL1C_PCIE_PHY_RESET);
-
-       /* Init GPHY as early as possible due to power saving issue  */
-       atl1c_phy_reset(&adapter->hw);
-
-       err = atl1c_reset_mac(&adapter->hw);
-       if (err) {
-               err = -EIO;
-               goto err_reset;
-       }
-
-       /* reset the controller to
-        * put the device in a known good starting state */
-       err = atl1c_phy_init(&adapter->hw);
-       if (err) {
-               err = -EIO;
-               goto err_reset;
-       }
-       if (atl1c_read_mac_addr(&adapter->hw) != 0) {
-               err = -EIO;
-               dev_err(&pdev->dev, "get mac address failed\n");
-               goto err_eeprom;
-       }
-       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
-       if (netif_msg_probe(adapter))
-               dev_dbg(&pdev->dev, "mac address : %pM\n",
-                       adapter->hw.mac_addr);
-
-       atl1c_hw_set_mac_addr(&adapter->hw);
-       INIT_WORK(&adapter->common_task, atl1c_common_task);
-       adapter->work_event = 0;
-       err = register_netdev(netdev);
-       if (err) {
-               dev_err(&pdev->dev, "register netdevice failed\n");
-               goto err_register;
-       }
-
-       if (netif_msg_probe(adapter))
-               dev_info(&pdev->dev, "version %s\n", ATL1C_DRV_VERSION);
-       cards_found++;
-       return 0;
-
-err_reset:
-err_register:
-err_sw_init:
-err_eeprom:
-       iounmap(adapter->hw.hw_addr);
-err_init_netdev:
-err_ioremap:
-       free_netdev(netdev);
-err_alloc_etherdev:
-       pci_release_regions(pdev);
-err_pci_reg:
-err_dma:
-       pci_disable_device(pdev);
-       return err;
-}
-
-/*
- * atl1c_remove - Device Removal Routine
- * @pdev: PCI device information struct
- *
- * atl1c_remove 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 __devexit atl1c_remove(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       unregister_netdev(netdev);
-       atl1c_phy_disable(&adapter->hw);
-
-       iounmap(adapter->hw.hw_addr);
-
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-       free_netdev(netdev);
-}
-
-/*
- * atl1c_io_error_detected - called when PCI error is detected
- * @pdev: Pointer to PCI device
- * @state: The current pci connection state
- *
- * This function is called after a PCI bus error affecting
- * this device has been detected.
- */
-static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev,
-                                               pci_channel_state_t state)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       netif_device_detach(netdev);
-
-       if (state == pci_channel_io_perm_failure)
-               return PCI_ERS_RESULT_DISCONNECT;
-
-       if (netif_running(netdev))
-               atl1c_down(adapter);
-
-       pci_disable_device(pdev);
-
-       /* Request a slot slot reset. */
-       return PCI_ERS_RESULT_NEED_RESET;
-}
-
-/*
- * atl1c_io_slot_reset - called after the pci bus has been reset.
- * @pdev: Pointer to PCI device
- *
- * Restart the card from scratch, as if from a cold-boot. Implementation
- * resembles the first-half of the e1000_resume routine.
- */
-static pci_ers_result_t atl1c_io_slot_reset(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       if (pci_enable_device(pdev)) {
-               if (netif_msg_hw(adapter))
-                       dev_err(&pdev->dev,
-                               "Cannot re-enable PCI device after reset\n");
-               return PCI_ERS_RESULT_DISCONNECT;
-       }
-       pci_set_master(pdev);
-
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
-       atl1c_reset_mac(&adapter->hw);
-
-       return PCI_ERS_RESULT_RECOVERED;
-}
-
-/*
- * atl1c_io_resume - called when traffic can start flowing again.
- * @pdev: Pointer to PCI device
- *
- * 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 atl1c_resume routine.
- */
-static void atl1c_io_resume(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1c_adapter *adapter = netdev_priv(netdev);
-
-       if (netif_running(netdev)) {
-               if (atl1c_up(adapter)) {
-                       if (netif_msg_hw(adapter))
-                               dev_err(&pdev->dev,
-                                       "Cannot bring device back up after reset\n");
-                       return;
-               }
-       }
-
-       netif_device_attach(netdev);
-}
-
-static struct pci_error_handlers atl1c_err_handler = {
-       .error_detected = atl1c_io_error_detected,
-       .slot_reset = atl1c_io_slot_reset,
-       .resume = atl1c_io_resume,
-};
-
-static SIMPLE_DEV_PM_OPS(atl1c_pm_ops, atl1c_suspend, atl1c_resume);
-
-static struct pci_driver atl1c_driver = {
-       .name     = atl1c_driver_name,
-       .id_table = atl1c_pci_tbl,
-       .probe    = atl1c_probe,
-       .remove   = __devexit_p(atl1c_remove),
-       .shutdown = atl1c_shutdown,
-       .err_handler = &atl1c_err_handler,
-       .driver.pm = &atl1c_pm_ops,
-};
-
-/*
- * atl1c_init_module - Driver Registration Routine
- *
- * atl1c_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1c_init_module(void)
-{
-       return pci_register_driver(&atl1c_driver);
-}
-
-/*
- * atl1c_exit_module - Driver Exit Cleanup Routine
- *
- * atl1c_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1c_exit_module(void)
-{
-       pci_unregister_driver(&atl1c_driver);
-}
-
-module_init(atl1c_init_module);
-module_exit(atl1c_exit_module);
diff --git a/drivers/net/atl1e/Makefile b/drivers/net/atl1e/Makefile
deleted file mode 100644 (file)
index bc11be8..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_ATL1E)    += atl1e.o
-atl1e-objs             += atl1e_main.o atl1e_hw.o atl1e_ethtool.o atl1e_param.o
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
deleted file mode 100644 (file)
index 829b5ad..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- * Copyright(c) 2007 xiong huang <xiong.huang@atheros.com>
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#ifndef _ATL1E_H_
-#define _ATL1E_H_
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/udp.h>
-#include <linux/mii.h>
-#include <linux/io.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <linux/tcp.h>
-#include <linux/ethtool.h>
-#include <linux/if_vlan.h>
-#include <linux/workqueue.h>
-#include <net/checksum.h>
-#include <net/ip6_checksum.h>
-
-#include "atl1e_hw.h"
-
-#define PCI_REG_COMMAND         0x04    /* PCI Command Register */
-#define CMD_IO_SPACE    0x0001
-#define CMD_MEMORY_SPACE 0x0002
-#define CMD_BUS_MASTER   0x0004
-
-#define BAR_0   0
-#define BAR_1   1
-#define BAR_5   5
-
-/* Wake Up Filter Control */
-#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
-#define AT_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
-#define AT_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
-#define AT_WUFC_MC   0x00000008 /* Multicast Wakeup Enable */
-#define AT_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
-
-#define SPEED_0                   0xffff
-#define HALF_DUPLEX        1
-#define FULL_DUPLEX        2
-
-/* Error Codes */
-#define AT_ERR_EEPROM      1
-#define AT_ERR_PHY         2
-#define AT_ERR_CONFIG      3
-#define AT_ERR_PARAM       4
-#define AT_ERR_MAC_TYPE    5
-#define AT_ERR_PHY_TYPE    6
-#define AT_ERR_PHY_SPEED   7
-#define AT_ERR_PHY_RES     8
-#define AT_ERR_TIMEOUT     9
-
-#define MAX_JUMBO_FRAME_SIZE 0x2000
-
-#define AT_VLAN_TAG_TO_TPD_TAG(_vlan, _tpd)    \
-       _tpd = (((_vlan) << (4)) | (((_vlan) >> 13) & 7) |\
-                (((_vlan) >> 9) & 8))
-
-#define AT_TPD_TAG_TO_VLAN_TAG(_tpd, _vlan)    \
-       _vlan = (((_tpd) >> 8) | (((_tpd) & 0x77) << 9) |\
-                  (((_tdp) & 0x88) << 5))
-
-#define AT_MAX_RECEIVE_QUEUE    4
-#define AT_PAGE_NUM_PER_QUEUE   2
-
-#define AT_DMA_HI_ADDR_MASK     0xffffffff00000000ULL
-#define AT_DMA_LO_ADDR_MASK     0x00000000ffffffffULL
-
-#define AT_TX_WATCHDOG  (5 * HZ)
-#define AT_MAX_INT_WORK                10
-#define AT_TWSI_EEPROM_TIMEOUT         100
-#define AT_HW_MAX_IDLE_DELAY   10
-#define AT_SUSPEND_LINK_TIMEOUT 28
-
-#define AT_REGS_LEN    75
-#define AT_EEPROM_LEN  512
-#define AT_ADV_MASK    (ADVERTISE_10_HALF  |\
-                        ADVERTISE_10_FULL  |\
-                        ADVERTISE_100_HALF |\
-                        ADVERTISE_100_FULL |\
-                        ADVERTISE_1000_FULL)
-
-/* tpd word 2 */
-#define TPD_BUFLEN_MASK        0x3FFF
-#define TPD_BUFLEN_SHIFT        0
-#define TPD_DMAINT_MASK                0x0001
-#define TPD_DMAINT_SHIFT        14
-#define TPD_PKTNT_MASK          0x0001
-#define TPD_PKTINT_SHIFT        15
-#define TPD_VLANTAG_MASK        0xFFFF
-#define TPD_VLAN_SHIFT          16
-
-/* tpd word 3 bits 0:4 */
-#define TPD_EOP_MASK            0x0001
-#define TPD_EOP_SHIFT           0
-#define TPD_IP_VERSION_MASK    0x0001
-#define TPD_IP_VERSION_SHIFT   1       /* 0 : IPV4, 1 : IPV6 */
-#define TPD_INS_VL_TAG_MASK    0x0001
-#define TPD_INS_VL_TAG_SHIFT   2
-#define TPD_CC_SEGMENT_EN_MASK 0x0001
-#define TPD_CC_SEGMENT_EN_SHIFT        3
-#define TPD_SEGMENT_EN_MASK     0x0001
-#define TPD_SEGMENT_EN_SHIFT    4
-
-/* tdp word 3 bits 5:7 if ip version is 0 */
-#define TPD_IP_CSUM_MASK        0x0001
-#define TPD_IP_CSUM_SHIFT       5
-#define TPD_TCP_CSUM_MASK       0x0001
-#define TPD_TCP_CSUM_SHIFT      6
-#define TPD_UDP_CSUM_MASK       0x0001
-#define TPD_UDP_CSUM_SHIFT      7
-
-/* tdp word 3 bits 5:7 if ip version is 1 */
-#define TPD_V6_IPHLLO_MASK     0x0007
-#define TPD_V6_IPHLLO_SHIFT    7
-
-/* tpd word 3 bits 8:9 bit */
-#define TPD_VL_TAGGED_MASK      0x0001
-#define TPD_VL_TAGGED_SHIFT     8
-#define TPD_ETHTYPE_MASK        0x0001
-#define TPD_ETHTYPE_SHIFT       9
-
-/* tdp word 3 bits 10:13 if ip version is 0 */
-#define TDP_V4_IPHL_MASK       0x000F
-#define TPD_V4_IPHL_SHIFT      10
-
-/* tdp word 3 bits 10:13 if ip version is 1 */
-#define TPD_V6_IPHLHI_MASK     0x000F
-#define TPD_V6_IPHLHI_SHIFT    10
-
-/* tpd word 3 bit 14:31 if segment enabled */
-#define TPD_TCPHDRLEN_MASK      0x000F
-#define TPD_TCPHDRLEN_SHIFT     14
-#define TPD_HDRFLAG_MASK        0x0001
-#define TPD_HDRFLAG_SHIFT       18
-#define TPD_MSS_MASK            0x1FFF
-#define TPD_MSS_SHIFT           19
-
-/* tdp word 3 bit 16:31 if custom csum enabled */
-#define TPD_PLOADOFFSET_MASK    0x00FF
-#define TPD_PLOADOFFSET_SHIFT   16
-#define TPD_CCSUMOFFSET_MASK    0x00FF
-#define TPD_CCSUMOFFSET_SHIFT   24
-
-struct atl1e_tpd_desc {
-       __le64 buffer_addr;
-       __le32 word2;
-       __le32 word3;
-};
-
-/* how about 0x2000 */
-#define MAX_TX_BUF_LEN      0x2000
-#define MAX_TX_BUF_SHIFT    13
-/*#define MAX_TX_BUF_LEN  0x3000 */
-
-/* rrs word 1 bit 0:31 */
-#define RRS_RX_CSUM_MASK       0xFFFF
-#define RRS_RX_CSUM_SHIFT      0
-#define RRS_PKT_SIZE_MASK      0x3FFF
-#define RRS_PKT_SIZE_SHIFT     16
-#define RRS_CPU_NUM_MASK       0x0003
-#define        RRS_CPU_NUM_SHIFT       30
-
-#define        RRS_IS_RSS_IPV4         0x0001
-#define RRS_IS_RSS_IPV4_TCP    0x0002
-#define RRS_IS_RSS_IPV6                0x0004
-#define RRS_IS_RSS_IPV6_TCP    0x0008
-#define RRS_IS_IPV6            0x0010
-#define RRS_IS_IP_FRAG         0x0020
-#define RRS_IS_IP_DF           0x0040
-#define RRS_IS_802_3           0x0080
-#define RRS_IS_VLAN_TAG                0x0100
-#define RRS_IS_ERR_FRAME       0x0200
-#define RRS_IS_IPV4            0x0400
-#define RRS_IS_UDP             0x0800
-#define RRS_IS_TCP             0x1000
-#define RRS_IS_BCAST           0x2000
-#define RRS_IS_MCAST           0x4000
-#define RRS_IS_PAUSE           0x8000
-
-#define RRS_ERR_BAD_CRC                0x0001
-#define RRS_ERR_CODE           0x0002
-#define RRS_ERR_DRIBBLE                0x0004
-#define RRS_ERR_RUNT           0x0008
-#define RRS_ERR_RX_OVERFLOW    0x0010
-#define RRS_ERR_TRUNC          0x0020
-#define RRS_ERR_IP_CSUM                0x0040
-#define RRS_ERR_L4_CSUM                0x0080
-#define RRS_ERR_LENGTH         0x0100
-#define RRS_ERR_DES_ADDR       0x0200
-
-struct atl1e_recv_ret_status {
-       u16 seq_num;
-       u16 hash_lo;
-       __le32  word1;
-       u16 pkt_flag;
-       u16 err_flag;
-       u16 hash_hi;
-       u16 vtag;
-};
-
-enum atl1e_dma_req_block {
-       atl1e_dma_req_128 = 0,
-       atl1e_dma_req_256 = 1,
-       atl1e_dma_req_512 = 2,
-       atl1e_dma_req_1024 = 3,
-       atl1e_dma_req_2048 = 4,
-       atl1e_dma_req_4096 = 5
-};
-
-enum atl1e_rrs_type {
-       atl1e_rrs_disable = 0,
-       atl1e_rrs_ipv4 = 1,
-       atl1e_rrs_ipv4_tcp = 2,
-       atl1e_rrs_ipv6 = 4,
-       atl1e_rrs_ipv6_tcp = 8
-};
-
-enum atl1e_nic_type {
-       athr_l1e = 0,
-       athr_l2e_revA = 1,
-       athr_l2e_revB = 2
-};
-
-struct atl1e_hw_stats {
-       /* rx */
-       unsigned long rx_ok;          /* The number of good packet received. */
-       unsigned long rx_bcast;       /* The number of good broadcast packet received. */
-       unsigned long rx_mcast;       /* The number of good multicast packet received. */
-       unsigned long rx_pause;       /* The number of Pause packet received. */
-       unsigned long rx_ctrl;        /* The number of Control packet received other than Pause frame. */
-       unsigned long rx_fcs_err;     /* The number of packets with bad FCS. */
-       unsigned long rx_len_err;     /* The number of packets with mismatch of length field and actual size. */
-       unsigned long rx_byte_cnt;    /* The number of bytes of good packet received. FCS is NOT included. */
-       unsigned long rx_runt;        /* The number of packets received that are less than 64 byte long and with good FCS. */
-       unsigned long rx_frag;        /* The number of packets received that are less than 64 byte long and with bad FCS. */
-       unsigned long rx_sz_64;       /* The number of good and bad packets received that are 64 byte long. */
-       unsigned long rx_sz_65_127;   /* The number of good and bad packets received that are between 65 and 127-byte long. */
-       unsigned long rx_sz_128_255;  /* The number of good and bad packets received that are between 128 and 255-byte long. */
-       unsigned long rx_sz_256_511;  /* The number of good and bad packets received that are between 256 and 511-byte long. */
-       unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
-       unsigned long rx_sz_1024_1518;    /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
-       unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
-       unsigned long rx_sz_ov;       /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
-       unsigned long rx_rxf_ov;      /* The number of frame dropped due to occurrence of RX FIFO overflow. */
-       unsigned long rx_rrd_ov;      /* The number of frame dropped due to occurrence of RRD overflow. */
-       unsigned long rx_align_err;   /* Alignment Error */
-       unsigned long rx_bcast_byte_cnt;  /* The byte count of broadcast packet received, excluding FCS. */
-       unsigned long rx_mcast_byte_cnt;  /* The byte count of multicast packet received, excluding FCS. */
-       unsigned long rx_err_addr;    /* The number of packets dropped due to address filtering. */
-
-       /* tx */
-       unsigned long tx_ok;      /* The number of good packet transmitted. */
-       unsigned long tx_bcast;       /* The number of good broadcast packet transmitted. */
-       unsigned long tx_mcast;       /* The number of good multicast packet transmitted. */
-       unsigned long tx_pause;       /* The number of Pause packet transmitted. */
-       unsigned long tx_exc_defer;   /* The number of packets transmitted with excessive deferral. */
-       unsigned long tx_ctrl;        /* The number of packets transmitted is a control frame, excluding Pause frame. */
-       unsigned long tx_defer;       /* The number of packets transmitted that is deferred. */
-       unsigned long tx_byte_cnt;    /* The number of bytes of data transmitted. FCS is NOT included. */
-       unsigned long tx_sz_64;       /* The number of good and bad packets transmitted that are 64 byte long. */
-       unsigned long tx_sz_65_127;   /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
-       unsigned long tx_sz_128_255;  /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
-       unsigned long tx_sz_256_511;  /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
-       unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
-       unsigned long tx_sz_1024_1518;    /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
-       unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
-       unsigned long tx_1_col;       /* The number of packets subsequently transmitted successfully with a single prior collision. */
-       unsigned long tx_2_col;       /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
-       unsigned long tx_late_col;    /* The number of packets transmitted with late collisions. */
-       unsigned long tx_abort_col;   /* The number of transmit packets aborted due to excessive collisions. */
-       unsigned long tx_underrun;    /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
-       unsigned long tx_rd_eop;      /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
-       unsigned long tx_len_err;     /* The number of transmit packets with length field does NOT match the actual frame size. */
-       unsigned long tx_trunc;       /* The number of transmit packets truncated due to size exceeding MTU. */
-       unsigned long tx_bcast_byte;  /* The byte count of broadcast packet transmitted, excluding FCS. */
-       unsigned long tx_mcast_byte;  /* The byte count of multicast packet transmitted, excluding FCS. */
-};
-
-struct atl1e_hw {
-       u8 __iomem      *hw_addr;            /* inner register address */
-       resource_size_t mem_rang;
-       struct atl1e_adapter *adapter;
-       enum atl1e_nic_type  nic_type;
-       u16 device_id;
-       u16 vendor_id;
-       u16 subsystem_id;
-       u16 subsystem_vendor_id;
-       u8  revision_id;
-       u16 pci_cmd_word;
-       u8 mac_addr[ETH_ALEN];
-       u8 perm_mac_addr[ETH_ALEN];
-       u8 preamble_len;
-       u16 max_frame_size;
-       u16 rx_jumbo_th;
-       u16 tx_jumbo_th;
-
-       u16 media_type;
-#define MEDIA_TYPE_AUTO_SENSOR  0
-#define MEDIA_TYPE_100M_FULL    1
-#define MEDIA_TYPE_100M_HALF    2
-#define MEDIA_TYPE_10M_FULL     3
-#define MEDIA_TYPE_10M_HALF     4
-
-       u16 autoneg_advertised;
-#define ADVERTISE_10_HALF               0x0001
-#define ADVERTISE_10_FULL               0x0002
-#define ADVERTISE_100_HALF              0x0004
-#define ADVERTISE_100_FULL              0x0008
-#define ADVERTISE_1000_HALF             0x0010 /* Not used, just FYI */
-#define ADVERTISE_1000_FULL             0x0020
-       u16 mii_autoneg_adv_reg;
-       u16 mii_1000t_ctrl_reg;
-
-       u16 imt;        /* Interrupt Moderator timer ( 2us resolution) */
-       u16 ict;        /* Interrupt Clear timer (2us resolution) */
-       u32 smb_timer;
-       u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
-                         interrupt request */
-       u16 tpd_thresh;
-       u16 rx_count_down; /* 2us resolution */
-       u16 tx_count_down;
-
-       u8 tpd_burst;   /* Number of TPD to prefetch in cache-aligned burst. */
-       enum atl1e_rrs_type rrs_type;
-       u32 base_cpu;
-       u32 indirect_tab;
-
-       enum atl1e_dma_req_block dmar_block;
-       enum atl1e_dma_req_block dmaw_block;
-       u8 dmaw_dly_cnt;
-       u8 dmar_dly_cnt;
-
-       bool phy_configured;
-       bool re_autoneg;
-       bool emi_ca;
-};
-
-/*
- * wrapper around a pointer to a socket buffer,
- * so a DMA handle can be stored along with the buffer
- */
-struct atl1e_tx_buffer {
-       struct sk_buff *skb;
-       u16 flags;
-#define ATL1E_TX_PCIMAP_SINGLE         0x0001
-#define ATL1E_TX_PCIMAP_PAGE           0x0002
-#define ATL1E_TX_PCIMAP_TYPE_MASK      0x0003
-       u16 length;
-       dma_addr_t dma;
-};
-
-#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do {              \
-       ((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK;       \
-       ((tx_buff)->flags) |= (type);                           \
-       } while (0)
-
-struct atl1e_rx_page {
-       dma_addr_t      dma;    /* receive rage DMA address */
-       u8              *addr;   /* receive rage virtual address */
-       dma_addr_t      write_offset_dma;  /* the DMA address which contain the
-                                             receive data offset in the page */
-       u32             *write_offset_addr; /* the virtaul address which contain
-                                            the receive data offset in the page */
-       u32             read_offset;       /* the offset where we have read */
-};
-
-struct atl1e_rx_page_desc {
-       struct atl1e_rx_page   rx_page[AT_PAGE_NUM_PER_QUEUE];
-       u8  rx_using;
-       u16 rx_nxseq;
-};
-
-/* transmit packet descriptor (tpd) ring */
-struct atl1e_tx_ring {
-       struct atl1e_tpd_desc *desc;  /* descriptor ring virtual address  */
-       dma_addr_t         dma;    /* descriptor ring physical address */
-       u16                count;  /* the count of transmit rings  */
-       rwlock_t           tx_lock;
-       u16                next_to_use;
-       atomic_t           next_to_clean;
-       struct atl1e_tx_buffer *tx_buffer;
-       dma_addr_t         cmb_dma;
-       u32                *cmb;
-};
-
-/* receive packet descriptor ring */
-struct atl1e_rx_ring {
-       void            *desc;
-       dma_addr_t      dma;
-       int             size;
-       u32             page_size; /* bytes length of rxf page */
-       u32             real_page_size; /* real_page_size = page_size + jumbo + aliagn */
-       struct atl1e_rx_page_desc       rx_page_desc[AT_MAX_RECEIVE_QUEUE];
-};
-
-/* board specific private data structure */
-struct atl1e_adapter {
-       struct net_device   *netdev;
-       struct pci_dev      *pdev;
-       struct napi_struct  napi;
-       struct mii_if_info  mii;    /* MII interface info */
-       struct atl1e_hw        hw;
-       struct atl1e_hw_stats  hw_stats;
-
-       bool have_msi;
-       u32 wol;
-       u16 link_speed;
-       u16 link_duplex;
-
-       spinlock_t mdio_lock;
-       spinlock_t tx_lock;
-       atomic_t irq_sem;
-
-       struct work_struct reset_task;
-       struct work_struct link_chg_task;
-       struct timer_list watchdog_timer;
-       struct timer_list phy_config_timer;
-
-       /* All Descriptor memory */
-       dma_addr_t      ring_dma;
-       void            *ring_vir_addr;
-       u32             ring_size;
-
-       struct atl1e_tx_ring tx_ring;
-       struct atl1e_rx_ring rx_ring;
-       int num_rx_queues;
-       unsigned long flags;
-#define __AT_TESTING        0x0001
-#define __AT_RESETTING      0x0002
-#define __AT_DOWN           0x0003
-
-       u32 bd_number;     /* board number;*/
-       u32 pci_state[16];
-       u32 *config_space;
-};
-
-#define AT_WRITE_REG(a, reg, value) ( \
-               writel((value), ((a)->hw_addr + reg)))
-
-#define AT_WRITE_FLUSH(a) (\
-               readl((a)->hw_addr))
-
-#define AT_READ_REG(a, reg) ( \
-               readl((a)->hw_addr + reg))
-
-#define AT_WRITE_REGB(a, reg, value) (\
-               writeb((value), ((a)->hw_addr + reg)))
-
-#define AT_READ_REGB(a, reg) (\
-               readb((a)->hw_addr + reg))
-
-#define AT_WRITE_REGW(a, reg, value) (\
-               writew((value), ((a)->hw_addr + reg)))
-
-#define AT_READ_REGW(a, reg) (\
-               readw((a)->hw_addr + reg))
-
-#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
-               writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
-
-#define AT_READ_REG_ARRAY(a, reg, offset) ( \
-               readl(((a)->hw_addr + reg) + ((offset) << 2)))
-
-extern char atl1e_driver_name[];
-extern char atl1e_driver_version[];
-
-extern void atl1e_check_options(struct atl1e_adapter *adapter);
-extern int atl1e_up(struct atl1e_adapter *adapter);
-extern void atl1e_down(struct atl1e_adapter *adapter);
-extern void atl1e_reinit_locked(struct atl1e_adapter *adapter);
-extern s32 atl1e_reset_hw(struct atl1e_hw *hw);
-extern void atl1e_set_ethtool_ops(struct net_device *netdev);
-#endif /* _ATL1_E_H_ */
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
deleted file mode 100644 (file)
index 6269438..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- *
- */
-
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/slab.h>
-
-#include "atl1e.h"
-
-static int atl1e_get_settings(struct net_device *netdev,
-                             struct ethtool_cmd *ecmd)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-
-       ecmd->supported = (SUPPORTED_10baseT_Half  |
-                          SUPPORTED_10baseT_Full  |
-                          SUPPORTED_100baseT_Half |
-                          SUPPORTED_100baseT_Full |
-                          SUPPORTED_Autoneg       |
-                          SUPPORTED_TP);
-       if (hw->nic_type == athr_l1e)
-               ecmd->supported |= SUPPORTED_1000baseT_Full;
-
-       ecmd->advertising = ADVERTISED_TP;
-
-       ecmd->advertising |= ADVERTISED_Autoneg;
-       ecmd->advertising |= hw->autoneg_advertised;
-
-       ecmd->port = PORT_TP;
-       ecmd->phy_address = 0;
-       ecmd->transceiver = XCVR_INTERNAL;
-
-       if (adapter->link_speed != SPEED_0) {
-               ethtool_cmd_speed_set(ecmd, adapter->link_speed);
-               if (adapter->link_duplex == FULL_DUPLEX)
-                       ecmd->duplex = DUPLEX_FULL;
-               else
-                       ecmd->duplex = DUPLEX_HALF;
-       } else {
-               ethtool_cmd_speed_set(ecmd, -1);
-               ecmd->duplex = -1;
-       }
-
-       ecmd->autoneg = AUTONEG_ENABLE;
-       return 0;
-}
-
-static int atl1e_set_settings(struct net_device *netdev,
-                             struct ethtool_cmd *ecmd)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-
-       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
-               msleep(1);
-
-       if (ecmd->autoneg == AUTONEG_ENABLE) {
-               u16 adv4, adv9;
-
-               if ((ecmd->advertising&ADVERTISE_1000_FULL)) {
-                       if (hw->nic_type == athr_l1e) {
-                               hw->autoneg_advertised =
-                                       ecmd->advertising & AT_ADV_MASK;
-                       } else {
-                               clear_bit(__AT_RESETTING, &adapter->flags);
-                               return -EINVAL;
-                       }
-               } else if (ecmd->advertising&ADVERTISE_1000_HALF) {
-                       clear_bit(__AT_RESETTING, &adapter->flags);
-                       return -EINVAL;
-               } else {
-                       hw->autoneg_advertised =
-                               ecmd->advertising & AT_ADV_MASK;
-               }
-               ecmd->advertising = hw->autoneg_advertised |
-                                   ADVERTISED_TP | ADVERTISED_Autoneg;
-
-               adv4 = hw->mii_autoneg_adv_reg & ~ADVERTISE_ALL;
-               adv9 = hw->mii_1000t_ctrl_reg & ~MII_AT001_CR_1000T_SPEED_MASK;
-               if (hw->autoneg_advertised & ADVERTISE_10_HALF)
-                       adv4 |= ADVERTISE_10HALF;
-               if (hw->autoneg_advertised & ADVERTISE_10_FULL)
-                       adv4 |= ADVERTISE_10FULL;
-               if (hw->autoneg_advertised & ADVERTISE_100_HALF)
-                       adv4 |= ADVERTISE_100HALF;
-               if (hw->autoneg_advertised & ADVERTISE_100_FULL)
-                       adv4 |= ADVERTISE_100FULL;
-               if (hw->autoneg_advertised & ADVERTISE_1000_FULL)
-                       adv9 |= ADVERTISE_1000FULL;
-
-               if (adv4 != hw->mii_autoneg_adv_reg ||
-                               adv9 != hw->mii_1000t_ctrl_reg) {
-                       hw->mii_autoneg_adv_reg = adv4;
-                       hw->mii_1000t_ctrl_reg = adv9;
-                       hw->re_autoneg = true;
-               }
-
-       } else {
-               clear_bit(__AT_RESETTING, &adapter->flags);
-               return -EINVAL;
-       }
-
-       /* reset the link */
-
-       if (netif_running(adapter->netdev)) {
-               atl1e_down(adapter);
-               atl1e_up(adapter);
-       } else
-               atl1e_reset_hw(&adapter->hw);
-
-       clear_bit(__AT_RESETTING, &adapter->flags);
-       return 0;
-}
-
-static u32 atl1e_get_msglevel(struct net_device *netdev)
-{
-#ifdef DBG
-       return 1;
-#else
-       return 0;
-#endif
-}
-
-static int atl1e_get_regs_len(struct net_device *netdev)
-{
-       return AT_REGS_LEN * sizeof(u32);
-}
-
-static void atl1e_get_regs(struct net_device *netdev,
-                          struct ethtool_regs *regs, void *p)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-       u32 *regs_buff = p;
-       u16 phy_data;
-
-       memset(p, 0, AT_REGS_LEN * sizeof(u32));
-
-       regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
-
-       regs_buff[0]  = AT_READ_REG(hw, REG_VPD_CAP);
-       regs_buff[1]  = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
-       regs_buff[2]  = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG);
-       regs_buff[3]  = AT_READ_REG(hw, REG_TWSI_CTRL);
-       regs_buff[4]  = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
-       regs_buff[5]  = AT_READ_REG(hw, REG_MASTER_CTRL);
-       regs_buff[6]  = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT);
-       regs_buff[7]  = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
-       regs_buff[8]  = AT_READ_REG(hw, REG_GPHY_CTRL);
-       regs_buff[9]  = AT_READ_REG(hw, REG_CMBDISDMA_TIMER);
-       regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS);
-       regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL);
-       regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK);
-       regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL);
-       regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG);
-       regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
-       regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4);
-       regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE);
-       regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4);
-       regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
-       regs_buff[20] = AT_READ_REG(hw, REG_MTU);
-       regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL);
-       regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR);
-       regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN);
-       regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR);
-       regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
-       regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR);
-       regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN);
-       regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR);
-       regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR);
-
-       atl1e_read_phy_reg(hw, MII_BMCR, &phy_data);
-       regs_buff[73] = (u32)phy_data;
-       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
-       regs_buff[74] = (u32)phy_data;
-}
-
-static int atl1e_get_eeprom_len(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       if (!atl1e_check_eeprom_exist(&adapter->hw))
-               return AT_EEPROM_LEN;
-       else
-               return 0;
-}
-
-static int atl1e_get_eeprom(struct net_device *netdev,
-               struct ethtool_eeprom *eeprom, u8 *bytes)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-       u32 *eeprom_buff;
-       int first_dword, last_dword;
-       int ret_val = 0;
-       int i;
-
-       if (eeprom->len == 0)
-               return -EINVAL;
-
-       if (atl1e_check_eeprom_exist(hw)) /* not exist */
-               return -EINVAL;
-
-       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
-
-       first_dword = eeprom->offset >> 2;
-       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
-
-       eeprom_buff = kmalloc(sizeof(u32) *
-                       (last_dword - first_dword + 1), GFP_KERNEL);
-       if (eeprom_buff == NULL)
-               return -ENOMEM;
-
-       for (i = first_dword; i < last_dword; i++) {
-               if (!atl1e_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
-                       kfree(eeprom_buff);
-                       return -EIO;
-               }
-       }
-
-       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
-                       eeprom->len);
-       kfree(eeprom_buff);
-
-       return ret_val;
-}
-
-static int atl1e_set_eeprom(struct net_device *netdev,
-                           struct ethtool_eeprom *eeprom, u8 *bytes)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-       u32 *eeprom_buff;
-       u32 *ptr;
-       int first_dword, last_dword;
-       int ret_val = 0;
-       int i;
-
-       if (eeprom->len == 0)
-               return -EOPNOTSUPP;
-
-       if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
-               return -EINVAL;
-
-       first_dword = eeprom->offset >> 2;
-       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
-       eeprom_buff = kmalloc(AT_EEPROM_LEN, GFP_KERNEL);
-       if (eeprom_buff == NULL)
-               return -ENOMEM;
-
-       ptr = (u32 *)eeprom_buff;
-
-       if (eeprom->offset & 3) {
-               /* need read/modify/write of first changed EEPROM word */
-               /* only the second byte of the word is being modified */
-               if (!atl1e_read_eeprom(hw, first_dword * 4, &(eeprom_buff[0]))) {
-                       ret_val = -EIO;
-                       goto out;
-               }
-               ptr++;
-       }
-       if (((eeprom->offset + eeprom->len) & 3)) {
-               /* need read/modify/write of last changed EEPROM word */
-               /* only the first byte of the word is being modified */
-
-               if (!atl1e_read_eeprom(hw, last_dword * 4,
-                               &(eeprom_buff[last_dword - first_dword]))) {
-                       ret_val = -EIO;
-                       goto out;
-               }
-       }
-
-       /* Device's eeprom is always little-endian, word addressable */
-       memcpy(ptr, bytes, eeprom->len);
-
-       for (i = 0; i < last_dword - first_dword + 1; i++) {
-               if (!atl1e_write_eeprom(hw, ((first_dword + i) * 4),
-                                 eeprom_buff[i])) {
-                       ret_val = -EIO;
-                       goto out;
-               }
-       }
-out:
-       kfree(eeprom_buff);
-       return ret_val;
-}
-
-static void atl1e_get_drvinfo(struct net_device *netdev,
-               struct ethtool_drvinfo *drvinfo)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       strncpy(drvinfo->driver,  atl1e_driver_name, 32);
-       strncpy(drvinfo->version, atl1e_driver_version, 32);
-       strncpy(drvinfo->fw_version, "L1e", 32);
-       strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
-       drvinfo->n_stats = 0;
-       drvinfo->testinfo_len = 0;
-       drvinfo->regdump_len = atl1e_get_regs_len(netdev);
-       drvinfo->eedump_len = atl1e_get_eeprom_len(netdev);
-}
-
-static void atl1e_get_wol(struct net_device *netdev,
-                         struct ethtool_wolinfo *wol)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       wol->supported = WAKE_MAGIC | WAKE_PHY;
-       wol->wolopts = 0;
-
-       if (adapter->wol & AT_WUFC_EX)
-               wol->wolopts |= WAKE_UCAST;
-       if (adapter->wol & AT_WUFC_MC)
-               wol->wolopts |= WAKE_MCAST;
-       if (adapter->wol & AT_WUFC_BC)
-               wol->wolopts |= WAKE_BCAST;
-       if (adapter->wol & AT_WUFC_MAG)
-               wol->wolopts |= WAKE_MAGIC;
-       if (adapter->wol & AT_WUFC_LNKC)
-               wol->wolopts |= WAKE_PHY;
-}
-
-static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-                           WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
-               return -EOPNOTSUPP;
-       /* these settings will always override what we currently have */
-       adapter->wol = 0;
-
-       if (wol->wolopts & WAKE_MAGIC)
-               adapter->wol |= AT_WUFC_MAG;
-       if (wol->wolopts & WAKE_PHY)
-               adapter->wol |= AT_WUFC_LNKC;
-
-       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
-
-       return 0;
-}
-
-static int atl1e_nway_reset(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       if (netif_running(netdev))
-               atl1e_reinit_locked(adapter);
-       return 0;
-}
-
-static const struct ethtool_ops atl1e_ethtool_ops = {
-       .get_settings           = atl1e_get_settings,
-       .set_settings           = atl1e_set_settings,
-       .get_drvinfo            = atl1e_get_drvinfo,
-       .get_regs_len           = atl1e_get_regs_len,
-       .get_regs               = atl1e_get_regs,
-       .get_wol                = atl1e_get_wol,
-       .set_wol                = atl1e_set_wol,
-       .get_msglevel           = atl1e_get_msglevel,
-       .nway_reset             = atl1e_nway_reset,
-       .get_link               = ethtool_op_get_link,
-       .get_eeprom_len         = atl1e_get_eeprom_len,
-       .get_eeprom             = atl1e_get_eeprom,
-       .set_eeprom             = atl1e_set_eeprom,
-};
-
-void atl1e_set_ethtool_ops(struct net_device *netdev)
-{
-       SET_ETHTOOL_OPS(netdev, &atl1e_ethtool_ops);
-}
diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/atl1e/atl1e_hw.c
deleted file mode 100644 (file)
index 923063d..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-/*
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/mii.h>
-#include <linux/crc32.h>
-
-#include "atl1e.h"
-
-/*
- * check_eeprom_exist
- * return 0 if eeprom exist
- */
-int atl1e_check_eeprom_exist(struct atl1e_hw *hw)
-{
-       u32 value;
-
-       value = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
-       if (value & SPI_FLASH_CTRL_EN_VPD) {
-               value &= ~SPI_FLASH_CTRL_EN_VPD;
-               AT_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
-       }
-       value = AT_READ_REGW(hw, REG_PCIE_CAP_LIST);
-       return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
-}
-
-void atl1e_hw_set_mac_addr(struct atl1e_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])) ;
-       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
-       /* hight dword */
-       value = (((u32)hw->mac_addr[0]) << 8) |
-               (((u32)hw->mac_addr[1])) ;
-       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
-}
-
-/*
- * atl1e_get_permanent_address
- * return 0 if get valid mac address,
- */
-static int atl1e_get_permanent_address(struct atl1e_hw *hw)
-{
-       u32 addr[2];
-       u32 i;
-       u32 twsi_ctrl_data;
-       u8  eth_addr[ETH_ALEN];
-
-       if (is_valid_ether_addr(hw->perm_mac_addr))
-               return 0;
-
-       /* init */
-       addr[0] = addr[1] = 0;
-
-       if (!atl1e_check_eeprom_exist(hw)) {
-               /* eeprom exist */
-               twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
-               twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
-               AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
-               for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
-                       msleep(10);
-                       twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
-                       if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
-                               break;
-               }
-               if (i >= AT_TWSI_EEPROM_TIMEOUT)
-                       return AT_ERR_TIMEOUT;
-       }
-
-       /* maybe MAC-address is from BIOS */
-       addr[0] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
-       addr[1] = AT_READ_REG(hw, 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 AT_ERR_EEPROM;
-}
-
-bool atl1e_write_eeprom(struct atl1e_hw *hw, u32 offset, u32 value)
-{
-       return true;
-}
-
-bool atl1e_read_eeprom(struct atl1e_hw *hw, u32 offset, u32 *p_value)
-{
-       int i;
-       u32 control;
-
-       if (offset & 3)
-               return false; /* address do not align */
-
-       AT_WRITE_REG(hw, REG_VPD_DATA, 0);
-       control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
-       AT_WRITE_REG(hw, REG_VPD_CAP, control);
-
-       for (i = 0; i < 10; i++) {
-               msleep(2);
-               control = AT_READ_REG(hw, REG_VPD_CAP);
-               if (control & VPD_CAP_VPD_FLAG)
-                       break;
-       }
-       if (control & VPD_CAP_VPD_FLAG) {
-               *p_value = AT_READ_REG(hw, REG_VPD_DATA);
-               return true;
-       }
-       return false; /* timeout */
-}
-
-void atl1e_force_ps(struct atl1e_hw *hw)
-{
-       AT_WRITE_REGW(hw, REG_GPHY_CTRL,
-                       GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
-}
-
-/*
- * Reads the adapter's MAC address from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- */
-int atl1e_read_mac_addr(struct atl1e_hw *hw)
-{
-       int err = 0;
-
-       err = atl1e_get_permanent_address(hw);
-       if (err)
-               return AT_ERR_EEPROM;
-       memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
-       return 0;
-}
-
-/*
- * atl1e_hash_mc_addr
- *  purpose
- *      set hash value for a multicast address
- */
-u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
-{
-       u32 crc32;
-       u32 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 atl1e_hash_set(struct atl1e_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 = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
-
-       mta |= (1 << hash_bit);
-
-       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
-}
-/*
- * Reads the value from a PHY register
- * hw - Struct containing variables accessed by shared code
- * reg_addr - address of the PHY register to read
- */
-int atl1e_read_phy_reg(struct atl1e_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;
-
-       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
-
-       wmb();
-
-       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
-               udelay(2);
-               val = AT_READ_REG(hw, REG_MDIO_CTRL);
-               if (!(val & (MDIO_START | MDIO_BUSY)))
-                       break;
-               wmb();
-       }
-       if (!(val & (MDIO_START | MDIO_BUSY))) {
-               *phy_data = (u16)val;
-               return 0;
-       }
-
-       return AT_ERR_PHY;
-}
-
-/*
- * 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
- */
-int atl1e_write_phy_reg(struct atl1e_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;
-
-       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
-       wmb();
-
-       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
-               udelay(2);
-               val = AT_READ_REG(hw, REG_MDIO_CTRL);
-               if (!(val & (MDIO_START | MDIO_BUSY)))
-                       break;
-               wmb();
-       }
-
-       if (!(val & (MDIO_START | MDIO_BUSY)))
-               return 0;
-
-       return AT_ERR_PHY;
-}
-
-/*
- * atl1e_init_pcie - init PCIE module
- */
-static void atl1e_init_pcie(struct atl1e_hw *hw)
-{
-       u32 value;
-       /* comment 2lines below to save more power when sususpend
-          value = LTSSM_TEST_MODE_DEF;
-          AT_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value);
-        */
-
-       /* pcie flow control mode change */
-       value = AT_READ_REG(hw, 0x1008);
-       value |= 0x8000;
-       AT_WRITE_REG(hw, 0x1008, value);
-}
-/*
- * Configures PHY autoneg and flow control advertisement settings
- *
- * hw - Struct containing variables accessed by shared code
- */
-static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
-{
-       s32 ret_val;
-       u16 mii_autoneg_adv_reg;
-       u16 mii_1000t_ctrl_reg;
-
-       if (0 != hw->mii_autoneg_adv_reg)
-               return 0;
-       /* Read the MII Auto-Neg Advertisement Register (Address 4/9). */
-       mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
-       mii_1000t_ctrl_reg  = MII_AT001_CR_1000T_DEFAULT_CAP_MASK;
-
-       /*
-        * Need to parse autoneg_advertised  and set up
-        * the appropriate PHY registers.  First we will parse for
-        * autoneg_advertised software override.  Since we can advertise
-        * a plethora of combinations, we need to check each bit
-        * individually.
-        */
-
-       /*
-        * 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 &= ~ADVERTISE_ALL;
-       mii_1000t_ctrl_reg  &= ~MII_AT001_CR_1000T_SPEED_MASK;
-
-       /*
-        * Need to parse MediaType and setup the
-        * appropriate PHY registers.
-        */
-       switch (hw->media_type) {
-       case MEDIA_TYPE_AUTO_SENSOR:
-               mii_autoneg_adv_reg |= ADVERTISE_ALL;
-               hw->autoneg_advertised = ADVERTISE_ALL;
-               if (hw->nic_type == athr_l1e) {
-                       mii_1000t_ctrl_reg |= ADVERTISE_1000FULL;
-                       hw->autoneg_advertised |= ADVERTISE_1000_FULL;
-               }
-               break;
-
-       case MEDIA_TYPE_100M_FULL:
-               mii_autoneg_adv_reg   |= ADVERTISE_100FULL;
-               hw->autoneg_advertised = ADVERTISE_100_FULL;
-               break;
-
-       case MEDIA_TYPE_100M_HALF:
-               mii_autoneg_adv_reg   |= ADVERTISE_100_HALF;
-               hw->autoneg_advertised = ADVERTISE_100_HALF;
-               break;
-
-       case MEDIA_TYPE_10M_FULL:
-               mii_autoneg_adv_reg   |= ADVERTISE_10_FULL;
-               hw->autoneg_advertised = ADVERTISE_10_FULL;
-               break;
-
-       default:
-               mii_autoneg_adv_reg   |= ADVERTISE_10_HALF;
-               hw->autoneg_advertised = ADVERTISE_10_HALF;
-               break;
-       }
-
-       /* flow control fixed to enable all */
-       mii_autoneg_adv_reg |= (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP);
-
-       hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
-       hw->mii_1000t_ctrl_reg  = mii_1000t_ctrl_reg;
-
-       ret_val = atl1e_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
-       if (ret_val)
-               return ret_val;
-
-       if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
-               ret_val = atl1e_write_phy_reg(hw, MII_CTRL1000,
-                                          mii_1000t_ctrl_reg);
-               if (ret_val)
-                       return ret_val;
-       }
-
-       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)
- */
-int atl1e_phy_commit(struct atl1e_hw *hw)
-{
-       struct atl1e_adapter *adapter = hw->adapter;
-       int ret_val;
-       u16 phy_data;
-
-       phy_data = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART;
-
-       ret_val = atl1e_write_phy_reg(hw, MII_BMCR, phy_data);
-       if (ret_val) {
-               u32 val;
-               int i;
-               /**************************************
-                * pcie serdes link may be down !
-                **************************************/
-               for (i = 0; i < 25; i++) {
-                       msleep(1);
-                       val = AT_READ_REG(hw, REG_MDIO_CTRL);
-                       if (!(val & (MDIO_START | MDIO_BUSY)))
-                               break;
-               }
-
-               if (0 != (val & (MDIO_START | MDIO_BUSY))) {
-                       netdev_err(adapter->netdev,
-                                  "pcie linkdown at least for 25ms\n");
-                       return ret_val;
-               }
-
-               netdev_err(adapter->netdev, "pcie linkup after %d ms\n", i);
-       }
-       return 0;
-}
-
-int atl1e_phy_init(struct atl1e_hw *hw)
-{
-       struct atl1e_adapter *adapter = hw->adapter;
-       s32 ret_val;
-       u16 phy_val;
-
-       if (hw->phy_configured) {
-               if (hw->re_autoneg) {
-                       hw->re_autoneg = false;
-                       return atl1e_restart_autoneg(hw);
-               }
-               return 0;
-       }
-
-       /* RESET GPHY Core */
-       AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
-       msleep(2);
-       AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
-                     GPHY_CTRL_EXT_RESET);
-       msleep(2);
-
-       /* patches */
-       /* p1. eable hibernation mode */
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0xB);
-       if (ret_val)
-               return ret_val;
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0xBC00);
-       if (ret_val)
-               return ret_val;
-       /* p2. set Class A/B for all modes */
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0);
-       if (ret_val)
-               return ret_val;
-       phy_val = 0x02ef;
-       /* remove Class AB */
-       /* phy_val = hw->emi_ca ? 0x02ef : 0x02df; */
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, phy_val);
-       if (ret_val)
-               return ret_val;
-       /* p3. 10B ??? */
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x12);
-       if (ret_val)
-               return ret_val;
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x4C04);
-       if (ret_val)
-               return ret_val;
-       /* p4. 1000T power */
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x4);
-       if (ret_val)
-               return ret_val;
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x8BBB);
-       if (ret_val)
-               return ret_val;
-
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x5);
-       if (ret_val)
-               return ret_val;
-       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x2C46);
-       if (ret_val)
-               return ret_val;
-
-       msleep(1);
-
-       /*Enable PHY LinkChange Interrupt */
-       ret_val = atl1e_write_phy_reg(hw, MII_INT_CTRL, 0xC00);
-       if (ret_val) {
-               netdev_err(adapter->netdev,
-                          "Error enable PHY linkChange Interrupt\n");
-               return ret_val;
-       }
-       /* setup AutoNeg parameters */
-       ret_val = atl1e_phy_setup_autoneg_adv(hw);
-       if (ret_val) {
-               netdev_err(adapter->netdev,
-                          "Error Setting up Auto-Negotiation\n");
-               return ret_val;
-       }
-       /* SW.Reset & En-Auto-Neg to restart Auto-Neg*/
-       netdev_dbg(adapter->netdev, "Restarting Auto-Negotiation\n");
-       ret_val = atl1e_phy_commit(hw);
-       if (ret_val) {
-               netdev_err(adapter->netdev, "Error resetting the phy\n");
-               return ret_val;
-       }
-
-       hw->phy_configured = true;
-
-       return 0;
-}
-
-/*
- * 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)
- */
-int atl1e_reset_hw(struct atl1e_hw *hw)
-{
-       struct atl1e_adapter *adapter = hw->adapter;
-       struct pci_dev *pdev = adapter->pdev;
-
-       u32 idle_status_data = 0;
-       u16 pci_cfg_cmd_word = 0;
-       int timeout = 0;
-
-       /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
-       pci_read_config_word(pdev, PCI_REG_COMMAND, &pci_cfg_cmd_word);
-       if ((pci_cfg_cmd_word & (CMD_IO_SPACE |
-                               CMD_MEMORY_SPACE | CMD_BUS_MASTER))
-                       != (CMD_IO_SPACE | CMD_MEMORY_SPACE | CMD_BUS_MASTER)) {
-               pci_cfg_cmd_word |= (CMD_IO_SPACE |
-                                    CMD_MEMORY_SPACE | CMD_BUS_MASTER);
-               pci_write_config_word(pdev, PCI_REG_COMMAND, pci_cfg_cmd_word);
-       }
-
-       /*
-        * 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.
-        */
-       AT_WRITE_REG(hw, REG_MASTER_CTRL,
-                       MASTER_CTRL_LED_MODE | MASTER_CTRL_SOFT_RST);
-       wmb();
-       msleep(1);
-
-       /* Wait at least 10ms for All module to be Idle */
-       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
-               idle_status_data = AT_READ_REG(hw, REG_IDLE_STATUS);
-               if (idle_status_data == 0)
-                       break;
-               msleep(1);
-               cpu_relax();
-       }
-
-       if (timeout >= AT_HW_MAX_IDLE_DELAY) {
-               netdev_err(adapter->netdev,
-                          "MAC state machine can't be idle since disabled for 10ms second\n");
-               return AT_ERR_TIMEOUT;
-       }
-
-       return 0;
-}
-
-
-/*
- * 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.
- */
-int atl1e_init_hw(struct atl1e_hw *hw)
-{
-       s32 ret_val = 0;
-
-       atl1e_init_pcie(hw);
-
-       /* Zero out the Multicast HASH table */
-       /* clear the old settings from the multicast hash table */
-       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
-       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
-
-       ret_val = atl1e_phy_init(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
- */
-int atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex)
-{
-       int err;
-       u16 phy_data;
-
-       /* Read   PHY Specific Status Register (17) */
-       err = atl1e_read_phy_reg(hw, MII_AT001_PSSR, &phy_data);
-       if (err)
-               return err;
-
-       if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED))
-               return AT_ERR_PHY_RES;
-
-       switch (phy_data & MII_AT001_PSSR_SPEED) {
-       case MII_AT001_PSSR_1000MBS:
-               *speed = SPEED_1000;
-               break;
-       case MII_AT001_PSSR_100MBS:
-               *speed = SPEED_100;
-               break;
-       case MII_AT001_PSSR_10MBS:
-               *speed = SPEED_10;
-               break;
-       default:
-               return AT_ERR_PHY_SPEED;
-               break;
-       }
-
-       if (phy_data & MII_AT001_PSSR_DPLX)
-               *duplex = FULL_DUPLEX;
-       else
-               *duplex = HALF_DUPLEX;
-
-       return 0;
-}
-
-int atl1e_restart_autoneg(struct atl1e_hw *hw)
-{
-       int err = 0;
-
-       err = atl1e_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
-       if (err)
-               return err;
-
-       if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
-               err = atl1e_write_phy_reg(hw, MII_CTRL1000,
-                                      hw->mii_1000t_ctrl_reg);
-               if (err)
-                       return err;
-       }
-
-       err = atl1e_write_phy_reg(hw, MII_BMCR,
-                       BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
-       return err;
-}
-
diff --git a/drivers/net/atl1e/atl1e_hw.h b/drivers/net/atl1e/atl1e_hw.h
deleted file mode 100644 (file)
index 74df16a..0000000
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#ifndef _ATHL1E_HW_H_
-#define _ATHL1E_HW_H_
-
-#include <linux/types.h>
-#include <linux/mii.h>
-
-struct atl1e_adapter;
-struct atl1e_hw;
-
-/* function prototype */
-s32 atl1e_reset_hw(struct atl1e_hw *hw);
-s32 atl1e_read_mac_addr(struct atl1e_hw *hw);
-s32 atl1e_init_hw(struct atl1e_hw *hw);
-s32 atl1e_phy_commit(struct atl1e_hw *hw);
-s32 atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex);
-u32 atl1e_auto_get_fc(struct atl1e_adapter *adapter, u16 duplex);
-u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr);
-void atl1e_hash_set(struct atl1e_hw *hw, u32 hash_value);
-s32 atl1e_read_phy_reg(struct atl1e_hw *hw, u16 reg_addr, u16 *phy_data);
-s32 atl1e_write_phy_reg(struct atl1e_hw *hw, u32 reg_addr, u16 phy_data);
-s32 atl1e_validate_mdi_setting(struct atl1e_hw *hw);
-void atl1e_hw_set_mac_addr(struct atl1e_hw *hw);
-bool atl1e_read_eeprom(struct atl1e_hw *hw, u32 offset, u32 *p_value);
-bool atl1e_write_eeprom(struct atl1e_hw *hw, u32 offset, u32 value);
-s32 atl1e_phy_enter_power_saving(struct atl1e_hw *hw);
-s32 atl1e_phy_leave_power_saving(struct atl1e_hw *hw);
-s32 atl1e_phy_init(struct atl1e_hw *hw);
-int atl1e_check_eeprom_exist(struct atl1e_hw *hw);
-void atl1e_force_ps(struct atl1e_hw *hw);
-s32 atl1e_restart_autoneg(struct atl1e_hw *hw);
-
-/* register definition */
-#define REG_PM_CTRLSTAT             0x44
-
-#define REG_PCIE_CAP_LIST           0x58
-
-#define REG_DEVICE_CAP              0x5C
-#define     DEVICE_CAP_MAX_PAYLOAD_MASK     0x7
-#define     DEVICE_CAP_MAX_PAYLOAD_SHIFT    0
-
-#define REG_DEVICE_CTRL             0x60
-#define     DEVICE_CTRL_MAX_PAYLOAD_MASK    0x7
-#define     DEVICE_CTRL_MAX_PAYLOAD_SHIFT   5
-#define     DEVICE_CTRL_MAX_RREQ_SZ_MASK    0x7
-#define     DEVICE_CTRL_MAX_RREQ_SZ_SHIFT   12
-
-#define REG_VPD_CAP                 0x6C
-#define     VPD_CAP_ID_MASK                 0xff
-#define     VPD_CAP_ID_SHIFT                0
-#define     VPD_CAP_NEXT_PTR_MASK           0xFF
-#define     VPD_CAP_NEXT_PTR_SHIFT          8
-#define     VPD_CAP_VPD_ADDR_MASK           0x7FFF
-#define     VPD_CAP_VPD_ADDR_SHIFT          16
-#define     VPD_CAP_VPD_FLAG                0x80000000
-
-#define REG_VPD_DATA                0x70
-
-#define REG_SPI_FLASH_CTRL          0x200
-#define     SPI_FLASH_CTRL_STS_NON_RDY      0x1
-#define     SPI_FLASH_CTRL_STS_WEN          0x2
-#define     SPI_FLASH_CTRL_STS_WPEN         0x80
-#define     SPI_FLASH_CTRL_DEV_STS_MASK     0xFF
-#define     SPI_FLASH_CTRL_DEV_STS_SHIFT    0
-#define     SPI_FLASH_CTRL_INS_MASK         0x7
-#define     SPI_FLASH_CTRL_INS_SHIFT        8
-#define     SPI_FLASH_CTRL_START            0x800
-#define     SPI_FLASH_CTRL_EN_VPD           0x2000
-#define     SPI_FLASH_CTRL_LDSTART          0x8000
-#define     SPI_FLASH_CTRL_CS_HI_MASK       0x3
-#define     SPI_FLASH_CTRL_CS_HI_SHIFT      16
-#define     SPI_FLASH_CTRL_CS_HOLD_MASK     0x3
-#define     SPI_FLASH_CTRL_CS_HOLD_SHIFT    18
-#define     SPI_FLASH_CTRL_CLK_LO_MASK      0x3
-#define     SPI_FLASH_CTRL_CLK_LO_SHIFT     20
-#define     SPI_FLASH_CTRL_CLK_HI_MASK      0x3
-#define     SPI_FLASH_CTRL_CLK_HI_SHIFT     22
-#define     SPI_FLASH_CTRL_CS_SETUP_MASK    0x3
-#define     SPI_FLASH_CTRL_CS_SETUP_SHIFT   24
-#define     SPI_FLASH_CTRL_EROM_PGSZ_MASK   0x3
-#define     SPI_FLASH_CTRL_EROM_PGSZ_SHIFT  26
-#define     SPI_FLASH_CTRL_WAIT_READY       0x10000000
-
-#define REG_SPI_ADDR                0x204
-
-#define REG_SPI_DATA                0x208
-
-#define REG_SPI_FLASH_CONFIG        0x20C
-#define     SPI_FLASH_CONFIG_LD_ADDR_MASK   0xFFFFFF
-#define     SPI_FLASH_CONFIG_LD_ADDR_SHIFT  0
-#define     SPI_FLASH_CONFIG_VPD_ADDR_MASK  0x3
-#define     SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24
-#define     SPI_FLASH_CONFIG_LD_EXIST       0x4000000
-
-
-#define REG_SPI_FLASH_OP_PROGRAM    0x210
-#define REG_SPI_FLASH_OP_SC_ERASE   0x211
-#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212
-#define REG_SPI_FLASH_OP_RDID       0x213
-#define REG_SPI_FLASH_OP_WREN       0x214
-#define REG_SPI_FLASH_OP_RDSR       0x215
-#define REG_SPI_FLASH_OP_WRSR       0x216
-#define REG_SPI_FLASH_OP_READ       0x217
-
-#define REG_TWSI_CTRL               0x218
-#define     TWSI_CTRL_LD_OFFSET_MASK        0xFF
-#define     TWSI_CTRL_LD_OFFSET_SHIFT       0
-#define     TWSI_CTRL_LD_SLV_ADDR_MASK      0x7
-#define     TWSI_CTRL_LD_SLV_ADDR_SHIFT     8
-#define     TWSI_CTRL_SW_LDSTART            0x800
-#define     TWSI_CTRL_HW_LDSTART            0x1000
-#define     TWSI_CTRL_SMB_SLV_ADDR_MASK     0x0x7F
-#define     TWSI_CTRL_SMB_SLV_ADDR_SHIFT    15
-#define     TWSI_CTRL_LD_EXIST              0x400000
-#define     TWSI_CTRL_READ_FREQ_SEL_MASK    0x3
-#define     TWSI_CTRL_READ_FREQ_SEL_SHIFT   23
-#define     TWSI_CTRL_FREQ_SEL_100K         0
-#define     TWSI_CTRL_FREQ_SEL_200K         1
-#define     TWSI_CTRL_FREQ_SEL_300K         2
-#define     TWSI_CTRL_FREQ_SEL_400K         3
-#define     TWSI_CTRL_SMB_SLV_ADDR
-#define     TWSI_CTRL_WRITE_FREQ_SEL_MASK   0x3
-#define     TWSI_CTRL_WRITE_FREQ_SEL_SHIFT  24
-
-
-#define REG_PCIE_DEV_MISC_CTRL      0x21C
-#define     PCIE_DEV_MISC_CTRL_EXT_PIPE     0x2
-#define     PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1
-#define     PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4
-#define     PCIE_DEV_MISC_CTRL_SERDES_ENDIAN    0x8
-#define     PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN   0x10
-
-#define REG_PCIE_PHYMISC           0x1000
-#define PCIE_PHYMISC_FORCE_RCV_DET     0x4
-
-#define REG_LTSSM_TEST_MODE         0x12FC
-#define         LTSSM_TEST_MODE_DEF     0xE000
-
-/* Selene Master Control Register */
-#define REG_MASTER_CTRL             0x1400
-#define     MASTER_CTRL_SOFT_RST            0x1
-#define     MASTER_CTRL_MTIMER_EN           0x2
-#define     MASTER_CTRL_ITIMER_EN           0x4
-#define     MASTER_CTRL_MANUAL_INT          0x8
-#define     MASTER_CTRL_ITIMER2_EN          0x20
-#define     MASTER_CTRL_INT_RDCLR           0x40
-#define     MASTER_CTRL_LED_MODE           0x200
-#define     MASTER_CTRL_REV_NUM_SHIFT       16
-#define     MASTER_CTRL_REV_NUM_MASK        0xff
-#define     MASTER_CTRL_DEV_ID_SHIFT        24
-#define     MASTER_CTRL_DEV_ID_MASK         0xff
-
-/* Timer Initial Value Register */
-#define REG_MANUAL_TIMER_INIT       0x1404
-
-
-/* IRQ ModeratorTimer Initial Value Register */
-#define REG_IRQ_MODU_TIMER_INIT     0x1408   /* w */
-#define REG_IRQ_MODU_TIMER2_INIT    0x140A   /* w */
-
-
-#define REG_GPHY_CTRL               0x140C
-#define     GPHY_CTRL_EXT_RESET         1
-#define     GPHY_CTRL_PIPE_MOD          2
-#define     GPHY_CTRL_TEST_MODE_MASK    3
-#define     GPHY_CTRL_TEST_MODE_SHIFT   2
-#define     GPHY_CTRL_BERT_START        0x10
-#define     GPHY_CTRL_GATE_25M_EN       0x20
-#define     GPHY_CTRL_LPW_EXIT          0x40
-#define     GPHY_CTRL_PHY_IDDQ          0x80
-#define     GPHY_CTRL_PHY_IDDQ_DIS      0x100
-#define     GPHY_CTRL_PCLK_SEL_DIS      0x200
-#define     GPHY_CTRL_HIB_EN            0x400
-#define     GPHY_CTRL_HIB_PULSE         0x800
-#define     GPHY_CTRL_SEL_ANA_RST       0x1000
-#define     GPHY_CTRL_PHY_PLL_ON        0x2000
-#define     GPHY_CTRL_PWDOWN_HW                0x4000
-#define     GPHY_CTRL_DEFAULT (\
-               GPHY_CTRL_PHY_PLL_ON    |\
-               GPHY_CTRL_SEL_ANA_RST   |\
-               GPHY_CTRL_HIB_PULSE     |\
-               GPHY_CTRL_HIB_EN)
-
-#define     GPHY_CTRL_PW_WOL_DIS (\
-               GPHY_CTRL_PHY_PLL_ON    |\
-               GPHY_CTRL_SEL_ANA_RST   |\
-               GPHY_CTRL_HIB_PULSE     |\
-               GPHY_CTRL_HIB_EN        |\
-               GPHY_CTRL_PWDOWN_HW     |\
-               GPHY_CTRL_PCLK_SEL_DIS  |\
-               GPHY_CTRL_PHY_IDDQ)
-
-/* IRQ Anti-Lost Timer Initial Value Register */
-#define REG_CMBDISDMA_TIMER         0x140E
-
-
-/* Block IDLE Status Register */
-#define REG_IDLE_STATUS        0x1410
-#define     IDLE_STATUS_RXMAC       1    /* 1: RXMAC state machine is in non-IDLE state. 0: RXMAC is idling */
-#define     IDLE_STATUS_TXMAC       2    /* 1: TXMAC state machine is in non-IDLE state. 0: TXMAC is idling */
-#define     IDLE_STATUS_RXQ         4    /* 1: RXQ state machine is in non-IDLE state.   0: RXQ is idling   */
-#define     IDLE_STATUS_TXQ         8    /* 1: TXQ state machine is in non-IDLE state.   0: TXQ is idling   */
-#define     IDLE_STATUS_DMAR        0x10 /* 1: DMAR state machine is in non-IDLE state.  0: DMAR is idling  */
-#define     IDLE_STATUS_DMAW        0x20 /* 1: DMAW state machine is in non-IDLE state.  0: DMAW is idling  */
-#define     IDLE_STATUS_SMB         0x40 /* 1: SMB state machine is in non-IDLE state.   0: SMB is idling   */
-#define     IDLE_STATUS_CMB         0x80 /* 1: CMB state machine is in non-IDLE state.   0: CMB is idling   */
-
-/* MDIO Control Register */
-#define REG_MDIO_CTRL           0x1414
-#define     MDIO_DATA_MASK          0xffff  /* On MDIO write, the 16-bit control data to write to PHY MII management register */
-#define     MDIO_DATA_SHIFT         0       /* On MDIO read, the 16-bit status data that was read from the PHY MII management register*/
-#define     MDIO_REG_ADDR_MASK      0x1f    /* MDIO register address */
-#define     MDIO_REG_ADDR_SHIFT     16
-#define     MDIO_RW                 0x200000      /* 1: read, 0: write */
-#define     MDIO_SUP_PREAMBLE       0x400000      /* Suppress preamble */
-#define     MDIO_START              0x800000      /* Write 1 to initiate the MDIO master. And this bit is self cleared after one cycle*/
-#define     MDIO_CLK_SEL_SHIFT      24
-#define     MDIO_CLK_25_4           0
-#define     MDIO_CLK_25_6           2
-#define     MDIO_CLK_25_8           3
-#define     MDIO_CLK_25_10          4
-#define     MDIO_CLK_25_14          5
-#define     MDIO_CLK_25_20          6
-#define     MDIO_CLK_25_28          7
-#define     MDIO_BUSY               0x8000000
-#define     MDIO_AP_EN              0x10000000
-#define MDIO_WAIT_TIMES         10
-
-/* MII PHY Status Register */
-#define REG_PHY_STATUS           0x1418
-#define     PHY_STATUS_100M          0x20000
-#define     PHY_STATUS_EMI_CA        0x40000
-
-/* BIST Control and Status Register0 (for the Packet Memory) */
-#define REG_BIST0_CTRL              0x141c
-#define     BIST0_NOW                   0x1 /* 1: To trigger BIST0 logic. This bit stays high during the */
-/* BIST process and reset to zero when BIST is done */
-#define     BIST0_SRAM_FAIL             0x2 /* 1: The SRAM failure is un-repairable because it has address */
-/* decoder failure or more than 1 cell stuck-to-x failure */
-#define     BIST0_FUSE_FLAG             0x4 /* 1: Indicating one cell has been fixed */
-
-/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
-#define REG_BIST1_CTRL              0x1420
-#define     BIST1_NOW                   0x1 /* 1: To trigger BIST0 logic. This bit stays high during the */
-/* BIST process and reset to zero when BIST is done */
-#define     BIST1_SRAM_FAIL             0x2 /* 1: The SRAM failure is un-repairable because it has address */
-/* decoder failure or more than 1 cell stuck-to-x failure.*/
-#define     BIST1_FUSE_FLAG             0x4
-
-/* SerDes Lock Detect Control and Status Register */
-#define REG_SERDES_LOCK             0x1424
-#define     SERDES_LOCK_DETECT          1  /* 1: SerDes lock detected . This signal comes from Analog SerDes */
-#define     SERDES_LOCK_DETECT_EN       2  /* 1: Enable SerDes Lock detect function */
-
-/* MAC Control Register  */
-#define REG_MAC_CTRL                0x1480
-#define     MAC_CTRL_TX_EN              1  /* 1: Transmit Enable */
-#define     MAC_CTRL_RX_EN              2  /* 1: Receive Enable */
-#define     MAC_CTRL_TX_FLOW            4  /* 1: Transmit Flow Control Enable */
-#define     MAC_CTRL_RX_FLOW            8  /* 1: Receive Flow Control Enable */
-#define     MAC_CTRL_LOOPBACK           0x10      /* 1: Loop back at G/MII Interface */
-#define     MAC_CTRL_DUPLX              0x20      /* 1: Full-duplex mode  0: Half-duplex mode */
-#define     MAC_CTRL_ADD_CRC            0x40      /* 1: Instruct MAC to attach CRC on all egress Ethernet frames */
-#define     MAC_CTRL_PAD                0x80      /* 1: Instruct MAC to pad short frames to 60-bytes, and then attach CRC. This bit has higher priority over CRC_EN */
-#define     MAC_CTRL_LENCHK             0x100     /* 1: Instruct MAC to check if length field matches the real packet length */
-#define     MAC_CTRL_HUGE_EN            0x200     /* 1: receive Jumbo frame enable */
-#define     MAC_CTRL_PRMLEN_SHIFT       10        /* Preamble length */
-#define     MAC_CTRL_PRMLEN_MASK        0xf
-#define     MAC_CTRL_RMV_VLAN           0x4000    /* 1: to remove VLAN Tag automatically from all receive packets */
-#define     MAC_CTRL_PROMIS_EN          0x8000    /* 1: Promiscuous Mode Enable */
-#define     MAC_CTRL_TX_PAUSE           0x10000   /* 1: transmit test pause */
-#define     MAC_CTRL_SCNT               0x20000   /* 1: shortcut slot time counter */
-#define     MAC_CTRL_SRST_TX            0x40000   /* 1: synchronized reset Transmit MAC module */
-#define     MAC_CTRL_TX_SIMURST         0x80000   /* 1: transmit simulation reset */
-#define     MAC_CTRL_SPEED_SHIFT        20        /* 10: gigabit 01:10M/100M */
-#define     MAC_CTRL_SPEED_MASK         0x300000
-#define     MAC_CTRL_SPEED_1000         2
-#define     MAC_CTRL_SPEED_10_100       1
-#define     MAC_CTRL_DBG_TX_BKPRESURE   0x400000  /* 1: transmit maximum backoff (half-duplex test bit) */
-#define     MAC_CTRL_TX_HUGE            0x800000  /* 1: transmit huge enable */
-#define     MAC_CTRL_RX_CHKSUM_EN       0x1000000 /* 1: RX checksum enable */
-#define     MAC_CTRL_MC_ALL_EN          0x2000000 /* 1: upload all multicast frame without error to system */
-#define     MAC_CTRL_BC_EN              0x4000000 /* 1: upload all broadcast frame without error to system */
-#define     MAC_CTRL_DBG                0x8000000 /* 1: upload all received frame to system (Debug Mode) */
-
-/* MAC IPG/IFG Control Register  */
-#define REG_MAC_IPG_IFG             0x1484
-#define     MAC_IPG_IFG_IPGT_SHIFT      0     /* Desired back to back inter-packet gap. The default is 96-bit time */
-#define     MAC_IPG_IFG_IPGT_MASK       0x7f
-#define     MAC_IPG_IFG_MIFG_SHIFT      8     /* Minimum number of IFG to enforce in between RX frames */
-#define     MAC_IPG_IFG_MIFG_MASK       0xff  /* Frame gap below such IFP is dropped */
-#define     MAC_IPG_IFG_IPGR1_SHIFT     16    /* 64bit Carrier-Sense window */
-#define     MAC_IPG_IFG_IPGR1_MASK      0x7f
-#define     MAC_IPG_IFG_IPGR2_SHIFT     24    /* 96-bit IPG window */
-#define     MAC_IPG_IFG_IPGR2_MASK      0x7f
-
-/* MAC STATION ADDRESS  */
-#define REG_MAC_STA_ADDR            0x1488
-
-/* Hash table for multicast address */
-#define REG_RX_HASH_TABLE           0x1490
-
-
-/* MAC Half-Duplex Control Register */
-#define REG_MAC_HALF_DUPLX_CTRL     0x1498
-#define     MAC_HALF_DUPLX_CTRL_LCOL_SHIFT   0      /* Collision Window */
-#define     MAC_HALF_DUPLX_CTRL_LCOL_MASK    0x3ff
-#define     MAC_HALF_DUPLX_CTRL_RETRY_SHIFT  12     /* Retransmission maximum, afterwards the packet will be discarded */
-#define     MAC_HALF_DUPLX_CTRL_RETRY_MASK   0xf
-#define     MAC_HALF_DUPLX_CTRL_EXC_DEF_EN   0x10000 /* 1: Allow the transmission of a packet which has been excessively deferred */
-#define     MAC_HALF_DUPLX_CTRL_NO_BACK_C    0x20000 /* 1: No back-off on collision, immediately start the retransmission */
-#define     MAC_HALF_DUPLX_CTRL_NO_BACK_P    0x40000 /* 1: No back-off on backpressure, immediately start the transmission after back pressure */
-#define     MAC_HALF_DUPLX_CTRL_ABEBE        0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
-#define     MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT  20      /* Maximum binary exponential number */
-#define     MAC_HALF_DUPLX_CTRL_ABEBT_MASK   0xf
-#define     MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24      /* IPG to start JAM for collision based flow control in half-duplex */
-#define     MAC_HALF_DUPLX_CTRL_JAMIPG_MASK  0xf     /* mode. In unit of 8-bit time */
-
-/* Maximum Frame Length Control Register   */
-#define REG_MTU                     0x149c
-
-/* Wake-On-Lan control register */
-#define REG_WOL_CTRL                0x14a0
-#define     WOL_PATTERN_EN                  0x00000001
-#define     WOL_PATTERN_PME_EN              0x00000002
-#define     WOL_MAGIC_EN                    0x00000004
-#define     WOL_MAGIC_PME_EN                0x00000008
-#define     WOL_LINK_CHG_EN                 0x00000010
-#define     WOL_LINK_CHG_PME_EN             0x00000020
-#define     WOL_PATTERN_ST                  0x00000100
-#define     WOL_MAGIC_ST                    0x00000200
-#define     WOL_LINKCHG_ST                  0x00000400
-#define     WOL_CLK_SWITCH_EN               0x00008000
-#define     WOL_PT0_EN                      0x00010000
-#define     WOL_PT1_EN                      0x00020000
-#define     WOL_PT2_EN                      0x00040000
-#define     WOL_PT3_EN                      0x00080000
-#define     WOL_PT4_EN                      0x00100000
-#define     WOL_PT5_EN                      0x00200000
-#define     WOL_PT6_EN                      0x00400000
-/* 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 Register */
-#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_ADDR          0x1530
-#define REG_SRAM_PKTH_ADDR          0x1532
-
-/* Load Ptr Register */
-#define REG_LOAD_PTR                0x1534  /* Software sets this bit after the initialization of the head and tail */
-
-/*
- * addresses of all descriptors, as well as the following descriptor
- * control register, which triggers each function block to load the head
- * pointer to prepare for the operation. This bit is then self-cleared
- * after one cycle.
- */
-
-/* Descriptor Control register  */
-#define REG_RXF3_BASE_ADDR_HI           0x153C
-#define REG_DESC_BASE_ADDR_HI           0x1540
-#define REG_RXF0_BASE_ADDR_HI           0x1540 /* share with DESC BASE ADDR HI */
-#define REG_HOST_RXF0_PAGE0_LO          0x1544
-#define REG_HOST_RXF0_PAGE1_LO          0x1548
-#define REG_TPD_BASE_ADDR_LO            0x154C
-#define REG_RXF1_BASE_ADDR_HI           0x1550
-#define REG_RXF2_BASE_ADDR_HI           0x1554
-#define REG_HOST_RXFPAGE_SIZE           0x1558
-#define REG_TPD_RING_SIZE               0x155C
-/* RSS about */
-#define REG_RSS_KEY0                    0x14B0
-#define REG_RSS_KEY1                    0x14B4
-#define REG_RSS_KEY2                    0x14B8
-#define REG_RSS_KEY3                    0x14BC
-#define REG_RSS_KEY4                    0x14C0
-#define REG_RSS_KEY5                    0x14C4
-#define REG_RSS_KEY6                    0x14C8
-#define REG_RSS_KEY7                    0x14CC
-#define REG_RSS_KEY8                    0x14D0
-#define REG_RSS_KEY9                    0x14D4
-#define REG_IDT_TABLE4                  0x14E0
-#define REG_IDT_TABLE5                  0x14E4
-#define REG_IDT_TABLE6                  0x14E8
-#define REG_IDT_TABLE7                  0x14EC
-#define REG_IDT_TABLE0                  0x1560
-#define REG_IDT_TABLE1                  0x1564
-#define REG_IDT_TABLE2                  0x1568
-#define REG_IDT_TABLE3                  0x156C
-#define REG_IDT_TABLE                   REG_IDT_TABLE0
-#define REG_RSS_HASH_VALUE              0x1570
-#define REG_RSS_HASH_FLAG               0x1574
-#define REG_BASE_CPU_NUMBER             0x157C
-
-
-/* TXQ Control Register */
-#define REG_TXQ_CTRL                0x1580
-#define     TXQ_CTRL_NUM_TPD_BURST_MASK     0xF
-#define     TXQ_CTRL_NUM_TPD_BURST_SHIFT    0
-#define     TXQ_CTRL_EN                     0x20  /* 1: Enable TXQ */
-#define     TXQ_CTRL_ENH_MODE               0x40  /* Performance enhancement mode, in which up to two back-to-back DMA read commands might be dispatched. */
-#define     TXQ_CTRL_TXF_BURST_NUM_SHIFT    16    /* Number of data byte to read in a cache-aligned burst. Each SRAM entry is 8-byte in length. */
-#define     TXQ_CTRL_TXF_BURST_NUM_MASK     0xffff
-
-/* Jumbo packet Threshold for task offload */
-#define REG_TX_EARLY_TH                     0x1584 /* Jumbo frame threshold in QWORD unit. Packet greater than */
-/* JUMBO_TASK_OFFLOAD_THRESHOLD will not be task offloaded. */
-#define     TX_TX_EARLY_TH_MASK             0x7ff
-#define     TX_TX_EARLY_TH_SHIFT            0
-
-
-/* RXQ Control Register */
-#define REG_RXQ_CTRL                0x15A0
-#define         RXQ_CTRL_PBA_ALIGN_32                   0   /* rx-packet alignment */
-#define         RXQ_CTRL_PBA_ALIGN_64                   1
-#define         RXQ_CTRL_PBA_ALIGN_128                  2
-#define         RXQ_CTRL_PBA_ALIGN_256                  3
-#define         RXQ_CTRL_Q1_EN                         0x10
-#define         RXQ_CTRL_Q2_EN                         0x20
-#define         RXQ_CTRL_Q3_EN                         0x40
-#define         RXQ_CTRL_IPV6_XSUM_VERIFY_EN           0x80
-#define         RXQ_CTRL_HASH_TLEN_SHIFT                8
-#define         RXQ_CTRL_HASH_TLEN_MASK                 0xFF
-#define         RXQ_CTRL_HASH_TYPE_IPV4                 0x10000
-#define         RXQ_CTRL_HASH_TYPE_IPV4_TCP             0x20000
-#define         RXQ_CTRL_HASH_TYPE_IPV6                 0x40000
-#define         RXQ_CTRL_HASH_TYPE_IPV6_TCP             0x80000
-#define         RXQ_CTRL_RSS_MODE_DISABLE               0
-#define         RXQ_CTRL_RSS_MODE_SQSINT                0x4000000
-#define         RXQ_CTRL_RSS_MODE_MQUESINT              0x8000000
-#define         RXQ_CTRL_RSS_MODE_MQUEMINT              0xC000000
-#define         RXQ_CTRL_NIP_QUEUE_SEL_TBL              0x10000000
-#define         RXQ_CTRL_HASH_ENABLE                    0x20000000
-#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
-/*
- * Jumbo packet threshold for non-VLAN packet, in QWORD (64-bit) unit.
- * When the packet length greater than or equal to this value, RXQ
- * shall start cut-through forwarding of the received packet.
- */
-#define         RXQ_JMBOSZ_TH_MASK      0x7ff
-#define         RXQ_JMBOSZ_TH_SHIFT         0  /* RRD retirement timer. Decrement by 1 after every 512ns passes*/
-#define         RXQ_JMBO_LKAH_MASK          0xf
-#define         RXQ_JMBO_LKAH_SHIFT         11
-
-/* RXF flow control register */
-#define REG_RXQ_RXF_PAUSE_THRESH    0x15A8
-#define     RXQ_RXF_PAUSE_TH_HI_SHIFT       0
-#define     RXQ_RXF_PAUSE_TH_HI_MASK        0xfff
-#define     RXQ_RXF_PAUSE_TH_LO_SHIFT       16
-#define     RXQ_RXF_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_REQ_PRI           0x400
-#define     DMA_CTRL_DMAR_DLY_CNT_MASK      0x1F
-#define     DMA_CTRL_DMAR_DLY_CNT_SHIFT     11
-#define     DMA_CTRL_DMAW_DLY_CNT_MASK      0xF
-#define     DMA_CTRL_DMAW_DLY_CNT_SHIFT     16
-#define     DMA_CTRL_TXCMB_EN               0x100000
-#define     DMA_CTRL_RXCMB_EN                          0x200000
-
-
-/* CMB/SMB Control Register */
-#define REG_SMB_STAT_TIMER                      0x15C4
-#define REG_TRIG_RRD_THRESH                     0x15CA
-#define REG_TRIG_TPD_THRESH                     0x15C8
-#define REG_TRIG_TXTIMER                        0x15CC
-#define REG_TRIG_RXTIMER                        0x15CE
-
-/* HOST RXF Page 1,2,3 address */
-#define REG_HOST_RXF1_PAGE0_LO                  0x15D0
-#define REG_HOST_RXF1_PAGE1_LO                  0x15D4
-#define REG_HOST_RXF2_PAGE0_LO                  0x15D8
-#define REG_HOST_RXF2_PAGE1_LO                  0x15DC
-#define REG_HOST_RXF3_PAGE0_LO                  0x15E0
-#define REG_HOST_RXF3_PAGE1_LO                  0x15E4
-
-/* Mail box */
-#define REG_MB_RXF1_RADDR                       0x15B4
-#define REG_MB_RXF2_RADDR                       0x15B8
-#define REG_MB_RXF3_RADDR                       0x15BC
-#define REG_MB_TPD_PROD_IDX                     0x15F0
-
-/* RXF-Page 0-3  PageNo & Valid bit */
-#define REG_HOST_RXF0_PAGE0_VLD     0x15F4
-#define     HOST_RXF_VALID              1
-#define     HOST_RXF_PAGENO_SHIFT       1
-#define     HOST_RXF_PAGENO_MASK        0x7F
-#define REG_HOST_RXF0_PAGE1_VLD     0x15F5
-#define REG_HOST_RXF1_PAGE0_VLD     0x15F6
-#define REG_HOST_RXF1_PAGE1_VLD     0x15F7
-#define REG_HOST_RXF2_PAGE0_VLD     0x15F8
-#define REG_HOST_RXF2_PAGE1_VLD     0x15F9
-#define REG_HOST_RXF3_PAGE0_VLD     0x15FA
-#define REG_HOST_RXF3_PAGE1_VLD     0x15FB
-
-/* Interrupt Status Register */
-#define REG_ISR    0x1600
-#define  ISR_SMB               1
-#define  ISR_TIMER             2       /* Interrupt when Timer is counted down to zero */
-/*
- * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
- * in Table 51 Selene Master Control Register (Offset 0x1400).
- */
-#define  ISR_MANUAL            4
-#define  ISR_HW_RXF_OV          8        /* RXF overflow interrupt */
-#define  ISR_HOST_RXF0_OV       0x10
-#define  ISR_HOST_RXF1_OV       0x20
-#define  ISR_HOST_RXF2_OV       0x40
-#define  ISR_HOST_RXF3_OV       0x80
-#define  ISR_TXF_UN             0x100
-#define  ISR_RX0_PAGE_FULL      0x200
-#define  ISR_DMAR_TO_RST        0x400
-#define  ISR_DMAW_TO_RST        0x800
-#define  ISR_GPHY               0x1000
-#define  ISR_TX_CREDIT          0x2000
-#define  ISR_GPHY_LPW           0x4000    /* GPHY low power state interrupt */
-#define  ISR_RX_PKT             0x10000   /* One packet received, triggered by RFD */
-#define  ISR_TX_PKT             0x20000   /* One packet transmitted, triggered by TPD */
-#define  ISR_TX_DMA             0x40000
-#define  ISR_RX_PKT_1           0x80000
-#define  ISR_RX_PKT_2           0x100000
-#define  ISR_RX_PKT_3           0x200000
-#define  ISR_MAC_RX             0x400000
-#define  ISR_MAC_TX             0x800000
-#define  ISR_UR_DETECTED        0x1000000
-#define  ISR_FERR_DETECTED      0x2000000
-#define  ISR_NFERR_DETECTED     0x4000000
-#define  ISR_CERR_DETECTED      0x8000000
-#define  ISR_PHY_LINKDOWN       0x10000000
-#define  ISR_DIS_INT            0x80000000
-
-
-/* Interrupt Mask Register */
-#define REG_IMR 0x1604
-
-
-#define IMR_NORMAL_MASK (\
-               ISR_SMB         |\
-               ISR_TXF_UN      |\
-               ISR_HW_RXF_OV   |\
-               ISR_HOST_RXF0_OV|\
-               ISR_MANUAL      |\
-               ISR_GPHY        |\
-               ISR_GPHY_LPW    |\
-               ISR_DMAR_TO_RST |\
-               ISR_DMAW_TO_RST |\
-               ISR_PHY_LINKDOWN|\
-               ISR_RX_PKT      |\
-               ISR_TX_PKT)
-
-#define ISR_TX_EVENT (ISR_TXF_UN | ISR_TX_PKT)
-#define ISR_RX_EVENT (ISR_HOST_RXF0_OV | ISR_HW_RXF_OV | ISR_RX_PKT)
-
-#define REG_MAC_RX_STATUS_BIN 0x1700
-#define REG_MAC_RX_STATUS_END 0x175c
-#define REG_MAC_TX_STATUS_BIN 0x1760
-#define REG_MAC_TX_STATUS_END 0x17c0
-
-/* Hardware Offset Register */
-#define REG_HOST_RXF0_PAGEOFF 0x1800
-#define REG_TPD_CONS_IDX      0x1804
-#define REG_HOST_RXF1_PAGEOFF 0x1808
-#define REG_HOST_RXF2_PAGEOFF 0x180C
-#define REG_HOST_RXF3_PAGEOFF 0x1810
-
-/* RXF-Page 0-3 Offset DMA Address */
-#define REG_HOST_RXF0_MB0_LO  0x1820
-#define REG_HOST_RXF0_MB1_LO  0x1824
-#define REG_HOST_RXF1_MB0_LO  0x1828
-#define REG_HOST_RXF1_MB1_LO  0x182C
-#define REG_HOST_RXF2_MB0_LO  0x1830
-#define REG_HOST_RXF2_MB1_LO  0x1834
-#define REG_HOST_RXF3_MB0_LO  0x1838
-#define REG_HOST_RXF3_MB1_LO  0x183C
-
-/* Tpd CMB DMA Address */
-#define REG_HOST_TX_CMB_LO    0x1840
-#define REG_HOST_SMB_ADDR_LO  0x1844
-
-/* DEBUG ADDR */
-#define REG_DEBUG_DATA0 0x1900
-#define REG_DEBUG_DATA1 0x1904
-
-/***************************** MII definition ***************************************/
-/* PHY Common Register */
-#define MII_AT001_PSCR                  0x10
-#define MII_AT001_PSSR                  0x11
-#define MII_INT_CTRL                    0x12
-#define MII_INT_STATUS                  0x13
-#define MII_SMARTSPEED                  0x14
-#define MII_LBRERROR                    0x18
-#define MII_RESV2                       0x1a
-
-#define MII_DBG_ADDR                   0x1D
-#define MII_DBG_DATA                   0x1E
-
-/* Autoneg Advertisement Register */
-#define MII_AR_DEFAULT_CAP_MASK                 0
-
-/* 1000BASE-T Control Register */
-#define MII_AT001_CR_1000T_SPEED_MASK \
-       (ADVERTISE_1000FULL | ADVERTISE_1000HALF)
-#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK    MII_AT001_CR_1000T_SPEED_MASK
-
-/* AT001 PHY Specific Control Register */
-#define MII_AT001_PSCR_JABBER_DISABLE           0x0001  /* 1=Jabber Function disabled */
-#define MII_AT001_PSCR_POLARITY_REVERSAL        0x0002  /* 1=Polarity Reversal enabled */
-#define MII_AT001_PSCR_SQE_TEST                 0x0004  /* 1=SQE Test enabled */
-#define MII_AT001_PSCR_MAC_POWERDOWN            0x0008
-#define MII_AT001_PSCR_CLK125_DISABLE           0x0010  /* 1=CLK125 low,
-                                                        * 0=CLK125 toggling
-                                                        */
-#define MII_AT001_PSCR_MDI_MANUAL_MODE          0x0000  /* MDI Crossover Mode bits 6:5 */
-/* Manual MDI configuration */
-#define MII_AT001_PSCR_MDIX_MANUAL_MODE         0x0020  /* Manual MDIX configuration */
-#define MII_AT001_PSCR_AUTO_X_1000T             0x0040  /* 1000BASE-T: Auto crossover,
-                                                        *  100BASE-TX/10BASE-T:
-                                                        *  MDI Mode
-                                                        */
-#define MII_AT001_PSCR_AUTO_X_MODE              0x0060  /* Auto crossover enabled
-                                                        * all speeds.
-                                                        */
-#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE     0x0080
-/* 1=Enable Extended 10BASE-T distance
- * (Lower 10BASE-T RX Threshold)
- * 0=Normal 10BASE-T RX Threshold */
-#define MII_AT001_PSCR_MII_5BIT_ENABLE          0x0100
-/* 1=5-Bit interface in 100BASE-TX
- * 0=MII interface in 100BASE-TX */
-#define MII_AT001_PSCR_SCRAMBLER_DISABLE        0x0200  /* 1=Scrambler disable */
-#define MII_AT001_PSCR_FORCE_LINK_GOOD          0x0400  /* 1=Force link good */
-#define MII_AT001_PSCR_ASSERT_CRS_ON_TX         0x0800  /* 1=Assert CRS on Transmit */
-#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT    1
-#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT          5
-#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
-/* AT001 PHY Specific Status Register */
-#define MII_AT001_PSSR_SPD_DPLX_RESOLVED        0x0800  /* 1=Speed & Duplex resolved */
-#define MII_AT001_PSSR_DPLX                     0x2000  /* 1=Duplex 0=Half Duplex */
-#define MII_AT001_PSSR_SPEED                    0xC000  /* Speed, bits 14:15 */
-#define MII_AT001_PSSR_10MBS                    0x0000  /* 00=10Mbs */
-#define MII_AT001_PSSR_100MBS                   0x4000  /* 01=100Mbs */
-#define MII_AT001_PSSR_1000MBS                  0x8000  /* 10=1000Mbs */
-
-#endif /*_ATHL1E_HW_H_*/
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
deleted file mode 100644 (file)
index d8d4119..0000000
+++ /dev/null
@@ -1,2558 +0,0 @@
-/*
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#include "atl1e.h"
-
-#define DRV_VERSION "1.0.0.7-NAPI"
-
-char atl1e_driver_name[] = "ATL1E";
-char atl1e_driver_version[] = DRV_VERSION;
-#define PCI_DEVICE_ID_ATTANSIC_L1E      0x1026
-/*
- * atl1e_pci_tbl - PCI Device ID Table
- *
- * Wildcard entries (PCI_ANY_ID) should come last
- * Last entry must be all 0s
- *
- * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
- *   Class, Class Mask, private data (not used) }
- */
-static DEFINE_PCI_DEVICE_TABLE(atl1e_pci_tbl) = {
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
-       /* required last entry */
-       { 0 }
-};
-MODULE_DEVICE_TABLE(pci, atl1e_pci_tbl);
-
-MODULE_AUTHOR("Atheros Corporation, <xiong.huang@atheros.com>, Jie Yang <jie.yang@atheros.com>");
-MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-
-static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter);
-
-static const u16
-atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
-{
-       {REG_HOST_RXF0_PAGE0_VLD, REG_HOST_RXF0_PAGE1_VLD},
-       {REG_HOST_RXF1_PAGE0_VLD, REG_HOST_RXF1_PAGE1_VLD},
-       {REG_HOST_RXF2_PAGE0_VLD, REG_HOST_RXF2_PAGE1_VLD},
-       {REG_HOST_RXF3_PAGE0_VLD, REG_HOST_RXF3_PAGE1_VLD}
-};
-
-static const u16 atl1e_rx_page_hi_addr_regs[AT_MAX_RECEIVE_QUEUE] =
-{
-       REG_RXF0_BASE_ADDR_HI,
-       REG_RXF1_BASE_ADDR_HI,
-       REG_RXF2_BASE_ADDR_HI,
-       REG_RXF3_BASE_ADDR_HI
-};
-
-static const u16
-atl1e_rx_page_lo_addr_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
-{
-       {REG_HOST_RXF0_PAGE0_LO, REG_HOST_RXF0_PAGE1_LO},
-       {REG_HOST_RXF1_PAGE0_LO, REG_HOST_RXF1_PAGE1_LO},
-       {REG_HOST_RXF2_PAGE0_LO, REG_HOST_RXF2_PAGE1_LO},
-       {REG_HOST_RXF3_PAGE0_LO, REG_HOST_RXF3_PAGE1_LO}
-};
-
-static const u16
-atl1e_rx_page_write_offset_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
-{
-       {REG_HOST_RXF0_MB0_LO,  REG_HOST_RXF0_MB1_LO},
-       {REG_HOST_RXF1_MB0_LO,  REG_HOST_RXF1_MB1_LO},
-       {REG_HOST_RXF2_MB0_LO,  REG_HOST_RXF2_MB1_LO},
-       {REG_HOST_RXF3_MB0_LO,  REG_HOST_RXF3_MB1_LO}
-};
-
-static const u16 atl1e_pay_load_size[] = {
-       128, 256, 512, 1024, 2048, 4096,
-};
-
-/*
- * atl1e_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- */
-static inline void atl1e_irq_enable(struct atl1e_adapter *adapter)
-{
-       if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
-               AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
-               AT_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK);
-               AT_WRITE_FLUSH(&adapter->hw);
-       }
-}
-
-/*
- * atl1e_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- */
-static inline void atl1e_irq_disable(struct atl1e_adapter *adapter)
-{
-       atomic_inc(&adapter->irq_sem);
-       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
-       AT_WRITE_FLUSH(&adapter->hw);
-       synchronize_irq(adapter->pdev->irq);
-}
-
-/*
- * atl1e_irq_reset - reset interrupt confiure on the NIC
- * @adapter: board private structure
- */
-static inline void atl1e_irq_reset(struct atl1e_adapter *adapter)
-{
-       atomic_set(&adapter->irq_sem, 0);
-       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
-       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
-       AT_WRITE_FLUSH(&adapter->hw);
-}
-
-/*
- * atl1e_phy_config - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl1e_phy_config(unsigned long data)
-{
-       struct atl1e_adapter *adapter = (struct atl1e_adapter *) data;
-       struct atl1e_hw *hw = &adapter->hw;
-       unsigned long flags;
-
-       spin_lock_irqsave(&adapter->mdio_lock, flags);
-       atl1e_restart_autoneg(hw);
-       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
-}
-
-void atl1e_reinit_locked(struct atl1e_adapter *adapter)
-{
-
-       WARN_ON(in_interrupt());
-       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
-               msleep(1);
-       atl1e_down(adapter);
-       atl1e_up(adapter);
-       clear_bit(__AT_RESETTING, &adapter->flags);
-}
-
-static void atl1e_reset_task(struct work_struct *work)
-{
-       struct atl1e_adapter *adapter;
-       adapter = container_of(work, struct atl1e_adapter, reset_task);
-
-       atl1e_reinit_locked(adapter);
-}
-
-static int atl1e_check_link(struct atl1e_adapter *adapter)
-{
-       struct atl1e_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       int err = 0;
-       u16 speed, duplex, phy_data;
-
-       /* MII_BMSR must read twice */
-       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
-       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
-       if ((phy_data & BMSR_LSTATUS) == 0) {
-               /* link down */
-               if (netif_carrier_ok(netdev)) { /* old link state: Up */
-                       u32 value;
-                       /* disable rx */
-                       value = AT_READ_REG(hw, REG_MAC_CTRL);
-                       value &= ~MAC_CTRL_RX_EN;
-                       AT_WRITE_REG(hw, REG_MAC_CTRL, value);
-                       adapter->link_speed = SPEED_0;
-                       netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
-               }
-       } else {
-               /* Link Up */
-               err = atl1e_get_speed_and_duplex(hw, &speed, &duplex);
-               if (unlikely(err))
-                       return err;
-
-               /* link result is our setting */
-               if (adapter->link_speed != speed ||
-                   adapter->link_duplex != duplex) {
-                       adapter->link_speed  = speed;
-                       adapter->link_duplex = duplex;
-                       atl1e_setup_mac_ctrl(adapter);
-                       netdev_info(netdev,
-                                   "NIC Link is Up <%d Mbps %s Duplex>\n",
-                                   adapter->link_speed,
-                                   adapter->link_duplex == FULL_DUPLEX ?
-                                   "Full" : "Half");
-               }
-
-               if (!netif_carrier_ok(netdev)) {
-                       /* Link down -> Up */
-                       netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
-               }
-       }
-       return 0;
-}
-
-/*
- * atl1e_link_chg_task - deal with link change event Out of interrupt context
- * @netdev: network interface device structure
- */
-static void atl1e_link_chg_task(struct work_struct *work)
-{
-       struct atl1e_adapter *adapter;
-       unsigned long flags;
-
-       adapter = container_of(work, struct atl1e_adapter, link_chg_task);
-       spin_lock_irqsave(&adapter->mdio_lock, flags);
-       atl1e_check_link(adapter);
-       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
-}
-
-static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       u16 phy_data = 0;
-       u16 link_up = 0;
-
-       spin_lock(&adapter->mdio_lock);
-       atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-       atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-       spin_unlock(&adapter->mdio_lock);
-       link_up = phy_data & BMSR_LSTATUS;
-       /* notify upper layer link down ASAP */
-       if (!link_up) {
-               if (netif_carrier_ok(netdev)) {
-                       /* old link state: Up */
-                       netdev_info(netdev, "NIC Link is Down\n");
-                       adapter->link_speed = SPEED_0;
-                       netif_stop_queue(netdev);
-               }
-       }
-       schedule_work(&adapter->link_chg_task);
-}
-
-static void atl1e_del_timer(struct atl1e_adapter *adapter)
-{
-       del_timer_sync(&adapter->phy_config_timer);
-}
-
-static void atl1e_cancel_work(struct atl1e_adapter *adapter)
-{
-       cancel_work_sync(&adapter->reset_task);
-       cancel_work_sync(&adapter->link_chg_task);
-}
-
-/*
- * atl1e_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- */
-static void atl1e_tx_timeout(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       /* Do the reset outside of interrupt context */
-       schedule_work(&adapter->reset_task);
-}
-
-/*
- * atl1e_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 atl1e_set_multi(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-       struct netdev_hw_addr *ha;
-       u32 mac_ctrl_data = 0;
-       u32 hash_value;
-
-       /* Check for Promiscuous and All Multicast modes */
-       mac_ctrl_data = AT_READ_REG(hw, REG_MAC_CTRL);
-
-       if (netdev->flags & IFF_PROMISC) {
-               mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
-       } else if (netdev->flags & IFF_ALLMULTI) {
-               mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
-               mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
-       } else {
-               mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
-       }
-
-       AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-
-       /* clear the old settings from the multicast hash table */
-       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
-       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
-
-       /* comoute mc addresses' hash value ,and put it into hash table */
-       netdev_for_each_mc_addr(ha, netdev) {
-               hash_value = atl1e_hash_mc_addr(hw, ha->addr);
-               atl1e_hash_set(hw, hash_value);
-       }
-}
-
-static void __atl1e_vlan_mode(u32 features, u32 *mac_ctrl_data)
-{
-       if (features & NETIF_F_HW_VLAN_RX) {
-               /* enable VLAN tag insert/strip */
-               *mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
-       } else {
-               /* disable VLAN tag insert/strip */
-               *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
-       }
-}
-
-static void atl1e_vlan_mode(struct net_device *netdev, u32 features)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       u32 mac_ctrl_data = 0;
-
-       netdev_dbg(adapter->netdev, "%s\n", __func__);
-
-       atl1e_irq_disable(adapter);
-       mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
-       __atl1e_vlan_mode(features, &mac_ctrl_data);
-       AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
-       atl1e_irq_enable(adapter);
-}
-
-static void atl1e_restore_vlan(struct atl1e_adapter *adapter)
-{
-       netdev_dbg(adapter->netdev, "%s\n", __func__);
-       atl1e_vlan_mode(adapter->netdev, adapter->netdev->features);
-}
-
-/*
- * atl1e_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 atl1e_set_mac_addr(struct net_device *netdev, void *p)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct sockaddr *addr = p;
-
-       if (!is_valid_ether_addr(addr->sa_data))
-               return -EADDRNOTAVAIL;
-
-       if (netif_running(netdev))
-               return -EBUSY;
-
-       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
-
-       atl1e_hw_set_mac_addr(&adapter->hw);
-
-       return 0;
-}
-
-static u32 atl1e_fix_features(struct net_device *netdev, u32 features)
-{
-       /*
-        * Since there is no support for separate rx/tx vlan accel
-        * enable/disable make sure tx flag is always in same state as rx.
-        */
-       if (features & NETIF_F_HW_VLAN_RX)
-               features |= NETIF_F_HW_VLAN_TX;
-       else
-               features &= ~NETIF_F_HW_VLAN_TX;
-
-       return features;
-}
-
-static int atl1e_set_features(struct net_device *netdev, u32 features)
-{
-       u32 changed = netdev->features ^ features;
-
-       if (changed & NETIF_F_HW_VLAN_RX)
-               atl1e_vlan_mode(netdev, features);
-
-       return 0;
-}
-
-/*
- * atl1e_change_mtu - Change the Maximum Transfer Unit
- * @netdev: network interface device structure
- * @new_mtu: new value for maximum frame size
- *
- * Returns 0 on success, negative on failure
- */
-static int atl1e_change_mtu(struct net_device *netdev, int new_mtu)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       int old_mtu   = netdev->mtu;
-       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-
-       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
-                       (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-               netdev_warn(adapter->netdev, "invalid MTU setting\n");
-               return -EINVAL;
-       }
-       /* set MTU */
-       if (old_mtu != new_mtu && netif_running(netdev)) {
-               while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
-                       msleep(1);
-               netdev->mtu = new_mtu;
-               adapter->hw.max_frame_size = new_mtu;
-               adapter->hw.rx_jumbo_th = (max_frame + 7) >> 3;
-               atl1e_down(adapter);
-               atl1e_up(adapter);
-               clear_bit(__AT_RESETTING, &adapter->flags);
-       }
-       return 0;
-}
-
-/*
- *  caller should hold mdio_lock
- */
-static int atl1e_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       u16 result;
-
-       atl1e_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
-       return result;
-}
-
-static void atl1e_mdio_write(struct net_device *netdev, int phy_id,
-                            int reg_num, int val)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       atl1e_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
-}
-
-/*
- * atl1e_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1e_mii_ioctl(struct net_device *netdev,
-                          struct ifreq *ifr, int cmd)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct mii_ioctl_data *data = if_mii(ifr);
-       unsigned long flags;
-       int retval = 0;
-
-       if (!netif_running(netdev))
-               return -EINVAL;
-
-       spin_lock_irqsave(&adapter->mdio_lock, flags);
-       switch (cmd) {
-       case SIOCGMIIPHY:
-               data->phy_id = 0;
-               break;
-
-       case SIOCGMIIREG:
-               if (atl1e_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
-                                   &data->val_out)) {
-                       retval = -EIO;
-                       goto out;
-               }
-               break;
-
-       case SIOCSMIIREG:
-               if (data->reg_num & ~(0x1F)) {
-                       retval = -EFAULT;
-                       goto out;
-               }
-
-               netdev_dbg(adapter->netdev, "<atl1e_mii_ioctl> write %x %x\n",
-                          data->reg_num, data->val_in);
-               if (atl1e_write_phy_reg(&adapter->hw,
-                                    data->reg_num, data->val_in)) {
-                       retval = -EIO;
-                       goto out;
-               }
-               break;
-
-       default:
-               retval = -EOPNOTSUPP;
-               break;
-       }
-out:
-       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
-       return retval;
-
-}
-
-/*
- * atl1e_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-       switch (cmd) {
-       case SIOCGMIIPHY:
-       case SIOCGMIIREG:
-       case SIOCSMIIREG:
-               return atl1e_mii_ioctl(netdev, ifr, cmd);
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-static void atl1e_setup_pcicmd(struct pci_dev *pdev)
-{
-       u16 cmd;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-       cmd &= ~(PCI_COMMAND_INTX_DISABLE | PCI_COMMAND_IO);
-       cmd |=  (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-       pci_write_config_word(pdev, PCI_COMMAND, cmd);
-
-       /*
-        * some motherboards BIOS(PXE/EFI) driver may set PME
-        * while they transfer control to OS (Windows/Linux)
-        * so we should clear this bit before NIC work normally
-        */
-       pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0);
-       msleep(1);
-}
-
-/*
- * atl1e_alloc_queues - Allocate memory for all rings
- * @adapter: board private structure to initialize
- *
- */
-static int __devinit atl1e_alloc_queues(struct atl1e_adapter *adapter)
-{
-       return 0;
-}
-
-/*
- * atl1e_sw_init - Initialize general software structures (struct atl1e_adapter)
- * @adapter: board private structure to initialize
- *
- * atl1e_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 __devinit atl1e_sw_init(struct atl1e_adapter *adapter)
-{
-       struct atl1e_hw *hw   = &adapter->hw;
-       struct pci_dev  *pdev = adapter->pdev;
-       u32 phy_status_data = 0;
-
-       adapter->wol = 0;
-       adapter->link_speed = SPEED_0;   /* hardware init */
-       adapter->link_duplex = FULL_DUPLEX;
-       adapter->num_rx_queues = 1;
-
-       /* PCI config space info */
-       hw->vendor_id = pdev->vendor;
-       hw->device_id = pdev->device;
-       hw->subsystem_vendor_id = pdev->subsystem_vendor;
-       hw->subsystem_id = pdev->subsystem_device;
-       hw->revision_id  = pdev->revision;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
-
-       phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
-       /* nic type */
-       if (hw->revision_id >= 0xF0) {
-               hw->nic_type = athr_l2e_revB;
-       } else {
-               if (phy_status_data & PHY_STATUS_100M)
-                       hw->nic_type = athr_l1e;
-               else
-                       hw->nic_type = athr_l2e_revA;
-       }
-
-       phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
-
-       if (phy_status_data & PHY_STATUS_EMI_CA)
-               hw->emi_ca = true;
-       else
-               hw->emi_ca = false;
-
-       hw->phy_configured = false;
-       hw->preamble_len = 7;
-       hw->max_frame_size = adapter->netdev->mtu;
-       hw->rx_jumbo_th = (hw->max_frame_size + ETH_HLEN +
-                               VLAN_HLEN + ETH_FCS_LEN + 7) >> 3;
-
-       hw->rrs_type = atl1e_rrs_disable;
-       hw->indirect_tab = 0;
-       hw->base_cpu = 0;
-
-       /* need confirm */
-
-       hw->ict = 50000;                 /* 100ms */
-       hw->smb_timer = 200000;          /* 200ms  */
-       hw->tpd_burst = 5;
-       hw->rrd_thresh = 1;
-       hw->tpd_thresh = adapter->tx_ring.count / 2;
-       hw->rx_count_down = 4;  /* 2us resolution */
-       hw->tx_count_down = hw->imt * 4 / 3;
-       hw->dmar_block = atl1e_dma_req_1024;
-       hw->dmaw_block = atl1e_dma_req_1024;
-       hw->dmar_dly_cnt = 15;
-       hw->dmaw_dly_cnt = 4;
-
-       if (atl1e_alloc_queues(adapter)) {
-               netdev_err(adapter->netdev, "Unable to allocate memory for queues\n");
-               return -ENOMEM;
-       }
-
-       atomic_set(&adapter->irq_sem, 1);
-       spin_lock_init(&adapter->mdio_lock);
-       spin_lock_init(&adapter->tx_lock);
-
-       set_bit(__AT_DOWN, &adapter->flags);
-
-       return 0;
-}
-
-/*
- * atl1e_clean_tx_ring - Free Tx-skb
- * @adapter: board private structure
- */
-static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
-{
-       struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
-                               &adapter->tx_ring;
-       struct atl1e_tx_buffer *tx_buffer = NULL;
-       struct pci_dev *pdev = adapter->pdev;
-       u16 index, ring_count;
-
-       if (tx_ring->desc == NULL || tx_ring->tx_buffer == NULL)
-               return;
-
-       ring_count = tx_ring->count;
-       /* first unmmap dma */
-       for (index = 0; index < ring_count; index++) {
-               tx_buffer = &tx_ring->tx_buffer[index];
-               if (tx_buffer->dma) {
-                       if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
-                               pci_unmap_single(pdev, tx_buffer->dma,
-                                       tx_buffer->length, PCI_DMA_TODEVICE);
-                       else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
-                               pci_unmap_page(pdev, tx_buffer->dma,
-                                       tx_buffer->length, PCI_DMA_TODEVICE);
-                       tx_buffer->dma = 0;
-               }
-       }
-       /* second free skb */
-       for (index = 0; index < ring_count; index++) {
-               tx_buffer = &tx_ring->tx_buffer[index];
-               if (tx_buffer->skb) {
-                       dev_kfree_skb_any(tx_buffer->skb);
-                       tx_buffer->skb = NULL;
-               }
-       }
-       /* Zero out Tx-buffers */
-       memset(tx_ring->desc, 0, sizeof(struct atl1e_tpd_desc) *
-                               ring_count);
-       memset(tx_ring->tx_buffer, 0, sizeof(struct atl1e_tx_buffer) *
-                               ring_count);
-}
-
-/*
- * atl1e_clean_rx_ring - Free rx-reservation skbs
- * @adapter: board private structure
- */
-static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter)
-{
-       struct atl1e_rx_ring *rx_ring =
-               (struct atl1e_rx_ring *)&adapter->rx_ring;
-       struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc;
-       u16 i, j;
-
-
-       if (adapter->ring_vir_addr == NULL)
-               return;
-       /* Zero out the descriptor ring */
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
-                       if (rx_page_desc[i].rx_page[j].addr != NULL) {
-                               memset(rx_page_desc[i].rx_page[j].addr, 0,
-                                               rx_ring->real_page_size);
-                       }
-               }
-       }
-}
-
-static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size)
-{
-       *ring_size = ((u32)(adapter->tx_ring.count *
-                    sizeof(struct atl1e_tpd_desc) + 7
-                       /* tx ring, qword align */
-                    + adapter->rx_ring.real_page_size * AT_PAGE_NUM_PER_QUEUE *
-                       adapter->num_rx_queues + 31
-                       /* rx ring,  32 bytes align */
-                    + (1 + AT_PAGE_NUM_PER_QUEUE * adapter->num_rx_queues) *
-                       sizeof(u32) + 3));
-                       /* tx, rx cmd, dword align   */
-}
-
-static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
-{
-       struct atl1e_rx_ring *rx_ring = NULL;
-
-       rx_ring = &adapter->rx_ring;
-
-       rx_ring->real_page_size = adapter->rx_ring.page_size
-                                + adapter->hw.max_frame_size
-                                + ETH_HLEN + VLAN_HLEN
-                                + ETH_FCS_LEN;
-       rx_ring->real_page_size = roundup(rx_ring->real_page_size, 32);
-       atl1e_cal_ring_size(adapter, &adapter->ring_size);
-
-       adapter->ring_vir_addr = NULL;
-       adapter->rx_ring.desc = NULL;
-       rwlock_init(&adapter->tx_ring.tx_lock);
-}
-
-/*
- * Read / Write Ptr Initialize:
- */
-static void atl1e_init_ring_ptrs(struct atl1e_adapter *adapter)
-{
-       struct atl1e_tx_ring *tx_ring = NULL;
-       struct atl1e_rx_ring *rx_ring = NULL;
-       struct atl1e_rx_page_desc *rx_page_desc = NULL;
-       int i, j;
-
-       tx_ring = &adapter->tx_ring;
-       rx_ring = &adapter->rx_ring;
-       rx_page_desc = rx_ring->rx_page_desc;
-
-       tx_ring->next_to_use = 0;
-       atomic_set(&tx_ring->next_to_clean, 0);
-
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               rx_page_desc[i].rx_using  = 0;
-               rx_page_desc[i].rx_nxseq = 0;
-               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
-                       *rx_page_desc[i].rx_page[j].write_offset_addr = 0;
-                       rx_page_desc[i].rx_page[j].read_offset = 0;
-               }
-       }
-}
-
-/*
- * atl1e_free_ring_resources - Free Tx / RX descriptor Resources
- * @adapter: board private structure
- *
- * Free all transmit software resources
- */
-static void atl1e_free_ring_resources(struct atl1e_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-
-       atl1e_clean_tx_ring(adapter);
-       atl1e_clean_rx_ring(adapter);
-
-       if (adapter->ring_vir_addr) {
-               pci_free_consistent(pdev, adapter->ring_size,
-                               adapter->ring_vir_addr, adapter->ring_dma);
-               adapter->ring_vir_addr = NULL;
-       }
-
-       if (adapter->tx_ring.tx_buffer) {
-               kfree(adapter->tx_ring.tx_buffer);
-               adapter->tx_ring.tx_buffer = NULL;
-       }
-}
-
-/*
- * atl1e_setup_mem_resources - allocate Tx / RX descriptor resources
- * @adapter: board private structure
- *
- * Return 0 on success, negative on failure
- */
-static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       struct atl1e_tx_ring *tx_ring;
-       struct atl1e_rx_ring *rx_ring;
-       struct atl1e_rx_page_desc  *rx_page_desc;
-       int size, i, j;
-       u32 offset = 0;
-       int err = 0;
-
-       if (adapter->ring_vir_addr != NULL)
-               return 0; /* alloced already */
-
-       tx_ring = &adapter->tx_ring;
-       rx_ring = &adapter->rx_ring;
-
-       /* real ring DMA buffer */
-
-       size = adapter->ring_size;
-       adapter->ring_vir_addr = pci_alloc_consistent(pdev,
-                       adapter->ring_size, &adapter->ring_dma);
-
-       if (adapter->ring_vir_addr == NULL) {
-               netdev_err(adapter->netdev,
-                          "pci_alloc_consistent failed, size = D%d\n", size);
-               return -ENOMEM;
-       }
-
-       memset(adapter->ring_vir_addr, 0, adapter->ring_size);
-
-       rx_page_desc = rx_ring->rx_page_desc;
-
-       /* Init TPD Ring */
-       tx_ring->dma = roundup(adapter->ring_dma, 8);
-       offset = tx_ring->dma - adapter->ring_dma;
-       tx_ring->desc = adapter->ring_vir_addr + offset;
-       size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count);
-       tx_ring->tx_buffer = kzalloc(size, GFP_KERNEL);
-       if (tx_ring->tx_buffer == NULL) {
-               netdev_err(adapter->netdev, "kzalloc failed, size = D%d\n",
-                          size);
-               err = -ENOMEM;
-               goto failed;
-       }
-
-       /* Init RXF-Pages */
-       offset += (sizeof(struct atl1e_tpd_desc) * tx_ring->count);
-       offset = roundup(offset, 32);
-
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
-                       rx_page_desc[i].rx_page[j].dma =
-                               adapter->ring_dma + offset;
-                       rx_page_desc[i].rx_page[j].addr =
-                               adapter->ring_vir_addr + offset;
-                       offset += rx_ring->real_page_size;
-               }
-       }
-
-       /* Init CMB dma address */
-       tx_ring->cmb_dma = adapter->ring_dma + offset;
-       tx_ring->cmb = adapter->ring_vir_addr + offset;
-       offset += sizeof(u32);
-
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
-                       rx_page_desc[i].rx_page[j].write_offset_dma =
-                               adapter->ring_dma + offset;
-                       rx_page_desc[i].rx_page[j].write_offset_addr =
-                               adapter->ring_vir_addr + offset;
-                       offset += sizeof(u32);
-               }
-       }
-
-       if (unlikely(offset > adapter->ring_size)) {
-               netdev_err(adapter->netdev, "offset(%d) > ring size(%d) !!\n",
-                          offset, adapter->ring_size);
-               err = -1;
-               goto failed;
-       }
-
-       return 0;
-failed:
-       if (adapter->ring_vir_addr != NULL) {
-               pci_free_consistent(pdev, adapter->ring_size,
-                               adapter->ring_vir_addr, adapter->ring_dma);
-               adapter->ring_vir_addr = NULL;
-       }
-       return err;
-}
-
-static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter)
-{
-
-       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
-       struct atl1e_rx_ring *rx_ring =
-                       (struct atl1e_rx_ring *)&adapter->rx_ring;
-       struct atl1e_tx_ring *tx_ring =
-                       (struct atl1e_tx_ring *)&adapter->tx_ring;
-       struct atl1e_rx_page_desc *rx_page_desc = NULL;
-       int i, j;
-
-       AT_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI,
-                       (u32)((adapter->ring_dma & AT_DMA_HI_ADDR_MASK) >> 32));
-       AT_WRITE_REG(hw, REG_TPD_BASE_ADDR_LO,
-                       (u32)((tx_ring->dma) & AT_DMA_LO_ADDR_MASK));
-       AT_WRITE_REG(hw, REG_TPD_RING_SIZE, (u16)(tx_ring->count));
-       AT_WRITE_REG(hw, REG_HOST_TX_CMB_LO,
-                       (u32)((tx_ring->cmb_dma) & AT_DMA_LO_ADDR_MASK));
-
-       rx_page_desc = rx_ring->rx_page_desc;
-       /* RXF Page Physical address / Page Length */
-       for (i = 0; i < AT_MAX_RECEIVE_QUEUE; i++) {
-               AT_WRITE_REG(hw, atl1e_rx_page_hi_addr_regs[i],
-                                (u32)((adapter->ring_dma &
-                                AT_DMA_HI_ADDR_MASK) >> 32));
-               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
-                       u32 page_phy_addr;
-                       u32 offset_phy_addr;
-
-                       page_phy_addr = rx_page_desc[i].rx_page[j].dma;
-                       offset_phy_addr =
-                                  rx_page_desc[i].rx_page[j].write_offset_dma;
-
-                       AT_WRITE_REG(hw, atl1e_rx_page_lo_addr_regs[i][j],
-                                       page_phy_addr & AT_DMA_LO_ADDR_MASK);
-                       AT_WRITE_REG(hw, atl1e_rx_page_write_offset_regs[i][j],
-                                       offset_phy_addr & AT_DMA_LO_ADDR_MASK);
-                       AT_WRITE_REGB(hw, atl1e_rx_page_vld_regs[i][j], 1);
-               }
-       }
-       /* Page Length */
-       AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size);
-       /* Load all of base address above */
-       AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
-}
-
-static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
-{
-       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
-       u32 dev_ctrl_data = 0;
-       u32 max_pay_load = 0;
-       u32 jumbo_thresh = 0;
-       u32 extra_size = 0;     /* Jumbo frame threshold in QWORD unit */
-
-       /* configure TXQ param */
-       if (hw->nic_type != athr_l2e_revB) {
-               extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
-               if (hw->max_frame_size <= 1500) {
-                       jumbo_thresh = hw->max_frame_size + extra_size;
-               } else if (hw->max_frame_size < 6*1024) {
-                       jumbo_thresh =
-                               (hw->max_frame_size + extra_size) * 2 / 3;
-               } else {
-                       jumbo_thresh = (hw->max_frame_size + extra_size) / 2;
-               }
-               AT_WRITE_REG(hw, REG_TX_EARLY_TH, (jumbo_thresh + 7) >> 3);
-       }
-
-       dev_ctrl_data = AT_READ_REG(hw, REG_DEVICE_CTRL);
-
-       max_pay_load  = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) &
-                       DEVICE_CTRL_MAX_PAYLOAD_MASK;
-
-       hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
-
-       max_pay_load  = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) &
-                       DEVICE_CTRL_MAX_RREQ_SZ_MASK;
-       hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
-
-       if (hw->nic_type != athr_l2e_revB)
-               AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2,
-                             atl1e_pay_load_size[hw->dmar_block]);
-       /* enable TXQ */
-       AT_WRITE_REGW(hw, REG_TXQ_CTRL,
-                       (((u16)hw->tpd_burst & TXQ_CTRL_NUM_TPD_BURST_MASK)
-                        << TXQ_CTRL_NUM_TPD_BURST_SHIFT)
-                       | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN);
-}
-
-static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
-{
-       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
-       u32 rxf_len  = 0;
-       u32 rxf_low  = 0;
-       u32 rxf_high = 0;
-       u32 rxf_thresh_data = 0;
-       u32 rxq_ctrl_data = 0;
-
-       if (hw->nic_type != athr_l2e_revB) {
-               AT_WRITE_REGW(hw, REG_RXQ_JMBOSZ_RRDTIM,
-                             (u16)((hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) <<
-                             RXQ_JMBOSZ_TH_SHIFT |
-                             (1 & RXQ_JMBO_LKAH_MASK) <<
-                             RXQ_JMBO_LKAH_SHIFT));
-
-               rxf_len  = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
-               rxf_high = rxf_len * 4 / 5;
-               rxf_low  = rxf_len / 5;
-               rxf_thresh_data = ((rxf_high  & RXQ_RXF_PAUSE_TH_HI_MASK)
-                                 << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
-                                 ((rxf_low & RXQ_RXF_PAUSE_TH_LO_MASK)
-                                 << RXQ_RXF_PAUSE_TH_LO_SHIFT);
-
-               AT_WRITE_REG(hw, REG_RXQ_RXF_PAUSE_THRESH, rxf_thresh_data);
-       }
-
-       /* RRS */
-       AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
-       AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
-
-       if (hw->rrs_type & atl1e_rrs_ipv4)
-               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4;
-
-       if (hw->rrs_type & atl1e_rrs_ipv4_tcp)
-               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4_TCP;
-
-       if (hw->rrs_type & atl1e_rrs_ipv6)
-               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6;
-
-       if (hw->rrs_type & atl1e_rrs_ipv6_tcp)
-               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6_TCP;
-
-       if (hw->rrs_type != atl1e_rrs_disable)
-               rxq_ctrl_data |=
-                       (RXQ_CTRL_HASH_ENABLE | RXQ_CTRL_RSS_MODE_MQUESINT);
-
-       rxq_ctrl_data |= RXQ_CTRL_IPV6_XSUM_VERIFY_EN | RXQ_CTRL_PBA_ALIGN_32 |
-                        RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
-
-       AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
-}
-
-static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
-{
-       struct atl1e_hw *hw = &adapter->hw;
-       u32 dma_ctrl_data = 0;
-
-       dma_ctrl_data = DMA_CTRL_RXCMB_EN;
-       dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
-               << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
-       dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
-               << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
-       dma_ctrl_data |= DMA_CTRL_DMAR_REQ_PRI | DMA_CTRL_DMAR_OUT_ORDER;
-       dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
-               << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
-       dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
-               << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
-
-       AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
-}
-
-static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
-{
-       u32 value;
-       struct atl1e_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-
-       /* Config MAC CTRL Register */
-       value = MAC_CTRL_TX_EN |
-               MAC_CTRL_RX_EN ;
-
-       if (FULL_DUPLEX == adapter->link_duplex)
-               value |= MAC_CTRL_DUPLX;
-
-       value |= ((u32)((SPEED_1000 == adapter->link_speed) ?
-                         MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) <<
-                         MAC_CTRL_SPEED_SHIFT);
-       value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
-
-       value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
-       value |= (((u32)adapter->hw.preamble_len &
-                 MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
-
-       __atl1e_vlan_mode(netdev->features, &value);
-
-       value |= MAC_CTRL_BC_EN;
-       if (netdev->flags & IFF_PROMISC)
-               value |= MAC_CTRL_PROMIS_EN;
-       if (netdev->flags & IFF_ALLMULTI)
-               value |= MAC_CTRL_MC_ALL_EN;
-
-       AT_WRITE_REG(hw, REG_MAC_CTRL, value);
-}
-
-/*
- * atl1e_configure - Configure Transmit&Receive Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx /Rx unit of the MAC after a reset.
- */
-static int atl1e_configure(struct atl1e_adapter *adapter)
-{
-       struct atl1e_hw *hw = &adapter->hw;
-
-       u32 intr_status_data = 0;
-
-       /* clear interrupt status */
-       AT_WRITE_REG(hw, REG_ISR, ~0);
-
-       /* 1. set MAC Address */
-       atl1e_hw_set_mac_addr(hw);
-
-       /* 2. Init the Multicast HASH table done by set_muti */
-
-       /* 3. Clear any WOL status */
-       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
-
-       /* 4. Descripter Ring BaseMem/Length/Read ptr/Write ptr
-        *    TPD Ring/SMB/RXF0 Page CMBs, they use the same
-        *    High 32bits memory */
-       atl1e_configure_des_ring(adapter);
-
-       /* 5. set Interrupt Moderator Timer */
-       AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, hw->imt);
-       AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER2_INIT, hw->imt);
-       AT_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_LED_MODE |
-                       MASTER_CTRL_ITIMER_EN | MASTER_CTRL_ITIMER2_EN);
-
-       /* 6. rx/tx threshold to trig interrupt */
-       AT_WRITE_REGW(hw, REG_TRIG_RRD_THRESH, hw->rrd_thresh);
-       AT_WRITE_REGW(hw, REG_TRIG_TPD_THRESH, hw->tpd_thresh);
-       AT_WRITE_REGW(hw, REG_TRIG_RXTIMER, hw->rx_count_down);
-       AT_WRITE_REGW(hw, REG_TRIG_TXTIMER, hw->tx_count_down);
-
-       /* 7. set Interrupt Clear Timer */
-       AT_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, hw->ict);
-
-       /* 8. set MTU */
-       AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
-                       VLAN_HLEN + ETH_FCS_LEN);
-
-       /* 9. config TXQ early tx threshold */
-       atl1e_configure_tx(adapter);
-
-       /* 10. config RXQ */
-       atl1e_configure_rx(adapter);
-
-       /* 11. config  DMA Engine */
-       atl1e_configure_dma(adapter);
-
-       /* 12. smb timer to trig interrupt */
-       AT_WRITE_REG(hw, REG_SMB_STAT_TIMER, hw->smb_timer);
-
-       intr_status_data = AT_READ_REG(hw, REG_ISR);
-       if (unlikely((intr_status_data & ISR_PHY_LINKDOWN) != 0)) {
-               netdev_err(adapter->netdev,
-                          "atl1e_configure failed, PCIE phy link down\n");
-               return -1;
-       }
-
-       AT_WRITE_REG(hw, REG_ISR, 0x7fffffff);
-       return 0;
-}
-
-/*
- * atl1e_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 *atl1e_get_stats(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw_stats  *hw_stats = &adapter->hw_stats;
-       struct net_device_stats *net_stats = &netdev->stats;
-
-       net_stats->rx_packets = hw_stats->rx_ok;
-       net_stats->tx_packets = hw_stats->tx_ok;
-       net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
-       net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
-       net_stats->multicast  = hw_stats->rx_mcast;
-       net_stats->collisions = hw_stats->tx_1_col +
-                               hw_stats->tx_2_col * 2 +
-                               hw_stats->tx_late_col + hw_stats->tx_abort_col;
-
-       net_stats->rx_errors  = hw_stats->rx_frag + hw_stats->rx_fcs_err +
-                               hw_stats->rx_len_err + hw_stats->rx_sz_ov +
-                               hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
-       net_stats->rx_fifo_errors   = hw_stats->rx_rxf_ov;
-       net_stats->rx_length_errors = hw_stats->rx_len_err;
-       net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
-       net_stats->rx_frame_errors  = hw_stats->rx_align_err;
-       net_stats->rx_over_errors   = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
-
-       net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
-
-       net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
-                              hw_stats->tx_underrun + hw_stats->tx_trunc;
-       net_stats->tx_fifo_errors    = hw_stats->tx_underrun;
-       net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
-       net_stats->tx_window_errors  = hw_stats->tx_late_col;
-
-       return net_stats;
-}
-
-static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
-{
-       u16 hw_reg_addr = 0;
-       unsigned long *stats_item = NULL;
-
-       /* update rx status */
-       hw_reg_addr = REG_MAC_RX_STATUS_BIN;
-       stats_item  = &adapter->hw_stats.rx_ok;
-       while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
-               *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
-               stats_item++;
-               hw_reg_addr += 4;
-       }
-       /* update tx status */
-       hw_reg_addr = REG_MAC_TX_STATUS_BIN;
-       stats_item  = &adapter->hw_stats.tx_ok;
-       while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
-               *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
-               stats_item++;
-               hw_reg_addr += 4;
-       }
-}
-
-static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter)
-{
-       u16 phy_data;
-
-       spin_lock(&adapter->mdio_lock);
-       atl1e_read_phy_reg(&adapter->hw, MII_INT_STATUS, &phy_data);
-       spin_unlock(&adapter->mdio_lock);
-}
-
-static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
-{
-       struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
-                                       &adapter->tx_ring;
-       struct atl1e_tx_buffer *tx_buffer = NULL;
-       u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX);
-       u16 next_to_clean = atomic_read(&tx_ring->next_to_clean);
-
-       while (next_to_clean != hw_next_to_clean) {
-               tx_buffer = &tx_ring->tx_buffer[next_to_clean];
-               if (tx_buffer->dma) {
-                       if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
-                               pci_unmap_single(adapter->pdev, tx_buffer->dma,
-                                       tx_buffer->length, PCI_DMA_TODEVICE);
-                       else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
-                               pci_unmap_page(adapter->pdev, tx_buffer->dma,
-                                       tx_buffer->length, PCI_DMA_TODEVICE);
-                       tx_buffer->dma = 0;
-               }
-
-               if (tx_buffer->skb) {
-                       dev_kfree_skb_irq(tx_buffer->skb);
-                       tx_buffer->skb = NULL;
-               }
-
-               if (++next_to_clean == tx_ring->count)
-                       next_to_clean = 0;
-       }
-
-       atomic_set(&tx_ring->next_to_clean, next_to_clean);
-
-       if (netif_queue_stopped(adapter->netdev) &&
-                       netif_carrier_ok(adapter->netdev)) {
-               netif_wake_queue(adapter->netdev);
-       }
-
-       return true;
-}
-
-/*
- * atl1e_intr - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
- */
-static irqreturn_t atl1e_intr(int irq, void *data)
-{
-       struct net_device *netdev  = data;
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-       int max_ints = AT_MAX_INT_WORK;
-       int handled = IRQ_NONE;
-       u32 status;
-
-       do {
-               status = AT_READ_REG(hw, REG_ISR);
-               if ((status & IMR_NORMAL_MASK) == 0 ||
-                               (status & ISR_DIS_INT) != 0) {
-                       if (max_ints != AT_MAX_INT_WORK)
-                               handled = IRQ_HANDLED;
-                       break;
-               }
-               /* link event */
-               if (status & ISR_GPHY)
-                       atl1e_clear_phy_int(adapter);
-               /* Ack ISR */
-               AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
-
-               handled = IRQ_HANDLED;
-               /* check if PCIE PHY Link down */
-               if (status & ISR_PHY_LINKDOWN) {
-                       netdev_err(adapter->netdev,
-                                  "pcie phy linkdown %x\n", status);
-                       if (netif_running(adapter->netdev)) {
-                               /* reset MAC */
-                               atl1e_irq_reset(adapter);
-                               schedule_work(&adapter->reset_task);
-                               break;
-                       }
-               }
-
-               /* check if DMA read/write error */
-               if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
-                       netdev_err(adapter->netdev,
-                                  "PCIE DMA RW error (status = 0x%x)\n",
-                                  status);
-                       atl1e_irq_reset(adapter);
-                       schedule_work(&adapter->reset_task);
-                       break;
-               }
-
-               if (status & ISR_SMB)
-                       atl1e_update_hw_stats(adapter);
-
-               /* link event */
-               if (status & (ISR_GPHY | ISR_MANUAL)) {
-                       netdev->stats.tx_carrier_errors++;
-                       atl1e_link_chg_event(adapter);
-                       break;
-               }
-
-               /* transmit event */
-               if (status & ISR_TX_EVENT)
-                       atl1e_clean_tx_irq(adapter);
-
-               if (status & ISR_RX_EVENT) {
-                       /*
-                        * disable rx interrupts, without
-                        * the synchronize_irq bit
-                        */
-                       AT_WRITE_REG(hw, REG_IMR,
-                                    IMR_NORMAL_MASK & ~ISR_RX_EVENT);
-                       AT_WRITE_FLUSH(hw);
-                       if (likely(napi_schedule_prep(
-                                  &adapter->napi)))
-                               __napi_schedule(&adapter->napi);
-               }
-       } while (--max_ints > 0);
-       /* re-enable Interrupt*/
-       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
-
-       return handled;
-}
-
-static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
-                 struct sk_buff *skb, struct atl1e_recv_ret_status *prrs)
-{
-       u8 *packet = (u8 *)(prrs + 1);
-       struct iphdr *iph;
-       u16 head_len = ETH_HLEN;
-       u16 pkt_flags;
-       u16 err_flags;
-
-       skb_checksum_none_assert(skb);
-       pkt_flags = prrs->pkt_flag;
-       err_flags = prrs->err_flag;
-       if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
-               ((pkt_flags & RRS_IS_TCP) || (pkt_flags & RRS_IS_UDP))) {
-               if (pkt_flags & RRS_IS_IPV4) {
-                       if (pkt_flags & RRS_IS_802_3)
-                               head_len += 8;
-                       iph = (struct iphdr *) (packet + head_len);
-                       if (iph->frag_off != 0 && !(pkt_flags & RRS_IS_IP_DF))
-                               goto hw_xsum;
-               }
-               if (!(err_flags & (RRS_ERR_IP_CSUM | RRS_ERR_L4_CSUM))) {
-                       skb->ip_summed = CHECKSUM_UNNECESSARY;
-                       return;
-               }
-       }
-
-hw_xsum :
-       return;
-}
-
-static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter,
-                                              u8 que)
-{
-       struct atl1e_rx_page_desc *rx_page_desc =
-               (struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc;
-       u8 rx_using = rx_page_desc[que].rx_using;
-
-       return (struct atl1e_rx_page *)&(rx_page_desc[que].rx_page[rx_using]);
-}
-
-static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
-                  int *work_done, int work_to_do)
-{
-       struct net_device *netdev  = adapter->netdev;
-       struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *)
-                                        &adapter->rx_ring;
-       struct atl1e_rx_page_desc *rx_page_desc =
-               (struct atl1e_rx_page_desc *) rx_ring->rx_page_desc;
-       struct sk_buff *skb = NULL;
-       struct atl1e_rx_page *rx_page = atl1e_get_rx_page(adapter, que);
-       u32 packet_size, write_offset;
-       struct atl1e_recv_ret_status *prrs;
-
-       write_offset = *(rx_page->write_offset_addr);
-       if (likely(rx_page->read_offset < write_offset)) {
-               do {
-                       if (*work_done >= work_to_do)
-                               break;
-                       (*work_done)++;
-                       /* get new packet's  rrs */
-                       prrs = (struct atl1e_recv_ret_status *) (rx_page->addr +
-                                                rx_page->read_offset);
-                       /* check sequence number */
-                       if (prrs->seq_num != rx_page_desc[que].rx_nxseq) {
-                               netdev_err(netdev,
-                                          "rx sequence number error (rx=%d) (expect=%d)\n",
-                                          prrs->seq_num,
-                                          rx_page_desc[que].rx_nxseq);
-                               rx_page_desc[que].rx_nxseq++;
-                               /* just for debug use */
-                               AT_WRITE_REG(&adapter->hw, REG_DEBUG_DATA0,
-                                            (((u32)prrs->seq_num) << 16) |
-                                            rx_page_desc[que].rx_nxseq);
-                               goto fatal_err;
-                       }
-                       rx_page_desc[que].rx_nxseq++;
-
-                       /* error packet */
-                       if (prrs->pkt_flag & RRS_IS_ERR_FRAME) {
-                               if (prrs->err_flag & (RRS_ERR_BAD_CRC |
-                                       RRS_ERR_DRIBBLE | RRS_ERR_CODE |
-                                       RRS_ERR_TRUNC)) {
-                               /* hardware error, discard this packet*/
-                                       netdev_err(netdev,
-                                                  "rx packet desc error %x\n",
-                                                  *((u32 *)prrs + 1));
-                                       goto skip_pkt;
-                               }
-                       }
-
-                       packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
-                                       RRS_PKT_SIZE_MASK) - 4; /* CRC */
-                       skb = netdev_alloc_skb_ip_align(netdev, packet_size);
-                       if (skb == NULL) {
-                               netdev_warn(netdev,
-                                           "Memory squeeze, deferring packet\n");
-                               goto skip_pkt;
-                       }
-                       memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
-                       skb_put(skb, packet_size);
-                       skb->protocol = eth_type_trans(skb, netdev);
-                       atl1e_rx_checksum(adapter, skb, prrs);
-
-                       if (prrs->pkt_flag & RRS_IS_VLAN_TAG) {
-                               u16 vlan_tag = (prrs->vtag >> 4) |
-                                              ((prrs->vtag & 7) << 13) |
-                                              ((prrs->vtag & 8) << 9);
-                               netdev_dbg(netdev,
-                                          "RXD VLAN TAG<RRD>=0x%04x\n",
-                                          prrs->vtag);
-                               __vlan_hwaccel_put_tag(skb, vlan_tag);
-                       }
-                       netif_receive_skb(skb);
-
-skip_pkt:
-       /* skip current packet whether it's ok or not. */
-                       rx_page->read_offset +=
-                               (((u32)((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
-                               RRS_PKT_SIZE_MASK) +
-                               sizeof(struct atl1e_recv_ret_status) + 31) &
-                                               0xFFFFFFE0);
-
-                       if (rx_page->read_offset >= rx_ring->page_size) {
-                               /* mark this page clean */
-                               u16 reg_addr;
-                               u8  rx_using;
-
-                               rx_page->read_offset =
-                                       *(rx_page->write_offset_addr) = 0;
-                               rx_using = rx_page_desc[que].rx_using;
-                               reg_addr =
-                                       atl1e_rx_page_vld_regs[que][rx_using];
-                               AT_WRITE_REGB(&adapter->hw, reg_addr, 1);
-                               rx_page_desc[que].rx_using ^= 1;
-                               rx_page = atl1e_get_rx_page(adapter, que);
-                       }
-                       write_offset = *(rx_page->write_offset_addr);
-               } while (rx_page->read_offset < write_offset);
-       }
-
-       return;
-
-fatal_err:
-       if (!test_bit(__AT_DOWN, &adapter->flags))
-               schedule_work(&adapter->reset_task);
-}
-
-/*
- * atl1e_clean - NAPI Rx polling callback
- * @adapter: board private structure
- */
-static int atl1e_clean(struct napi_struct *napi, int budget)
-{
-       struct atl1e_adapter *adapter =
-                       container_of(napi, struct atl1e_adapter, napi);
-       u32 imr_data;
-       int work_done = 0;
-
-       /* Keep link state information with original netdev */
-       if (!netif_carrier_ok(adapter->netdev))
-               goto quit_polling;
-
-       atl1e_clean_rx_irq(adapter, 0, &work_done, budget);
-
-       /* If no Tx and not enough Rx work done, exit the polling mode */
-       if (work_done < budget) {
-quit_polling:
-               napi_complete(napi);
-               imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
-               AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
-               /* test debug */
-               if (test_bit(__AT_DOWN, &adapter->flags)) {
-                       atomic_dec(&adapter->irq_sem);
-                       netdev_err(adapter->netdev,
-                                  "atl1e_clean is called when AT_DOWN\n");
-               }
-               /* reenable RX intr */
-               /*atl1e_irq_enable(adapter); */
-
-       }
-       return work_done;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void atl1e_netpoll(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       disable_irq(adapter->pdev->irq);
-       atl1e_intr(adapter->pdev->irq, netdev);
-       enable_irq(adapter->pdev->irq);
-}
-#endif
-
-static inline u16 atl1e_tpd_avail(struct atl1e_adapter *adapter)
-{
-       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
-       u16 next_to_use = 0;
-       u16 next_to_clean = 0;
-
-       next_to_clean = atomic_read(&tx_ring->next_to_clean);
-       next_to_use   = tx_ring->next_to_use;
-
-       return (u16)(next_to_clean > next_to_use) ?
-               (next_to_clean - next_to_use - 1) :
-               (tx_ring->count + next_to_clean - next_to_use - 1);
-}
-
-/*
- * get next usable tpd
- * Note: should call atl1e_tdp_avail to make sure
- * there is enough tpd to use
- */
-static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter)
-{
-       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
-       u16 next_to_use = 0;
-
-       next_to_use = tx_ring->next_to_use;
-       if (++tx_ring->next_to_use == tx_ring->count)
-               tx_ring->next_to_use = 0;
-
-       memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc));
-       return (struct atl1e_tpd_desc *)&tx_ring->desc[next_to_use];
-}
-
-static struct atl1e_tx_buffer *
-atl1e_get_tx_buffer(struct atl1e_adapter *adapter, struct atl1e_tpd_desc *tpd)
-{
-       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
-
-       return &tx_ring->tx_buffer[tpd - tx_ring->desc];
-}
-
-/* Calculate the transmit packet descript needed*/
-static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
-{
-       int i = 0;
-       u16 tpd_req = 1;
-       u16 fg_size = 0;
-       u16 proto_hdr_len = 0;
-
-       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-               fg_size = skb_shinfo(skb)->frags[i].size;
-               tpd_req += ((fg_size + MAX_TX_BUF_LEN - 1) >> MAX_TX_BUF_SHIFT);
-       }
-
-       if (skb_is_gso(skb)) {
-               if (skb->protocol == htons(ETH_P_IP) ||
-                  (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
-                       proto_hdr_len = skb_transport_offset(skb) +
-                                       tcp_hdrlen(skb);
-                       if (proto_hdr_len < skb_headlen(skb)) {
-                               tpd_req += ((skb_headlen(skb) - proto_hdr_len +
-                                          MAX_TX_BUF_LEN - 1) >>
-                                          MAX_TX_BUF_SHIFT);
-                       }
-               }
-
-       }
-       return tpd_req;
-}
-
-static int atl1e_tso_csum(struct atl1e_adapter *adapter,
-                      struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
-{
-       u8 hdr_len;
-       u32 real_len;
-       unsigned short offload_type;
-       int err;
-
-       if (skb_is_gso(skb)) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (unlikely(err))
-                               return -1;
-               }
-               offload_type = skb_shinfo(skb)->gso_type;
-
-               if (offload_type & SKB_GSO_TCPV4) {
-                       real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
-                                       + ntohs(ip_hdr(skb)->tot_len));
-
-                       if (real_len < skb->len)
-                               pskb_trim(skb, real_len);
-
-                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
-                       if (unlikely(skb->len == hdr_len)) {
-                               /* only xsum need */
-                               netdev_warn(adapter->netdev,
-                                           "IPV4 tso with zero data??\n");
-                               goto check_sum;
-                       } else {
-                               ip_hdr(skb)->check = 0;
-                               ip_hdr(skb)->tot_len = 0;
-                               tcp_hdr(skb)->check = ~csum_tcpudp_magic(
-                                                       ip_hdr(skb)->saddr,
-                                                       ip_hdr(skb)->daddr,
-                                                       0, IPPROTO_TCP, 0);
-                               tpd->word3 |= (ip_hdr(skb)->ihl &
-                                       TDP_V4_IPHL_MASK) <<
-                                       TPD_V4_IPHL_SHIFT;
-                               tpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
-                                       TPD_TCPHDRLEN_MASK) <<
-                                       TPD_TCPHDRLEN_SHIFT;
-                               tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
-                                       TPD_MSS_MASK) << TPD_MSS_SHIFT;
-                               tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
-                       }
-                       return 0;
-               }
-       }
-
-check_sum:
-       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-               u8 css, cso;
-
-               cso = skb_checksum_start_offset(skb);
-               if (unlikely(cso & 0x1)) {
-                       netdev_err(adapter->netdev,
-                                  "payload offset should not ant event number\n");
-                       return -1;
-               } else {
-                       css = cso + skb->csum_offset;
-                       tpd->word3 |= (cso & TPD_PLOADOFFSET_MASK) <<
-                                       TPD_PLOADOFFSET_SHIFT;
-                       tpd->word3 |= (css & TPD_CCSUMOFFSET_MASK) <<
-                                       TPD_CCSUMOFFSET_SHIFT;
-                       tpd->word3 |= 1 << TPD_CC_SEGMENT_EN_SHIFT;
-               }
-       }
-
-       return 0;
-}
-
-static void atl1e_tx_map(struct atl1e_adapter *adapter,
-                     struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
-{
-       struct atl1e_tpd_desc *use_tpd = NULL;
-       struct atl1e_tx_buffer *tx_buffer = NULL;
-       u16 buf_len = skb_headlen(skb);
-       u16 map_len = 0;
-       u16 mapped_len = 0;
-       u16 hdr_len = 0;
-       u16 nr_frags;
-       u16 f;
-       int segment;
-
-       nr_frags = skb_shinfo(skb)->nr_frags;
-       segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
-       if (segment) {
-               /* TSO */
-               map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-               use_tpd = tpd;
-
-               tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
-               tx_buffer->length = map_len;
-               tx_buffer->dma = pci_map_single(adapter->pdev,
-                                       skb->data, hdr_len, PCI_DMA_TODEVICE);
-               ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
-               mapped_len += map_len;
-               use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
-               use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
-                       ((cpu_to_le32(tx_buffer->length) &
-                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
-       }
-
-       while (mapped_len < buf_len) {
-               /* mapped_len == 0, means we should use the first tpd,
-                  which is given by caller  */
-               if (mapped_len == 0) {
-                       use_tpd = tpd;
-               } else {
-                       use_tpd = atl1e_get_tpd(adapter);
-                       memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
-               }
-               tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
-               tx_buffer->skb = NULL;
-
-               tx_buffer->length = map_len =
-                       ((buf_len - mapped_len) >= MAX_TX_BUF_LEN) ?
-                       MAX_TX_BUF_LEN : (buf_len - mapped_len);
-               tx_buffer->dma =
-                       pci_map_single(adapter->pdev, skb->data + mapped_len,
-                                       map_len, PCI_DMA_TODEVICE);
-               ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
-               mapped_len  += map_len;
-               use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
-               use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
-                       ((cpu_to_le32(tx_buffer->length) &
-                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
-       }
-
-       for (f = 0; f < nr_frags; f++) {
-               struct skb_frag_struct *frag;
-               u16 i;
-               u16 seg_num;
-
-               frag = &skb_shinfo(skb)->frags[f];
-               buf_len = frag->size;
-
-               seg_num = (buf_len + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
-               for (i = 0; i < seg_num; i++) {
-                       use_tpd = atl1e_get_tpd(adapter);
-                       memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
-
-                       tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
-                       BUG_ON(tx_buffer->skb);
-
-                       tx_buffer->skb = NULL;
-                       tx_buffer->length =
-                               (buf_len > MAX_TX_BUF_LEN) ?
-                               MAX_TX_BUF_LEN : buf_len;
-                       buf_len -= tx_buffer->length;
-
-                       tx_buffer->dma =
-                               pci_map_page(adapter->pdev, frag->page,
-                                               frag->page_offset +
-                                               (i * MAX_TX_BUF_LEN),
-                                               tx_buffer->length,
-                                               PCI_DMA_TODEVICE);
-                       ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
-                       use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
-                       use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
-                                       ((cpu_to_le32(tx_buffer->length) &
-                                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
-               }
-       }
-
-       if ((tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK)
-               /* note this one is a tcp header */
-               tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
-       /* The last tpd */
-
-       use_tpd->word3 |= 1 << TPD_EOP_SHIFT;
-       /* The last buffer info contain the skb address,
-          so it will be free after unmap */
-       tx_buffer->skb = skb;
-}
-
-static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
-                          struct atl1e_tpd_desc *tpd)
-{
-       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
-       /* Force memory writes to complete before letting h/w
-        * know there are new descriptors to fetch.  (Only
-        * applicable for weak-ordered memory model archs,
-        * such as IA-64). */
-       wmb();
-       AT_WRITE_REG(&adapter->hw, REG_MB_TPD_PROD_IDX, tx_ring->next_to_use);
-}
-
-static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
-                                         struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       unsigned long flags;
-       u16 tpd_req = 1;
-       struct atl1e_tpd_desc *tpd;
-
-       if (test_bit(__AT_DOWN, &adapter->flags)) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       if (unlikely(skb->len <= 0)) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-       tpd_req = atl1e_cal_tdp_req(skb);
-       if (!spin_trylock_irqsave(&adapter->tx_lock, flags))
-               return NETDEV_TX_LOCKED;
-
-       if (atl1e_tpd_avail(adapter) < tpd_req) {
-               /* no enough descriptor, just stop queue */
-               netif_stop_queue(netdev);
-               spin_unlock_irqrestore(&adapter->tx_lock, flags);
-               return NETDEV_TX_BUSY;
-       }
-
-       tpd = atl1e_get_tpd(adapter);
-
-       if (vlan_tx_tag_present(skb)) {
-               u16 vlan_tag = vlan_tx_tag_get(skb);
-               u16 atl1e_vlan_tag;
-
-               tpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
-               AT_VLAN_TAG_TO_TPD_TAG(vlan_tag, atl1e_vlan_tag);
-               tpd->word2 |= (atl1e_vlan_tag & TPD_VLANTAG_MASK) <<
-                               TPD_VLAN_SHIFT;
-       }
-
-       if (skb->protocol == htons(ETH_P_8021Q))
-               tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
-
-       if (skb_network_offset(skb) != ETH_HLEN)
-               tpd->word3 |= 1 << TPD_ETHTYPE_SHIFT; /* 802.3 frame */
-
-       /* do TSO and check sum */
-       if (atl1e_tso_csum(adapter, skb, tpd) != 0) {
-               spin_unlock_irqrestore(&adapter->tx_lock, flags);
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       atl1e_tx_map(adapter, skb, tpd);
-       atl1e_tx_queue(adapter, tpd_req, tpd);
-
-       netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
-       spin_unlock_irqrestore(&adapter->tx_lock, flags);
-       return NETDEV_TX_OK;
-}
-
-static void atl1e_free_irq(struct atl1e_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       free_irq(adapter->pdev->irq, netdev);
-
-       if (adapter->have_msi)
-               pci_disable_msi(adapter->pdev);
-}
-
-static int atl1e_request_irq(struct atl1e_adapter *adapter)
-{
-       struct pci_dev    *pdev   = adapter->pdev;
-       struct net_device *netdev = adapter->netdev;
-       int flags = 0;
-       int err = 0;
-
-       adapter->have_msi = true;
-       err = pci_enable_msi(adapter->pdev);
-       if (err) {
-               netdev_dbg(adapter->netdev,
-                          "Unable to allocate MSI interrupt Error: %d\n", err);
-               adapter->have_msi = false;
-       } else
-               netdev->irq = pdev->irq;
-
-
-       if (!adapter->have_msi)
-               flags |= IRQF_SHARED;
-       err = request_irq(adapter->pdev->irq, atl1e_intr, flags,
-                       netdev->name, netdev);
-       if (err) {
-               netdev_dbg(adapter->netdev,
-                          "Unable to allocate interrupt Error: %d\n", err);
-               if (adapter->have_msi)
-                       pci_disable_msi(adapter->pdev);
-               return err;
-       }
-       netdev_dbg(adapter->netdev, "atl1e_request_irq OK\n");
-       return err;
-}
-
-int atl1e_up(struct atl1e_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       int err = 0;
-       u32 val;
-
-       /* hardware has been reset, we need to reload some things */
-       err = atl1e_init_hw(&adapter->hw);
-       if (err) {
-               err = -EIO;
-               return err;
-       }
-       atl1e_init_ring_ptrs(adapter);
-       atl1e_set_multi(netdev);
-       atl1e_restore_vlan(adapter);
-
-       if (atl1e_configure(adapter)) {
-               err = -EIO;
-               goto err_up;
-       }
-
-       clear_bit(__AT_DOWN, &adapter->flags);
-       napi_enable(&adapter->napi);
-       atl1e_irq_enable(adapter);
-       val = AT_READ_REG(&adapter->hw, REG_MASTER_CTRL);
-       AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
-                     val | MASTER_CTRL_MANUAL_INT);
-
-err_up:
-       return err;
-}
-
-void atl1e_down(struct atl1e_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       /* signal that we're down so the interrupt handler does not
-        * reschedule our watchdog timer */
-       set_bit(__AT_DOWN, &adapter->flags);
-
-       netif_stop_queue(netdev);
-
-       /* reset MAC to disable all RX/TX */
-       atl1e_reset_hw(&adapter->hw);
-       msleep(1);
-
-       napi_disable(&adapter->napi);
-       atl1e_del_timer(adapter);
-       atl1e_irq_disable(adapter);
-
-       netif_carrier_off(netdev);
-       adapter->link_speed = SPEED_0;
-       adapter->link_duplex = -1;
-       atl1e_clean_tx_ring(adapter);
-       atl1e_clean_rx_ring(adapter);
-}
-
-/*
- * atl1e_open - Called when a network interface is made active
- * @netdev: network interface device structure
- *
- * Returns 0 on success, negative value on failure
- *
- * 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 atl1e_open(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       int err;
-
-       /* disallow open during test */
-       if (test_bit(__AT_TESTING, &adapter->flags))
-               return -EBUSY;
-
-       /* allocate rx/tx dma buffer & descriptors */
-       atl1e_init_ring_resources(adapter);
-       err = atl1e_setup_ring_resources(adapter);
-       if (unlikely(err))
-               return err;
-
-       err = atl1e_request_irq(adapter);
-       if (unlikely(err))
-               goto err_req_irq;
-
-       err = atl1e_up(adapter);
-       if (unlikely(err))
-               goto err_up;
-
-       return 0;
-
-err_up:
-       atl1e_free_irq(adapter);
-err_req_irq:
-       atl1e_free_ring_resources(adapter);
-       atl1e_reset_hw(&adapter->hw);
-
-       return err;
-}
-
-/*
- * atl1e_close - Disables a network interface
- * @netdev: network interface device structure
- *
- * Returns 0, this is not allowed to fail
- *
- * 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 atl1e_close(struct net_device *netdev)
-{
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
-       atl1e_down(adapter);
-       atl1e_free_irq(adapter);
-       atl1e_free_ring_resources(adapter);
-
-       return 0;
-}
-
-static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       struct atl1e_hw *hw = &adapter->hw;
-       u32 ctrl = 0;
-       u32 mac_ctrl_data = 0;
-       u32 wol_ctrl_data = 0;
-       u16 mii_advertise_data = 0;
-       u16 mii_bmsr_data = 0;
-       u16 mii_intr_status_data = 0;
-       u32 wufc = adapter->wol;
-       u32 i;
-#ifdef CONFIG_PM
-       int retval = 0;
-#endif
-
-       if (netif_running(netdev)) {
-               WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
-               atl1e_down(adapter);
-       }
-       netif_device_detach(netdev);
-
-#ifdef CONFIG_PM
-       retval = pci_save_state(pdev);
-       if (retval)
-               return retval;
-#endif
-
-       if (wufc) {
-               /* get link status */
-               atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
-               atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
-
-               mii_advertise_data = ADVERTISE_10HALF;
-
-               if ((atl1e_write_phy_reg(hw, MII_CTRL1000, 0) != 0) ||
-                   (atl1e_write_phy_reg(hw,
-                          MII_ADVERTISE, mii_advertise_data) != 0) ||
-                   (atl1e_phy_commit(hw)) != 0) {
-                       netdev_dbg(adapter->netdev, "set phy register failed\n");
-                       goto wol_dis;
-               }
-
-               hw->phy_configured = false; /* re-init PHY when resume */
-
-               /* turn on magic packet wol */
-               if (wufc & AT_WUFC_MAG)
-                       wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
-
-               if (wufc & AT_WUFC_LNKC) {
-               /* if orignal link status is link, just wait for retrive link */
-                       if (mii_bmsr_data & BMSR_LSTATUS) {
-                               for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
-                                       msleep(100);
-                                       atl1e_read_phy_reg(hw, MII_BMSR,
-                                                       (u16 *)&mii_bmsr_data);
-                                       if (mii_bmsr_data & BMSR_LSTATUS)
-                                               break;
-                               }
-
-                               if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
-                                       netdev_dbg(adapter->netdev,
-                                                  "Link may change when suspend\n");
-                       }
-                       wol_ctrl_data |=  WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
-                       /* only link up can wake up */
-                       if (atl1e_write_phy_reg(hw, MII_INT_CTRL, 0x400) != 0) {
-                               netdev_dbg(adapter->netdev,
-                                          "read write phy register failed\n");
-                               goto wol_dis;
-                       }
-               }
-               /* clear phy interrupt */
-               atl1e_read_phy_reg(hw, MII_INT_STATUS, &mii_intr_status_data);
-               /* Config MAC Ctrl register */
-               mac_ctrl_data = MAC_CTRL_RX_EN;
-               /* set to 10/100M halt duplex */
-               mac_ctrl_data |= MAC_CTRL_SPEED_10_100 << MAC_CTRL_SPEED_SHIFT;
-               mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
-                                MAC_CTRL_PRMLEN_MASK) <<
-                                MAC_CTRL_PRMLEN_SHIFT);
-
-               __atl1e_vlan_mode(netdev->features, &mac_ctrl_data);
-
-               /* magic packet maybe Broadcast&multicast&Unicast frame */
-               if (wufc & AT_WUFC_MAG)
-                       mac_ctrl_data |= MAC_CTRL_BC_EN;
-
-               netdev_dbg(adapter->netdev, "suspend MAC=0x%x\n",
-                          mac_ctrl_data);
-
-               AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
-               AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
-               /* pcie patch */
-               ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
-               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
-               AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
-               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
-               goto suspend_exit;
-       }
-wol_dis:
-
-       /* WOL disabled */
-       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
-
-       /* pcie patch */
-       ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
-       ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
-       AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
-
-       atl1e_force_ps(hw);
-       hw->phy_configured = false; /* re-init PHY when resume */
-
-       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
-
-suspend_exit:
-
-       if (netif_running(netdev))
-               atl1e_free_irq(adapter);
-
-       pci_disable_device(pdev);
-
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int atl1e_resume(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-       u32 err;
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-
-       err = pci_enable_device(pdev);
-       if (err) {
-               netdev_err(adapter->netdev,
-                          "Cannot enable PCI device from suspend\n");
-               return err;
-       }
-
-       pci_set_master(pdev);
-
-       AT_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */
-
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
-       AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
-
-       if (netif_running(netdev)) {
-               err = atl1e_request_irq(adapter);
-               if (err)
-                       return err;
-       }
-
-       atl1e_reset_hw(&adapter->hw);
-
-       if (netif_running(netdev))
-               atl1e_up(adapter);
-
-       netif_device_attach(netdev);
-
-       return 0;
-}
-#endif
-
-static void atl1e_shutdown(struct pci_dev *pdev)
-{
-       atl1e_suspend(pdev, PMSG_SUSPEND);
-}
-
-static const struct net_device_ops atl1e_netdev_ops = {
-       .ndo_open               = atl1e_open,
-       .ndo_stop               = atl1e_close,
-       .ndo_start_xmit         = atl1e_xmit_frame,
-       .ndo_get_stats          = atl1e_get_stats,
-       .ndo_set_multicast_list = atl1e_set_multi,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = atl1e_set_mac_addr,
-       .ndo_fix_features       = atl1e_fix_features,
-       .ndo_set_features       = atl1e_set_features,
-       .ndo_change_mtu         = atl1e_change_mtu,
-       .ndo_do_ioctl           = atl1e_ioctl,
-       .ndo_tx_timeout         = atl1e_tx_timeout,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = atl1e_netpoll,
-#endif
-
-};
-
-static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
-{
-       SET_NETDEV_DEV(netdev, &pdev->dev);
-       pci_set_drvdata(pdev, netdev);
-
-       netdev->irq  = pdev->irq;
-       netdev->netdev_ops = &atl1e_netdev_ops;
-
-       netdev->watchdog_timeo = AT_TX_WATCHDOG;
-       atl1e_set_ethtool_ops(netdev);
-
-       netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
-                             NETIF_F_HW_VLAN_RX;
-       netdev->features = netdev->hw_features | NETIF_F_LLTX |
-                          NETIF_F_HW_VLAN_TX;
-
-       return 0;
-}
-
-/*
- * atl1e_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in atl1e_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * atl1e_probe 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 __devinit atl1e_probe(struct pci_dev *pdev,
-                                const struct pci_device_id *ent)
-{
-       struct net_device *netdev;
-       struct atl1e_adapter *adapter = NULL;
-       static int cards_found;
-
-       int err = 0;
-
-       err = pci_enable_device(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "cannot enable PCI device\n");
-               return err;
-       }
-
-       /*
-        * The atl1e chip can DMA to 64-bit addresses, but it uses a single
-        * shared register for the high 32 bits, so only a single, aligned,
-        * 4 GB physical address range can be used at a time.
-        *
-        * Supporting 64-bit DMA on this hardware is more trouble than it's
-        * worth.  It is far easier to limit to 32-bit DMA than update
-        * various kernel subsystems to support the mechanics required by a
-        * fixed-high-32-bit system.
-        */
-       if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
-           (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
-               dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
-               goto err_dma;
-       }
-
-       err = pci_request_regions(pdev, atl1e_driver_name);
-       if (err) {
-               dev_err(&pdev->dev, "cannot obtain PCI resources\n");
-               goto err_pci_reg;
-       }
-
-       pci_set_master(pdev);
-
-       netdev = alloc_etherdev(sizeof(struct atl1e_adapter));
-       if (netdev == NULL) {
-               err = -ENOMEM;
-               dev_err(&pdev->dev, "etherdev alloc failed\n");
-               goto err_alloc_etherdev;
-       }
-
-       err = atl1e_init_netdev(netdev, pdev);
-       if (err) {
-               netdev_err(netdev, "init netdevice failed\n");
-               goto err_init_netdev;
-       }
-       adapter = netdev_priv(netdev);
-       adapter->bd_number = cards_found;
-       adapter->netdev = netdev;
-       adapter->pdev = pdev;
-       adapter->hw.adapter = adapter;
-       adapter->hw.hw_addr = pci_iomap(pdev, BAR_0, 0);
-       if (!adapter->hw.hw_addr) {
-               err = -EIO;
-               netdev_err(netdev, "cannot map device registers\n");
-               goto err_ioremap;
-       }
-       netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
-
-       /* init mii data */
-       adapter->mii.dev = netdev;
-       adapter->mii.mdio_read  = atl1e_mdio_read;
-       adapter->mii.mdio_write = atl1e_mdio_write;
-       adapter->mii.phy_id_mask = 0x1f;
-       adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
-
-       netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64);
-
-       init_timer(&adapter->phy_config_timer);
-       adapter->phy_config_timer.function = atl1e_phy_config;
-       adapter->phy_config_timer.data = (unsigned long) adapter;
-
-       /* get user settings */
-       atl1e_check_options(adapter);
-       /*
-        * Mark all PCI regions associated with PCI device
-        * pdev as being reserved by owner atl1e_driver_name
-        * Enables bus-mastering on the device and calls
-        * pcibios_set_master to do the needed arch specific settings
-        */
-       atl1e_setup_pcicmd(pdev);
-       /* setup the private structure */
-       err = atl1e_sw_init(adapter);
-       if (err) {
-               netdev_err(netdev, "net device private data init failed\n");
-               goto err_sw_init;
-       }
-
-       /* Init GPHY as early as possible due to power saving issue  */
-       atl1e_phy_init(&adapter->hw);
-       /* reset the controller to
-        * put the device in a known good starting state */
-       err = atl1e_reset_hw(&adapter->hw);
-       if (err) {
-               err = -EIO;
-               goto err_reset;
-       }
-
-       if (atl1e_read_mac_addr(&adapter->hw) != 0) {
-               err = -EIO;
-               netdev_err(netdev, "get mac address failed\n");
-               goto err_eeprom;
-       }
-
-       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
-       netdev_dbg(netdev, "mac address : %pM\n", adapter->hw.mac_addr);
-
-       INIT_WORK(&adapter->reset_task, atl1e_reset_task);
-       INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
-       err = register_netdev(netdev);
-       if (err) {
-               netdev_err(netdev, "register netdevice failed\n");
-               goto err_register;
-       }
-
-       /* assume we have no link for now */
-       netif_stop_queue(netdev);
-       netif_carrier_off(netdev);
-
-       cards_found++;
-
-       return 0;
-
-err_reset:
-err_register:
-err_sw_init:
-err_eeprom:
-       iounmap(adapter->hw.hw_addr);
-err_init_netdev:
-err_ioremap:
-       free_netdev(netdev);
-err_alloc_etherdev:
-       pci_release_regions(pdev);
-err_pci_reg:
-err_dma:
-       pci_disable_device(pdev);
-       return err;
-}
-
-/*
- * atl1e_remove - Device Removal Routine
- * @pdev: PCI device information struct
- *
- * atl1e_remove 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 __devexit atl1e_remove(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       /*
-        * flush_scheduled work may reschedule our watchdog task, so
-        * explicitly disable watchdog tasks from being rescheduled
-        */
-       set_bit(__AT_DOWN, &adapter->flags);
-
-       atl1e_del_timer(adapter);
-       atl1e_cancel_work(adapter);
-
-       unregister_netdev(netdev);
-       atl1e_free_ring_resources(adapter);
-       atl1e_force_ps(&adapter->hw);
-       iounmap(adapter->hw.hw_addr);
-       pci_release_regions(pdev);
-       free_netdev(netdev);
-       pci_disable_device(pdev);
-}
-
-/*
- * atl1e_io_error_detected - called when PCI error is detected
- * @pdev: Pointer to PCI device
- * @state: The current pci connection state
- *
- * This function is called after a PCI bus error affecting
- * this device has been detected.
- */
-static pci_ers_result_t
-atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       netif_device_detach(netdev);
-
-       if (state == pci_channel_io_perm_failure)
-               return PCI_ERS_RESULT_DISCONNECT;
-
-       if (netif_running(netdev))
-               atl1e_down(adapter);
-
-       pci_disable_device(pdev);
-
-       /* Request a slot slot reset. */
-       return PCI_ERS_RESULT_NEED_RESET;
-}
-
-/*
- * atl1e_io_slot_reset - called after the pci bus has been reset.
- * @pdev: Pointer to PCI device
- *
- * Restart the card from scratch, as if from a cold-boot. Implementation
- * resembles the first-half of the e1000_resume routine.
- */
-static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       if (pci_enable_device(pdev)) {
-               netdev_err(adapter->netdev,
-                          "Cannot re-enable PCI device after reset\n");
-               return PCI_ERS_RESULT_DISCONNECT;
-       }
-       pci_set_master(pdev);
-
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
-       atl1e_reset_hw(&adapter->hw);
-
-       return PCI_ERS_RESULT_RECOVERED;
-}
-
-/*
- * atl1e_io_resume - called when traffic can start flowing again.
- * @pdev: Pointer to PCI device
- *
- * 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 atl1e_resume routine.
- */
-static void atl1e_io_resume(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev_priv(netdev);
-
-       if (netif_running(netdev)) {
-               if (atl1e_up(adapter)) {
-                       netdev_err(adapter->netdev,
-                                  "can't bring device back up after reset\n");
-                       return;
-               }
-       }
-
-       netif_device_attach(netdev);
-}
-
-static struct pci_error_handlers atl1e_err_handler = {
-       .error_detected = atl1e_io_error_detected,
-       .slot_reset = atl1e_io_slot_reset,
-       .resume = atl1e_io_resume,
-};
-
-static struct pci_driver atl1e_driver = {
-       .name     = atl1e_driver_name,
-       .id_table = atl1e_pci_tbl,
-       .probe    = atl1e_probe,
-       .remove   = __devexit_p(atl1e_remove),
-       /* Power Management Hooks */
-#ifdef CONFIG_PM
-       .suspend  = atl1e_suspend,
-       .resume   = atl1e_resume,
-#endif
-       .shutdown = atl1e_shutdown,
-       .err_handler = &atl1e_err_handler
-};
-
-/*
- * atl1e_init_module - Driver Registration Routine
- *
- * atl1e_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1e_init_module(void)
-{
-       return pci_register_driver(&atl1e_driver);
-}
-
-/*
- * atl1e_exit_module - Driver Exit Cleanup Routine
- *
- * atl1e_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1e_exit_module(void)
-{
-       pci_unregister_driver(&atl1e_driver);
-}
-
-module_init(atl1e_init_module);
-module_exit(atl1e_exit_module);
diff --git a/drivers/net/atl1e/atl1e_param.c b/drivers/net/atl1e/atl1e_param.c
deleted file mode 100644 (file)
index 0ce60b6..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#include <linux/netdevice.h>
-
-#include "atl1e.h"
-
-/* This is the only thing that needs to be changed to adjust the
- * maximum number of ports that the driver can manage.
- */
-
-#define ATL1E_MAX_NIC 32
-
-#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 ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET }
-
-#define ATL1E_PARAM(x, desc) \
-       static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
-       static unsigned int num_##x; \
-       module_param_array_named(x, x, int, &num_##x, 0); \
-       MODULE_PARM_DESC(x, desc);
-
-/* Transmit Memory count
- *
- * Valid Range: 64-2048
- *
- * Default Value: 128
- */
-#define ATL1E_MIN_TX_DESC_CNT          32
-#define ATL1E_MAX_TX_DESC_CNT          1020
-#define ATL1E_DEFAULT_TX_DESC_CNT      128
-ATL1E_PARAM(tx_desc_cnt, "Transmit description count");
-
-/* Receive Memory Block Count
- *
- * Valid Range: 16-512
- *
- * Default Value: 128
- */
-#define ATL1E_MIN_RX_MEM_SIZE          8    /* 8KB   */
-#define ATL1E_MAX_RX_MEM_SIZE          1024 /* 1MB   */
-#define ATL1E_DEFAULT_RX_MEM_SIZE      256  /* 128KB */
-ATL1E_PARAM(rx_mem_size, "memory size of rx buffer(KB)");
-
-/* User Specified MediaType Override
- *
- * Valid Range: 0-5
- *  - 0    - auto-negotiate at all supported speeds
- *  - 1    - only link at 100Mbps Full Duplex
- *  - 2    - only link at 100Mbps Half Duplex
- *  - 3    - only link at 10Mbps Full Duplex
- *  - 4    - only link at 10Mbps Half Duplex
- * Default Value: 0
- */
-
-ATL1E_PARAM(media_type, "MediaType Select");
-
-/* Interrupt Moderate Timer in units of 2 us
- *
- * Valid Range: 10-65535
- *
- * Default Value: 45000(90ms)
- */
-#define INT_MOD_DEFAULT_CNT             100 /* 200us */
-#define INT_MOD_MAX_CNT                 65000
-#define INT_MOD_MIN_CNT                 50
-ATL1E_PARAM(int_mod_timer, "Interrupt Moderator Timer");
-
-#define AUTONEG_ADV_DEFAULT  0x2F
-#define AUTONEG_ADV_MASK     0x2F
-#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
-
-#define FLASH_VENDOR_DEFAULT    0
-#define FLASH_VENDOR_MIN        0
-#define FLASH_VENDOR_MAX        2
-
-struct atl1e_option {
-       enum { enable_option, range_option, list_option } type;
-       char *name;
-       char *err;
-       int  def;
-       union {
-               struct { /* range_option info */
-                       int min;
-                       int max;
-               } r;
-               struct { /* list_option info */
-                       int nr;
-                       struct atl1e_opt_list { int i; char *str; } *p;
-               } l;
-       } arg;
-};
-
-static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct atl1e_adapter *adapter)
-{
-       if (*value == OPTION_UNSET) {
-               *value = opt->def;
-               return 0;
-       }
-
-       switch (opt->type) {
-       case enable_option:
-               switch (*value) {
-               case OPTION_ENABLED:
-                       netdev_info(adapter->netdev,
-                                   "%s Enabled\n", opt->name);
-                       return 0;
-               case OPTION_DISABLED:
-                       netdev_info(adapter->netdev,
-                                   "%s Disabled\n", opt->name);
-                       return 0;
-               }
-               break;
-       case range_option:
-               if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-                       netdev_info(adapter->netdev, "%s set to %i\n",
-                                   opt->name, *value);
-                       return 0;
-               }
-               break;
-       case list_option:{
-                       int i;
-                       struct atl1e_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')
-                                               netdev_info(adapter->netdev,
-                                                           "%s\n", ent->str);
-                                       return 0;
-                               }
-                       }
-                       break;
-               }
-       default:
-               BUG();
-       }
-
-       netdev_info(adapter->netdev, "Invalid %s specified (%i) %s\n",
-                   opt->name, *value, opt->err);
-       *value = opt->def;
-       return -1;
-}
-
-/*
- * atl1e_check_options - Range Checking for Command Line Parameters
- * @adapter: board private structure
- *
- * 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 __devinit atl1e_check_options(struct atl1e_adapter *adapter)
-{
-       int bd = adapter->bd_number;
-
-       if (bd >= ATL1E_MAX_NIC) {
-               netdev_notice(adapter->netdev,
-                             "no configuration for board #%i\n", bd);
-               netdev_notice(adapter->netdev,
-                             "Using defaults for all values\n");
-       }
-
-       {               /* Transmit Ring Size */
-               struct atl1e_option opt = {
-                       .type = range_option,
-                       .name = "Transmit Ddescription Count",
-                       .err  = "using default of "
-                               __MODULE_STRING(ATL1E_DEFAULT_TX_DESC_CNT),
-                       .def  = ATL1E_DEFAULT_TX_DESC_CNT,
-                       .arg  = { .r = { .min = ATL1E_MIN_TX_DESC_CNT,
-                                        .max = ATL1E_MAX_TX_DESC_CNT} }
-               };
-               int val;
-               if (num_tx_desc_cnt > bd) {
-                       val = tx_desc_cnt[bd];
-                       atl1e_validate_option(&val, &opt, adapter);
-                       adapter->tx_ring.count = (u16) val & 0xFFFC;
-               } else
-                       adapter->tx_ring.count = (u16)opt.def;
-       }
-
-       {               /* Receive Memory Block Count */
-               struct atl1e_option opt = {
-                       .type = range_option,
-                       .name = "Memory size of rx buffer(KB)",
-                       .err  = "using default of "
-                               __MODULE_STRING(ATL1E_DEFAULT_RX_MEM_SIZE),
-                       .def  = ATL1E_DEFAULT_RX_MEM_SIZE,
-                       .arg  = { .r = { .min = ATL1E_MIN_RX_MEM_SIZE,
-                                        .max = ATL1E_MAX_RX_MEM_SIZE} }
-               };
-               int val;
-               if (num_rx_mem_size > bd) {
-                       val = rx_mem_size[bd];
-                       atl1e_validate_option(&val, &opt, adapter);
-                       adapter->rx_ring.page_size = (u32)val * 1024;
-               } else {
-                       adapter->rx_ring.page_size = (u32)opt.def * 1024;
-               }
-       }
-
-       {               /* Interrupt Moderate Timer */
-               struct atl1e_option opt = {
-                       .type = range_option,
-                       .name = "Interrupt Moderate Timer",
-                       .err  = "using default of "
-                               __MODULE_STRING(INT_MOD_DEFAULT_CNT),
-                       .def  = INT_MOD_DEFAULT_CNT,
-                       .arg  = { .r = { .min = INT_MOD_MIN_CNT,
-                                        .max = INT_MOD_MAX_CNT} }
-               } ;
-               int val;
-               if (num_int_mod_timer > bd) {
-                       val = int_mod_timer[bd];
-                       atl1e_validate_option(&val, &opt, adapter);
-                       adapter->hw.imt = (u16) val;
-               } else
-                       adapter->hw.imt = (u16)(opt.def);
-       }
-
-       {               /* MediaType */
-               struct atl1e_option opt = {
-                       .type = range_option,
-                       .name = "Speed/Duplex Selection",
-                       .err  = "using default of "
-                               __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR),
-                       .def  = MEDIA_TYPE_AUTO_SENSOR,
-                       .arg  = { .r = { .min = MEDIA_TYPE_AUTO_SENSOR,
-                                        .max = MEDIA_TYPE_10M_HALF} }
-               } ;
-               int val;
-               if (num_media_type > bd) {
-                       val = media_type[bd];
-                       atl1e_validate_option(&val, &opt, adapter);
-                       adapter->hw.media_type = (u16) val;
-               } else
-                       adapter->hw.media_type = (u16)(opt.def);
-
-       }
-}
diff --git a/drivers/net/atlx/Makefile b/drivers/net/atlx/Makefile
deleted file mode 100644 (file)
index e4f6022..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_ATL1)     += atl1.o
-obj-$(CONFIG_ATL2)     += atl2.o
-
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
deleted file mode 100644 (file)
index 97e6954..0000000
+++ /dev/null
@@ -1,3675 +0,0 @@
-/*
- * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
- * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- *
- * Contact Information:
- * Xiong Huang <xiong.huang@atheros.com>
- * Jie Yang <jie.yang@atheros.com>
- * Chris Snook <csnook@redhat.com>
- * Jay Cliburn <jcliburn@gmail.com>
- *
- * This version is adapted from the Attansic reference driver.
- *
- * TODO:
- * Add more ethtool functions.
- * Fix abstruse irq enable/disable condition described here:
- *     http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2
- *
- * NEEDS TESTING:
- * VLAN
- * multicast
- * promiscuous mode
- * interrupt coalescing
- * SMP torture testing
- */
-
-#include <linux/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/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/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/skbuff.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/tcp.h>
-#include <linux/timer.h>
-#include <linux/types.h>
-#include <linux/workqueue.h>
-
-#include <net/checksum.h>
-
-#include "atl1.h"
-
-#define ATLX_DRIVER_VERSION "2.1.3"
-MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, "
-             "Chris Snook <csnook@redhat.com>, "
-             "Jay Cliburn <jcliburn@gmail.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ATLX_DRIVER_VERSION);
-
-/* Temporary hack for merging atl1 and atl2 */
-#include "atlx.c"
-
-static const struct ethtool_ops atl1_ethtool_ops;
-
-/*
- * This is the only thing that needs to be changed to adjust the
- * maximum number of ports that the driver can manage.
- */
-#define ATL1_MAX_NIC 4
-
-#define OPTION_UNSET    -1
-#define OPTION_DISABLED 0
-#define OPTION_ENABLED  1
-
-#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }
-
-/*
- * Interrupt Moderate Timer in units of 2 us
- *
- * Valid Range: 10-65535
- *
- * Default Value: 100 (200us)
- */
-static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
-static unsigned int num_int_mod_timer;
-module_param_array_named(int_mod_timer, int_mod_timer, int,
-       &num_int_mod_timer, 0);
-MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
-
-#define DEFAULT_INT_MOD_CNT    100     /* 200us */
-#define MAX_INT_MOD_CNT                65000
-#define MIN_INT_MOD_CNT                50
-
-struct atl1_option {
-       enum { enable_option, range_option, list_option } type;
-       char *name;
-       char *err;
-       int def;
-       union {
-               struct {        /* range_option info */
-                       int min;
-                       int max;
-               } r;
-               struct {        /* list_option info */
-                       int nr;
-                       struct atl1_opt_list {
-                               int i;
-                               char *str;
-                       } *p;
-               } l;
-       } arg;
-};
-
-static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
-       struct pci_dev *pdev)
-{
-       if (*value == OPTION_UNSET) {
-               *value = opt->def;
-               return 0;
-       }
-
-       switch (opt->type) {
-       case enable_option:
-               switch (*value) {
-               case OPTION_ENABLED:
-                       dev_info(&pdev->dev, "%s enabled\n", opt->name);
-                       return 0;
-               case OPTION_DISABLED:
-                       dev_info(&pdev->dev, "%s disabled\n", opt->name);
-                       return 0;
-               }
-               break;
-       case range_option:
-               if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-                       dev_info(&pdev->dev, "%s set to %i\n", opt->name,
-                               *value);
-                       return 0;
-               }
-               break;
-       case list_option:{
-                       int i;
-                       struct atl1_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')
-                                               dev_info(&pdev->dev, "%s\n",
-                                                       ent->str);
-                                       return 0;
-                               }
-                       }
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
-               opt->name, *value, opt->err);
-       *value = opt->def;
-       return -1;
-}
-
-/*
- * atl1_check_options - Range Checking for Command Line Parameters
- * @adapter: board private structure
- *
- * 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.
- */
-static void __devinit atl1_check_options(struct atl1_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       int bd = adapter->bd_number;
-       if (bd >= ATL1_MAX_NIC) {
-               dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
-               dev_notice(&pdev->dev, "using defaults for all values\n");
-       }
-       {                       /* Interrupt Moderate Timer */
-               struct atl1_option opt = {
-                       .type = range_option,
-                       .name = "Interrupt Moderator Timer",
-                       .err = "using default of "
-                               __MODULE_STRING(DEFAULT_INT_MOD_CNT),
-                       .def = DEFAULT_INT_MOD_CNT,
-                       .arg = {.r = {.min = MIN_INT_MOD_CNT,
-                                       .max = MAX_INT_MOD_CNT} }
-               };
-               int val;
-               if (num_int_mod_timer > bd) {
-                       val = int_mod_timer[bd];
-                       atl1_validate_option(&val, &opt, pdev);
-                       adapter->imt = (u16) val;
-               } else
-                       adapter->imt = (u16) (opt.def);
-       }
-}
-
-/*
- * atl1_pci_tbl - PCI Device ID Table
- */
-static DEFINE_PCI_DEVICE_TABLE(atl1_pci_tbl) = {
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1)},
-       /* required last entry */
-       {0,}
-};
-MODULE_DEVICE_TABLE(pci, atl1_pci_tbl);
-
-static const u32 atl1_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
-       NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
-
-static int debug = -1;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Message level (0=none,...,16=all)");
-
-/*
- * 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)
- */
-static s32 atl1_reset_hw(struct atl1_hw *hw)
-{
-       struct pci_dev *pdev = hw->back->pdev;
-       struct atl1_adapter *adapter = hw->back;
-       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) {
-               if (netif_msg_hw(adapter))
-                       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
- */
-static 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;
-               }
-       }
-
-       /* 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
- */
-static 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
- */
-static 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
- */
-static 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
- */
-static 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);
-}
-
-/*
- * 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;
-       struct atl1_adapter *adapter = hw->back;
-       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! */
-               if (netif_msg_hw(adapter))
-                       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) {
-                       if (netif_msg_hw(adapter))
-                               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
- */
-static 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;
-       struct atl1_adapter *adapter = hw->back;
-       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) {
-               if (netif_msg_link(adapter))
-                       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) {
-               if (netif_msg_link(adapter))
-                       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.
- */
-static 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
- */
-static s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
-{
-       struct pci_dev *pdev = hw->back->pdev;
-       struct atl1_adapter *adapter = hw->back;
-       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:
-               if (netif_msg_hw(adapter))
-                       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;
-}
-
-static 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));
-}
-
-/*
- * atl1_sw_init - Initialize general software structures (struct atl1_adapter)
- * @adapter: board private structure to initialize
- *
- * atl1_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 __devinit atl1_sw_init(struct atl1_adapter *adapter)
-{
-       struct atl1_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-
-       hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-       hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
-
-       adapter->wol = 0;
-       device_set_wakeup_enable(&adapter->pdev->dev, false);
-       adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
-       adapter->ict = 50000;           /* 100ms */
-       adapter->link_speed = SPEED_0;  /* hardware init */
-       adapter->link_duplex = FULL_DUPLEX;
-
-       hw->phy_configured = false;
-       hw->preamble_len = 7;
-       hw->ipgt = 0x60;
-       hw->min_ifg = 0x50;
-       hw->ipgr1 = 0x40;
-       hw->ipgr2 = 0x60;
-       hw->max_retry = 0xf;
-       hw->lcol = 0x37;
-       hw->jam_ipg = 7;
-       hw->rfd_burst = 8;
-       hw->rrd_burst = 8;
-       hw->rfd_fetch_gap = 1;
-       hw->rx_jumbo_th = adapter->rx_buffer_len / 8;
-       hw->rx_jumbo_lkah = 1;
-       hw->rrd_ret_timer = 16;
-       hw->tpd_burst = 4;
-       hw->tpd_fetch_th = 16;
-       hw->txf_burst = 0x100;
-       hw->tx_jumbo_task_th = (hw->max_frame_size + 7) >> 3;
-       hw->tpd_fetch_gap = 1;
-       hw->rcb_value = atl1_rcb_64;
-       hw->dma_ord = atl1_dma_ord_enh;
-       hw->dmar_block = atl1_dma_req_256;
-       hw->dmaw_block = atl1_dma_req_256;
-       hw->cmb_rrd = 4;
-       hw->cmb_tpd = 4;
-       hw->cmb_rx_timer = 1;   /* about 2us */
-       hw->cmb_tx_timer = 1;   /* about 2us */
-       hw->smb_timer = 100000; /* about 200ms */
-
-       spin_lock_init(&adapter->lock);
-       spin_lock_init(&adapter->mb_lock);
-
-       return 0;
-}
-
-static int mdio_read(struct net_device *netdev, int phy_id, int reg_num)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       u16 result;
-
-       atl1_read_phy_reg(&adapter->hw, reg_num & 0x1f, &result);
-
-       return result;
-}
-
-static void mdio_write(struct net_device *netdev, int phy_id, int reg_num,
-       int val)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-
-       atl1_write_phy_reg(&adapter->hw, reg_num, val);
-}
-
-/*
- * atl1_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       unsigned long flags;
-       int retval;
-
-       if (!netif_running(netdev))
-               return -EINVAL;
-
-       spin_lock_irqsave(&adapter->lock, flags);
-       retval = generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);
-       spin_unlock_irqrestore(&adapter->lock, flags);
-
-       return retval;
-}
-
-/*
- * atl1_setup_mem_resources - allocate Tx / RX descriptor resources
- * @adapter: board private structure
- *
- * Return 0 on success, negative on failure
- */
-static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
-{
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
-       struct atl1_ring_header *ring_header = &adapter->ring_header;
-       struct pci_dev *pdev = adapter->pdev;
-       int size;
-       u8 offset = 0;
-
-       size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count);
-       tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
-       if (unlikely(!tpd_ring->buffer_info)) {
-               if (netif_msg_drv(adapter))
-                       dev_err(&pdev->dev, "kzalloc failed , size = D%d\n",
-                               size);
-               goto err_nomem;
-       }
-       rfd_ring->buffer_info =
-               (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
-
-       /*
-        * real ring DMA buffer
-        * each ring/block may need up to 8 bytes for alignment, hence the
-        * additional 40 bytes tacked onto the end.
-        */
-       ring_header->size = size =
-               sizeof(struct tx_packet_desc) * tpd_ring->count
-               + sizeof(struct rx_free_desc) * rfd_ring->count
-               + sizeof(struct rx_return_desc) * rrd_ring->count
-               + sizeof(struct coals_msg_block)
-               + sizeof(struct stats_msg_block)
-               + 40;
-
-       ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
-               &ring_header->dma);
-       if (unlikely(!ring_header->desc)) {
-               if (netif_msg_drv(adapter))
-                       dev_err(&pdev->dev, "pci_alloc_consistent failed\n");
-               goto err_nomem;
-       }
-
-       memset(ring_header->desc, 0, ring_header->size);
-
-       /* init TPD ring */
-       tpd_ring->dma = ring_header->dma;
-       offset = (tpd_ring->dma & 0x7) ? (8 - (ring_header->dma & 0x7)) : 0;
-       tpd_ring->dma += offset;
-       tpd_ring->desc = (u8 *) ring_header->desc + offset;
-       tpd_ring->size = sizeof(struct tx_packet_desc) * tpd_ring->count;
-
-       /* init RFD ring */
-       rfd_ring->dma = tpd_ring->dma + tpd_ring->size;
-       offset = (rfd_ring->dma & 0x7) ? (8 - (rfd_ring->dma & 0x7)) : 0;
-       rfd_ring->dma += offset;
-       rfd_ring->desc = (u8 *) tpd_ring->desc + (tpd_ring->size + offset);
-       rfd_ring->size = sizeof(struct rx_free_desc) * rfd_ring->count;
-
-
-       /* init RRD ring */
-       rrd_ring->dma = rfd_ring->dma + rfd_ring->size;
-       offset = (rrd_ring->dma & 0x7) ? (8 - (rrd_ring->dma & 0x7)) : 0;
-       rrd_ring->dma += offset;
-       rrd_ring->desc = (u8 *) rfd_ring->desc + (rfd_ring->size + offset);
-       rrd_ring->size = sizeof(struct rx_return_desc) * rrd_ring->count;
-
-
-       /* init CMB */
-       adapter->cmb.dma = rrd_ring->dma + rrd_ring->size;
-       offset = (adapter->cmb.dma & 0x7) ? (8 - (adapter->cmb.dma & 0x7)) : 0;
-       adapter->cmb.dma += offset;
-       adapter->cmb.cmb = (struct coals_msg_block *)
-               ((u8 *) rrd_ring->desc + (rrd_ring->size + offset));
-
-       /* init SMB */
-       adapter->smb.dma = adapter->cmb.dma + sizeof(struct coals_msg_block);
-       offset = (adapter->smb.dma & 0x7) ? (8 - (adapter->smb.dma & 0x7)) : 0;
-       adapter->smb.dma += offset;
-       adapter->smb.smb = (struct stats_msg_block *)
-               ((u8 *) adapter->cmb.cmb +
-               (sizeof(struct coals_msg_block) + offset));
-
-       return 0;
-
-err_nomem:
-       kfree(tpd_ring->buffer_info);
-       return -ENOMEM;
-}
-
-static void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
-{
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
-
-       atomic_set(&tpd_ring->next_to_use, 0);
-       atomic_set(&tpd_ring->next_to_clean, 0);
-
-       rfd_ring->next_to_clean = 0;
-       atomic_set(&rfd_ring->next_to_use, 0);
-
-       rrd_ring->next_to_use = 0;
-       atomic_set(&rrd_ring->next_to_clean, 0);
-}
-
-/*
- * atl1_clean_rx_ring - Free RFD Buffers
- * @adapter: board private structure
- */
-static void atl1_clean_rx_ring(struct atl1_adapter *adapter)
-{
-       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
-       struct atl1_buffer *buffer_info;
-       struct pci_dev *pdev = adapter->pdev;
-       unsigned long size;
-       unsigned int i;
-
-       /* Free all the Rx ring sk_buffs */
-       for (i = 0; i < rfd_ring->count; i++) {
-               buffer_info = &rfd_ring->buffer_info[i];
-               if (buffer_info->dma) {
-                       pci_unmap_page(pdev, buffer_info->dma,
-                               buffer_info->length, PCI_DMA_FROMDEVICE);
-                       buffer_info->dma = 0;
-               }
-               if (buffer_info->skb) {
-                       dev_kfree_skb(buffer_info->skb);
-                       buffer_info->skb = NULL;
-               }
-       }
-
-       size = sizeof(struct atl1_buffer) * rfd_ring->count;
-       memset(rfd_ring->buffer_info, 0, size);
-
-       /* Zero out the descriptor ring */
-       memset(rfd_ring->desc, 0, rfd_ring->size);
-
-       rfd_ring->next_to_clean = 0;
-       atomic_set(&rfd_ring->next_to_use, 0);
-
-       rrd_ring->next_to_use = 0;
-       atomic_set(&rrd_ring->next_to_clean, 0);
-}
-
-/*
- * atl1_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
- */
-static void atl1_clean_tx_ring(struct atl1_adapter *adapter)
-{
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       struct atl1_buffer *buffer_info;
-       struct pci_dev *pdev = adapter->pdev;
-       unsigned long size;
-       unsigned int i;
-
-       /* Free all the Tx ring sk_buffs */
-       for (i = 0; i < tpd_ring->count; i++) {
-               buffer_info = &tpd_ring->buffer_info[i];
-               if (buffer_info->dma) {
-                       pci_unmap_page(pdev, buffer_info->dma,
-                               buffer_info->length, PCI_DMA_TODEVICE);
-                       buffer_info->dma = 0;
-               }
-       }
-
-       for (i = 0; i < tpd_ring->count; i++) {
-               buffer_info = &tpd_ring->buffer_info[i];
-               if (buffer_info->skb) {
-                       dev_kfree_skb_any(buffer_info->skb);
-                       buffer_info->skb = NULL;
-               }
-       }
-
-       size = sizeof(struct atl1_buffer) * tpd_ring->count;
-       memset(tpd_ring->buffer_info, 0, size);
-
-       /* Zero out the descriptor ring */
-       memset(tpd_ring->desc, 0, tpd_ring->size);
-
-       atomic_set(&tpd_ring->next_to_use, 0);
-       atomic_set(&tpd_ring->next_to_clean, 0);
-}
-
-/*
- * atl1_free_ring_resources - Free Tx / RX descriptor Resources
- * @adapter: board private structure
- *
- * Free all transmit software resources
- */
-static void atl1_free_ring_resources(struct atl1_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
-       struct atl1_ring_header *ring_header = &adapter->ring_header;
-
-       atl1_clean_tx_ring(adapter);
-       atl1_clean_rx_ring(adapter);
-
-       kfree(tpd_ring->buffer_info);
-       pci_free_consistent(pdev, ring_header->size, ring_header->desc,
-               ring_header->dma);
-
-       tpd_ring->buffer_info = NULL;
-       tpd_ring->desc = NULL;
-       tpd_ring->dma = 0;
-
-       rfd_ring->buffer_info = NULL;
-       rfd_ring->desc = NULL;
-       rfd_ring->dma = 0;
-
-       rrd_ring->desc = NULL;
-       rrd_ring->dma = 0;
-
-       adapter->cmb.dma = 0;
-       adapter->cmb.cmb = NULL;
-
-       adapter->smb.dma = 0;
-       adapter->smb.smb = NULL;
-}
-
-static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
-{
-       u32 value;
-       struct atl1_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       /* Config MAC CTRL Register */
-       value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN;
-       /* duplex */
-       if (FULL_DUPLEX == adapter->link_duplex)
-               value |= MAC_CTRL_DUPLX;
-       /* speed */
-       value |= ((u32) ((SPEED_1000 == adapter->link_speed) ?
-                        MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) <<
-                 MAC_CTRL_SPEED_SHIFT);
-       /* flow control */
-       value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
-       /* PAD & CRC */
-       value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
-       /* preamble length */
-       value |= (((u32) adapter->hw.preamble_len
-                  & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
-       /* vlan */
-       __atlx_vlan_mode(netdev->features, &value);
-       /* rx checksum
-          if (adapter->rx_csum)
-          value |= MAC_CTRL_RX_CHKSUM_EN;
-        */
-       /* filter mode */
-       value |= MAC_CTRL_BC_EN;
-       if (netdev->flags & IFF_PROMISC)
-               value |= MAC_CTRL_PROMIS_EN;
-       else if (netdev->flags & IFF_ALLMULTI)
-               value |= MAC_CTRL_MC_ALL_EN;
-       /* value |= MAC_CTRL_LOOPBACK; */
-       iowrite32(value, hw->hw_addr + REG_MAC_CTRL);
-}
-
-static u32 atl1_check_link(struct atl1_adapter *adapter)
-{
-       struct atl1_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       u32 ret_val;
-       u16 speed, duplex, phy_data;
-       int reconfig = 0;
-
-       /* 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 (netif_msg_link(adapter))
-                               dev_info(&adapter->pdev->dev, "link is down\n");
-                       adapter->link_speed = SPEED_0;
-                       netif_carrier_off(netdev);
-               }
-               return 0;
-       }
-
-       /* Link Up */
-       ret_val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
-       if (ret_val)
-               return ret_val;
-
-       switch (hw->media_type) {
-       case MEDIA_TYPE_1000M_FULL:
-               if (speed != SPEED_1000 || duplex != FULL_DUPLEX)
-                       reconfig = 1;
-               break;
-       case MEDIA_TYPE_100M_FULL:
-               if (speed != SPEED_100 || duplex != FULL_DUPLEX)
-                       reconfig = 1;
-               break;
-       case MEDIA_TYPE_100M_HALF:
-               if (speed != SPEED_100 || duplex != HALF_DUPLEX)
-                       reconfig = 1;
-               break;
-       case MEDIA_TYPE_10M_FULL:
-               if (speed != SPEED_10 || duplex != FULL_DUPLEX)
-                       reconfig = 1;
-               break;
-       case MEDIA_TYPE_10M_HALF:
-               if (speed != SPEED_10 || duplex != HALF_DUPLEX)
-                       reconfig = 1;
-               break;
-       }
-
-       /* link result is our setting */
-       if (!reconfig) {
-               if (adapter->link_speed != speed ||
-                   adapter->link_duplex != duplex) {
-                       adapter->link_speed = speed;
-                       adapter->link_duplex = duplex;
-                       atl1_setup_mac_ctrl(adapter);
-                       if (netif_msg_link(adapter))
-                               dev_info(&adapter->pdev->dev,
-                                       "%s link is up %d Mbps %s\n",
-                                       netdev->name, adapter->link_speed,
-                                       adapter->link_duplex == FULL_DUPLEX ?
-                                       "full duplex" : "half duplex");
-               }
-               if (!netif_carrier_ok(netdev)) {
-                       /* Link down -> Up */
-                       netif_carrier_on(netdev);
-               }
-               return 0;
-       }
-
-       /* change original link status */
-       if (netif_carrier_ok(netdev)) {
-               adapter->link_speed = SPEED_0;
-               netif_carrier_off(netdev);
-               netif_stop_queue(netdev);
-       }
-
-       if (hw->media_type != MEDIA_TYPE_AUTO_SENSOR &&
-           hw->media_type != MEDIA_TYPE_1000M_FULL) {
-               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);
-               return 0;
-       }
-
-       /* auto-neg, insert timer to re-config phy */
-       if (!adapter->phy_timer_pending) {
-               adapter->phy_timer_pending = true;
-               mod_timer(&adapter->phy_config_timer,
-                         round_jiffies(jiffies + 3 * HZ));
-       }
-
-       return 0;
-}
-
-static void set_flow_ctrl_old(struct atl1_adapter *adapter)
-{
-       u32 hi, lo, value;
-
-       /* RFD Flow Control */
-       value = adapter->rfd_ring.count;
-       hi = value / 16;
-       if (hi < 2)
-               hi = 2;
-       lo = value * 7 / 8;
-
-       value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
-               ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
-       iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RXF_PAUSE_THRESH);
-
-       /* RRD Flow Control */
-       value = adapter->rrd_ring.count;
-       lo = value / 16;
-       hi = value * 7 / 8;
-       if (lo < 2)
-               lo = 2;
-       value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) |
-               ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
-       iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RRD_PAUSE_THRESH);
-}
-
-static void set_flow_ctrl_new(struct atl1_hw *hw)
-{
-       u32 hi, lo, value;
-
-       /* RXF Flow Control */
-       value = ioread32(hw->hw_addr + REG_SRAM_RXF_LEN);
-       lo = value / 16;
-       if (lo < 192)
-               lo = 192;
-       hi = value * 7 / 8;
-       if (hi < lo)
-               hi = lo + 16;
-       value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
-               ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
-       iowrite32(value, hw->hw_addr + REG_RXQ_RXF_PAUSE_THRESH);
-
-       /* RRD Flow Control */
-       value = ioread32(hw->hw_addr + REG_SRAM_RRD_LEN);
-       lo = value / 8;
-       hi = value * 7 / 8;
-       if (lo < 2)
-               lo = 2;
-       if (hi < lo)
-               hi = lo + 3;
-       value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) |
-               ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
-       iowrite32(value, hw->hw_addr + REG_RXQ_RRD_PAUSE_THRESH);
-}
-
-/*
- * atl1_configure - Configure Transmit&Receive Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx /Rx unit of the MAC after a reset.
- */
-static u32 atl1_configure(struct atl1_adapter *adapter)
-{
-       struct atl1_hw *hw = &adapter->hw;
-       u32 value;
-
-       /* clear interrupt status */
-       iowrite32(0xffffffff, adapter->hw.hw_addr + REG_ISR);
-
-       /* set MAC Address */
-       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);
-       value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1]));
-       iowrite32(value, hw->hw_addr + (REG_MAC_STA_ADDR + 4));
-
-       /* tx / rx ring */
-
-       /* HI base address */
-       iowrite32((u32) ((adapter->tpd_ring.dma & 0xffffffff00000000ULL) >> 32),
-               hw->hw_addr + REG_DESC_BASE_ADDR_HI);
-       /* LO base address */
-       iowrite32((u32) (adapter->rfd_ring.dma & 0x00000000ffffffffULL),
-               hw->hw_addr + REG_DESC_RFD_ADDR_LO);
-       iowrite32((u32) (adapter->rrd_ring.dma & 0x00000000ffffffffULL),
-               hw->hw_addr + REG_DESC_RRD_ADDR_LO);
-       iowrite32((u32) (adapter->tpd_ring.dma & 0x00000000ffffffffULL),
-               hw->hw_addr + REG_DESC_TPD_ADDR_LO);
-       iowrite32((u32) (adapter->cmb.dma & 0x00000000ffffffffULL),
-               hw->hw_addr + REG_DESC_CMB_ADDR_LO);
-       iowrite32((u32) (adapter->smb.dma & 0x00000000ffffffffULL),
-               hw->hw_addr + REG_DESC_SMB_ADDR_LO);
-
-       /* element count */
-       value = adapter->rrd_ring.count;
-       value <<= 16;
-       value += adapter->rfd_ring.count;
-       iowrite32(value, hw->hw_addr + REG_DESC_RFD_RRD_RING_SIZE);
-       iowrite32(adapter->tpd_ring.count, hw->hw_addr +
-               REG_DESC_TPD_RING_SIZE);
-
-       /* Load Ptr */
-       iowrite32(1, hw->hw_addr + REG_LOAD_PTR);
-
-       /* config Mailbox */
-       value = ((atomic_read(&adapter->tpd_ring.next_to_use)
-                 & MB_TPD_PROD_INDX_MASK) << MB_TPD_PROD_INDX_SHIFT) |
-               ((atomic_read(&adapter->rrd_ring.next_to_clean)
-               & MB_RRD_CONS_INDX_MASK) << MB_RRD_CONS_INDX_SHIFT) |
-               ((atomic_read(&adapter->rfd_ring.next_to_use)
-               & MB_RFD_PROD_INDX_MASK) << MB_RFD_PROD_INDX_SHIFT);
-       iowrite32(value, hw->hw_addr + REG_MAILBOX);
-
-       /* config IPG/IFG */
-       value = (((u32) hw->ipgt & MAC_IPG_IFG_IPGT_MASK)
-                << MAC_IPG_IFG_IPGT_SHIFT) |
-               (((u32) hw->min_ifg & MAC_IPG_IFG_MIFG_MASK)
-               << MAC_IPG_IFG_MIFG_SHIFT) |
-               (((u32) hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK)
-               << MAC_IPG_IFG_IPGR1_SHIFT) |
-               (((u32) hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK)
-               << MAC_IPG_IFG_IPGR2_SHIFT);
-       iowrite32(value, hw->hw_addr + REG_MAC_IPG_IFG);
-
-       /* config  Half-Duplex Control */
-       value = ((u32) hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) |
-               (((u32) hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK)
-               << MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) |
-               MAC_HALF_DUPLX_CTRL_EXC_DEF_EN |
-               (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) |
-               (((u32) hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK)
-               << MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT);
-       iowrite32(value, hw->hw_addr + REG_MAC_HALF_DUPLX_CTRL);
-
-       /* set Interrupt Moderator Timer */
-       iowrite16(adapter->imt, hw->hw_addr + REG_IRQ_MODU_TIMER_INIT);
-       iowrite32(MASTER_CTRL_ITIMER_EN, hw->hw_addr + REG_MASTER_CTRL);
-
-       /* set Interrupt Clear Timer */
-       iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER);
-
-       /* set max frame size hw will accept */
-       iowrite32(hw->max_frame_size, hw->hw_addr + REG_MTU);
-
-       /* jumbo size & rrd retirement timer */
-       value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK)
-                << RXQ_JMBOSZ_TH_SHIFT) |
-               (((u32) hw->rx_jumbo_lkah & RXQ_JMBO_LKAH_MASK)
-               << RXQ_JMBO_LKAH_SHIFT) |
-               (((u32) hw->rrd_ret_timer & RXQ_RRD_TIMER_MASK)
-               << RXQ_RRD_TIMER_SHIFT);
-       iowrite32(value, hw->hw_addr + REG_RXQ_JMBOSZ_RRDTIM);
-
-       /* Flow Control */
-       switch (hw->dev_rev) {
-       case 0x8001:
-       case 0x9001:
-       case 0x9002:
-       case 0x9003:
-               set_flow_ctrl_old(adapter);
-               break;
-       default:
-               set_flow_ctrl_new(hw);
-               break;
-       }
-
-       /* config TXQ */
-       value = (((u32) hw->tpd_burst & TXQ_CTRL_TPD_BURST_NUM_MASK)
-                << TXQ_CTRL_TPD_BURST_NUM_SHIFT) |
-               (((u32) hw->txf_burst & TXQ_CTRL_TXF_BURST_NUM_MASK)
-               << TXQ_CTRL_TXF_BURST_NUM_SHIFT) |
-               (((u32) hw->tpd_fetch_th & TXQ_CTRL_TPD_FETCH_TH_MASK)
-               << TXQ_CTRL_TPD_FETCH_TH_SHIFT) | TXQ_CTRL_ENH_MODE |
-               TXQ_CTRL_EN;
-       iowrite32(value, hw->hw_addr + REG_TXQ_CTRL);
-
-       /* min tpd fetch gap & tx jumbo packet size threshold for taskoffload */
-       value = (((u32) hw->tx_jumbo_task_th & TX_JUMBO_TASK_TH_MASK)
-               << TX_JUMBO_TASK_TH_SHIFT) |
-               (((u32) hw->tpd_fetch_gap & TX_TPD_MIN_IPG_MASK)
-               << TX_TPD_MIN_IPG_SHIFT);
-       iowrite32(value, hw->hw_addr + REG_TX_JUMBO_TASK_TH_TPD_IPG);
-
-       /* config RXQ */
-       value = (((u32) hw->rfd_burst & RXQ_CTRL_RFD_BURST_NUM_MASK)
-               << RXQ_CTRL_RFD_BURST_NUM_SHIFT) |
-               (((u32) hw->rrd_burst & RXQ_CTRL_RRD_BURST_THRESH_MASK)
-               << RXQ_CTRL_RRD_BURST_THRESH_SHIFT) |
-               (((u32) hw->rfd_fetch_gap & RXQ_CTRL_RFD_PREF_MIN_IPG_MASK)
-               << RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT) | RXQ_CTRL_CUT_THRU_EN |
-               RXQ_CTRL_EN;
-       iowrite32(value, hw->hw_addr + REG_RXQ_CTRL);
-
-       /* config DMA Engine */
-       value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
-               << DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
-               ((((u32) hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
-               << DMA_CTRL_DMAW_BURST_LEN_SHIFT) | DMA_CTRL_DMAR_EN |
-               DMA_CTRL_DMAW_EN;
-       value |= (u32) hw->dma_ord;
-       if (atl1_rcb_128 == hw->rcb_value)
-               value |= DMA_CTRL_RCB_VALUE;
-       iowrite32(value, hw->hw_addr + REG_DMA_CTRL);
-
-       /* config CMB / SMB */
-       value = (hw->cmb_tpd > adapter->tpd_ring.count) ?
-               hw->cmb_tpd : adapter->tpd_ring.count;
-       value <<= 16;
-       value |= hw->cmb_rrd;
-       iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TH);
-       value = hw->cmb_rx_timer | ((u32) hw->cmb_tx_timer << 16);
-       iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TIMER);
-       iowrite32(hw->smb_timer, hw->hw_addr + REG_SMB_TIMER);
-
-       /* --- enable CMB / SMB */
-       value = CSMB_CTRL_CMB_EN | CSMB_CTRL_SMB_EN;
-       iowrite32(value, hw->hw_addr + REG_CSMB_CTRL);
-
-       value = ioread32(adapter->hw.hw_addr + REG_ISR);
-       if (unlikely((value & ISR_PHY_LINKDOWN) != 0))
-               value = 1;      /* config failed */
-       else
-               value = 0;
-
-       /* clear all interrupt status */
-       iowrite32(0x3fffffff, adapter->hw.hw_addr + REG_ISR);
-       iowrite32(0, adapter->hw.hw_addr + REG_ISR);
-       return value;
-}
-
-/*
- * atl1_pcie_patch - Patch for PCIE module
- */
-static void atl1_pcie_patch(struct atl1_adapter *adapter)
-{
-       u32 value;
-
-       /* much vendor magic here */
-       value = 0x6500;
-       iowrite32(value, adapter->hw.hw_addr + 0x12FC);
-       /* pcie flow control mode change */
-       value = ioread32(adapter->hw.hw_addr + 0x1008);
-       value |= 0x8000;
-       iowrite32(value, adapter->hw.hw_addr + 0x1008);
-}
-
-/*
- * When ACPI resume on some VIA MotherBoard, the Interrupt Disable bit/0x400
- * on PCI Command register is disable.
- * The function enable this bit.
- * Brackett, 2006/03/15
- */
-static void atl1_via_workaround(struct atl1_adapter *adapter)
-{
-       unsigned long value;
-
-       value = ioread16(adapter->hw.hw_addr + PCI_COMMAND);
-       if (value & PCI_COMMAND_INTX_DISABLE)
-               value &= ~PCI_COMMAND_INTX_DISABLE;
-       iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
-}
-
-static void atl1_inc_smb(struct atl1_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       struct stats_msg_block *smb = adapter->smb.smb;
-
-       /* Fill out the OS statistics structure */
-       adapter->soft_stats.rx_packets += smb->rx_ok;
-       adapter->soft_stats.tx_packets += smb->tx_ok;
-       adapter->soft_stats.rx_bytes += smb->rx_byte_cnt;
-       adapter->soft_stats.tx_bytes += smb->tx_byte_cnt;
-       adapter->soft_stats.multicast += smb->rx_mcast;
-       adapter->soft_stats.collisions += (smb->tx_1_col + smb->tx_2_col * 2 +
-               smb->tx_late_col + smb->tx_abort_col * adapter->hw.max_retry);
-
-       /* Rx Errors */
-       adapter->soft_stats.rx_errors += (smb->rx_frag + smb->rx_fcs_err +
-               smb->rx_len_err + smb->rx_sz_ov + smb->rx_rxf_ov +
-               smb->rx_rrd_ov + smb->rx_align_err);
-       adapter->soft_stats.rx_fifo_errors += smb->rx_rxf_ov;
-       adapter->soft_stats.rx_length_errors += smb->rx_len_err;
-       adapter->soft_stats.rx_crc_errors += smb->rx_fcs_err;
-       adapter->soft_stats.rx_frame_errors += smb->rx_align_err;
-       adapter->soft_stats.rx_missed_errors += (smb->rx_rrd_ov +
-               smb->rx_rxf_ov);
-
-       adapter->soft_stats.rx_pause += smb->rx_pause;
-       adapter->soft_stats.rx_rrd_ov += smb->rx_rrd_ov;
-       adapter->soft_stats.rx_trunc += smb->rx_sz_ov;
-
-       /* Tx Errors */
-       adapter->soft_stats.tx_errors += (smb->tx_late_col +
-               smb->tx_abort_col + smb->tx_underrun + smb->tx_trunc);
-       adapter->soft_stats.tx_fifo_errors += smb->tx_underrun;
-       adapter->soft_stats.tx_aborted_errors += smb->tx_abort_col;
-       adapter->soft_stats.tx_window_errors += smb->tx_late_col;
-
-       adapter->soft_stats.excecol += smb->tx_abort_col;
-       adapter->soft_stats.deffer += smb->tx_defer;
-       adapter->soft_stats.scc += smb->tx_1_col;
-       adapter->soft_stats.mcc += smb->tx_2_col;
-       adapter->soft_stats.latecol += smb->tx_late_col;
-       adapter->soft_stats.tx_underun += smb->tx_underrun;
-       adapter->soft_stats.tx_trunc += smb->tx_trunc;
-       adapter->soft_stats.tx_pause += smb->tx_pause;
-
-       netdev->stats.rx_packets = adapter->soft_stats.rx_packets;
-       netdev->stats.tx_packets = adapter->soft_stats.tx_packets;
-       netdev->stats.rx_bytes = adapter->soft_stats.rx_bytes;
-       netdev->stats.tx_bytes = adapter->soft_stats.tx_bytes;
-       netdev->stats.multicast = adapter->soft_stats.multicast;
-       netdev->stats.collisions = adapter->soft_stats.collisions;
-       netdev->stats.rx_errors = adapter->soft_stats.rx_errors;
-       netdev->stats.rx_over_errors =
-               adapter->soft_stats.rx_missed_errors;
-       netdev->stats.rx_length_errors =
-               adapter->soft_stats.rx_length_errors;
-       netdev->stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
-       netdev->stats.rx_frame_errors =
-               adapter->soft_stats.rx_frame_errors;
-       netdev->stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
-       netdev->stats.rx_missed_errors =
-               adapter->soft_stats.rx_missed_errors;
-       netdev->stats.tx_errors = adapter->soft_stats.tx_errors;
-       netdev->stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
-       netdev->stats.tx_aborted_errors =
-               adapter->soft_stats.tx_aborted_errors;
-       netdev->stats.tx_window_errors =
-               adapter->soft_stats.tx_window_errors;
-       netdev->stats.tx_carrier_errors =
-               adapter->soft_stats.tx_carrier_errors;
-}
-
-static void atl1_update_mailbox(struct atl1_adapter *adapter)
-{
-       unsigned long flags;
-       u32 tpd_next_to_use;
-       u32 rfd_next_to_use;
-       u32 rrd_next_to_clean;
-       u32 value;
-
-       spin_lock_irqsave(&adapter->mb_lock, flags);
-
-       tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
-       rfd_next_to_use = atomic_read(&adapter->rfd_ring.next_to_use);
-       rrd_next_to_clean = atomic_read(&adapter->rrd_ring.next_to_clean);
-
-       value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
-               MB_RFD_PROD_INDX_SHIFT) |
-               ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
-               MB_RRD_CONS_INDX_SHIFT) |
-               ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
-               MB_TPD_PROD_INDX_SHIFT);
-       iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
-
-       spin_unlock_irqrestore(&adapter->mb_lock, flags);
-}
-
-static void atl1_clean_alloc_flag(struct atl1_adapter *adapter,
-       struct rx_return_desc *rrd, u16 offset)
-{
-       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-
-       while (rfd_ring->next_to_clean != (rrd->buf_indx + offset)) {
-               rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced = 0;
-               if (++rfd_ring->next_to_clean == rfd_ring->count) {
-                       rfd_ring->next_to_clean = 0;
-               }
-       }
-}
-
-static void atl1_update_rfd_index(struct atl1_adapter *adapter,
-       struct rx_return_desc *rrd)
-{
-       u16 num_buf;
-
-       num_buf = (rrd->xsz.xsum_sz.pkt_size + adapter->rx_buffer_len - 1) /
-               adapter->rx_buffer_len;
-       if (rrd->num_buf == num_buf)
-               /* clean alloc flag for bad rrd */
-               atl1_clean_alloc_flag(adapter, rrd, num_buf);
-}
-
-static void atl1_rx_checksum(struct atl1_adapter *adapter,
-       struct rx_return_desc *rrd, struct sk_buff *skb)
-{
-       struct pci_dev *pdev = adapter->pdev;
-
-       /*
-        * The L1 hardware contains a bug that erroneously sets the
-        * PACKET_FLAG_ERR and ERR_FLAG_L4_CHKSUM bits whenever a
-        * fragmented IP packet is received, even though the packet
-        * is perfectly valid and its checksum is correct. There's
-        * no way to distinguish between one of these good packets
-        * and a packet that actually contains a TCP/UDP checksum
-        * error, so all we can do is allow it to be handed up to
-        * the higher layers and let it be sorted out there.
-        */
-
-       skb_checksum_none_assert(skb);
-
-       if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
-               if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
-                                       ERR_FLAG_CODE | ERR_FLAG_OV)) {
-                       adapter->hw_csum_err++;
-                       if (netif_msg_rx_err(adapter))
-                               dev_printk(KERN_DEBUG, &pdev->dev,
-                                       "rx checksum error\n");
-                       return;
-               }
-       }
-
-       /* not IPv4 */
-       if (!(rrd->pkt_flg & PACKET_FLAG_IPV4))
-               /* checksum is invalid, but it's not an IPv4 pkt, so ok */
-               return;
-
-       /* IPv4 packet */
-       if (likely(!(rrd->err_flg &
-               (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM)))) {
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-               adapter->hw_csum_good++;
-               return;
-       }
-}
-
-/*
- * atl1_alloc_rx_buffers - Replace used receive buffers
- * @adapter: address of board private structure
- */
-static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
-{
-       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-       struct pci_dev *pdev = adapter->pdev;
-       struct page *page;
-       unsigned long offset;
-       struct atl1_buffer *buffer_info, *next_info;
-       struct sk_buff *skb;
-       u16 num_alloc = 0;
-       u16 rfd_next_to_use, next_next;
-       struct rx_free_desc *rfd_desc;
-
-       next_next = rfd_next_to_use = atomic_read(&rfd_ring->next_to_use);
-       if (++next_next == rfd_ring->count)
-               next_next = 0;
-       buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
-       next_info = &rfd_ring->buffer_info[next_next];
-
-       while (!buffer_info->alloced && !next_info->alloced) {
-               if (buffer_info->skb) {
-                       buffer_info->alloced = 1;
-                       goto next;
-               }
-
-               rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
-
-               skb = netdev_alloc_skb_ip_align(adapter->netdev,
-                                               adapter->rx_buffer_len);
-               if (unlikely(!skb)) {
-                       /* Better luck next round */
-                       adapter->netdev->stats.rx_dropped++;
-                       break;
-               }
-
-               buffer_info->alloced = 1;
-               buffer_info->skb = skb;
-               buffer_info->length = (u16) adapter->rx_buffer_len;
-               page = virt_to_page(skb->data);
-               offset = (unsigned long)skb->data & ~PAGE_MASK;
-               buffer_info->dma = pci_map_page(pdev, page, offset,
-                                               adapter->rx_buffer_len,
-                                               PCI_DMA_FROMDEVICE);
-               rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
-               rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len);
-               rfd_desc->coalese = 0;
-
-next:
-               rfd_next_to_use = next_next;
-               if (unlikely(++next_next == rfd_ring->count))
-                       next_next = 0;
-
-               buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
-               next_info = &rfd_ring->buffer_info[next_next];
-               num_alloc++;
-       }
-
-       if (num_alloc) {
-               /*
-                * Force memory writes to complete before letting h/w
-                * know there are new descriptors to fetch.  (Only
-                * applicable for weak-ordered memory model archs,
-                * such as IA-64).
-                */
-               wmb();
-               atomic_set(&rfd_ring->next_to_use, (int)rfd_next_to_use);
-       }
-       return num_alloc;
-}
-
-static void atl1_intr_rx(struct atl1_adapter *adapter)
-{
-       int i, count;
-       u16 length;
-       u16 rrd_next_to_clean;
-       u32 value;
-       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
-       struct atl1_buffer *buffer_info;
-       struct rx_return_desc *rrd;
-       struct sk_buff *skb;
-
-       count = 0;
-
-       rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
-
-       while (1) {
-               rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
-               i = 1;
-               if (likely(rrd->xsz.valid)) {   /* packet valid */
-chk_rrd:
-                       /* check rrd status */
-                       if (likely(rrd->num_buf == 1))
-                               goto rrd_ok;
-                       else if (netif_msg_rx_err(adapter)) {
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "unexpected RRD buffer count\n");
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "rx_buf_len = %d\n",
-                                       adapter->rx_buffer_len);
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "RRD num_buf = %d\n",
-                                       rrd->num_buf);
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "RRD pkt_len = %d\n",
-                                       rrd->xsz.xsum_sz.pkt_size);
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "RRD pkt_flg = 0x%08X\n",
-                                       rrd->pkt_flg);
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "RRD err_flg = 0x%08X\n",
-                                       rrd->err_flg);
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "RRD vlan_tag = 0x%08X\n",
-                                       rrd->vlan_tag);
-                       }
-
-                       /* rrd seems to be bad */
-                       if (unlikely(i-- > 0)) {
-                               /* rrd may not be DMAed completely */
-                               udelay(1);
-                               goto chk_rrd;
-                       }
-                       /* bad rrd */
-                       if (netif_msg_rx_err(adapter))
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "bad RRD\n");
-                       /* see if update RFD index */
-                       if (rrd->num_buf > 1)
-                               atl1_update_rfd_index(adapter, rrd);
-
-                       /* update rrd */
-                       rrd->xsz.valid = 0;
-                       if (++rrd_next_to_clean == rrd_ring->count)
-                               rrd_next_to_clean = 0;
-                       count++;
-                       continue;
-               } else {        /* current rrd still not be updated */
-
-                       break;
-               }
-rrd_ok:
-               /* clean alloc flag for bad rrd */
-               atl1_clean_alloc_flag(adapter, rrd, 0);
-
-               buffer_info = &rfd_ring->buffer_info[rrd->buf_indx];
-               if (++rfd_ring->next_to_clean == rfd_ring->count)
-                       rfd_ring->next_to_clean = 0;
-
-               /* update rrd next to clean */
-               if (++rrd_next_to_clean == rrd_ring->count)
-                       rrd_next_to_clean = 0;
-               count++;
-
-               if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
-                       if (!(rrd->err_flg &
-                               (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM
-                               | ERR_FLAG_LEN))) {
-                               /* packet error, don't need upstream */
-                               buffer_info->alloced = 0;
-                               rrd->xsz.valid = 0;
-                               continue;
-                       }
-               }
-
-               /* Good Receive */
-               pci_unmap_page(adapter->pdev, buffer_info->dma,
-                              buffer_info->length, PCI_DMA_FROMDEVICE);
-               buffer_info->dma = 0;
-               skb = buffer_info->skb;
-               length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size);
-
-               skb_put(skb, length - ETH_FCS_LEN);
-
-               /* Receive Checksum Offload */
-               atl1_rx_checksum(adapter, rrd, skb);
-               skb->protocol = eth_type_trans(skb, adapter->netdev);
-
-               if (rrd->pkt_flg & PACKET_FLAG_VLAN_INS) {
-                       u16 vlan_tag = (rrd->vlan_tag >> 4) |
-                                       ((rrd->vlan_tag & 7) << 13) |
-                                       ((rrd->vlan_tag & 8) << 9);
-
-                       __vlan_hwaccel_put_tag(skb, vlan_tag);
-               }
-               netif_rx(skb);
-
-               /* let protocol layer free skb */
-               buffer_info->skb = NULL;
-               buffer_info->alloced = 0;
-               rrd->xsz.valid = 0;
-       }
-
-       atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean);
-
-       atl1_alloc_rx_buffers(adapter);
-
-       /* update mailbox ? */
-       if (count) {
-               u32 tpd_next_to_use;
-               u32 rfd_next_to_use;
-
-               spin_lock(&adapter->mb_lock);
-
-               tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
-               rfd_next_to_use =
-                   atomic_read(&adapter->rfd_ring.next_to_use);
-               rrd_next_to_clean =
-                   atomic_read(&adapter->rrd_ring.next_to_clean);
-               value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
-                       MB_RFD_PROD_INDX_SHIFT) |
-                        ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
-                       MB_RRD_CONS_INDX_SHIFT) |
-                        ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
-                       MB_TPD_PROD_INDX_SHIFT);
-               iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
-               spin_unlock(&adapter->mb_lock);
-       }
-}
-
-static void atl1_intr_tx(struct atl1_adapter *adapter)
-{
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       struct atl1_buffer *buffer_info;
-       u16 sw_tpd_next_to_clean;
-       u16 cmb_tpd_next_to_clean;
-
-       sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
-       cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
-
-       while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
-               buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
-               if (buffer_info->dma) {
-                       pci_unmap_page(adapter->pdev, buffer_info->dma,
-                                      buffer_info->length, PCI_DMA_TODEVICE);
-                       buffer_info->dma = 0;
-               }
-
-               if (buffer_info->skb) {
-                       dev_kfree_skb_irq(buffer_info->skb);
-                       buffer_info->skb = NULL;
-               }
-
-               if (++sw_tpd_next_to_clean == tpd_ring->count)
-                       sw_tpd_next_to_clean = 0;
-       }
-       atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean);
-
-       if (netif_queue_stopped(adapter->netdev) &&
-           netif_carrier_ok(adapter->netdev))
-               netif_wake_queue(adapter->netdev);
-}
-
-static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
-{
-       u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
-       u16 next_to_use = atomic_read(&tpd_ring->next_to_use);
-       return (next_to_clean > next_to_use) ?
-               next_to_clean - next_to_use - 1 :
-               tpd_ring->count + next_to_clean - next_to_use - 1;
-}
-
-static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
-       struct tx_packet_desc *ptpd)
-{
-       u8 hdr_len, ip_off;
-       u32 real_len;
-       int err;
-
-       if (skb_shinfo(skb)->gso_size) {
-               if (skb_header_cloned(skb)) {
-                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-                       if (unlikely(err))
-                               return -1;
-               }
-
-               if (skb->protocol == htons(ETH_P_IP)) {
-                       struct iphdr *iph = ip_hdr(skb);
-
-                       real_len = (((unsigned char *)iph - skb->data) +
-                               ntohs(iph->tot_len));
-                       if (real_len < skb->len)
-                               pskb_trim(skb, real_len);
-                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
-                       if (skb->len == hdr_len) {
-                               iph->check = 0;
-                               tcp_hdr(skb)->check =
-                                       ~csum_tcpudp_magic(iph->saddr,
-                                       iph->daddr, tcp_hdrlen(skb),
-                                       IPPROTO_TCP, 0);
-                               ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
-                                       TPD_IPHL_SHIFT;
-                               ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
-                                       TPD_TCPHDRLEN_MASK) <<
-                                       TPD_TCPHDRLEN_SHIFT;
-                               ptpd->word3 |= 1 << TPD_IP_CSUM_SHIFT;
-                               ptpd->word3 |= 1 << TPD_TCP_CSUM_SHIFT;
-                               return 1;
-                       }
-
-                       iph->check = 0;
-                       tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-                                       iph->daddr, 0, IPPROTO_TCP, 0);
-                       ip_off = (unsigned char *)iph -
-                               (unsigned char *) skb_network_header(skb);
-                       if (ip_off == 8) /* 802.3-SNAP frame */
-                               ptpd->word3 |= 1 << TPD_ETHTYPE_SHIFT;
-                       else if (ip_off != 0)
-                               return -2;
-
-                       ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
-                               TPD_IPHL_SHIFT;
-                       ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
-                               TPD_TCPHDRLEN_MASK) << TPD_TCPHDRLEN_SHIFT;
-                       ptpd->word3 |= (skb_shinfo(skb)->gso_size &
-                               TPD_MSS_MASK) << TPD_MSS_SHIFT;
-                       ptpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
-                       return 3;
-               }
-       }
-       return false;
-}
-
-static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
-       struct tx_packet_desc *ptpd)
-{
-       u8 css, cso;
-
-       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-               css = skb_checksum_start_offset(skb);
-               cso = css + (u8) skb->csum_offset;
-               if (unlikely(css & 0x1)) {
-                       /* L1 hardware requires an even number here */
-                       if (netif_msg_tx_err(adapter))
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "payload offset not an even number\n");
-                       return -1;
-               }
-               ptpd->word3 |= (css & TPD_PLOADOFFSET_MASK) <<
-                       TPD_PLOADOFFSET_SHIFT;
-               ptpd->word3 |= (cso & TPD_CCSUMOFFSET_MASK) <<
-                       TPD_CCSUMOFFSET_SHIFT;
-               ptpd->word3 |= 1 << TPD_CUST_CSUM_EN_SHIFT;
-               return true;
-       }
-       return 0;
-}
-
-static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
-       struct tx_packet_desc *ptpd)
-{
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       struct atl1_buffer *buffer_info;
-       u16 buf_len = skb->len;
-       struct page *page;
-       unsigned long offset;
-       unsigned int nr_frags;
-       unsigned int f;
-       int retval;
-       u16 next_to_use;
-       u16 data_len;
-       u8 hdr_len;
-
-       buf_len -= skb->data_len;
-       nr_frags = skb_shinfo(skb)->nr_frags;
-       next_to_use = atomic_read(&tpd_ring->next_to_use);
-       buffer_info = &tpd_ring->buffer_info[next_to_use];
-       BUG_ON(buffer_info->skb);
-       /* put skb in last TPD */
-       buffer_info->skb = NULL;
-
-       retval = (ptpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
-       if (retval) {
-               /* TSO */
-               hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-               buffer_info->length = hdr_len;
-               page = virt_to_page(skb->data);
-               offset = (unsigned long)skb->data & ~PAGE_MASK;
-               buffer_info->dma = pci_map_page(adapter->pdev, page,
-                                               offset, hdr_len,
-                                               PCI_DMA_TODEVICE);
-
-               if (++next_to_use == tpd_ring->count)
-                       next_to_use = 0;
-
-               if (buf_len > hdr_len) {
-                       int i, nseg;
-
-                       data_len = buf_len - hdr_len;
-                       nseg = (data_len + ATL1_MAX_TX_BUF_LEN - 1) /
-                               ATL1_MAX_TX_BUF_LEN;
-                       for (i = 0; i < nseg; i++) {
-                               buffer_info =
-                                   &tpd_ring->buffer_info[next_to_use];
-                               buffer_info->skb = NULL;
-                               buffer_info->length =
-                                   (ATL1_MAX_TX_BUF_LEN >=
-                                    data_len) ? ATL1_MAX_TX_BUF_LEN : data_len;
-                               data_len -= buffer_info->length;
-                               page = virt_to_page(skb->data +
-                                       (hdr_len + i * ATL1_MAX_TX_BUF_LEN));
-                               offset = (unsigned long)(skb->data +
-                                       (hdr_len + i * ATL1_MAX_TX_BUF_LEN)) &
-                                       ~PAGE_MASK;
-                               buffer_info->dma = pci_map_page(adapter->pdev,
-                                       page, offset, buffer_info->length,
-                                       PCI_DMA_TODEVICE);
-                               if (++next_to_use == tpd_ring->count)
-                                       next_to_use = 0;
-                       }
-               }
-       } else {
-               /* not TSO */
-               buffer_info->length = buf_len;
-               page = virt_to_page(skb->data);
-               offset = (unsigned long)skb->data & ~PAGE_MASK;
-               buffer_info->dma = pci_map_page(adapter->pdev, page,
-                       offset, buf_len, PCI_DMA_TODEVICE);
-               if (++next_to_use == tpd_ring->count)
-                       next_to_use = 0;
-       }
-
-       for (f = 0; f < nr_frags; f++) {
-               struct skb_frag_struct *frag;
-               u16 i, nseg;
-
-               frag = &skb_shinfo(skb)->frags[f];
-               buf_len = frag->size;
-
-               nseg = (buf_len + ATL1_MAX_TX_BUF_LEN - 1) /
-                       ATL1_MAX_TX_BUF_LEN;
-               for (i = 0; i < nseg; i++) {
-                       buffer_info = &tpd_ring->buffer_info[next_to_use];
-                       BUG_ON(buffer_info->skb);
-
-                       buffer_info->skb = NULL;
-                       buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
-                               ATL1_MAX_TX_BUF_LEN : buf_len;
-                       buf_len -= buffer_info->length;
-                       buffer_info->dma = pci_map_page(adapter->pdev,
-                               frag->page,
-                               frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN),
-                               buffer_info->length, PCI_DMA_TODEVICE);
-
-                       if (++next_to_use == tpd_ring->count)
-                               next_to_use = 0;
-               }
-       }
-
-       /* last tpd's buffer-info */
-       buffer_info->skb = skb;
-}
-
-static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
-       struct tx_packet_desc *ptpd)
-{
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       struct atl1_buffer *buffer_info;
-       struct tx_packet_desc *tpd;
-       u16 j;
-       u32 val;
-       u16 next_to_use = (u16) atomic_read(&tpd_ring->next_to_use);
-
-       for (j = 0; j < count; j++) {
-               buffer_info = &tpd_ring->buffer_info[next_to_use];
-               tpd = ATL1_TPD_DESC(&adapter->tpd_ring, next_to_use);
-               if (tpd != ptpd)
-                       memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
-               tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
-               tpd->word2 &= ~(TPD_BUFLEN_MASK << TPD_BUFLEN_SHIFT);
-               tpd->word2 |= (cpu_to_le16(buffer_info->length) &
-                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
-
-               /*
-                * if this is the first packet in a TSO chain, set
-                * TPD_HDRFLAG, otherwise, clear it.
-                */
-               val = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) &
-                       TPD_SEGMENT_EN_MASK;
-               if (val) {
-                       if (!j)
-                               tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
-                       else
-                               tpd->word3 &= ~(1 << TPD_HDRFLAG_SHIFT);
-               }
-
-               if (j == (count - 1))
-                       tpd->word3 |= 1 << TPD_EOP_SHIFT;
-
-               if (++next_to_use == tpd_ring->count)
-                       next_to_use = 0;
-       }
-       /*
-        * Force memory writes to complete before letting h/w
-        * know there are new descriptors to fetch.  (Only
-        * applicable for weak-ordered memory model archs,
-        * such as IA-64).
-        */
-       wmb();
-
-       atomic_set(&tpd_ring->next_to_use, next_to_use);
-}
-
-static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
-                                        struct net_device *netdev)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-       int len;
-       int tso;
-       int count = 1;
-       int ret_val;
-       struct tx_packet_desc *ptpd;
-       u16 frag_size;
-       u16 vlan_tag;
-       unsigned int nr_frags = 0;
-       unsigned int mss = 0;
-       unsigned int f;
-       unsigned int proto_hdr_len;
-
-       len = skb_headlen(skb);
-
-       if (unlikely(skb->len <= 0)) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       nr_frags = skb_shinfo(skb)->nr_frags;
-       for (f = 0; f < nr_frags; f++) {
-               frag_size = skb_shinfo(skb)->frags[f].size;
-               if (frag_size)
-                       count += (frag_size + ATL1_MAX_TX_BUF_LEN - 1) /
-                               ATL1_MAX_TX_BUF_LEN;
-       }
-
-       mss = skb_shinfo(skb)->gso_size;
-       if (mss) {
-               if (skb->protocol == htons(ETH_P_IP)) {
-                       proto_hdr_len = (skb_transport_offset(skb) +
-                                        tcp_hdrlen(skb));
-                       if (unlikely(proto_hdr_len > len)) {
-                               dev_kfree_skb_any(skb);
-                               return NETDEV_TX_OK;
-                       }
-                       /* need additional TPD ? */
-                       if (proto_hdr_len != len)
-                               count += (len - proto_hdr_len +
-                                       ATL1_MAX_TX_BUF_LEN - 1) /
-                                       ATL1_MAX_TX_BUF_LEN;
-               }
-       }
-
-       if (atl1_tpd_avail(&adapter->tpd_ring) < count) {
-               /* not enough descriptors */
-               netif_stop_queue(netdev);
-               if (netif_msg_tx_queued(adapter))
-                       dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                               "tx busy\n");
-               return NETDEV_TX_BUSY;
-       }
-
-       ptpd = ATL1_TPD_DESC(tpd_ring,
-               (u16) atomic_read(&tpd_ring->next_to_use));
-       memset(ptpd, 0, sizeof(struct tx_packet_desc));
-
-       if (vlan_tx_tag_present(skb)) {
-               vlan_tag = vlan_tx_tag_get(skb);
-               vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
-                       ((vlan_tag >> 9) & 0x8);
-               ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
-               ptpd->word2 |= (vlan_tag & TPD_VLANTAG_MASK) <<
-                       TPD_VLANTAG_SHIFT;
-       }
-
-       tso = atl1_tso(adapter, skb, ptpd);
-       if (tso < 0) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       if (!tso) {
-               ret_val = atl1_tx_csum(adapter, skb, ptpd);
-               if (ret_val < 0) {
-                       dev_kfree_skb_any(skb);
-                       return NETDEV_TX_OK;
-               }
-       }
-
-       atl1_tx_map(adapter, skb, ptpd);
-       atl1_tx_queue(adapter, count, ptpd);
-       atl1_update_mailbox(adapter);
-       mmiowb();
-       return NETDEV_TX_OK;
-}
-
-/*
- * atl1_intr - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
- */
-static irqreturn_t atl1_intr(int irq, void *data)
-{
-       struct atl1_adapter *adapter = netdev_priv(data);
-       u32 status;
-       int max_ints = 10;
-
-       status = adapter->cmb.cmb->int_stats;
-       if (!status)
-               return IRQ_NONE;
-
-       do {
-               /* clear CMB interrupt status at once */
-               adapter->cmb.cmb->int_stats = 0;
-
-               if (status & ISR_GPHY)  /* clear phy status */
-                       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);
-
-               /* check if SMB intr */
-               if (status & ISR_SMB)
-                       atl1_inc_smb(adapter);
-
-               /* check if PCIE PHY Link down */
-               if (status & ISR_PHY_LINKDOWN) {
-                       if (netif_msg_intr(adapter))
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "pcie phy link down %x\n", status);
-                       if (netif_running(adapter->netdev)) {   /* reset MAC */
-                               iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-                               schedule_work(&adapter->pcie_dma_to_rst_task);
-                               return IRQ_HANDLED;
-                       }
-               }
-
-               /* check if DMA read/write error ? */
-               if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
-                       if (netif_msg_intr(adapter))
-                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
-                                       "pcie DMA r/w error (status = 0x%x)\n",
-                                       status);
-                       iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-                       schedule_work(&adapter->pcie_dma_to_rst_task);
-                       return IRQ_HANDLED;
-               }
-
-               /* link event */
-               if (status & ISR_GPHY) {
-                       adapter->soft_stats.tx_carrier_errors++;
-                       atl1_check_for_link(adapter);
-               }
-
-               /* transmit event */
-               if (status & ISR_CMB_TX)
-                       atl1_intr_tx(adapter);
-
-               /* rx exception */
-               if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
-                       ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
-                       ISR_HOST_RRD_OV | ISR_CMB_RX))) {
-                       if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
-                               ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
-                               ISR_HOST_RRD_OV))
-                               if (netif_msg_intr(adapter))
-                                       dev_printk(KERN_DEBUG,
-                                               &adapter->pdev->dev,
-                                               "rx exception, ISR = 0x%x\n",
-                                               status);
-                       atl1_intr_rx(adapter);
-               }
-
-               if (--max_ints < 0)
-                       break;
-
-       } while ((status = adapter->cmb.cmb->int_stats));
-
-       /* re-enable Interrupt */
-       iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
-       return IRQ_HANDLED;
-}
-
-
-/*
- * atl1_phy_config - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl1_phy_config(unsigned long data)
-{
-       struct atl1_adapter *adapter = (struct atl1_adapter *)data;
-       struct atl1_hw *hw = &adapter->hw;
-       unsigned long flags;
-
-       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_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);
-}
-
-/*
- * Orphaned vendor comment left intact here:
- * <vendor comment>
- * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
- * will assert. We do soft reset <0x1400=1> according
- * with the SPEC. BUT, it seemes that PCIE or DMA
- * state-machine will not be reset. DMAR_TO_INT will
- * assert again and again.
- * </vendor comment>
- */
-
-static int atl1_reset(struct atl1_adapter *adapter)
-{
-       int ret;
-       ret = atl1_reset_hw(&adapter->hw);
-       if (ret)
-               return ret;
-       return atl1_init_hw(&adapter->hw);
-}
-
-static s32 atl1_up(struct atl1_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       int err;
-       int irq_flags = 0;
-
-       /* hardware has been reset, we need to reload some things */
-       atlx_set_multi(netdev);
-       atl1_init_ring_ptrs(adapter);
-       atlx_restore_vlan(adapter);
-       err = atl1_alloc_rx_buffers(adapter);
-       if (unlikely(!err))
-               /* no RX BUFFER allocated */
-               return -ENOMEM;
-
-       if (unlikely(atl1_configure(adapter))) {
-               err = -EIO;
-               goto err_up;
-       }
-
-       err = pci_enable_msi(adapter->pdev);
-       if (err) {
-               if (netif_msg_ifup(adapter))
-                       dev_info(&adapter->pdev->dev,
-                               "Unable to enable MSI: %d\n", err);
-               irq_flags |= IRQF_SHARED;
-       }
-
-       err = request_irq(adapter->pdev->irq, atl1_intr, irq_flags,
-                       netdev->name, netdev);
-       if (unlikely(err))
-               goto err_up;
-
-       atlx_irq_enable(adapter);
-       atl1_check_link(adapter);
-       netif_start_queue(netdev);
-       return 0;
-
-err_up:
-       pci_disable_msi(adapter->pdev);
-       /* free rx_buffers */
-       atl1_clean_rx_ring(adapter);
-       return err;
-}
-
-static void atl1_down(struct atl1_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       netif_stop_queue(netdev);
-       del_timer_sync(&adapter->phy_config_timer);
-       adapter->phy_timer_pending = false;
-
-       atlx_irq_disable(adapter);
-       free_irq(adapter->pdev->irq, netdev);
-       pci_disable_msi(adapter->pdev);
-       atl1_reset_hw(&adapter->hw);
-       adapter->cmb.cmb->int_stats = 0;
-
-       adapter->link_speed = SPEED_0;
-       adapter->link_duplex = -1;
-       netif_carrier_off(netdev);
-
-       atl1_clean_tx_ring(adapter);
-       atl1_clean_rx_ring(adapter);
-}
-
-static void atl1_tx_timeout_task(struct work_struct *work)
-{
-       struct atl1_adapter *adapter =
-               container_of(work, struct atl1_adapter, tx_timeout_task);
-       struct net_device *netdev = adapter->netdev;
-
-       netif_device_detach(netdev);
-       atl1_down(adapter);
-       atl1_up(adapter);
-       netif_device_attach(netdev);
-}
-
-/*
- * atl1_change_mtu - Change the Maximum Transfer Unit
- * @netdev: network interface device structure
- * @new_mtu: new value for maximum frame size
- *
- * Returns 0 on success, negative on failure
- */
-static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       int old_mtu = netdev->mtu;
-       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
-
-       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
-           (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-               if (netif_msg_link(adapter))
-                       dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
-               return -EINVAL;
-       }
-
-       adapter->hw.max_frame_size = max_frame;
-       adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3;
-       adapter->rx_buffer_len = (max_frame + 7) & ~7;
-       adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8;
-
-       netdev->mtu = new_mtu;
-       if ((old_mtu != new_mtu) && netif_running(netdev)) {
-               atl1_down(adapter);
-               atl1_up(adapter);
-       }
-
-       return 0;
-}
-
-/*
- * atl1_open - Called when a network interface is made active
- * @netdev: network interface device structure
- *
- * Returns 0 on success, negative value on failure
- *
- * 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 atl1_open(struct net_device *netdev)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       int err;
-
-       netif_carrier_off(netdev);
-
-       /* allocate transmit descriptors */
-       err = atl1_setup_ring_resources(adapter);
-       if (err)
-               return err;
-
-       err = atl1_up(adapter);
-       if (err)
-               goto err_up;
-
-       return 0;
-
-err_up:
-       atl1_reset(adapter);
-       return err;
-}
-
-/*
- * atl1_close - Disables a network interface
- * @netdev: network interface device structure
- *
- * Returns 0, this is not allowed to fail
- *
- * 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 atl1_close(struct net_device *netdev)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       atl1_down(adapter);
-       atl1_free_ring_resources(adapter);
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int atl1_suspend(struct device *dev)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       struct atl1_hw *hw = &adapter->hw;
-       u32 ctrl = 0;
-       u32 wufc = adapter->wol;
-       u32 val;
-       u16 speed;
-       u16 duplex;
-
-       netif_device_detach(netdev);
-       if (netif_running(netdev))
-               atl1_down(adapter);
-
-       atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
-       atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
-       val = ctrl & BMSR_LSTATUS;
-       if (val)
-               wufc &= ~ATLX_WUFC_LNKC;
-       if (!wufc)
-               goto disable_wol;
-
-       if (val) {
-               val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
-               if (val) {
-                       if (netif_msg_ifdown(adapter))
-                               dev_printk(KERN_DEBUG, &pdev->dev,
-                                       "error getting speed/duplex\n");
-                       goto disable_wol;
-               }
-
-               ctrl = 0;
-
-               /* enable magic packet WOL */
-               if (wufc & ATLX_WUFC_MAG)
-                       ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
-               iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
-               ioread32(hw->hw_addr + REG_WOL_CTRL);
-
-               /* configure the mac */
-               ctrl = MAC_CTRL_RX_EN;
-               ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 :
-                       MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT);
-               if (duplex == FULL_DUPLEX)
-                       ctrl |= MAC_CTRL_DUPLX;
-               ctrl |= (((u32)adapter->hw.preamble_len &
-                       MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
-               __atlx_vlan_mode(netdev->features, &ctrl);
-               if (wufc & ATLX_WUFC_MAG)
-                       ctrl |= MAC_CTRL_BC_EN;
-               iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
-               ioread32(hw->hw_addr + REG_MAC_CTRL);
-
-               /* poke the PHY */
-               ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
-               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
-               iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
-               ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
-       } else {
-               ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
-               iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
-               ioread32(hw->hw_addr + REG_WOL_CTRL);
-               iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
-               ioread32(hw->hw_addr + REG_MAC_CTRL);
-               hw->phy_configured = false;
-       }
-
-       return 0;
-
- disable_wol:
-       iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
-       ioread32(hw->hw_addr + REG_WOL_CTRL);
-       ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
-       ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
-       iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
-       ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
-       hw->phy_configured = false;
-
-       return 0;
-}
-
-static int atl1_resume(struct device *dev)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-
-       iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
-
-       atl1_reset_hw(&adapter->hw);
-
-       if (netif_running(netdev)) {
-               adapter->cmb.cmb->int_stats = 0;
-               atl1_up(adapter);
-       }
-       netif_device_attach(netdev);
-
-       return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(atl1_pm_ops, atl1_suspend, atl1_resume);
-#define ATL1_PM_OPS    (&atl1_pm_ops)
-
-#else
-
-static int atl1_suspend(struct device *dev) { return 0; }
-
-#define ATL1_PM_OPS    NULL
-#endif
-
-static void atl1_shutdown(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-
-       atl1_suspend(&pdev->dev);
-       pci_wake_from_d3(pdev, adapter->wol);
-       pci_set_power_state(pdev, PCI_D3hot);
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void atl1_poll_controller(struct net_device *netdev)
-{
-       disable_irq(netdev->irq);
-       atl1_intr(netdev->irq, netdev);
-       enable_irq(netdev->irq);
-}
-#endif
-
-static const struct net_device_ops atl1_netdev_ops = {
-       .ndo_open               = atl1_open,
-       .ndo_stop               = atl1_close,
-       .ndo_start_xmit         = atl1_xmit_frame,
-       .ndo_set_multicast_list = atlx_set_multi,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = atl1_set_mac,
-       .ndo_change_mtu         = atl1_change_mtu,
-       .ndo_fix_features       = atlx_fix_features,
-       .ndo_set_features       = atlx_set_features,
-       .ndo_do_ioctl           = atlx_ioctl,
-       .ndo_tx_timeout         = atlx_tx_timeout,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = atl1_poll_controller,
-#endif
-};
-
-/*
- * atl1_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in atl1_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * atl1_probe 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 __devinit atl1_probe(struct pci_dev *pdev,
-       const struct pci_device_id *ent)
-{
-       struct net_device *netdev;
-       struct atl1_adapter *adapter;
-       static int cards_found = 0;
-       int err;
-
-       err = pci_enable_device(pdev);
-       if (err)
-               return err;
-
-       /*
-        * The atl1 chip can DMA to 64-bit addresses, but it uses a single
-        * shared register for the high 32 bits, so only a single, aligned,
-        * 4 GB physical address range can be used at a time.
-        *
-        * Supporting 64-bit DMA on this hardware is more trouble than it's
-        * worth.  It is far easier to limit to 32-bit DMA than update
-        * various kernel subsystems to support the mechanics required by a
-        * fixed-high-32-bit system.
-        */
-       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (err) {
-               dev_err(&pdev->dev, "no usable DMA configuration\n");
-               goto err_dma;
-       }
-       /*
-        * Mark all PCI regions associated with PCI device
-        * pdev as being reserved by owner 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
-        * pcibios_set_master to do the needed arch specific settings
-        */
-       pci_set_master(pdev);
-
-       netdev = alloc_etherdev(sizeof(struct atl1_adapter));
-       if (!netdev) {
-               err = -ENOMEM;
-               goto err_alloc_etherdev;
-       }
-       SET_NETDEV_DEV(netdev, &pdev->dev);
-
-       pci_set_drvdata(pdev, netdev);
-       adapter = netdev_priv(netdev);
-       adapter->netdev = netdev;
-       adapter->pdev = pdev;
-       adapter->hw.back = adapter;
-       adapter->msg_enable = netif_msg_init(debug, atl1_default_msg);
-
-       adapter->hw.hw_addr = pci_iomap(pdev, 0, 0);
-       if (!adapter->hw.hw_addr) {
-               err = -EIO;
-               goto err_pci_iomap;
-       }
-       /* get device revision number */
-       adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
-               (REG_MASTER_CTRL + 2));
-       if (netif_msg_probe(adapter))
-               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;
-       adapter->tpd_ring.count = ATL1_DEFAULT_TPD;
-
-       adapter->mii.dev = netdev;
-       adapter->mii.mdio_read = mdio_read;
-       adapter->mii.mdio_write = mdio_write;
-       adapter->mii.phy_id_mask = 0x1f;
-       adapter->mii.reg_num_mask = 0x1f;
-
-       netdev->netdev_ops = &atl1_netdev_ops;
-       netdev->watchdog_timeo = 5 * HZ;
-
-       netdev->ethtool_ops = &atl1_ethtool_ops;
-       adapter->bd_number = cards_found;
-
-       /* setup the private structure */
-       err = atl1_sw_init(adapter);
-       if (err)
-               goto err_common;
-
-       netdev->features = NETIF_F_HW_CSUM;
-       netdev->features |= NETIF_F_SG;
-       netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
-
-       netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO |
-                             NETIF_F_HW_VLAN_RX;
-
-       /* is this valid? see atl1_setup_mac_ctrl() */
-       netdev->features |= NETIF_F_RXCSUM;
-
-       /*
-        * patch for some L1 of old version,
-        * the final version of L1 may not need these
-        * patches
-        */
-       /* atl1_pcie_patch(adapter); */
-
-       /* really reset GPHY core */
-       iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
-
-       /*
-        * reset the controller to
-        * put the device in a known good starting state
-        */
-       if (atl1_reset_hw(&adapter->hw)) {
-               err = -EIO;
-               goto err_common;
-       }
-
-       /* copy the MAC address out of the EEPROM */
-       atl1_read_mac_addr(&adapter->hw);
-       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-
-       if (!is_valid_ether_addr(netdev->dev_addr)) {
-               err = -EIO;
-               goto err_common;
-       }
-
-       atl1_check_options(adapter);
-
-       /* pre-init the MAC, and setup link */
-       err = atl1_init_hw(&adapter->hw);
-       if (err) {
-               err = -EIO;
-               goto err_common;
-       }
-
-       atl1_pcie_patch(adapter);
-       /* assume we have no link for now */
-       netif_carrier_off(netdev);
-
-       setup_timer(&adapter->phy_config_timer, atl1_phy_config,
-                   (unsigned long)adapter);
-       adapter->phy_timer_pending = false;
-
-       INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
-
-       INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
-
-       INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
-
-       err = register_netdev(netdev);
-       if (err)
-               goto err_common;
-
-       cards_found++;
-       atl1_via_workaround(adapter);
-       return 0;
-
-err_common:
-       pci_iounmap(pdev, adapter->hw.hw_addr);
-err_pci_iomap:
-       free_netdev(netdev);
-err_alloc_etherdev:
-       pci_release_regions(pdev);
-err_dma:
-err_request_regions:
-       pci_disable_device(pdev);
-       return err;
-}
-
-/*
- * atl1_remove - Device Removal Routine
- * @pdev: PCI device information struct
- *
- * atl1_remove 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 __devexit atl1_remove(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1_adapter *adapter;
-       /* Device not available. Return. */
-       if (!netdev)
-               return;
-
-       adapter = netdev_priv(netdev);
-
-       /*
-        * 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.
-        */
-       if (memcmp(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN)) {
-               memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr,
-                       ETH_ALEN);
-               atl1_set_mac_addr(&adapter->hw);
-       }
-
-       iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
-       unregister_netdev(netdev);
-       pci_iounmap(pdev, adapter->hw.hw_addr);
-       pci_release_regions(pdev);
-       free_netdev(netdev);
-       pci_disable_device(pdev);
-}
-
-static struct pci_driver atl1_driver = {
-       .name = ATLX_DRIVER_NAME,
-       .id_table = atl1_pci_tbl,
-       .probe = atl1_probe,
-       .remove = __devexit_p(atl1_remove),
-       .shutdown = atl1_shutdown,
-       .driver.pm = ATL1_PM_OPS,
-};
-
-/*
- * atl1_exit_module - Driver Exit Cleanup Routine
- *
- * atl1_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1_exit_module(void)
-{
-       pci_unregister_driver(&atl1_driver);
-}
-
-/*
- * atl1_init_module - Driver Registration Routine
- *
- * atl1_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1_init_module(void)
-{
-       return pci_register_driver(&atl1_driver);
-}
-
-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)},
-       {"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);
-               ethtool_cmd_speed_set(ecmd, link_speed);
-               if (link_duplex == FULL_DUPLEX)
-                       ecmd->duplex = DUPLEX_FULL;
-               else
-                       ecmd->duplex = DUPLEX_HALF;
-       } else {
-               ethtool_cmd_speed_set(ecmd, -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)) {
-               if (netif_msg_link(adapter))
-                       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 {
-               u32 speed = ethtool_cmd_speed(ecmd);
-               if (speed == SPEED_1000) {
-                       if (ecmd->duplex != DUPLEX_FULL) {
-                               if (netif_msg_link(adapter))
-                                       dev_warn(&adapter->pdev->dev,
-                                               "1000M half is invalid\n");
-                               ret_val = -EINVAL;
-                               goto exit_sset;
-                       }
-                       hw->media_type = MEDIA_TYPE_1000M_FULL;
-               } else if (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;
-               if (netif_msg_link(adapter))
-                       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)) {
-               if (netif_msg_link(adapter))
-                       dev_dbg(&adapter->pdev->dev,
-                               "ethtool starting adapter\n");
-               atl1_up(adapter);
-       } else if (!ret_val) {
-               if (netif_msg_link(adapter))
-                       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);
-
-       strlcpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
-       strlcpy(drvinfo->version, ATLX_DRIVER_VERSION,
-               sizeof(drvinfo->version));
-       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-       strlcpy(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_MAGIC;
-       wol->wolopts = 0;
-       if (adapter->wol & ATLX_WUFC_MAG)
-               wol->wolopts |= WAKE_MAGIC;
-}
-
-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_UCAST | WAKE_MCAST | WAKE_BCAST |
-               WAKE_ARP | WAKE_MAGICSECURE))
-               return -EOPNOTSUPP;
-       adapter->wol = 0;
-       if (wol->wolopts & WAKE_MAGIC)
-               adapter->wol |= ATLX_WUFC_MAG;
-
-       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
-
-       return 0;
-}
-
-static u32 atl1_get_msglevel(struct net_device *netdev)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       return adapter->msg_enable;
-}
-
-static void atl1_set_msglevel(struct net_device *netdev, u32 value)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       adapter->msg_enable = value;
-}
-
-static int atl1_get_regs_len(struct net_device *netdev)
-{
-       return ATL1_REG_COUNT * sizeof(u32);
-}
-
-static void atl1_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
-       void *p)
-{
-       struct atl1_adapter *adapter = netdev_priv(netdev);
-       struct atl1_hw *hw = &adapter->hw;
-       unsigned int i;
-       u32 *regbuf = p;
-
-       for (i = 0; i < ATL1_REG_COUNT; i++) {
-               /*
-                * This switch statement avoids reserved regions
-                * of register space.
-                */
-               switch (i) {
-               case 6 ... 9:
-               case 14:
-               case 29 ... 31:
-               case 34 ... 63:
-               case 75 ... 127:
-               case 136 ... 1023:
-               case 1027 ... 1087:
-               case 1091 ... 1151:
-               case 1194 ... 1195:
-               case 1200 ... 1201:
-               case 1206 ... 1213:
-               case 1216 ... 1279:
-               case 1290 ... 1311:
-               case 1323 ... 1343:
-               case 1358 ... 1359:
-               case 1368 ... 1375:
-               case 1378 ... 1383:
-               case 1388 ... 1391:
-               case 1393 ... 1395:
-               case 1402 ... 1403:
-               case 1410 ... 1471:
-               case 1522 ... 1535:
-                       /* reserved region; don't read it */
-                       regbuf[i] = 0;
-                       break;
-               default:
-                       /* unreserved region */
-                       regbuf[i] = ioread32(hw->hw_addr + (i * sizeof(u32)));
-               }
-       }
-}
-
-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;
-       struct atl1_smb smb;
-       struct atl1_cmb cmb;
-       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;
-               /*
-                * Save SMB and CMB, since atl1_free_ring_resources
-                * will clear them.
-                */
-               smb = adapter->smb;
-               cmb = adapter->cmb;
-               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;
-               adapter->smb = smb;
-               adapter->cmb = cmb;
-
-               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;
-}
-
-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;
-}
-
-static 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_msglevel           = atl1_get_msglevel,
-       .set_msglevel           = atl1_set_msglevel,
-       .get_regs_len           = atl1_get_regs_len,
-       .get_regs               = atl1_get_regs,
-       .get_ringparam          = atl1_get_ringparam,
-       .set_ringparam          = atl1_set_ringparam,
-       .get_pauseparam         = atl1_get_pauseparam,
-       .set_pauseparam         = atl1_set_pauseparam,
-       .get_link               = ethtool_op_get_link,
-       .get_strings            = atl1_get_strings,
-       .nway_reset             = atl1_nway_reset,
-       .get_ethtool_stats      = atl1_get_ethtool_stats,
-       .get_sset_count         = atl1_get_sset_count,
-};
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
deleted file mode 100644 (file)
index 109d6da..0000000
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
- * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#ifndef ATL1_H
-#define ATL1_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"
-
-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 */
-static u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
-static void atl1_hash_set(struct atl1_hw *hw, u32 hash_value);
-static void atl1_set_mac_addr(struct atl1_hw *hw);
-static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
-       int cmd);
-static u32 atl1_check_link(struct atl1_adapter *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                       0x800
-
-/* CMB/SMB Control Register */
-#define REG_CSMB_CTRL                          0x15D0
-#define CSMB_CTRL_CMB_NOW                      1
-#define CSMB_CTRL_SMB_NOW                      2
-#define CSMB_CTRL_CMB_EN                       4
-#define CSMB_CTRL_SMB_EN                       8
-
-/* CMB DMA Write Threshold Register */
-#define REG_CMB_WRITE_TH                       0x15D4
-#define CMB_RRD_TH_SHIFT                       0
-#define CMB_RRD_TH_MASK                                0x7FF
-#define CMB_TPD_TH_SHIFT                       16
-#define CMB_TPD_TH_MASK                                0x7FF
-
-/* RX/TX count-down timer to trigger CMB-write. 2us resolution. */
-#define REG_CMB_WRITE_TIMER                    0x15D8
-#define CMB_RX_TM_SHIFT                                0
-#define CMB_RX_TM_MASK                         0xFFFF
-#define CMB_TX_TM_SHIFT                                16
-#define CMB_TX_TM_MASK                         0xFFFF
-
-/* Number of packet received since last CMB write */
-#define REG_CMB_RX_PKT_CNT                     0x15DC
-
-/* Number of packet transmitted since last CMB write */
-#define REG_CMB_TX_PKT_CNT                     0x15E0
-
-/* SMB auto DMA timer register */
-#define REG_SMB_TIMER                          0x15E4
-
-/* Mailbox Register */
-#define REG_MAILBOX                            0x15F0
-#define MB_RFD_PROD_INDX_SHIFT                 0
-#define MB_RFD_PROD_INDX_MASK                  0x7FF
-#define MB_RRD_CONS_INDX_SHIFT                 11
-#define MB_RRD_CONS_INDX_MASK                  0x7FF
-#define MB_TPD_PROD_INDX_SHIFT                 22
-#define MB_TPD_PROD_INDX_MASK                  0x3FF
-
-/* Interrupt Status Register */
-#define ISR_SMB                                        0x1
-#define ISR_TIMER                              0x2
-#define ISR_MANUAL                             0x4
-#define ISR_RXF_OV                             0x8
-#define ISR_RFD_UNRUN                          0x10
-#define ISR_RRD_OV                             0x20
-#define ISR_TXF_UNRUN                          0x40
-#define ISR_LINK                               0x80
-#define ISR_HOST_RFD_UNRUN                     0x100
-#define ISR_HOST_RRD_OV                                0x200
-#define ISR_DMAR_TO_RST                                0x400
-#define ISR_DMAW_TO_RST                                0x800
-#define ISR_GPHY                               0x1000
-#define ISR_RX_PKT                             0x10000
-#define ISR_TX_PKT                             0x20000
-#define ISR_TX_DMA                             0x40000
-#define ISR_RX_DMA                             0x80000
-#define ISR_CMB_RX                             0x100000
-#define ISR_CMB_TX                             0x200000
-#define ISR_MAC_RX                             0x400000
-#define ISR_MAC_TX                             0x800000
-#define ISR_DIS_SMB                            0x20000000
-#define ISR_DIS_DMA                            0x40000000
-
-/* Normal Interrupt mask  */
-#define IMR_NORMAL_MASK        (\
-       ISR_SMB         |\
-       ISR_GPHY        |\
-       ISR_PHY_LINKDOWN|\
-       ISR_DMAR_TO_RST |\
-       ISR_DMAW_TO_RST |\
-       ISR_CMB_TX      |\
-       ISR_CMB_RX)
-
-/* Debug Interrupt Mask  (enable all interrupt) */
-#define IMR_DEBUG_MASK (\
-       ISR_SMB         |\
-       ISR_TIMER       |\
-       ISR_MANUAL      |\
-       ISR_RXF_OV      |\
-       ISR_RFD_UNRUN   |\
-       ISR_RRD_OV      |\
-       ISR_TXF_UNRUN   |\
-       ISR_LINK        |\
-       ISR_CMB_TX      |\
-       ISR_CMB_RX      |\
-       ISR_RX_PKT      |\
-       ISR_TX_PKT      |\
-       ISR_MAC_RX      |\
-       ISR_MAC_TX)
-
-#define MEDIA_TYPE_1000M_FULL                  1
-#define MEDIA_TYPE_100M_FULL                   2
-#define MEDIA_TYPE_100M_HALF                   3
-#define MEDIA_TYPE_10M_FULL                    4
-#define MEDIA_TYPE_10M_HALF                    5
-
-#define AUTONEG_ADVERTISE_SPEED_DEFAULT                0x002F  /* All but 1000-Half */
-
-#define MAX_JUMBO_FRAME_SIZE                   10240
-
-#define ATL1_EEDUMP_LEN                                48
-
-/* Statistics counters collected by the MAC */
-struct stats_msg_block {
-       /* rx */
-       u32 rx_ok;              /* good RX packets */
-       u32 rx_bcast;           /* good RX broadcast packets */
-       u32 rx_mcast;           /* good RX multicast packets */
-       u32 rx_pause;           /* RX pause frames */
-       u32 rx_ctrl;            /* RX control packets other than pause frames */
-       u32 rx_fcs_err;         /* RX packets with bad FCS */
-       u32 rx_len_err;         /* RX packets with length != actual size */
-       u32 rx_byte_cnt;        /* good bytes received. FCS is NOT included */
-       u32 rx_runt;            /* RX packets < 64 bytes with good FCS */
-       u32 rx_frag;            /* RX packets < 64 bytes with bad FCS */
-       u32 rx_sz_64;           /* 64 byte RX packets */
-       u32 rx_sz_65_127;
-       u32 rx_sz_128_255;
-       u32 rx_sz_256_511;
-       u32 rx_sz_512_1023;
-       u32 rx_sz_1024_1518;
-       u32 rx_sz_1519_max;     /* 1519 byte to MTU RX packets */
-       u32 rx_sz_ov;           /* truncated RX packets > MTU */
-       u32 rx_rxf_ov;          /* frames dropped due to RX FIFO overflow */
-       u32 rx_rrd_ov;          /* frames dropped due to RRD overflow */
-       u32 rx_align_err;       /* alignment errors */
-       u32 rx_bcast_byte_cnt;  /* RX broadcast bytes, excluding FCS */
-       u32 rx_mcast_byte_cnt;  /* RX multicast bytes, excluding FCS */
-       u32 rx_err_addr;        /* packets dropped due to address filtering */
-
-       /* tx */
-       u32 tx_ok;              /* good TX packets */
-       u32 tx_bcast;           /* good TX broadcast packets */
-       u32 tx_mcast;           /* good TX multicast packets */
-       u32 tx_pause;           /* TX pause frames */
-       u32 tx_exc_defer;       /* TX packets deferred excessively */
-       u32 tx_ctrl;            /* TX control frames, excluding pause frames */
-       u32 tx_defer;           /* TX packets deferred */
-       u32 tx_byte_cnt;        /* bytes transmitted, FCS is NOT included */
-       u32 tx_sz_64;           /* 64 byte TX packets */
-       u32 tx_sz_65_127;
-       u32 tx_sz_128_255;
-       u32 tx_sz_256_511;
-       u32 tx_sz_512_1023;
-       u32 tx_sz_1024_1518;
-       u32 tx_sz_1519_max;     /* 1519 byte to MTU TX packets */
-       u32 tx_1_col;           /* packets TX after a single collision */
-       u32 tx_2_col;           /* packets TX after multiple collisions */
-       u32 tx_late_col;        /* TX packets with late collisions */
-       u32 tx_abort_col;       /* TX packets aborted w/excessive collisions */
-       u32 tx_underrun;        /* TX packets aborted due to TX FIFO underrun
-                                * or TRD FIFO underrun */
-       u32 tx_rd_eop;          /* reads beyond the EOP into the next frame
-                                * when TRD was not written timely */
-       u32 tx_len_err;         /* TX packets where length != actual size */
-       u32 tx_trunc;           /* TX packets truncated due to size > MTU */
-       u32 tx_bcast_byte;      /* broadcast bytes transmitted, excluding FCS */
-       u32 tx_mcast_byte;      /* multicast bytes transmitted, excluding FCS */
-       u32 smb_updated;        /* 1: SMB Updated. This is used by software to
-                                * indicate the statistics update. Software
-                                * should clear this bit after retrieving the
-                                * statistics information. */
-};
-
-/* Coalescing Message Block */
-struct coals_msg_block {
-       u32 int_stats;          /* interrupt status */
-       u16 rrd_prod_idx;       /* TRD Producer Index. */
-       u16 rfd_cons_idx;       /* RFD Consumer Index. */
-       u16 update;             /* Selene sets this bit every time it DMAs the
-                                * CMB to host memory. Software should clear
-                                * this bit when CMB info is processed. */
-       u16 tpd_cons_idx;       /* TPD Consumer Index. */
-};
-
-/* RRD descriptor */
-struct rx_return_desc {
-       u8 num_buf;     /* Number of RFD buffers used by the received packet */
-       u8 resved;
-       u16 buf_indx;   /* RFD Index of the first buffer */
-       union {
-               u32 valid;
-               struct {
-                       u16 rx_chksum;
-                       u16 pkt_size;
-               } xsum_sz;
-       } xsz;
-
-       u16 pkt_flg;    /* Packet flags */
-       u16 err_flg;    /* Error flags */
-       u16 resved2;
-       u16 vlan_tag;   /* VLAN TAG */
-};
-
-#define PACKET_FLAG_ETH_TYPE   0x0080
-#define PACKET_FLAG_VLAN_INS   0x0100
-#define PACKET_FLAG_ERR                0x0200
-#define PACKET_FLAG_IPV4       0x0400
-#define PACKET_FLAG_UDP                0x0800
-#define PACKET_FLAG_TCP                0x1000
-#define PACKET_FLAG_BCAST      0x2000
-#define PACKET_FLAG_MCAST      0x4000
-#define PACKET_FLAG_PAUSE      0x8000
-
-#define ERR_FLAG_CRC           0x0001
-#define ERR_FLAG_CODE          0x0002
-#define ERR_FLAG_DRIBBLE       0x0004
-#define ERR_FLAG_RUNT          0x0008
-#define ERR_FLAG_OV            0x0010
-#define ERR_FLAG_TRUNC         0x0020
-#define ERR_FLAG_IP_CHKSUM     0x0040
-#define ERR_FLAG_L4_CHKSUM     0x0080
-#define ERR_FLAG_LEN           0x0100
-#define ERR_FLAG_DES_ADDR      0x0200
-
-/* RFD descriptor */
-struct rx_free_desc {
-       __le64 buffer_addr;     /* Address of the descriptor's data buffer */
-       __le16 buf_len;         /* Size of the receive buffer in host memory */
-       u16 coalese;            /* Update consumer index to host after the
-                                * reception of this frame */
-       /* __packed is required */
-} __packed;
-
-/*
- * The L1 transmit packet descriptor is comprised of four 32-bit words.
- *
- *     31                                      0
- *     +---------------------------------------+
- *      |      Word 0: Buffer addr lo          |
- *      +---------------------------------------+
- *      |      Word 1: Buffer addr hi          |
- *      +---------------------------------------+
- *      |              Word 2                  |
- *      +---------------------------------------+
- *      |              Word 3                  |
- *      +---------------------------------------+
- *
- * Words 0 and 1 combine to form a 64-bit buffer address.
- *
- * Word 2 is self explanatory in the #define block below.
- *
- * Word 3 has two forms, depending upon the state of bits 3 and 4.
- * If bits 3 and 4 are both zero, then bits 14:31 are unused by the
- * hardware.  Otherwise, if either bit 3 or 4 is set, the definition
- * of bits 14:31 vary according to the following depiction.
- *
- *     0       End of packet                   0       End of packet
- *     1       Coalesce                        1       Coalesce
- *     2       Insert VLAN tag                 2       Insert VLAN tag
- *     3       Custom csum enable = 0          3       Custom csum enable = 1
- *     4       Segment enable = 1              4       Segment enable = 0
- *     5       Generate IP checksum            5       Generate IP checksum
- *     6       Generate TCP checksum           6       Generate TCP checksum
- *     7       Generate UDP checksum           7       Generate UDP checksum
- *     8       VLAN tagged                     8       VLAN tagged
- *     9       Ethernet frame type             9       Ethernet frame type
- *     10-+                                    10-+
- *     11 |    IP hdr length (10:13)           11 |    IP hdr length (10:13)
- *     12 |    (num 32-bit words)              12 |    (num 32-bit words)
- *     13-+                                    13-+
- *     14-+                                    14      Unused
- *     15 |    TCP hdr length (14:17)          15      Unused
- *     16 |    (num 32-bit words)              16-+
- *     17-+                                    17 |
- *     18      Header TPD flag                 18 |
- *     19-+                                    19 |    Payload offset
- *     20 |                                    20 |        (16:23)
- *     21 |                                    21 |
- *     22 |                                    22 |
- *     23 |                                    23-+
- *     24 |                                    24-+
- *     25 |    MSS (19:31)                     25 |
- *     26 |                                    26 |
- *     27 |                                    27 |    Custom csum offset
- *     28 |                                    28 |         (24:31)
- *     29 |                                    29 |
- *     30 |                                    30 |
- *     31-+                                    31-+
- */
-
-/* tpd word 2 */
-#define TPD_BUFLEN_MASK                0x3FFF
-#define TPD_BUFLEN_SHIFT       0
-#define TPD_DMAINT_MASK                0x0001
-#define TPD_DMAINT_SHIFT       14
-#define TPD_PKTNT_MASK         0x0001
-#define TPD_PKTINT_SHIFT       15
-#define TPD_VLANTAG_MASK       0xFFFF
-#define TPD_VLANTAG_SHIFT      16
-
-/* tpd word 3 bits 0:13 */
-#define TPD_EOP_MASK           0x0001
-#define TPD_EOP_SHIFT          0
-#define TPD_COALESCE_MASK      0x0001
-#define TPD_COALESCE_SHIFT     1
-#define TPD_INS_VL_TAG_MASK    0x0001
-#define TPD_INS_VL_TAG_SHIFT   2
-#define TPD_CUST_CSUM_EN_MASK  0x0001
-#define TPD_CUST_CSUM_EN_SHIFT 3
-#define TPD_SEGMENT_EN_MASK    0x0001
-#define TPD_SEGMENT_EN_SHIFT   4
-#define TPD_IP_CSUM_MASK       0x0001
-#define TPD_IP_CSUM_SHIFT      5
-#define TPD_TCP_CSUM_MASK      0x0001
-#define TPD_TCP_CSUM_SHIFT     6
-#define TPD_UDP_CSUM_MASK      0x0001
-#define TPD_UDP_CSUM_SHIFT     7
-#define TPD_VL_TAGGED_MASK     0x0001
-#define TPD_VL_TAGGED_SHIFT    8
-#define TPD_ETHTYPE_MASK       0x0001
-#define TPD_ETHTYPE_SHIFT      9
-#define TPD_IPHL_MASK          0x000F
-#define TPD_IPHL_SHIFT         10
-
-/* tpd word 3 bits 14:31 if segment enabled */
-#define TPD_TCPHDRLEN_MASK     0x000F
-#define TPD_TCPHDRLEN_SHIFT    14
-#define TPD_HDRFLAG_MASK       0x0001
-#define TPD_HDRFLAG_SHIFT      18
-#define TPD_MSS_MASK           0x1FFF
-#define TPD_MSS_SHIFT          19
-
-/* tpd word 3 bits 16:31 if custom csum enabled */
-#define TPD_PLOADOFFSET_MASK   0x00FF
-#define TPD_PLOADOFFSET_SHIFT  16
-#define TPD_CCSUMOFFSET_MASK   0x00FF
-#define TPD_CCSUMOFFSET_SHIFT  24
-
-struct tx_packet_desc {
-       __le64 buffer_addr;
-       __le32 word2;
-       __le32 word3;
-};
-
-/* DMA Order Settings */
-enum atl1_dma_order {
-       atl1_dma_ord_in = 1,
-       atl1_dma_ord_enh = 2,
-       atl1_dma_ord_out = 4
-};
-
-enum atl1_dma_rcb {
-       atl1_rcb_64 = 0,
-       atl1_rcb_128 = 1
-};
-
-enum atl1_dma_req_block {
-       atl1_dma_req_128 = 0,
-       atl1_dma_req_256 = 1,
-       atl1_dma_req_512 = 2,
-       atl1_dma_req_1024 = 3,
-       atl1_dma_req_2048 = 4,
-       atl1_dma_req_4096 = 5
-};
-
-#define ATL1_MAX_INTR          3
-#define ATL1_MAX_TX_BUF_LEN    0x3000  /* 12288 bytes */
-
-#define ATL1_DEFAULT_TPD       256
-#define ATL1_MAX_TPD           1024
-#define ATL1_MIN_TPD           64
-#define ATL1_DEFAULT_RFD       512
-#define ATL1_MIN_RFD           128
-#define ATL1_MAX_RFD           2048
-#define ATL1_REG_COUNT         1538
-
-#define ATL1_GET_DESC(R, i, type)      (&(((type *)((R)->desc))[i]))
-#define ATL1_RFD_DESC(R, i)    ATL1_GET_DESC(R, i, struct rx_free_desc)
-#define ATL1_TPD_DESC(R, i)    ATL1_GET_DESC(R, i, struct tx_packet_desc)
-#define ATL1_RRD_DESC(R, i)    ATL1_GET_DESC(R, i, struct rx_return_desc)
-
-/*
- * atl1_ring_header represents a single, contiguous block of DMA space
- * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
- * message blocks (cmb, smb) described below
- */
-struct atl1_ring_header {
-       void *desc;             /* virtual address */
-       dma_addr_t dma;         /* physical address*/
-       unsigned int size;      /* length in bytes */
-};
-
-/*
- * atl1_buffer is wrapper around a pointer to a socket buffer
- * so a DMA handle can be stored along with the skb
- */
-struct atl1_buffer {
-       struct sk_buff *skb;    /* socket buffer */
-       u16 length;             /* rx buffer length */
-       u16 alloced;            /* 1 if skb allocated */
-       dma_addr_t dma;
-};
-
-/* transmit packet descriptor (tpd) ring */
-struct atl1_tpd_ring {
-       void *desc;             /* descriptor ring virtual address */
-       dma_addr_t dma;         /* descriptor ring physical address */
-       u16 size;               /* descriptor ring length in bytes */
-       u16 count;              /* number of descriptors in the ring */
-       u16 hw_idx;             /* hardware index */
-       atomic_t next_to_clean;
-       atomic_t next_to_use;
-       struct atl1_buffer *buffer_info;
-};
-
-/* receive free descriptor (rfd) ring */
-struct atl1_rfd_ring {
-       void *desc;             /* descriptor ring virtual address */
-       dma_addr_t dma;         /* descriptor ring physical address */
-       u16 size;               /* descriptor ring length in bytes */
-       u16 count;              /* number of descriptors in the ring */
-       atomic_t next_to_use;
-       u16 next_to_clean;
-       struct atl1_buffer *buffer_info;
-};
-
-/* receive return descriptor (rrd) ring */
-struct atl1_rrd_ring {
-       void *desc;             /* descriptor ring virtual address */
-       dma_addr_t dma;         /* descriptor ring physical address */
-       unsigned int size;      /* descriptor ring length in bytes */
-       u16 count;              /* number of descriptors in the ring */
-       u16 next_to_use;
-       atomic_t next_to_clean;
-};
-
-/* coalescing message block (cmb) */
-struct atl1_cmb {
-       struct coals_msg_block *cmb;
-       dma_addr_t dma;
-};
-
-/* statistics message block (smb) */
-struct atl1_smb {
-       struct stats_msg_block *smb;
-       dma_addr_t dma;
-};
-
-/* Statistics counters */
-struct atl1_sft_stats {
-       u64 rx_packets;
-       u64 tx_packets;
-       u64 rx_bytes;
-       u64 tx_bytes;
-       u64 multicast;
-       u64 collisions;
-       u64 rx_errors;
-       u64 rx_length_errors;
-       u64 rx_crc_errors;
-       u64 rx_frame_errors;
-       u64 rx_fifo_errors;
-       u64 rx_missed_errors;
-       u64 tx_errors;
-       u64 tx_fifo_errors;
-       u64 tx_aborted_errors;
-       u64 tx_window_errors;
-       u64 tx_carrier_errors;
-       u64 tx_pause;           /* TX pause frames */
-       u64 excecol;            /* TX packets w/ excessive collisions */
-       u64 deffer;             /* TX packets deferred */
-       u64 scc;                /* packets TX after a single collision */
-       u64 mcc;                /* packets TX after multiple collisions */
-       u64 latecol;            /* TX packets w/ late collisions */
-       u64 tx_underun;         /* TX packets aborted due to TX FIFO underrun
-                                * or TRD FIFO underrun */
-       u64 tx_trunc;           /* TX packets truncated due to size > MTU */
-       u64 rx_pause;           /* num Pause packets received. */
-       u64 rx_rrd_ov;
-       u64 rx_trunc;
-};
-
-/* hardware structure */
-struct atl1_hw {
-       u8 __iomem *hw_addr;
-       struct atl1_adapter *back;
-       enum atl1_dma_order dma_ord;
-       enum atl1_dma_rcb rcb_value;
-       enum atl1_dma_req_block dmar_block;
-       enum atl1_dma_req_block dmaw_block;
-       u8 preamble_len;
-       u8 max_retry;
-       u8 jam_ipg;             /* IPG to start JAM for collision based flow
-                                * control in half-duplex mode. In units of
-                                * 8-bit time */
-       u8 ipgt;                /* Desired back to back inter-packet gap.
-                                * The default is 96-bit time */
-       u8 min_ifg;             /* Minimum number of IFG to enforce in between
-                                * receive frames. Frame gap below such IFP
-                                * is dropped */
-       u8 ipgr1;               /* 64bit Carrier-Sense window */
-       u8 ipgr2;               /* 96-bit IPG window */
-       u8 tpd_burst;           /* Number of TPD to prefetch in cache-aligned
-                                * burst. Each TPD is 16 bytes long */
-       u8 rfd_burst;           /* Number of RFD to prefetch in cache-aligned
-                                * burst. Each RFD is 12 bytes long */
-       u8 rfd_fetch_gap;
-       u8 rrd_burst;           /* Threshold number of RRDs that can be retired
-                                * in a burst. Each RRD is 16 bytes long */
-       u8 tpd_fetch_th;
-       u8 tpd_fetch_gap;
-       u16 tx_jumbo_task_th;
-       u16 txf_burst;          /* Number of data bytes to read in a cache-
-                                * aligned burst. Each SRAM entry is 8 bytes */
-       u16 rx_jumbo_th;        /* Jumbo packet size for non-VLAN packet. VLAN
-                                * packets should add 4 bytes */
-       u16 rx_jumbo_lkah;
-       u16 rrd_ret_timer;      /* RRD retirement timer. Decrement by 1 after
-                                * every 512ns passes. */
-       u16 lcol;               /* Collision Window */
-
-       u16 cmb_tpd;
-       u16 cmb_rrd;
-       u16 cmb_rx_timer;
-       u16 cmb_tx_timer;
-       u32 smb_timer;
-       u16 media_type;
-       u16 autoneg_advertised;
-
-       u16 mii_autoneg_adv_reg;
-       u16 mii_1000t_ctrl_reg;
-
-       u32 max_frame_size;
-       u32 min_frame_size;
-
-       u16 dev_rev;
-
-       /* spi flash */
-       u8 flash_vendor;
-
-       u8 mac_addr[ETH_ALEN];
-       u8 perm_mac_addr[ETH_ALEN];
-
-       bool phy_configured;
-};
-
-struct atl1_adapter {
-       struct net_device *netdev;
-       struct pci_dev *pdev;
-
-       struct atl1_sft_stats soft_stats;
-       u32 rx_buffer_len;
-       u32 wol;
-       u16 link_speed;
-       u16 link_duplex;
-       spinlock_t lock;
-       struct work_struct tx_timeout_task;
-       struct work_struct link_chg_task;
-       struct work_struct pcie_dma_to_rst_task;
-
-       struct timer_list phy_config_timer;
-       bool phy_timer_pending;
-
-       /* all descriptor rings' memory */
-       struct atl1_ring_header ring_header;
-
-       /* TX */
-       struct atl1_tpd_ring tpd_ring;
-       spinlock_t mb_lock;
-
-       /* RX */
-       struct atl1_rfd_ring rfd_ring;
-       struct atl1_rrd_ring rrd_ring;
-       u64 hw_csum_err;
-       u64 hw_csum_good;
-       u32 msg_enable;
-       u16 imt;                /* interrupt moderator timer (2us resolution) */
-       u16 ict;                /* interrupt clear timer (2us resolution */
-       struct mii_if_info mii; /* MII interface info */
-
-       u32 bd_number;          /* board number */
-       bool pci_using_64;
-       struct atl1_hw hw;
-       struct atl1_smb smb;
-       struct atl1_cmb cmb;
-};
-
-#endif /* ATL1_H */
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
deleted file mode 100644 (file)
index d4f7dda..0000000
+++ /dev/null
@@ -1,3119 +0,0 @@
-/*
- * Copyright(c) 2006 - 2007 Atheros Corporation. All rights reserved.
- * Copyright(c) 2007 - 2008 Chris Snook <csnook@redhat.com>
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#include <linux/atomic.h>
-#include <linux/crc32.h>
-#include <linux/dma-mapping.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/hardirq.h>
-#include <linux/if_vlan.h>
-#include <linux/in.h>
-#include <linux/interrupt.h>
-#include <linux/ip.h>
-#include <linux/irqflags.h>
-#include <linux/irqreturn.h>
-#include <linux/mii.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/pm.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/tcp.h>
-#include <linux/timer.h>
-#include <linux/types.h>
-#include <linux/workqueue.h>
-
-#include "atl2.h"
-
-#define ATL2_DRV_VERSION "2.2.3"
-
-static const char atl2_driver_name[] = "atl2";
-static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver";
-static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation.";
-static const char atl2_driver_version[] = ATL2_DRV_VERSION;
-
-MODULE_AUTHOR("Atheros Corporation <xiong.huang@atheros.com>, Chris Snook <csnook@redhat.com>");
-MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ATL2_DRV_VERSION);
-
-/*
- * atl2_pci_tbl - PCI Device ID Table
- */
-static DEFINE_PCI_DEVICE_TABLE(atl2_pci_tbl) = {
-       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2)},
-       /* required last entry */
-       {0,}
-};
-MODULE_DEVICE_TABLE(pci, atl2_pci_tbl);
-
-static void atl2_set_ethtool_ops(struct net_device *netdev);
-
-static void atl2_check_options(struct atl2_adapter *adapter);
-
-/*
- * atl2_sw_init - Initialize general software structures (struct atl2_adapter)
- * @adapter: board private structure to initialize
- *
- * atl2_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 __devinit atl2_sw_init(struct atl2_adapter *adapter)
-{
-       struct atl2_hw *hw = &adapter->hw;
-       struct pci_dev *pdev = adapter->pdev;
-
-       /* PCI config space info */
-       hw->vendor_id = pdev->vendor;
-       hw->device_id = pdev->device;
-       hw->subsystem_vendor_id = pdev->subsystem_vendor;
-       hw->subsystem_id = pdev->subsystem_device;
-       hw->revision_id  = pdev->revision;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
-
-       adapter->wol = 0;
-       adapter->ict = 50000;  /* ~100ms */
-       adapter->link_speed = SPEED_0;   /* hardware init */
-       adapter->link_duplex = FULL_DUPLEX;
-
-       hw->phy_configured = false;
-       hw->preamble_len = 7;
-       hw->ipgt = 0x60;
-       hw->min_ifg = 0x50;
-       hw->ipgr1 = 0x40;
-       hw->ipgr2 = 0x60;
-       hw->retry_buf = 2;
-       hw->max_retry = 0xf;
-       hw->lcol = 0x37;
-       hw->jam_ipg = 7;
-       hw->fc_rxd_hi = 0;
-       hw->fc_rxd_lo = 0;
-       hw->max_frame_size = adapter->netdev->mtu;
-
-       spin_lock_init(&adapter->stats_lock);
-
-       set_bit(__ATL2_DOWN, &adapter->flags);
-
-       return 0;
-}
-
-/*
- * atl2_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 atl2_set_multi(struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-       struct netdev_hw_addr *ha;
-       u32 rctl;
-       u32 hash_value;
-
-       /* Check for Promiscuous and All Multicast modes */
-       rctl = ATL2_READ_REG(hw, 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);
-
-       ATL2_WRITE_REG(hw, REG_MAC_CTRL, rctl);
-
-       /* clear the old settings from the multicast hash table */
-       ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
-       ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
-
-       /* comoute mc addresses' hash value ,and put it into hash table */
-       netdev_for_each_mc_addr(ha, netdev) {
-               hash_value = atl2_hash_mc_addr(hw, ha->addr);
-               atl2_hash_set(hw, hash_value);
-       }
-}
-
-static void init_ring_ptrs(struct atl2_adapter *adapter)
-{
-       /* Read / Write Ptr Initialize: */
-       adapter->txd_write_ptr = 0;
-       atomic_set(&adapter->txd_read_ptr, 0);
-
-       adapter->rxd_read_ptr = 0;
-       adapter->rxd_write_ptr = 0;
-
-       atomic_set(&adapter->txs_write_ptr, 0);
-       adapter->txs_next_clear = 0;
-}
-
-/*
- * atl2_configure - Configure Transmit&Receive Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx /Rx unit of the MAC after a reset.
- */
-static int atl2_configure(struct atl2_adapter *adapter)
-{
-       struct atl2_hw *hw = &adapter->hw;
-       u32 value;
-
-       /* clear interrupt status */
-       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0xffffffff);
-
-       /* set MAC Address */
-       value = (((u32)hw->mac_addr[2]) << 24) |
-               (((u32)hw->mac_addr[3]) << 16) |
-               (((u32)hw->mac_addr[4]) << 8) |
-               (((u32)hw->mac_addr[5]));
-       ATL2_WRITE_REG(hw, REG_MAC_STA_ADDR, value);
-       value = (((u32)hw->mac_addr[0]) << 8) |
-               (((u32)hw->mac_addr[1]));
-       ATL2_WRITE_REG(hw, (REG_MAC_STA_ADDR+4), value);
-
-       /* HI base address */
-       ATL2_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI,
-               (u32)((adapter->ring_dma & 0xffffffff00000000ULL) >> 32));
-
-       /* LO base address */
-       ATL2_WRITE_REG(hw, REG_TXD_BASE_ADDR_LO,
-               (u32)(adapter->txd_dma & 0x00000000ffffffffULL));
-       ATL2_WRITE_REG(hw, REG_TXS_BASE_ADDR_LO,
-               (u32)(adapter->txs_dma & 0x00000000ffffffffULL));
-       ATL2_WRITE_REG(hw, REG_RXD_BASE_ADDR_LO,
-               (u32)(adapter->rxd_dma & 0x00000000ffffffffULL));
-
-       /* element count */
-       ATL2_WRITE_REGW(hw, REG_TXD_MEM_SIZE, (u16)(adapter->txd_ring_size/4));
-       ATL2_WRITE_REGW(hw, REG_TXS_MEM_SIZE, (u16)adapter->txs_ring_size);
-       ATL2_WRITE_REGW(hw, REG_RXD_BUF_NUM,  (u16)adapter->rxd_ring_size);
-
-       /* config Internal SRAM */
-/*
-    ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_tx_end);
-    ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_rx_end);
-*/
-
-       /* config IPG/IFG */
-       value = (((u32)hw->ipgt & MAC_IPG_IFG_IPGT_MASK) <<
-               MAC_IPG_IFG_IPGT_SHIFT) |
-               (((u32)hw->min_ifg & MAC_IPG_IFG_MIFG_MASK) <<
-               MAC_IPG_IFG_MIFG_SHIFT) |
-               (((u32)hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK) <<
-               MAC_IPG_IFG_IPGR1_SHIFT)|
-               (((u32)hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK) <<
-               MAC_IPG_IFG_IPGR2_SHIFT);
-       ATL2_WRITE_REG(hw, REG_MAC_IPG_IFG, value);
-
-       /* config  Half-Duplex Control */
-       value = ((u32)hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) |
-               (((u32)hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK) <<
-               MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) |
-               MAC_HALF_DUPLX_CTRL_EXC_DEF_EN |
-               (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) |
-               (((u32)hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) <<
-               MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT);
-       ATL2_WRITE_REG(hw, REG_MAC_HALF_DUPLX_CTRL, value);
-
-       /* set Interrupt Moderator Timer */
-       ATL2_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, adapter->imt);
-       ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_ITIMER_EN);
-
-       /* set Interrupt Clear Timer */
-       ATL2_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, adapter->ict);
-
-       /* set MTU */
-       ATL2_WRITE_REG(hw, REG_MTU, adapter->netdev->mtu +
-               ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE);
-
-       /* 1590 */
-       ATL2_WRITE_REG(hw, REG_TX_CUT_THRESH, 0x177);
-
-       /* flow control */
-       ATL2_WRITE_REGW(hw, REG_PAUSE_ON_TH, hw->fc_rxd_hi);
-       ATL2_WRITE_REGW(hw, REG_PAUSE_OFF_TH, hw->fc_rxd_lo);
-
-       /* Init mailbox */
-       ATL2_WRITE_REGW(hw, REG_MB_TXD_WR_IDX, (u16)adapter->txd_write_ptr);
-       ATL2_WRITE_REGW(hw, REG_MB_RXD_RD_IDX, (u16)adapter->rxd_read_ptr);
-
-       /* enable DMA read/write */
-       ATL2_WRITE_REGB(hw, REG_DMAR, DMAR_EN);
-       ATL2_WRITE_REGB(hw, REG_DMAW, DMAW_EN);
-
-       value = ATL2_READ_REG(&adapter->hw, REG_ISR);
-       if ((value & ISR_PHY_LINKDOWN) != 0)
-               value = 1; /* config failed */
-       else
-               value = 0;
-
-       /* clear all interrupt status */
-       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0x3fffffff);
-       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0);
-       return value;
-}
-
-/*
- * atl2_setup_ring_resources - allocate Tx / RX descriptor resources
- * @adapter: board private structure
- *
- * Return 0 on success, negative on failure
- */
-static s32 atl2_setup_ring_resources(struct atl2_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       int size;
-       u8 offset = 0;
-
-       /* real ring DMA buffer */
-       adapter->ring_size = size =
-               adapter->txd_ring_size * 1 + 7 +        /* dword align */
-               adapter->txs_ring_size * 4 + 7 +        /* dword align */
-               adapter->rxd_ring_size * 1536 + 127;    /* 128bytes align */
-
-       adapter->ring_vir_addr = pci_alloc_consistent(pdev, size,
-               &adapter->ring_dma);
-       if (!adapter->ring_vir_addr)
-               return -ENOMEM;
-       memset(adapter->ring_vir_addr, 0, adapter->ring_size);
-
-       /* Init TXD Ring */
-       adapter->txd_dma = adapter->ring_dma ;
-       offset = (adapter->txd_dma & 0x7) ? (8 - (adapter->txd_dma & 0x7)) : 0;
-       adapter->txd_dma += offset;
-       adapter->txd_ring = adapter->ring_vir_addr + offset;
-
-       /* Init TXS Ring */
-       adapter->txs_dma = adapter->txd_dma + adapter->txd_ring_size;
-       offset = (adapter->txs_dma & 0x7) ? (8 - (adapter->txs_dma & 0x7)) : 0;
-       adapter->txs_dma += offset;
-       adapter->txs_ring = (struct tx_pkt_status *)
-               (((u8 *)adapter->txd_ring) + (adapter->txd_ring_size + offset));
-
-       /* Init RXD Ring */
-       adapter->rxd_dma = adapter->txs_dma + adapter->txs_ring_size * 4;
-       offset = (adapter->rxd_dma & 127) ?
-               (128 - (adapter->rxd_dma & 127)) : 0;
-       if (offset > 7)
-               offset -= 8;
-       else
-               offset += (128 - 8);
-
-       adapter->rxd_dma += offset;
-       adapter->rxd_ring = (struct rx_desc *) (((u8 *)adapter->txs_ring) +
-               (adapter->txs_ring_size * 4 + offset));
-
-/*
- * Read / Write Ptr Initialize:
- *      init_ring_ptrs(adapter);
- */
-       return 0;
-}
-
-/*
- * atl2_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- */
-static inline void atl2_irq_enable(struct atl2_adapter *adapter)
-{
-       ATL2_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK);
-       ATL2_WRITE_FLUSH(&adapter->hw);
-}
-
-/*
- * atl2_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- */
-static inline void atl2_irq_disable(struct atl2_adapter *adapter)
-{
-    ATL2_WRITE_REG(&adapter->hw, REG_IMR, 0);
-    ATL2_WRITE_FLUSH(&adapter->hw);
-    synchronize_irq(adapter->pdev->irq);
-}
-
-static void __atl2_vlan_mode(u32 features, u32 *ctrl)
-{
-       if (features & NETIF_F_HW_VLAN_RX) {
-               /* enable VLAN tag insert/strip */
-               *ctrl |= MAC_CTRL_RMV_VLAN;
-       } else {
-               /* disable VLAN tag insert/strip */
-               *ctrl &= ~MAC_CTRL_RMV_VLAN;
-       }
-}
-
-static void atl2_vlan_mode(struct net_device *netdev, u32 features)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       u32 ctrl;
-
-       atl2_irq_disable(adapter);
-
-       ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL);
-       __atl2_vlan_mode(features, &ctrl);
-       ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl);
-
-       atl2_irq_enable(adapter);
-}
-
-static void atl2_restore_vlan(struct atl2_adapter *adapter)
-{
-       atl2_vlan_mode(adapter->netdev, adapter->netdev->features);
-}
-
-static u32 atl2_fix_features(struct net_device *netdev, u32 features)
-{
-       /*
-        * Since there is no support for separate rx/tx vlan accel
-        * enable/disable make sure tx flag is always in same state as rx.
-        */
-       if (features & NETIF_F_HW_VLAN_RX)
-               features |= NETIF_F_HW_VLAN_TX;
-       else
-               features &= ~NETIF_F_HW_VLAN_TX;
-
-       return features;
-}
-
-static int atl2_set_features(struct net_device *netdev, u32 features)
-{
-       u32 changed = netdev->features ^ features;
-
-       if (changed & NETIF_F_HW_VLAN_RX)
-               atl2_vlan_mode(netdev, features);
-
-       return 0;
-}
-
-static void atl2_intr_rx(struct atl2_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       struct rx_desc *rxd;
-       struct sk_buff *skb;
-
-       do {
-               rxd = adapter->rxd_ring+adapter->rxd_write_ptr;
-               if (!rxd->status.update)
-                       break; /* end of tx */
-
-               /* clear this flag at once */
-               rxd->status.update = 0;
-
-               if (rxd->status.ok && rxd->status.pkt_size >= 60) {
-                       int rx_size = (int)(rxd->status.pkt_size - 4);
-                       /* alloc new buffer */
-                       skb = netdev_alloc_skb_ip_align(netdev, rx_size);
-                       if (NULL == skb) {
-                               printk(KERN_WARNING
-                                       "%s: Mem squeeze, deferring packet.\n",
-                                       netdev->name);
-                               /*
-                                * Check that some rx space is free. If not,
-                                * free one and mark stats->rx_dropped++.
-                                */
-                               netdev->stats.rx_dropped++;
-                               break;
-                       }
-                       memcpy(skb->data, rxd->packet, rx_size);
-                       skb_put(skb, rx_size);
-                       skb->protocol = eth_type_trans(skb, netdev);
-                       if (rxd->status.vlan) {
-                               u16 vlan_tag = (rxd->status.vtag>>4) |
-                                       ((rxd->status.vtag&7) << 13) |
-                                       ((rxd->status.vtag&8) << 9);
-
-                               __vlan_hwaccel_put_tag(skb, vlan_tag);
-                       }
-                       netif_rx(skb);
-                       netdev->stats.rx_bytes += rx_size;
-                       netdev->stats.rx_packets++;
-               } else {
-                       netdev->stats.rx_errors++;
-
-                       if (rxd->status.ok && rxd->status.pkt_size <= 60)
-                               netdev->stats.rx_length_errors++;
-                       if (rxd->status.mcast)
-                               netdev->stats.multicast++;
-                       if (rxd->status.crc)
-                               netdev->stats.rx_crc_errors++;
-                       if (rxd->status.align)
-                               netdev->stats.rx_frame_errors++;
-               }
-
-               /* advance write ptr */
-               if (++adapter->rxd_write_ptr == adapter->rxd_ring_size)
-                       adapter->rxd_write_ptr = 0;
-       } while (1);
-
-       /* update mailbox? */
-       adapter->rxd_read_ptr = adapter->rxd_write_ptr;
-       ATL2_WRITE_REGW(&adapter->hw, REG_MB_RXD_RD_IDX, adapter->rxd_read_ptr);
-}
-
-static void atl2_intr_tx(struct atl2_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       u32 txd_read_ptr;
-       u32 txs_write_ptr;
-       struct tx_pkt_status *txs;
-       struct tx_pkt_header *txph;
-       int free_hole = 0;
-
-       do {
-               txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr);
-               txs = adapter->txs_ring + txs_write_ptr;
-               if (!txs->update)
-                       break; /* tx stop here */
-
-               free_hole = 1;
-               txs->update = 0;
-
-               if (++txs_write_ptr == adapter->txs_ring_size)
-                       txs_write_ptr = 0;
-               atomic_set(&adapter->txs_write_ptr, (int)txs_write_ptr);
-
-               txd_read_ptr = (u32) atomic_read(&adapter->txd_read_ptr);
-               txph = (struct tx_pkt_header *)
-                       (((u8 *)adapter->txd_ring) + txd_read_ptr);
-
-               if (txph->pkt_size != txs->pkt_size) {
-                       struct tx_pkt_status *old_txs = txs;
-                       printk(KERN_WARNING
-                               "%s: txs packet size not consistent with txd"
-                               " txd_:0x%08x, txs_:0x%08x!\n",
-                               adapter->netdev->name,
-                               *(u32 *)txph, *(u32 *)txs);
-                       printk(KERN_WARNING
-                               "txd read ptr: 0x%x\n",
-                               txd_read_ptr);
-                       txs = adapter->txs_ring + txs_write_ptr;
-                       printk(KERN_WARNING
-                               "txs-behind:0x%08x\n",
-                               *(u32 *)txs);
-                       if (txs_write_ptr < 2) {
-                               txs = adapter->txs_ring +
-                                       (adapter->txs_ring_size +
-                                       txs_write_ptr - 2);
-                       } else {
-                               txs = adapter->txs_ring + (txs_write_ptr - 2);
-                       }
-                       printk(KERN_WARNING
-                               "txs-before:0x%08x\n",
-                               *(u32 *)txs);
-                       txs = old_txs;
-               }
-
-                /* 4for TPH */
-               txd_read_ptr += (((u32)(txph->pkt_size) + 7) & ~3);
-               if (txd_read_ptr >= adapter->txd_ring_size)
-                       txd_read_ptr -= adapter->txd_ring_size;
-
-               atomic_set(&adapter->txd_read_ptr, (int)txd_read_ptr);
-
-               /* tx statistics: */
-               if (txs->ok) {
-                       netdev->stats.tx_bytes += txs->pkt_size;
-                       netdev->stats.tx_packets++;
-               }
-               else
-                       netdev->stats.tx_errors++;
-
-               if (txs->defer)
-                       netdev->stats.collisions++;
-               if (txs->abort_col)
-                       netdev->stats.tx_aborted_errors++;
-               if (txs->late_col)
-                       netdev->stats.tx_window_errors++;
-               if (txs->underun)
-                       netdev->stats.tx_fifo_errors++;
-       } while (1);
-
-       if (free_hole) {
-               if (netif_queue_stopped(adapter->netdev) &&
-                       netif_carrier_ok(adapter->netdev))
-                       netif_wake_queue(adapter->netdev);
-       }
-}
-
-static void atl2_check_for_link(struct atl2_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       u16 phy_data = 0;
-
-       spin_lock(&adapter->stats_lock);
-       atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-       atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-       spin_unlock(&adapter->stats_lock);
-
-       /* notify upper layer link down ASAP */
-       if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */
-               if (netif_carrier_ok(netdev)) { /* old link state: Up */
-               printk(KERN_INFO "%s: %s NIC Link is Down\n",
-                       atl2_driver_name, netdev->name);
-               adapter->link_speed = SPEED_0;
-               netif_carrier_off(netdev);
-               netif_stop_queue(netdev);
-               }
-       }
-       schedule_work(&adapter->link_chg_task);
-}
-
-static inline void atl2_clear_phy_int(struct atl2_adapter *adapter)
-{
-       u16 phy_data;
-       spin_lock(&adapter->stats_lock);
-       atl2_read_phy_reg(&adapter->hw, 19, &phy_data);
-       spin_unlock(&adapter->stats_lock);
-}
-
-/*
- * atl2_intr - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
- */
-static irqreturn_t atl2_intr(int irq, void *data)
-{
-       struct atl2_adapter *adapter = netdev_priv(data);
-       struct atl2_hw *hw = &adapter->hw;
-       u32 status;
-
-       status = ATL2_READ_REG(hw, REG_ISR);
-       if (0 == status)
-               return IRQ_NONE;
-
-       /* link event */
-       if (status & ISR_PHY)
-               atl2_clear_phy_int(adapter);
-
-       /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
-       ATL2_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
-
-       /* check if PCIE PHY Link down */
-       if (status & ISR_PHY_LINKDOWN) {
-               if (netif_running(adapter->netdev)) { /* reset MAC */
-                       ATL2_WRITE_REG(hw, REG_ISR, 0);
-                       ATL2_WRITE_REG(hw, REG_IMR, 0);
-                       ATL2_WRITE_FLUSH(hw);
-                       schedule_work(&adapter->reset_task);
-                       return IRQ_HANDLED;
-               }
-       }
-
-       /* check if DMA read/write error? */
-       if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
-               ATL2_WRITE_REG(hw, REG_ISR, 0);
-               ATL2_WRITE_REG(hw, REG_IMR, 0);
-               ATL2_WRITE_FLUSH(hw);
-               schedule_work(&adapter->reset_task);
-               return IRQ_HANDLED;
-       }
-
-       /* link event */
-       if (status & (ISR_PHY | ISR_MANUAL)) {
-               adapter->netdev->stats.tx_carrier_errors++;
-               atl2_check_for_link(adapter);
-       }
-
-       /* transmit event */
-       if (status & ISR_TX_EVENT)
-               atl2_intr_tx(adapter);
-
-       /* rx exception */
-       if (status & ISR_RX_EVENT)
-               atl2_intr_rx(adapter);
-
-       /* re-enable Interrupt */
-       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0);
-       return IRQ_HANDLED;
-}
-
-static int atl2_request_irq(struct atl2_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       int flags, err = 0;
-
-       flags = IRQF_SHARED;
-       adapter->have_msi = true;
-       err = pci_enable_msi(adapter->pdev);
-       if (err)
-               adapter->have_msi = false;
-
-       if (adapter->have_msi)
-               flags &= ~IRQF_SHARED;
-
-       return request_irq(adapter->pdev->irq, atl2_intr, flags, netdev->name,
-               netdev);
-}
-
-/*
- * atl2_free_ring_resources - Free Tx / RX descriptor Resources
- * @adapter: board private structure
- *
- * Free all transmit software resources
- */
-static void atl2_free_ring_resources(struct atl2_adapter *adapter)
-{
-       struct pci_dev *pdev = adapter->pdev;
-       pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr,
-               adapter->ring_dma);
-}
-
-/*
- * atl2_open - Called when a network interface is made active
- * @netdev: network interface device structure
- *
- * Returns 0 on success, negative value on failure
- *
- * 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 atl2_open(struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       int err;
-       u32 val;
-
-       /* disallow open during test */
-       if (test_bit(__ATL2_TESTING, &adapter->flags))
-               return -EBUSY;
-
-       /* allocate transmit descriptors */
-       err = atl2_setup_ring_resources(adapter);
-       if (err)
-               return err;
-
-       err = atl2_init_hw(&adapter->hw);
-       if (err) {
-               err = -EIO;
-               goto err_init_hw;
-       }
-
-       /* hardware has been reset, we need to reload some things */
-       atl2_set_multi(netdev);
-       init_ring_ptrs(adapter);
-
-       atl2_restore_vlan(adapter);
-
-       if (atl2_configure(adapter)) {
-               err = -EIO;
-               goto err_config;
-       }
-
-       err = atl2_request_irq(adapter);
-       if (err)
-               goto err_req_irq;
-
-       clear_bit(__ATL2_DOWN, &adapter->flags);
-
-       mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 4*HZ));
-
-       val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL);
-       ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
-               val | MASTER_CTRL_MANUAL_INT);
-
-       atl2_irq_enable(adapter);
-
-       return 0;
-
-err_init_hw:
-err_req_irq:
-err_config:
-       atl2_free_ring_resources(adapter);
-       atl2_reset_hw(&adapter->hw);
-
-       return err;
-}
-
-static void atl2_down(struct atl2_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       /* signal that we're down so the interrupt handler does not
-        * reschedule our watchdog timer */
-       set_bit(__ATL2_DOWN, &adapter->flags);
-
-       netif_tx_disable(netdev);
-
-       /* reset MAC to disable all RX/TX */
-       atl2_reset_hw(&adapter->hw);
-       msleep(1);
-
-       atl2_irq_disable(adapter);
-
-       del_timer_sync(&adapter->watchdog_timer);
-       del_timer_sync(&adapter->phy_config_timer);
-       clear_bit(0, &adapter->cfg_phy);
-
-       netif_carrier_off(netdev);
-       adapter->link_speed = SPEED_0;
-       adapter->link_duplex = -1;
-}
-
-static void atl2_free_irq(struct atl2_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       free_irq(adapter->pdev->irq, netdev);
-
-#ifdef CONFIG_PCI_MSI
-       if (adapter->have_msi)
-               pci_disable_msi(adapter->pdev);
-#endif
-}
-
-/*
- * atl2_close - Disables a network interface
- * @netdev: network interface device structure
- *
- * Returns 0, this is not allowed to fail
- *
- * 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 atl2_close(struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-
-       WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags));
-
-       atl2_down(adapter);
-       atl2_free_irq(adapter);
-       atl2_free_ring_resources(adapter);
-
-       return 0;
-}
-
-static inline int TxsFreeUnit(struct atl2_adapter *adapter)
-{
-       u32 txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr);
-
-       return (adapter->txs_next_clear >= txs_write_ptr) ?
-               (int) (adapter->txs_ring_size - adapter->txs_next_clear +
-               txs_write_ptr - 1) :
-               (int) (txs_write_ptr - adapter->txs_next_clear - 1);
-}
-
-static inline int TxdFreeBytes(struct atl2_adapter *adapter)
-{
-       u32 txd_read_ptr = (u32)atomic_read(&adapter->txd_read_ptr);
-
-       return (adapter->txd_write_ptr >= txd_read_ptr) ?
-               (int) (adapter->txd_ring_size - adapter->txd_write_ptr +
-               txd_read_ptr - 1) :
-               (int) (txd_read_ptr - adapter->txd_write_ptr - 1);
-}
-
-static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
-                                        struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct tx_pkt_header *txph;
-       u32 offset, copy_len;
-       int txs_unused;
-       int txbuf_unused;
-
-       if (test_bit(__ATL2_DOWN, &adapter->flags)) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       if (unlikely(skb->len <= 0)) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       txs_unused = TxsFreeUnit(adapter);
-       txbuf_unused = TxdFreeBytes(adapter);
-
-       if (skb->len + sizeof(struct tx_pkt_header) + 4  > txbuf_unused ||
-               txs_unused < 1) {
-               /* not enough resources */
-               netif_stop_queue(netdev);
-               return NETDEV_TX_BUSY;
-       }
-
-       offset = adapter->txd_write_ptr;
-
-       txph = (struct tx_pkt_header *) (((u8 *)adapter->txd_ring) + offset);
-
-       *(u32 *)txph = 0;
-       txph->pkt_size = skb->len;
-
-       offset += 4;
-       if (offset >= adapter->txd_ring_size)
-               offset -= adapter->txd_ring_size;
-       copy_len = adapter->txd_ring_size - offset;
-       if (copy_len >= skb->len) {
-               memcpy(((u8 *)adapter->txd_ring) + offset, skb->data, skb->len);
-               offset += ((u32)(skb->len + 3) & ~3);
-       } else {
-               memcpy(((u8 *)adapter->txd_ring)+offset, skb->data, copy_len);
-               memcpy((u8 *)adapter->txd_ring, skb->data+copy_len,
-                       skb->len-copy_len);
-               offset = ((u32)(skb->len-copy_len + 3) & ~3);
-       }
-#ifdef NETIF_F_HW_VLAN_TX
-       if (vlan_tx_tag_present(skb)) {
-               u16 vlan_tag = vlan_tx_tag_get(skb);
-               vlan_tag = (vlan_tag << 4) |
-                       (vlan_tag >> 13) |
-                       ((vlan_tag >> 9) & 0x8);
-               txph->ins_vlan = 1;
-               txph->vlan = vlan_tag;
-       }
-#endif
-       if (offset >= adapter->txd_ring_size)
-               offset -= adapter->txd_ring_size;
-       adapter->txd_write_ptr = offset;
-
-       /* clear txs before send */
-       adapter->txs_ring[adapter->txs_next_clear].update = 0;
-       if (++adapter->txs_next_clear == adapter->txs_ring_size)
-               adapter->txs_next_clear = 0;
-
-       ATL2_WRITE_REGW(&adapter->hw, REG_MB_TXD_WR_IDX,
-               (adapter->txd_write_ptr >> 2));
-
-       mmiowb();
-       dev_kfree_skb_any(skb);
-       return NETDEV_TX_OK;
-}
-
-/*
- * atl2_change_mtu - Change the Maximum Transfer Unit
- * @netdev: network interface device structure
- * @new_mtu: new value for maximum frame size
- *
- * Returns 0 on success, negative on failure
- */
-static int atl2_change_mtu(struct net_device *netdev, int new_mtu)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-
-       if ((new_mtu < 40) || (new_mtu > (ETH_DATA_LEN + VLAN_SIZE)))
-               return -EINVAL;
-
-       /* set MTU */
-       if (hw->max_frame_size != new_mtu) {
-               netdev->mtu = new_mtu;
-               ATL2_WRITE_REG(hw, REG_MTU, new_mtu + ENET_HEADER_SIZE +
-                       VLAN_SIZE + ETHERNET_FCS_SIZE);
-       }
-
-       return 0;
-}
-
-/*
- * atl2_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 atl2_set_mac(struct net_device *netdev, void *p)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct sockaddr *addr = p;
-
-       if (!is_valid_ether_addr(addr->sa_data))
-               return -EADDRNOTAVAIL;
-
-       if (netif_running(netdev))
-               return -EBUSY;
-
-       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
-
-       atl2_set_mac_addr(&adapter->hw);
-
-       return 0;
-}
-
-/*
- * atl2_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl2_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct mii_ioctl_data *data = if_mii(ifr);
-       unsigned long flags;
-
-       switch (cmd) {
-       case SIOCGMIIPHY:
-               data->phy_id = 0;
-               break;
-       case SIOCGMIIREG:
-               spin_lock_irqsave(&adapter->stats_lock, flags);
-               if (atl2_read_phy_reg(&adapter->hw,
-                       data->reg_num & 0x1F, &data->val_out)) {
-                       spin_unlock_irqrestore(&adapter->stats_lock, flags);
-                       return -EIO;
-               }
-               spin_unlock_irqrestore(&adapter->stats_lock, flags);
-               break;
-       case SIOCSMIIREG:
-               if (data->reg_num & ~(0x1F))
-                       return -EFAULT;
-               spin_lock_irqsave(&adapter->stats_lock, flags);
-               if (atl2_write_phy_reg(&adapter->hw, data->reg_num,
-                       data->val_in)) {
-                       spin_unlock_irqrestore(&adapter->stats_lock, flags);
-                       return -EIO;
-               }
-               spin_unlock_irqrestore(&adapter->stats_lock, flags);
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-       return 0;
-}
-
-/*
- * atl2_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl2_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-       switch (cmd) {
-       case SIOCGMIIPHY:
-       case SIOCGMIIREG:
-       case SIOCSMIIREG:
-               return atl2_mii_ioctl(netdev, ifr, cmd);
-#ifdef ETHTOOL_OPS_COMPAT
-       case SIOCETHTOOL:
-               return ethtool_ioctl(ifr);
-#endif
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-/*
- * atl2_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- */
-static void atl2_tx_timeout(struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-
-       /* Do the reset outside of interrupt context */
-       schedule_work(&adapter->reset_task);
-}
-
-/*
- * atl2_watchdog - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl2_watchdog(unsigned long data)
-{
-       struct atl2_adapter *adapter = (struct atl2_adapter *) data;
-
-       if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
-               u32 drop_rxd, drop_rxs;
-               unsigned long flags;
-
-               spin_lock_irqsave(&adapter->stats_lock, flags);
-               drop_rxd = ATL2_READ_REG(&adapter->hw, REG_STS_RXD_OV);
-               drop_rxs = ATL2_READ_REG(&adapter->hw, REG_STS_RXS_OV);
-               spin_unlock_irqrestore(&adapter->stats_lock, flags);
-
-               adapter->netdev->stats.rx_over_errors += drop_rxd + drop_rxs;
-
-               /* Reset the timer */
-               mod_timer(&adapter->watchdog_timer,
-                         round_jiffies(jiffies + 4 * HZ));
-       }
-}
-
-/*
- * atl2_phy_config - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl2_phy_config(unsigned long data)
-{
-       struct atl2_adapter *adapter = (struct atl2_adapter *) data;
-       struct atl2_hw *hw = &adapter->hw;
-       unsigned long flags;
-
-       spin_lock_irqsave(&adapter->stats_lock, flags);
-       atl2_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
-       atl2_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN |
-               MII_CR_RESTART_AUTO_NEG);
-       spin_unlock_irqrestore(&adapter->stats_lock, flags);
-       clear_bit(0, &adapter->cfg_phy);
-}
-
-static int atl2_up(struct atl2_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       int err = 0;
-       u32 val;
-
-       /* hardware has been reset, we need to reload some things */
-
-       err = atl2_init_hw(&adapter->hw);
-       if (err) {
-               err = -EIO;
-               return err;
-       }
-
-       atl2_set_multi(netdev);
-       init_ring_ptrs(adapter);
-
-       atl2_restore_vlan(adapter);
-
-       if (atl2_configure(adapter)) {
-               err = -EIO;
-               goto err_up;
-       }
-
-       clear_bit(__ATL2_DOWN, &adapter->flags);
-
-       val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL);
-       ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val |
-               MASTER_CTRL_MANUAL_INT);
-
-       atl2_irq_enable(adapter);
-
-err_up:
-       return err;
-}
-
-static void atl2_reinit_locked(struct atl2_adapter *adapter)
-{
-       WARN_ON(in_interrupt());
-       while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags))
-               msleep(1);
-       atl2_down(adapter);
-       atl2_up(adapter);
-       clear_bit(__ATL2_RESETTING, &adapter->flags);
-}
-
-static void atl2_reset_task(struct work_struct *work)
-{
-       struct atl2_adapter *adapter;
-       adapter = container_of(work, struct atl2_adapter, reset_task);
-
-       atl2_reinit_locked(adapter);
-}
-
-static void atl2_setup_mac_ctrl(struct atl2_adapter *adapter)
-{
-       u32 value;
-       struct atl2_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-
-       /* Config MAC CTRL Register */
-       value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY;
-
-       /* duplex */
-       if (FULL_DUPLEX == adapter->link_duplex)
-               value |= MAC_CTRL_DUPLX;
-
-       /* flow control */
-       value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
-
-       /* PAD & CRC */
-       value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
-
-       /* preamble length */
-       value |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) <<
-               MAC_CTRL_PRMLEN_SHIFT);
-
-       /* vlan */
-       __atl2_vlan_mode(netdev->features, &value);
-
-       /* filter mode */
-       value |= MAC_CTRL_BC_EN;
-       if (netdev->flags & IFF_PROMISC)
-               value |= MAC_CTRL_PROMIS_EN;
-       else if (netdev->flags & IFF_ALLMULTI)
-               value |= MAC_CTRL_MC_ALL_EN;
-
-       /* half retry buffer */
-       value |= (((u32)(adapter->hw.retry_buf &
-               MAC_CTRL_HALF_LEFT_BUF_MASK)) << MAC_CTRL_HALF_LEFT_BUF_SHIFT);
-
-       ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
-}
-
-static int atl2_check_link(struct atl2_adapter *adapter)
-{
-       struct atl2_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       int ret_val;
-       u16 speed, duplex, phy_data;
-       int reconfig = 0;
-
-       /* MII_BMSR must read twise */
-       atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
-       atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
-       if (!(phy_data&BMSR_LSTATUS)) { /* link down */
-               if (netif_carrier_ok(netdev)) { /* old link state: Up */
-                       u32 value;
-                       /* disable rx */
-                       value = ATL2_READ_REG(hw, REG_MAC_CTRL);
-                       value &= ~MAC_CTRL_RX_EN;
-                       ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
-                       adapter->link_speed = SPEED_0;
-                       netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
-               }
-               return 0;
-       }
-
-       /* Link Up */
-       ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex);
-       if (ret_val)
-               return ret_val;
-       switch (hw->MediaType) {
-       case MEDIA_TYPE_100M_FULL:
-               if (speed  != SPEED_100 || duplex != FULL_DUPLEX)
-                       reconfig = 1;
-               break;
-       case MEDIA_TYPE_100M_HALF:
-               if (speed  != SPEED_100 || duplex != HALF_DUPLEX)
-                       reconfig = 1;
-               break;
-       case MEDIA_TYPE_10M_FULL:
-               if (speed != SPEED_10 || duplex != FULL_DUPLEX)
-                       reconfig = 1;
-               break;
-       case MEDIA_TYPE_10M_HALF:
-               if (speed  != SPEED_10 || duplex != HALF_DUPLEX)
-                       reconfig = 1;
-               break;
-       }
-       /* link result is our setting */
-       if (reconfig == 0) {
-               if (adapter->link_speed != speed ||
-                       adapter->link_duplex != duplex) {
-                       adapter->link_speed = speed;
-                       adapter->link_duplex = duplex;
-                       atl2_setup_mac_ctrl(adapter);
-                       printk(KERN_INFO "%s: %s NIC Link is Up<%d Mbps %s>\n",
-                               atl2_driver_name, netdev->name,
-                               adapter->link_speed,
-                               adapter->link_duplex == FULL_DUPLEX ?
-                                       "Full Duplex" : "Half Duplex");
-               }
-
-               if (!netif_carrier_ok(netdev)) { /* Link down -> Up */
-                       netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
-               }
-               return 0;
-       }
-
-       /* change original link status */
-       if (netif_carrier_ok(netdev)) {
-               u32 value;
-               /* disable rx */
-               value = ATL2_READ_REG(hw, REG_MAC_CTRL);
-               value &= ~MAC_CTRL_RX_EN;
-               ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
-
-               adapter->link_speed = SPEED_0;
-               netif_carrier_off(netdev);
-               netif_stop_queue(netdev);
-       }
-
-       /* auto-neg, insert timer to re-config phy
-        * (if interval smaller than 5 seconds, something strange) */
-       if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
-               if (!test_and_set_bit(0, &adapter->cfg_phy))
-                       mod_timer(&adapter->phy_config_timer,
-                                 round_jiffies(jiffies + 5 * HZ));
-       }
-
-       return 0;
-}
-
-/*
- * atl2_link_chg_task - deal with link change event Out of interrupt context
- * @netdev: network interface device structure
- */
-static void atl2_link_chg_task(struct work_struct *work)
-{
-       struct atl2_adapter *adapter;
-       unsigned long flags;
-
-       adapter = container_of(work, struct atl2_adapter, link_chg_task);
-
-       spin_lock_irqsave(&adapter->stats_lock, flags);
-       atl2_check_link(adapter);
-       spin_unlock_irqrestore(&adapter->stats_lock, flags);
-}
-
-static void atl2_setup_pcicmd(struct pci_dev *pdev)
-{
-       u16 cmd;
-
-       pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-
-       if (cmd & PCI_COMMAND_INTX_DISABLE)
-               cmd &= ~PCI_COMMAND_INTX_DISABLE;
-       if (cmd & PCI_COMMAND_IO)
-               cmd &= ~PCI_COMMAND_IO;
-       if (0 == (cmd & PCI_COMMAND_MEMORY))
-               cmd |= PCI_COMMAND_MEMORY;
-       if (0 == (cmd & PCI_COMMAND_MASTER))
-               cmd |= PCI_COMMAND_MASTER;
-       pci_write_config_word(pdev, PCI_COMMAND, cmd);
-
-       /*
-        * some motherboards BIOS(PXE/EFI) driver may set PME
-        * while they transfer control to OS (Windows/Linux)
-        * so we should clear this bit before NIC work normally
-        */
-       pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0);
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void atl2_poll_controller(struct net_device *netdev)
-{
-       disable_irq(netdev->irq);
-       atl2_intr(netdev->irq, netdev);
-       enable_irq(netdev->irq);
-}
-#endif
-
-
-static const struct net_device_ops atl2_netdev_ops = {
-       .ndo_open               = atl2_open,
-       .ndo_stop               = atl2_close,
-       .ndo_start_xmit         = atl2_xmit_frame,
-       .ndo_set_multicast_list = atl2_set_multi,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = atl2_set_mac,
-       .ndo_change_mtu         = atl2_change_mtu,
-       .ndo_fix_features       = atl2_fix_features,
-       .ndo_set_features       = atl2_set_features,
-       .ndo_do_ioctl           = atl2_ioctl,
-       .ndo_tx_timeout         = atl2_tx_timeout,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = atl2_poll_controller,
-#endif
-};
-
-/*
- * atl2_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in atl2_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * atl2_probe 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 __devinit atl2_probe(struct pci_dev *pdev,
-       const struct pci_device_id *ent)
-{
-       struct net_device *netdev;
-       struct atl2_adapter *adapter;
-       static int cards_found;
-       unsigned long mmio_start;
-       int mmio_len;
-       int err;
-
-       cards_found = 0;
-
-       err = pci_enable_device(pdev);
-       if (err)
-               return err;
-
-       /*
-        * atl2 is a shared-high-32-bit device, so we're stuck with 32-bit DMA
-        * until the kernel has the proper infrastructure to support 64-bit DMA
-        * on these devices.
-        */
-       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) &&
-               pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
-               printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n");
-               goto err_dma;
-       }
-
-       /* Mark all PCI regions associated with PCI device
-        * pdev as being reserved by owner atl2_driver_name */
-       err = pci_request_regions(pdev, atl2_driver_name);
-       if (err)
-               goto err_pci_reg;
-
-       /* Enables bus-mastering on the device and calls
-        * pcibios_set_master to do the needed arch specific settings */
-       pci_set_master(pdev);
-
-       err = -ENOMEM;
-       netdev = alloc_etherdev(sizeof(struct atl2_adapter));
-       if (!netdev)
-               goto err_alloc_etherdev;
-
-       SET_NETDEV_DEV(netdev, &pdev->dev);
-
-       pci_set_drvdata(pdev, netdev);
-       adapter = netdev_priv(netdev);
-       adapter->netdev = netdev;
-       adapter->pdev = pdev;
-       adapter->hw.back = adapter;
-
-       mmio_start = pci_resource_start(pdev, 0x0);
-       mmio_len = pci_resource_len(pdev, 0x0);
-
-       adapter->hw.mem_rang = (u32)mmio_len;
-       adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
-       if (!adapter->hw.hw_addr) {
-               err = -EIO;
-               goto err_ioremap;
-       }
-
-       atl2_setup_pcicmd(pdev);
-
-       netdev->netdev_ops = &atl2_netdev_ops;
-       atl2_set_ethtool_ops(netdev);
-       netdev->watchdog_timeo = 5 * HZ;
-       strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
-
-       netdev->mem_start = mmio_start;
-       netdev->mem_end = mmio_start + mmio_len;
-       adapter->bd_number = cards_found;
-       adapter->pci_using_64 = false;
-
-       /* setup the private structure */
-       err = atl2_sw_init(adapter);
-       if (err)
-               goto err_sw_init;
-
-       err = -EIO;
-
-       netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_RX;
-       netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
-
-       /* Init PHY as early as possible due to power saving issue  */
-       atl2_phy_init(&adapter->hw);
-
-       /* reset the controller to
-        * put the device in a known good starting state */
-
-       if (atl2_reset_hw(&adapter->hw)) {
-               err = -EIO;
-               goto err_reset;
-       }
-
-       /* copy the MAC address out of the EEPROM */
-       atl2_read_mac_addr(&adapter->hw);
-       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-/* FIXME: do we still need this? */
-#ifdef ETHTOOL_GPERMADDR
-       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
-
-       if (!is_valid_ether_addr(netdev->perm_addr)) {
-#else
-       if (!is_valid_ether_addr(netdev->dev_addr)) {
-#endif
-               err = -EIO;
-               goto err_eeprom;
-       }
-
-       atl2_check_options(adapter);
-
-       init_timer(&adapter->watchdog_timer);
-       adapter->watchdog_timer.function = atl2_watchdog;
-       adapter->watchdog_timer.data = (unsigned long) adapter;
-
-       init_timer(&adapter->phy_config_timer);
-       adapter->phy_config_timer.function = atl2_phy_config;
-       adapter->phy_config_timer.data = (unsigned long) adapter;
-
-       INIT_WORK(&adapter->reset_task, atl2_reset_task);
-       INIT_WORK(&adapter->link_chg_task, atl2_link_chg_task);
-
-       strcpy(netdev->name, "eth%d"); /* ?? */
-       err = register_netdev(netdev);
-       if (err)
-               goto err_register;
-
-       /* assume we have no link for now */
-       netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
-
-       cards_found++;
-
-       return 0;
-
-err_reset:
-err_register:
-err_sw_init:
-err_eeprom:
-       iounmap(adapter->hw.hw_addr);
-err_ioremap:
-       free_netdev(netdev);
-err_alloc_etherdev:
-       pci_release_regions(pdev);
-err_pci_reg:
-err_dma:
-       pci_disable_device(pdev);
-       return err;
-}
-
-/*
- * atl2_remove - Device Removal Routine
- * @pdev: PCI device information struct
- *
- * atl2_remove 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.
- */
-/* FIXME: write the original MAC address back in case it was changed from a
- * BIOS-set value, as in atl1 -- CHS */
-static void __devexit atl2_remove(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-
-       /* flush_scheduled work may reschedule our watchdog task, so
-        * explicitly disable watchdog tasks from being rescheduled  */
-       set_bit(__ATL2_DOWN, &adapter->flags);
-
-       del_timer_sync(&adapter->watchdog_timer);
-       del_timer_sync(&adapter->phy_config_timer);
-       cancel_work_sync(&adapter->reset_task);
-       cancel_work_sync(&adapter->link_chg_task);
-
-       unregister_netdev(netdev);
-
-       atl2_force_ps(&adapter->hw);
-
-       iounmap(adapter->hw.hw_addr);
-       pci_release_regions(pdev);
-
-       free_netdev(netdev);
-
-       pci_disable_device(pdev);
-}
-
-static int atl2_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-       u16 speed, duplex;
-       u32 ctrl = 0;
-       u32 wufc = adapter->wol;
-
-#ifdef CONFIG_PM
-       int retval = 0;
-#endif
-
-       netif_device_detach(netdev);
-
-       if (netif_running(netdev)) {
-               WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags));
-               atl2_down(adapter);
-       }
-
-#ifdef CONFIG_PM
-       retval = pci_save_state(pdev);
-       if (retval)
-               return retval;
-#endif
-
-       atl2_read_phy_reg(hw, MII_BMSR, (u16 *)&ctrl);
-       atl2_read_phy_reg(hw, MII_BMSR, (u16 *)&ctrl);
-       if (ctrl & BMSR_LSTATUS)
-               wufc &= ~ATLX_WUFC_LNKC;
-
-       if (0 != (ctrl & BMSR_LSTATUS) && 0 != wufc) {
-               u32 ret_val;
-               /* get current link speed & duplex */
-               ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex);
-               if (ret_val) {
-                       printk(KERN_DEBUG
-                               "%s: get speed&duplex error while suspend\n",
-                               atl2_driver_name);
-                       goto wol_dis;
-               }
-
-               ctrl = 0;
-
-               /* turn on magic packet wol */
-               if (wufc & ATLX_WUFC_MAG)
-                       ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
-
-               /* ignore Link Chg event when Link is up */
-               ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl);
-
-               /* Config MAC CTRL Register */
-               ctrl = MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY;
-               if (FULL_DUPLEX == adapter->link_duplex)
-                       ctrl |= MAC_CTRL_DUPLX;
-               ctrl |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
-               ctrl |= (((u32)adapter->hw.preamble_len &
-                       MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
-               ctrl |= (((u32)(adapter->hw.retry_buf &
-                       MAC_CTRL_HALF_LEFT_BUF_MASK)) <<
-                       MAC_CTRL_HALF_LEFT_BUF_SHIFT);
-               if (wufc & ATLX_WUFC_MAG) {
-                       /* magic packet maybe Broadcast&multicast&Unicast */
-                       ctrl |= MAC_CTRL_BC_EN;
-               }
-
-               ATL2_WRITE_REG(hw, REG_MAC_CTRL, ctrl);
-
-               /* pcie patch */
-               ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
-               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
-               ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
-               ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
-               ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
-               ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
-
-               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
-               goto suspend_exit;
-       }
-
-       if (0 == (ctrl&BMSR_LSTATUS) && 0 != (wufc&ATLX_WUFC_LNKC)) {
-               /* link is down, so only LINK CHG WOL event enable */
-               ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
-               ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl);
-               ATL2_WRITE_REG(hw, REG_MAC_CTRL, 0);
-
-               /* pcie patch */
-               ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
-               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
-               ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
-               ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
-               ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
-               ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
-
-               hw->phy_configured = false; /* re-init PHY when resume */
-
-               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
-
-               goto suspend_exit;
-       }
-
-wol_dis:
-       /* WOL disabled */
-       ATL2_WRITE_REG(hw, REG_WOL_CTRL, 0);
-
-       /* pcie patch */
-       ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
-       ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
-       ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
-       ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
-       ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
-       ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
-
-       atl2_force_ps(hw);
-       hw->phy_configured = false; /* re-init PHY when resume */
-
-       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
-
-suspend_exit:
-       if (netif_running(netdev))
-               atl2_free_irq(adapter);
-
-       pci_disable_device(pdev);
-
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int atl2_resume(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       u32 err;
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-
-       err = pci_enable_device(pdev);
-       if (err) {
-               printk(KERN_ERR
-                       "atl2: Cannot enable PCI device from suspend\n");
-               return err;
-       }
-
-       pci_set_master(pdev);
-
-       ATL2_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */
-
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
-       ATL2_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
-
-       if (netif_running(netdev)) {
-               err = atl2_request_irq(adapter);
-               if (err)
-                       return err;
-       }
-
-       atl2_reset_hw(&adapter->hw);
-
-       if (netif_running(netdev))
-               atl2_up(adapter);
-
-       netif_device_attach(netdev);
-
-       return 0;
-}
-#endif
-
-static void atl2_shutdown(struct pci_dev *pdev)
-{
-       atl2_suspend(pdev, PMSG_SUSPEND);
-}
-
-static struct pci_driver atl2_driver = {
-       .name     = atl2_driver_name,
-       .id_table = atl2_pci_tbl,
-       .probe    = atl2_probe,
-       .remove   = __devexit_p(atl2_remove),
-       /* Power Management Hooks */
-       .suspend  = atl2_suspend,
-#ifdef CONFIG_PM
-       .resume   = atl2_resume,
-#endif
-       .shutdown = atl2_shutdown,
-};
-
-/*
- * atl2_init_module - Driver Registration Routine
- *
- * atl2_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl2_init_module(void)
-{
-       printk(KERN_INFO "%s - version %s\n", atl2_driver_string,
-               atl2_driver_version);
-       printk(KERN_INFO "%s\n", atl2_copyright);
-       return pci_register_driver(&atl2_driver);
-}
-module_init(atl2_init_module);
-
-/*
- * atl2_exit_module - Driver Exit Cleanup Routine
- *
- * atl2_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl2_exit_module(void)
-{
-       pci_unregister_driver(&atl2_driver);
-}
-module_exit(atl2_exit_module);
-
-static void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value)
-{
-       struct atl2_adapter *adapter = hw->back;
-       pci_read_config_word(adapter->pdev, reg, value);
-}
-
-static void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value)
-{
-       struct atl2_adapter *adapter = hw->back;
-       pci_write_config_word(adapter->pdev, reg, *value);
-}
-
-static int atl2_get_settings(struct net_device *netdev,
-       struct ethtool_cmd *ecmd)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-
-       ecmd->supported = (SUPPORTED_10baseT_Half |
-               SUPPORTED_10baseT_Full |
-               SUPPORTED_100baseT_Half |
-               SUPPORTED_100baseT_Full |
-               SUPPORTED_Autoneg |
-               SUPPORTED_TP);
-       ecmd->advertising = ADVERTISED_TP;
-
-       ecmd->advertising |= ADVERTISED_Autoneg;
-       ecmd->advertising |= hw->autoneg_advertised;
-
-       ecmd->port = PORT_TP;
-       ecmd->phy_address = 0;
-       ecmd->transceiver = XCVR_INTERNAL;
-
-       if (adapter->link_speed != SPEED_0) {
-               ethtool_cmd_speed_set(ecmd, adapter->link_speed);
-               if (adapter->link_duplex == FULL_DUPLEX)
-                       ecmd->duplex = DUPLEX_FULL;
-               else
-                       ecmd->duplex = DUPLEX_HALF;
-       } else {
-               ethtool_cmd_speed_set(ecmd, -1);
-               ecmd->duplex = -1;
-       }
-
-       ecmd->autoneg = AUTONEG_ENABLE;
-       return 0;
-}
-
-static int atl2_set_settings(struct net_device *netdev,
-       struct ethtool_cmd *ecmd)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-
-       while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags))
-               msleep(1);
-
-       if (ecmd->autoneg == AUTONEG_ENABLE) {
-#define MY_ADV_MASK    (ADVERTISE_10_HALF | \
-                        ADVERTISE_10_FULL | \
-                        ADVERTISE_100_HALF| \
-                        ADVERTISE_100_FULL)
-
-               if ((ecmd->advertising & MY_ADV_MASK) == MY_ADV_MASK) {
-                       hw->MediaType = MEDIA_TYPE_AUTO_SENSOR;
-                       hw->autoneg_advertised =  MY_ADV_MASK;
-               } else if ((ecmd->advertising & MY_ADV_MASK) ==
-                               ADVERTISE_100_FULL) {
-                       hw->MediaType = MEDIA_TYPE_100M_FULL;
-                       hw->autoneg_advertised = ADVERTISE_100_FULL;
-               } else if ((ecmd->advertising & MY_ADV_MASK) ==
-                               ADVERTISE_100_HALF) {
-                       hw->MediaType = MEDIA_TYPE_100M_HALF;
-                       hw->autoneg_advertised = ADVERTISE_100_HALF;
-               } else if ((ecmd->advertising & MY_ADV_MASK) ==
-                               ADVERTISE_10_FULL) {
-                       hw->MediaType = MEDIA_TYPE_10M_FULL;
-                       hw->autoneg_advertised = ADVERTISE_10_FULL;
-               }  else if ((ecmd->advertising & MY_ADV_MASK) ==
-                               ADVERTISE_10_HALF) {
-                       hw->MediaType = MEDIA_TYPE_10M_HALF;
-                       hw->autoneg_advertised = ADVERTISE_10_HALF;
-               } else {
-                       clear_bit(__ATL2_RESETTING, &adapter->flags);
-                       return -EINVAL;
-               }
-               ecmd->advertising = hw->autoneg_advertised |
-                       ADVERTISED_TP | ADVERTISED_Autoneg;
-       } else {
-               clear_bit(__ATL2_RESETTING, &adapter->flags);
-               return -EINVAL;
-       }
-
-       /* reset the link */
-       if (netif_running(adapter->netdev)) {
-               atl2_down(adapter);
-               atl2_up(adapter);
-       } else
-               atl2_reset_hw(&adapter->hw);
-
-       clear_bit(__ATL2_RESETTING, &adapter->flags);
-       return 0;
-}
-
-static u32 atl2_get_msglevel(struct net_device *netdev)
-{
-       return 0;
-}
-
-/*
- * It's sane for this to be empty, but we might want to take advantage of this.
- */
-static void atl2_set_msglevel(struct net_device *netdev, u32 data)
-{
-}
-
-static int atl2_get_regs_len(struct net_device *netdev)
-{
-#define ATL2_REGS_LEN 42
-       return sizeof(u32) * ATL2_REGS_LEN;
-}
-
-static void atl2_get_regs(struct net_device *netdev,
-       struct ethtool_regs *regs, void *p)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-       u32 *regs_buff = p;
-       u16 phy_data;
-
-       memset(p, 0, sizeof(u32) * ATL2_REGS_LEN);
-
-       regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
-
-       regs_buff[0]  = ATL2_READ_REG(hw, REG_VPD_CAP);
-       regs_buff[1]  = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
-       regs_buff[2]  = ATL2_READ_REG(hw, REG_SPI_FLASH_CONFIG);
-       regs_buff[3]  = ATL2_READ_REG(hw, REG_TWSI_CTRL);
-       regs_buff[4]  = ATL2_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
-       regs_buff[5]  = ATL2_READ_REG(hw, REG_MASTER_CTRL);
-       regs_buff[6]  = ATL2_READ_REG(hw, REG_MANUAL_TIMER_INIT);
-       regs_buff[7]  = ATL2_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
-       regs_buff[8]  = ATL2_READ_REG(hw, REG_PHY_ENABLE);
-       regs_buff[9]  = ATL2_READ_REG(hw, REG_CMBDISDMA_TIMER);
-       regs_buff[10] = ATL2_READ_REG(hw, REG_IDLE_STATUS);
-       regs_buff[11] = ATL2_READ_REG(hw, REG_MDIO_CTRL);
-       regs_buff[12] = ATL2_READ_REG(hw, REG_SERDES_LOCK);
-       regs_buff[13] = ATL2_READ_REG(hw, REG_MAC_CTRL);
-       regs_buff[14] = ATL2_READ_REG(hw, REG_MAC_IPG_IFG);
-       regs_buff[15] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR);
-       regs_buff[16] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR+4);
-       regs_buff[17] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE);
-       regs_buff[18] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE+4);
-       regs_buff[19] = ATL2_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
-       regs_buff[20] = ATL2_READ_REG(hw, REG_MTU);
-       regs_buff[21] = ATL2_READ_REG(hw, REG_WOL_CTRL);
-       regs_buff[22] = ATL2_READ_REG(hw, REG_SRAM_TXRAM_END);
-       regs_buff[23] = ATL2_READ_REG(hw, REG_DESC_BASE_ADDR_HI);
-       regs_buff[24] = ATL2_READ_REG(hw, REG_TXD_BASE_ADDR_LO);
-       regs_buff[25] = ATL2_READ_REG(hw, REG_TXD_MEM_SIZE);
-       regs_buff[26] = ATL2_READ_REG(hw, REG_TXS_BASE_ADDR_LO);
-       regs_buff[27] = ATL2_READ_REG(hw, REG_TXS_MEM_SIZE);
-       regs_buff[28] = ATL2_READ_REG(hw, REG_RXD_BASE_ADDR_LO);
-       regs_buff[29] = ATL2_READ_REG(hw, REG_RXD_BUF_NUM);
-       regs_buff[30] = ATL2_READ_REG(hw, REG_DMAR);
-       regs_buff[31] = ATL2_READ_REG(hw, REG_TX_CUT_THRESH);
-       regs_buff[32] = ATL2_READ_REG(hw, REG_DMAW);
-       regs_buff[33] = ATL2_READ_REG(hw, REG_PAUSE_ON_TH);
-       regs_buff[34] = ATL2_READ_REG(hw, REG_PAUSE_OFF_TH);
-       regs_buff[35] = ATL2_READ_REG(hw, REG_MB_TXD_WR_IDX);
-       regs_buff[36] = ATL2_READ_REG(hw, REG_MB_RXD_RD_IDX);
-       regs_buff[38] = ATL2_READ_REG(hw, REG_ISR);
-       regs_buff[39] = ATL2_READ_REG(hw, REG_IMR);
-
-       atl2_read_phy_reg(hw, MII_BMCR, &phy_data);
-       regs_buff[40] = (u32)phy_data;
-       atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
-       regs_buff[41] = (u32)phy_data;
-}
-
-static int atl2_get_eeprom_len(struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-
-       if (!atl2_check_eeprom_exist(&adapter->hw))
-               return 512;
-       else
-               return 0;
-}
-
-static int atl2_get_eeprom(struct net_device *netdev,
-       struct ethtool_eeprom *eeprom, u8 *bytes)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-       u32 *eeprom_buff;
-       int first_dword, last_dword;
-       int ret_val = 0;
-       int i;
-
-       if (eeprom->len == 0)
-               return -EINVAL;
-
-       if (atl2_check_eeprom_exist(hw))
-               return -EINVAL;
-
-       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
-
-       first_dword = eeprom->offset >> 2;
-       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
-
-       eeprom_buff = kmalloc(sizeof(u32) * (last_dword - first_dword + 1),
-               GFP_KERNEL);
-       if (!eeprom_buff)
-               return -ENOMEM;
-
-       for (i = first_dword; i < last_dword; i++) {
-               if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) {
-                       ret_val = -EIO;
-                       goto free;
-               }
-       }
-
-       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
-               eeprom->len);
-free:
-       kfree(eeprom_buff);
-
-       return ret_val;
-}
-
-static int atl2_set_eeprom(struct net_device *netdev,
-       struct ethtool_eeprom *eeprom, u8 *bytes)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       struct atl2_hw *hw = &adapter->hw;
-       u32 *eeprom_buff;
-       u32 *ptr;
-       int max_len, first_dword, last_dword, ret_val = 0;
-       int i;
-
-       if (eeprom->len == 0)
-               return -EOPNOTSUPP;
-
-       if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
-               return -EFAULT;
-
-       max_len = 512;
-
-       first_dword = eeprom->offset >> 2;
-       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
-       eeprom_buff = kmalloc(max_len, GFP_KERNEL);
-       if (!eeprom_buff)
-               return -ENOMEM;
-
-       ptr = eeprom_buff;
-
-       if (eeprom->offset & 3) {
-               /* need read/modify/write of first changed EEPROM word */
-               /* only the second byte of the word is being modified */
-               if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) {
-                       ret_val = -EIO;
-                       goto out;
-               }
-               ptr++;
-       }
-       if (((eeprom->offset + eeprom->len) & 3)) {
-               /*
-                * need read/modify/write of last changed EEPROM word
-                * only the first byte of the word is being modified
-                */
-               if (!atl2_read_eeprom(hw, last_dword * 4,
-                                       &(eeprom_buff[last_dword - first_dword]))) {
-                       ret_val = -EIO;
-                       goto out;
-               }
-       }
-
-       /* Device's eeprom is always little-endian, word addressable */
-       memcpy(ptr, bytes, eeprom->len);
-
-       for (i = 0; i < last_dword - first_dword + 1; i++) {
-               if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) {
-                       ret_val = -EIO;
-                       goto out;
-               }
-       }
- out:
-       kfree(eeprom_buff);
-       return ret_val;
-}
-
-static void atl2_get_drvinfo(struct net_device *netdev,
-       struct ethtool_drvinfo *drvinfo)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-
-       strncpy(drvinfo->driver,  atl2_driver_name, 32);
-       strncpy(drvinfo->version, atl2_driver_version, 32);
-       strncpy(drvinfo->fw_version, "L2", 32);
-       strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
-       drvinfo->n_stats = 0;
-       drvinfo->testinfo_len = 0;
-       drvinfo->regdump_len = atl2_get_regs_len(netdev);
-       drvinfo->eedump_len = atl2_get_eeprom_len(netdev);
-}
-
-static void atl2_get_wol(struct net_device *netdev,
-       struct ethtool_wolinfo *wol)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-
-       wol->supported = 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;
-       if (adapter->wol & ATLX_WUFC_LNKC)
-               wol->wolopts |= WAKE_PHY;
-}
-
-static int atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-
-       if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
-               return -EOPNOTSUPP;
-
-       if (wol->wolopts & (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
-               return -EOPNOTSUPP;
-
-       /* these settings will always override what we currently have */
-       adapter->wol = 0;
-
-       if (wol->wolopts & WAKE_MAGIC)
-               adapter->wol |= ATLX_WUFC_MAG;
-       if (wol->wolopts & WAKE_PHY)
-               adapter->wol |= ATLX_WUFC_LNKC;
-
-       return 0;
-}
-
-static int atl2_nway_reset(struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       if (netif_running(netdev))
-               atl2_reinit_locked(adapter);
-       return 0;
-}
-
-static const struct ethtool_ops atl2_ethtool_ops = {
-       .get_settings           = atl2_get_settings,
-       .set_settings           = atl2_set_settings,
-       .get_drvinfo            = atl2_get_drvinfo,
-       .get_regs_len           = atl2_get_regs_len,
-       .get_regs               = atl2_get_regs,
-       .get_wol                = atl2_get_wol,
-       .set_wol                = atl2_set_wol,
-       .get_msglevel           = atl2_get_msglevel,
-       .set_msglevel           = atl2_set_msglevel,
-       .nway_reset             = atl2_nway_reset,
-       .get_link               = ethtool_op_get_link,
-       .get_eeprom_len         = atl2_get_eeprom_len,
-       .get_eeprom             = atl2_get_eeprom,
-       .set_eeprom             = atl2_set_eeprom,
-};
-
-static void atl2_set_ethtool_ops(struct net_device *netdev)
-{
-       SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops);
-}
-
-#define LBYTESWAP(a)  ((((a) & 0x00ff00ff) << 8) | \
-       (((a) & 0xff00ff00) >> 8))
-#define LONGSWAP(a)   ((LBYTESWAP(a) << 16) | (LBYTESWAP(a) >> 16))
-#define SHORTSWAP(a)  (((a) << 8) | ((a) >> 8))
-
-/*
- * 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)
- */
-static s32 atl2_reset_hw(struct atl2_hw *hw)
-{
-       u32 icr;
-       u16 pci_cfg_cmd_word;
-       int i;
-
-       /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
-       atl2_read_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word);
-       if ((pci_cfg_cmd_word &
-               (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) !=
-               (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) {
-               pci_cfg_cmd_word |=
-                       (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER);
-               atl2_write_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word);
-       }
-
-       /* Clear Interrupt mask to stop board from generating
-        * interrupts & Clear any pending interrupt events
-        */
-       /* FIXME */
-       /* ATL2_WRITE_REG(hw, REG_IMR, 0); */
-       /* ATL2_WRITE_REG(hw, REG_ISR, 0xffffffff); */
-
-       /* 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.
-        */
-       ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST);
-       wmb();
-       msleep(1); /* delay about 1ms */
-
-       /* Wait at least 10ms for All module to be Idle */
-       for (i = 0; i < 10; i++) {
-               icr = ATL2_READ_REG(hw, REG_IDLE_STATUS);
-               if (!icr)
-                       break;
-               msleep(1); /* delay 1 ms */
-               cpu_relax();
-       }
-
-       if (icr)
-               return icr;
-
-       return 0;
-}
-
-#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 struct atl2_spi_flash_dev flash_table[] =
-{
-/* MFR    WRSR  READ  PROGRAM WREN  WRDI  RDSR  RDID  SECTOR_ERASE CHIP_ERASE */
-{"Atmel", 0x0,  0x03, 0x02,   0x06, 0x04, 0x05, 0x15, 0x52,        0x62 },
-{"SST",   0x01, 0x03, 0x02,   0x06, 0x04, 0x05, 0x90, 0x20,        0x60 },
-{"ST",    0x01, 0x03, 0x02,   0x06, 0x04, 0x05, 0xAB, 0xD8,        0xC7 },
-};
-
-static bool atl2_spi_read(struct atl2_hw *hw, u32 addr, u32 *buf)
-{
-       int i;
-       u32 value;
-
-       ATL2_WRITE_REG(hw, REG_SPI_DATA, 0);
-       ATL2_WRITE_REG(hw, REG_SPI_ADDR, 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 |
-               (0x1 & SPI_FLASH_CTRL_INS_MASK) << SPI_FLASH_CTRL_INS_SHIFT;
-
-       ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
-
-       value |= SPI_FLASH_CTRL_START;
-
-       ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
-
-       for (i = 0; i < 10; i++) {
-               msleep(1);
-               value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
-               if (!(value & SPI_FLASH_CTRL_START))
-                       break;
-       }
-
-       if (value & SPI_FLASH_CTRL_START)
-               return false;
-
-       *buf = ATL2_READ_REG(hw, REG_SPI_DATA);
-
-       return true;
-}
-
-/*
- * get_permanent_address
- * return 0 if get valid mac address,
- */
-static int get_permanent_address(struct atl2_hw *hw)
-{
-       u32 Addr[2];
-       u32 i, Control;
-       u16 Register;
-       u8  EthAddr[NODE_ADDRESS_SIZE];
-       bool KeyValid;
-
-       if (is_valid_ether_addr(hw->perm_mac_addr))
-               return 0;
-
-       Addr[0] = 0;
-       Addr[1] = 0;
-
-       if (!atl2_check_eeprom_exist(hw)) { /* eeprom exists */
-               Register = 0;
-               KeyValid = false;
-
-               /* Read out all EEPROM content */
-               i = 0;
-               while (1) {
-                       if (atl2_read_eeprom(hw, i + 0x100, &Control)) {
-                               if (KeyValid) {
-                                       if (Register == REG_MAC_STA_ADDR)
-                                               Addr[0] = Control;
-                                       else if (Register ==
-                                               (REG_MAC_STA_ADDR + 4))
-                                               Addr[1] = Control;
-                                       KeyValid = false;
-                               } else if ((Control & 0xff) == 0x5A) {
-                                       KeyValid = true;
-                                       Register = (u16) (Control >> 16);
-                               } else {
-                       /* assume data end while encount an invalid KEYWORD */
-                                       break;
-                               }
-                       } else {
-                               break; /* read error */
-                       }
-                       i += 4;
-               }
-
-               *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
-               *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *) &Addr[1]);
-
-               if (is_valid_ether_addr(EthAddr)) {
-                       memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE);
-                       return 0;
-               }
-               return 1;
-       }
-
-       /* see if SPI flash exists? */
-       Addr[0] = 0;
-       Addr[1] = 0;
-       Register = 0;
-       KeyValid = false;
-       i = 0;
-       while (1) {
-               if (atl2_spi_read(hw, i + 0x1f000, &Control)) {
-                       if (KeyValid) {
-                               if (Register == REG_MAC_STA_ADDR)
-                                       Addr[0] = Control;
-                               else if (Register == (REG_MAC_STA_ADDR + 4))
-                                       Addr[1] = Control;
-                               KeyValid = false;
-                       } else if ((Control & 0xff) == 0x5A) {
-                               KeyValid = true;
-                               Register = (u16) (Control >> 16);
-                       } else {
-                               break; /* data end */
-                       }
-               } else {
-                       break; /* read error */
-               }
-               i += 4;
-       }
-
-       *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
-       *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *)&Addr[1]);
-       if (is_valid_ether_addr(EthAddr)) {
-               memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE);
-               return 0;
-       }
-       /* maybe MAC-address is from BIOS */
-       Addr[0] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR);
-       Addr[1] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR + 4);
-       *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
-       *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *) &Addr[1]);
-
-       if (is_valid_ether_addr(EthAddr)) {
-               memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE);
-               return 0;
-       }
-
-       return 1;
-}
-
-/*
- * Reads the adapter's MAC address from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- */
-static s32 atl2_read_mac_addr(struct atl2_hw *hw)
-{
-       u16 i;
-
-       if (get_permanent_address(hw)) {
-               /* for test */
-               /* FIXME: shouldn't we use random_ether_addr() here? */
-               hw->perm_mac_addr[0] = 0x00;
-               hw->perm_mac_addr[1] = 0x13;
-               hw->perm_mac_addr[2] = 0x74;
-               hw->perm_mac_addr[3] = 0x00;
-               hw->perm_mac_addr[4] = 0x5c;
-               hw->perm_mac_addr[5] = 0x38;
-       }
-
-       for (i = 0; i < NODE_ADDRESS_SIZE; 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
- *
- * atl2_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
- */
-static u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr)
-{
-       u32 crc32, value;
-       int i;
-
-       value = 0;
-       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
- */
-static void atl2_hash_set(struct atl2_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 = ATL2_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
-
-       mta |= (1 << hash_bit);
-
-       ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
-}
-
-/*
- * atl2_init_pcie - init PCIE module
- */
-static void atl2_init_pcie(struct atl2_hw *hw)
-{
-    u32 value;
-    value = LTSSM_TEST_MODE_DEF;
-    ATL2_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value);
-
-    value = PCIE_DLL_TX_CTRL1_DEF;
-    ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, value);
-}
-
-static void atl2_init_flash_opcode(struct atl2_hw *hw)
-{
-       if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
-               hw->flash_vendor = 0; /* ATMEL */
-
-       /* Init OP table */
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_PROGRAM,
-               flash_table[hw->flash_vendor].cmdPROGRAM);
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_SC_ERASE,
-               flash_table[hw->flash_vendor].cmdSECTOR_ERASE);
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_CHIP_ERASE,
-               flash_table[hw->flash_vendor].cmdCHIP_ERASE);
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDID,
-               flash_table[hw->flash_vendor].cmdRDID);
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WREN,
-               flash_table[hw->flash_vendor].cmdWREN);
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDSR,
-               flash_table[hw->flash_vendor].cmdRDSR);
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WRSR,
-               flash_table[hw->flash_vendor].cmdWRSR);
-       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_READ,
-               flash_table[hw->flash_vendor].cmdREAD);
-}
-
-/********************************************************************
-* 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.
-********************************************************************/
-static s32 atl2_init_hw(struct atl2_hw *hw)
-{
-       u32 ret_val = 0;
-
-       atl2_init_pcie(hw);
-
-       /* Zero out the Multicast HASH table */
-       /* clear the old settings from the multicast hash table */
-       ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
-       ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
-
-       atl2_init_flash_opcode(hw);
-
-       ret_val = atl2_phy_init(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
- */
-static s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed,
-       u16 *duplex)
-{
-       s32 ret_val;
-       u16 phy_data;
-
-       /* Read PHY Specific Status Register (17) */
-       ret_val = atl2_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_100MBS:
-               *speed = SPEED_100;
-               break;
-       case MII_ATLX_PSSR_10MBS:
-               *speed = SPEED_10;
-               break;
-       default:
-               return ATLX_ERR_PHY_SPEED;
-               break;
-       }
-
-       if (phy_data & MII_ATLX_PSSR_DPLX)
-               *duplex = FULL_DUPLEX;
-       else
-               *duplex = HALF_DUPLEX;
-
-       return 0;
-}
-
-/*
- * Reads the value from a PHY register
- * hw - Struct containing variables accessed by shared code
- * reg_addr - address of the PHY register to read
- */
-static s32 atl2_read_phy_reg(struct atl2_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;
-       ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val);
-
-       wmb();
-
-       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
-               udelay(2);
-               val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
-               if (!(val & (MDIO_START | MDIO_BUSY)))
-                       break;
-               wmb();
-       }
-       if (!(val & (MDIO_START | MDIO_BUSY))) {
-               *phy_data = (u16)val;
-               return 0;
-       }
-
-       return ATLX_ERR_PHY;
-}
-
-/*
- * 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
- */
-static s32 atl2_write_phy_reg(struct atl2_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;
-       ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val);
-
-       wmb();
-
-       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
-               udelay(2);
-               val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
-               if (!(val & (MDIO_START | MDIO_BUSY)))
-                       break;
-
-               wmb();
-       }
-
-       if (!(val & (MDIO_START | MDIO_BUSY)))
-               return 0;
-
-       return ATLX_ERR_PHY;
-}
-
-/*
- * Configures PHY autoneg and flow control advertisement settings
- *
- * hw - Struct containing variables accessed by shared code
- */
-static s32 atl2_phy_setup_autoneg_adv(struct atl2_hw *hw)
-{
-       s32 ret_val;
-       s16 mii_autoneg_adv_reg;
-
-       /* Read the MII Auto-Neg Advertisement Register (Address 4). */
-       mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
-
-       /* Need to parse autoneg_advertised  and set up
-        * the appropriate PHY registers.  First we will parse for
-        * autoneg_advertised software override.  Since we can advertise
-        * a plethora of combinations, we need to check each bit
-        * individually.
-        */
-
-       /* 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;
-
-       /* Need to parse MediaType and setup the
-        * appropriate PHY registers. */
-       switch (hw->MediaType) {
-       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);
-               hw->autoneg_advertised =
-                       ADVERTISE_10_HALF |
-                       ADVERTISE_10_FULL |
-                       ADVERTISE_100_HALF|
-                       ADVERTISE_100_FULL;
-               break;
-       case MEDIA_TYPE_100M_FULL:
-               mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
-               hw->autoneg_advertised = ADVERTISE_100_FULL;
-               break;
-       case MEDIA_TYPE_100M_HALF:
-               mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
-               hw->autoneg_advertised = ADVERTISE_100_HALF;
-               break;
-       case MEDIA_TYPE_10M_FULL:
-               mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
-               hw->autoneg_advertised = ADVERTISE_10_FULL;
-               break;
-       default:
-               mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
-               hw->autoneg_advertised = ADVERTISE_10_HALF;
-               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;
-
-       ret_val = atl2_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
-
-       if (ret_val)
-               return ret_val;
-
-       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 atl2_phy_commit(struct atl2_hw *hw)
-{
-       s32 ret_val;
-       u16 phy_data;
-
-       phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG;
-       ret_val = atl2_write_phy_reg(hw, MII_BMCR, phy_data);
-       if (ret_val) {
-               u32 val;
-               int i;
-               /* pcie serdes link may be down ! */
-               for (i = 0; i < 25; i++) {
-                       msleep(1);
-                       val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
-                       if (!(val & (MDIO_START | MDIO_BUSY)))
-                               break;
-               }
-
-               if (0 != (val & (MDIO_START | MDIO_BUSY))) {
-                       printk(KERN_ERR "atl2: PCIe link down for at least 25ms !\n");
-                       return ret_val;
-               }
-       }
-       return 0;
-}
-
-static s32 atl2_phy_init(struct atl2_hw *hw)
-{
-       s32 ret_val;
-       u16 phy_val;
-
-       if (hw->phy_configured)
-               return 0;
-
-       /* Enable PHY */
-       ATL2_WRITE_REGW(hw, REG_PHY_ENABLE, 1);
-       ATL2_WRITE_FLUSH(hw);
-       msleep(1);
-
-       /* check if the PHY is in powersaving mode */
-       atl2_write_phy_reg(hw, MII_DBG_ADDR, 0);
-       atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val);
-
-       /* 024E / 124E 0r 0274 / 1274 ? */
-       if (phy_val & 0x1000) {
-               phy_val &= ~0x1000;
-               atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val);
-       }
-
-       msleep(1);
-
-       /*Enable PHY LinkChange Interrupt */
-       ret_val = atl2_write_phy_reg(hw, 18, 0xC00);
-       if (ret_val)
-               return ret_val;
-
-       /* setup AutoNeg parameters */
-       ret_val = atl2_phy_setup_autoneg_adv(hw);
-       if (ret_val)
-               return ret_val;
-
-       /* SW.Reset & En-Auto-Neg to restart Auto-Neg */
-       ret_val = atl2_phy_commit(hw);
-       if (ret_val)
-               return ret_val;
-
-       hw->phy_configured = true;
-
-       return ret_val;
-}
-
-static void atl2_set_mac_addr(struct atl2_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]));
-       ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
-       /* hight dword */
-       value = (((u32)hw->mac_addr[0]) << 8) |
-               (((u32)hw->mac_addr[1]));
-       ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
-}
-
-/*
- * check_eeprom_exist
- * return 0 if eeprom exist
- */
-static int atl2_check_eeprom_exist(struct atl2_hw *hw)
-{
-       u32 value;
-
-       value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
-       if (value & SPI_FLASH_CTRL_EN_VPD) {
-               value &= ~SPI_FLASH_CTRL_EN_VPD;
-               ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
-       }
-       value = ATL2_READ_REGW(hw, REG_PCIE_CAP_LIST);
-       return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
-}
-
-/* FIXME: This doesn't look right. -- CHS */
-static bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value)
-{
-       return true;
-}
-
-static bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue)
-{
-       int i;
-       u32    Control;
-
-       if (Offset & 0x3)
-               return false; /* address do not align */
-
-       ATL2_WRITE_REG(hw, REG_VPD_DATA, 0);
-       Control = (Offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
-       ATL2_WRITE_REG(hw, REG_VPD_CAP, Control);
-
-       for (i = 0; i < 10; i++) {
-               msleep(2);
-               Control = ATL2_READ_REG(hw, REG_VPD_CAP);
-               if (Control & VPD_CAP_VPD_FLAG)
-                       break;
-       }
-
-       if (Control & VPD_CAP_VPD_FLAG) {
-               *pValue = ATL2_READ_REG(hw, REG_VPD_DATA);
-               return true;
-       }
-       return false; /* timeout */
-}
-
-static void atl2_force_ps(struct atl2_hw *hw)
-{
-       u16 phy_val;
-
-       atl2_write_phy_reg(hw, MII_DBG_ADDR, 0);
-       atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val);
-       atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val | 0x1000);
-
-       atl2_write_phy_reg(hw, MII_DBG_ADDR, 2);
-       atl2_write_phy_reg(hw, MII_DBG_DATA, 0x3000);
-       atl2_write_phy_reg(hw, MII_DBG_ADDR, 3);
-       atl2_write_phy_reg(hw, MII_DBG_DATA, 0);
-}
-
-/* This is the only thing that needs to be changed to adjust the
- * maximum number of ports that the driver can manage.
- */
-#define ATL2_MAX_NIC 4
-
-#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 ATL2_PARAM_INIT {[0 ... ATL2_MAX_NIC] = OPTION_UNSET}
-#ifndef module_param_array
-/* Module Parameters are always initialized to -1, so that the driver
- * can tell the difference between no user specified value or the
- * user asking for the default value.
- * The true default values are loaded in when atl2_check_options is called.
- *
- * This is a GCC extension to ANSI C.
- * See the item "Labeled Elements in Initializers" in the section
- * "Extensions to the C Language Family" of the GCC documentation.
- */
-
-#define ATL2_PARAM(X, desc) \
-    static const int __devinitdata X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \
-    MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \
-    MODULE_PARM_DESC(X, desc);
-#else
-#define ATL2_PARAM(X, desc) \
-    static int __devinitdata X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \
-    static unsigned int num_##X; \
-    module_param_array_named(X, X, int, &num_##X, 0); \
-    MODULE_PARM_DESC(X, desc);
-#endif
-
-/*
- * Transmit Memory Size
- * Valid Range: 64-2048
- * Default Value: 128
- */
-#define ATL2_MIN_TX_MEMSIZE            4       /* 4KB */
-#define ATL2_MAX_TX_MEMSIZE            64      /* 64KB */
-#define ATL2_DEFAULT_TX_MEMSIZE                8       /* 8KB */
-ATL2_PARAM(TxMemSize, "Bytes of Transmit Memory");
-
-/*
- * Receive Memory Block Count
- * Valid Range: 16-512
- * Default Value: 128
- */
-#define ATL2_MIN_RXD_COUNT             16
-#define ATL2_MAX_RXD_COUNT             512
-#define ATL2_DEFAULT_RXD_COUNT         64
-ATL2_PARAM(RxMemBlock, "Number of receive memory block");
-
-/*
- * User Specified MediaType Override
- *
- * Valid Range: 0-5
- *  - 0    - auto-negotiate at all supported speeds
- *  - 1    - only link at 1000Mbps Full Duplex
- *  - 2    - only link at 100Mbps Full Duplex
- *  - 3    - only link at 100Mbps Half Duplex
- *  - 4    - only link at 10Mbps Full Duplex
- *  - 5    - only link at 10Mbps Half Duplex
- * Default Value: 0
- */
-ATL2_PARAM(MediaType, "MediaType Select");
-
-/*
- * Interrupt Moderate Timer in units of 2048 ns (~2 us)
- * Valid Range: 10-65535
- * Default Value: 45000(90ms)
- */
-#define INT_MOD_DEFAULT_CNT    100 /* 200us */
-#define INT_MOD_MAX_CNT                65000
-#define INT_MOD_MIN_CNT                50
-ATL2_PARAM(IntModTimer, "Interrupt Moderator Timer");
-
-/*
- * FlashVendor
- * Valid Range: 0-2
- * 0 - Atmel
- * 1 - SST
- * 2 - ST
- */
-ATL2_PARAM(FlashVendor, "SPI Flash Vendor");
-
-#define AUTONEG_ADV_DEFAULT    0x2F
-#define AUTONEG_ADV_MASK       0x2F
-#define FLOW_CONTROL_DEFAULT   FLOW_CONTROL_FULL
-
-#define FLASH_VENDOR_DEFAULT   0
-#define FLASH_VENDOR_MIN       0
-#define FLASH_VENDOR_MAX       2
-
-struct atl2_option {
-       enum { enable_option, range_option, list_option } type;
-       char *name;
-       char *err;
-       int  def;
-       union {
-               struct { /* range_option info */
-                       int min;
-                       int max;
-               } r;
-               struct { /* list_option info */
-                       int nr;
-                       struct atl2_opt_list { int i; char *str; } *p;
-               } l;
-       } arg;
-};
-
-static int __devinit atl2_validate_option(int *value, struct atl2_option *opt)
-{
-       int i;
-       struct atl2_opt_list *ent;
-
-       if (*value == OPTION_UNSET) {
-               *value = opt->def;
-               return 0;
-       }
-
-       switch (opt->type) {
-       case enable_option:
-               switch (*value) {
-               case OPTION_ENABLED:
-                       printk(KERN_INFO "%s Enabled\n", opt->name);
-                       return 0;
-                       break;
-               case OPTION_DISABLED:
-                       printk(KERN_INFO "%s Disabled\n", opt->name);
-                       return 0;
-                       break;
-               }
-               break;
-       case range_option:
-               if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-                       printk(KERN_INFO "%s set to %i\n", opt->name, *value);
-                       return 0;
-               }
-               break;
-       case list_option:
-               for (i = 0; i < opt->arg.l.nr; i++) {
-                       ent = &opt->arg.l.p[i];
-                       if (*value == ent->i) {
-                               if (ent->str[0] != '\0')
-                                       printk(KERN_INFO "%s\n", ent->str);
-                       return 0;
-                       }
-               }
-               break;
-       default:
-               BUG();
-       }
-
-       printk(KERN_INFO "Invalid %s specified (%i) %s\n",
-               opt->name, *value, opt->err);
-       *value = opt->def;
-       return -1;
-}
-
-/*
- * atl2_check_options - Range Checking for Command Line Parameters
- * @adapter: board private structure
- *
- * 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.
- */
-static void __devinit atl2_check_options(struct atl2_adapter *adapter)
-{
-       int val;
-       struct atl2_option opt;
-       int bd = adapter->bd_number;
-       if (bd >= ATL2_MAX_NIC) {
-               printk(KERN_NOTICE "Warning: no configuration for board #%i\n",
-                       bd);
-               printk(KERN_NOTICE "Using defaults for all values\n");
-#ifndef module_param_array
-               bd = ATL2_MAX_NIC;
-#endif
-       }
-
-       /* Bytes of Transmit Memory */
-       opt.type = range_option;
-       opt.name = "Bytes of Transmit Memory";
-       opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_TX_MEMSIZE);
-       opt.def = ATL2_DEFAULT_TX_MEMSIZE;
-       opt.arg.r.min = ATL2_MIN_TX_MEMSIZE;
-       opt.arg.r.max = ATL2_MAX_TX_MEMSIZE;
-#ifdef module_param_array
-       if (num_TxMemSize > bd) {
-#endif
-               val = TxMemSize[bd];
-               atl2_validate_option(&val, &opt);
-               adapter->txd_ring_size = ((u32) val) * 1024;
-#ifdef module_param_array
-       } else
-               adapter->txd_ring_size = ((u32)opt.def) * 1024;
-#endif
-       /* txs ring size: */
-       adapter->txs_ring_size = adapter->txd_ring_size / 128;
-       if (adapter->txs_ring_size > 160)
-               adapter->txs_ring_size = 160;
-
-       /* Receive Memory Block Count */
-       opt.type = range_option;
-       opt.name = "Number of receive memory block";
-       opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_RXD_COUNT);
-       opt.def = ATL2_DEFAULT_RXD_COUNT;
-       opt.arg.r.min = ATL2_MIN_RXD_COUNT;
-       opt.arg.r.max = ATL2_MAX_RXD_COUNT;
-#ifdef module_param_array
-       if (num_RxMemBlock > bd) {
-#endif
-               val = RxMemBlock[bd];
-               atl2_validate_option(&val, &opt);
-               adapter->rxd_ring_size = (u32)val;
-               /* FIXME */
-               /* ((u16)val)&~1; */    /* even number */
-#ifdef module_param_array
-       } else
-               adapter->rxd_ring_size = (u32)opt.def;
-#endif
-       /* init RXD Flow control value */
-       adapter->hw.fc_rxd_hi = (adapter->rxd_ring_size / 8) * 7;
-       adapter->hw.fc_rxd_lo = (ATL2_MIN_RXD_COUNT / 8) >
-               (adapter->rxd_ring_size / 12) ? (ATL2_MIN_RXD_COUNT / 8) :
-               (adapter->rxd_ring_size / 12);
-
-       /* Interrupt Moderate Timer */
-       opt.type = range_option;
-       opt.name = "Interrupt Moderate Timer";
-       opt.err = "using default of " __MODULE_STRING(INT_MOD_DEFAULT_CNT);
-       opt.def = INT_MOD_DEFAULT_CNT;
-       opt.arg.r.min = INT_MOD_MIN_CNT;
-       opt.arg.r.max = INT_MOD_MAX_CNT;
-#ifdef module_param_array
-       if (num_IntModTimer > bd) {
-#endif
-               val = IntModTimer[bd];
-               atl2_validate_option(&val, &opt);
-               adapter->imt = (u16) val;
-#ifdef module_param_array
-       } else
-               adapter->imt = (u16)(opt.def);
-#endif
-       /* Flash Vendor */
-       opt.type = range_option;
-       opt.name = "SPI Flash Vendor";
-       opt.err = "using default of " __MODULE_STRING(FLASH_VENDOR_DEFAULT);
-       opt.def = FLASH_VENDOR_DEFAULT;
-       opt.arg.r.min = FLASH_VENDOR_MIN;
-       opt.arg.r.max = FLASH_VENDOR_MAX;
-#ifdef module_param_array
-       if (num_FlashVendor > bd) {
-#endif
-               val = FlashVendor[bd];
-               atl2_validate_option(&val, &opt);
-               adapter->hw.flash_vendor = (u8) val;
-#ifdef module_param_array
-       } else
-               adapter->hw.flash_vendor = (u8)(opt.def);
-#endif
-       /* MediaType */
-       opt.type = range_option;
-       opt.name = "Speed/Duplex Selection";
-       opt.err = "using default of " __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR);
-       opt.def = MEDIA_TYPE_AUTO_SENSOR;
-       opt.arg.r.min = MEDIA_TYPE_AUTO_SENSOR;
-       opt.arg.r.max = MEDIA_TYPE_10M_HALF;
-#ifdef module_param_array
-       if (num_MediaType > bd) {
-#endif
-               val = MediaType[bd];
-               atl2_validate_option(&val, &opt);
-               adapter->hw.MediaType = (u16) val;
-#ifdef module_param_array
-       } else
-               adapter->hw.MediaType = (u16)(opt.def);
-#endif
-}
diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h
deleted file mode 100644 (file)
index bf9016e..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-/* atl2.h -- atl2 driver definitions
- *
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- * Copyright(c) 2006 xiong huang <xiong.huang@atheros.com>
- * Copyright(c) 2007 Chris Snook <csnook@redhat.com>
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#ifndef _ATL2_H_
-#define _ATL2_H_
-
-#include <linux/atomic.h>
-#include <linux/netdevice.h>
-
-#ifndef _ATL2_HW_H_
-#define _ATL2_HW_H_
-
-#ifndef _ATL2_OSDEP_H_
-#define _ATL2_OSDEP_H_
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-
-#include "atlx.h"
-
-#ifdef ETHTOOL_OPS_COMPAT
-extern int ethtool_ioctl(struct ifreq *ifr);
-#endif
-
-#define PCI_COMMAND_REGISTER   PCI_COMMAND
-#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
-#define ETH_ADDR_LEN           ETH_ALEN
-
-#define ATL2_WRITE_REG(a, reg, value) (iowrite32((value), \
-       ((a)->hw_addr + (reg))))
-
-#define ATL2_WRITE_FLUSH(a) (ioread32((a)->hw_addr))
-
-#define ATL2_READ_REG(a, reg) (ioread32((a)->hw_addr + (reg)))
-
-#define ATL2_WRITE_REGB(a, reg, value) (iowrite8((value), \
-       ((a)->hw_addr + (reg))))
-
-#define ATL2_READ_REGB(a, reg) (ioread8((a)->hw_addr + (reg)))
-
-#define ATL2_WRITE_REGW(a, reg, value) (iowrite16((value), \
-       ((a)->hw_addr + (reg))))
-
-#define ATL2_READ_REGW(a, reg) (ioread16((a)->hw_addr + (reg)))
-
-#define ATL2_WRITE_REG_ARRAY(a, reg, offset, value) \
-       (iowrite32((value), (((a)->hw_addr + (reg)) + ((offset) << 2))))
-
-#define ATL2_READ_REG_ARRAY(a, reg, offset) \
-       (ioread32(((a)->hw_addr + (reg)) + ((offset) << 2)))
-
-#endif /* _ATL2_OSDEP_H_ */
-
-struct atl2_adapter;
-struct atl2_hw;
-
-/* function prototype */
-static s32 atl2_reset_hw(struct atl2_hw *hw);
-static s32 atl2_read_mac_addr(struct atl2_hw *hw);
-static s32 atl2_init_hw(struct atl2_hw *hw);
-static s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed,
-       u16 *duplex);
-static u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr);
-static void atl2_hash_set(struct atl2_hw *hw, u32 hash_value);
-static s32 atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data);
-static s32 atl2_write_phy_reg(struct atl2_hw *hw, u32 reg_addr, u16 phy_data);
-static void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value);
-static void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value);
-static void atl2_set_mac_addr(struct atl2_hw *hw);
-static bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue);
-static bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value);
-static s32 atl2_phy_init(struct atl2_hw *hw);
-static int atl2_check_eeprom_exist(struct atl2_hw *hw);
-static void atl2_force_ps(struct atl2_hw *hw);
-
-/* register definition */
-
-/* Block IDLE Status Register */
-#define IDLE_STATUS_RXMAC      1       /* 1: RXMAC is non-IDLE */
-#define IDLE_STATUS_TXMAC      2       /* 1: TXMAC is non-IDLE */
-#define IDLE_STATUS_DMAR       8       /* 1: DMAR is non-IDLE */
-#define IDLE_STATUS_DMAW       4       /* 1: DMAW is non-IDLE */
-
-/* MDIO Control Register */
-#define MDIO_WAIT_TIMES                10
-
-/* MAC Control Register */
-#define MAC_CTRL_DBG_TX_BKPRESURE      0x100000        /* 1: TX max backoff */
-#define MAC_CTRL_MACLP_CLK_PHY         0x8000000       /* 1: 25MHz from phy */
-#define MAC_CTRL_HALF_LEFT_BUF_SHIFT   28
-#define MAC_CTRL_HALF_LEFT_BUF_MASK    0xF             /* MAC retry buf x32B */
-
-/* Internal SRAM Partition Register */
-#define REG_SRAM_TXRAM_END     0x1500  /* Internal tail address of TXRAM
-                                        * default: 2byte*1024 */
-#define REG_SRAM_RXRAM_END     0x1502  /* Internal tail address of RXRAM
-                                        * default: 2byte*1024 */
-
-/* Descriptor Control register */
-#define REG_TXD_BASE_ADDR_LO   0x1544  /* The base address of the Transmit
-                                        * Data Mem low 32-bit(dword align) */
-#define REG_TXD_MEM_SIZE       0x1548  /* Transmit Data Memory size(by
-                                        * double word , max 256KB) */
-#define REG_TXS_BASE_ADDR_LO   0x154C  /* The base address of the Transmit
-                                        * Status Memory low 32-bit(dword word
-                                        * align) */
-#define REG_TXS_MEM_SIZE       0x1550  /* double word unit, max 4*2047
-                                        * bytes. */
-#define REG_RXD_BASE_ADDR_LO   0x1554  /* The base address of the Transmit
-                                        * Status Memory low 32-bit(unit 8
-                                        * bytes) */
-#define REG_RXD_BUF_NUM                0x1558  /* Receive Data & Status Memory buffer
-                                        * number (unit 1536bytes, max
-                                        * 1536*2047) */
-
-/* DMAR Control Register */
-#define REG_DMAR       0x1580
-#define     DMAR_EN    0x1     /* 1: Enable DMAR */
-
-/* TX Cur-Through (early tx threshold) Control Register */
-#define REG_TX_CUT_THRESH      0x1590  /* TxMac begin transmit packet
-                                        * threshold(unit word) */
-
-/* DMAW Control Register */
-#define REG_DMAW       0x15A0
-#define     DMAW_EN    0x1
-
-/* Flow control register */
-#define REG_PAUSE_ON_TH                0x15A8  /* RXD high watermark of overflow
-                                        * threshold configuration register */
-#define REG_PAUSE_OFF_TH       0x15AA  /* RXD lower watermark of overflow
-                                        * threshold configuration register */
-
-/* Mailbox Register */
-#define REG_MB_TXD_WR_IDX      0x15f0  /* double word align */
-#define REG_MB_RXD_RD_IDX      0x15F4  /* RXD Read index (unit: 1536byets) */
-
-/* Interrupt Status Register */
-#define ISR_TIMER      1       /* Interrupt when Timer counts down to zero */
-#define ISR_MANUAL     2       /* Software manual interrupt, for debug. Set
-                                * when SW_MAN_INT_EN is set in Table 51
-                                * Selene Master Control Register
-                                * (Offset 0x1400). */
-#define ISR_RXF_OV     4       /* RXF overflow interrupt */
-#define ISR_TXF_UR     8       /* TXF underrun interrupt */
-#define ISR_TXS_OV     0x10    /* Internal transmit status buffer full
-                                * interrupt */
-#define ISR_RXS_OV     0x20    /* Internal receive status buffer full
-                                * interrupt */
-#define ISR_LINK_CHG   0x40    /* Link Status Change Interrupt */
-#define ISR_HOST_TXD_UR        0x80
-#define ISR_HOST_RXD_OV        0x100   /* Host rx data memory full , one pulse */
-#define ISR_DMAR_TO_RST        0x200   /* DMAR op timeout interrupt. SW should
-                                * do Reset */
-#define ISR_DMAW_TO_RST        0x400
-#define ISR_PHY                0x800   /* phy interrupt */
-#define ISR_TS_UPDATE  0x10000 /* interrupt after new tx pkt status written
-                                * to host */
-#define ISR_RS_UPDATE  0x20000 /* interrupt ater new rx pkt status written
-                                * to host. */
-#define ISR_TX_EARLY   0x40000 /* interrupt when txmac begin transmit one
-                                * packet */
-
-#define ISR_TX_EVENT (ISR_TXF_UR | ISR_TXS_OV | ISR_HOST_TXD_UR |\
-       ISR_TS_UPDATE | ISR_TX_EARLY)
-#define ISR_RX_EVENT (ISR_RXF_OV | ISR_RXS_OV | ISR_HOST_RXD_OV |\
-        ISR_RS_UPDATE)
-
-#define IMR_NORMAL_MASK                (\
-       /*ISR_LINK_CHG          |*/\
-       ISR_MANUAL              |\
-       ISR_DMAR_TO_RST         |\
-       ISR_DMAW_TO_RST         |\
-       ISR_PHY                 |\
-       ISR_PHY_LINKDOWN        |\
-       ISR_TS_UPDATE           |\
-       ISR_RS_UPDATE)
-
-/* Receive MAC Statistics Registers */
-#define REG_STS_RX_PAUSE       0x1700  /* Num pause packets received */
-#define REG_STS_RXD_OV         0x1704  /* Num frames dropped due to RX
-                                        * FIFO overflow */
-#define REG_STS_RXS_OV         0x1708  /* Num frames dropped due to RX
-                                        * Status Buffer Overflow */
-#define REG_STS_RX_FILTER      0x170C  /* Num packets dropped due to
-                                        * address filtering */
-
-/* MII definitions */
-
-/* PHY Common Register */
-#define MII_SMARTSPEED 0x14
-#define MII_DBG_ADDR   0x1D
-#define MII_DBG_DATA   0x1E
-
-/* PCI Command Register Bit Definitions */
-#define PCI_REG_COMMAND                0x04
-#define CMD_IO_SPACE           0x0001
-#define CMD_MEMORY_SPACE       0x0002
-#define CMD_BUS_MASTER         0x0004
-
-#define MEDIA_TYPE_100M_FULL   1
-#define MEDIA_TYPE_100M_HALF   2
-#define MEDIA_TYPE_10M_FULL    3
-#define MEDIA_TYPE_10M_HALF    4
-
-#define AUTONEG_ADVERTISE_SPEED_DEFAULT        0x000F  /* Everything */
-
-/* The size (in bytes) of a ethernet packet */
-#define ENET_HEADER_SIZE               14
-#define MAXIMUM_ETHERNET_FRAME_SIZE    1518    /* with FCS */
-#define MINIMUM_ETHERNET_FRAME_SIZE    64      /* with FCS */
-#define ETHERNET_FCS_SIZE              4
-#define MAX_JUMBO_FRAME_SIZE           0x2000
-#define VLAN_SIZE                                               4
-
-struct tx_pkt_header {
-       unsigned pkt_size:11;
-       unsigned:4;                     /* reserved */
-       unsigned ins_vlan:1;            /* txmac should insert vlan */
-       unsigned short vlan;            /* vlan tag */
-};
-/* FIXME: replace above bitfields with MASK/SHIFT defines below */
-#define TX_PKT_HEADER_SIZE_MASK                0x7FF
-#define TX_PKT_HEADER_SIZE_SHIFT       0
-#define TX_PKT_HEADER_INS_VLAN_MASK    0x1
-#define TX_PKT_HEADER_INS_VLAN_SHIFT   15
-#define TX_PKT_HEADER_VLAN_TAG_MASK    0xFFFF
-#define TX_PKT_HEADER_VLAN_TAG_SHIFT   16
-
-struct tx_pkt_status {
-       unsigned pkt_size:11;
-       unsigned:5;             /* reserved */
-       unsigned ok:1;          /* current packet transmitted without error */
-       unsigned bcast:1;       /* broadcast packet */
-       unsigned mcast:1;       /* multicast packet */
-       unsigned pause:1;       /* transmiited a pause frame */
-       unsigned ctrl:1;
-       unsigned defer:1;       /* current packet is xmitted with defer */
-       unsigned exc_defer:1;
-       unsigned single_col:1;
-       unsigned multi_col:1;
-       unsigned late_col:1;
-       unsigned abort_col:1;
-       unsigned underun:1;     /* current packet is aborted
-                                * due to txram underrun */
-       unsigned:3;             /* reserved */
-       unsigned update:1;      /* always 1'b1 in tx_status_buf */
-};
-/* FIXME: replace above bitfields with MASK/SHIFT defines below */
-#define TX_PKT_STATUS_SIZE_MASK                0x7FF
-#define TX_PKT_STATUS_SIZE_SHIFT       0
-#define TX_PKT_STATUS_OK_MASK          0x1
-#define TX_PKT_STATUS_OK_SHIFT         16
-#define TX_PKT_STATUS_BCAST_MASK       0x1
-#define TX_PKT_STATUS_BCAST_SHIFT      17
-#define TX_PKT_STATUS_MCAST_MASK       0x1
-#define TX_PKT_STATUS_MCAST_SHIFT      18
-#define TX_PKT_STATUS_PAUSE_MASK       0x1
-#define TX_PKT_STATUS_PAUSE_SHIFT      19
-#define TX_PKT_STATUS_CTRL_MASK                0x1
-#define TX_PKT_STATUS_CTRL_SHIFT       20
-#define TX_PKT_STATUS_DEFER_MASK       0x1
-#define TX_PKT_STATUS_DEFER_SHIFT      21
-#define TX_PKT_STATUS_EXC_DEFER_MASK   0x1
-#define TX_PKT_STATUS_EXC_DEFER_SHIFT  22
-#define TX_PKT_STATUS_SINGLE_COL_MASK  0x1
-#define TX_PKT_STATUS_SINGLE_COL_SHIFT 23
-#define TX_PKT_STATUS_MULTI_COL_MASK   0x1
-#define TX_PKT_STATUS_MULTI_COL_SHIFT  24
-#define TX_PKT_STATUS_LATE_COL_MASK    0x1
-#define TX_PKT_STATUS_LATE_COL_SHIFT   25
-#define TX_PKT_STATUS_ABORT_COL_MASK   0x1
-#define TX_PKT_STATUS_ABORT_COL_SHIFT  26
-#define TX_PKT_STATUS_UNDERRUN_MASK    0x1
-#define TX_PKT_STATUS_UNDERRUN_SHIFT   27
-#define TX_PKT_STATUS_UPDATE_MASK      0x1
-#define TX_PKT_STATUS_UPDATE_SHIFT     31
-
-struct rx_pkt_status {
-       unsigned pkt_size:11;   /* packet size, max 2047 bytes */
-       unsigned:5;             /* reserved */
-       unsigned ok:1;          /* current packet received ok without error */
-       unsigned bcast:1;       /* current packet is broadcast */
-       unsigned mcast:1;       /* current packet is multicast */
-       unsigned pause:1;
-       unsigned ctrl:1;
-       unsigned crc:1;         /* received a packet with crc error */
-       unsigned code:1;        /* received a packet with code error */
-       unsigned runt:1;        /* received a packet less than 64 bytes
-                                * with good crc */
-       unsigned frag:1;        /* received a packet less than 64 bytes
-                                * with bad crc */
-       unsigned trunc:1;       /* current frame truncated due to rxram full */
-       unsigned align:1;       /* this packet is alignment error */
-       unsigned vlan:1;        /* this packet has vlan */
-       unsigned:3;             /* reserved */
-       unsigned update:1;
-       unsigned short vtag;    /* vlan tag */
-       unsigned:16;
-};
-/* FIXME: replace above bitfields with MASK/SHIFT defines below */
-#define RX_PKT_STATUS_SIZE_MASK                0x7FF
-#define RX_PKT_STATUS_SIZE_SHIFT       0
-#define RX_PKT_STATUS_OK_MASK          0x1
-#define RX_PKT_STATUS_OK_SHIFT         16
-#define RX_PKT_STATUS_BCAST_MASK       0x1
-#define RX_PKT_STATUS_BCAST_SHIFT      17
-#define RX_PKT_STATUS_MCAST_MASK       0x1
-#define RX_PKT_STATUS_MCAST_SHIFT      18
-#define RX_PKT_STATUS_PAUSE_MASK       0x1
-#define RX_PKT_STATUS_PAUSE_SHIFT      19
-#define RX_PKT_STATUS_CTRL_MASK                0x1
-#define RX_PKT_STATUS_CTRL_SHIFT       20
-#define RX_PKT_STATUS_CRC_MASK         0x1
-#define RX_PKT_STATUS_CRC_SHIFT                21
-#define RX_PKT_STATUS_CODE_MASK                0x1
-#define RX_PKT_STATUS_CODE_SHIFT       22
-#define RX_PKT_STATUS_RUNT_MASK                0x1
-#define RX_PKT_STATUS_RUNT_SHIFT       23
-#define RX_PKT_STATUS_FRAG_MASK                0x1
-#define RX_PKT_STATUS_FRAG_SHIFT       24
-#define RX_PKT_STATUS_TRUNK_MASK       0x1
-#define RX_PKT_STATUS_TRUNK_SHIFT      25
-#define RX_PKT_STATUS_ALIGN_MASK       0x1
-#define RX_PKT_STATUS_ALIGN_SHIFT      26
-#define RX_PKT_STATUS_VLAN_MASK                0x1
-#define RX_PKT_STATUS_VLAN_SHIFT       27
-#define RX_PKT_STATUS_UPDATE_MASK      0x1
-#define RX_PKT_STATUS_UPDATE_SHIFT     31
-#define RX_PKT_STATUS_VLAN_TAG_MASK    0xFFFF
-#define RX_PKT_STATUS_VLAN_TAG_SHIFT   32
-
-struct rx_desc {
-       struct rx_pkt_status    status;
-       unsigned char           packet[1536-sizeof(struct rx_pkt_status)];
-};
-
-enum atl2_speed_duplex {
-       atl2_10_half = 0,
-       atl2_10_full = 1,
-       atl2_100_half = 2,
-       atl2_100_full = 3
-};
-
-struct atl2_spi_flash_dev {
-       const char *manu_name;  /* manufacturer id */
-       /* op-code */
-       u8 cmdWRSR;
-       u8 cmdREAD;
-       u8 cmdPROGRAM;
-       u8 cmdWREN;
-       u8 cmdWRDI;
-       u8 cmdRDSR;
-       u8 cmdRDID;
-       u8 cmdSECTOR_ERASE;
-       u8 cmdCHIP_ERASE;
-};
-
-/* Structure containing variables used by the shared code (atl2_hw.c) */
-struct atl2_hw {
-       u8 __iomem *hw_addr;
-       void *back;
-
-       u8 preamble_len;
-       u8 max_retry;          /* Retransmission maximum, afterwards the
-                               * packet will be discarded. */
-       u8 jam_ipg;            /* IPG to start JAM for collision based flow
-                               * control in half-duplex mode. In unit of
-                               * 8-bit time. */
-       u8 ipgt;               /* Desired back to back inter-packet gap. The
-                               * default is 96-bit time. */
-       u8 min_ifg;            /* Minimum number of IFG to enforce in between
-                               * RX frames. Frame gap below such IFP is
-                               * dropped. */
-       u8 ipgr1;              /* 64bit Carrier-Sense window */
-       u8 ipgr2;              /* 96-bit IPG window */
-       u8 retry_buf;          /* When half-duplex mode, should hold some
-                               * bytes for mac retry . (8*4bytes unit) */
-
-       u16 fc_rxd_hi;
-       u16 fc_rxd_lo;
-       u16 lcol;              /* Collision Window */
-       u16 max_frame_size;
-
-       u16 MediaType;
-       u16 autoneg_advertised;
-       u16 pci_cmd_word;
-
-       u16 mii_autoneg_adv_reg;
-
-       u32 mem_rang;
-       u32 txcw;
-       u32 mc_filter_type;
-       u32 num_mc_addrs;
-       u32 collision_delta;
-       u32 tx_packet_delta;
-       u16 phy_spd_default;
-
-       u16 device_id;
-       u16 vendor_id;
-       u16 subsystem_id;
-       u16 subsystem_vendor_id;
-       u8 revision_id;
-
-       /* spi flash */
-       u8 flash_vendor;
-
-       u8 dma_fairness;
-       u8 mac_addr[NODE_ADDRESS_SIZE];
-       u8 perm_mac_addr[NODE_ADDRESS_SIZE];
-
-       /* FIXME */
-       /* bool phy_preamble_sup; */
-       bool phy_configured;
-};
-
-#endif /* _ATL2_HW_H_ */
-
-struct atl2_ring_header {
-    /* pointer to the descriptor ring memory */
-    void *desc;
-    /* physical address of the descriptor ring */
-    dma_addr_t dma;
-    /* length of descriptor ring in bytes */
-    unsigned int size;
-};
-
-/* board specific private data structure */
-struct atl2_adapter {
-       /* OS defined structs */
-       struct net_device *netdev;
-       struct pci_dev *pdev;
-       u32 wol;
-       u16 link_speed;
-       u16 link_duplex;
-
-       spinlock_t stats_lock;
-
-       struct work_struct reset_task;
-       struct work_struct link_chg_task;
-       struct timer_list watchdog_timer;
-       struct timer_list phy_config_timer;
-
-       unsigned long cfg_phy;
-       bool mac_disabled;
-
-       /* All Descriptor memory */
-       dma_addr_t      ring_dma;
-       void            *ring_vir_addr;
-       int             ring_size;
-
-       struct tx_pkt_header    *txd_ring;
-       dma_addr_t      txd_dma;
-
-       struct tx_pkt_status    *txs_ring;
-       dma_addr_t      txs_dma;
-
-       struct rx_desc  *rxd_ring;
-       dma_addr_t      rxd_dma;
-
-       u32 txd_ring_size;         /* bytes per unit */
-       u32 txs_ring_size;         /* dwords per unit */
-       u32 rxd_ring_size;         /* 1536 bytes per unit */
-
-       /* read /write ptr: */
-       /* host */
-       u32 txd_write_ptr;
-       u32 txs_next_clear;
-       u32 rxd_read_ptr;
-
-       /* nic */
-       atomic_t txd_read_ptr;
-       atomic_t txs_write_ptr;
-       u32 rxd_write_ptr;
-
-       /* Interrupt Moderator timer ( 2us resolution) */
-       u16 imt;
-       /* Interrupt Clear timer (2us resolution) */
-       u16 ict;
-
-       unsigned long flags;
-       /* structs defined in atl2_hw.h */
-       u32 bd_number;     /* board number */
-       bool pci_using_64;
-       bool have_msi;
-       struct atl2_hw hw;
-
-       u32 usr_cmd;
-       /* FIXME */
-       /* u32 regs_buff[ATL2_REGS_LEN]; */
-       u32 pci_state[16];
-
-       u32 *config_space;
-};
-
-enum atl2_state_t {
-       __ATL2_TESTING,
-       __ATL2_RESETTING,
-       __ATL2_DOWN
-};
-
-#endif /* _ATL2_H_ */
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
deleted file mode 100644 (file)
index aabcf4b..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/* atlx.c -- common functions for Attansic network drivers
- *
- * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
- * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-/* Including this file like a header is a temporary hack, I promise. -- CHS */
-#ifndef ATLX_C
-#define ATLX_C
-
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/etherdevice.h>
-#include <linux/if.h>
-#include <linux/netdevice.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/workqueue.h>
-
-#include "atlx.h"
-
-static s32 atlx_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data);
-static u32 atlx_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
-static void atlx_set_mac_addr(struct atl1_hw *hw);
-
-static struct atlx_spi_flash_dev flash_table[] = {
-/*     MFR_NAME  WRSR  READ  PRGM  WREN  WRDI  RDSR  RDID  SEC_ERS CHIP_ERS */
-       {"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52,   0x62},
-       {"SST",   0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20,   0x60},
-       {"ST",    0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8,   0xC7},
-};
-
-static int atlx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-       switch (cmd) {
-       case SIOCGMIIPHY:
-       case SIOCGMIIREG:
-       case SIOCSMIIREG:
-               return atlx_mii_ioctl(netdev, ifr, cmd);
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-/*
- * atlx_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 atlx_set_mac(struct net_device *netdev, void *p)
-{
-       struct atlx_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);
-
-       atlx_set_mac_addr(&adapter->hw);
-       return 0;
-}
-
-static void atlx_check_for_link(struct atlx_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       u16 phy_data = 0;
-
-       spin_lock(&adapter->lock);
-       adapter->phy_timer_pending = false;
-       atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-       atlx_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);
-               }
-       }
-       schedule_work(&adapter->link_chg_task);
-}
-
-/*
- * atlx_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 atlx_set_multi(struct net_device *netdev)
-{
-       struct atlx_adapter *adapter = netdev_priv(netdev);
-       struct atlx_hw *hw = &adapter->hw;
-       struct netdev_hw_addr *ha;
-       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 */
-       netdev_for_each_mc_addr(ha, netdev) {
-               hash_value = atlx_hash_mc_addr(hw, ha->addr);
-               atlx_hash_set(hw, hash_value);
-       }
-}
-
-/*
- * atlx_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- */
-static void atlx_irq_enable(struct atlx_adapter *adapter)
-{
-       iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
-       ioread32(adapter->hw.hw_addr + REG_IMR);
-}
-
-/*
- * atlx_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- */
-static void atlx_irq_disable(struct atlx_adapter *adapter)
-{
-       iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-       ioread32(adapter->hw.hw_addr + REG_IMR);
-       synchronize_irq(adapter->pdev->irq);
-}
-
-static void atlx_clear_phy_int(struct atlx_adapter *adapter)
-{
-       u16 phy_data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&adapter->lock, flags);
-       atlx_read_phy_reg(&adapter->hw, 19, &phy_data);
-       spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-/*
- * atlx_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- */
-static void atlx_tx_timeout(struct net_device *netdev)
-{
-       struct atlx_adapter *adapter = netdev_priv(netdev);
-       /* Do the reset outside of interrupt context */
-       schedule_work(&adapter->tx_timeout_task);
-}
-
-/*
- * atlx_link_chg_task - deal with link change event Out of interrupt context
- */
-static void atlx_link_chg_task(struct work_struct *work)
-{
-       struct atlx_adapter *adapter;
-       unsigned long flags;
-
-       adapter = container_of(work, struct atlx_adapter, link_chg_task);
-
-       spin_lock_irqsave(&adapter->lock, flags);
-       atlx_check_link(adapter);
-       spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static void __atlx_vlan_mode(u32 features, u32 *ctrl)
-{
-       if (features & NETIF_F_HW_VLAN_RX) {
-               /* enable VLAN tag insert/strip */
-               *ctrl |= MAC_CTRL_RMV_VLAN;
-       } else {
-               /* disable VLAN tag insert/strip */
-               *ctrl &= ~MAC_CTRL_RMV_VLAN;
-       }
-}
-
-static void atlx_vlan_mode(struct net_device *netdev, u32 features)
-{
-       struct atlx_adapter *adapter = netdev_priv(netdev);
-       unsigned long flags;
-       u32 ctrl;
-
-       spin_lock_irqsave(&adapter->lock, flags);
-       /* atlx_irq_disable(adapter); FIXME: confirm/remove */
-       ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
-       __atlx_vlan_mode(features, &ctrl);
-       iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
-       /* atlx_irq_enable(adapter); FIXME */
-       spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static void atlx_restore_vlan(struct atlx_adapter *adapter)
-{
-       atlx_vlan_mode(adapter->netdev, adapter->netdev->features);
-}
-
-static u32 atlx_fix_features(struct net_device *netdev, u32 features)
-{
-       /*
-        * Since there is no support for separate rx/tx vlan accel
-        * enable/disable make sure tx flag is always in same state as rx.
-        */
-       if (features & NETIF_F_HW_VLAN_RX)
-               features |= NETIF_F_HW_VLAN_TX;
-       else
-               features &= ~NETIF_F_HW_VLAN_TX;
-
-       return features;
-}
-
-static int atlx_set_features(struct net_device *netdev, u32 features)
-{
-       u32 changed = netdev->features ^ features;
-
-       if (changed & NETIF_F_HW_VLAN_RX)
-               atlx_vlan_mode(netdev, features);
-
-       return 0;
-}
-
-#endif /* ATLX_C */
diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h
deleted file mode 100644 (file)
index 14054b7..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/* atlx_hw.h -- common hardware definitions for Attansic network drivers
- *
- * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
- * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
- * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
- * Copyright(c) 2007 Atheros Corporation. All rights reserved.
- *
- * Derived from Intel e1000 driver
- * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * 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.
- */
-
-#ifndef ATLX_H
-#define ATLX_H
-
-#include <linux/module.h>
-#include <linux/types.h>
-
-#define ATLX_ERR_PHY                   2
-#define ATLX_ERR_PHY_SPEED             7
-#define ATLX_ERR_PHY_RES               8
-
-#define SPEED_0                                0xffff
-#define SPEED_10                       10
-#define SPEED_100                      100
-#define SPEED_1000                     1000
-#define HALF_DUPLEX                    1
-#define FULL_DUPLEX                    2
-
-#define MEDIA_TYPE_AUTO_SENSOR         0
-
-/* register definitions */
-#define REG_PM_CTRLSTAT                        0x44
-
-#define REG_PCIE_CAP_LIST              0x58
-
-#define REG_VPD_CAP                    0x6C
-#define VPD_CAP_ID_MASK                        0xFF
-#define VPD_CAP_ID_SHIFT               0
-#define VPD_CAP_NEXT_PTR_MASK          0xFF
-#define VPD_CAP_NEXT_PTR_SHIFT         8
-#define VPD_CAP_VPD_ADDR_MASK          0x7FFF
-#define VPD_CAP_VPD_ADDR_SHIFT         16
-#define VPD_CAP_VPD_FLAG               0x80000000
-
-#define REG_VPD_DATA                   0x70
-
-#define REG_SPI_FLASH_CTRL             0x200
-#define SPI_FLASH_CTRL_STS_NON_RDY     0x1
-#define SPI_FLASH_CTRL_STS_WEN         0x2
-#define SPI_FLASH_CTRL_STS_WPEN                0x80
-#define SPI_FLASH_CTRL_DEV_STS_MASK    0xFF
-#define SPI_FLASH_CTRL_DEV_STS_SHIFT   0
-#define SPI_FLASH_CTRL_INS_MASK                0x7
-#define SPI_FLASH_CTRL_INS_SHIFT       8
-#define SPI_FLASH_CTRL_START           0x800
-#define SPI_FLASH_CTRL_EN_VPD          0x2000
-#define SPI_FLASH_CTRL_LDSTART         0x8000
-#define SPI_FLASH_CTRL_CS_HI_MASK      0x3
-#define SPI_FLASH_CTRL_CS_HI_SHIFT     16
-#define SPI_FLASH_CTRL_CS_HOLD_MASK    0x3
-#define SPI_FLASH_CTRL_CS_HOLD_SHIFT   18
-#define SPI_FLASH_CTRL_CLK_LO_MASK     0x3
-#define SPI_FLASH_CTRL_CLK_LO_SHIFT    20
-#define SPI_FLASH_CTRL_CLK_HI_MASK     0x3
-#define SPI_FLASH_CTRL_CLK_HI_SHIFT    22
-#define SPI_FLASH_CTRL_CS_SETUP_MASK   0x3
-#define SPI_FLASH_CTRL_CS_SETUP_SHIFT  24
-#define SPI_FLASH_CTRL_EROM_PGSZ_MASK  0x3
-#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26
-#define SPI_FLASH_CTRL_WAIT_READY      0x10000000
-
-#define REG_SPI_ADDR                   0x204
-
-#define REG_SPI_DATA                   0x208
-
-#define REG_SPI_FLASH_CONFIG           0x20C
-#define SPI_FLASH_CONFIG_LD_ADDR_MASK  0xFFFFFF
-#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0
-#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3
-#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT        24
-#define SPI_FLASH_CONFIG_LD_EXIST      0x4000000
-
-#define REG_SPI_FLASH_OP_PROGRAM       0x210
-#define REG_SPI_FLASH_OP_SC_ERASE      0x211
-#define REG_SPI_FLASH_OP_CHIP_ERASE    0x212
-#define REG_SPI_FLASH_OP_RDID          0x213
-#define REG_SPI_FLASH_OP_WREN          0x214
-#define REG_SPI_FLASH_OP_RDSR          0x215
-#define REG_SPI_FLASH_OP_WRSR          0x216
-#define REG_SPI_FLASH_OP_READ          0x217
-
-#define REG_TWSI_CTRL                  0x218
-#define TWSI_CTRL_LD_OFFSET_MASK       0xFF
-#define TWSI_CTRL_LD_OFFSET_SHIFT      0
-#define TWSI_CTRL_LD_SLV_ADDR_MASK     0x7
-#define TWSI_CTRL_LD_SLV_ADDR_SHIFT    8
-#define TWSI_CTRL_SW_LDSTART           0x800
-#define TWSI_CTRL_HW_LDSTART           0x1000
-#define TWSI_CTRL_SMB_SLV_ADDR_MASK    0x7F
-#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT   15
-#define TWSI_CTRL_LD_EXIST             0x400000
-#define TWSI_CTRL_READ_FREQ_SEL_MASK   0x3
-#define TWSI_CTRL_READ_FREQ_SEL_SHIFT  23
-#define TWSI_CTRL_FREQ_SEL_100K                0
-#define TWSI_CTRL_FREQ_SEL_200K                1
-#define TWSI_CTRL_FREQ_SEL_300K                2
-#define TWSI_CTRL_FREQ_SEL_400K                3
-#define TWSI_CTRL_SMB_SLV_ADDR         /* FIXME: define or remove */
-#define TWSI_CTRL_WRITE_FREQ_SEL_MASK  0x3
-#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24
-
-#define REG_PCIE_DEV_MISC_CTRL                 0x21C
-#define PCIE_DEV_MISC_CTRL_EXT_PIPE            0x2
-#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS                0x1
-#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST                0x4
-#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN       0x8
-#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN      0x10
-
-#define REG_PCIE_PHYMISC               0x1000
-#define PCIE_PHYMISC_FORCE_RCV_DET     0x4
-
-#define REG_PCIE_DLL_TX_CTRL1          0x1104
-#define PCIE_DLL_TX_CTRL1_SEL_NOR_CLK  0x400
-#define PCIE_DLL_TX_CTRL1_DEF          0x568
-
-#define REG_LTSSM_TEST_MODE            0x12FC
-#define LTSSM_TEST_MODE_DEF            0x6500
-
-/* Master Control Register */
-#define REG_MASTER_CTRL                        0x1400
-#define MASTER_CTRL_SOFT_RST           0x1
-#define MASTER_CTRL_MTIMER_EN          0x2
-#define MASTER_CTRL_ITIMER_EN          0x4
-#define MASTER_CTRL_MANUAL_INT         0x8
-#define MASTER_CTRL_REV_NUM_SHIFT      16
-#define MASTER_CTRL_REV_NUM_MASK       0xFF
-#define MASTER_CTRL_DEV_ID_SHIFT       24
-#define MASTER_CTRL_DEV_ID_MASK                0xFF
-
-/* Timer Initial Value Register */
-#define REG_MANUAL_TIMER_INIT          0x1404
-
-/* IRQ Moderator Timer Initial Value Register */
-#define REG_IRQ_MODU_TIMER_INIT                0x1408
-
-#define REG_PHY_ENABLE                 0x140C
-
-/* IRQ Anti-Lost Timer Initial Value Register */
-#define REG_CMBDISDMA_TIMER            0x140E
-
-/* Block IDLE Status Register */
-#define REG_IDLE_STATUS                        0x1410
-
-/* MDIO Control Register */
-#define REG_MDIO_CTRL                  0x1414
-#define MDIO_DATA_MASK                 0xFFFF
-#define MDIO_DATA_SHIFT                        0
-#define MDIO_REG_ADDR_MASK             0x1F
-#define MDIO_REG_ADDR_SHIFT            16
-#define MDIO_RW                                0x200000
-#define MDIO_SUP_PREAMBLE              0x400000
-#define MDIO_START                     0x800000
-#define MDIO_CLK_SEL_SHIFT             24
-#define MDIO_CLK_25_4                  0
-#define MDIO_CLK_25_6                  2
-#define MDIO_CLK_25_8                  3
-#define MDIO_CLK_25_10                 4
-#define MDIO_CLK_25_14                 5
-#define MDIO_CLK_25_20                 6
-#define MDIO_CLK_25_28                 7
-#define MDIO_BUSY                      0x8000000
-
-/* MII PHY Status Register */
-#define REG_PHY_STATUS                 0x1418
-
-/* BIST Control and Status Register0 (for the Packet Memory) */
-#define REG_BIST0_CTRL                 0x141C
-#define BIST0_NOW                      0x1
-#define BIST0_SRAM_FAIL                        0x2
-#define BIST0_FUSE_FLAG                        0x4
-#define REG_BIST1_CTRL                 0x1420
-#define BIST1_NOW                      0x1
-#define BIST1_SRAM_FAIL                        0x2
-#define BIST1_FUSE_FLAG                        0x4
-
-/* SerDes Lock Detect Control and Status Register */
-#define REG_SERDES_LOCK                        0x1424
-#define SERDES_LOCK_DETECT             1
-#define SERDES_LOCK_DETECT_EN          2
-
-/* MAC Control Register */
-#define REG_MAC_CTRL                   0x1480
-#define MAC_CTRL_TX_EN                 1
-#define MAC_CTRL_RX_EN                 2
-#define MAC_CTRL_TX_FLOW               4
-#define MAC_CTRL_RX_FLOW               8
-#define MAC_CTRL_LOOPBACK              0x10
-#define MAC_CTRL_DUPLX                 0x20
-#define MAC_CTRL_ADD_CRC               0x40
-#define MAC_CTRL_PAD                   0x80
-#define MAC_CTRL_LENCHK                        0x100
-#define MAC_CTRL_HUGE_EN               0x200
-#define MAC_CTRL_PRMLEN_SHIFT          10
-#define MAC_CTRL_PRMLEN_MASK           0xF
-#define MAC_CTRL_RMV_VLAN              0x4000
-#define MAC_CTRL_PROMIS_EN             0x8000
-#define MAC_CTRL_MC_ALL_EN             0x2000000
-#define MAC_CTRL_BC_EN                 0x4000000
-
-/* MAC IPG/IFG Control Register */
-#define REG_MAC_IPG_IFG                        0x1484
-#define MAC_IPG_IFG_IPGT_SHIFT         0
-#define MAC_IPG_IFG_IPGT_MASK          0x7F
-#define MAC_IPG_IFG_MIFG_SHIFT         8
-#define MAC_IPG_IFG_MIFG_MASK          0xFF
-#define MAC_IPG_IFG_IPGR1_SHIFT                16
-#define MAC_IPG_IFG_IPGR1_MASK         0x7F
-#define MAC_IPG_IFG_IPGR2_SHIFT                24
-#define MAC_IPG_IFG_IPGR2_MASK         0x7F
-
-/* MAC STATION ADDRESS */
-#define REG_MAC_STA_ADDR               0x1488
-
-/* Hash table for multicast address */
-#define REG_RX_HASH_TABLE              0x1490
-
-/* MAC Half-Duplex Control Register */
-#define REG_MAC_HALF_DUPLX_CTRL                        0x1498
-#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT         0
-#define MAC_HALF_DUPLX_CTRL_LCOL_MASK          0x3FF
-#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT                12
-#define MAC_HALF_DUPLX_CTRL_RETRY_MASK         0xF
-#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN         0x10000
-#define MAC_HALF_DUPLX_CTRL_NO_BACK_C          0x20000
-#define MAC_HALF_DUPLX_CTRL_NO_BACK_P          0x40000
-#define MAC_HALF_DUPLX_CTRL_ABEBE              0x80000
-#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT                20
-#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK         0xF
-#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT       24
-#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK                0xF
-
-/* Maximum Frame Length Control Register */
-#define REG_MTU                                0x149C
-
-/* Wake-On-Lan control register */
-#define REG_WOL_CTRL                   0x14A0
-#define WOL_PATTERN_EN                 0x1
-#define WOL_PATTERN_PME_EN             0x2
-#define WOL_MAGIC_EN                   0x4
-#define WOL_MAGIC_PME_EN               0x8
-#define WOL_LINK_CHG_EN                        0x10
-#define WOL_LINK_CHG_PME_EN            0x20
-#define WOL_PATTERN_ST                 0x100
-#define WOL_MAGIC_ST                   0x200
-#define WOL_LINKCHG_ST                 0x400
-#define WOL_PT0_EN                     0x10000
-#define WOL_PT1_EN                     0x20000
-#define WOL_PT2_EN                     0x40000
-#define WOL_PT3_EN                     0x80000
-#define WOL_PT4_EN                     0x100000
-#define WOL_PT0_MATCH                  0x1000000
-#define WOL_PT1_MATCH                  0x2000000
-#define WOL_PT2_MATCH                  0x4000000
-#define WOL_PT3_MATCH                  0x8000000
-#define WOL_PT4_MATCH                  0x10000000
-
-/* Internal SRAM Partition Register, high 32 bits */
-#define REG_SRAM_RFD_ADDR              0x1500
-
-/* Descriptor Control register, high 32 bits */
-#define REG_DESC_BASE_ADDR_HI          0x1540
-
-/* Interrupt Status Register */
-#define REG_ISR                                0x1600
-#define ISR_UR_DETECTED                        0x1000000
-#define ISR_FERR_DETECTED              0x2000000
-#define ISR_NFERR_DETECTED             0x4000000
-#define ISR_CERR_DETECTED              0x8000000
-#define ISR_PHY_LINKDOWN               0x10000000
-#define ISR_DIS_INT                    0x80000000
-
-/* Interrupt Mask Register */
-#define REG_IMR                                0x1604
-
-#define REG_RFD_RRD_IDX                        0x1800
-#define REG_TPD_IDX                    0x1804
-
-/* MII definitions */
-
-/* PHY Common Register */
-#define MII_ATLX_CR                    0x09
-#define MII_ATLX_SR                    0x0A
-#define MII_ATLX_ESR                   0x0F
-#define MII_ATLX_PSCR                  0x10
-#define MII_ATLX_PSSR                  0x11
-
-/* 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_MASK              0x2040
-#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  /* Ext 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 stat 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 */
-
-/* Link partner ability register */
-#define MII_LPA_SLCT                   0x001f  /* Same as advertise selector */
-#define MII_LPA_10HALF                 0x0020  /* Can do 10mbps half-duplex */
-#define MII_LPA_10FULL                 0x0040  /* Can do 10mbps full-duplex */
-#define MII_LPA_100HALF                        0x0080  /* Can do 100mbps half-duplex */
-#define MII_LPA_100FULL                        0x0100  /* Can do 100mbps full-duplex */
-#define MII_LPA_100BASE4               0x0200  /* 100BASE-T4 */
-#define MII_LPA_PAUSE                  0x0400  /* PAUSE */
-#define MII_LPA_ASYPAUSE               0x0800  /* Asymmetrical PAUSE */
-#define MII_LPA_RFAULT                 0x2000  /* Link partner faulted */
-#define MII_LPA_LPACK                  0x4000  /* Link partner acked us */
-#define MII_LPA_NPAGE                  0x8000  /* Next page bit */
-
-/* Autoneg Advertisement Register */
-#define MII_AR_SELECTOR_FIELD          0x0001  /* IEEE 802.3 CSMA/CD */
-#define MII_AR_10T_HD_CAPS             0x0020  /* 10T   Half Duplex Capable */
-#define MII_AR_10T_FD_CAPS             0x0040  /* 10T   Full Duplex Capable */
-#define MII_AR_100TX_HD_CAPS           0x0080  /* 100TX Half Duplex Capable */
-#define MII_AR_100TX_FD_CAPS           0x0100  /* 100TX Full Duplex Capable */
-#define MII_AR_100T4_CAPS              0x0200  /* 100T4 Capable */
-#define MII_AR_PAUSE                   0x0400  /* Pause operation desired */
-#define MII_AR_ASM_DIR                 0x0800  /* Asymmetric Pause Dir bit */
-#define MII_AR_REMOTE_FAULT            0x2000  /* Remote Fault detected */
-#define MII_AR_NEXT_PAGE               0x8000  /* Next Page ability support */
-#define MII_AR_SPEED_MASK              0x01E0
-#define MII_AR_DEFAULT_CAP_MASK                0x0DE0
-
-/* 1000BASE-T Control Register */
-#define MII_ATLX_CR_1000T_HD_CAPS      0x0100  /* Adv 1000T HD cap */
-#define MII_ATLX_CR_1000T_FD_CAPS      0x0200  /* Adv 1000T FD cap */
-#define MII_ATLX_CR_1000T_REPEATER_DTE 0x0400  /* 1=Repeater/switch device,
-                                                * 0=DTE device */
-#define MII_ATLX_CR_1000T_MS_VALUE     0x0800  /* 1=Config PHY as Master,
-                                                * 0=Configure PHY as Slave */
-#define MII_ATLX_CR_1000T_MS_ENABLE    0x1000  /* 1=Man Master/Slave config,
-                                                * 0=Auto Master/Slave config
-                                                */
-#define MII_ATLX_CR_1000T_TEST_MODE_NORMAL     0x0000  /* Normal Operation */
-#define MII_ATLX_CR_1000T_TEST_MODE_1  0x2000  /* Transmit Waveform test */
-#define MII_ATLX_CR_1000T_TEST_MODE_2  0x4000  /* Master Xmit Jitter test */
-#define MII_ATLX_CR_1000T_TEST_MODE_3  0x6000  /* Slave Xmit Jitter test */
-#define MII_ATLX_CR_1000T_TEST_MODE_4  0x8000  /* Xmitter Distortion test */
-#define MII_ATLX_CR_1000T_SPEED_MASK   0x0300
-#define MII_ATLX_CR_1000T_DEFAULT_CAP_MASK     0x0300
-
-/* 1000BASE-T Status Register */
-#define MII_ATLX_SR_1000T_LP_HD_CAPS   0x0400  /* LP is 1000T HD capable */
-#define MII_ATLX_SR_1000T_LP_FD_CAPS   0x0800  /* LP is 1000T FD capable */
-#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS     0x1000  /* Remote receiver OK */
-#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS      0x2000  /* Local receiver OK */
-#define MII_ATLX_SR_1000T_MS_CONFIG_RES                0x4000  /* 1=Local TX is Master
-                                                        * 0=Slave
-                                                        */
-#define MII_ATLX_SR_1000T_MS_CONFIG_FAULT      0x8000  /* Master/Slave config
-                                                        * fault */
-#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS_SHIFT       12
-#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS_SHIFT                13
-
-/* Extended Status Register */
-#define MII_ATLX_ESR_1000T_HD_CAPS     0x1000  /* 1000T HD capable */
-#define MII_ATLX_ESR_1000T_FD_CAPS     0x2000  /* 1000T FD capable */
-#define MII_ATLX_ESR_1000X_HD_CAPS     0x4000  /* 1000X HD capable */
-#define MII_ATLX_ESR_1000X_FD_CAPS     0x8000  /* 1000X FD capable */
-
-/* ATLX PHY Specific Control Register */
-#define MII_ATLX_PSCR_JABBER_DISABLE   0x0001  /* 1=Jabber Func disabled */
-#define MII_ATLX_PSCR_POLARITY_REVERSAL        0x0002  /* 1=Polarity Reversal enbld */
-#define MII_ATLX_PSCR_SQE_TEST         0x0004  /* 1=SQE Test enabled */
-#define MII_ATLX_PSCR_MAC_POWERDOWN    0x0008
-#define MII_ATLX_PSCR_CLK125_DISABLE   0x0010  /* 1=CLK125 low
-                                                * 0=CLK125 toggling
-                                                */
-#define MII_ATLX_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5,
-                                                * Manual MDI configuration
-                                                */
-#define MII_ATLX_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
-#define MII_ATLX_PSCR_AUTO_X_1000T     0x0040  /* 1000BASE-T: Auto crossover
-                                                * 100BASE-TX/10BASE-T: MDI
-                                                * Mode */
-#define MII_ATLX_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled
-                                                * all speeds.
-                                                */
-#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE     0x0080  /* 1=Enable Extended
-                                                        * 10BASE-T distance
-                                                        * (Lower 10BASE-T RX
-                                                        * Threshold)
-                                                        * 0=Normal 10BASE-T RX
-                                                        * Threshold
-                                                        */
-#define MII_ATLX_PSCR_MII_5BIT_ENABLE  0x0100  /* 1=5-Bit interface in
-                                                * 100BASE-TX
-                                                * 0=MII interface in
-                                                * 100BASE-TX
-                                                */
-#define MII_ATLX_PSCR_SCRAMBLER_DISABLE        0x0200  /* 1=Scrambler dsbl */
-#define MII_ATLX_PSCR_FORCE_LINK_GOOD  0x0400  /* 1=Force link good */
-#define MII_ATLX_PSCR_ASSERT_CRS_ON_TX 0x0800  /* 1=Assert CRS on Transmit */
-#define MII_ATLX_PSCR_POLARITY_REVERSAL_SHIFT          1
-#define MII_ATLX_PSCR_AUTO_X_MODE_SHIFT                        5
-#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE_SHIFT       7
-
-/* ATLX PHY Specific Status Register */
-#define MII_ATLX_PSSR_SPD_DPLX_RESOLVED        0x0800  /* 1=Speed & Duplex resolved */
-#define MII_ATLX_PSSR_DPLX             0x2000  /* 1=Duplex 0=Half Duplex */
-#define MII_ATLX_PSSR_SPEED            0xC000  /* Speed, bits 14:15 */
-#define MII_ATLX_PSSR_10MBS            0x0000  /* 00=10Mbs */
-#define MII_ATLX_PSSR_100MBS           0x4000  /* 01=100Mbs */
-#define MII_ATLX_PSSR_1000MBS          0x8000  /* 10=1000Mbs */
-
-#define MII_DBG_ADDR                   0x1D
-#define MII_DBG_DATA                   0x1E
-
-/* PCI Command Register Bit Definitions */
-#define PCI_REG_COMMAND                        0x04    /* PCI Command Register */
-#define CMD_IO_SPACE                   0x0001
-#define CMD_MEMORY_SPACE               0x0002
-#define CMD_BUS_MASTER                 0x0004
-
-/* Wake Up Filter Control */
-#define ATLX_WUFC_LNKC 0x00000001      /* Link Status Change Wakeup Enable */
-#define ATLX_WUFC_MAG  0x00000002      /* Magic Packet Wakeup Enable */
-#define ATLX_WUFC_EX   0x00000004      /* Directed Exact Wakeup Enable */
-#define ATLX_WUFC_MC   0x00000008      /* Multicast Wakeup Enable */
-#define ATLX_WUFC_BC   0x00000010      /* Broadcast Wakeup Enable */
-
-#define ADVERTISE_10_HALF              0x0001
-#define ADVERTISE_10_FULL              0x0002
-#define ADVERTISE_100_HALF             0x0004
-#define ADVERTISE_100_FULL             0x0008
-#define ADVERTISE_1000_HALF            0x0010
-#define ADVERTISE_1000_FULL            0x0020
-#define AUTONEG_ADVERTISE_10_100_ALL   0x000F  /* All 10/100 speeds */
-#define AUTONEG_ADVERTISE_10_ALL       0x0003  /* 10Mbps Full & Half speeds */
-
-#define PHY_AUTO_NEG_TIME              45      /* 4.5 Seconds */
-#define PHY_FORCE_TIME                 20      /* 2.0 Seconds */
-
-/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA */
-#define EEPROM_SUM                     0xBABA
-#define NODE_ADDRESS_SIZE              6
-
-struct atlx_spi_flash_dev {
-       const char *manu_name;  /* manufacturer id */
-       /* op-code */
-       u8 cmd_wrsr;
-       u8 cmd_read;
-       u8 cmd_program;
-       u8 cmd_wren;
-       u8 cmd_wrdi;
-       u8 cmd_rdsr;
-       u8 cmd_rdid;
-       u8 cmd_sector_erase;
-       u8 cmd_chip_erase;
-};
-
-#endif /* ATLX_H */
index 8007e20972e48cfb500b7434bb6cc295e06ccc50..9410f20241f6d817c5fc62cbceeb86e256b1acb7 100644 (file)
@@ -14,6 +14,7 @@ if ETHERNET
 source "drivers/net/ethernet/3com/Kconfig"
 source "drivers/net/ethernet/amd/Kconfig"
 source "drivers/net/ethernet/apple/Kconfig"
+source "drivers/net/ethernet/atheros/Kconfig"
 source "drivers/net/ethernet/broadcom/Kconfig"
 source "drivers/net/ethernet/brocade/Kconfig"
 source "drivers/net/ethernet/chelsio/Kconfig"
index 22ef3808f439cbb80c27a6a7016a7dc3ad0f9c87..5d89fd9d672b5a15eae76356afa173ad167cbc66 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_NET_VENDOR_3COM) += 3com/
 obj-$(CONFIG_NET_VENDOR_8390) += 8390/
 obj-$(CONFIG_NET_VENDOR_AMD) += amd/
 obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
+obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
 obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
 obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/
 obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
diff --git a/drivers/net/ethernet/atheros/Kconfig b/drivers/net/ethernet/atheros/Kconfig
new file mode 100644 (file)
index 0000000..966c6c7
--- /dev/null
@@ -0,0 +1,65 @@
+#
+# Atheros device configuration
+#
+
+config NET_VENDOR_ATHEROS
+       bool "Atheros devices"
+       depends on PCI
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about Atheros devices. If you say Y, you will be asked
+         for your specific card in the following questions.
+
+if NET_VENDOR_ATHEROS
+
+config ATL2
+       tristate "Atheros L2 Fast Ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros L2 fast ethernet adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl2.
+
+config ATL1
+       tristate "Atheros/Attansic L1 Gigabit Ethernet support"
+       depends on PCI
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros/Attansic L1 gigabit ethernet
+         adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl1.
+
+config ATL1E
+       tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros L1E gigabit ethernet adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl1e.
+
+config ATL1C
+       tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       select MII
+       ---help---
+         This driver supports the Atheros L1C gigabit ethernet adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl1c.
+
+endif # NET_VENDOR_ATHEROS
diff --git a/drivers/net/ethernet/atheros/Makefile b/drivers/net/ethernet/atheros/Makefile
new file mode 100644 (file)
index 0000000..e7e76fb
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the Atheros network device drivers.
+#
+
+obj-$(CONFIG_ATL1) += atlx/
+obj-$(CONFIG_ATL2) += atlx/
+obj-$(CONFIG_ATL1E) += atl1e/
+obj-$(CONFIG_ATL1C) += atl1c/
diff --git a/drivers/net/ethernet/atheros/atl1c/Makefile b/drivers/net/ethernet/atheros/atl1c/Makefile
new file mode 100644 (file)
index 0000000..c37d966
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ATL1C) += atl1c.o
+atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h
new file mode 100644 (file)
index 0000000..ca70e16
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#ifndef _ATL1C_H_
+#define _ATL1C_H_
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/mii.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/tcp.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/workqueue.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include "atl1c_hw.h"
+
+/* Wake Up Filter Control */
+#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define AT_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
+#define AT_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
+#define AT_WUFC_MC   0x00000008 /* Multicast Wakeup Enable */
+#define AT_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
+
+#define AT_VLAN_TO_TAG(_vlan, _tag)       \
+       _tag =  ((((_vlan) >> 8) & 0xFF)  |\
+                (((_vlan) & 0xFF) << 8))
+
+#define AT_TAG_TO_VLAN(_tag, _vlan)     \
+       _vlan = ((((_tag) >> 8) & 0xFF) |\
+               (((_tag) & 0xFF) << 8))
+
+#define SPEED_0                   0xffff
+#define HALF_DUPLEX        1
+#define FULL_DUPLEX        2
+
+#define AT_RX_BUF_SIZE         (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)
+#define MAX_JUMBO_FRAME_SIZE   (6*1024)
+#define MAX_TSO_FRAME_SIZE      (7*1024)
+#define MAX_TX_OFFLOAD_THRESH  (9*1024)
+
+#define AT_MAX_RECEIVE_QUEUE    4
+#define AT_DEF_RECEIVE_QUEUE   1
+#define AT_MAX_TRANSMIT_QUEUE  2
+
+#define AT_DMA_HI_ADDR_MASK     0xffffffff00000000ULL
+#define AT_DMA_LO_ADDR_MASK     0x00000000ffffffffULL
+
+#define AT_TX_WATCHDOG  (5 * HZ)
+#define AT_MAX_INT_WORK                5
+#define AT_TWSI_EEPROM_TIMEOUT         100
+#define AT_HW_MAX_IDLE_DELAY   10
+#define AT_SUSPEND_LINK_TIMEOUT 100
+
+#define AT_ASPM_L0S_TIMER      6
+#define AT_ASPM_L1_TIMER       12
+#define AT_LCKDET_TIMER                12
+
+#define ATL1C_PCIE_L0S_L1_DISABLE      0x01
+#define ATL1C_PCIE_PHY_RESET           0x02
+
+#define ATL1C_ASPM_L0s_ENABLE          0x0001
+#define ATL1C_ASPM_L1_ENABLE           0x0002
+
+#define AT_REGS_LEN    (75 * sizeof(u32))
+#define AT_EEPROM_LEN  512
+
+#define ATL1C_GET_DESC(R, i, type)     (&(((type *)((R)->desc))[i]))
+#define ATL1C_RFD_DESC(R, i)   ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc)
+#define ATL1C_TPD_DESC(R, i)   ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc)
+#define ATL1C_RRD_DESC(R, i)   ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status)
+
+/* tpd word 1 bit 0:7 General Checksum task offload */
+#define TPD_L4HDR_OFFSET_MASK  0x00FF
+#define TPD_L4HDR_OFFSET_SHIFT 0
+
+/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */
+#define TPD_TCPHDR_OFFSET_MASK 0x00FF
+#define TPD_TCPHDR_OFFSET_SHIFT        0
+
+/* tpd word 1 bit 0:7 Custom Checksum task offload */
+#define TPD_PLOADOFFSET_MASK   0x00FF
+#define TPD_PLOADOFFSET_SHIFT  0
+
+/* tpd word 1 bit 8:17 */
+#define TPD_CCSUM_EN_MASK      0x0001
+#define TPD_CCSUM_EN_SHIFT     8
+#define TPD_IP_CSUM_MASK       0x0001
+#define TPD_IP_CSUM_SHIFT      9
+#define TPD_TCP_CSUM_MASK      0x0001
+#define TPD_TCP_CSUM_SHIFT     10
+#define TPD_UDP_CSUM_MASK      0x0001
+#define TPD_UDP_CSUM_SHIFT     11
+#define TPD_LSO_EN_MASK                0x0001  /* TCP Large Send Offload */
+#define TPD_LSO_EN_SHIFT       12
+#define TPD_LSO_VER_MASK       0x0001
+#define TPD_LSO_VER_SHIFT      13      /* 0 : ipv4; 1 : ipv4/ipv6 */
+#define TPD_CON_VTAG_MASK      0x0001
+#define TPD_CON_VTAG_SHIFT     14
+#define TPD_INS_VTAG_MASK      0x0001
+#define TPD_INS_VTAG_SHIFT     15
+#define TPD_IPV4_PACKET_MASK   0x0001  /* valid when LSO VER  is 1 */
+#define TPD_IPV4_PACKET_SHIFT  16
+#define TPD_ETH_TYPE_MASK      0x0001
+#define TPD_ETH_TYPE_SHIFT     17      /* 0 : 802.3 frame; 1 : Ethernet */
+
+/* tpd word 18:25 Custom Checksum task offload */
+#define TPD_CCSUM_OFFSET_MASK  0x00FF
+#define TPD_CCSUM_OFFSET_SHIFT 18
+#define TPD_CCSUM_EPAD_MASK    0x0001
+#define TPD_CCSUM_EPAD_SHIFT   30
+
+/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */
+#define TPD_MSS_MASK            0x1FFF
+#define TPD_MSS_SHIFT          18
+
+#define TPD_EOP_MASK           0x0001
+#define TPD_EOP_SHIFT          31
+
+struct atl1c_tpd_desc {
+       __le16  buffer_len; /* include 4-byte CRC */
+       __le16  vlan_tag;
+       __le32  word1;
+       __le64  buffer_addr;
+};
+
+struct atl1c_tpd_ext_desc {
+       u32 reservd_0;
+       __le32 word1;
+       __le32 pkt_len;
+       u32 reservd_1;
+};
+/* rrs word 0 bit 0:31 */
+#define RRS_RX_CSUM_MASK       0xFFFF
+#define RRS_RX_CSUM_SHIFT      0
+#define RRS_RX_RFD_CNT_MASK    0x000F
+#define RRS_RX_RFD_CNT_SHIFT   16
+#define RRS_RX_RFD_INDEX_MASK  0x0FFF
+#define RRS_RX_RFD_INDEX_SHIFT 20
+
+/* rrs flag bit 0:16 */
+#define RRS_HEAD_LEN_MASK      0x00FF
+#define RRS_HEAD_LEN_SHIFT     0
+#define RRS_HDS_TYPE_MASK      0x0003
+#define RRS_HDS_TYPE_SHIFT     8
+#define RRS_CPU_NUM_MASK       0x0003
+#define        RRS_CPU_NUM_SHIFT       10
+#define RRS_HASH_FLG_MASK      0x000F
+#define RRS_HASH_FLG_SHIFT     12
+
+#define RRS_HDS_TYPE_HEAD      1
+#define RRS_HDS_TYPE_DATA      2
+
+#define RRS_IS_NO_HDS_TYPE(flag) \
+       ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0)
+
+#define RRS_IS_HDS_HEAD(flag) \
+       ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
+                       RRS_HDS_TYPE_HEAD)
+
+#define RRS_IS_HDS_DATA(flag) \
+       ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
+                       RRS_HDS_TYPE_DATA)
+
+/* rrs word 3 bit 0:31 */
+#define RRS_PKT_SIZE_MASK      0x3FFF
+#define RRS_PKT_SIZE_SHIFT     0
+#define RRS_ERR_L4_CSUM_MASK   0x0001
+#define RRS_ERR_L4_CSUM_SHIFT  14
+#define RRS_ERR_IP_CSUM_MASK   0x0001
+#define RRS_ERR_IP_CSUM_SHIFT  15
+#define RRS_VLAN_INS_MASK      0x0001
+#define RRS_VLAN_INS_SHIFT     16
+#define RRS_PROT_ID_MASK       0x0007
+#define RRS_PROT_ID_SHIFT      17
+#define RRS_RX_ERR_SUM_MASK    0x0001
+#define RRS_RX_ERR_SUM_SHIFT   20
+#define RRS_RX_ERR_CRC_MASK    0x0001
+#define RRS_RX_ERR_CRC_SHIFT   21
+#define RRS_RX_ERR_FAE_MASK    0x0001
+#define RRS_RX_ERR_FAE_SHIFT   22
+#define RRS_RX_ERR_TRUNC_MASK  0x0001
+#define RRS_RX_ERR_TRUNC_SHIFT 23
+#define RRS_RX_ERR_RUNC_MASK   0x0001
+#define RRS_RX_ERR_RUNC_SHIFT  24
+#define RRS_RX_ERR_ICMP_MASK   0x0001
+#define RRS_RX_ERR_ICMP_SHIFT  25
+#define RRS_PACKET_BCAST_MASK  0x0001
+#define RRS_PACKET_BCAST_SHIFT 26
+#define RRS_PACKET_MCAST_MASK  0x0001
+#define RRS_PACKET_MCAST_SHIFT 27
+#define RRS_PACKET_TYPE_MASK   0x0001
+#define RRS_PACKET_TYPE_SHIFT  28
+#define RRS_FIFO_FULL_MASK     0x0001
+#define RRS_FIFO_FULL_SHIFT    29
+#define RRS_802_3_LEN_ERR_MASK         0x0001
+#define RRS_802_3_LEN_ERR_SHIFT 30
+#define RRS_RXD_UPDATED_MASK   0x0001
+#define RRS_RXD_UPDATED_SHIFT  31
+
+#define RRS_ERR_L4_CSUM         0x00004000
+#define RRS_ERR_IP_CSUM         0x00008000
+#define RRS_VLAN_INS            0x00010000
+#define RRS_RX_ERR_SUM          0x00100000
+#define RRS_RX_ERR_CRC          0x00200000
+#define RRS_802_3_LEN_ERR      0x40000000
+#define RRS_RXD_UPDATED                0x80000000
+
+#define RRS_PACKET_TYPE_802_3          1
+#define RRS_PACKET_TYPE_ETH    0
+#define RRS_PACKET_IS_ETH(word) \
+       ((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \
+                       RRS_PACKET_TYPE_ETH)
+#define RRS_RXD_IS_VALID(word) \
+       ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
+
+#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \
+       ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1)
+#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \
+       ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6)
+
+struct atl1c_recv_ret_status {
+       __le32  word0;
+       __le32  rss_hash;
+       __le16  vlan_tag;
+       __le16  flag;
+       __le32  word3;
+};
+
+/* RFD descriptor */
+struct atl1c_rx_free_desc {
+       __le64  buffer_addr;
+};
+
+/* DMA Order Settings */
+enum atl1c_dma_order {
+       atl1c_dma_ord_in = 1,
+       atl1c_dma_ord_enh = 2,
+       atl1c_dma_ord_out = 4
+};
+
+enum atl1c_dma_rcb {
+       atl1c_rcb_64 = 0,
+       atl1c_rcb_128 = 1
+};
+
+enum atl1c_mac_speed {
+       atl1c_mac_speed_0 = 0,
+       atl1c_mac_speed_10_100 = 1,
+       atl1c_mac_speed_1000 = 2
+};
+
+enum atl1c_dma_req_block {
+       atl1c_dma_req_128 = 0,
+       atl1c_dma_req_256 = 1,
+       atl1c_dma_req_512 = 2,
+       atl1c_dma_req_1024 = 3,
+       atl1c_dma_req_2048 = 4,
+       atl1c_dma_req_4096 = 5
+};
+
+enum atl1c_rss_mode {
+       atl1c_rss_mode_disable = 0,
+       atl1c_rss_sig_que = 1,
+       atl1c_rss_mul_que_sig_int = 2,
+       atl1c_rss_mul_que_mul_int = 4,
+};
+
+enum atl1c_rss_type {
+       atl1c_rss_disable = 0,
+       atl1c_rss_ipv4 = 1,
+       atl1c_rss_ipv4_tcp = 2,
+       atl1c_rss_ipv6 = 4,
+       atl1c_rss_ipv6_tcp = 8
+};
+
+enum atl1c_nic_type {
+       athr_l1c = 0,
+       athr_l2c = 1,
+       athr_l2c_b,
+       athr_l2c_b2,
+       athr_l1d,
+       athr_l1d_2,
+};
+
+enum atl1c_trans_queue {
+       atl1c_trans_normal = 0,
+       atl1c_trans_high = 1
+};
+
+struct atl1c_hw_stats {
+       /* rx */
+       unsigned long rx_ok;            /* The number of good packet received. */
+       unsigned long rx_bcast;         /* The number of good broadcast packet received. */
+       unsigned long rx_mcast;         /* The number of good multicast packet received. */
+       unsigned long rx_pause;         /* The number of Pause packet received. */
+       unsigned long rx_ctrl;          /* The number of Control packet received other than Pause frame. */
+       unsigned long rx_fcs_err;       /* The number of packets with bad FCS. */
+       unsigned long rx_len_err;       /* The number of packets with mismatch of length field and actual size. */
+       unsigned long rx_byte_cnt;      /* The number of bytes of good packet received. FCS is NOT included. */
+       unsigned long rx_runt;          /* The number of packets received that are less than 64 byte long and with good FCS. */
+       unsigned long rx_frag;          /* The number of packets received that are less than 64 byte long and with bad FCS. */
+       unsigned long rx_sz_64;         /* The number of good and bad packets received that are 64 byte long. */
+       unsigned long rx_sz_65_127;     /* The number of good and bad packets received that are between 65 and 127-byte long. */
+       unsigned long rx_sz_128_255;    /* The number of good and bad packets received that are between 128 and 255-byte long. */
+       unsigned long rx_sz_256_511;    /* The number of good and bad packets received that are between 256 and 511-byte long. */
+       unsigned long rx_sz_512_1023;   /* The number of good and bad packets received that are between 512 and 1023-byte long. */
+       unsigned long rx_sz_1024_1518;  /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
+       unsigned long rx_sz_1519_max;   /* The number of good and bad packets received that are between 1519-byte and MTU. */
+       unsigned long rx_sz_ov;         /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
+       unsigned long rx_rxf_ov;        /* The number of frame dropped due to occurrence of RX FIFO overflow. */
+       unsigned long rx_rrd_ov;        /* The number of frame dropped due to occurrence of RRD overflow. */
+       unsigned long rx_align_err;     /* Alignment Error */
+       unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
+       unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
+       unsigned long rx_err_addr;      /* The number of packets dropped due to address filtering. */
+
+       /* tx */
+       unsigned long tx_ok;            /* The number of good packet transmitted. */
+       unsigned long tx_bcast;         /* The number of good broadcast packet transmitted. */
+       unsigned long tx_mcast;         /* The number of good multicast packet transmitted. */
+       unsigned long tx_pause;         /* The number of Pause packet transmitted. */
+       unsigned long tx_exc_defer;     /* The number of packets transmitted with excessive deferral. */
+       unsigned long tx_ctrl;          /* The number of packets transmitted is a control frame, excluding Pause frame. */
+       unsigned long tx_defer;         /* The number of packets transmitted that is deferred. */
+       unsigned long tx_byte_cnt;      /* The number of bytes of data transmitted. FCS is NOT included. */
+       unsigned long tx_sz_64;         /* The number of good and bad packets transmitted that are 64 byte long. */
+       unsigned long tx_sz_65_127;     /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
+       unsigned long tx_sz_128_255;    /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
+       unsigned long tx_sz_256_511;    /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
+       unsigned long tx_sz_512_1023;   /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
+       unsigned long tx_sz_1024_1518;  /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
+       unsigned long tx_sz_1519_max;   /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
+       unsigned long tx_1_col;         /* The number of packets subsequently transmitted successfully with a single prior collision. */
+       unsigned long tx_2_col;         /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
+       unsigned long tx_late_col;      /* The number of packets transmitted with late collisions. */
+       unsigned long tx_abort_col;     /* The number of transmit packets aborted due to excessive collisions. */
+       unsigned long tx_underrun;      /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
+       unsigned long tx_rd_eop;        /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
+       unsigned long tx_len_err;       /* The number of transmit packets with length field does NOT match the actual frame size. */
+       unsigned long tx_trunc;         /* The number of transmit packets truncated due to size exceeding MTU. */
+       unsigned long tx_bcast_byte;    /* The byte count of broadcast packet transmitted, excluding FCS. */
+       unsigned long tx_mcast_byte;    /* The byte count of multicast packet transmitted, excluding FCS. */
+};
+
+struct atl1c_hw {
+       u8 __iomem      *hw_addr;            /* inner register address */
+       struct atl1c_adapter *adapter;
+       enum atl1c_nic_type  nic_type;
+       enum atl1c_dma_order dma_order;
+       enum atl1c_dma_rcb   rcb_value;
+       enum atl1c_dma_req_block dmar_block;
+       enum atl1c_dma_req_block dmaw_block;
+
+       u16 device_id;
+       u16 vendor_id;
+       u16 subsystem_id;
+       u16 subsystem_vendor_id;
+       u8 revision_id;
+       u16 phy_id1;
+       u16 phy_id2;
+
+       u32 intr_mask;
+       u8 dmaw_dly_cnt;
+       u8 dmar_dly_cnt;
+
+       u8 preamble_len;
+       u16 max_frame_size;
+       u16 min_frame_size;
+
+       enum atl1c_mac_speed mac_speed;
+       bool mac_duplex;
+       bool hibernate;
+       u16 media_type;
+#define MEDIA_TYPE_AUTO_SENSOR  0
+#define MEDIA_TYPE_100M_FULL    1
+#define MEDIA_TYPE_100M_HALF    2
+#define MEDIA_TYPE_10M_FULL     3
+#define MEDIA_TYPE_10M_HALF     4
+
+       u16 autoneg_advertised;
+       u16 mii_autoneg_adv_reg;
+       u16 mii_1000t_ctrl_reg;
+
+       u16 tx_imt;     /* TX Interrupt Moderator timer ( 2us resolution) */
+       u16 rx_imt;     /* RX Interrupt Moderator timer ( 2us resolution) */
+       u16 ict;        /* Interrupt Clear timer (2us resolution) */
+       u16 ctrl_flags;
+#define ATL1C_INTR_CLEAR_ON_READ       0x0001
+#define ATL1C_INTR_MODRT_ENABLE                0x0002
+#define ATL1C_CMB_ENABLE               0x0004
+#define ATL1C_SMB_ENABLE               0x0010
+#define ATL1C_TXQ_MODE_ENHANCE         0x0020
+#define ATL1C_RX_IPV6_CHKSUM           0x0040
+#define ATL1C_ASPM_L0S_SUPPORT         0x0080
+#define ATL1C_ASPM_L1_SUPPORT          0x0100
+#define ATL1C_ASPM_CTRL_MON            0x0200
+#define ATL1C_HIB_DISABLE              0x0400
+#define ATL1C_APS_MODE_ENABLE           0x0800
+#define ATL1C_LINK_EXT_SYNC             0x1000
+#define ATL1C_CLK_GATING_EN             0x2000
+#define ATL1C_FPGA_VERSION              0x8000
+       u16 link_cap_flags;
+#define ATL1C_LINK_CAP_1000M           0x0001
+       u16 cmb_tpd;
+       u16 cmb_rrd;
+       u16 cmb_rx_timer; /* 2us resolution */
+       u16 cmb_tx_timer;
+       u32 smb_timer;
+
+       u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
+                         interrupt request */
+       u16 tpd_thresh;
+       u8 tpd_burst;   /* Number of TPD to prefetch in cache-aligned burst. */
+       u8 rfd_burst;
+       enum atl1c_rss_type rss_type;
+       enum atl1c_rss_mode rss_mode;
+       u8 rss_hash_bits;
+       u32 base_cpu;
+       u32 indirect_tab;
+       u8 mac_addr[ETH_ALEN];
+       u8 perm_mac_addr[ETH_ALEN];
+
+       bool phy_configured;
+       bool re_autoneg;
+       bool emi_ca;
+};
+
+/*
+ * atl1c_ring_header represents a single, contiguous block of DMA space
+ * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
+ * message blocks (cmb, smb) described below
+ */
+struct atl1c_ring_header {
+       void *desc;             /* virtual address */
+       dma_addr_t dma;         /* physical address*/
+       unsigned int size;      /* length in bytes */
+};
+
+/*
+ * atl1c_buffer is wrapper around a pointer to a socket buffer
+ * so a DMA handle can be stored along with the skb
+ */
+struct atl1c_buffer {
+       struct sk_buff *skb;    /* socket buffer */
+       u16 length;             /* rx buffer length */
+       u16 flags;              /* information of buffer */
+#define ATL1C_BUFFER_FREE              0x0001
+#define ATL1C_BUFFER_BUSY              0x0002
+#define ATL1C_BUFFER_STATE_MASK                0x0003
+
+#define ATL1C_PCIMAP_SINGLE            0x0004
+#define ATL1C_PCIMAP_PAGE              0x0008
+#define ATL1C_PCIMAP_TYPE_MASK         0x000C
+
+#define ATL1C_PCIMAP_TODEVICE          0x0010
+#define ATL1C_PCIMAP_FROMDEVICE                0x0020
+#define ATL1C_PCIMAP_DIRECTION_MASK    0x0030
+       dma_addr_t dma;
+};
+
+#define ATL1C_SET_BUFFER_STATE(buff, state) do {       \
+       ((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK;    \
+       ((buff)->flags) |= (state);                     \
+       } while (0)
+
+#define ATL1C_SET_PCIMAP_TYPE(buff, type, direction) do {      \
+       ((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK;             \
+       ((buff)->flags) |= (type);                              \
+       ((buff)->flags) &= ~ATL1C_PCIMAP_DIRECTION_MASK;        \
+       ((buff)->flags) |= (direction);                         \
+       } while (0)
+
+/* transimit packet descriptor (tpd) ring */
+struct atl1c_tpd_ring {
+       void *desc;             /* descriptor ring virtual address */
+       dma_addr_t dma;         /* descriptor ring physical address */
+       u16 size;               /* descriptor ring length in bytes */
+       u16 count;              /* number of descriptors in the ring */
+       u16 next_to_use;        /* this is protectd by adapter->tx_lock */
+       atomic_t next_to_clean;
+       struct atl1c_buffer *buffer_info;
+};
+
+/* receive free descriptor (rfd) ring */
+struct atl1c_rfd_ring {
+       void *desc;             /* descriptor ring virtual address */
+       dma_addr_t dma;         /* descriptor ring physical address */
+       u16 size;               /* descriptor ring length in bytes */
+       u16 count;              /* number of descriptors in the ring */
+       u16 next_to_use;
+       u16 next_to_clean;
+       struct atl1c_buffer *buffer_info;
+};
+
+/* receive return descriptor (rrd) ring */
+struct atl1c_rrd_ring {
+       void *desc;             /* descriptor ring virtual address */
+       dma_addr_t dma;         /* descriptor ring physical address */
+       u16 size;               /* descriptor ring length in bytes */
+       u16 count;              /* number of descriptors in the ring */
+       u16 next_to_use;
+       u16 next_to_clean;
+};
+
+struct atl1c_cmb {
+       void *cmb;
+       dma_addr_t dma;
+};
+
+struct atl1c_smb {
+       void *smb;
+       dma_addr_t dma;
+};
+
+/* board specific private data structure */
+struct atl1c_adapter {
+       struct net_device   *netdev;
+       struct pci_dev      *pdev;
+       struct napi_struct  napi;
+       struct atl1c_hw        hw;
+       struct atl1c_hw_stats  hw_stats;
+       struct mii_if_info  mii;    /* MII interface info */
+       u16 rx_buffer_len;
+
+       unsigned long flags;
+#define __AT_TESTING        0x0001
+#define __AT_RESETTING      0x0002
+#define __AT_DOWN           0x0003
+       unsigned long work_event;
+#define        ATL1C_WORK_EVENT_RESET          0
+#define        ATL1C_WORK_EVENT_LINK_CHANGE    1
+       u32 msg_enable;
+
+       bool have_msi;
+       u32 wol;
+       u16 link_speed;
+       u16 link_duplex;
+
+       spinlock_t mdio_lock;
+       spinlock_t tx_lock;
+       atomic_t irq_sem;
+
+       struct work_struct common_task;
+       struct timer_list watchdog_timer;
+       struct timer_list phy_config_timer;
+
+       /* All Descriptor memory */
+       struct atl1c_ring_header ring_header;
+       struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE];
+       struct atl1c_rfd_ring rfd_ring[AT_MAX_RECEIVE_QUEUE];
+       struct atl1c_rrd_ring rrd_ring[AT_MAX_RECEIVE_QUEUE];
+       struct atl1c_cmb cmb;
+       struct atl1c_smb smb;
+       int num_rx_queues;
+       u32 bd_number;     /* board number;*/
+};
+
+#define AT_WRITE_REG(a, reg, value) ( \
+               writel((value), ((a)->hw_addr + reg)))
+
+#define AT_WRITE_FLUSH(a) (\
+               readl((a)->hw_addr))
+
+#define AT_READ_REG(a, reg, pdata) do {                                        \
+               if (unlikely((a)->hibernate)) {                         \
+                       readl((a)->hw_addr + reg);                      \
+                       *(u32 *)pdata = readl((a)->hw_addr + reg);      \
+               } else {                                                \
+                       *(u32 *)pdata = readl((a)->hw_addr + reg);      \
+               }                                                       \
+       } while (0)
+
+#define AT_WRITE_REGB(a, reg, value) (\
+               writeb((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGB(a, reg) (\
+               readb((a)->hw_addr + reg))
+
+#define AT_WRITE_REGW(a, reg, value) (\
+               writew((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGW(a, reg) (\
+               readw((a)->hw_addr + reg))
+
+#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+               writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
+
+#define AT_READ_REG_ARRAY(a, reg, offset) ( \
+               readl(((a)->hw_addr + reg) + ((offset) << 2)))
+
+extern char atl1c_driver_name[];
+extern char atl1c_driver_version[];
+
+extern void atl1c_reinit_locked(struct atl1c_adapter *adapter);
+extern s32 atl1c_reset_hw(struct atl1c_hw *hw);
+extern void atl1c_set_ethtool_ops(struct net_device *netdev);
+#endif /* _ATL1C_H_ */
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
new file mode 100644 (file)
index 0000000..7be884d
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/slab.h>
+
+#include "atl1c.h"
+
+static int atl1c_get_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct atl1c_hw *hw = &adapter->hw;
+
+       ecmd->supported = (SUPPORTED_10baseT_Half  |
+                          SUPPORTED_10baseT_Full  |
+                          SUPPORTED_100baseT_Half |
+                          SUPPORTED_100baseT_Full |
+                          SUPPORTED_Autoneg       |
+                          SUPPORTED_TP);
+       if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M)
+               ecmd->supported |= SUPPORTED_1000baseT_Full;
+
+       ecmd->advertising = ADVERTISED_TP;
+
+       ecmd->advertising |= hw->autoneg_advertised;
+
+       ecmd->port = PORT_TP;
+       ecmd->phy_address = 0;
+       ecmd->transceiver = XCVR_INTERNAL;
+
+       if (adapter->link_speed != SPEED_0) {
+               ethtool_cmd_speed_set(ecmd, adapter->link_speed);
+               if (adapter->link_duplex == FULL_DUPLEX)
+                       ecmd->duplex = DUPLEX_FULL;
+               else
+                       ecmd->duplex = DUPLEX_HALF;
+       } else {
+               ethtool_cmd_speed_set(ecmd, -1);
+               ecmd->duplex = -1;
+       }
+
+       ecmd->autoneg = AUTONEG_ENABLE;
+       return 0;
+}
+
+static int atl1c_set_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct atl1c_hw *hw = &adapter->hw;
+       u16  autoneg_advertised;
+
+       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+               msleep(1);
+
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               autoneg_advertised = ADVERTISED_Autoneg;
+       } else {
+               u32 speed = ethtool_cmd_speed(ecmd);
+               if (speed == SPEED_1000) {
+                       if (ecmd->duplex != DUPLEX_FULL) {
+                               if (netif_msg_link(adapter))
+                                       dev_warn(&adapter->pdev->dev,
+                                               "1000M half is invalid\n");
+                               clear_bit(__AT_RESETTING, &adapter->flags);
+                               return -EINVAL;
+                       }
+                       autoneg_advertised = ADVERTISED_1000baseT_Full;
+               } else if (speed == SPEED_100) {
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               autoneg_advertised = ADVERTISED_100baseT_Full;
+                       else
+                               autoneg_advertised = ADVERTISED_100baseT_Half;
+               } else {
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               autoneg_advertised = ADVERTISED_10baseT_Full;
+                       else
+                               autoneg_advertised = ADVERTISED_10baseT_Half;
+               }
+       }
+
+       if (hw->autoneg_advertised != autoneg_advertised) {
+               hw->autoneg_advertised = autoneg_advertised;
+               if (atl1c_restart_autoneg(hw) != 0) {
+                       if (netif_msg_link(adapter))
+                               dev_warn(&adapter->pdev->dev,
+                                       "ethtool speed/duplex setting failed\n");
+                       clear_bit(__AT_RESETTING, &adapter->flags);
+                       return -EINVAL;
+               }
+       }
+       clear_bit(__AT_RESETTING, &adapter->flags);
+       return 0;
+}
+
+static u32 atl1c_get_msglevel(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       return adapter->msg_enable;
+}
+
+static void atl1c_set_msglevel(struct net_device *netdev, u32 data)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       adapter->msg_enable = data;
+}
+
+static int atl1c_get_regs_len(struct net_device *netdev)
+{
+       return AT_REGS_LEN;
+}
+
+static void atl1c_get_regs(struct net_device *netdev,
+                          struct ethtool_regs *regs, void *p)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct atl1c_hw *hw = &adapter->hw;
+       u32 *regs_buff = p;
+       u16 phy_data;
+
+       memset(p, 0, AT_REGS_LEN);
+
+       regs->version = 0;
+       AT_READ_REG(hw, REG_VPD_CAP,              p++);
+       AT_READ_REG(hw, REG_PM_CTRL,              p++);
+       AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL,  p++);
+       AT_READ_REG(hw, REG_TWSI_CTRL,            p++);
+       AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL,   p++);
+       AT_READ_REG(hw, REG_MASTER_CTRL,          p++);
+       AT_READ_REG(hw, REG_MANUAL_TIMER_INIT,    p++);
+       AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++);
+       AT_READ_REG(hw, REG_GPHY_CTRL,            p++);
+       AT_READ_REG(hw, REG_LINK_CTRL,            p++);
+       AT_READ_REG(hw, REG_IDLE_STATUS,          p++);
+       AT_READ_REG(hw, REG_MDIO_CTRL,            p++);
+       AT_READ_REG(hw, REG_SERDES_LOCK,          p++);
+       AT_READ_REG(hw, REG_MAC_CTRL,             p++);
+       AT_READ_REG(hw, REG_MAC_IPG_IFG,          p++);
+       AT_READ_REG(hw, REG_MAC_STA_ADDR,         p++);
+       AT_READ_REG(hw, REG_MAC_STA_ADDR+4,       p++);
+       AT_READ_REG(hw, REG_RX_HASH_TABLE,        p++);
+       AT_READ_REG(hw, REG_RX_HASH_TABLE+4,      p++);
+       AT_READ_REG(hw, REG_RXQ_CTRL,             p++);
+       AT_READ_REG(hw, REG_TXQ_CTRL,             p++);
+       AT_READ_REG(hw, REG_MTU,                  p++);
+       AT_READ_REG(hw, REG_WOL_CTRL,             p++);
+
+       atl1c_read_phy_reg(hw, MII_BMCR, &phy_data);
+       regs_buff[73] = (u32) phy_data;
+       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+       regs_buff[74] = (u32) phy_data;
+}
+
+static int atl1c_get_eeprom_len(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       if (atl1c_check_eeprom_exist(&adapter->hw))
+               return AT_EEPROM_LEN;
+       else
+               return 0;
+}
+
+static int atl1c_get_eeprom(struct net_device *netdev,
+               struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct atl1c_hw *hw = &adapter->hw;
+       u32 *eeprom_buff;
+       int first_dword, last_dword;
+       int ret_val = 0;
+       int i;
+
+       if (eeprom->len == 0)
+               return -EINVAL;
+
+       if (!atl1c_check_eeprom_exist(hw)) /* not exist */
+               return -EINVAL;
+
+       eeprom->magic = adapter->pdev->vendor |
+                       (adapter->pdev->device << 16);
+
+       first_dword = eeprom->offset >> 2;
+       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+       eeprom_buff = kmalloc(sizeof(u32) *
+                       (last_dword - first_dword + 1), GFP_KERNEL);
+       if (eeprom_buff == NULL)
+               return -ENOMEM;
+
+       for (i = first_dword; i < last_dword; i++) {
+               if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
+                       kfree(eeprom_buff);
+                       return -EIO;
+               }
+       }
+
+       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+                       eeprom->len);
+       kfree(eeprom_buff);
+
+       return ret_val;
+       return 0;
+}
+
+static void atl1c_get_drvinfo(struct net_device *netdev,
+               struct ethtool_drvinfo *drvinfo)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       strlcpy(drvinfo->driver,  atl1c_driver_name, sizeof(drvinfo->driver));
+       strlcpy(drvinfo->version, atl1c_driver_version,
+               sizeof(drvinfo->version));
+       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
+               sizeof(drvinfo->bus_info));
+       drvinfo->n_stats = 0;
+       drvinfo->testinfo_len = 0;
+       drvinfo->regdump_len = atl1c_get_regs_len(netdev);
+       drvinfo->eedump_len = atl1c_get_eeprom_len(netdev);
+}
+
+static void atl1c_get_wol(struct net_device *netdev,
+                         struct ethtool_wolinfo *wol)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       wol->supported = WAKE_MAGIC | WAKE_PHY;
+       wol->wolopts = 0;
+
+       if (adapter->wol & AT_WUFC_EX)
+               wol->wolopts |= WAKE_UCAST;
+       if (adapter->wol & AT_WUFC_MC)
+               wol->wolopts |= WAKE_MCAST;
+       if (adapter->wol & AT_WUFC_BC)
+               wol->wolopts |= WAKE_BCAST;
+       if (adapter->wol & AT_WUFC_MAG)
+               wol->wolopts |= WAKE_MAGIC;
+       if (adapter->wol & AT_WUFC_LNKC)
+               wol->wolopts |= WAKE_PHY;
+}
+
+static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
+                           WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
+               return -EOPNOTSUPP;
+       /* these settings will always override what we currently have */
+       adapter->wol = 0;
+
+       if (wol->wolopts & WAKE_MAGIC)
+               adapter->wol |= AT_WUFC_MAG;
+       if (wol->wolopts & WAKE_PHY)
+               adapter->wol |= AT_WUFC_LNKC;
+
+       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+       return 0;
+}
+
+static int atl1c_nway_reset(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       if (netif_running(netdev))
+               atl1c_reinit_locked(adapter);
+       return 0;
+}
+
+static const struct ethtool_ops atl1c_ethtool_ops = {
+       .get_settings           = atl1c_get_settings,
+       .set_settings           = atl1c_set_settings,
+       .get_drvinfo            = atl1c_get_drvinfo,
+       .get_regs_len           = atl1c_get_regs_len,
+       .get_regs               = atl1c_get_regs,
+       .get_wol                = atl1c_get_wol,
+       .set_wol                = atl1c_set_wol,
+       .get_msglevel           = atl1c_get_msglevel,
+       .set_msglevel           = atl1c_set_msglevel,
+       .nway_reset             = atl1c_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_eeprom_len         = atl1c_get_eeprom_len,
+       .get_eeprom             = atl1c_get_eeprom,
+};
+
+void atl1c_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops);
+}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
new file mode 100644 (file)
index 0000000..23f2ab0
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+
+#include "atl1c.h"
+
+/*
+ * check_eeprom_exist
+ * return 1 if eeprom exist
+ */
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
+{
+       u32 data;
+
+       AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
+       if (data & TWSI_DEBUG_DEV_EXIST)
+               return 1;
+
+       AT_READ_REG(hw, REG_MASTER_CTRL, &data);
+       if (data & MASTER_CTRL_OTP_SEL)
+               return 1;
+       return 0;
+}
+
+void atl1c_hw_set_mac_addr(struct atl1c_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])) ;
+       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+       /* hight dword */
+       value = (((u32)hw->mac_addr[0]) << 8) |
+               (((u32)hw->mac_addr[1])) ;
+       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/*
+ * atl1c_get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int atl1c_get_permanent_address(struct atl1c_hw *hw)
+{
+       u32 addr[2];
+       u32 i;
+       u32 otp_ctrl_data;
+       u32 twsi_ctrl_data;
+       u32 ltssm_ctrl_data;
+       u32 wol_data;
+       u8  eth_addr[ETH_ALEN];
+       u16 phy_data;
+       bool raise_vol = false;
+
+       /* init */
+       addr[0] = addr[1] = 0;
+       AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+       if (atl1c_check_eeprom_exist(hw)) {
+               if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
+                       /* Enable OTP CLK */
+                       if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
+                               otp_ctrl_data |= OTP_CTRL_CLK_EN;
+                               AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+                               AT_WRITE_FLUSH(hw);
+                               msleep(1);
+                       }
+               }
+
+               if (hw->nic_type == athr_l2c_b ||
+                   hw->nic_type == athr_l2c_b2 ||
+                   hw->nic_type == athr_l1d) {
+                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
+                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+                               goto out;
+                       phy_data &= 0xFF7F;
+                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+                               goto out;
+                       phy_data |= 0x8;
+                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+                       udelay(20);
+                       raise_vol = true;
+               }
+               /* close open bit of ReadOnly*/
+               AT_READ_REG(hw, REG_LTSSM_ID_CTRL, &ltssm_ctrl_data);
+               ltssm_ctrl_data &= ~LTSSM_ID_EN_WRO;
+               AT_WRITE_REG(hw, REG_LTSSM_ID_CTRL, ltssm_ctrl_data);
+
+               /* clear any WOL settings */
+               AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+               AT_READ_REG(hw, REG_WOL_CTRL, &wol_data);
+
+
+               AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+               twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
+               AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
+               for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
+                       msleep(10);
+                       AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+                       if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
+                               break;
+               }
+               if (i >= AT_TWSI_EEPROM_TIMEOUT)
+                       return -1;
+       }
+       /* Disable OTP_CLK */
+       if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
+               otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
+               AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+               msleep(1);
+       }
+       if (raise_vol) {
+               if (hw->nic_type == athr_l2c_b ||
+                   hw->nic_type == athr_l2c_b2 ||
+                   hw->nic_type == athr_l1d ||
+                   hw->nic_type == athr_l1d_2) {
+                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00);
+                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+                               goto out;
+                       phy_data |= 0x80;
+                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+                       atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+                       if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data))
+                               goto out;
+                       phy_data &= 0xFFF7;
+                       atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+                       udelay(20);
+               }
+       }
+
+       /* maybe MAC-address is from BIOS */
+       AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
+       AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
+       *(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;
+       }
+
+out:
+       return -1;
+}
+
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
+{
+       int i;
+       int ret = false;
+       u32 otp_ctrl_data;
+       u32 control;
+       u32 data;
+
+       if (offset & 3)
+               return ret; /* address do not align */
+
+       AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+       if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+               AT_WRITE_REG(hw, REG_OTP_CTRL,
+                               (otp_ctrl_data | OTP_CTRL_CLK_EN));
+
+       AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
+       control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
+       AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
+
+       for (i = 0; i < 10; i++) {
+               udelay(100);
+               AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
+               if (control & EEPROM_CTRL_RW)
+                       break;
+       }
+       if (control & EEPROM_CTRL_RW) {
+               AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
+               AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
+               data = data & 0xFFFF;
+               *p_value = swab32((data << 16) | (*p_value >> 16));
+               ret = true;
+       }
+       if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+               AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+
+       return ret;
+}
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+int atl1c_read_mac_addr(struct atl1c_hw *hw)
+{
+       int err = 0;
+
+       err = atl1c_get_permanent_address(hw);
+       if (err)
+               random_ether_addr(hw->perm_mac_addr);
+
+       memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
+       return 0;
+}
+
+/*
+ * atl1c_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 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
+{
+       u32 crc32;
+       u32 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 atl1c_hash_set(struct atl1c_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 bit 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 = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+       mta |= (1 << hash_bit);
+
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+int atl1c_read_phy_reg(struct atl1c_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;
+
+       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+       }
+       if (!(val & (MDIO_START | MDIO_BUSY))) {
+               *phy_data = (u16)val;
+               return 0;
+       }
+
+       return -1;
+}
+
+/*
+ * 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
+ */
+int atl1c_write_phy_reg(struct atl1c_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;
+
+       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+       }
+
+       if (!(val & (MDIO_START | MDIO_BUSY)))
+               return 0;
+
+       return -1;
+}
+
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
+{
+       u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_ALL;
+       u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
+                               ~GIGA_CR_1000T_SPEED_MASK;
+
+       if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
+               mii_adv_data |= ADVERTISE_10HALF;
+       if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
+               mii_adv_data |= ADVERTISE_10FULL;
+       if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
+               mii_adv_data |= ADVERTISE_100HALF;
+       if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
+               mii_adv_data |= ADVERTISE_100FULL;
+
+       if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+               mii_adv_data |= ADVERTISE_10HALF  | ADVERTISE_10FULL |
+                               ADVERTISE_100HALF | ADVERTISE_100FULL;
+
+       if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
+               if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
+                       mii_giga_ctrl_data |= ADVERTISE_1000HALF;
+               if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
+                       mii_giga_ctrl_data |= ADVERTISE_1000FULL;
+               if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+                       mii_giga_ctrl_data |= ADVERTISE_1000HALF |
+                                       ADVERTISE_1000FULL;
+       }
+
+       if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
+           atl1c_write_phy_reg(hw, MII_CTRL1000, mii_giga_ctrl_data) != 0)
+               return -1;
+       return 0;
+}
+
+void atl1c_phy_disable(struct atl1c_hw *hw)
+{
+       AT_WRITE_REGW(hw, REG_GPHY_CTRL,
+                       GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
+}
+
+static void atl1c_phy_magic_data(struct atl1c_hw *hw)
+{
+       u16 data;
+
+       data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
+               ((1 & ANA_INTERVAL_SEL_TIMER_MASK) <<
+               ANA_INTERVAL_SEL_TIMER_SHIFT);
+
+       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_18);
+       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+       data = (2 & ANA_SERDES_CDR_BW_MASK) | ANA_MS_PAD_DBG |
+               ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | ANA_SERDES_EN_PLL |
+               ANA_SERDES_EN_LCKDT;
+
+       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_5);
+       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+       data = (44 & ANA_LONG_CABLE_TH_100_MASK) |
+               ((33 & ANA_SHORT_CABLE_TH_100_MASK) <<
+               ANA_SHORT_CABLE_TH_100_SHIFT) | ANA_BP_BAD_LINK_ACCUM |
+               ANA_BP_SMALL_BW;
+
+       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_54);
+       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+       data = (11 & ANA_IECHO_ADJ_MASK) | ((11 & ANA_IECHO_ADJ_MASK) <<
+               ANA_IECHO_ADJ_2_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
+               ANA_IECHO_ADJ_1_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
+               ANA_IECHO_ADJ_0_SHIFT);
+
+       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_4);
+       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+       data = ANA_RESTART_CAL | ((7 & ANA_MANUL_SWICH_ON_MASK) <<
+               ANA_MANUL_SWICH_ON_SHIFT) | ANA_MAN_ENABLE |
+               ANA_SEL_HSP | ANA_EN_HB | ANA_OEN_125M;
+
+       atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_0);
+       atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+       if (hw->ctrl_flags & ATL1C_HIB_DISABLE) {
+               atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_41);
+               if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
+                       return;
+               data &= ~ANA_TOP_PS_EN;
+               atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+               atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_11);
+               if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
+                       return;
+               data &= ~ANA_PS_HIB_EN;
+               atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+       }
+}
+
+int atl1c_phy_reset(struct atl1c_hw *hw)
+{
+       struct atl1c_adapter *adapter = hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+       u16 phy_data;
+       u32 phy_ctrl_data = GPHY_CTRL_DEFAULT;
+       u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN;
+       int err;
+
+       if (hw->ctrl_flags & ATL1C_HIB_DISABLE)
+               phy_ctrl_data &= ~GPHY_CTRL_HIB_EN;
+
+       AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+       AT_WRITE_FLUSH(hw);
+       msleep(40);
+       phy_ctrl_data |= GPHY_CTRL_EXT_RESET;
+       AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+       AT_WRITE_FLUSH(hw);
+       msleep(10);
+
+       if (hw->nic_type == athr_l2c_b) {
+               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x0A);
+               atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
+               atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xDFFF);
+       }
+
+       if (hw->nic_type == athr_l2c_b ||
+           hw->nic_type == athr_l2c_b2 ||
+           hw->nic_type == athr_l1d ||
+           hw->nic_type == athr_l1d_2) {
+               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B);
+               atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data);
+               atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7);
+               msleep(20);
+       }
+       if (hw->nic_type == athr_l1d) {
+               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
+               atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D);
+       }
+       if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2
+               || hw->nic_type == athr_l2c) {
+               atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29);
+               atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD);
+       }
+       err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data);
+       if (err) {
+               if (netif_msg_hw(adapter))
+                       dev_err(&pdev->dev,
+                               "Error enable PHY linkChange Interrupt\n");
+               return err;
+       }
+       if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+               atl1c_phy_magic_data(hw);
+       return 0;
+}
+
+int atl1c_phy_init(struct atl1c_hw *hw)
+{
+       struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+       int ret_val;
+       u16 mii_bmcr_data = BMCR_RESET;
+
+       if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) ||
+               (atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) {
+               dev_err(&pdev->dev, "Error get phy ID\n");
+               return -1;
+       }
+       switch (hw->media_type) {
+       case MEDIA_TYPE_AUTO_SENSOR:
+               ret_val = atl1c_phy_setup_adv(hw);
+               if (ret_val) {
+                       if (netif_msg_link(adapter))
+                               dev_err(&pdev->dev,
+                                       "Error Setting up Auto-Negotiation\n");
+                       return ret_val;
+               }
+               mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
+               break;
+       case MEDIA_TYPE_100M_FULL:
+               mii_bmcr_data |= BMCR_SPEED100 | BMCR_FULLDPLX;
+               break;
+       case MEDIA_TYPE_100M_HALF:
+               mii_bmcr_data |= BMCR_SPEED100;
+               break;
+       case MEDIA_TYPE_10M_FULL:
+               mii_bmcr_data |= BMCR_FULLDPLX;
+               break;
+       case MEDIA_TYPE_10M_HALF:
+               break;
+       default:
+               if (netif_msg_link(adapter))
+                       dev_err(&pdev->dev, "Wrong Media type %d\n",
+                               hw->media_type);
+               return -1;
+               break;
+       }
+
+       ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+       if (ret_val)
+               return ret_val;
+       hw->phy_configured = true;
+
+       return 0;
+}
+
+/*
+ * 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
+ */
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
+{
+       int err;
+       u16 phy_data;
+
+       /* Read   PHY Specific Status Register (17) */
+       err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
+       if (err)
+               return err;
+
+       if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
+               return -1;
+
+       switch (phy_data & GIGA_PSSR_SPEED) {
+       case GIGA_PSSR_1000MBS:
+               *speed = SPEED_1000;
+               break;
+       case GIGA_PSSR_100MBS:
+               *speed = SPEED_100;
+               break;
+       case  GIGA_PSSR_10MBS:
+               *speed = SPEED_10;
+               break;
+       default:
+               return -1;
+               break;
+       }
+
+       if (phy_data & GIGA_PSSR_DPLX)
+               *duplex = FULL_DUPLEX;
+       else
+               *duplex = HALF_DUPLEX;
+
+       return 0;
+}
+
+int atl1c_phy_power_saving(struct atl1c_hw *hw)
+{
+       struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+       int ret = 0;
+       u16 autoneg_advertised = ADVERTISED_10baseT_Half;
+       u16 save_autoneg_advertised;
+       u16 phy_data;
+       u16 mii_lpa_data;
+       u16 speed = SPEED_0;
+       u16 duplex = FULL_DUPLEX;
+       int i;
+
+       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+       if (phy_data & BMSR_LSTATUS) {
+               atl1c_read_phy_reg(hw, MII_LPA, &mii_lpa_data);
+               if (mii_lpa_data & LPA_10FULL)
+                       autoneg_advertised = ADVERTISED_10baseT_Full;
+               else if (mii_lpa_data & LPA_10HALF)
+                       autoneg_advertised = ADVERTISED_10baseT_Half;
+               else if (mii_lpa_data & LPA_100HALF)
+                       autoneg_advertised = ADVERTISED_100baseT_Half;
+               else if (mii_lpa_data & LPA_100FULL)
+                       autoneg_advertised = ADVERTISED_100baseT_Full;
+
+               save_autoneg_advertised = hw->autoneg_advertised;
+               hw->phy_configured = false;
+               hw->autoneg_advertised = autoneg_advertised;
+               if (atl1c_restart_autoneg(hw) != 0) {
+                       dev_dbg(&pdev->dev, "phy autoneg failed\n");
+                       ret = -1;
+               }
+               hw->autoneg_advertised = save_autoneg_advertised;
+
+               if (mii_lpa_data) {
+                       for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
+                               mdelay(100);
+                               atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+                               atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+                               if (phy_data & BMSR_LSTATUS) {
+                                       if (atl1c_get_speed_and_duplex(hw, &speed,
+                                                                       &duplex) != 0)
+                                               dev_dbg(&pdev->dev,
+                                                       "get speed and duplex failed\n");
+                                       break;
+                               }
+                       }
+               }
+       } else {
+               speed = SPEED_10;
+               duplex = HALF_DUPLEX;
+       }
+       adapter->link_speed = speed;
+       adapter->link_duplex = duplex;
+
+       return ret;
+}
+
+int atl1c_restart_autoneg(struct atl1c_hw *hw)
+{
+       int err = 0;
+       u16 mii_bmcr_data = BMCR_RESET;
+
+       err = atl1c_phy_setup_adv(hw);
+       if (err)
+               return err;
+       mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
+
+       return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
new file mode 100644 (file)
index 0000000..655fc6c
--- /dev/null
@@ -0,0 +1,868 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#ifndef _ATL1C_HW_H_
+#define _ATL1C_HW_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+
+struct atl1c_adapter;
+struct atl1c_hw;
+
+/* function prototype */
+void atl1c_phy_disable(struct atl1c_hw *hw);
+void atl1c_hw_set_mac_addr(struct atl1c_hw *hw);
+int atl1c_phy_reset(struct atl1c_hw *hw);
+int atl1c_read_mac_addr(struct atl1c_hw *hw);
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex);
+u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr);
+void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value);
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data);
+int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data);
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value);
+int atl1c_phy_init(struct atl1c_hw *hw);
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw);
+int atl1c_restart_autoneg(struct atl1c_hw *hw);
+int atl1c_phy_power_saving(struct atl1c_hw *hw);
+/* register definition */
+#define REG_DEVICE_CAP                 0x5C
+#define DEVICE_CAP_MAX_PAYLOAD_MASK     0x7
+#define DEVICE_CAP_MAX_PAYLOAD_SHIFT    0
+
+#define REG_DEVICE_CTRL                        0x60
+#define DEVICE_CTRL_MAX_PAYLOAD_MASK    0x7
+#define DEVICE_CTRL_MAX_PAYLOAD_SHIFT   5
+#define DEVICE_CTRL_MAX_RREQ_SZ_MASK    0x7
+#define DEVICE_CTRL_MAX_RREQ_SZ_SHIFT   12
+
+#define REG_LINK_CTRL                  0x68
+#define LINK_CTRL_L0S_EN               0x01
+#define LINK_CTRL_L1_EN                        0x02
+#define LINK_CTRL_EXT_SYNC             0x80
+
+#define REG_VPD_CAP                    0x6C
+#define VPD_CAP_ID_MASK                 0xff
+#define VPD_CAP_ID_SHIFT                0
+#define VPD_CAP_NEXT_PTR_MASK           0xFF
+#define VPD_CAP_NEXT_PTR_SHIFT          8
+#define VPD_CAP_VPD_ADDR_MASK           0x7FFF
+#define VPD_CAP_VPD_ADDR_SHIFT          16
+#define VPD_CAP_VPD_FLAG                0x80000000
+
+#define REG_VPD_DATA                   0x70
+
+#define REG_PCIE_UC_SEVERITY           0x10C
+#define PCIE_UC_SERVRITY_TRN           0x00000001
+#define PCIE_UC_SERVRITY_DLP           0x00000010
+#define PCIE_UC_SERVRITY_PSN_TLP       0x00001000
+#define PCIE_UC_SERVRITY_FCP           0x00002000
+#define PCIE_UC_SERVRITY_CPL_TO                0x00004000
+#define PCIE_UC_SERVRITY_CA            0x00008000
+#define PCIE_UC_SERVRITY_UC            0x00010000
+#define PCIE_UC_SERVRITY_ROV           0x00020000
+#define PCIE_UC_SERVRITY_MLFP          0x00040000
+#define PCIE_UC_SERVRITY_ECRC          0x00080000
+#define PCIE_UC_SERVRITY_UR            0x00100000
+
+#define REG_DEV_SERIALNUM_CTRL         0x200
+#define REG_DEV_MAC_SEL_MASK           0x0 /* 0:EUI; 1:MAC */
+#define REG_DEV_MAC_SEL_SHIFT          0
+#define REG_DEV_SERIAL_NUM_EN_MASK     0x1
+#define REG_DEV_SERIAL_NUM_EN_SHIFT    1
+
+#define REG_TWSI_CTRL                  0x218
+#define TWSI_CTRL_LD_OFFSET_MASK        0xFF
+#define TWSI_CTRL_LD_OFFSET_SHIFT       0
+#define TWSI_CTRL_LD_SLV_ADDR_MASK      0x7
+#define TWSI_CTRL_LD_SLV_ADDR_SHIFT     8
+#define TWSI_CTRL_SW_LDSTART            0x800
+#define TWSI_CTRL_HW_LDSTART            0x1000
+#define TWSI_CTRL_SMB_SLV_ADDR_MASK     0x7F
+#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT    15
+#define TWSI_CTRL_LD_EXIST              0x400000
+#define TWSI_CTRL_READ_FREQ_SEL_MASK    0x3
+#define TWSI_CTRL_READ_FREQ_SEL_SHIFT   23
+#define TWSI_CTRL_FREQ_SEL_100K         0
+#define TWSI_CTRL_FREQ_SEL_200K         1
+#define TWSI_CTRL_FREQ_SEL_300K         2
+#define TWSI_CTRL_FREQ_SEL_400K         3
+#define TWSI_CTRL_SMB_SLV_ADDR
+#define TWSI_CTRL_WRITE_FREQ_SEL_MASK   0x3
+#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT  24
+
+
+#define REG_PCIE_DEV_MISC_CTRL         0x21C
+#define PCIE_DEV_MISC_EXT_PIPE         0x2
+#define PCIE_DEV_MISC_RETRY_BUFDIS     0x1
+#define PCIE_DEV_MISC_SPIROM_EXIST     0x4
+#define PCIE_DEV_MISC_SERDES_ENDIAN            0x8
+#define PCIE_DEV_MISC_SERDES_SEL_DIN           0x10
+
+#define REG_PCIE_PHYMISC               0x1000
+#define PCIE_PHYMISC_FORCE_RCV_DET     0x4
+
+#define REG_PCIE_PHYMISC2              0x1004
+#define PCIE_PHYMISC2_SERDES_CDR_MASK  0x3
+#define PCIE_PHYMISC2_SERDES_CDR_SHIFT 16
+#define PCIE_PHYMISC2_SERDES_TH_MASK   0x3
+#define PCIE_PHYMISC2_SERDES_TH_SHIFT  18
+
+#define REG_TWSI_DEBUG                 0x1108
+#define TWSI_DEBUG_DEV_EXIST           0x20000000
+
+#define REG_EEPROM_CTRL                        0x12C0
+#define EEPROM_CTRL_DATA_HI_MASK       0xFFFF
+#define EEPROM_CTRL_DATA_HI_SHIFT      0
+#define EEPROM_CTRL_ADDR_MASK          0x3FF
+#define EEPROM_CTRL_ADDR_SHIFT         16
+#define EEPROM_CTRL_ACK                        0x40000000
+#define EEPROM_CTRL_RW                 0x80000000
+
+#define REG_EEPROM_DATA_LO             0x12C4
+
+#define REG_OTP_CTRL                   0x12F0
+#define OTP_CTRL_CLK_EN                        0x0002
+
+#define REG_PM_CTRL                    0x12F8
+#define PM_CTRL_SDES_EN                        0x00000001
+#define PM_CTRL_RBER_EN                        0x00000002
+#define PM_CTRL_CLK_REQ_EN             0x00000004
+#define PM_CTRL_ASPM_L1_EN             0x00000008
+#define PM_CTRL_SERDES_L1_EN           0x00000010
+#define PM_CTRL_SERDES_PLL_L1_EN       0x00000020
+#define PM_CTRL_SERDES_PD_EX_L1                0x00000040
+#define PM_CTRL_SERDES_BUDS_RX_L1_EN   0x00000080
+#define PM_CTRL_L0S_ENTRY_TIMER_MASK   0xF
+#define PM_CTRL_L0S_ENTRY_TIMER_SHIFT  8
+#define PM_CTRL_ASPM_L0S_EN            0x00001000
+#define PM_CTRL_CLK_SWH_L1             0x00002000
+#define PM_CTRL_CLK_PWM_VER1_1         0x00004000
+#define PM_CTRL_RCVR_WT_TIMER          0x00008000
+#define PM_CTRL_L1_ENTRY_TIMER_MASK    0xF
+#define PM_CTRL_L1_ENTRY_TIMER_SHIFT   16
+#define PM_CTRL_PM_REQ_TIMER_MASK      0xF
+#define PM_CTRL_PM_REQ_TIMER_SHIFT     20
+#define PM_CTRL_LCKDET_TIMER_MASK      0xF
+#define PM_CTRL_LCKDET_TIMER_SHIFT     24
+#define PM_CTRL_EN_BUFS_RX_L0S         0x10000000
+#define PM_CTRL_SA_DLY_EN              0x20000000
+#define PM_CTRL_MAC_ASPM_CHK           0x40000000
+#define PM_CTRL_HOTRST                 0x80000000
+
+#define REG_LTSSM_ID_CTRL              0x12FC
+#define LTSSM_ID_EN_WRO                        0x1000
+/* Selene Master Control Register */
+#define REG_MASTER_CTRL                        0x1400
+#define MASTER_CTRL_SOFT_RST            0x1
+#define MASTER_CTRL_TEST_MODE_MASK     0x3
+#define MASTER_CTRL_TEST_MODE_SHIFT    2
+#define MASTER_CTRL_BERT_START         0x10
+#define MASTER_CTRL_OOB_DIS_OFF                0x40
+#define MASTER_CTRL_SA_TIMER_EN                0x80
+#define MASTER_CTRL_MTIMER_EN           0x100
+#define MASTER_CTRL_MANUAL_INT          0x200
+#define MASTER_CTRL_TX_ITIMER_EN       0x400
+#define MASTER_CTRL_RX_ITIMER_EN       0x800
+#define MASTER_CTRL_CLK_SEL_DIS                0x1000
+#define MASTER_CTRL_CLK_SWH_MODE       0x2000
+#define MASTER_CTRL_INT_RDCLR          0x4000
+#define MASTER_CTRL_REV_NUM_SHIFT      16
+#define MASTER_CTRL_REV_NUM_MASK       0xff
+#define MASTER_CTRL_DEV_ID_SHIFT       24
+#define MASTER_CTRL_DEV_ID_MASK                0x7f
+#define MASTER_CTRL_OTP_SEL            0x80000000
+
+/* Timer Initial Value Register */
+#define REG_MANUAL_TIMER_INIT          0x1404
+
+/* IRQ ModeratorTimer Initial Value Register */
+#define REG_IRQ_MODRT_TIMER_INIT       0x1408
+#define IRQ_MODRT_TIMER_MASK           0xffff
+#define IRQ_MODRT_TX_TIMER_SHIFT       0
+#define IRQ_MODRT_RX_TIMER_SHIFT       16
+
+#define REG_GPHY_CTRL                  0x140C
+#define GPHY_CTRL_EXT_RESET            0x1
+#define GPHY_CTRL_RTL_MODE             0x2
+#define GPHY_CTRL_LED_MODE             0x4
+#define GPHY_CTRL_ANEG_NOW             0x8
+#define GPHY_CTRL_REV_ANEG             0x10
+#define GPHY_CTRL_GATE_25M_EN          0x20
+#define GPHY_CTRL_LPW_EXIT             0x40
+#define GPHY_CTRL_PHY_IDDQ             0x80
+#define GPHY_CTRL_PHY_IDDQ_DIS         0x100
+#define GPHY_CTRL_GIGA_DIS             0x200
+#define GPHY_CTRL_HIB_EN               0x400
+#define GPHY_CTRL_HIB_PULSE            0x800
+#define GPHY_CTRL_SEL_ANA_RST          0x1000
+#define GPHY_CTRL_PHY_PLL_ON           0x2000
+#define GPHY_CTRL_PWDOWN_HW            0x4000
+#define GPHY_CTRL_PHY_PLL_BYPASS       0x8000
+
+#define GPHY_CTRL_DEFAULT (             \
+               GPHY_CTRL_SEL_ANA_RST   |\
+               GPHY_CTRL_HIB_PULSE     |\
+               GPHY_CTRL_HIB_EN)
+
+#define GPHY_CTRL_PW_WOL_DIS (          \
+               GPHY_CTRL_SEL_ANA_RST   |\
+               GPHY_CTRL_HIB_PULSE     |\
+               GPHY_CTRL_HIB_EN        |\
+               GPHY_CTRL_PWDOWN_HW     |\
+               GPHY_CTRL_PHY_IDDQ)
+
+#define GPHY_CTRL_POWER_SAVING (       \
+               GPHY_CTRL_SEL_ANA_RST   |\
+               GPHY_CTRL_HIB_EN        |\
+               GPHY_CTRL_HIB_PULSE     |\
+               GPHY_CTRL_PWDOWN_HW     |\
+               GPHY_CTRL_PHY_IDDQ)
+/* Block IDLE Status Register */
+#define REG_IDLE_STATUS                0x1410
+#define IDLE_STATUS_MASK               0x00FF
+#define IDLE_STATUS_RXMAC_NO_IDLE              0x1
+#define IDLE_STATUS_TXMAC_NO_IDLE              0x2
+#define IDLE_STATUS_RXQ_NO_IDLE                0x4
+#define IDLE_STATUS_TXQ_NO_IDLE                0x8
+#define IDLE_STATUS_DMAR_NO_IDLE               0x10
+#define IDLE_STATUS_DMAW_NO_IDLE               0x20
+#define IDLE_STATUS_SMB_NO_IDLE                0x40
+#define IDLE_STATUS_CMB_NO_IDLE                0x80
+
+/* MDIO Control Register */
+#define REG_MDIO_CTRL                  0x1414
+#define MDIO_DATA_MASK                 0xffff  /* On MDIO write, the 16-bit
+                                                * control data to write to PHY
+                                                * MII management register */
+#define MDIO_DATA_SHIFT                0       /* On MDIO read, the 16-bit
+                                                * status data that was read
+                                                * from the PHY MII management register */
+#define MDIO_REG_ADDR_MASK             0x1f    /* MDIO register address */
+#define MDIO_REG_ADDR_SHIFT            16
+#define MDIO_RW                        0x200000  /* 1: read, 0: write */
+#define MDIO_SUP_PREAMBLE              0x400000  /* Suppress preamble */
+#define MDIO_START                     0x800000  /* Write 1 to initiate the MDIO
+                                                  * master. And this bit is self
+                                                  * cleared after one cycle */
+#define MDIO_CLK_SEL_SHIFT             24
+#define MDIO_CLK_25_4                  0
+#define MDIO_CLK_25_6                  2
+#define MDIO_CLK_25_8                  3
+#define MDIO_CLK_25_10                 4
+#define MDIO_CLK_25_14                 5
+#define MDIO_CLK_25_20                 6
+#define MDIO_CLK_25_28                 7
+#define MDIO_BUSY                      0x8000000
+#define MDIO_AP_EN                     0x10000000
+#define MDIO_WAIT_TIMES                10
+
+/* MII PHY Status Register */
+#define REG_PHY_STATUS                 0x1418
+#define PHY_GENERAL_STATUS_MASK                0xFFFF
+#define PHY_STATUS_RECV_ENABLE         0x0001
+#define PHY_OE_PWSP_STATUS_MASK                0x07FF
+#define PHY_OE_PWSP_STATUS_SHIFT       16
+#define PHY_STATUS_LPW_STATE           0x80000000
+/* BIST Control and Status Register0 (for the Packet Memory) */
+#define REG_BIST0_CTRL                 0x141c
+#define BIST0_NOW                      0x1
+#define BIST0_SRAM_FAIL                0x2 /* 1: The SRAM failure is
+                                            * un-repairable  because
+                                            * it has address decoder
+                                            * failure or more than 1 cell
+                                            * stuck-to-x failure */
+#define BIST0_FUSE_FLAG                0x4
+
+/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
+#define REG_BIST1_CTRL                 0x1420
+#define BIST1_NOW                      0x1
+#define BIST1_SRAM_FAIL                0x2
+#define BIST1_FUSE_FLAG                0x4
+
+/* SerDes Lock Detect Control and Status Register */
+#define REG_SERDES_LOCK                0x1424
+#define SERDES_LOCK_DETECT             0x1  /* SerDes lock detected. This signal
+                                             * comes from Analog SerDes */
+#define SERDES_LOCK_DETECT_EN          0x2  /* 1: Enable SerDes Lock detect function */
+#define SERDES_LOCK_STS_SELFB_PLL_SHIFT 0xE
+#define SERDES_LOCK_STS_SELFB_PLL_MASK  0x3
+#define SERDES_OVCLK_18_25             0x0
+#define SERDES_OVCLK_12_18             0x1
+#define SERDES_OVCLK_0_4               0x2
+#define SERDES_OVCLK_4_12              0x3
+#define SERDES_MAC_CLK_SLOWDOWN                0x20000
+#define SERDES_PYH_CLK_SLOWDOWN                0x40000
+
+/* MAC Control Register  */
+#define REG_MAC_CTRL                   0x1480
+#define MAC_CTRL_TX_EN                 0x1
+#define MAC_CTRL_RX_EN                 0x2
+#define MAC_CTRL_TX_FLOW               0x4
+#define MAC_CTRL_RX_FLOW               0x8
+#define MAC_CTRL_LOOPBACK              0x10
+#define MAC_CTRL_DUPLX                 0x20
+#define MAC_CTRL_ADD_CRC               0x40
+#define MAC_CTRL_PAD                   0x80
+#define MAC_CTRL_LENCHK                0x100
+#define MAC_CTRL_HUGE_EN               0x200
+#define MAC_CTRL_PRMLEN_SHIFT          10
+#define MAC_CTRL_PRMLEN_MASK           0xf
+#define MAC_CTRL_RMV_VLAN              0x4000
+#define MAC_CTRL_PROMIS_EN             0x8000
+#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            0x3
+#define MAC_CTRL_DBG_TX_BKPRESURE      0x400000
+#define MAC_CTRL_TX_HUGE               0x800000
+#define MAC_CTRL_RX_CHKSUM_EN          0x1000000
+#define MAC_CTRL_MC_ALL_EN             0x2000000
+#define MAC_CTRL_BC_EN                 0x4000000
+#define MAC_CTRL_DBG                   0x8000000
+#define MAC_CTRL_SINGLE_PAUSE_EN       0x10000000
+#define MAC_CTRL_HASH_ALG_CRC32                0x20000000
+#define MAC_CTRL_SPEED_MODE_SW         0x40000000
+
+/* MAC IPG/IFG Control Register  */
+#define REG_MAC_IPG_IFG                0x1484
+#define MAC_IPG_IFG_IPGT_SHIFT         0       /* Desired back to back
+                                                * inter-packet gap. The
+                                                * default is 96-bit time */
+#define MAC_IPG_IFG_IPGT_MASK          0x7f
+#define MAC_IPG_IFG_MIFG_SHIFT         8       /* Minimum number of IFG to
+                                                * enforce in between RX frames */
+#define MAC_IPG_IFG_MIFG_MASK          0xff    /* Frame gap below such IFP is dropped */
+#define MAC_IPG_IFG_IPGR1_SHIFT        16      /* 64bit Carrier-Sense window */
+#define MAC_IPG_IFG_IPGR1_MASK         0x7f
+#define MAC_IPG_IFG_IPGR2_SHIFT        24      /* 96-bit IPG window */
+#define MAC_IPG_IFG_IPGR2_MASK         0x7f
+
+/* MAC STATION ADDRESS  */
+#define REG_MAC_STA_ADDR               0x1488
+
+/* Hash table for multicast address */
+#define REG_RX_HASH_TABLE              0x1490
+
+/* MAC Half-Duplex Control Register */
+#define REG_MAC_HALF_DUPLX_CTRL        0x1498
+#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT  0      /* Collision Window */
+#define MAC_HALF_DUPLX_CTRL_LCOL_MASK   0x3ff
+#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
+#define MAC_HALF_DUPLX_CTRL_RETRY_MASK  0xf
+#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN  0x10000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_C   0x20000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_P   0x40000 /* No back-off on backpressure,
+                                                * immediately start the
+                                                * transmission after back pressure */
+#define MAC_HALF_DUPLX_CTRL_ABEBE        0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT  20      /* Maximum binary exponential number */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK   0xf
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24      /* IPG to start JAM for collision based flow control in half-duplex */
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK  0xf     /* mode. In unit of 8-bit time */
+
+/* Maximum Frame Length Control Register   */
+#define REG_MTU                        0x149c
+
+/* Wake-On-Lan control register */
+#define REG_WOL_CTRL                   0x14a0
+#define WOL_PATTERN_EN                 0x00000001
+#define WOL_PATTERN_PME_EN              0x00000002
+#define WOL_MAGIC_EN                    0x00000004
+#define WOL_MAGIC_PME_EN                0x00000008
+#define WOL_LINK_CHG_EN                 0x00000010
+#define WOL_LINK_CHG_PME_EN             0x00000020
+#define WOL_PATTERN_ST                  0x00000100
+#define WOL_MAGIC_ST                    0x00000200
+#define WOL_LINKCHG_ST                  0x00000400
+#define WOL_CLK_SWITCH_EN               0x00008000
+#define WOL_PT0_EN                      0x00010000
+#define WOL_PT1_EN                      0x00020000
+#define WOL_PT2_EN                      0x00040000
+#define WOL_PT3_EN                      0x00080000
+#define WOL_PT4_EN                      0x00100000
+#define WOL_PT5_EN                      0x00200000
+#define WOL_PT6_EN                      0x00400000
+
+/* 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 Register */
+#define RFDX_HEAD_ADDR_MASK            0x03FF
+#define RFDX_HARD_ADDR_SHIFT           0
+#define RFDX_TAIL_ADDR_MASK            0x03FF
+#define RFDX_TAIL_ADDR_SHIFT            16
+
+#define REG_SRAM_RFD0_INFO             0x1500
+#define REG_SRAM_RFD1_INFO             0x1504
+#define REG_SRAM_RFD2_INFO             0x1508
+#define        REG_SRAM_RFD3_INFO              0x150C
+
+#define REG_RFD_NIC_LEN                        0x1510 /* In 8-bytes */
+#define RFD_NIC_LEN_MASK               0x03FF
+
+#define REG_SRAM_TRD_ADDR              0x1518
+#define TPD_HEAD_ADDR_MASK             0x03FF
+#define TPD_HEAD_ADDR_SHIFT            0
+#define TPD_TAIL_ADDR_MASK             0x03FF
+#define TPD_TAIL_ADDR_SHIFT            16
+
+#define REG_SRAM_TRD_LEN               0x151C /* In 8-bytes */
+#define TPD_NIC_LEN_MASK               0x03FF
+
+#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_ADDR             0x1530
+#define REG_SRAM_PKTH_ADDR             0x1532
+
+/*
+ * Load Ptr Register
+ * Software sets this bit after the initialization of the head and tail */
+#define REG_LOAD_PTR                   0x1534
+
+/*
+ * addresses of all descriptors, as well as the following descriptor
+ * control register, which triggers each function block to load the head
+ * pointer to prepare for the operation. This bit is then self-cleared
+ * after one cycle.
+ */
+#define REG_RX_BASE_ADDR_HI            0x1540
+#define REG_TX_BASE_ADDR_HI            0x1544
+#define REG_SMB_BASE_ADDR_HI           0x1548
+#define REG_SMB_BASE_ADDR_LO           0x154C
+#define REG_RFD0_HEAD_ADDR_LO          0x1550
+#define REG_RFD1_HEAD_ADDR_LO          0x1554
+#define REG_RFD2_HEAD_ADDR_LO          0x1558
+#define REG_RFD3_HEAD_ADDR_LO          0x155C
+#define REG_RFD_RING_SIZE              0x1560
+#define RFD_RING_SIZE_MASK             0x0FFF
+#define REG_RX_BUF_SIZE                        0x1564
+#define RX_BUF_SIZE_MASK               0xFFFF
+#define REG_RRD0_HEAD_ADDR_LO          0x1568
+#define REG_RRD1_HEAD_ADDR_LO          0x156C
+#define REG_RRD2_HEAD_ADDR_LO          0x1570
+#define REG_RRD3_HEAD_ADDR_LO          0x1574
+#define REG_RRD_RING_SIZE              0x1578
+#define RRD_RING_SIZE_MASK             0x0FFF
+#define REG_HTPD_HEAD_ADDR_LO          0x157C
+#define REG_NTPD_HEAD_ADDR_LO          0x1580
+#define REG_TPD_RING_SIZE              0x1584
+#define TPD_RING_SIZE_MASK             0xFFFF
+#define REG_CMB_BASE_ADDR_LO           0x1588
+
+/* RSS about */
+#define REG_RSS_KEY0                    0x14B0
+#define REG_RSS_KEY1                    0x14B4
+#define REG_RSS_KEY2                    0x14B8
+#define REG_RSS_KEY3                    0x14BC
+#define REG_RSS_KEY4                    0x14C0
+#define REG_RSS_KEY5                    0x14C4
+#define REG_RSS_KEY6                    0x14C8
+#define REG_RSS_KEY7                    0x14CC
+#define REG_RSS_KEY8                    0x14D0
+#define REG_RSS_KEY9                    0x14D4
+#define REG_IDT_TABLE0                 0x14E0
+#define REG_IDT_TABLE1                  0x14E4
+#define REG_IDT_TABLE2                  0x14E8
+#define REG_IDT_TABLE3                  0x14EC
+#define REG_IDT_TABLE4                  0x14F0
+#define REG_IDT_TABLE5                  0x14F4
+#define REG_IDT_TABLE6                  0x14F8
+#define REG_IDT_TABLE7                  0x14FC
+#define REG_IDT_TABLE                   REG_IDT_TABLE0
+#define REG_RSS_HASH_VALUE              0x15B0
+#define REG_RSS_HASH_FLAG               0x15B4
+#define REG_BASE_CPU_NUMBER             0x15B8
+
+/* TXQ Control Register */
+#define REG_TXQ_CTRL                   0x1590
+#define        TXQ_NUM_TPD_BURST_MASK          0xF
+#define TXQ_NUM_TPD_BURST_SHIFT        0
+#define TXQ_CTRL_IP_OPTION_EN          0x10
+#define TXQ_CTRL_EN                     0x20
+#define TXQ_CTRL_ENH_MODE               0x40
+#define TXQ_CTRL_LS_8023_EN            0x80
+#define TXQ_TXF_BURST_NUM_SHIFT        16
+#define TXQ_TXF_BURST_NUM_MASK         0xFFFF
+
+/* Jumbo packet Threshold for task offload */
+#define REG_TX_TSO_OFFLOAD_THRESH      0x1594 /* In 8-bytes */
+#define TX_TSO_OFFLOAD_THRESH_MASK     0x07FF
+
+#define        REG_TXF_WATER_MARK              0x1598 /* In 8-bytes */
+#define TXF_WATER_MARK_MASK            0x0FFF
+#define TXF_LOW_WATER_MARK_SHIFT       0
+#define TXF_HIGH_WATER_MARK_SHIFT      16
+#define TXQ_CTRL_BURST_MODE_EN         0x80000000
+
+#define REG_THRUPUT_MON_CTRL           0x159C
+#define THRUPUT_MON_RATE_MASK          0x3
+#define THRUPUT_MON_RATE_SHIFT         0
+#define THRUPUT_MON_EN                 0x80
+
+/* RXQ Control Register */
+#define REG_RXQ_CTRL                   0x15A0
+#define ASPM_THRUPUT_LIMIT_MASK                0x3
+#define ASPM_THRUPUT_LIMIT_SHIFT       0
+#define ASPM_THRUPUT_LIMIT_NO          0x00
+#define ASPM_THRUPUT_LIMIT_1M          0x01
+#define ASPM_THRUPUT_LIMIT_10M         0x02
+#define ASPM_THRUPUT_LIMIT_100M                0x04
+#define RXQ1_CTRL_EN                   0x10
+#define RXQ2_CTRL_EN                   0x20
+#define RXQ3_CTRL_EN                   0x40
+#define IPV6_CHKSUM_CTRL_EN            0x80
+#define RSS_HASH_BITS_MASK             0x00FF
+#define RSS_HASH_BITS_SHIFT            8
+#define RSS_HASH_IPV4                  0x10000
+#define RSS_HASH_IPV4_TCP              0x20000
+#define RSS_HASH_IPV6                  0x40000
+#define RSS_HASH_IPV6_TCP              0x80000
+#define RXQ_RFD_BURST_NUM_MASK         0x003F
+#define RXQ_RFD_BURST_NUM_SHIFT                20
+#define RSS_MODE_MASK                  0x0003
+#define RSS_MODE_SHIFT                 26
+#define RSS_NIP_QUEUE_SEL_MASK         0x1
+#define RSS_NIP_QUEUE_SEL_SHIFT                28
+#define RRS_HASH_CTRL_EN               0x20000000
+#define RX_CUT_THRU_EN                 0x40000000
+#define RXQ_CTRL_EN                    0x80000000
+
+#define REG_RFD_FREE_THRESH            0x15A4
+#define RFD_FREE_THRESH_MASK           0x003F
+#define RFD_FREE_HI_THRESH_SHIFT       0
+#define RFD_FREE_LO_THRESH_SHIFT       6
+
+/* RXF flow control register */
+#define REG_RXQ_RXF_PAUSE_THRESH       0x15A8
+#define RXQ_RXF_PAUSE_TH_HI_SHIFT       0
+#define RXQ_RXF_PAUSE_TH_HI_MASK        0x0FFF
+#define RXQ_RXF_PAUSE_TH_LO_SHIFT       16
+#define RXQ_RXF_PAUSE_TH_LO_MASK        0x0FFF
+
+#define REG_RXD_DMA_CTRL               0x15AC
+#define RXD_DMA_THRESH_MASK            0x0FFF  /* In 8-bytes */
+#define RXD_DMA_THRESH_SHIFT           0
+#define RXD_DMA_DOWN_TIMER_MASK                0xFFFF
+#define RXD_DMA_DOWN_TIMER_SHIFT       16
+
+/* 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_MASK    0x0007
+#define DMA_CTRL_DMAR_BURST_LEN_SHIFT   4
+#define DMA_CTRL_DMAW_BURST_LEN_MASK    0x0007
+#define DMA_CTRL_DMAW_BURST_LEN_SHIFT   7
+#define DMA_CTRL_DMAR_REQ_PRI           0x400
+#define DMA_CTRL_DMAR_DLY_CNT_MASK      0x001F
+#define DMA_CTRL_DMAR_DLY_CNT_SHIFT     11
+#define DMA_CTRL_DMAW_DLY_CNT_MASK      0x000F
+#define DMA_CTRL_DMAW_DLY_CNT_SHIFT     16
+#define DMA_CTRL_CMB_EN                0x100000
+#define DMA_CTRL_SMB_EN                        0x200000
+#define DMA_CTRL_CMB_NOW               0x400000
+#define MAC_CTRL_SMB_DIS               0x1000000
+#define DMA_CTRL_SMB_NOW               0x80000000
+
+/* CMB/SMB Control Register */
+#define REG_SMB_STAT_TIMER             0x15C4  /* 2us resolution */
+#define SMB_STAT_TIMER_MASK            0xFFFFFF
+#define REG_CMB_TPD_THRESH             0x15C8
+#define CMB_TPD_THRESH_MASK            0xFFFF
+#define REG_CMB_TX_TIMER               0x15CC  /* 2us resolution */
+#define CMB_TX_TIMER_MASK              0xFFFF
+
+/* Mail box */
+#define MB_RFDX_PROD_IDX_MASK          0xFFFF
+#define REG_MB_RFD0_PROD_IDX           0x15E0
+#define REG_MB_RFD1_PROD_IDX           0x15E4
+#define REG_MB_RFD2_PROD_IDX           0x15E8
+#define REG_MB_RFD3_PROD_IDX           0x15EC
+
+#define MB_PRIO_PROD_IDX_MASK          0xFFFF
+#define REG_MB_PRIO_PROD_IDX           0x15F0
+#define MB_HTPD_PROD_IDX_SHIFT         0
+#define MB_NTPD_PROD_IDX_SHIFT         16
+
+#define MB_PRIO_CONS_IDX_MASK          0xFFFF
+#define REG_MB_PRIO_CONS_IDX           0x15F4
+#define MB_HTPD_CONS_IDX_SHIFT         0
+#define MB_NTPD_CONS_IDX_SHIFT         16
+
+#define REG_MB_RFD01_CONS_IDX          0x15F8
+#define MB_RFD0_CONS_IDX_MASK          0x0000FFFF
+#define MB_RFD1_CONS_IDX_MASK          0xFFFF0000
+#define REG_MB_RFD23_CONS_IDX          0x15FC
+#define MB_RFD2_CONS_IDX_MASK          0x0000FFFF
+#define MB_RFD3_CONS_IDX_MASK          0xFFFF0000
+
+/* Interrupt Status Register */
+#define REG_ISR                        0x1600
+#define ISR_SMB                                0x00000001
+#define ISR_TIMER                      0x00000002
+/*
+ * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
+ * in Table 51 Selene Master Control Register (Offset 0x1400).
+ */
+#define ISR_MANUAL                     0x00000004
+#define ISR_HW_RXF_OV                          0x00000008 /* RXF overflow interrupt */
+#define ISR_RFD0_UR                    0x00000010 /* RFD0 under run */
+#define ISR_RFD1_UR                    0x00000020
+#define ISR_RFD2_UR                    0x00000040
+#define ISR_RFD3_UR                    0x00000080
+#define ISR_TXF_UR                     0x00000100
+#define ISR_DMAR_TO_RST                        0x00000200
+#define ISR_DMAW_TO_RST                        0x00000400
+#define ISR_TX_CREDIT                  0x00000800
+#define ISR_GPHY                       0x00001000
+/* GPHY low power state interrupt */
+#define ISR_GPHY_LPW                           0x00002000
+#define ISR_TXQ_TO_RST                 0x00004000
+#define ISR_TX_PKT                     0x00008000
+#define ISR_RX_PKT_0                   0x00010000
+#define ISR_RX_PKT_1                   0x00020000
+#define ISR_RX_PKT_2                   0x00040000
+#define ISR_RX_PKT_3                   0x00080000
+#define ISR_MAC_RX                     0x00100000
+#define ISR_MAC_TX                     0x00200000
+#define ISR_UR_DETECTED                        0x00400000
+#define ISR_FERR_DETECTED              0x00800000
+#define ISR_NFERR_DETECTED             0x01000000
+#define ISR_CERR_DETECTED              0x02000000
+#define ISR_PHY_LINKDOWN               0x04000000
+#define ISR_DIS_INT                    0x80000000
+
+/* Interrupt Mask Register */
+#define REG_IMR                                0x1604
+
+#define IMR_NORMAL_MASK                (\
+               ISR_MANUAL      |\
+               ISR_HW_RXF_OV   |\
+               ISR_RFD0_UR     |\
+               ISR_TXF_UR      |\
+               ISR_DMAR_TO_RST |\
+               ISR_TXQ_TO_RST  |\
+               ISR_DMAW_TO_RST |\
+               ISR_GPHY        |\
+               ISR_TX_PKT      |\
+               ISR_RX_PKT_0    |\
+               ISR_GPHY_LPW    |\
+               ISR_PHY_LINKDOWN)
+
+#define ISR_RX_PKT     (\
+       ISR_RX_PKT_0    |\
+       ISR_RX_PKT_1    |\
+       ISR_RX_PKT_2    |\
+       ISR_RX_PKT_3)
+
+#define ISR_OVER       (\
+       ISR_RFD0_UR     |\
+       ISR_RFD1_UR     |\
+       ISR_RFD2_UR     |\
+       ISR_RFD3_UR     |\
+       ISR_HW_RXF_OV   |\
+       ISR_TXF_UR)
+
+#define ISR_ERROR      (\
+       ISR_DMAR_TO_RST |\
+       ISR_TXQ_TO_RST  |\
+       ISR_DMAW_TO_RST |\
+       ISR_PHY_LINKDOWN)
+
+#define REG_INT_RETRIG_TIMER           0x1608
+#define INT_RETRIG_TIMER_MASK          0xFFFF
+
+#define REG_HDS_CTRL                   0x160C
+#define HDS_CTRL_EN                    0x0001
+#define HDS_CTRL_BACKFILLSIZE_SHIFT    8
+#define HDS_CTRL_BACKFILLSIZE_MASK     0x0FFF
+#define HDS_CTRL_MAX_HDRSIZE_SHIFT     20
+#define HDS_CTRL_MAC_HDRSIZE_MASK      0x0FFF
+
+#define REG_MAC_RX_STATUS_BIN          0x1700
+#define REG_MAC_RX_STATUS_END          0x175c
+#define REG_MAC_TX_STATUS_BIN          0x1760
+#define REG_MAC_TX_STATUS_END          0x17c0
+
+#define REG_CLK_GATING_CTRL            0x1814
+#define CLK_GATING_DMAW_EN             0x0001
+#define CLK_GATING_DMAR_EN             0x0002
+#define CLK_GATING_TXQ_EN              0x0004
+#define CLK_GATING_RXQ_EN              0x0008
+#define CLK_GATING_TXMAC_EN            0x0010
+#define CLK_GATING_RXMAC_EN            0x0020
+
+#define CLK_GATING_EN_ALL      (CLK_GATING_DMAW_EN |\
+                                CLK_GATING_DMAR_EN |\
+                                CLK_GATING_TXQ_EN  |\
+                                CLK_GATING_RXQ_EN  |\
+                                CLK_GATING_TXMAC_EN|\
+                                CLK_GATING_RXMAC_EN)
+
+/* DEBUG ADDR */
+#define REG_DEBUG_DATA0                0x1900
+#define REG_DEBUG_DATA1                0x1904
+
+#define L1D_MPW_PHYID1                 0xD01C  /* V7 */
+#define L1D_MPW_PHYID2                 0xD01D  /* V1-V6 */
+#define L1D_MPW_PHYID3                 0xD01E  /* V8 */
+
+
+/* Autoneg Advertisement Register */
+#define ADVERTISE_DEFAULT_CAP \
+       (ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)
+
+/* 1000BASE-T Control Register */
+#define GIGA_CR_1000T_REPEATER_DTE     0x0400  /* 1=Repeater/switch device port 0=DTE device */
+
+#define GIGA_CR_1000T_MS_VALUE         0x0800  /* 1=Configure PHY as Master 0=Configure PHY as Slave */
+#define GIGA_CR_1000T_MS_ENABLE                0x1000  /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
+#define GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000  /* Normal Operation */
+#define GIGA_CR_1000T_TEST_MODE_1      0x2000  /* Transmit Waveform test */
+#define GIGA_CR_1000T_TEST_MODE_2      0x4000  /* Master Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_3      0x6000  /* Slave Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_4      0x8000  /* Transmitter Distortion test */
+#define GIGA_CR_1000T_SPEED_MASK       0x0300
+#define GIGA_CR_1000T_DEFAULT_CAP      0x0300
+
+/* PHY Specific Status Register */
+#define MII_GIGA_PSSR                  0x11
+#define GIGA_PSSR_SPD_DPLX_RESOLVED    0x0800  /* 1=Speed & Duplex resolved */
+#define GIGA_PSSR_DPLX                 0x2000  /* 1=Duplex 0=Half Duplex */
+#define GIGA_PSSR_SPEED                        0xC000  /* Speed, bits 14:15 */
+#define GIGA_PSSR_10MBS                        0x0000  /* 00=10Mbs */
+#define GIGA_PSSR_100MBS               0x4000  /* 01=100Mbs */
+#define GIGA_PSSR_1000MBS              0x8000  /* 10=1000Mbs */
+
+/* PHY Interrupt Enable Register */
+#define MII_IER                                0x12
+#define IER_LINK_UP                    0x0400
+#define IER_LINK_DOWN                  0x0800
+
+/* PHY Interrupt Status Register */
+#define MII_ISR                                0x13
+#define ISR_LINK_UP                    0x0400
+#define ISR_LINK_DOWN                  0x0800
+
+/* Cable-Detect-Test Control Register */
+#define MII_CDTC                       0x16
+#define CDTC_EN_OFF                    0   /* sc */
+#define CDTC_EN_BITS                   1
+#define CDTC_PAIR_OFF                  8
+#define CDTC_PAIR_BIT                  2
+
+/* Cable-Detect-Test Status Register */
+#define MII_CDTS                       0x1C
+#define CDTS_STATUS_OFF                        8
+#define CDTS_STATUS_BITS               2
+#define CDTS_STATUS_NORMAL             0
+#define CDTS_STATUS_SHORT              1
+#define CDTS_STATUS_OPEN               2
+#define CDTS_STATUS_INVALID            3
+
+#define MII_DBG_ADDR                   0x1D
+#define MII_DBG_DATA                   0x1E
+
+#define MII_ANA_CTRL_0                 0x0
+#define ANA_RESTART_CAL                        0x0001
+#define ANA_MANUL_SWICH_ON_SHIFT       0x1
+#define ANA_MANUL_SWICH_ON_MASK                0xF
+#define ANA_MAN_ENABLE                 0x0020
+#define ANA_SEL_HSP                    0x0040
+#define ANA_EN_HB                      0x0080
+#define ANA_EN_HBIAS                   0x0100
+#define ANA_OEN_125M                   0x0200
+#define ANA_EN_LCKDT                   0x0400
+#define ANA_LCKDT_PHY                  0x0800
+#define ANA_AFE_MODE                   0x1000
+#define ANA_VCO_SLOW                   0x2000
+#define ANA_VCO_FAST                   0x4000
+#define ANA_SEL_CLK125M_DSP            0x8000
+
+#define MII_ANA_CTRL_4                 0x4
+#define ANA_IECHO_ADJ_MASK             0xF
+#define ANA_IECHO_ADJ_3_SHIFT          0
+#define ANA_IECHO_ADJ_2_SHIFT          4
+#define ANA_IECHO_ADJ_1_SHIFT          8
+#define ANA_IECHO_ADJ_0_SHIFT          12
+
+#define MII_ANA_CTRL_5                 0x5
+#define ANA_SERDES_CDR_BW_SHIFT                0
+#define ANA_SERDES_CDR_BW_MASK         0x3
+#define ANA_MS_PAD_DBG                 0x0004
+#define ANA_SPEEDUP_DBG                        0x0008
+#define ANA_SERDES_TH_LOS_SHIFT                4
+#define ANA_SERDES_TH_LOS_MASK         0x3
+#define ANA_SERDES_EN_DEEM             0x0040
+#define ANA_SERDES_TXELECIDLE          0x0080
+#define ANA_SERDES_BEACON              0x0100
+#define ANA_SERDES_HALFTXDR            0x0200
+#define ANA_SERDES_SEL_HSP             0x0400
+#define ANA_SERDES_EN_PLL              0x0800
+#define ANA_SERDES_EN                  0x1000
+#define ANA_SERDES_EN_LCKDT            0x2000
+
+#define MII_ANA_CTRL_11                        0xB
+#define ANA_PS_HIB_EN                  0x8000
+
+#define MII_ANA_CTRL_18                        0x12
+#define ANA_TEST_MODE_10BT_01SHIFT     0
+#define ANA_TEST_MODE_10BT_01MASK      0x3
+#define ANA_LOOP_SEL_10BT              0x0004
+#define ANA_RGMII_MODE_SW              0x0008
+#define ANA_EN_LONGECABLE              0x0010
+#define ANA_TEST_MODE_10BT_2           0x0020
+#define ANA_EN_10BT_IDLE               0x0400
+#define ANA_EN_MASK_TB                 0x0800
+#define ANA_TRIGGER_SEL_TIMER_SHIFT    12
+#define ANA_TRIGGER_SEL_TIMER_MASK     0x3
+#define ANA_INTERVAL_SEL_TIMER_SHIFT   14
+#define ANA_INTERVAL_SEL_TIMER_MASK    0x3
+
+#define MII_ANA_CTRL_41                        0x29
+#define ANA_TOP_PS_EN                  0x8000
+
+#define MII_ANA_CTRL_54                        0x36
+#define ANA_LONG_CABLE_TH_100_SHIFT    0
+#define ANA_LONG_CABLE_TH_100_MASK     0x3F
+#define ANA_DESERVED                   0x0040
+#define ANA_EN_LIT_CH                  0x0080
+#define ANA_SHORT_CABLE_TH_100_SHIFT   8
+#define ANA_SHORT_CABLE_TH_100_MASK    0x3F
+#define ANA_BP_BAD_LINK_ACCUM          0x4000
+#define ANA_BP_SMALL_BW                        0x8000
+
+#endif /*_ATL1C_HW_H_*/
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
new file mode 100644 (file)
index 0000000..9722442
--- /dev/null
@@ -0,0 +1,2934 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#include "atl1c.h"
+
+#define ATL1C_DRV_VERSION "1.0.1.0-NAPI"
+char atl1c_driver_name[] = "atl1c";
+char atl1c_driver_version[] = ATL1C_DRV_VERSION;
+#define PCI_DEVICE_ID_ATTANSIC_L2C      0x1062
+#define PCI_DEVICE_ID_ATTANSIC_L1C      0x1063
+#define PCI_DEVICE_ID_ATHEROS_L2C_B    0x2060 /* AR8152 v1.1 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L2C_B2   0x2062 /* AR8152 v2.0 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L1D      0x1073 /* AR8151 v1.0 Gigabit 1000 */
+#define PCI_DEVICE_ID_ATHEROS_L1D_2_0  0x1083 /* AR8151 v2.0 Gigabit 1000 */
+#define L2CB_V10                       0xc0
+#define L2CB_V11                       0xc1
+
+/*
+ * atl1c_pci_tbl - PCI Device ID Table
+ *
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ *   Class, Class Mask, private data (not used) }
+ */
+static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = {
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)},
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)},
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)},
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)},
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)},
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D_2_0)},
+       /* required last entry */
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl);
+
+MODULE_AUTHOR("Jie Yang <jie.yang@atheros.com>");
+MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATL1C_DRV_VERSION);
+
+static int atl1c_stop_mac(struct atl1c_hw *hw);
+static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw);
+static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw);
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw);
+static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup);
+static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter);
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
+                  int *work_done, int work_to_do);
+static int atl1c_up(struct atl1c_adapter *adapter);
+static void atl1c_down(struct atl1c_adapter *adapter);
+
+static const u16 atl1c_pay_load_size[] = {
+       128, 256, 512, 1024, 2048, 4096,
+};
+
+static const u16 atl1c_rfd_prod_idx_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+       REG_MB_RFD0_PROD_IDX,
+       REG_MB_RFD1_PROD_IDX,
+       REG_MB_RFD2_PROD_IDX,
+       REG_MB_RFD3_PROD_IDX
+};
+
+static const u16 atl1c_rfd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+       REG_RFD0_HEAD_ADDR_LO,
+       REG_RFD1_HEAD_ADDR_LO,
+       REG_RFD2_HEAD_ADDR_LO,
+       REG_RFD3_HEAD_ADDR_LO
+};
+
+static const u16 atl1c_rrd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+       REG_RRD0_HEAD_ADDR_LO,
+       REG_RRD1_HEAD_ADDR_LO,
+       REG_RRD2_HEAD_ADDR_LO,
+       REG_RRD3_HEAD_ADDR_LO
+};
+
+static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
+       NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
+static void atl1c_pcie_patch(struct atl1c_hw *hw)
+{
+       u32 data;
+
+       AT_READ_REG(hw, REG_PCIE_PHYMISC, &data);
+       data |= PCIE_PHYMISC_FORCE_RCV_DET;
+       AT_WRITE_REG(hw, REG_PCIE_PHYMISC, data);
+
+       if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V10) {
+               AT_READ_REG(hw, REG_PCIE_PHYMISC2, &data);
+
+               data &= ~(PCIE_PHYMISC2_SERDES_CDR_MASK <<
+                       PCIE_PHYMISC2_SERDES_CDR_SHIFT);
+               data |= 3 << PCIE_PHYMISC2_SERDES_CDR_SHIFT;
+               data &= ~(PCIE_PHYMISC2_SERDES_TH_MASK <<
+                       PCIE_PHYMISC2_SERDES_TH_SHIFT);
+               data |= 3 << PCIE_PHYMISC2_SERDES_TH_SHIFT;
+               AT_WRITE_REG(hw, REG_PCIE_PHYMISC2, data);
+       }
+}
+
+/* FIXME: no need any more ? */
+/*
+ * atl1c_init_pcie - init PCIE module
+ */
+static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
+{
+       u32 data;
+       u32 pci_cmd;
+       struct pci_dev *pdev = hw->adapter->pdev;
+
+       AT_READ_REG(hw, PCI_COMMAND, &pci_cmd);
+       pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+       pci_cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+               PCI_COMMAND_IO);
+       AT_WRITE_REG(hw, PCI_COMMAND, pci_cmd);
+
+       /*
+        * Clear any PowerSaveing Settings
+        */
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       /*
+        * Mask some pcie error bits
+        */
+       AT_READ_REG(hw, REG_PCIE_UC_SEVERITY, &data);
+       data &= ~PCIE_UC_SERVRITY_DLP;
+       data &= ~PCIE_UC_SERVRITY_FCP;
+       AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data);
+
+       AT_READ_REG(hw, REG_LTSSM_ID_CTRL, &data);
+       data &= ~LTSSM_ID_EN_WRO;
+       AT_WRITE_REG(hw, REG_LTSSM_ID_CTRL, data);
+
+       atl1c_pcie_patch(hw);
+       if (flag & ATL1C_PCIE_L0S_L1_DISABLE)
+               atl1c_disable_l0s_l1(hw);
+       if (flag & ATL1C_PCIE_PHY_RESET)
+               AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
+       else
+               AT_WRITE_REG(hw, REG_GPHY_CTRL,
+                       GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET);
+
+       msleep(5);
+}
+
+/*
+ * atl1c_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_enable(struct atl1c_adapter *adapter)
+{
+       if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
+               AT_WRITE_REG(&adapter->hw, REG_ISR, 0x7FFFFFFF);
+               AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+               AT_WRITE_FLUSH(&adapter->hw);
+       }
+}
+
+/*
+ * atl1c_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_disable(struct atl1c_adapter *adapter)
+{
+       atomic_inc(&adapter->irq_sem);
+       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+       AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT);
+       AT_WRITE_FLUSH(&adapter->hw);
+       synchronize_irq(adapter->pdev->irq);
+}
+
+/*
+ * atl1c_irq_reset - reset interrupt confiure on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
+{
+       atomic_set(&adapter->irq_sem, 1);
+       atl1c_irq_enable(adapter);
+}
+
+/*
+ * atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
+ * of the idle status register until the device is actually idle
+ */
+static u32 atl1c_wait_until_idle(struct atl1c_hw *hw)
+{
+       int timeout;
+       u32 data;
+
+       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+               AT_READ_REG(hw, REG_IDLE_STATUS, &data);
+               if ((data & IDLE_STATUS_MASK) == 0)
+                       return 0;
+               msleep(1);
+       }
+       return data;
+}
+
+/*
+ * atl1c_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1c_phy_config(unsigned long data)
+{
+       struct atl1c_adapter *adapter = (struct atl1c_adapter *) data;
+       struct atl1c_hw *hw = &adapter->hw;
+       unsigned long flags;
+
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       atl1c_restart_autoneg(hw);
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+void atl1c_reinit_locked(struct atl1c_adapter *adapter)
+{
+       WARN_ON(in_interrupt());
+       atl1c_down(adapter);
+       atl1c_up(adapter);
+       clear_bit(__AT_RESETTING, &adapter->flags);
+}
+
+static void atl1c_check_link_status(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev    *pdev   = adapter->pdev;
+       int err;
+       unsigned long flags;
+       u16 speed, duplex, phy_data;
+
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       /* MII_BMSR must read twise */
+       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+       atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+
+       if ((phy_data & BMSR_LSTATUS) == 0) {
+               /* link down */
+               hw->hibernate = true;
+               if (atl1c_stop_mac(hw) != 0)
+                       if (netif_msg_hw(adapter))
+                               dev_warn(&pdev->dev, "stop mac failed\n");
+               atl1c_set_aspm(hw, false);
+               netif_carrier_off(netdev);
+               netif_stop_queue(netdev);
+               atl1c_phy_reset(hw);
+               atl1c_phy_init(&adapter->hw);
+       } else {
+               /* Link Up */
+               hw->hibernate = false;
+               spin_lock_irqsave(&adapter->mdio_lock, flags);
+               err = atl1c_get_speed_and_duplex(hw, &speed, &duplex);
+               spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+               if (unlikely(err))
+                       return;
+               /* link result is our setting */
+               if (adapter->link_speed != speed ||
+                   adapter->link_duplex != duplex) {
+                       adapter->link_speed  = speed;
+                       adapter->link_duplex = duplex;
+                       atl1c_set_aspm(hw, true);
+                       atl1c_enable_tx_ctrl(hw);
+                       atl1c_enable_rx_ctrl(hw);
+                       atl1c_setup_mac_ctrl(adapter);
+                       if (netif_msg_link(adapter))
+                               dev_info(&pdev->dev,
+                                       "%s: %s NIC Link is Up<%d Mbps %s>\n",
+                                       atl1c_driver_name, netdev->name,
+                                       adapter->link_speed,
+                                       adapter->link_duplex == FULL_DUPLEX ?
+                                       "Full Duplex" : "Half Duplex");
+               }
+               if (!netif_carrier_ok(netdev))
+                       netif_carrier_on(netdev);
+       }
+}
+
+static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev    *pdev   = adapter->pdev;
+       u16 phy_data;
+       u16 link_up;
+
+       spin_lock(&adapter->mdio_lock);
+       atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       spin_unlock(&adapter->mdio_lock);
+       link_up = phy_data & BMSR_LSTATUS;
+       /* notify upper layer link down ASAP */
+       if (!link_up) {
+               if (netif_carrier_ok(netdev)) {
+                       /* old link state: Up */
+                       netif_carrier_off(netdev);
+                       if (netif_msg_link(adapter))
+                               dev_info(&pdev->dev,
+                                       "%s: %s NIC Link is Down\n",
+                                       atl1c_driver_name, netdev->name);
+                       adapter->link_speed = SPEED_0;
+               }
+       }
+
+       set_bit(ATL1C_WORK_EVENT_LINK_CHANGE, &adapter->work_event);
+       schedule_work(&adapter->common_task);
+}
+
+static void atl1c_common_task(struct work_struct *work)
+{
+       struct atl1c_adapter *adapter;
+       struct net_device *netdev;
+
+       adapter = container_of(work, struct atl1c_adapter, common_task);
+       netdev = adapter->netdev;
+
+       if (test_and_clear_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event)) {
+               netif_device_detach(netdev);
+               atl1c_down(adapter);
+               atl1c_up(adapter);
+               netif_device_attach(netdev);
+       }
+
+       if (test_and_clear_bit(ATL1C_WORK_EVENT_LINK_CHANGE,
+               &adapter->work_event))
+               atl1c_check_link_status(adapter);
+}
+
+
+static void atl1c_del_timer(struct atl1c_adapter *adapter)
+{
+       del_timer_sync(&adapter->phy_config_timer);
+}
+
+
+/*
+ * atl1c_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl1c_tx_timeout(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       /* Do the reset outside of interrupt context */
+       set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event);
+       schedule_work(&adapter->common_task);
+}
+
+/*
+ * atl1c_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 atl1c_set_multi(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct atl1c_hw *hw = &adapter->hw;
+       struct netdev_hw_addr *ha;
+       u32 mac_ctrl_data;
+       u32 hash_value;
+
+       /* Check for Promiscuous and All Multicast modes */
+       AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
+
+       if (netdev->flags & IFF_PROMISC) {
+               mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+       } else if (netdev->flags & IFF_ALLMULTI) {
+               mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+               mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
+       } else {
+               mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+       }
+
+       AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+       /* clear the old settings from the multicast hash table */
+       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+       /* comoute mc addresses' hash value ,and put it into hash table */
+       netdev_for_each_mc_addr(ha, netdev) {
+               hash_value = atl1c_hash_mc_addr(hw, ha->addr);
+               atl1c_hash_set(hw, hash_value);
+       }
+}
+
+static void __atl1c_vlan_mode(u32 features, u32 *mac_ctrl_data)
+{
+       if (features & NETIF_F_HW_VLAN_RX) {
+               /* enable VLAN tag insert/strip */
+               *mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+       } else {
+               /* disable VLAN tag insert/strip */
+               *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
+       }
+}
+
+static void atl1c_vlan_mode(struct net_device *netdev, u32 features)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = adapter->pdev;
+       u32 mac_ctrl_data = 0;
+
+       if (netif_msg_pktdata(adapter))
+               dev_dbg(&pdev->dev, "atl1c_vlan_mode\n");
+
+       atl1c_irq_disable(adapter);
+       AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data);
+       __atl1c_vlan_mode(features, &mac_ctrl_data);
+       AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
+       atl1c_irq_enable(adapter);
+}
+
+static void atl1c_restore_vlan(struct atl1c_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       if (netif_msg_pktdata(adapter))
+               dev_dbg(&pdev->dev, "atl1c_restore_vlan\n");
+       atl1c_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+/*
+ * atl1c_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 atl1c_set_mac_addr(struct net_device *netdev, void *p)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       if (netif_running(netdev))
+               return -EBUSY;
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+       atl1c_hw_set_mac_addr(&adapter->hw);
+
+       return 0;
+}
+
+static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
+                               struct net_device *dev)
+{
+       int mtu = dev->mtu;
+
+       adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
+               roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
+}
+
+static u32 atl1c_fix_features(struct net_device *netdev, u32 features)
+{
+       /*
+        * Since there is no support for separate rx/tx vlan accel
+        * enable/disable make sure tx flag is always in same state as rx.
+        */
+       if (features & NETIF_F_HW_VLAN_RX)
+               features |= NETIF_F_HW_VLAN_TX;
+       else
+               features &= ~NETIF_F_HW_VLAN_TX;
+
+       if (netdev->mtu > MAX_TSO_FRAME_SIZE)
+               features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+       return features;
+}
+
+static int atl1c_set_features(struct net_device *netdev, u32 features)
+{
+       u32 changed = netdev->features ^ features;
+
+       if (changed & NETIF_F_HW_VLAN_RX)
+               atl1c_vlan_mode(netdev, features);
+
+       return 0;
+}
+
+/*
+ * atl1c_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       int old_mtu   = netdev->mtu;
+       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+                       (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+               if (netif_msg_link(adapter))
+                       dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+               return -EINVAL;
+       }
+       /* set MTU */
+       if (old_mtu != new_mtu && netif_running(netdev)) {
+               while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+                       msleep(1);
+               netdev->mtu = new_mtu;
+               adapter->hw.max_frame_size = new_mtu;
+               atl1c_set_rxbufsize(adapter, netdev);
+               atl1c_down(adapter);
+               netdev_update_features(netdev);
+               atl1c_up(adapter);
+               clear_bit(__AT_RESETTING, &adapter->flags);
+               if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
+                       u32 phy_data;
+
+                       AT_READ_REG(&adapter->hw, 0x1414, &phy_data);
+                       phy_data |= 0x10000000;
+                       AT_WRITE_REG(&adapter->hw, 0x1414, phy_data);
+               }
+
+       }
+       return 0;
+}
+
+/*
+ *  caller should hold mdio_lock
+ */
+static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       u16 result;
+
+       atl1c_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
+       return result;
+}
+
+static void atl1c_mdio_write(struct net_device *netdev, int phy_id,
+                            int reg_num, int val)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       atl1c_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
+}
+
+/*
+ * atl1c_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1c_mii_ioctl(struct net_device *netdev,
+                          struct ifreq *ifr, int cmd)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = adapter->pdev;
+       struct mii_ioctl_data *data = if_mii(ifr);
+       unsigned long flags;
+       int retval = 0;
+
+       if (!netif_running(netdev))
+               return -EINVAL;
+
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = 0;
+               break;
+
+       case SIOCGMIIREG:
+               if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+                                   &data->val_out)) {
+                       retval = -EIO;
+                       goto out;
+               }
+               break;
+
+       case SIOCSMIIREG:
+               if (data->reg_num & ~(0x1F)) {
+                       retval = -EFAULT;
+                       goto out;
+               }
+
+               dev_dbg(&pdev->dev, "<atl1c_mii_ioctl> write %x %x",
+                               data->reg_num, data->val_in);
+               if (atl1c_write_phy_reg(&adapter->hw,
+                                    data->reg_num, data->val_in)) {
+                       retval = -EIO;
+                       goto out;
+               }
+               break;
+
+       default:
+               retval = -EOPNOTSUPP;
+               break;
+       }
+out:
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+       return retval;
+}
+
+/*
+ * atl1c_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1c_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       switch (cmd) {
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               return atl1c_mii_ioctl(netdev, ifr, cmd);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+/*
+ * atl1c_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ */
+static int __devinit atl1c_alloc_queues(struct atl1c_adapter *adapter)
+{
+       return 0;
+}
+
+static void atl1c_set_mac_type(struct atl1c_hw *hw)
+{
+       switch (hw->device_id) {
+       case PCI_DEVICE_ID_ATTANSIC_L2C:
+               hw->nic_type = athr_l2c;
+               break;
+       case PCI_DEVICE_ID_ATTANSIC_L1C:
+               hw->nic_type = athr_l1c;
+               break;
+       case PCI_DEVICE_ID_ATHEROS_L2C_B:
+               hw->nic_type = athr_l2c_b;
+               break;
+       case PCI_DEVICE_ID_ATHEROS_L2C_B2:
+               hw->nic_type = athr_l2c_b2;
+               break;
+       case PCI_DEVICE_ID_ATHEROS_L1D:
+               hw->nic_type = athr_l1d;
+               break;
+       case PCI_DEVICE_ID_ATHEROS_L1D_2_0:
+               hw->nic_type = athr_l1d_2;
+               break;
+       default:
+               break;
+       }
+}
+
+static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
+{
+       u32 phy_status_data;
+       u32 link_ctrl_data;
+
+       atl1c_set_mac_type(hw);
+       AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data);
+       AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
+
+       hw->ctrl_flags = ATL1C_INTR_MODRT_ENABLE  |
+                        ATL1C_TXQ_MODE_ENHANCE;
+       if (link_ctrl_data & LINK_CTRL_L0S_EN)
+               hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT;
+       if (link_ctrl_data & LINK_CTRL_L1_EN)
+               hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT;
+       if (link_ctrl_data & LINK_CTRL_EXT_SYNC)
+               hw->ctrl_flags |= ATL1C_LINK_EXT_SYNC;
+       hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON;
+
+       if (hw->nic_type == athr_l1c ||
+           hw->nic_type == athr_l1d ||
+           hw->nic_type == athr_l1d_2)
+               hw->link_cap_flags |= ATL1C_LINK_CAP_1000M;
+       return 0;
+}
+/*
+ * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl1c_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 __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw   = &adapter->hw;
+       struct pci_dev  *pdev = adapter->pdev;
+       u32 revision;
+
+
+       adapter->wol = 0;
+       device_set_wakeup_enable(&pdev->dev, false);
+       adapter->link_speed = SPEED_0;
+       adapter->link_duplex = FULL_DUPLEX;
+       adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE;
+       adapter->tpd_ring[0].count = 1024;
+       adapter->rfd_ring[0].count = 512;
+
+       hw->vendor_id = pdev->vendor;
+       hw->device_id = pdev->device;
+       hw->subsystem_vendor_id = pdev->subsystem_vendor;
+       hw->subsystem_id = pdev->subsystem_device;
+       AT_READ_REG(hw, PCI_CLASS_REVISION, &revision);
+       hw->revision_id = revision & 0xFF;
+       /* before link up, we assume hibernate is true */
+       hw->hibernate = true;
+       hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
+       if (atl1c_setup_mac_funcs(hw) != 0) {
+               dev_err(&pdev->dev, "set mac function pointers failed\n");
+               return -1;
+       }
+       hw->intr_mask = IMR_NORMAL_MASK;
+       hw->phy_configured = false;
+       hw->preamble_len = 7;
+       hw->max_frame_size = adapter->netdev->mtu;
+       if (adapter->num_rx_queues < 2) {
+               hw->rss_type = atl1c_rss_disable;
+               hw->rss_mode = atl1c_rss_mode_disable;
+       } else {
+               hw->rss_type = atl1c_rss_ipv4;
+               hw->rss_mode = atl1c_rss_mul_que_mul_int;
+               hw->rss_hash_bits = 16;
+       }
+       hw->autoneg_advertised = ADVERTISED_Autoneg;
+       hw->indirect_tab = 0xE4E4E4E4;
+       hw->base_cpu = 0;
+
+       hw->ict = 50000;                /* 100ms */
+       hw->smb_timer = 200000;         /* 400ms */
+       hw->cmb_tpd = 4;
+       hw->cmb_tx_timer = 1;           /* 2 us  */
+       hw->rx_imt = 200;
+       hw->tx_imt = 1000;
+
+       hw->tpd_burst = 5;
+       hw->rfd_burst = 8;
+       hw->dma_order = atl1c_dma_ord_out;
+       hw->dmar_block = atl1c_dma_req_1024;
+       hw->dmaw_block = atl1c_dma_req_1024;
+       hw->dmar_dly_cnt = 15;
+       hw->dmaw_dly_cnt = 4;
+
+       if (atl1c_alloc_queues(adapter)) {
+               dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+               return -ENOMEM;
+       }
+       /* TODO */
+       atl1c_set_rxbufsize(adapter, adapter->netdev);
+       atomic_set(&adapter->irq_sem, 1);
+       spin_lock_init(&adapter->mdio_lock);
+       spin_lock_init(&adapter->tx_lock);
+       set_bit(__AT_DOWN, &adapter->flags);
+
+       return 0;
+}
+
+static inline void atl1c_clean_buffer(struct pci_dev *pdev,
+                               struct atl1c_buffer *buffer_info, int in_irq)
+{
+       u16 pci_driection;
+       if (buffer_info->flags & ATL1C_BUFFER_FREE)
+               return;
+       if (buffer_info->dma) {
+               if (buffer_info->flags & ATL1C_PCIMAP_FROMDEVICE)
+                       pci_driection = PCI_DMA_FROMDEVICE;
+               else
+                       pci_driection = PCI_DMA_TODEVICE;
+
+               if (buffer_info->flags & ATL1C_PCIMAP_SINGLE)
+                       pci_unmap_single(pdev, buffer_info->dma,
+                                       buffer_info->length, pci_driection);
+               else if (buffer_info->flags & ATL1C_PCIMAP_PAGE)
+                       pci_unmap_page(pdev, buffer_info->dma,
+                                       buffer_info->length, pci_driection);
+       }
+       if (buffer_info->skb) {
+               if (in_irq)
+                       dev_kfree_skb_irq(buffer_info->skb);
+               else
+                       dev_kfree_skb(buffer_info->skb);
+       }
+       buffer_info->dma = 0;
+       buffer_info->skb = NULL;
+       ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
+}
+/*
+ * atl1c_clean_tx_ring - Free Tx-skb
+ * @adapter: board private structure
+ */
+static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
+                               enum atl1c_trans_queue type)
+{
+       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+       struct atl1c_buffer *buffer_info;
+       struct pci_dev *pdev = adapter->pdev;
+       u16 index, ring_count;
+
+       ring_count = tpd_ring->count;
+       for (index = 0; index < ring_count; index++) {
+               buffer_info = &tpd_ring->buffer_info[index];
+               atl1c_clean_buffer(pdev, buffer_info, 0);
+       }
+
+       /* Zero out Tx-buffers */
+       memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
+               ring_count);
+       atomic_set(&tpd_ring->next_to_clean, 0);
+       tpd_ring->next_to_use = 0;
+}
+
+/*
+ * atl1c_clean_rx_ring - Free rx-reservation skbs
+ * @adapter: board private structure
+ */
+static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
+{
+       struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+       struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+       struct atl1c_buffer *buffer_info;
+       struct pci_dev *pdev = adapter->pdev;
+       int i, j;
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < rfd_ring[i].count; j++) {
+                       buffer_info = &rfd_ring[i].buffer_info[j];
+                       atl1c_clean_buffer(pdev, buffer_info, 0);
+               }
+               /* zero out the descriptor ring */
+               memset(rfd_ring[i].desc, 0, rfd_ring[i].size);
+               rfd_ring[i].next_to_clean = 0;
+               rfd_ring[i].next_to_use = 0;
+               rrd_ring[i].next_to_use = 0;
+               rrd_ring[i].next_to_clean = 0;
+       }
+}
+
+/*
+ * Read / Write Ptr Initialize:
+ */
+static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
+{
+       struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+       struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+       struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+       struct atl1c_buffer *buffer_info;
+       int i, j;
+
+       for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+               tpd_ring[i].next_to_use = 0;
+               atomic_set(&tpd_ring[i].next_to_clean, 0);
+               buffer_info = tpd_ring[i].buffer_info;
+               for (j = 0; j < tpd_ring->count; j++)
+                       ATL1C_SET_BUFFER_STATE(&buffer_info[i],
+                                       ATL1C_BUFFER_FREE);
+       }
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               rfd_ring[i].next_to_use = 0;
+               rfd_ring[i].next_to_clean = 0;
+               rrd_ring[i].next_to_use = 0;
+               rrd_ring[i].next_to_clean = 0;
+               for (j = 0; j < rfd_ring[i].count; j++) {
+                       buffer_info = &rfd_ring[i].buffer_info[j];
+                       ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
+               }
+       }
+}
+
+/*
+ * atl1c_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl1c_free_ring_resources(struct atl1c_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       pci_free_consistent(pdev, adapter->ring_header.size,
+                                       adapter->ring_header.desc,
+                                       adapter->ring_header.dma);
+       adapter->ring_header.desc = NULL;
+
+       /* Note: just free tdp_ring.buffer_info,
+       *  it contain rfd_ring.buffer_info, do not double free */
+       if (adapter->tpd_ring[0].buffer_info) {
+               kfree(adapter->tpd_ring[0].buffer_info);
+               adapter->tpd_ring[0].buffer_info = NULL;
+       }
+}
+
+/*
+ * atl1c_setup_mem_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+       struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+       struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+       struct atl1c_ring_header *ring_header = &adapter->ring_header;
+       int num_rx_queues = adapter->num_rx_queues;
+       int size;
+       int i;
+       int count = 0;
+       int rx_desc_count = 0;
+       u32 offset = 0;
+
+       rrd_ring[0].count = rfd_ring[0].count;
+       for (i = 1; i < AT_MAX_TRANSMIT_QUEUE; i++)
+               tpd_ring[i].count = tpd_ring[0].count;
+
+       for (i = 1; i < adapter->num_rx_queues; i++)
+               rfd_ring[i].count = rrd_ring[i].count = rfd_ring[0].count;
+
+       /* 2 tpd queue, one high priority queue,
+        * another normal priority queue */
+       size = sizeof(struct atl1c_buffer) * (tpd_ring->count * 2 +
+               rfd_ring->count * num_rx_queues);
+       tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
+       if (unlikely(!tpd_ring->buffer_info)) {
+               dev_err(&pdev->dev, "kzalloc failed, size = %d\n",
+                       size);
+               goto err_nomem;
+       }
+       for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+               tpd_ring[i].buffer_info =
+                       (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
+               count += tpd_ring[i].count;
+       }
+
+       for (i = 0; i < num_rx_queues; i++) {
+               rfd_ring[i].buffer_info =
+                       (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
+               count += rfd_ring[i].count;
+               rx_desc_count += rfd_ring[i].count;
+       }
+       /*
+        * real ring DMA buffer
+        * each ring/block may need up to 8 bytes for alignment, hence the
+        * additional bytes tacked onto the end.
+        */
+       ring_header->size = size =
+               sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 +
+               sizeof(struct atl1c_rx_free_desc) * rx_desc_count +
+               sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
+               sizeof(struct atl1c_hw_stats) +
+               8 * 4 + 8 * 2 * num_rx_queues;
+
+       ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
+                               &ring_header->dma);
+       if (unlikely(!ring_header->desc)) {
+               dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+               goto err_nomem;
+       }
+       memset(ring_header->desc, 0, ring_header->size);
+       /* init TPD ring */
+
+       tpd_ring[0].dma = roundup(ring_header->dma, 8);
+       offset = tpd_ring[0].dma - ring_header->dma;
+       for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+               tpd_ring[i].dma = ring_header->dma + offset;
+               tpd_ring[i].desc = (u8 *) ring_header->desc + offset;
+               tpd_ring[i].size =
+                       sizeof(struct atl1c_tpd_desc) * tpd_ring[i].count;
+               offset += roundup(tpd_ring[i].size, 8);
+       }
+       /* init RFD ring */
+       for (i = 0; i < num_rx_queues; i++) {
+               rfd_ring[i].dma = ring_header->dma + offset;
+               rfd_ring[i].desc = (u8 *) ring_header->desc + offset;
+               rfd_ring[i].size = sizeof(struct atl1c_rx_free_desc) *
+                               rfd_ring[i].count;
+               offset += roundup(rfd_ring[i].size, 8);
+       }
+
+       /* init RRD ring */
+       for (i = 0; i < num_rx_queues; i++) {
+               rrd_ring[i].dma = ring_header->dma + offset;
+               rrd_ring[i].desc = (u8 *) ring_header->desc + offset;
+               rrd_ring[i].size = sizeof(struct atl1c_recv_ret_status) *
+                               rrd_ring[i].count;
+               offset += roundup(rrd_ring[i].size, 8);
+       }
+
+       adapter->smb.dma = ring_header->dma + offset;
+       adapter->smb.smb = (u8 *)ring_header->desc + offset;
+       return 0;
+
+err_nomem:
+       kfree(tpd_ring->buffer_info);
+       return -ENOMEM;
+}
+
+static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+       struct atl1c_rfd_ring *rfd_ring = (struct atl1c_rfd_ring *)
+                               adapter->rfd_ring;
+       struct atl1c_rrd_ring *rrd_ring = (struct atl1c_rrd_ring *)
+                               adapter->rrd_ring;
+       struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
+                               adapter->tpd_ring;
+       struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb;
+       struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb;
+       int i;
+       u32 data;
+
+       /* TPD */
+       AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI,
+                       (u32)((tpd_ring[atl1c_trans_normal].dma &
+                               AT_DMA_HI_ADDR_MASK) >> 32));
+       /* just enable normal priority TX queue */
+       AT_WRITE_REG(hw, REG_NTPD_HEAD_ADDR_LO,
+                       (u32)(tpd_ring[atl1c_trans_normal].dma &
+                               AT_DMA_LO_ADDR_MASK));
+       AT_WRITE_REG(hw, REG_HTPD_HEAD_ADDR_LO,
+                       (u32)(tpd_ring[atl1c_trans_high].dma &
+                               AT_DMA_LO_ADDR_MASK));
+       AT_WRITE_REG(hw, REG_TPD_RING_SIZE,
+                       (u32)(tpd_ring[0].count & TPD_RING_SIZE_MASK));
+
+
+       /* RFD */
+       AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI,
+                       (u32)((rfd_ring[0].dma & AT_DMA_HI_ADDR_MASK) >> 32));
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               AT_WRITE_REG(hw, atl1c_rfd_addr_lo_regs[i],
+                       (u32)(rfd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
+
+       AT_WRITE_REG(hw, REG_RFD_RING_SIZE,
+                       rfd_ring[0].count & RFD_RING_SIZE_MASK);
+       AT_WRITE_REG(hw, REG_RX_BUF_SIZE,
+                       adapter->rx_buffer_len & RX_BUF_SIZE_MASK);
+
+       /* RRD */
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               AT_WRITE_REG(hw, atl1c_rrd_addr_lo_regs[i],
+                       (u32)(rrd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
+       AT_WRITE_REG(hw, REG_RRD_RING_SIZE,
+                       (rrd_ring[0].count & RRD_RING_SIZE_MASK));
+
+       /* CMB */
+       AT_WRITE_REG(hw, REG_CMB_BASE_ADDR_LO, cmb->dma & AT_DMA_LO_ADDR_MASK);
+
+       /* SMB */
+       AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_HI,
+                       (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32));
+       AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO,
+                       (u32)(smb->dma & AT_DMA_LO_ADDR_MASK));
+       if (hw->nic_type == athr_l2c_b) {
+               AT_WRITE_REG(hw, REG_SRAM_RXF_LEN, 0x02a0L);
+               AT_WRITE_REG(hw, REG_SRAM_TXF_LEN, 0x0100L);
+               AT_WRITE_REG(hw, REG_SRAM_RXF_ADDR, 0x029f0000L);
+               AT_WRITE_REG(hw, REG_SRAM_RFD0_INFO, 0x02bf02a0L);
+               AT_WRITE_REG(hw, REG_SRAM_TXF_ADDR, 0x03bf02c0L);
+               AT_WRITE_REG(hw, REG_SRAM_TRD_ADDR, 0x03df03c0L);
+               AT_WRITE_REG(hw, REG_TXF_WATER_MARK, 0);        /* TX watermark, to enter l1 state.*/
+               AT_WRITE_REG(hw, REG_RXD_DMA_CTRL, 0);          /* RXD threshold.*/
+       }
+       if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d_2) {
+                       /* Power Saving for L2c_B */
+               AT_READ_REG(hw, REG_SERDES_LOCK, &data);
+               data |= SERDES_MAC_CLK_SLOWDOWN;
+               data |= SERDES_PYH_CLK_SLOWDOWN;
+               AT_WRITE_REG(hw, REG_SERDES_LOCK, data);
+       }
+       /* Load all of base address above */
+       AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
+}
+
+static void atl1c_configure_tx(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+       u32 dev_ctrl_data;
+       u32 max_pay_load;
+       u16 tx_offload_thresh;
+       u32 txq_ctrl_data;
+       u32 max_pay_load_data;
+
+       tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
+       AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
+               (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
+       AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data);
+       max_pay_load  = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) &
+                       DEVICE_CTRL_MAX_PAYLOAD_MASK;
+       hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
+       max_pay_load  = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) &
+                       DEVICE_CTRL_MAX_RREQ_SZ_MASK;
+       hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
+
+       txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) <<
+                       TXQ_NUM_TPD_BURST_SHIFT;
+       if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE)
+               txq_ctrl_data |= TXQ_CTRL_ENH_MODE;
+       max_pay_load_data = (atl1c_pay_load_size[hw->dmar_block] &
+                       TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT;
+       if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2)
+               max_pay_load_data >>= 1;
+       txq_ctrl_data |= max_pay_load_data;
+
+       AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data);
+}
+
+static void atl1c_configure_rx(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+       u32 rxq_ctrl_data;
+
+       rxq_ctrl_data = (hw->rfd_burst & RXQ_RFD_BURST_NUM_MASK) <<
+                       RXQ_RFD_BURST_NUM_SHIFT;
+
+       if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM)
+               rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN;
+       if (hw->rss_type == atl1c_rss_ipv4)
+               rxq_ctrl_data |= RSS_HASH_IPV4;
+       if (hw->rss_type == atl1c_rss_ipv4_tcp)
+               rxq_ctrl_data |= RSS_HASH_IPV4_TCP;
+       if (hw->rss_type == atl1c_rss_ipv6)
+               rxq_ctrl_data |= RSS_HASH_IPV6;
+       if (hw->rss_type == atl1c_rss_ipv6_tcp)
+               rxq_ctrl_data |= RSS_HASH_IPV6_TCP;
+       if (hw->rss_type != atl1c_rss_disable)
+               rxq_ctrl_data |= RRS_HASH_CTRL_EN;
+
+       rxq_ctrl_data |= (hw->rss_mode & RSS_MODE_MASK) <<
+                       RSS_MODE_SHIFT;
+       rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) <<
+                       RSS_HASH_BITS_SHIFT;
+       if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON)
+               rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_1M &
+                       ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT;
+
+       AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
+}
+
+static void atl1c_configure_rss(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+
+       AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
+       AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
+}
+
+static void atl1c_configure_dma(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+       u32 dma_ctrl_data;
+
+       dma_ctrl_data = DMA_CTRL_DMAR_REQ_PRI;
+       if (hw->ctrl_flags & ATL1C_CMB_ENABLE)
+               dma_ctrl_data |= DMA_CTRL_CMB_EN;
+       if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
+               dma_ctrl_data |= DMA_CTRL_SMB_EN;
+       else
+               dma_ctrl_data |= MAC_CTRL_SMB_DIS;
+
+       switch (hw->dma_order) {
+       case atl1c_dma_ord_in:
+               dma_ctrl_data |= DMA_CTRL_DMAR_IN_ORDER;
+               break;
+       case atl1c_dma_ord_enh:
+               dma_ctrl_data |= DMA_CTRL_DMAR_ENH_ORDER;
+               break;
+       case atl1c_dma_ord_out:
+               dma_ctrl_data |= DMA_CTRL_DMAR_OUT_ORDER;
+               break;
+       default:
+               break;
+       }
+
+       dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
+               << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
+       dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+               << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
+       dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
+               << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
+       dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
+               << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
+
+       AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
+}
+
+/*
+ * Stop the mac, transmit and receive units
+ * hw - Struct containing variables accessed by shared code
+ * return : 0  or  idle status (if error)
+ */
+static int atl1c_stop_mac(struct atl1c_hw *hw)
+{
+       u32 data;
+
+       AT_READ_REG(hw, REG_RXQ_CTRL, &data);
+       data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN |
+                 RXQ3_CTRL_EN | RXQ_CTRL_EN);
+       AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
+
+       AT_READ_REG(hw, REG_TXQ_CTRL, &data);
+       data &= ~TXQ_CTRL_EN;
+       AT_WRITE_REG(hw, REG_TWSI_CTRL, data);
+
+       atl1c_wait_until_idle(hw);
+
+       AT_READ_REG(hw, REG_MAC_CTRL, &data);
+       data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
+       AT_WRITE_REG(hw, REG_MAC_CTRL, data);
+
+       return (int)atl1c_wait_until_idle(hw);
+}
+
+static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
+{
+       u32 data;
+
+       AT_READ_REG(hw, REG_RXQ_CTRL, &data);
+       switch (hw->adapter->num_rx_queues) {
+       case 4:
+               data |= (RXQ3_CTRL_EN | RXQ2_CTRL_EN | RXQ1_CTRL_EN);
+               break;
+       case 3:
+               data |= (RXQ2_CTRL_EN | RXQ1_CTRL_EN);
+               break;
+       case 2:
+               data |= RXQ1_CTRL_EN;
+               break;
+       default:
+               break;
+       }
+       data |= RXQ_CTRL_EN;
+       AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
+}
+
+static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw)
+{
+       u32 data;
+
+       AT_READ_REG(hw, REG_TXQ_CTRL, &data);
+       data |= TXQ_CTRL_EN;
+       AT_WRITE_REG(hw, REG_TXQ_CTRL, data);
+}
+
+/*
+ * 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)
+ */
+static int atl1c_reset_mac(struct atl1c_hw *hw)
+{
+       struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+       u32 master_ctrl_data = 0;
+
+       AT_WRITE_REG(hw, REG_IMR, 0);
+       AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT);
+
+       atl1c_stop_mac(hw);
+       /*
+        * 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.
+        */
+       AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
+       master_ctrl_data |= MASTER_CTRL_OOB_DIS_OFF;
+       AT_WRITE_REGW(hw, REG_MASTER_CTRL, ((master_ctrl_data | MASTER_CTRL_SOFT_RST)
+                       & 0xFFFF));
+
+       AT_WRITE_FLUSH(hw);
+       msleep(10);
+       /* Wait at least 10ms for All module to be Idle */
+
+       if (atl1c_wait_until_idle(hw)) {
+               dev_err(&pdev->dev,
+                       "MAC state machine can't be idle since"
+                       " disabled for 10ms second\n");
+               return -1;
+       }
+       return 0;
+}
+
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw)
+{
+       u32 pm_ctrl_data;
+
+       AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
+       pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
+                       PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+       pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
+       pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+       pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+       pm_ctrl_data &= ~PM_CTRL_MAC_ASPM_CHK;
+       pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
+
+       pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
+       pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
+       pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
+       AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
+}
+
+/*
+ * Set ASPM state.
+ * Enable/disable L0s/L1 depend on link state.
+ */
+static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
+{
+       u32 pm_ctrl_data;
+       u32 link_ctrl_data;
+       u32 link_l1_timer = 0xF;
+
+       AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
+       AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
+
+       pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
+       pm_ctrl_data &=  ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
+                       PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+       pm_ctrl_data &= ~(PM_CTRL_LCKDET_TIMER_MASK <<
+                       PM_CTRL_LCKDET_TIMER_SHIFT);
+       pm_ctrl_data |= AT_LCKDET_TIMER << PM_CTRL_LCKDET_TIMER_SHIFT;
+
+       if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d ||
+               hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) {
+               link_ctrl_data &= ~LINK_CTRL_EXT_SYNC;
+               if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) {
+                       if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V10)
+                               link_ctrl_data |= LINK_CTRL_EXT_SYNC;
+               }
+
+               AT_WRITE_REG(hw, REG_LINK_CTRL, link_ctrl_data);
+
+               pm_ctrl_data |= PM_CTRL_RCVR_WT_TIMER;
+               pm_ctrl_data &= ~(PM_CTRL_PM_REQ_TIMER_MASK <<
+                       PM_CTRL_PM_REQ_TIMER_SHIFT);
+               pm_ctrl_data |= AT_ASPM_L1_TIMER <<
+                       PM_CTRL_PM_REQ_TIMER_SHIFT;
+               pm_ctrl_data &= ~PM_CTRL_SA_DLY_EN;
+               pm_ctrl_data &= ~PM_CTRL_HOTRST;
+               pm_ctrl_data |= 1 << PM_CTRL_L1_ENTRY_TIMER_SHIFT;
+               pm_ctrl_data |= PM_CTRL_SERDES_PD_EX_L1;
+       }
+       pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK;
+       if (linkup) {
+               pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+               pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+               if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT)
+                       pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
+               if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
+                       pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
+
+               if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d ||
+                       hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) {
+                       if (hw->nic_type == athr_l2c_b)
+                               if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE))
+                                       pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+                       pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
+                       pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
+                       pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
+                       pm_ctrl_data |= PM_CTRL_CLK_SWH_L1;
+               if (hw->adapter->link_speed == SPEED_100 ||
+                               hw->adapter->link_speed == SPEED_1000) {
+                               pm_ctrl_data &=  ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
+                                       PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+                               if (hw->nic_type == athr_l2c_b)
+                                       link_l1_timer = 7;
+                               else if (hw->nic_type == athr_l2c_b2 ||
+                                       hw->nic_type == athr_l1d_2)
+                                       link_l1_timer = 4;
+                               pm_ctrl_data |= link_l1_timer <<
+                                       PM_CTRL_L1_ENTRY_TIMER_SHIFT;
+                       }
+               } else {
+                       pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
+                       pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
+                       pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
+                       pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
+                       pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+                       pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+
+               }
+       } else {
+               pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
+               pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+               pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
+               pm_ctrl_data |= PM_CTRL_CLK_SWH_L1;
+
+               if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT)
+                       pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
+               else
+                       pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+       }
+       AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
+
+       return;
+}
+
+static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       u32 mac_ctrl_data;
+
+       mac_ctrl_data = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN;
+       mac_ctrl_data |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+
+       if (adapter->link_duplex == FULL_DUPLEX) {
+               hw->mac_duplex = true;
+               mac_ctrl_data |= MAC_CTRL_DUPLX;
+       }
+
+       if (adapter->link_speed == SPEED_1000)
+               hw->mac_speed = atl1c_mac_speed_1000;
+       else
+               hw->mac_speed = atl1c_mac_speed_10_100;
+
+       mac_ctrl_data |= (hw->mac_speed & MAC_CTRL_SPEED_MASK) <<
+                       MAC_CTRL_SPEED_SHIFT;
+
+       mac_ctrl_data |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+       mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) <<
+                       MAC_CTRL_PRMLEN_SHIFT);
+
+       __atl1c_vlan_mode(netdev->features, &mac_ctrl_data);
+
+       mac_ctrl_data |= MAC_CTRL_BC_EN;
+       if (netdev->flags & IFF_PROMISC)
+               mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+       if (netdev->flags & IFF_ALLMULTI)
+               mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+
+       mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN;
+       if (hw->nic_type == athr_l1d || hw->nic_type == athr_l2c_b2 ||
+           hw->nic_type == athr_l1d_2) {
+               mac_ctrl_data |= MAC_CTRL_SPEED_MODE_SW;
+               mac_ctrl_data |= MAC_CTRL_HASH_ALG_CRC32;
+       }
+       AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+}
+
+/*
+ * atl1c_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl1c_configure(struct atl1c_adapter *adapter)
+{
+       struct atl1c_hw *hw = &adapter->hw;
+       u32 master_ctrl_data = 0;
+       u32 intr_modrt_data;
+       u32 data;
+
+       /* clear interrupt status */
+       AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF);
+       /*  Clear any WOL status */
+       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+       /* set Interrupt Clear Timer
+        * HW will enable self to assert interrupt event to system after
+        * waiting x-time for software to notify it accept interrupt.
+        */
+
+       data = CLK_GATING_EN_ALL;
+       if (hw->ctrl_flags & ATL1C_CLK_GATING_EN) {
+               if (hw->nic_type == athr_l2c_b)
+                       data &= ~CLK_GATING_RXMAC_EN;
+       } else
+               data = 0;
+       AT_WRITE_REG(hw, REG_CLK_GATING_CTRL, data);
+
+       AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER,
+               hw->ict & INT_RETRIG_TIMER_MASK);
+
+       atl1c_configure_des_ring(adapter);
+
+       if (hw->ctrl_flags & ATL1C_INTR_MODRT_ENABLE) {
+               intr_modrt_data = (hw->tx_imt & IRQ_MODRT_TIMER_MASK) <<
+                                       IRQ_MODRT_TX_TIMER_SHIFT;
+               intr_modrt_data |= (hw->rx_imt & IRQ_MODRT_TIMER_MASK) <<
+                                       IRQ_MODRT_RX_TIMER_SHIFT;
+               AT_WRITE_REG(hw, REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data);
+               master_ctrl_data |=
+                       MASTER_CTRL_TX_ITIMER_EN | MASTER_CTRL_RX_ITIMER_EN;
+       }
+
+       if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ)
+               master_ctrl_data |= MASTER_CTRL_INT_RDCLR;
+
+       master_ctrl_data |= MASTER_CTRL_SA_TIMER_EN;
+       AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+
+       if (hw->ctrl_flags & ATL1C_CMB_ENABLE) {
+               AT_WRITE_REG(hw, REG_CMB_TPD_THRESH,
+                       hw->cmb_tpd & CMB_TPD_THRESH_MASK);
+               AT_WRITE_REG(hw, REG_CMB_TX_TIMER,
+                       hw->cmb_tx_timer & CMB_TX_TIMER_MASK);
+       }
+
+       if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
+               AT_WRITE_REG(hw, REG_SMB_STAT_TIMER,
+                       hw->smb_timer & SMB_STAT_TIMER_MASK);
+       /* set MTU */
+       AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
+                       VLAN_HLEN + ETH_FCS_LEN);
+       /* HDS, disable */
+       AT_WRITE_REG(hw, REG_HDS_CTRL, 0);
+
+       atl1c_configure_tx(adapter);
+       atl1c_configure_rx(adapter);
+       atl1c_configure_rss(adapter);
+       atl1c_configure_dma(adapter);
+
+       return 0;
+}
+
+static void atl1c_update_hw_stats(struct atl1c_adapter *adapter)
+{
+       u16 hw_reg_addr = 0;
+       unsigned long *stats_item = NULL;
+       u32 data;
+
+       /* update rx status */
+       hw_reg_addr = REG_MAC_RX_STATUS_BIN;
+       stats_item  = &adapter->hw_stats.rx_ok;
+       while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
+               AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+               *stats_item += data;
+               stats_item++;
+               hw_reg_addr += 4;
+       }
+/* update tx status */
+       hw_reg_addr = REG_MAC_TX_STATUS_BIN;
+       stats_item  = &adapter->hw_stats.tx_ok;
+       while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
+               AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+               *stats_item += data;
+               stats_item++;
+               hw_reg_addr += 4;
+       }
+}
+
+/*
+ * atl1c_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 *atl1c_get_stats(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct atl1c_hw_stats  *hw_stats = &adapter->hw_stats;
+       struct net_device_stats *net_stats = &netdev->stats;
+
+       atl1c_update_hw_stats(adapter);
+       net_stats->rx_packets = hw_stats->rx_ok;
+       net_stats->tx_packets = hw_stats->tx_ok;
+       net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
+       net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
+       net_stats->multicast  = hw_stats->rx_mcast;
+       net_stats->collisions = hw_stats->tx_1_col +
+                               hw_stats->tx_2_col * 2 +
+                               hw_stats->tx_late_col + hw_stats->tx_abort_col;
+       net_stats->rx_errors  = hw_stats->rx_frag + hw_stats->rx_fcs_err +
+                               hw_stats->rx_len_err + hw_stats->rx_sz_ov +
+                               hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
+       net_stats->rx_fifo_errors   = hw_stats->rx_rxf_ov;
+       net_stats->rx_length_errors = hw_stats->rx_len_err;
+       net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
+       net_stats->rx_frame_errors  = hw_stats->rx_align_err;
+       net_stats->rx_over_errors   = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+       net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+       net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
+                               hw_stats->tx_underrun + hw_stats->tx_trunc;
+       net_stats->tx_fifo_errors    = hw_stats->tx_underrun;
+       net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+       net_stats->tx_window_errors  = hw_stats->tx_late_col;
+
+       return net_stats;
+}
+
+static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter)
+{
+       u16 phy_data;
+
+       spin_lock(&adapter->mdio_lock);
+       atl1c_read_phy_reg(&adapter->hw, MII_ISR, &phy_data);
+       spin_unlock(&adapter->mdio_lock);
+}
+
+static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
+                               enum atl1c_trans_queue type)
+{
+       struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
+                               &adapter->tpd_ring[type];
+       struct atl1c_buffer *buffer_info;
+       struct pci_dev *pdev = adapter->pdev;
+       u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+       u16 hw_next_to_clean;
+       u16 shift;
+       u32 data;
+
+       if (type == atl1c_trans_high)
+               shift = MB_HTPD_CONS_IDX_SHIFT;
+       else
+               shift = MB_NTPD_CONS_IDX_SHIFT;
+
+       AT_READ_REG(&adapter->hw, REG_MB_PRIO_CONS_IDX, &data);
+       hw_next_to_clean = (data >> shift) & MB_PRIO_PROD_IDX_MASK;
+
+       while (next_to_clean != hw_next_to_clean) {
+               buffer_info = &tpd_ring->buffer_info[next_to_clean];
+               atl1c_clean_buffer(pdev, buffer_info, 1);
+               if (++next_to_clean == tpd_ring->count)
+                       next_to_clean = 0;
+               atomic_set(&tpd_ring->next_to_clean, next_to_clean);
+       }
+
+       if (netif_queue_stopped(adapter->netdev) &&
+                       netif_carrier_ok(adapter->netdev)) {
+               netif_wake_queue(adapter->netdev);
+       }
+
+       return true;
+}
+
+/*
+ * atl1c_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ */
+static irqreturn_t atl1c_intr(int irq, void *data)
+{
+       struct net_device *netdev  = data;
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = adapter->pdev;
+       struct atl1c_hw *hw = &adapter->hw;
+       int max_ints = AT_MAX_INT_WORK;
+       int handled = IRQ_NONE;
+       u32 status;
+       u32 reg_data;
+
+       do {
+               AT_READ_REG(hw, REG_ISR, &reg_data);
+               status = reg_data & hw->intr_mask;
+
+               if (status == 0 || (status & ISR_DIS_INT) != 0) {
+                       if (max_ints != AT_MAX_INT_WORK)
+                               handled = IRQ_HANDLED;
+                       break;
+               }
+               /* link event */
+               if (status & ISR_GPHY)
+                       atl1c_clear_phy_int(adapter);
+               /* Ack ISR */
+               AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+               if (status & ISR_RX_PKT) {
+                       if (likely(napi_schedule_prep(&adapter->napi))) {
+                               hw->intr_mask &= ~ISR_RX_PKT;
+                               AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
+                               __napi_schedule(&adapter->napi);
+                       }
+               }
+               if (status & ISR_TX_PKT)
+                       atl1c_clean_tx_irq(adapter, atl1c_trans_normal);
+
+               handled = IRQ_HANDLED;
+               /* check if PCIE PHY Link down */
+               if (status & ISR_ERROR) {
+                       if (netif_msg_hw(adapter))
+                               dev_err(&pdev->dev,
+                                       "atl1c hardware error (status = 0x%x)\n",
+                                       status & ISR_ERROR);
+                       /* reset MAC */
+                       adapter->work_event |= ATL1C_WORK_EVENT_RESET;
+                       schedule_work(&adapter->common_task);
+                       return IRQ_HANDLED;
+               }
+
+               if (status & ISR_OVER)
+                       if (netif_msg_intr(adapter))
+                               dev_warn(&pdev->dev,
+                                       "TX/RX overflow (status = 0x%x)\n",
+                                       status & ISR_OVER);
+
+               /* link event */
+               if (status & (ISR_GPHY | ISR_MANUAL)) {
+                       netdev->stats.tx_carrier_errors++;
+                       atl1c_link_chg_event(adapter);
+                       break;
+               }
+
+       } while (--max_ints > 0);
+       /* re-enable Interrupt*/
+       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+       return handled;
+}
+
+static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
+                 struct sk_buff *skb, struct atl1c_recv_ret_status *prrs)
+{
+       /*
+        * The pid field in RRS in not correct sometimes, so we
+        * cannot figure out if the packet is fragmented or not,
+        * so we tell the KERNEL CHECKSUM_NONE
+        */
+       skb_checksum_none_assert(skb);
+}
+
+static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid)
+{
+       struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[ringid];
+       struct pci_dev *pdev = adapter->pdev;
+       struct atl1c_buffer *buffer_info, *next_info;
+       struct sk_buff *skb;
+       void *vir_addr = NULL;
+       u16 num_alloc = 0;
+       u16 rfd_next_to_use, next_next;
+       struct atl1c_rx_free_desc *rfd_desc;
+
+       next_next = rfd_next_to_use = rfd_ring->next_to_use;
+       if (++next_next == rfd_ring->count)
+               next_next = 0;
+       buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+       next_info = &rfd_ring->buffer_info[next_next];
+
+       while (next_info->flags & ATL1C_BUFFER_FREE) {
+               rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
+
+               skb = dev_alloc_skb(adapter->rx_buffer_len);
+               if (unlikely(!skb)) {
+                       if (netif_msg_rx_err(adapter))
+                               dev_warn(&pdev->dev, "alloc rx buffer failed\n");
+                       break;
+               }
+
+               /*
+                * Make buffer alignment 2 beyond a 16 byte boundary
+                * this will result in a 16 byte aligned IP header after
+                * the 14 byte MAC header is removed
+                */
+               vir_addr = skb->data;
+               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+               buffer_info->skb = skb;
+               buffer_info->length = adapter->rx_buffer_len;
+               buffer_info->dma = pci_map_single(pdev, vir_addr,
+                                               buffer_info->length,
+                                               PCI_DMA_FROMDEVICE);
+               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+                       ATL1C_PCIMAP_FROMDEVICE);
+               rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+               rfd_next_to_use = next_next;
+               if (++next_next == rfd_ring->count)
+                       next_next = 0;
+               buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+               next_info = &rfd_ring->buffer_info[next_next];
+               num_alloc++;
+       }
+
+       if (num_alloc) {
+               /* TODO: update mailbox here */
+               wmb();
+               rfd_ring->next_to_use = rfd_next_to_use;
+               AT_WRITE_REG(&adapter->hw, atl1c_rfd_prod_idx_regs[ringid],
+                       rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK);
+       }
+
+       return num_alloc;
+}
+
+static void atl1c_clean_rrd(struct atl1c_rrd_ring *rrd_ring,
+                       struct  atl1c_recv_ret_status *rrs, u16 num)
+{
+       u16 i;
+       /* the relationship between rrd and rfd is one map one */
+       for (i = 0; i < num; i++, rrs = ATL1C_RRD_DESC(rrd_ring,
+                                       rrd_ring->next_to_clean)) {
+               rrs->word3 &= ~RRS_RXD_UPDATED;
+               if (++rrd_ring->next_to_clean == rrd_ring->count)
+                       rrd_ring->next_to_clean = 0;
+       }
+}
+
+static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
+       struct atl1c_recv_ret_status *rrs, u16 num)
+{
+       u16 i;
+       u16 rfd_index;
+       struct atl1c_buffer *buffer_info = rfd_ring->buffer_info;
+
+       rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+                       RRS_RX_RFD_INDEX_MASK;
+       for (i = 0; i < num; i++) {
+               buffer_info[rfd_index].skb = NULL;
+               ATL1C_SET_BUFFER_STATE(&buffer_info[rfd_index],
+                                       ATL1C_BUFFER_FREE);
+               if (++rfd_index == rfd_ring->count)
+                       rfd_index = 0;
+       }
+       rfd_ring->next_to_clean = rfd_index;
+}
+
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
+                  int *work_done, int work_to_do)
+{
+       u16 rfd_num, rfd_index;
+       u16 count = 0;
+       u16 length;
+       struct pci_dev *pdev = adapter->pdev;
+       struct net_device *netdev  = adapter->netdev;
+       struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[que];
+       struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[que];
+       struct sk_buff *skb;
+       struct atl1c_recv_ret_status *rrs;
+       struct atl1c_buffer *buffer_info;
+
+       while (1) {
+               if (*work_done >= work_to_do)
+                       break;
+               rrs = ATL1C_RRD_DESC(rrd_ring, rrd_ring->next_to_clean);
+               if (likely(RRS_RXD_IS_VALID(rrs->word3))) {
+                       rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) &
+                               RRS_RX_RFD_CNT_MASK;
+                       if (unlikely(rfd_num != 1))
+                               /* TODO support mul rfd*/
+                               if (netif_msg_rx_err(adapter))
+                                       dev_warn(&pdev->dev,
+                                               "Multi rfd not support yet!\n");
+                       goto rrs_checked;
+               } else {
+                       break;
+               }
+rrs_checked:
+               atl1c_clean_rrd(rrd_ring, rrs, rfd_num);
+               if (rrs->word3 & (RRS_RX_ERR_SUM | RRS_802_3_LEN_ERR)) {
+                       atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+                               if (netif_msg_rx_err(adapter))
+                                       dev_warn(&pdev->dev,
+                                               "wrong packet! rrs word3 is %x\n",
+                                               rrs->word3);
+                       continue;
+               }
+
+               length = le16_to_cpu((rrs->word3 >> RRS_PKT_SIZE_SHIFT) &
+                               RRS_PKT_SIZE_MASK);
+               /* Good Receive */
+               if (likely(rfd_num == 1)) {
+                       rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+                                       RRS_RX_RFD_INDEX_MASK;
+                       buffer_info = &rfd_ring->buffer_info[rfd_index];
+                       pci_unmap_single(pdev, buffer_info->dma,
+                               buffer_info->length, PCI_DMA_FROMDEVICE);
+                       skb = buffer_info->skb;
+               } else {
+                       /* TODO */
+                       if (netif_msg_rx_err(adapter))
+                               dev_warn(&pdev->dev,
+                                       "Multi rfd not support yet!\n");
+                       break;
+               }
+               atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+               skb_put(skb, length - ETH_FCS_LEN);
+               skb->protocol = eth_type_trans(skb, netdev);
+               atl1c_rx_checksum(adapter, skb, rrs);
+               if (rrs->word3 & RRS_VLAN_INS) {
+                       u16 vlan;
+
+                       AT_TAG_TO_VLAN(rrs->vlan_tag, vlan);
+                       vlan = le16_to_cpu(vlan);
+                       __vlan_hwaccel_put_tag(skb, vlan);
+               }
+               netif_receive_skb(skb);
+
+               (*work_done)++;
+               count++;
+       }
+       if (count)
+               atl1c_alloc_rx_buffer(adapter, que);
+}
+
+/*
+ * atl1c_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ */
+static int atl1c_clean(struct napi_struct *napi, int budget)
+{
+       struct atl1c_adapter *adapter =
+                       container_of(napi, struct atl1c_adapter, napi);
+       int work_done = 0;
+
+       /* Keep link state information with original netdev */
+       if (!netif_carrier_ok(adapter->netdev))
+               goto quit_polling;
+       /* just enable one RXQ */
+       atl1c_clean_rx_irq(adapter, 0, &work_done, budget);
+
+       if (work_done < budget) {
+quit_polling:
+               napi_complete(napi);
+               adapter->hw.intr_mask |= ISR_RX_PKT;
+               AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+       }
+       return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void atl1c_netpoll(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       disable_irq(adapter->pdev->irq);
+       atl1c_intr(adapter->pdev->irq, netdev);
+       enable_irq(adapter->pdev->irq);
+}
+#endif
+
+static inline u16 atl1c_tpd_avail(struct atl1c_adapter *adapter, enum atl1c_trans_queue type)
+{
+       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+       u16 next_to_use = 0;
+       u16 next_to_clean = 0;
+
+       next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+       next_to_use   = tpd_ring->next_to_use;
+
+       return (u16)(next_to_clean > next_to_use) ?
+               (next_to_clean - next_to_use - 1) :
+               (tpd_ring->count + next_to_clean - next_to_use - 1);
+}
+
+/*
+ * get next usable tpd
+ * Note: should call atl1c_tdp_avail to make sure
+ * there is enough tpd to use
+ */
+static struct atl1c_tpd_desc *atl1c_get_tpd(struct atl1c_adapter *adapter,
+       enum atl1c_trans_queue type)
+{
+       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+       struct atl1c_tpd_desc *tpd_desc;
+       u16 next_to_use = 0;
+
+       next_to_use = tpd_ring->next_to_use;
+       if (++tpd_ring->next_to_use == tpd_ring->count)
+               tpd_ring->next_to_use = 0;
+       tpd_desc = ATL1C_TPD_DESC(tpd_ring, next_to_use);
+       memset(tpd_desc, 0, sizeof(struct atl1c_tpd_desc));
+       return  tpd_desc;
+}
+
+static struct atl1c_buffer *
+atl1c_get_tx_buffer(struct atl1c_adapter *adapter, struct atl1c_tpd_desc *tpd)
+{
+       struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+
+       return &tpd_ring->buffer_info[tpd -
+                       (struct atl1c_tpd_desc *)tpd_ring->desc];
+}
+
+/* Calculate the transmit packet descript needed*/
+static u16 atl1c_cal_tpd_req(const struct sk_buff *skb)
+{
+       u16 tpd_req;
+       u16 proto_hdr_len = 0;
+
+       tpd_req = skb_shinfo(skb)->nr_frags + 1;
+
+       if (skb_is_gso(skb)) {
+               proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+               if (proto_hdr_len < skb_headlen(skb))
+                       tpd_req++;
+               if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+                       tpd_req++;
+       }
+       return tpd_req;
+}
+
+static int atl1c_tso_csum(struct atl1c_adapter *adapter,
+                         struct sk_buff *skb,
+                         struct atl1c_tpd_desc **tpd,
+                         enum atl1c_trans_queue type)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       u8 hdr_len;
+       u32 real_len;
+       unsigned short offload_type;
+       int err;
+
+       if (skb_is_gso(skb)) {
+               if (skb_header_cloned(skb)) {
+                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+                       if (unlikely(err))
+                               return -1;
+               }
+               offload_type = skb_shinfo(skb)->gso_type;
+
+               if (offload_type & SKB_GSO_TCPV4) {
+                       real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
+                                       + ntohs(ip_hdr(skb)->tot_len));
+
+                       if (real_len < skb->len)
+                               pskb_trim(skb, real_len);
+
+                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+                       if (unlikely(skb->len == hdr_len)) {
+                               /* only xsum need */
+                               if (netif_msg_tx_queued(adapter))
+                                       dev_warn(&pdev->dev,
+                                               "IPV4 tso with zero data??\n");
+                               goto check_sum;
+                       } else {
+                               ip_hdr(skb)->check = 0;
+                               tcp_hdr(skb)->check = ~csum_tcpudp_magic(
+                                                       ip_hdr(skb)->saddr,
+                                                       ip_hdr(skb)->daddr,
+                                                       0, IPPROTO_TCP, 0);
+                               (*tpd)->word1 |= 1 << TPD_IPV4_PACKET_SHIFT;
+                       }
+               }
+
+               if (offload_type & SKB_GSO_TCPV6) {
+                       struct atl1c_tpd_ext_desc *etpd =
+                               *(struct atl1c_tpd_ext_desc **)(tpd);
+
+                       memset(etpd, 0, sizeof(struct atl1c_tpd_ext_desc));
+                       *tpd = atl1c_get_tpd(adapter, type);
+                       ipv6_hdr(skb)->payload_len = 0;
+                       /* check payload == 0 byte ? */
+                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+                       if (unlikely(skb->len == hdr_len)) {
+                               /* only xsum need */
+                               if (netif_msg_tx_queued(adapter))
+                                       dev_warn(&pdev->dev,
+                                               "IPV6 tso with zero data??\n");
+                               goto check_sum;
+                       } else
+                               tcp_hdr(skb)->check = ~csum_ipv6_magic(
+                                               &ipv6_hdr(skb)->saddr,
+                                               &ipv6_hdr(skb)->daddr,
+                                               0, IPPROTO_TCP, 0);
+                       etpd->word1 |= 1 << TPD_LSO_EN_SHIFT;
+                       etpd->word1 |= 1 << TPD_LSO_VER_SHIFT;
+                       etpd->pkt_len = cpu_to_le32(skb->len);
+                       (*tpd)->word1 |= 1 << TPD_LSO_VER_SHIFT;
+               }
+
+               (*tpd)->word1 |= 1 << TPD_LSO_EN_SHIFT;
+               (*tpd)->word1 |= (skb_transport_offset(skb) & TPD_TCPHDR_OFFSET_MASK) <<
+                               TPD_TCPHDR_OFFSET_SHIFT;
+               (*tpd)->word1 |= (skb_shinfo(skb)->gso_size & TPD_MSS_MASK) <<
+                               TPD_MSS_SHIFT;
+               return 0;
+       }
+
+check_sum:
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+               u8 css, cso;
+               cso = skb_checksum_start_offset(skb);
+
+               if (unlikely(cso & 0x1)) {
+                       if (netif_msg_tx_err(adapter))
+                               dev_err(&adapter->pdev->dev,
+                                       "payload offset should not an event number\n");
+                       return -1;
+               } else {
+                       css = cso + skb->csum_offset;
+
+                       (*tpd)->word1 |= ((cso >> 1) & TPD_PLOADOFFSET_MASK) <<
+                                       TPD_PLOADOFFSET_SHIFT;
+                       (*tpd)->word1 |= ((css >> 1) & TPD_CCSUM_OFFSET_MASK) <<
+                                       TPD_CCSUM_OFFSET_SHIFT;
+                       (*tpd)->word1 |= 1 << TPD_CCSUM_EN_SHIFT;
+               }
+       }
+       return 0;
+}
+
+static void atl1c_tx_map(struct atl1c_adapter *adapter,
+                     struct sk_buff *skb, struct atl1c_tpd_desc *tpd,
+                       enum atl1c_trans_queue type)
+{
+       struct atl1c_tpd_desc *use_tpd = NULL;
+       struct atl1c_buffer *buffer_info = NULL;
+       u16 buf_len = skb_headlen(skb);
+       u16 map_len = 0;
+       u16 mapped_len = 0;
+       u16 hdr_len = 0;
+       u16 nr_frags;
+       u16 f;
+       int tso;
+
+       nr_frags = skb_shinfo(skb)->nr_frags;
+       tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK;
+       if (tso) {
+               /* TSO */
+               map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+               use_tpd = tpd;
+
+               buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+               buffer_info->length = map_len;
+               buffer_info->dma = pci_map_single(adapter->pdev,
+                                       skb->data, hdr_len, PCI_DMA_TODEVICE);
+               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+                       ATL1C_PCIMAP_TODEVICE);
+               mapped_len += map_len;
+               use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+               use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+       }
+
+       if (mapped_len < buf_len) {
+               /* mapped_len == 0, means we should use the first tpd,
+                  which is given by caller  */
+               if (mapped_len == 0)
+                       use_tpd = tpd;
+               else {
+                       use_tpd = atl1c_get_tpd(adapter, type);
+                       memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+               }
+               buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+               buffer_info->length = buf_len - mapped_len;
+               buffer_info->dma =
+                       pci_map_single(adapter->pdev, skb->data + mapped_len,
+                                       buffer_info->length, PCI_DMA_TODEVICE);
+               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+                       ATL1C_PCIMAP_TODEVICE);
+               use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+               use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
+       }
+
+       for (f = 0; f < nr_frags; f++) {
+               struct skb_frag_struct *frag;
+
+               frag = &skb_shinfo(skb)->frags[f];
+
+               use_tpd = atl1c_get_tpd(adapter, type);
+               memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+
+               buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+               buffer_info->length = frag->size;
+               buffer_info->dma =
+                       pci_map_page(adapter->pdev, frag->page,
+                                       frag->page_offset,
+                                       buffer_info->length,
+                                       PCI_DMA_TODEVICE);
+               ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+               ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE,
+                       ATL1C_PCIMAP_TODEVICE);
+               use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+               use_tpd->buffer_len  = cpu_to_le16(buffer_info->length);
+       }
+
+       /* The last tpd */
+       use_tpd->word1 |= 1 << TPD_EOP_SHIFT;
+       /* The last buffer info contain the skb address,
+          so it will be free after unmap */
+       buffer_info->skb = skb;
+}
+
+static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
+                          struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type)
+{
+       struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+       u32 prod_data;
+
+       AT_READ_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, &prod_data);
+       switch (type) {
+       case atl1c_trans_high:
+               prod_data &= 0xFFFF0000;
+               prod_data |= tpd_ring->next_to_use & 0xFFFF;
+               break;
+       case atl1c_trans_normal:
+               prod_data &= 0x0000FFFF;
+               prod_data |= (tpd_ring->next_to_use & 0xFFFF) << 16;
+               break;
+       default:
+               break;
+       }
+       wmb();
+       AT_WRITE_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, prod_data);
+}
+
+static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
+                                         struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
+       u16 tpd_req = 1;
+       struct atl1c_tpd_desc *tpd;
+       enum atl1c_trans_queue type = atl1c_trans_normal;
+
+       if (test_bit(__AT_DOWN, &adapter->flags)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       tpd_req = atl1c_cal_tpd_req(skb);
+       if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
+               if (netif_msg_pktdata(adapter))
+                       dev_info(&adapter->pdev->dev, "tx locked\n");
+               return NETDEV_TX_LOCKED;
+       }
+       if (skb->mark == 0x01)
+               type = atl1c_trans_high;
+       else
+               type = atl1c_trans_normal;
+
+       if (atl1c_tpd_avail(adapter, type) < tpd_req) {
+               /* no enough descriptor, just stop queue */
+               netif_stop_queue(netdev);
+               spin_unlock_irqrestore(&adapter->tx_lock, flags);
+               return NETDEV_TX_BUSY;
+       }
+
+       tpd = atl1c_get_tpd(adapter, type);
+
+       /* do TSO and check sum */
+       if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) {
+               spin_unlock_irqrestore(&adapter->tx_lock, flags);
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       if (unlikely(vlan_tx_tag_present(skb))) {
+               u16 vlan = vlan_tx_tag_get(skb);
+               __le16 tag;
+
+               vlan = cpu_to_le16(vlan);
+               AT_VLAN_TO_TAG(vlan, tag);
+               tpd->word1 |= 1 << TPD_INS_VTAG_SHIFT;
+               tpd->vlan_tag = tag;
+       }
+
+       if (skb_network_offset(skb) != ETH_HLEN)
+               tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */
+
+       atl1c_tx_map(adapter, skb, tpd, type);
+       atl1c_tx_queue(adapter, skb, tpd, type);
+
+       spin_unlock_irqrestore(&adapter->tx_lock, flags);
+       return NETDEV_TX_OK;
+}
+
+static void atl1c_free_irq(struct atl1c_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       free_irq(adapter->pdev->irq, netdev);
+
+       if (adapter->have_msi)
+               pci_disable_msi(adapter->pdev);
+}
+
+static int atl1c_request_irq(struct atl1c_adapter *adapter)
+{
+       struct pci_dev    *pdev   = adapter->pdev;
+       struct net_device *netdev = adapter->netdev;
+       int flags = 0;
+       int err = 0;
+
+       adapter->have_msi = true;
+       err = pci_enable_msi(adapter->pdev);
+       if (err) {
+               if (netif_msg_ifup(adapter))
+                       dev_err(&pdev->dev,
+                               "Unable to allocate MSI interrupt Error: %d\n",
+                               err);
+               adapter->have_msi = false;
+       } else
+               netdev->irq = pdev->irq;
+
+       if (!adapter->have_msi)
+               flags |= IRQF_SHARED;
+       err = request_irq(adapter->pdev->irq, atl1c_intr, flags,
+                       netdev->name, netdev);
+       if (err) {
+               if (netif_msg_ifup(adapter))
+                       dev_err(&pdev->dev,
+                               "Unable to allocate interrupt Error: %d\n",
+                               err);
+               if (adapter->have_msi)
+                       pci_disable_msi(adapter->pdev);
+               return err;
+       }
+       if (netif_msg_ifup(adapter))
+               dev_dbg(&pdev->dev, "atl1c_request_irq OK\n");
+       return err;
+}
+
+static int atl1c_up(struct atl1c_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int num;
+       int err;
+       int i;
+
+       netif_carrier_off(netdev);
+       atl1c_init_ring_ptrs(adapter);
+       atl1c_set_multi(netdev);
+       atl1c_restore_vlan(adapter);
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               num = atl1c_alloc_rx_buffer(adapter, i);
+               if (unlikely(num == 0)) {
+                       err = -ENOMEM;
+                       goto err_alloc_rx;
+               }
+       }
+
+       if (atl1c_configure(adapter)) {
+               err = -EIO;
+               goto err_up;
+       }
+
+       err = atl1c_request_irq(adapter);
+       if (unlikely(err))
+               goto err_up;
+
+       clear_bit(__AT_DOWN, &adapter->flags);
+       napi_enable(&adapter->napi);
+       atl1c_irq_enable(adapter);
+       atl1c_check_link_status(adapter);
+       netif_start_queue(netdev);
+       return err;
+
+err_up:
+err_alloc_rx:
+       atl1c_clean_rx_ring(adapter);
+       return err;
+}
+
+static void atl1c_down(struct atl1c_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       atl1c_del_timer(adapter);
+       adapter->work_event = 0; /* clear all event */
+       /* signal that we're down so the interrupt handler does not
+        * reschedule our watchdog timer */
+       set_bit(__AT_DOWN, &adapter->flags);
+       netif_carrier_off(netdev);
+       napi_disable(&adapter->napi);
+       atl1c_irq_disable(adapter);
+       atl1c_free_irq(adapter);
+       /* reset MAC to disable all RX/TX */
+       atl1c_reset_mac(&adapter->hw);
+       msleep(1);
+
+       adapter->link_speed = SPEED_0;
+       adapter->link_duplex = -1;
+       atl1c_clean_tx_ring(adapter, atl1c_trans_normal);
+       atl1c_clean_tx_ring(adapter, atl1c_trans_high);
+       atl1c_clean_rx_ring(adapter);
+}
+
+/*
+ * atl1c_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * 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 atl1c_open(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       int err;
+
+       /* disallow open during test */
+       if (test_bit(__AT_TESTING, &adapter->flags))
+               return -EBUSY;
+
+       /* allocate rx/tx dma buffer & descriptors */
+       err = atl1c_setup_ring_resources(adapter);
+       if (unlikely(err))
+               return err;
+
+       err = atl1c_up(adapter);
+       if (unlikely(err))
+               goto err_up;
+
+       if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
+               u32 phy_data;
+
+               AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data);
+               phy_data |= MDIO_AP_EN;
+               AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data);
+       }
+       return 0;
+
+err_up:
+       atl1c_free_irq(adapter);
+       atl1c_free_ring_resources(adapter);
+       atl1c_reset_mac(&adapter->hw);
+       return err;
+}
+
+/*
+ * atl1c_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * 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 atl1c_close(struct net_device *netdev)
+{
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+       atl1c_down(adapter);
+       atl1c_free_ring_resources(adapter);
+       return 0;
+}
+
+static int atl1c_suspend(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+       struct atl1c_hw *hw = &adapter->hw;
+       u32 mac_ctrl_data = 0;
+       u32 master_ctrl_data = 0;
+       u32 wol_ctrl_data = 0;
+       u16 mii_intr_status_data = 0;
+       u32 wufc = adapter->wol;
+
+       atl1c_disable_l0s_l1(hw);
+       if (netif_running(netdev)) {
+               WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+               atl1c_down(adapter);
+       }
+       netif_device_detach(netdev);
+
+       if (wufc)
+               if (atl1c_phy_power_saving(hw) != 0)
+                       dev_dbg(&pdev->dev, "phy power saving failed");
+
+       AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
+       AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
+
+       master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS;
+       mac_ctrl_data &= ~(MAC_CTRL_PRMLEN_MASK << MAC_CTRL_PRMLEN_SHIFT);
+       mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
+                       MAC_CTRL_PRMLEN_MASK) <<
+                       MAC_CTRL_PRMLEN_SHIFT);
+       mac_ctrl_data &= ~(MAC_CTRL_SPEED_MASK << MAC_CTRL_SPEED_SHIFT);
+       mac_ctrl_data &= ~MAC_CTRL_DUPLX;
+
+       if (wufc) {
+               mac_ctrl_data |= MAC_CTRL_RX_EN;
+               if (adapter->link_speed == SPEED_1000 ||
+                       adapter->link_speed == SPEED_0) {
+                       mac_ctrl_data |= atl1c_mac_speed_1000 <<
+                                       MAC_CTRL_SPEED_SHIFT;
+                       mac_ctrl_data |= MAC_CTRL_DUPLX;
+               } else
+                       mac_ctrl_data |= atl1c_mac_speed_10_100 <<
+                                       MAC_CTRL_SPEED_SHIFT;
+
+               if (adapter->link_duplex == DUPLEX_FULL)
+                       mac_ctrl_data |= MAC_CTRL_DUPLX;
+
+               /* turn on magic packet wol */
+               if (wufc & AT_WUFC_MAG)
+                       wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+
+               if (wufc & AT_WUFC_LNKC) {
+                       wol_ctrl_data |=  WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
+                       /* only link up can wake up */
+                       if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
+                               dev_dbg(&pdev->dev, "%s: read write phy "
+                                                 "register failed.\n",
+                                                 atl1c_driver_name);
+                       }
+               }
+               /* clear phy interrupt */
+               atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data);
+               /* Config MAC Ctrl register */
+               __atl1c_vlan_mode(netdev->features, &mac_ctrl_data);
+
+               /* magic packet maybe Broadcast&multicast&Unicast frame */
+               if (wufc & AT_WUFC_MAG)
+                       mac_ctrl_data |= MAC_CTRL_BC_EN;
+
+               dev_dbg(&pdev->dev,
+                       "%s: suspend MAC=0x%x\n",
+                       atl1c_driver_name, mac_ctrl_data);
+               AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+               AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
+               AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+               AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
+                       GPHY_CTRL_EXT_RESET);
+       } else {
+               AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING);
+               master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS;
+               mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT;
+               mac_ctrl_data |= MAC_CTRL_DUPLX;
+               AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+               AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+               AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+               hw->phy_configured = false; /* re-init PHY when resume */
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int atl1c_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+       atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
+                       ATL1C_PCIE_PHY_RESET);
+
+       atl1c_phy_reset(&adapter->hw);
+       atl1c_reset_mac(&adapter->hw);
+       atl1c_phy_init(&adapter->hw);
+
+#if 0
+       AT_READ_REG(&adapter->hw, REG_PM_CTRLSTAT, &pm_data);
+       pm_data &= ~PM_CTRLSTAT_PME_EN;
+       AT_WRITE_REG(&adapter->hw, REG_PM_CTRLSTAT, pm_data);
+#endif
+
+       netif_device_attach(netdev);
+       if (netif_running(netdev))
+               atl1c_up(adapter);
+
+       return 0;
+}
+#endif
+
+static void atl1c_shutdown(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       atl1c_suspend(&pdev->dev);
+       pci_wake_from_d3(pdev, adapter->wol);
+       pci_set_power_state(pdev, PCI_D3hot);
+}
+
+static const struct net_device_ops atl1c_netdev_ops = {
+       .ndo_open               = atl1c_open,
+       .ndo_stop               = atl1c_close,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_start_xmit         = atl1c_xmit_frame,
+       .ndo_set_mac_address    = atl1c_set_mac_addr,
+       .ndo_set_multicast_list = atl1c_set_multi,
+       .ndo_change_mtu         = atl1c_change_mtu,
+       .ndo_fix_features       = atl1c_fix_features,
+       .ndo_set_features       = atl1c_set_features,
+       .ndo_do_ioctl           = atl1c_ioctl,
+       .ndo_tx_timeout         = atl1c_tx_timeout,
+       .ndo_get_stats          = atl1c_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = atl1c_netpoll,
+#endif
+};
+
+static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
+{
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+       pci_set_drvdata(pdev, netdev);
+
+       netdev->irq  = pdev->irq;
+       netdev->netdev_ops = &atl1c_netdev_ops;
+       netdev->watchdog_timeo = AT_TX_WATCHDOG;
+       atl1c_set_ethtool_ops(netdev);
+
+       /* TODO: add when ready */
+       netdev->hw_features =   NETIF_F_SG         |
+                               NETIF_F_HW_CSUM    |
+                               NETIF_F_HW_VLAN_RX |
+                               NETIF_F_TSO        |
+                               NETIF_F_TSO6;
+       netdev->features =      netdev->hw_features |
+                               NETIF_F_HW_VLAN_TX;
+       return 0;
+}
+
+/*
+ * atl1c_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl1c_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl1c_probe 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 __devinit atl1c_probe(struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
+{
+       struct net_device *netdev;
+       struct atl1c_adapter *adapter;
+       static int cards_found;
+
+       int err = 0;
+
+       /* enable device (incl. PCI PM wakeup and hotplug setup) */
+       err = pci_enable_device_mem(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "cannot enable PCI device\n");
+               return err;
+       }
+
+       /*
+        * The atl1c chip can DMA to 64-bit addresses, but it uses a single
+        * shared register for the high 32 bits, so only a single, aligned,
+        * 4 GB physical address range can be used at a time.
+        *
+        * Supporting 64-bit DMA on this hardware is more trouble than it's
+        * worth.  It is far easier to limit to 32-bit DMA than update
+        * various kernel subsystems to support the mechanics required by a
+        * fixed-high-32-bit system.
+        */
+       if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+           (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
+               dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
+               goto err_dma;
+       }
+
+       err = pci_request_regions(pdev, atl1c_driver_name);
+       if (err) {
+               dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+               goto err_pci_reg;
+       }
+
+       pci_set_master(pdev);
+
+       netdev = alloc_etherdev(sizeof(struct atl1c_adapter));
+       if (netdev == NULL) {
+               err = -ENOMEM;
+               dev_err(&pdev->dev, "etherdev alloc failed\n");
+               goto err_alloc_etherdev;
+       }
+
+       err = atl1c_init_netdev(netdev, pdev);
+       if (err) {
+               dev_err(&pdev->dev, "init netdevice failed\n");
+               goto err_init_netdev;
+       }
+       adapter = netdev_priv(netdev);
+       adapter->bd_number = cards_found;
+       adapter->netdev = netdev;
+       adapter->pdev = pdev;
+       adapter->hw.adapter = adapter;
+       adapter->msg_enable = netif_msg_init(-1, atl1c_default_msg);
+       adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+       if (!adapter->hw.hw_addr) {
+               err = -EIO;
+               dev_err(&pdev->dev, "cannot map device registers\n");
+               goto err_ioremap;
+       }
+       netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
+
+       /* init mii data */
+       adapter->mii.dev = netdev;
+       adapter->mii.mdio_read  = atl1c_mdio_read;
+       adapter->mii.mdio_write = atl1c_mdio_write;
+       adapter->mii.phy_id_mask = 0x1f;
+       adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
+       netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
+       setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
+                       (unsigned long)adapter);
+       /* setup the private structure */
+       err = atl1c_sw_init(adapter);
+       if (err) {
+               dev_err(&pdev->dev, "net device private data init failed\n");
+               goto err_sw_init;
+       }
+       atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
+                       ATL1C_PCIE_PHY_RESET);
+
+       /* Init GPHY as early as possible due to power saving issue  */
+       atl1c_phy_reset(&adapter->hw);
+
+       err = atl1c_reset_mac(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               goto err_reset;
+       }
+
+       /* reset the controller to
+        * put the device in a known good starting state */
+       err = atl1c_phy_init(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               goto err_reset;
+       }
+       if (atl1c_read_mac_addr(&adapter->hw) != 0) {
+               err = -EIO;
+               dev_err(&pdev->dev, "get mac address failed\n");
+               goto err_eeprom;
+       }
+       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+       if (netif_msg_probe(adapter))
+               dev_dbg(&pdev->dev, "mac address : %pM\n",
+                       adapter->hw.mac_addr);
+
+       atl1c_hw_set_mac_addr(&adapter->hw);
+       INIT_WORK(&adapter->common_task, atl1c_common_task);
+       adapter->work_event = 0;
+       err = register_netdev(netdev);
+       if (err) {
+               dev_err(&pdev->dev, "register netdevice failed\n");
+               goto err_register;
+       }
+
+       if (netif_msg_probe(adapter))
+               dev_info(&pdev->dev, "version %s\n", ATL1C_DRV_VERSION);
+       cards_found++;
+       return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+err_eeprom:
+       iounmap(adapter->hw.hw_addr);
+err_init_netdev:
+err_ioremap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+       pci_disable_device(pdev);
+       return err;
+}
+
+/*
+ * atl1c_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl1c_remove 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 __devexit atl1c_remove(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       unregister_netdev(netdev);
+       atl1c_phy_disable(&adapter->hw);
+
+       iounmap(adapter->hw.hw_addr);
+
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       free_netdev(netdev);
+}
+
+/*
+ * atl1c_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev,
+                                               pci_channel_state_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       netif_device_detach(netdev);
+
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+
+       if (netif_running(netdev))
+               atl1c_down(adapter);
+
+       pci_disable_device(pdev);
+
+       /* Request a slot slot reset. */
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/*
+ * atl1c_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t atl1c_io_slot_reset(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       if (pci_enable_device(pdev)) {
+               if (netif_msg_hw(adapter))
+                       dev_err(&pdev->dev,
+                               "Cannot re-enable PCI device after reset\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+       pci_set_master(pdev);
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       atl1c_reset_mac(&adapter->hw);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/*
+ * atl1c_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * 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 atl1c_resume routine.
+ */
+static void atl1c_io_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       if (netif_running(netdev)) {
+               if (atl1c_up(adapter)) {
+                       if (netif_msg_hw(adapter))
+                               dev_err(&pdev->dev,
+                                       "Cannot bring device back up after reset\n");
+                       return;
+               }
+       }
+
+       netif_device_attach(netdev);
+}
+
+static struct pci_error_handlers atl1c_err_handler = {
+       .error_detected = atl1c_io_error_detected,
+       .slot_reset = atl1c_io_slot_reset,
+       .resume = atl1c_io_resume,
+};
+
+static SIMPLE_DEV_PM_OPS(atl1c_pm_ops, atl1c_suspend, atl1c_resume);
+
+static struct pci_driver atl1c_driver = {
+       .name     = atl1c_driver_name,
+       .id_table = atl1c_pci_tbl,
+       .probe    = atl1c_probe,
+       .remove   = __devexit_p(atl1c_remove),
+       .shutdown = atl1c_shutdown,
+       .err_handler = &atl1c_err_handler,
+       .driver.pm = &atl1c_pm_ops,
+};
+
+/*
+ * atl1c_init_module - Driver Registration Routine
+ *
+ * atl1c_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl1c_init_module(void)
+{
+       return pci_register_driver(&atl1c_driver);
+}
+
+/*
+ * atl1c_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl1c_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl1c_exit_module(void)
+{
+       pci_unregister_driver(&atl1c_driver);
+}
+
+module_init(atl1c_init_module);
+module_exit(atl1c_exit_module);
diff --git a/drivers/net/ethernet/atheros/atl1e/Makefile b/drivers/net/ethernet/atheros/atl1e/Makefile
new file mode 100644 (file)
index 0000000..bc11be8
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ATL1E)    += atl1e.o
+atl1e-objs             += atl1e_main.o atl1e_hw.o atl1e_ethtool.o atl1e_param.o
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h
new file mode 100644 (file)
index 0000000..829b5ad
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ * Copyright(c) 2007 xiong huang <xiong.huang@atheros.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#ifndef _ATL1E_H_
+#define _ATL1E_H_
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/mii.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/tcp.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/workqueue.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include "atl1e_hw.h"
+
+#define PCI_REG_COMMAND         0x04    /* PCI Command Register */
+#define CMD_IO_SPACE    0x0001
+#define CMD_MEMORY_SPACE 0x0002
+#define CMD_BUS_MASTER   0x0004
+
+#define BAR_0   0
+#define BAR_1   1
+#define BAR_5   5
+
+/* Wake Up Filter Control */
+#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define AT_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
+#define AT_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
+#define AT_WUFC_MC   0x00000008 /* Multicast Wakeup Enable */
+#define AT_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
+
+#define SPEED_0                   0xffff
+#define HALF_DUPLEX        1
+#define FULL_DUPLEX        2
+
+/* Error Codes */
+#define AT_ERR_EEPROM      1
+#define AT_ERR_PHY         2
+#define AT_ERR_CONFIG      3
+#define AT_ERR_PARAM       4
+#define AT_ERR_MAC_TYPE    5
+#define AT_ERR_PHY_TYPE    6
+#define AT_ERR_PHY_SPEED   7
+#define AT_ERR_PHY_RES     8
+#define AT_ERR_TIMEOUT     9
+
+#define MAX_JUMBO_FRAME_SIZE 0x2000
+
+#define AT_VLAN_TAG_TO_TPD_TAG(_vlan, _tpd)    \
+       _tpd = (((_vlan) << (4)) | (((_vlan) >> 13) & 7) |\
+                (((_vlan) >> 9) & 8))
+
+#define AT_TPD_TAG_TO_VLAN_TAG(_tpd, _vlan)    \
+       _vlan = (((_tpd) >> 8) | (((_tpd) & 0x77) << 9) |\
+                  (((_tdp) & 0x88) << 5))
+
+#define AT_MAX_RECEIVE_QUEUE    4
+#define AT_PAGE_NUM_PER_QUEUE   2
+
+#define AT_DMA_HI_ADDR_MASK     0xffffffff00000000ULL
+#define AT_DMA_LO_ADDR_MASK     0x00000000ffffffffULL
+
+#define AT_TX_WATCHDOG  (5 * HZ)
+#define AT_MAX_INT_WORK                10
+#define AT_TWSI_EEPROM_TIMEOUT         100
+#define AT_HW_MAX_IDLE_DELAY   10
+#define AT_SUSPEND_LINK_TIMEOUT 28
+
+#define AT_REGS_LEN    75
+#define AT_EEPROM_LEN  512
+#define AT_ADV_MASK    (ADVERTISE_10_HALF  |\
+                        ADVERTISE_10_FULL  |\
+                        ADVERTISE_100_HALF |\
+                        ADVERTISE_100_FULL |\
+                        ADVERTISE_1000_FULL)
+
+/* tpd word 2 */
+#define TPD_BUFLEN_MASK        0x3FFF
+#define TPD_BUFLEN_SHIFT        0
+#define TPD_DMAINT_MASK                0x0001
+#define TPD_DMAINT_SHIFT        14
+#define TPD_PKTNT_MASK          0x0001
+#define TPD_PKTINT_SHIFT        15
+#define TPD_VLANTAG_MASK        0xFFFF
+#define TPD_VLAN_SHIFT          16
+
+/* tpd word 3 bits 0:4 */
+#define TPD_EOP_MASK            0x0001
+#define TPD_EOP_SHIFT           0
+#define TPD_IP_VERSION_MASK    0x0001
+#define TPD_IP_VERSION_SHIFT   1       /* 0 : IPV4, 1 : IPV6 */
+#define TPD_INS_VL_TAG_MASK    0x0001
+#define TPD_INS_VL_TAG_SHIFT   2
+#define TPD_CC_SEGMENT_EN_MASK 0x0001
+#define TPD_CC_SEGMENT_EN_SHIFT        3
+#define TPD_SEGMENT_EN_MASK     0x0001
+#define TPD_SEGMENT_EN_SHIFT    4
+
+/* tdp word 3 bits 5:7 if ip version is 0 */
+#define TPD_IP_CSUM_MASK        0x0001
+#define TPD_IP_CSUM_SHIFT       5
+#define TPD_TCP_CSUM_MASK       0x0001
+#define TPD_TCP_CSUM_SHIFT      6
+#define TPD_UDP_CSUM_MASK       0x0001
+#define TPD_UDP_CSUM_SHIFT      7
+
+/* tdp word 3 bits 5:7 if ip version is 1 */
+#define TPD_V6_IPHLLO_MASK     0x0007
+#define TPD_V6_IPHLLO_SHIFT    7
+
+/* tpd word 3 bits 8:9 bit */
+#define TPD_VL_TAGGED_MASK      0x0001
+#define TPD_VL_TAGGED_SHIFT     8
+#define TPD_ETHTYPE_MASK        0x0001
+#define TPD_ETHTYPE_SHIFT       9
+
+/* tdp word 3 bits 10:13 if ip version is 0 */
+#define TDP_V4_IPHL_MASK       0x000F
+#define TPD_V4_IPHL_SHIFT      10
+
+/* tdp word 3 bits 10:13 if ip version is 1 */
+#define TPD_V6_IPHLHI_MASK     0x000F
+#define TPD_V6_IPHLHI_SHIFT    10
+
+/* tpd word 3 bit 14:31 if segment enabled */
+#define TPD_TCPHDRLEN_MASK      0x000F
+#define TPD_TCPHDRLEN_SHIFT     14
+#define TPD_HDRFLAG_MASK        0x0001
+#define TPD_HDRFLAG_SHIFT       18
+#define TPD_MSS_MASK            0x1FFF
+#define TPD_MSS_SHIFT           19
+
+/* tdp word 3 bit 16:31 if custom csum enabled */
+#define TPD_PLOADOFFSET_MASK    0x00FF
+#define TPD_PLOADOFFSET_SHIFT   16
+#define TPD_CCSUMOFFSET_MASK    0x00FF
+#define TPD_CCSUMOFFSET_SHIFT   24
+
+struct atl1e_tpd_desc {
+       __le64 buffer_addr;
+       __le32 word2;
+       __le32 word3;
+};
+
+/* how about 0x2000 */
+#define MAX_TX_BUF_LEN      0x2000
+#define MAX_TX_BUF_SHIFT    13
+/*#define MAX_TX_BUF_LEN  0x3000 */
+
+/* rrs word 1 bit 0:31 */
+#define RRS_RX_CSUM_MASK       0xFFFF
+#define RRS_RX_CSUM_SHIFT      0
+#define RRS_PKT_SIZE_MASK      0x3FFF
+#define RRS_PKT_SIZE_SHIFT     16
+#define RRS_CPU_NUM_MASK       0x0003
+#define        RRS_CPU_NUM_SHIFT       30
+
+#define        RRS_IS_RSS_IPV4         0x0001
+#define RRS_IS_RSS_IPV4_TCP    0x0002
+#define RRS_IS_RSS_IPV6                0x0004
+#define RRS_IS_RSS_IPV6_TCP    0x0008
+#define RRS_IS_IPV6            0x0010
+#define RRS_IS_IP_FRAG         0x0020
+#define RRS_IS_IP_DF           0x0040
+#define RRS_IS_802_3           0x0080
+#define RRS_IS_VLAN_TAG                0x0100
+#define RRS_IS_ERR_FRAME       0x0200
+#define RRS_IS_IPV4            0x0400
+#define RRS_IS_UDP             0x0800
+#define RRS_IS_TCP             0x1000
+#define RRS_IS_BCAST           0x2000
+#define RRS_IS_MCAST           0x4000
+#define RRS_IS_PAUSE           0x8000
+
+#define RRS_ERR_BAD_CRC                0x0001
+#define RRS_ERR_CODE           0x0002
+#define RRS_ERR_DRIBBLE                0x0004
+#define RRS_ERR_RUNT           0x0008
+#define RRS_ERR_RX_OVERFLOW    0x0010
+#define RRS_ERR_TRUNC          0x0020
+#define RRS_ERR_IP_CSUM                0x0040
+#define RRS_ERR_L4_CSUM                0x0080
+#define RRS_ERR_LENGTH         0x0100
+#define RRS_ERR_DES_ADDR       0x0200
+
+struct atl1e_recv_ret_status {
+       u16 seq_num;
+       u16 hash_lo;
+       __le32  word1;
+       u16 pkt_flag;
+       u16 err_flag;
+       u16 hash_hi;
+       u16 vtag;
+};
+
+enum atl1e_dma_req_block {
+       atl1e_dma_req_128 = 0,
+       atl1e_dma_req_256 = 1,
+       atl1e_dma_req_512 = 2,
+       atl1e_dma_req_1024 = 3,
+       atl1e_dma_req_2048 = 4,
+       atl1e_dma_req_4096 = 5
+};
+
+enum atl1e_rrs_type {
+       atl1e_rrs_disable = 0,
+       atl1e_rrs_ipv4 = 1,
+       atl1e_rrs_ipv4_tcp = 2,
+       atl1e_rrs_ipv6 = 4,
+       atl1e_rrs_ipv6_tcp = 8
+};
+
+enum atl1e_nic_type {
+       athr_l1e = 0,
+       athr_l2e_revA = 1,
+       athr_l2e_revB = 2
+};
+
+struct atl1e_hw_stats {
+       /* rx */
+       unsigned long rx_ok;          /* The number of good packet received. */
+       unsigned long rx_bcast;       /* The number of good broadcast packet received. */
+       unsigned long rx_mcast;       /* The number of good multicast packet received. */
+       unsigned long rx_pause;       /* The number of Pause packet received. */
+       unsigned long rx_ctrl;        /* The number of Control packet received other than Pause frame. */
+       unsigned long rx_fcs_err;     /* The number of packets with bad FCS. */
+       unsigned long rx_len_err;     /* The number of packets with mismatch of length field and actual size. */
+       unsigned long rx_byte_cnt;    /* The number of bytes of good packet received. FCS is NOT included. */
+       unsigned long rx_runt;        /* The number of packets received that are less than 64 byte long and with good FCS. */
+       unsigned long rx_frag;        /* The number of packets received that are less than 64 byte long and with bad FCS. */
+       unsigned long rx_sz_64;       /* The number of good and bad packets received that are 64 byte long. */
+       unsigned long rx_sz_65_127;   /* The number of good and bad packets received that are between 65 and 127-byte long. */
+       unsigned long rx_sz_128_255;  /* The number of good and bad packets received that are between 128 and 255-byte long. */
+       unsigned long rx_sz_256_511;  /* The number of good and bad packets received that are between 256 and 511-byte long. */
+       unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
+       unsigned long rx_sz_1024_1518;    /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
+       unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
+       unsigned long rx_sz_ov;       /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
+       unsigned long rx_rxf_ov;      /* The number of frame dropped due to occurrence of RX FIFO overflow. */
+       unsigned long rx_rrd_ov;      /* The number of frame dropped due to occurrence of RRD overflow. */
+       unsigned long rx_align_err;   /* Alignment Error */
+       unsigned long rx_bcast_byte_cnt;  /* The byte count of broadcast packet received, excluding FCS. */
+       unsigned long rx_mcast_byte_cnt;  /* The byte count of multicast packet received, excluding FCS. */
+       unsigned long rx_err_addr;    /* The number of packets dropped due to address filtering. */
+
+       /* tx */
+       unsigned long tx_ok;      /* The number of good packet transmitted. */
+       unsigned long tx_bcast;       /* The number of good broadcast packet transmitted. */
+       unsigned long tx_mcast;       /* The number of good multicast packet transmitted. */
+       unsigned long tx_pause;       /* The number of Pause packet transmitted. */
+       unsigned long tx_exc_defer;   /* The number of packets transmitted with excessive deferral. */
+       unsigned long tx_ctrl;        /* The number of packets transmitted is a control frame, excluding Pause frame. */
+       unsigned long tx_defer;       /* The number of packets transmitted that is deferred. */
+       unsigned long tx_byte_cnt;    /* The number of bytes of data transmitted. FCS is NOT included. */
+       unsigned long tx_sz_64;       /* The number of good and bad packets transmitted that are 64 byte long. */
+       unsigned long tx_sz_65_127;   /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
+       unsigned long tx_sz_128_255;  /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
+       unsigned long tx_sz_256_511;  /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
+       unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
+       unsigned long tx_sz_1024_1518;    /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
+       unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
+       unsigned long tx_1_col;       /* The number of packets subsequently transmitted successfully with a single prior collision. */
+       unsigned long tx_2_col;       /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
+       unsigned long tx_late_col;    /* The number of packets transmitted with late collisions. */
+       unsigned long tx_abort_col;   /* The number of transmit packets aborted due to excessive collisions. */
+       unsigned long tx_underrun;    /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
+       unsigned long tx_rd_eop;      /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
+       unsigned long tx_len_err;     /* The number of transmit packets with length field does NOT match the actual frame size. */
+       unsigned long tx_trunc;       /* The number of transmit packets truncated due to size exceeding MTU. */
+       unsigned long tx_bcast_byte;  /* The byte count of broadcast packet transmitted, excluding FCS. */
+       unsigned long tx_mcast_byte;  /* The byte count of multicast packet transmitted, excluding FCS. */
+};
+
+struct atl1e_hw {
+       u8 __iomem      *hw_addr;            /* inner register address */
+       resource_size_t mem_rang;
+       struct atl1e_adapter *adapter;
+       enum atl1e_nic_type  nic_type;
+       u16 device_id;
+       u16 vendor_id;
+       u16 subsystem_id;
+       u16 subsystem_vendor_id;
+       u8  revision_id;
+       u16 pci_cmd_word;
+       u8 mac_addr[ETH_ALEN];
+       u8 perm_mac_addr[ETH_ALEN];
+       u8 preamble_len;
+       u16 max_frame_size;
+       u16 rx_jumbo_th;
+       u16 tx_jumbo_th;
+
+       u16 media_type;
+#define MEDIA_TYPE_AUTO_SENSOR  0
+#define MEDIA_TYPE_100M_FULL    1
+#define MEDIA_TYPE_100M_HALF    2
+#define MEDIA_TYPE_10M_FULL     3
+#define MEDIA_TYPE_10M_HALF     4
+
+       u16 autoneg_advertised;
+#define ADVERTISE_10_HALF               0x0001
+#define ADVERTISE_10_FULL               0x0002
+#define ADVERTISE_100_HALF              0x0004
+#define ADVERTISE_100_FULL              0x0008
+#define ADVERTISE_1000_HALF             0x0010 /* Not used, just FYI */
+#define ADVERTISE_1000_FULL             0x0020
+       u16 mii_autoneg_adv_reg;
+       u16 mii_1000t_ctrl_reg;
+
+       u16 imt;        /* Interrupt Moderator timer ( 2us resolution) */
+       u16 ict;        /* Interrupt Clear timer (2us resolution) */
+       u32 smb_timer;
+       u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
+                         interrupt request */
+       u16 tpd_thresh;
+       u16 rx_count_down; /* 2us resolution */
+       u16 tx_count_down;
+
+       u8 tpd_burst;   /* Number of TPD to prefetch in cache-aligned burst. */
+       enum atl1e_rrs_type rrs_type;
+       u32 base_cpu;
+       u32 indirect_tab;
+
+       enum atl1e_dma_req_block dmar_block;
+       enum atl1e_dma_req_block dmaw_block;
+       u8 dmaw_dly_cnt;
+       u8 dmar_dly_cnt;
+
+       bool phy_configured;
+       bool re_autoneg;
+       bool emi_ca;
+};
+
+/*
+ * wrapper around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer
+ */
+struct atl1e_tx_buffer {
+       struct sk_buff *skb;
+       u16 flags;
+#define ATL1E_TX_PCIMAP_SINGLE         0x0001
+#define ATL1E_TX_PCIMAP_PAGE           0x0002
+#define ATL1E_TX_PCIMAP_TYPE_MASK      0x0003
+       u16 length;
+       dma_addr_t dma;
+};
+
+#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do {              \
+       ((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK;       \
+       ((tx_buff)->flags) |= (type);                           \
+       } while (0)
+
+struct atl1e_rx_page {
+       dma_addr_t      dma;    /* receive rage DMA address */
+       u8              *addr;   /* receive rage virtual address */
+       dma_addr_t      write_offset_dma;  /* the DMA address which contain the
+                                             receive data offset in the page */
+       u32             *write_offset_addr; /* the virtaul address which contain
+                                            the receive data offset in the page */
+       u32             read_offset;       /* the offset where we have read */
+};
+
+struct atl1e_rx_page_desc {
+       struct atl1e_rx_page   rx_page[AT_PAGE_NUM_PER_QUEUE];
+       u8  rx_using;
+       u16 rx_nxseq;
+};
+
+/* transmit packet descriptor (tpd) ring */
+struct atl1e_tx_ring {
+       struct atl1e_tpd_desc *desc;  /* descriptor ring virtual address  */
+       dma_addr_t         dma;    /* descriptor ring physical address */
+       u16                count;  /* the count of transmit rings  */
+       rwlock_t           tx_lock;
+       u16                next_to_use;
+       atomic_t           next_to_clean;
+       struct atl1e_tx_buffer *tx_buffer;
+       dma_addr_t         cmb_dma;
+       u32                *cmb;
+};
+
+/* receive packet descriptor ring */
+struct atl1e_rx_ring {
+       void            *desc;
+       dma_addr_t      dma;
+       int             size;
+       u32             page_size; /* bytes length of rxf page */
+       u32             real_page_size; /* real_page_size = page_size + jumbo + aliagn */
+       struct atl1e_rx_page_desc       rx_page_desc[AT_MAX_RECEIVE_QUEUE];
+};
+
+/* board specific private data structure */
+struct atl1e_adapter {
+       struct net_device   *netdev;
+       struct pci_dev      *pdev;
+       struct napi_struct  napi;
+       struct mii_if_info  mii;    /* MII interface info */
+       struct atl1e_hw        hw;
+       struct atl1e_hw_stats  hw_stats;
+
+       bool have_msi;
+       u32 wol;
+       u16 link_speed;
+       u16 link_duplex;
+
+       spinlock_t mdio_lock;
+       spinlock_t tx_lock;
+       atomic_t irq_sem;
+
+       struct work_struct reset_task;
+       struct work_struct link_chg_task;
+       struct timer_list watchdog_timer;
+       struct timer_list phy_config_timer;
+
+       /* All Descriptor memory */
+       dma_addr_t      ring_dma;
+       void            *ring_vir_addr;
+       u32             ring_size;
+
+       struct atl1e_tx_ring tx_ring;
+       struct atl1e_rx_ring rx_ring;
+       int num_rx_queues;
+       unsigned long flags;
+#define __AT_TESTING        0x0001
+#define __AT_RESETTING      0x0002
+#define __AT_DOWN           0x0003
+
+       u32 bd_number;     /* board number;*/
+       u32 pci_state[16];
+       u32 *config_space;
+};
+
+#define AT_WRITE_REG(a, reg, value) ( \
+               writel((value), ((a)->hw_addr + reg)))
+
+#define AT_WRITE_FLUSH(a) (\
+               readl((a)->hw_addr))
+
+#define AT_READ_REG(a, reg) ( \
+               readl((a)->hw_addr + reg))
+
+#define AT_WRITE_REGB(a, reg, value) (\
+               writeb((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGB(a, reg) (\
+               readb((a)->hw_addr + reg))
+
+#define AT_WRITE_REGW(a, reg, value) (\
+               writew((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGW(a, reg) (\
+               readw((a)->hw_addr + reg))
+
+#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+               writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
+
+#define AT_READ_REG_ARRAY(a, reg, offset) ( \
+               readl(((a)->hw_addr + reg) + ((offset) << 2)))
+
+extern char atl1e_driver_name[];
+extern char atl1e_driver_version[];
+
+extern void atl1e_check_options(struct atl1e_adapter *adapter);
+extern int atl1e_up(struct atl1e_adapter *adapter);
+extern void atl1e_down(struct atl1e_adapter *adapter);
+extern void atl1e_reinit_locked(struct atl1e_adapter *adapter);
+extern s32 atl1e_reset_hw(struct atl1e_hw *hw);
+extern void atl1e_set_ethtool_ops(struct net_device *netdev);
+#endif /* _ATL1_E_H_ */
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
new file mode 100644 (file)
index 0000000..6269438
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/slab.h>
+
+#include "atl1e.h"
+
+static int atl1e_get_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+
+       ecmd->supported = (SUPPORTED_10baseT_Half  |
+                          SUPPORTED_10baseT_Full  |
+                          SUPPORTED_100baseT_Half |
+                          SUPPORTED_100baseT_Full |
+                          SUPPORTED_Autoneg       |
+                          SUPPORTED_TP);
+       if (hw->nic_type == athr_l1e)
+               ecmd->supported |= SUPPORTED_1000baseT_Full;
+
+       ecmd->advertising = ADVERTISED_TP;
+
+       ecmd->advertising |= ADVERTISED_Autoneg;
+       ecmd->advertising |= hw->autoneg_advertised;
+
+       ecmd->port = PORT_TP;
+       ecmd->phy_address = 0;
+       ecmd->transceiver = XCVR_INTERNAL;
+
+       if (adapter->link_speed != SPEED_0) {
+               ethtool_cmd_speed_set(ecmd, adapter->link_speed);
+               if (adapter->link_duplex == FULL_DUPLEX)
+                       ecmd->duplex = DUPLEX_FULL;
+               else
+                       ecmd->duplex = DUPLEX_HALF;
+       } else {
+               ethtool_cmd_speed_set(ecmd, -1);
+               ecmd->duplex = -1;
+       }
+
+       ecmd->autoneg = AUTONEG_ENABLE;
+       return 0;
+}
+
+static int atl1e_set_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+
+       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+               msleep(1);
+
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               u16 adv4, adv9;
+
+               if ((ecmd->advertising&ADVERTISE_1000_FULL)) {
+                       if (hw->nic_type == athr_l1e) {
+                               hw->autoneg_advertised =
+                                       ecmd->advertising & AT_ADV_MASK;
+                       } else {
+                               clear_bit(__AT_RESETTING, &adapter->flags);
+                               return -EINVAL;
+                       }
+               } else if (ecmd->advertising&ADVERTISE_1000_HALF) {
+                       clear_bit(__AT_RESETTING, &adapter->flags);
+                       return -EINVAL;
+               } else {
+                       hw->autoneg_advertised =
+                               ecmd->advertising & AT_ADV_MASK;
+               }
+               ecmd->advertising = hw->autoneg_advertised |
+                                   ADVERTISED_TP | ADVERTISED_Autoneg;
+
+               adv4 = hw->mii_autoneg_adv_reg & ~ADVERTISE_ALL;
+               adv9 = hw->mii_1000t_ctrl_reg & ~MII_AT001_CR_1000T_SPEED_MASK;
+               if (hw->autoneg_advertised & ADVERTISE_10_HALF)
+                       adv4 |= ADVERTISE_10HALF;
+               if (hw->autoneg_advertised & ADVERTISE_10_FULL)
+                       adv4 |= ADVERTISE_10FULL;
+               if (hw->autoneg_advertised & ADVERTISE_100_HALF)
+                       adv4 |= ADVERTISE_100HALF;
+               if (hw->autoneg_advertised & ADVERTISE_100_FULL)
+                       adv4 |= ADVERTISE_100FULL;
+               if (hw->autoneg_advertised & ADVERTISE_1000_FULL)
+                       adv9 |= ADVERTISE_1000FULL;
+
+               if (adv4 != hw->mii_autoneg_adv_reg ||
+                               adv9 != hw->mii_1000t_ctrl_reg) {
+                       hw->mii_autoneg_adv_reg = adv4;
+                       hw->mii_1000t_ctrl_reg = adv9;
+                       hw->re_autoneg = true;
+               }
+
+       } else {
+               clear_bit(__AT_RESETTING, &adapter->flags);
+               return -EINVAL;
+       }
+
+       /* reset the link */
+
+       if (netif_running(adapter->netdev)) {
+               atl1e_down(adapter);
+               atl1e_up(adapter);
+       } else
+               atl1e_reset_hw(&adapter->hw);
+
+       clear_bit(__AT_RESETTING, &adapter->flags);
+       return 0;
+}
+
+static u32 atl1e_get_msglevel(struct net_device *netdev)
+{
+#ifdef DBG
+       return 1;
+#else
+       return 0;
+#endif
+}
+
+static int atl1e_get_regs_len(struct net_device *netdev)
+{
+       return AT_REGS_LEN * sizeof(u32);
+}
+
+static void atl1e_get_regs(struct net_device *netdev,
+                          struct ethtool_regs *regs, void *p)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 *regs_buff = p;
+       u16 phy_data;
+
+       memset(p, 0, AT_REGS_LEN * sizeof(u32));
+
+       regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
+
+       regs_buff[0]  = AT_READ_REG(hw, REG_VPD_CAP);
+       regs_buff[1]  = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
+       regs_buff[2]  = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG);
+       regs_buff[3]  = AT_READ_REG(hw, REG_TWSI_CTRL);
+       regs_buff[4]  = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
+       regs_buff[5]  = AT_READ_REG(hw, REG_MASTER_CTRL);
+       regs_buff[6]  = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT);
+       regs_buff[7]  = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
+       regs_buff[8]  = AT_READ_REG(hw, REG_GPHY_CTRL);
+       regs_buff[9]  = AT_READ_REG(hw, REG_CMBDISDMA_TIMER);
+       regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS);
+       regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL);
+       regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK);
+       regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL);
+       regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG);
+       regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
+       regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4);
+       regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE);
+       regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4);
+       regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
+       regs_buff[20] = AT_READ_REG(hw, REG_MTU);
+       regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL);
+       regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR);
+       regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN);
+       regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR);
+       regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
+       regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR);
+       regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN);
+       regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR);
+       regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR);
+
+       atl1e_read_phy_reg(hw, MII_BMCR, &phy_data);
+       regs_buff[73] = (u32)phy_data;
+       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
+       regs_buff[74] = (u32)phy_data;
+}
+
+static int atl1e_get_eeprom_len(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       if (!atl1e_check_eeprom_exist(&adapter->hw))
+               return AT_EEPROM_LEN;
+       else
+               return 0;
+}
+
+static int atl1e_get_eeprom(struct net_device *netdev,
+               struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 *eeprom_buff;
+       int first_dword, last_dword;
+       int ret_val = 0;
+       int i;
+
+       if (eeprom->len == 0)
+               return -EINVAL;
+
+       if (atl1e_check_eeprom_exist(hw)) /* not exist */
+               return -EINVAL;
+
+       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+
+       first_dword = eeprom->offset >> 2;
+       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+       eeprom_buff = kmalloc(sizeof(u32) *
+                       (last_dword - first_dword + 1), GFP_KERNEL);
+       if (eeprom_buff == NULL)
+               return -ENOMEM;
+
+       for (i = first_dword; i < last_dword; i++) {
+               if (!atl1e_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
+                       kfree(eeprom_buff);
+                       return -EIO;
+               }
+       }
+
+       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+                       eeprom->len);
+       kfree(eeprom_buff);
+
+       return ret_val;
+}
+
+static int atl1e_set_eeprom(struct net_device *netdev,
+                           struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 *eeprom_buff;
+       u32 *ptr;
+       int first_dword, last_dword;
+       int ret_val = 0;
+       int i;
+
+       if (eeprom->len == 0)
+               return -EOPNOTSUPP;
+
+       if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+               return -EINVAL;
+
+       first_dword = eeprom->offset >> 2;
+       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+       eeprom_buff = kmalloc(AT_EEPROM_LEN, GFP_KERNEL);
+       if (eeprom_buff == NULL)
+               return -ENOMEM;
+
+       ptr = (u32 *)eeprom_buff;
+
+       if (eeprom->offset & 3) {
+               /* need read/modify/write of first changed EEPROM word */
+               /* only the second byte of the word is being modified */
+               if (!atl1e_read_eeprom(hw, first_dword * 4, &(eeprom_buff[0]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+               ptr++;
+       }
+       if (((eeprom->offset + eeprom->len) & 3)) {
+               /* need read/modify/write of last changed EEPROM word */
+               /* only the first byte of the word is being modified */
+
+               if (!atl1e_read_eeprom(hw, last_dword * 4,
+                               &(eeprom_buff[last_dword - first_dword]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+       }
+
+       /* Device's eeprom is always little-endian, word addressable */
+       memcpy(ptr, bytes, eeprom->len);
+
+       for (i = 0; i < last_dword - first_dword + 1; i++) {
+               if (!atl1e_write_eeprom(hw, ((first_dword + i) * 4),
+                                 eeprom_buff[i])) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+       }
+out:
+       kfree(eeprom_buff);
+       return ret_val;
+}
+
+static void atl1e_get_drvinfo(struct net_device *netdev,
+               struct ethtool_drvinfo *drvinfo)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       strncpy(drvinfo->driver,  atl1e_driver_name, 32);
+       strncpy(drvinfo->version, atl1e_driver_version, 32);
+       strncpy(drvinfo->fw_version, "L1e", 32);
+       strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+       drvinfo->n_stats = 0;
+       drvinfo->testinfo_len = 0;
+       drvinfo->regdump_len = atl1e_get_regs_len(netdev);
+       drvinfo->eedump_len = atl1e_get_eeprom_len(netdev);
+}
+
+static void atl1e_get_wol(struct net_device *netdev,
+                         struct ethtool_wolinfo *wol)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       wol->supported = WAKE_MAGIC | WAKE_PHY;
+       wol->wolopts = 0;
+
+       if (adapter->wol & AT_WUFC_EX)
+               wol->wolopts |= WAKE_UCAST;
+       if (adapter->wol & AT_WUFC_MC)
+               wol->wolopts |= WAKE_MCAST;
+       if (adapter->wol & AT_WUFC_BC)
+               wol->wolopts |= WAKE_BCAST;
+       if (adapter->wol & AT_WUFC_MAG)
+               wol->wolopts |= WAKE_MAGIC;
+       if (adapter->wol & AT_WUFC_LNKC)
+               wol->wolopts |= WAKE_PHY;
+}
+
+static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
+                           WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
+               return -EOPNOTSUPP;
+       /* these settings will always override what we currently have */
+       adapter->wol = 0;
+
+       if (wol->wolopts & WAKE_MAGIC)
+               adapter->wol |= AT_WUFC_MAG;
+       if (wol->wolopts & WAKE_PHY)
+               adapter->wol |= AT_WUFC_LNKC;
+
+       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+       return 0;
+}
+
+static int atl1e_nway_reset(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       if (netif_running(netdev))
+               atl1e_reinit_locked(adapter);
+       return 0;
+}
+
+static const struct ethtool_ops atl1e_ethtool_ops = {
+       .get_settings           = atl1e_get_settings,
+       .set_settings           = atl1e_set_settings,
+       .get_drvinfo            = atl1e_get_drvinfo,
+       .get_regs_len           = atl1e_get_regs_len,
+       .get_regs               = atl1e_get_regs,
+       .get_wol                = atl1e_get_wol,
+       .set_wol                = atl1e_set_wol,
+       .get_msglevel           = atl1e_get_msglevel,
+       .nway_reset             = atl1e_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_eeprom_len         = atl1e_get_eeprom_len,
+       .get_eeprom             = atl1e_get_eeprom,
+       .set_eeprom             = atl1e_set_eeprom,
+};
+
+void atl1e_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &atl1e_ethtool_ops);
+}
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c
new file mode 100644 (file)
index 0000000..923063d
--- /dev/null
@@ -0,0 +1,651 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+
+#include "atl1e.h"
+
+/*
+ * check_eeprom_exist
+ * return 0 if eeprom exist
+ */
+int atl1e_check_eeprom_exist(struct atl1e_hw *hw)
+{
+       u32 value;
+
+       value = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
+       if (value & SPI_FLASH_CTRL_EN_VPD) {
+               value &= ~SPI_FLASH_CTRL_EN_VPD;
+               AT_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+       }
+       value = AT_READ_REGW(hw, REG_PCIE_CAP_LIST);
+       return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
+}
+
+void atl1e_hw_set_mac_addr(struct atl1e_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])) ;
+       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+       /* hight dword */
+       value = (((u32)hw->mac_addr[0]) << 8) |
+               (((u32)hw->mac_addr[1])) ;
+       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/*
+ * atl1e_get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int atl1e_get_permanent_address(struct atl1e_hw *hw)
+{
+       u32 addr[2];
+       u32 i;
+       u32 twsi_ctrl_data;
+       u8  eth_addr[ETH_ALEN];
+
+       if (is_valid_ether_addr(hw->perm_mac_addr))
+               return 0;
+
+       /* init */
+       addr[0] = addr[1] = 0;
+
+       if (!atl1e_check_eeprom_exist(hw)) {
+               /* eeprom exist */
+               twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
+               twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
+               AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
+               for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
+                       msleep(10);
+                       twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
+                       if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
+                               break;
+               }
+               if (i >= AT_TWSI_EEPROM_TIMEOUT)
+                       return AT_ERR_TIMEOUT;
+       }
+
+       /* maybe MAC-address is from BIOS */
+       addr[0] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
+       addr[1] = AT_READ_REG(hw, 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 AT_ERR_EEPROM;
+}
+
+bool atl1e_write_eeprom(struct atl1e_hw *hw, u32 offset, u32 value)
+{
+       return true;
+}
+
+bool atl1e_read_eeprom(struct atl1e_hw *hw, u32 offset, u32 *p_value)
+{
+       int i;
+       u32 control;
+
+       if (offset & 3)
+               return false; /* address do not align */
+
+       AT_WRITE_REG(hw, REG_VPD_DATA, 0);
+       control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
+       AT_WRITE_REG(hw, REG_VPD_CAP, control);
+
+       for (i = 0; i < 10; i++) {
+               msleep(2);
+               control = AT_READ_REG(hw, REG_VPD_CAP);
+               if (control & VPD_CAP_VPD_FLAG)
+                       break;
+       }
+       if (control & VPD_CAP_VPD_FLAG) {
+               *p_value = AT_READ_REG(hw, REG_VPD_DATA);
+               return true;
+       }
+       return false; /* timeout */
+}
+
+void atl1e_force_ps(struct atl1e_hw *hw)
+{
+       AT_WRITE_REGW(hw, REG_GPHY_CTRL,
+                       GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
+}
+
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+int atl1e_read_mac_addr(struct atl1e_hw *hw)
+{
+       int err = 0;
+
+       err = atl1e_get_permanent_address(hw);
+       if (err)
+               return AT_ERR_EEPROM;
+       memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
+       return 0;
+}
+
+/*
+ * atl1e_hash_mc_addr
+ *  purpose
+ *      set hash value for a multicast address
+ */
+u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
+{
+       u32 crc32;
+       u32 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 atl1e_hash_set(struct atl1e_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 = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+       mta |= (1 << hash_bit);
+
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+int atl1e_read_phy_reg(struct atl1e_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;
+
+       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+       wmb();
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               val = AT_READ_REG(hw, REG_MDIO_CTRL);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+               wmb();
+       }
+       if (!(val & (MDIO_START | MDIO_BUSY))) {
+               *phy_data = (u16)val;
+               return 0;
+       }
+
+       return AT_ERR_PHY;
+}
+
+/*
+ * 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
+ */
+int atl1e_write_phy_reg(struct atl1e_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;
+
+       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+       wmb();
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               val = AT_READ_REG(hw, REG_MDIO_CTRL);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+               wmb();
+       }
+
+       if (!(val & (MDIO_START | MDIO_BUSY)))
+               return 0;
+
+       return AT_ERR_PHY;
+}
+
+/*
+ * atl1e_init_pcie - init PCIE module
+ */
+static void atl1e_init_pcie(struct atl1e_hw *hw)
+{
+       u32 value;
+       /* comment 2lines below to save more power when sususpend
+          value = LTSSM_TEST_MODE_DEF;
+          AT_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value);
+        */
+
+       /* pcie flow control mode change */
+       value = AT_READ_REG(hw, 0x1008);
+       value |= 0x8000;
+       AT_WRITE_REG(hw, 0x1008, value);
+}
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
+{
+       s32 ret_val;
+       u16 mii_autoneg_adv_reg;
+       u16 mii_1000t_ctrl_reg;
+
+       if (0 != hw->mii_autoneg_adv_reg)
+               return 0;
+       /* Read the MII Auto-Neg Advertisement Register (Address 4/9). */
+       mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
+       mii_1000t_ctrl_reg  = MII_AT001_CR_1000T_DEFAULT_CAP_MASK;
+
+       /*
+        * Need to parse autoneg_advertised  and set up
+        * the appropriate PHY registers.  First we will parse for
+        * autoneg_advertised software override.  Since we can advertise
+        * a plethora of combinations, we need to check each bit
+        * individually.
+        */
+
+       /*
+        * 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 &= ~ADVERTISE_ALL;
+       mii_1000t_ctrl_reg  &= ~MII_AT001_CR_1000T_SPEED_MASK;
+
+       /*
+        * Need to parse MediaType and setup the
+        * appropriate PHY registers.
+        */
+       switch (hw->media_type) {
+       case MEDIA_TYPE_AUTO_SENSOR:
+               mii_autoneg_adv_reg |= ADVERTISE_ALL;
+               hw->autoneg_advertised = ADVERTISE_ALL;
+               if (hw->nic_type == athr_l1e) {
+                       mii_1000t_ctrl_reg |= ADVERTISE_1000FULL;
+                       hw->autoneg_advertised |= ADVERTISE_1000_FULL;
+               }
+               break;
+
+       case MEDIA_TYPE_100M_FULL:
+               mii_autoneg_adv_reg   |= ADVERTISE_100FULL;
+               hw->autoneg_advertised = ADVERTISE_100_FULL;
+               break;
+
+       case MEDIA_TYPE_100M_HALF:
+               mii_autoneg_adv_reg   |= ADVERTISE_100_HALF;
+               hw->autoneg_advertised = ADVERTISE_100_HALF;
+               break;
+
+       case MEDIA_TYPE_10M_FULL:
+               mii_autoneg_adv_reg   |= ADVERTISE_10_FULL;
+               hw->autoneg_advertised = ADVERTISE_10_FULL;
+               break;
+
+       default:
+               mii_autoneg_adv_reg   |= ADVERTISE_10_HALF;
+               hw->autoneg_advertised = ADVERTISE_10_HALF;
+               break;
+       }
+
+       /* flow control fixed to enable all */
+       mii_autoneg_adv_reg |= (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP);
+
+       hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
+       hw->mii_1000t_ctrl_reg  = mii_1000t_ctrl_reg;
+
+       ret_val = atl1e_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
+       if (ret_val)
+               return ret_val;
+
+       if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
+               ret_val = atl1e_write_phy_reg(hw, MII_CTRL1000,
+                                          mii_1000t_ctrl_reg);
+               if (ret_val)
+                       return ret_val;
+       }
+
+       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)
+ */
+int atl1e_phy_commit(struct atl1e_hw *hw)
+{
+       struct atl1e_adapter *adapter = hw->adapter;
+       int ret_val;
+       u16 phy_data;
+
+       phy_data = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART;
+
+       ret_val = atl1e_write_phy_reg(hw, MII_BMCR, phy_data);
+       if (ret_val) {
+               u32 val;
+               int i;
+               /**************************************
+                * pcie serdes link may be down !
+                **************************************/
+               for (i = 0; i < 25; i++) {
+                       msleep(1);
+                       val = AT_READ_REG(hw, REG_MDIO_CTRL);
+                       if (!(val & (MDIO_START | MDIO_BUSY)))
+                               break;
+               }
+
+               if (0 != (val & (MDIO_START | MDIO_BUSY))) {
+                       netdev_err(adapter->netdev,
+                                  "pcie linkdown at least for 25ms\n");
+                       return ret_val;
+               }
+
+               netdev_err(adapter->netdev, "pcie linkup after %d ms\n", i);
+       }
+       return 0;
+}
+
+int atl1e_phy_init(struct atl1e_hw *hw)
+{
+       struct atl1e_adapter *adapter = hw->adapter;
+       s32 ret_val;
+       u16 phy_val;
+
+       if (hw->phy_configured) {
+               if (hw->re_autoneg) {
+                       hw->re_autoneg = false;
+                       return atl1e_restart_autoneg(hw);
+               }
+               return 0;
+       }
+
+       /* RESET GPHY Core */
+       AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
+       msleep(2);
+       AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
+                     GPHY_CTRL_EXT_RESET);
+       msleep(2);
+
+       /* patches */
+       /* p1. eable hibernation mode */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0xB);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0xBC00);
+       if (ret_val)
+               return ret_val;
+       /* p2. set Class A/B for all modes */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0);
+       if (ret_val)
+               return ret_val;
+       phy_val = 0x02ef;
+       /* remove Class AB */
+       /* phy_val = hw->emi_ca ? 0x02ef : 0x02df; */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, phy_val);
+       if (ret_val)
+               return ret_val;
+       /* p3. 10B ??? */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x12);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x4C04);
+       if (ret_val)
+               return ret_val;
+       /* p4. 1000T power */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x4);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x8BBB);
+       if (ret_val)
+               return ret_val;
+
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x5);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x2C46);
+       if (ret_val)
+               return ret_val;
+
+       msleep(1);
+
+       /*Enable PHY LinkChange Interrupt */
+       ret_val = atl1e_write_phy_reg(hw, MII_INT_CTRL, 0xC00);
+       if (ret_val) {
+               netdev_err(adapter->netdev,
+                          "Error enable PHY linkChange Interrupt\n");
+               return ret_val;
+       }
+       /* setup AutoNeg parameters */
+       ret_val = atl1e_phy_setup_autoneg_adv(hw);
+       if (ret_val) {
+               netdev_err(adapter->netdev,
+                          "Error Setting up Auto-Negotiation\n");
+               return ret_val;
+       }
+       /* SW.Reset & En-Auto-Neg to restart Auto-Neg*/
+       netdev_dbg(adapter->netdev, "Restarting Auto-Negotiation\n");
+       ret_val = atl1e_phy_commit(hw);
+       if (ret_val) {
+               netdev_err(adapter->netdev, "Error resetting the phy\n");
+               return ret_val;
+       }
+
+       hw->phy_configured = true;
+
+       return 0;
+}
+
+/*
+ * 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)
+ */
+int atl1e_reset_hw(struct atl1e_hw *hw)
+{
+       struct atl1e_adapter *adapter = hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+
+       u32 idle_status_data = 0;
+       u16 pci_cfg_cmd_word = 0;
+       int timeout = 0;
+
+       /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
+       pci_read_config_word(pdev, PCI_REG_COMMAND, &pci_cfg_cmd_word);
+       if ((pci_cfg_cmd_word & (CMD_IO_SPACE |
+                               CMD_MEMORY_SPACE | CMD_BUS_MASTER))
+                       != (CMD_IO_SPACE | CMD_MEMORY_SPACE | CMD_BUS_MASTER)) {
+               pci_cfg_cmd_word |= (CMD_IO_SPACE |
+                                    CMD_MEMORY_SPACE | CMD_BUS_MASTER);
+               pci_write_config_word(pdev, PCI_REG_COMMAND, pci_cfg_cmd_word);
+       }
+
+       /*
+        * 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.
+        */
+       AT_WRITE_REG(hw, REG_MASTER_CTRL,
+                       MASTER_CTRL_LED_MODE | MASTER_CTRL_SOFT_RST);
+       wmb();
+       msleep(1);
+
+       /* Wait at least 10ms for All module to be Idle */
+       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+               idle_status_data = AT_READ_REG(hw, REG_IDLE_STATUS);
+               if (idle_status_data == 0)
+                       break;
+               msleep(1);
+               cpu_relax();
+       }
+
+       if (timeout >= AT_HW_MAX_IDLE_DELAY) {
+               netdev_err(adapter->netdev,
+                          "MAC state machine can't be idle since disabled for 10ms second\n");
+               return AT_ERR_TIMEOUT;
+       }
+
+       return 0;
+}
+
+
+/*
+ * 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.
+ */
+int atl1e_init_hw(struct atl1e_hw *hw)
+{
+       s32 ret_val = 0;
+
+       atl1e_init_pcie(hw);
+
+       /* Zero out the Multicast HASH table */
+       /* clear the old settings from the multicast hash table */
+       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+       ret_val = atl1e_phy_init(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
+ */
+int atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex)
+{
+       int err;
+       u16 phy_data;
+
+       /* Read   PHY Specific Status Register (17) */
+       err = atl1e_read_phy_reg(hw, MII_AT001_PSSR, &phy_data);
+       if (err)
+               return err;
+
+       if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED))
+               return AT_ERR_PHY_RES;
+
+       switch (phy_data & MII_AT001_PSSR_SPEED) {
+       case MII_AT001_PSSR_1000MBS:
+               *speed = SPEED_1000;
+               break;
+       case MII_AT001_PSSR_100MBS:
+               *speed = SPEED_100;
+               break;
+       case MII_AT001_PSSR_10MBS:
+               *speed = SPEED_10;
+               break;
+       default:
+               return AT_ERR_PHY_SPEED;
+               break;
+       }
+
+       if (phy_data & MII_AT001_PSSR_DPLX)
+               *duplex = FULL_DUPLEX;
+       else
+               *duplex = HALF_DUPLEX;
+
+       return 0;
+}
+
+int atl1e_restart_autoneg(struct atl1e_hw *hw)
+{
+       int err = 0;
+
+       err = atl1e_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
+       if (err)
+               return err;
+
+       if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
+               err = atl1e_write_phy_reg(hw, MII_CTRL1000,
+                                      hw->mii_1000t_ctrl_reg);
+               if (err)
+                       return err;
+       }
+
+       err = atl1e_write_phy_reg(hw, MII_BMCR,
+                       BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
+       return err;
+}
+
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_hw.h b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.h
new file mode 100644 (file)
index 0000000..74df16a
--- /dev/null
@@ -0,0 +1,690 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#ifndef _ATHL1E_HW_H_
+#define _ATHL1E_HW_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+
+struct atl1e_adapter;
+struct atl1e_hw;
+
+/* function prototype */
+s32 atl1e_reset_hw(struct atl1e_hw *hw);
+s32 atl1e_read_mac_addr(struct atl1e_hw *hw);
+s32 atl1e_init_hw(struct atl1e_hw *hw);
+s32 atl1e_phy_commit(struct atl1e_hw *hw);
+s32 atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex);
+u32 atl1e_auto_get_fc(struct atl1e_adapter *adapter, u16 duplex);
+u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr);
+void atl1e_hash_set(struct atl1e_hw *hw, u32 hash_value);
+s32 atl1e_read_phy_reg(struct atl1e_hw *hw, u16 reg_addr, u16 *phy_data);
+s32 atl1e_write_phy_reg(struct atl1e_hw *hw, u32 reg_addr, u16 phy_data);
+s32 atl1e_validate_mdi_setting(struct atl1e_hw *hw);
+void atl1e_hw_set_mac_addr(struct atl1e_hw *hw);
+bool atl1e_read_eeprom(struct atl1e_hw *hw, u32 offset, u32 *p_value);
+bool atl1e_write_eeprom(struct atl1e_hw *hw, u32 offset, u32 value);
+s32 atl1e_phy_enter_power_saving(struct atl1e_hw *hw);
+s32 atl1e_phy_leave_power_saving(struct atl1e_hw *hw);
+s32 atl1e_phy_init(struct atl1e_hw *hw);
+int atl1e_check_eeprom_exist(struct atl1e_hw *hw);
+void atl1e_force_ps(struct atl1e_hw *hw);
+s32 atl1e_restart_autoneg(struct atl1e_hw *hw);
+
+/* register definition */
+#define REG_PM_CTRLSTAT             0x44
+
+#define REG_PCIE_CAP_LIST           0x58
+
+#define REG_DEVICE_CAP              0x5C
+#define     DEVICE_CAP_MAX_PAYLOAD_MASK     0x7
+#define     DEVICE_CAP_MAX_PAYLOAD_SHIFT    0
+
+#define REG_DEVICE_CTRL             0x60
+#define     DEVICE_CTRL_MAX_PAYLOAD_MASK    0x7
+#define     DEVICE_CTRL_MAX_PAYLOAD_SHIFT   5
+#define     DEVICE_CTRL_MAX_RREQ_SZ_MASK    0x7
+#define     DEVICE_CTRL_MAX_RREQ_SZ_SHIFT   12
+
+#define REG_VPD_CAP                 0x6C
+#define     VPD_CAP_ID_MASK                 0xff
+#define     VPD_CAP_ID_SHIFT                0
+#define     VPD_CAP_NEXT_PTR_MASK           0xFF
+#define     VPD_CAP_NEXT_PTR_SHIFT          8
+#define     VPD_CAP_VPD_ADDR_MASK           0x7FFF
+#define     VPD_CAP_VPD_ADDR_SHIFT          16
+#define     VPD_CAP_VPD_FLAG                0x80000000
+
+#define REG_VPD_DATA                0x70
+
+#define REG_SPI_FLASH_CTRL          0x200
+#define     SPI_FLASH_CTRL_STS_NON_RDY      0x1
+#define     SPI_FLASH_CTRL_STS_WEN          0x2
+#define     SPI_FLASH_CTRL_STS_WPEN         0x80
+#define     SPI_FLASH_CTRL_DEV_STS_MASK     0xFF
+#define     SPI_FLASH_CTRL_DEV_STS_SHIFT    0
+#define     SPI_FLASH_CTRL_INS_MASK         0x7
+#define     SPI_FLASH_CTRL_INS_SHIFT        8
+#define     SPI_FLASH_CTRL_START            0x800
+#define     SPI_FLASH_CTRL_EN_VPD           0x2000
+#define     SPI_FLASH_CTRL_LDSTART          0x8000
+#define     SPI_FLASH_CTRL_CS_HI_MASK       0x3
+#define     SPI_FLASH_CTRL_CS_HI_SHIFT      16
+#define     SPI_FLASH_CTRL_CS_HOLD_MASK     0x3
+#define     SPI_FLASH_CTRL_CS_HOLD_SHIFT    18
+#define     SPI_FLASH_CTRL_CLK_LO_MASK      0x3
+#define     SPI_FLASH_CTRL_CLK_LO_SHIFT     20
+#define     SPI_FLASH_CTRL_CLK_HI_MASK      0x3
+#define     SPI_FLASH_CTRL_CLK_HI_SHIFT     22
+#define     SPI_FLASH_CTRL_CS_SETUP_MASK    0x3
+#define     SPI_FLASH_CTRL_CS_SETUP_SHIFT   24
+#define     SPI_FLASH_CTRL_EROM_PGSZ_MASK   0x3
+#define     SPI_FLASH_CTRL_EROM_PGSZ_SHIFT  26
+#define     SPI_FLASH_CTRL_WAIT_READY       0x10000000
+
+#define REG_SPI_ADDR                0x204
+
+#define REG_SPI_DATA                0x208
+
+#define REG_SPI_FLASH_CONFIG        0x20C
+#define     SPI_FLASH_CONFIG_LD_ADDR_MASK   0xFFFFFF
+#define     SPI_FLASH_CONFIG_LD_ADDR_SHIFT  0
+#define     SPI_FLASH_CONFIG_VPD_ADDR_MASK  0x3
+#define     SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24
+#define     SPI_FLASH_CONFIG_LD_EXIST       0x4000000
+
+
+#define REG_SPI_FLASH_OP_PROGRAM    0x210
+#define REG_SPI_FLASH_OP_SC_ERASE   0x211
+#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212
+#define REG_SPI_FLASH_OP_RDID       0x213
+#define REG_SPI_FLASH_OP_WREN       0x214
+#define REG_SPI_FLASH_OP_RDSR       0x215
+#define REG_SPI_FLASH_OP_WRSR       0x216
+#define REG_SPI_FLASH_OP_READ       0x217
+
+#define REG_TWSI_CTRL               0x218
+#define     TWSI_CTRL_LD_OFFSET_MASK        0xFF
+#define     TWSI_CTRL_LD_OFFSET_SHIFT       0
+#define     TWSI_CTRL_LD_SLV_ADDR_MASK      0x7
+#define     TWSI_CTRL_LD_SLV_ADDR_SHIFT     8
+#define     TWSI_CTRL_SW_LDSTART            0x800
+#define     TWSI_CTRL_HW_LDSTART            0x1000
+#define     TWSI_CTRL_SMB_SLV_ADDR_MASK     0x0x7F
+#define     TWSI_CTRL_SMB_SLV_ADDR_SHIFT    15
+#define     TWSI_CTRL_LD_EXIST              0x400000
+#define     TWSI_CTRL_READ_FREQ_SEL_MASK    0x3
+#define     TWSI_CTRL_READ_FREQ_SEL_SHIFT   23
+#define     TWSI_CTRL_FREQ_SEL_100K         0
+#define     TWSI_CTRL_FREQ_SEL_200K         1
+#define     TWSI_CTRL_FREQ_SEL_300K         2
+#define     TWSI_CTRL_FREQ_SEL_400K         3
+#define     TWSI_CTRL_SMB_SLV_ADDR
+#define     TWSI_CTRL_WRITE_FREQ_SEL_MASK   0x3
+#define     TWSI_CTRL_WRITE_FREQ_SEL_SHIFT  24
+
+
+#define REG_PCIE_DEV_MISC_CTRL      0x21C
+#define     PCIE_DEV_MISC_CTRL_EXT_PIPE     0x2
+#define     PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1
+#define     PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4
+#define     PCIE_DEV_MISC_CTRL_SERDES_ENDIAN    0x8
+#define     PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN   0x10
+
+#define REG_PCIE_PHYMISC           0x1000
+#define PCIE_PHYMISC_FORCE_RCV_DET     0x4
+
+#define REG_LTSSM_TEST_MODE         0x12FC
+#define         LTSSM_TEST_MODE_DEF     0xE000
+
+/* Selene Master Control Register */
+#define REG_MASTER_CTRL             0x1400
+#define     MASTER_CTRL_SOFT_RST            0x1
+#define     MASTER_CTRL_MTIMER_EN           0x2
+#define     MASTER_CTRL_ITIMER_EN           0x4
+#define     MASTER_CTRL_MANUAL_INT          0x8
+#define     MASTER_CTRL_ITIMER2_EN          0x20
+#define     MASTER_CTRL_INT_RDCLR           0x40
+#define     MASTER_CTRL_LED_MODE           0x200
+#define     MASTER_CTRL_REV_NUM_SHIFT       16
+#define     MASTER_CTRL_REV_NUM_MASK        0xff
+#define     MASTER_CTRL_DEV_ID_SHIFT        24
+#define     MASTER_CTRL_DEV_ID_MASK         0xff
+
+/* Timer Initial Value Register */
+#define REG_MANUAL_TIMER_INIT       0x1404
+
+
+/* IRQ ModeratorTimer Initial Value Register */
+#define REG_IRQ_MODU_TIMER_INIT     0x1408   /* w */
+#define REG_IRQ_MODU_TIMER2_INIT    0x140A   /* w */
+
+
+#define REG_GPHY_CTRL               0x140C
+#define     GPHY_CTRL_EXT_RESET         1
+#define     GPHY_CTRL_PIPE_MOD          2
+#define     GPHY_CTRL_TEST_MODE_MASK    3
+#define     GPHY_CTRL_TEST_MODE_SHIFT   2
+#define     GPHY_CTRL_BERT_START        0x10
+#define     GPHY_CTRL_GATE_25M_EN       0x20
+#define     GPHY_CTRL_LPW_EXIT          0x40
+#define     GPHY_CTRL_PHY_IDDQ          0x80
+#define     GPHY_CTRL_PHY_IDDQ_DIS      0x100
+#define     GPHY_CTRL_PCLK_SEL_DIS      0x200
+#define     GPHY_CTRL_HIB_EN            0x400
+#define     GPHY_CTRL_HIB_PULSE         0x800
+#define     GPHY_CTRL_SEL_ANA_RST       0x1000
+#define     GPHY_CTRL_PHY_PLL_ON        0x2000
+#define     GPHY_CTRL_PWDOWN_HW                0x4000
+#define     GPHY_CTRL_DEFAULT (\
+               GPHY_CTRL_PHY_PLL_ON    |\
+               GPHY_CTRL_SEL_ANA_RST   |\
+               GPHY_CTRL_HIB_PULSE     |\
+               GPHY_CTRL_HIB_EN)
+
+#define     GPHY_CTRL_PW_WOL_DIS (\
+               GPHY_CTRL_PHY_PLL_ON    |\
+               GPHY_CTRL_SEL_ANA_RST   |\
+               GPHY_CTRL_HIB_PULSE     |\
+               GPHY_CTRL_HIB_EN        |\
+               GPHY_CTRL_PWDOWN_HW     |\
+               GPHY_CTRL_PCLK_SEL_DIS  |\
+               GPHY_CTRL_PHY_IDDQ)
+
+/* IRQ Anti-Lost Timer Initial Value Register */
+#define REG_CMBDISDMA_TIMER         0x140E
+
+
+/* Block IDLE Status Register */
+#define REG_IDLE_STATUS        0x1410
+#define     IDLE_STATUS_RXMAC       1    /* 1: RXMAC state machine is in non-IDLE state. 0: RXMAC is idling */
+#define     IDLE_STATUS_TXMAC       2    /* 1: TXMAC state machine is in non-IDLE state. 0: TXMAC is idling */
+#define     IDLE_STATUS_RXQ         4    /* 1: RXQ state machine is in non-IDLE state.   0: RXQ is idling   */
+#define     IDLE_STATUS_TXQ         8    /* 1: TXQ state machine is in non-IDLE state.   0: TXQ is idling   */
+#define     IDLE_STATUS_DMAR        0x10 /* 1: DMAR state machine is in non-IDLE state.  0: DMAR is idling  */
+#define     IDLE_STATUS_DMAW        0x20 /* 1: DMAW state machine is in non-IDLE state.  0: DMAW is idling  */
+#define     IDLE_STATUS_SMB         0x40 /* 1: SMB state machine is in non-IDLE state.   0: SMB is idling   */
+#define     IDLE_STATUS_CMB         0x80 /* 1: CMB state machine is in non-IDLE state.   0: CMB is idling   */
+
+/* MDIO Control Register */
+#define REG_MDIO_CTRL           0x1414
+#define     MDIO_DATA_MASK          0xffff  /* On MDIO write, the 16-bit control data to write to PHY MII management register */
+#define     MDIO_DATA_SHIFT         0       /* On MDIO read, the 16-bit status data that was read from the PHY MII management register*/
+#define     MDIO_REG_ADDR_MASK      0x1f    /* MDIO register address */
+#define     MDIO_REG_ADDR_SHIFT     16
+#define     MDIO_RW                 0x200000      /* 1: read, 0: write */
+#define     MDIO_SUP_PREAMBLE       0x400000      /* Suppress preamble */
+#define     MDIO_START              0x800000      /* Write 1 to initiate the MDIO master. And this bit is self cleared after one cycle*/
+#define     MDIO_CLK_SEL_SHIFT      24
+#define     MDIO_CLK_25_4           0
+#define     MDIO_CLK_25_6           2
+#define     MDIO_CLK_25_8           3
+#define     MDIO_CLK_25_10          4
+#define     MDIO_CLK_25_14          5
+#define     MDIO_CLK_25_20          6
+#define     MDIO_CLK_25_28          7
+#define     MDIO_BUSY               0x8000000
+#define     MDIO_AP_EN              0x10000000
+#define MDIO_WAIT_TIMES         10
+
+/* MII PHY Status Register */
+#define REG_PHY_STATUS           0x1418
+#define     PHY_STATUS_100M          0x20000
+#define     PHY_STATUS_EMI_CA        0x40000
+
+/* BIST Control and Status Register0 (for the Packet Memory) */
+#define REG_BIST0_CTRL              0x141c
+#define     BIST0_NOW                   0x1 /* 1: To trigger BIST0 logic. This bit stays high during the */
+/* BIST process and reset to zero when BIST is done */
+#define     BIST0_SRAM_FAIL             0x2 /* 1: The SRAM failure is un-repairable because it has address */
+/* decoder failure or more than 1 cell stuck-to-x failure */
+#define     BIST0_FUSE_FLAG             0x4 /* 1: Indicating one cell has been fixed */
+
+/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
+#define REG_BIST1_CTRL              0x1420
+#define     BIST1_NOW                   0x1 /* 1: To trigger BIST0 logic. This bit stays high during the */
+/* BIST process and reset to zero when BIST is done */
+#define     BIST1_SRAM_FAIL             0x2 /* 1: The SRAM failure is un-repairable because it has address */
+/* decoder failure or more than 1 cell stuck-to-x failure.*/
+#define     BIST1_FUSE_FLAG             0x4
+
+/* SerDes Lock Detect Control and Status Register */
+#define REG_SERDES_LOCK             0x1424
+#define     SERDES_LOCK_DETECT          1  /* 1: SerDes lock detected . This signal comes from Analog SerDes */
+#define     SERDES_LOCK_DETECT_EN       2  /* 1: Enable SerDes Lock detect function */
+
+/* MAC Control Register  */
+#define REG_MAC_CTRL                0x1480
+#define     MAC_CTRL_TX_EN              1  /* 1: Transmit Enable */
+#define     MAC_CTRL_RX_EN              2  /* 1: Receive Enable */
+#define     MAC_CTRL_TX_FLOW            4  /* 1: Transmit Flow Control Enable */
+#define     MAC_CTRL_RX_FLOW            8  /* 1: Receive Flow Control Enable */
+#define     MAC_CTRL_LOOPBACK           0x10      /* 1: Loop back at G/MII Interface */
+#define     MAC_CTRL_DUPLX              0x20      /* 1: Full-duplex mode  0: Half-duplex mode */
+#define     MAC_CTRL_ADD_CRC            0x40      /* 1: Instruct MAC to attach CRC on all egress Ethernet frames */
+#define     MAC_CTRL_PAD                0x80      /* 1: Instruct MAC to pad short frames to 60-bytes, and then attach CRC. This bit has higher priority over CRC_EN */
+#define     MAC_CTRL_LENCHK             0x100     /* 1: Instruct MAC to check if length field matches the real packet length */
+#define     MAC_CTRL_HUGE_EN            0x200     /* 1: receive Jumbo frame enable */
+#define     MAC_CTRL_PRMLEN_SHIFT       10        /* Preamble length */
+#define     MAC_CTRL_PRMLEN_MASK        0xf
+#define     MAC_CTRL_RMV_VLAN           0x4000    /* 1: to remove VLAN Tag automatically from all receive packets */
+#define     MAC_CTRL_PROMIS_EN          0x8000    /* 1: Promiscuous Mode Enable */
+#define     MAC_CTRL_TX_PAUSE           0x10000   /* 1: transmit test pause */
+#define     MAC_CTRL_SCNT               0x20000   /* 1: shortcut slot time counter */
+#define     MAC_CTRL_SRST_TX            0x40000   /* 1: synchronized reset Transmit MAC module */
+#define     MAC_CTRL_TX_SIMURST         0x80000   /* 1: transmit simulation reset */
+#define     MAC_CTRL_SPEED_SHIFT        20        /* 10: gigabit 01:10M/100M */
+#define     MAC_CTRL_SPEED_MASK         0x300000
+#define     MAC_CTRL_SPEED_1000         2
+#define     MAC_CTRL_SPEED_10_100       1
+#define     MAC_CTRL_DBG_TX_BKPRESURE   0x400000  /* 1: transmit maximum backoff (half-duplex test bit) */
+#define     MAC_CTRL_TX_HUGE            0x800000  /* 1: transmit huge enable */
+#define     MAC_CTRL_RX_CHKSUM_EN       0x1000000 /* 1: RX checksum enable */
+#define     MAC_CTRL_MC_ALL_EN          0x2000000 /* 1: upload all multicast frame without error to system */
+#define     MAC_CTRL_BC_EN              0x4000000 /* 1: upload all broadcast frame without error to system */
+#define     MAC_CTRL_DBG                0x8000000 /* 1: upload all received frame to system (Debug Mode) */
+
+/* MAC IPG/IFG Control Register  */
+#define REG_MAC_IPG_IFG             0x1484
+#define     MAC_IPG_IFG_IPGT_SHIFT      0     /* Desired back to back inter-packet gap. The default is 96-bit time */
+#define     MAC_IPG_IFG_IPGT_MASK       0x7f
+#define     MAC_IPG_IFG_MIFG_SHIFT      8     /* Minimum number of IFG to enforce in between RX frames */
+#define     MAC_IPG_IFG_MIFG_MASK       0xff  /* Frame gap below such IFP is dropped */
+#define     MAC_IPG_IFG_IPGR1_SHIFT     16    /* 64bit Carrier-Sense window */
+#define     MAC_IPG_IFG_IPGR1_MASK      0x7f
+#define     MAC_IPG_IFG_IPGR2_SHIFT     24    /* 96-bit IPG window */
+#define     MAC_IPG_IFG_IPGR2_MASK      0x7f
+
+/* MAC STATION ADDRESS  */
+#define REG_MAC_STA_ADDR            0x1488
+
+/* Hash table for multicast address */
+#define REG_RX_HASH_TABLE           0x1490
+
+
+/* MAC Half-Duplex Control Register */
+#define REG_MAC_HALF_DUPLX_CTRL     0x1498
+#define     MAC_HALF_DUPLX_CTRL_LCOL_SHIFT   0      /* Collision Window */
+#define     MAC_HALF_DUPLX_CTRL_LCOL_MASK    0x3ff
+#define     MAC_HALF_DUPLX_CTRL_RETRY_SHIFT  12     /* Retransmission maximum, afterwards the packet will be discarded */
+#define     MAC_HALF_DUPLX_CTRL_RETRY_MASK   0xf
+#define     MAC_HALF_DUPLX_CTRL_EXC_DEF_EN   0x10000 /* 1: Allow the transmission of a packet which has been excessively deferred */
+#define     MAC_HALF_DUPLX_CTRL_NO_BACK_C    0x20000 /* 1: No back-off on collision, immediately start the retransmission */
+#define     MAC_HALF_DUPLX_CTRL_NO_BACK_P    0x40000 /* 1: No back-off on backpressure, immediately start the transmission after back pressure */
+#define     MAC_HALF_DUPLX_CTRL_ABEBE        0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
+#define     MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT  20      /* Maximum binary exponential number */
+#define     MAC_HALF_DUPLX_CTRL_ABEBT_MASK   0xf
+#define     MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24      /* IPG to start JAM for collision based flow control in half-duplex */
+#define     MAC_HALF_DUPLX_CTRL_JAMIPG_MASK  0xf     /* mode. In unit of 8-bit time */
+
+/* Maximum Frame Length Control Register   */
+#define REG_MTU                     0x149c
+
+/* Wake-On-Lan control register */
+#define REG_WOL_CTRL                0x14a0
+#define     WOL_PATTERN_EN                  0x00000001
+#define     WOL_PATTERN_PME_EN              0x00000002
+#define     WOL_MAGIC_EN                    0x00000004
+#define     WOL_MAGIC_PME_EN                0x00000008
+#define     WOL_LINK_CHG_EN                 0x00000010
+#define     WOL_LINK_CHG_PME_EN             0x00000020
+#define     WOL_PATTERN_ST                  0x00000100
+#define     WOL_MAGIC_ST                    0x00000200
+#define     WOL_LINKCHG_ST                  0x00000400
+#define     WOL_CLK_SWITCH_EN               0x00008000
+#define     WOL_PT0_EN                      0x00010000
+#define     WOL_PT1_EN                      0x00020000
+#define     WOL_PT2_EN                      0x00040000
+#define     WOL_PT3_EN                      0x00080000
+#define     WOL_PT4_EN                      0x00100000
+#define     WOL_PT5_EN                      0x00200000
+#define     WOL_PT6_EN                      0x00400000
+/* 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 Register */
+#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_ADDR          0x1530
+#define REG_SRAM_PKTH_ADDR          0x1532
+
+/* Load Ptr Register */
+#define REG_LOAD_PTR                0x1534  /* Software sets this bit after the initialization of the head and tail */
+
+/*
+ * addresses of all descriptors, as well as the following descriptor
+ * control register, which triggers each function block to load the head
+ * pointer to prepare for the operation. This bit is then self-cleared
+ * after one cycle.
+ */
+
+/* Descriptor Control register  */
+#define REG_RXF3_BASE_ADDR_HI           0x153C
+#define REG_DESC_BASE_ADDR_HI           0x1540
+#define REG_RXF0_BASE_ADDR_HI           0x1540 /* share with DESC BASE ADDR HI */
+#define REG_HOST_RXF0_PAGE0_LO          0x1544
+#define REG_HOST_RXF0_PAGE1_LO          0x1548
+#define REG_TPD_BASE_ADDR_LO            0x154C
+#define REG_RXF1_BASE_ADDR_HI           0x1550
+#define REG_RXF2_BASE_ADDR_HI           0x1554
+#define REG_HOST_RXFPAGE_SIZE           0x1558
+#define REG_TPD_RING_SIZE               0x155C
+/* RSS about */
+#define REG_RSS_KEY0                    0x14B0
+#define REG_RSS_KEY1                    0x14B4
+#define REG_RSS_KEY2                    0x14B8
+#define REG_RSS_KEY3                    0x14BC
+#define REG_RSS_KEY4                    0x14C0
+#define REG_RSS_KEY5                    0x14C4
+#define REG_RSS_KEY6                    0x14C8
+#define REG_RSS_KEY7                    0x14CC
+#define REG_RSS_KEY8                    0x14D0
+#define REG_RSS_KEY9                    0x14D4
+#define REG_IDT_TABLE4                  0x14E0
+#define REG_IDT_TABLE5                  0x14E4
+#define REG_IDT_TABLE6                  0x14E8
+#define REG_IDT_TABLE7                  0x14EC
+#define REG_IDT_TABLE0                  0x1560
+#define REG_IDT_TABLE1                  0x1564
+#define REG_IDT_TABLE2                  0x1568
+#define REG_IDT_TABLE3                  0x156C
+#define REG_IDT_TABLE                   REG_IDT_TABLE0
+#define REG_RSS_HASH_VALUE              0x1570
+#define REG_RSS_HASH_FLAG               0x1574
+#define REG_BASE_CPU_NUMBER             0x157C
+
+
+/* TXQ Control Register */
+#define REG_TXQ_CTRL                0x1580
+#define     TXQ_CTRL_NUM_TPD_BURST_MASK     0xF
+#define     TXQ_CTRL_NUM_TPD_BURST_SHIFT    0
+#define     TXQ_CTRL_EN                     0x20  /* 1: Enable TXQ */
+#define     TXQ_CTRL_ENH_MODE               0x40  /* Performance enhancement mode, in which up to two back-to-back DMA read commands might be dispatched. */
+#define     TXQ_CTRL_TXF_BURST_NUM_SHIFT    16    /* Number of data byte to read in a cache-aligned burst. Each SRAM entry is 8-byte in length. */
+#define     TXQ_CTRL_TXF_BURST_NUM_MASK     0xffff
+
+/* Jumbo packet Threshold for task offload */
+#define REG_TX_EARLY_TH                     0x1584 /* Jumbo frame threshold in QWORD unit. Packet greater than */
+/* JUMBO_TASK_OFFLOAD_THRESHOLD will not be task offloaded. */
+#define     TX_TX_EARLY_TH_MASK             0x7ff
+#define     TX_TX_EARLY_TH_SHIFT            0
+
+
+/* RXQ Control Register */
+#define REG_RXQ_CTRL                0x15A0
+#define         RXQ_CTRL_PBA_ALIGN_32                   0   /* rx-packet alignment */
+#define         RXQ_CTRL_PBA_ALIGN_64                   1
+#define         RXQ_CTRL_PBA_ALIGN_128                  2
+#define         RXQ_CTRL_PBA_ALIGN_256                  3
+#define         RXQ_CTRL_Q1_EN                         0x10
+#define         RXQ_CTRL_Q2_EN                         0x20
+#define         RXQ_CTRL_Q3_EN                         0x40
+#define         RXQ_CTRL_IPV6_XSUM_VERIFY_EN           0x80
+#define         RXQ_CTRL_HASH_TLEN_SHIFT                8
+#define         RXQ_CTRL_HASH_TLEN_MASK                 0xFF
+#define         RXQ_CTRL_HASH_TYPE_IPV4                 0x10000
+#define         RXQ_CTRL_HASH_TYPE_IPV4_TCP             0x20000
+#define         RXQ_CTRL_HASH_TYPE_IPV6                 0x40000
+#define         RXQ_CTRL_HASH_TYPE_IPV6_TCP             0x80000
+#define         RXQ_CTRL_RSS_MODE_DISABLE               0
+#define         RXQ_CTRL_RSS_MODE_SQSINT                0x4000000
+#define         RXQ_CTRL_RSS_MODE_MQUESINT              0x8000000
+#define         RXQ_CTRL_RSS_MODE_MQUEMINT              0xC000000
+#define         RXQ_CTRL_NIP_QUEUE_SEL_TBL              0x10000000
+#define         RXQ_CTRL_HASH_ENABLE                    0x20000000
+#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
+/*
+ * Jumbo packet threshold for non-VLAN packet, in QWORD (64-bit) unit.
+ * When the packet length greater than or equal to this value, RXQ
+ * shall start cut-through forwarding of the received packet.
+ */
+#define         RXQ_JMBOSZ_TH_MASK      0x7ff
+#define         RXQ_JMBOSZ_TH_SHIFT         0  /* RRD retirement timer. Decrement by 1 after every 512ns passes*/
+#define         RXQ_JMBO_LKAH_MASK          0xf
+#define         RXQ_JMBO_LKAH_SHIFT         11
+
+/* RXF flow control register */
+#define REG_RXQ_RXF_PAUSE_THRESH    0x15A8
+#define     RXQ_RXF_PAUSE_TH_HI_SHIFT       0
+#define     RXQ_RXF_PAUSE_TH_HI_MASK        0xfff
+#define     RXQ_RXF_PAUSE_TH_LO_SHIFT       16
+#define     RXQ_RXF_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_REQ_PRI           0x400
+#define     DMA_CTRL_DMAR_DLY_CNT_MASK      0x1F
+#define     DMA_CTRL_DMAR_DLY_CNT_SHIFT     11
+#define     DMA_CTRL_DMAW_DLY_CNT_MASK      0xF
+#define     DMA_CTRL_DMAW_DLY_CNT_SHIFT     16
+#define     DMA_CTRL_TXCMB_EN               0x100000
+#define     DMA_CTRL_RXCMB_EN                          0x200000
+
+
+/* CMB/SMB Control Register */
+#define REG_SMB_STAT_TIMER                      0x15C4
+#define REG_TRIG_RRD_THRESH                     0x15CA
+#define REG_TRIG_TPD_THRESH                     0x15C8
+#define REG_TRIG_TXTIMER                        0x15CC
+#define REG_TRIG_RXTIMER                        0x15CE
+
+/* HOST RXF Page 1,2,3 address */
+#define REG_HOST_RXF1_PAGE0_LO                  0x15D0
+#define REG_HOST_RXF1_PAGE1_LO                  0x15D4
+#define REG_HOST_RXF2_PAGE0_LO                  0x15D8
+#define REG_HOST_RXF2_PAGE1_LO                  0x15DC
+#define REG_HOST_RXF3_PAGE0_LO                  0x15E0
+#define REG_HOST_RXF3_PAGE1_LO                  0x15E4
+
+/* Mail box */
+#define REG_MB_RXF1_RADDR                       0x15B4
+#define REG_MB_RXF2_RADDR                       0x15B8
+#define REG_MB_RXF3_RADDR                       0x15BC
+#define REG_MB_TPD_PROD_IDX                     0x15F0
+
+/* RXF-Page 0-3  PageNo & Valid bit */
+#define REG_HOST_RXF0_PAGE0_VLD     0x15F4
+#define     HOST_RXF_VALID              1
+#define     HOST_RXF_PAGENO_SHIFT       1
+#define     HOST_RXF_PAGENO_MASK        0x7F
+#define REG_HOST_RXF0_PAGE1_VLD     0x15F5
+#define REG_HOST_RXF1_PAGE0_VLD     0x15F6
+#define REG_HOST_RXF1_PAGE1_VLD     0x15F7
+#define REG_HOST_RXF2_PAGE0_VLD     0x15F8
+#define REG_HOST_RXF2_PAGE1_VLD     0x15F9
+#define REG_HOST_RXF3_PAGE0_VLD     0x15FA
+#define REG_HOST_RXF3_PAGE1_VLD     0x15FB
+
+/* Interrupt Status Register */
+#define REG_ISR    0x1600
+#define  ISR_SMB               1
+#define  ISR_TIMER             2       /* Interrupt when Timer is counted down to zero */
+/*
+ * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
+ * in Table 51 Selene Master Control Register (Offset 0x1400).
+ */
+#define  ISR_MANUAL            4
+#define  ISR_HW_RXF_OV          8        /* RXF overflow interrupt */
+#define  ISR_HOST_RXF0_OV       0x10
+#define  ISR_HOST_RXF1_OV       0x20
+#define  ISR_HOST_RXF2_OV       0x40
+#define  ISR_HOST_RXF3_OV       0x80
+#define  ISR_TXF_UN             0x100
+#define  ISR_RX0_PAGE_FULL      0x200
+#define  ISR_DMAR_TO_RST        0x400
+#define  ISR_DMAW_TO_RST        0x800
+#define  ISR_GPHY               0x1000
+#define  ISR_TX_CREDIT          0x2000
+#define  ISR_GPHY_LPW           0x4000    /* GPHY low power state interrupt */
+#define  ISR_RX_PKT             0x10000   /* One packet received, triggered by RFD */
+#define  ISR_TX_PKT             0x20000   /* One packet transmitted, triggered by TPD */
+#define  ISR_TX_DMA             0x40000
+#define  ISR_RX_PKT_1           0x80000
+#define  ISR_RX_PKT_2           0x100000
+#define  ISR_RX_PKT_3           0x200000
+#define  ISR_MAC_RX             0x400000
+#define  ISR_MAC_TX             0x800000
+#define  ISR_UR_DETECTED        0x1000000
+#define  ISR_FERR_DETECTED      0x2000000
+#define  ISR_NFERR_DETECTED     0x4000000
+#define  ISR_CERR_DETECTED      0x8000000
+#define  ISR_PHY_LINKDOWN       0x10000000
+#define  ISR_DIS_INT            0x80000000
+
+
+/* Interrupt Mask Register */
+#define REG_IMR 0x1604
+
+
+#define IMR_NORMAL_MASK (\
+               ISR_SMB         |\
+               ISR_TXF_UN      |\
+               ISR_HW_RXF_OV   |\
+               ISR_HOST_RXF0_OV|\
+               ISR_MANUAL      |\
+               ISR_GPHY        |\
+               ISR_GPHY_LPW    |\
+               ISR_DMAR_TO_RST |\
+               ISR_DMAW_TO_RST |\
+               ISR_PHY_LINKDOWN|\
+               ISR_RX_PKT      |\
+               ISR_TX_PKT)
+
+#define ISR_TX_EVENT (ISR_TXF_UN | ISR_TX_PKT)
+#define ISR_RX_EVENT (ISR_HOST_RXF0_OV | ISR_HW_RXF_OV | ISR_RX_PKT)
+
+#define REG_MAC_RX_STATUS_BIN 0x1700
+#define REG_MAC_RX_STATUS_END 0x175c
+#define REG_MAC_TX_STATUS_BIN 0x1760
+#define REG_MAC_TX_STATUS_END 0x17c0
+
+/* Hardware Offset Register */
+#define REG_HOST_RXF0_PAGEOFF 0x1800
+#define REG_TPD_CONS_IDX      0x1804
+#define REG_HOST_RXF1_PAGEOFF 0x1808
+#define REG_HOST_RXF2_PAGEOFF 0x180C
+#define REG_HOST_RXF3_PAGEOFF 0x1810
+
+/* RXF-Page 0-3 Offset DMA Address */
+#define REG_HOST_RXF0_MB0_LO  0x1820
+#define REG_HOST_RXF0_MB1_LO  0x1824
+#define REG_HOST_RXF1_MB0_LO  0x1828
+#define REG_HOST_RXF1_MB1_LO  0x182C
+#define REG_HOST_RXF2_MB0_LO  0x1830
+#define REG_HOST_RXF2_MB1_LO  0x1834
+#define REG_HOST_RXF3_MB0_LO  0x1838
+#define REG_HOST_RXF3_MB1_LO  0x183C
+
+/* Tpd CMB DMA Address */
+#define REG_HOST_TX_CMB_LO    0x1840
+#define REG_HOST_SMB_ADDR_LO  0x1844
+
+/* DEBUG ADDR */
+#define REG_DEBUG_DATA0 0x1900
+#define REG_DEBUG_DATA1 0x1904
+
+/***************************** MII definition ***************************************/
+/* PHY Common Register */
+#define MII_AT001_PSCR                  0x10
+#define MII_AT001_PSSR                  0x11
+#define MII_INT_CTRL                    0x12
+#define MII_INT_STATUS                  0x13
+#define MII_SMARTSPEED                  0x14
+#define MII_LBRERROR                    0x18
+#define MII_RESV2                       0x1a
+
+#define MII_DBG_ADDR                   0x1D
+#define MII_DBG_DATA                   0x1E
+
+/* Autoneg Advertisement Register */
+#define MII_AR_DEFAULT_CAP_MASK                 0
+
+/* 1000BASE-T Control Register */
+#define MII_AT001_CR_1000T_SPEED_MASK \
+       (ADVERTISE_1000FULL | ADVERTISE_1000HALF)
+#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK    MII_AT001_CR_1000T_SPEED_MASK
+
+/* AT001 PHY Specific Control Register */
+#define MII_AT001_PSCR_JABBER_DISABLE           0x0001  /* 1=Jabber Function disabled */
+#define MII_AT001_PSCR_POLARITY_REVERSAL        0x0002  /* 1=Polarity Reversal enabled */
+#define MII_AT001_PSCR_SQE_TEST                 0x0004  /* 1=SQE Test enabled */
+#define MII_AT001_PSCR_MAC_POWERDOWN            0x0008
+#define MII_AT001_PSCR_CLK125_DISABLE           0x0010  /* 1=CLK125 low,
+                                                        * 0=CLK125 toggling
+                                                        */
+#define MII_AT001_PSCR_MDI_MANUAL_MODE          0x0000  /* MDI Crossover Mode bits 6:5 */
+/* Manual MDI configuration */
+#define MII_AT001_PSCR_MDIX_MANUAL_MODE         0x0020  /* Manual MDIX configuration */
+#define MII_AT001_PSCR_AUTO_X_1000T             0x0040  /* 1000BASE-T: Auto crossover,
+                                                        *  100BASE-TX/10BASE-T:
+                                                        *  MDI Mode
+                                                        */
+#define MII_AT001_PSCR_AUTO_X_MODE              0x0060  /* Auto crossover enabled
+                                                        * all speeds.
+                                                        */
+#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE     0x0080
+/* 1=Enable Extended 10BASE-T distance
+ * (Lower 10BASE-T RX Threshold)
+ * 0=Normal 10BASE-T RX Threshold */
+#define MII_AT001_PSCR_MII_5BIT_ENABLE          0x0100
+/* 1=5-Bit interface in 100BASE-TX
+ * 0=MII interface in 100BASE-TX */
+#define MII_AT001_PSCR_SCRAMBLER_DISABLE        0x0200  /* 1=Scrambler disable */
+#define MII_AT001_PSCR_FORCE_LINK_GOOD          0x0400  /* 1=Force link good */
+#define MII_AT001_PSCR_ASSERT_CRS_ON_TX         0x0800  /* 1=Assert CRS on Transmit */
+#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT    1
+#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT          5
+#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
+/* AT001 PHY Specific Status Register */
+#define MII_AT001_PSSR_SPD_DPLX_RESOLVED        0x0800  /* 1=Speed & Duplex resolved */
+#define MII_AT001_PSSR_DPLX                     0x2000  /* 1=Duplex 0=Half Duplex */
+#define MII_AT001_PSSR_SPEED                    0xC000  /* Speed, bits 14:15 */
+#define MII_AT001_PSSR_10MBS                    0x0000  /* 00=10Mbs */
+#define MII_AT001_PSSR_100MBS                   0x4000  /* 01=100Mbs */
+#define MII_AT001_PSSR_1000MBS                  0x8000  /* 10=1000Mbs */
+
+#endif /*_ATHL1E_HW_H_*/
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
new file mode 100644 (file)
index 0000000..d8d4119
--- /dev/null
@@ -0,0 +1,2558 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#include "atl1e.h"
+
+#define DRV_VERSION "1.0.0.7-NAPI"
+
+char atl1e_driver_name[] = "ATL1E";
+char atl1e_driver_version[] = DRV_VERSION;
+#define PCI_DEVICE_ID_ATTANSIC_L1E      0x1026
+/*
+ * atl1e_pci_tbl - PCI Device ID Table
+ *
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ *   Class, Class Mask, private data (not used) }
+ */
+static DEFINE_PCI_DEVICE_TABLE(atl1e_pci_tbl) = {
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
+       /* required last entry */
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, atl1e_pci_tbl);
+
+MODULE_AUTHOR("Atheros Corporation, <xiong.huang@atheros.com>, Jie Yang <jie.yang@atheros.com>");
+MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter);
+
+static const u16
+atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
+{
+       {REG_HOST_RXF0_PAGE0_VLD, REG_HOST_RXF0_PAGE1_VLD},
+       {REG_HOST_RXF1_PAGE0_VLD, REG_HOST_RXF1_PAGE1_VLD},
+       {REG_HOST_RXF2_PAGE0_VLD, REG_HOST_RXF2_PAGE1_VLD},
+       {REG_HOST_RXF3_PAGE0_VLD, REG_HOST_RXF3_PAGE1_VLD}
+};
+
+static const u16 atl1e_rx_page_hi_addr_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+       REG_RXF0_BASE_ADDR_HI,
+       REG_RXF1_BASE_ADDR_HI,
+       REG_RXF2_BASE_ADDR_HI,
+       REG_RXF3_BASE_ADDR_HI
+};
+
+static const u16
+atl1e_rx_page_lo_addr_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
+{
+       {REG_HOST_RXF0_PAGE0_LO, REG_HOST_RXF0_PAGE1_LO},
+       {REG_HOST_RXF1_PAGE0_LO, REG_HOST_RXF1_PAGE1_LO},
+       {REG_HOST_RXF2_PAGE0_LO, REG_HOST_RXF2_PAGE1_LO},
+       {REG_HOST_RXF3_PAGE0_LO, REG_HOST_RXF3_PAGE1_LO}
+};
+
+static const u16
+atl1e_rx_page_write_offset_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
+{
+       {REG_HOST_RXF0_MB0_LO,  REG_HOST_RXF0_MB1_LO},
+       {REG_HOST_RXF1_MB0_LO,  REG_HOST_RXF1_MB1_LO},
+       {REG_HOST_RXF2_MB0_LO,  REG_HOST_RXF2_MB1_LO},
+       {REG_HOST_RXF3_MB0_LO,  REG_HOST_RXF3_MB1_LO}
+};
+
+static const u16 atl1e_pay_load_size[] = {
+       128, 256, 512, 1024, 2048, 4096,
+};
+
+/*
+ * atl1e_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl1e_irq_enable(struct atl1e_adapter *adapter)
+{
+       if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
+               AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+               AT_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK);
+               AT_WRITE_FLUSH(&adapter->hw);
+       }
+}
+
+/*
+ * atl1e_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1e_irq_disable(struct atl1e_adapter *adapter)
+{
+       atomic_inc(&adapter->irq_sem);
+       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+       AT_WRITE_FLUSH(&adapter->hw);
+       synchronize_irq(adapter->pdev->irq);
+}
+
+/*
+ * atl1e_irq_reset - reset interrupt confiure on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1e_irq_reset(struct atl1e_adapter *adapter)
+{
+       atomic_set(&adapter->irq_sem, 0);
+       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+       AT_WRITE_FLUSH(&adapter->hw);
+}
+
+/*
+ * atl1e_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1e_phy_config(unsigned long data)
+{
+       struct atl1e_adapter *adapter = (struct atl1e_adapter *) data;
+       struct atl1e_hw *hw = &adapter->hw;
+       unsigned long flags;
+
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       atl1e_restart_autoneg(hw);
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+void atl1e_reinit_locked(struct atl1e_adapter *adapter)
+{
+
+       WARN_ON(in_interrupt());
+       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+               msleep(1);
+       atl1e_down(adapter);
+       atl1e_up(adapter);
+       clear_bit(__AT_RESETTING, &adapter->flags);
+}
+
+static void atl1e_reset_task(struct work_struct *work)
+{
+       struct atl1e_adapter *adapter;
+       adapter = container_of(work, struct atl1e_adapter, reset_task);
+
+       atl1e_reinit_locked(adapter);
+}
+
+static int atl1e_check_link(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       int err = 0;
+       u16 speed, duplex, phy_data;
+
+       /* MII_BMSR must read twice */
+       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
+       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
+       if ((phy_data & BMSR_LSTATUS) == 0) {
+               /* link down */
+               if (netif_carrier_ok(netdev)) { /* old link state: Up */
+                       u32 value;
+                       /* disable rx */
+                       value = AT_READ_REG(hw, REG_MAC_CTRL);
+                       value &= ~MAC_CTRL_RX_EN;
+                       AT_WRITE_REG(hw, REG_MAC_CTRL, value);
+                       adapter->link_speed = SPEED_0;
+                       netif_carrier_off(netdev);
+                       netif_stop_queue(netdev);
+               }
+       } else {
+               /* Link Up */
+               err = atl1e_get_speed_and_duplex(hw, &speed, &duplex);
+               if (unlikely(err))
+                       return err;
+
+               /* link result is our setting */
+               if (adapter->link_speed != speed ||
+                   adapter->link_duplex != duplex) {
+                       adapter->link_speed  = speed;
+                       adapter->link_duplex = duplex;
+                       atl1e_setup_mac_ctrl(adapter);
+                       netdev_info(netdev,
+                                   "NIC Link is Up <%d Mbps %s Duplex>\n",
+                                   adapter->link_speed,
+                                   adapter->link_duplex == FULL_DUPLEX ?
+                                   "Full" : "Half");
+               }
+
+               if (!netif_carrier_ok(netdev)) {
+                       /* Link down -> Up */
+                       netif_carrier_on(netdev);
+                       netif_wake_queue(netdev);
+               }
+       }
+       return 0;
+}
+
+/*
+ * atl1e_link_chg_task - deal with link change event Out of interrupt context
+ * @netdev: network interface device structure
+ */
+static void atl1e_link_chg_task(struct work_struct *work)
+{
+       struct atl1e_adapter *adapter;
+       unsigned long flags;
+
+       adapter = container_of(work, struct atl1e_adapter, link_chg_task);
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       atl1e_check_link(adapter);
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       u16 phy_data = 0;
+       u16 link_up = 0;
+
+       spin_lock(&adapter->mdio_lock);
+       atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       spin_unlock(&adapter->mdio_lock);
+       link_up = phy_data & BMSR_LSTATUS;
+       /* notify upper layer link down ASAP */
+       if (!link_up) {
+               if (netif_carrier_ok(netdev)) {
+                       /* old link state: Up */
+                       netdev_info(netdev, "NIC Link is Down\n");
+                       adapter->link_speed = SPEED_0;
+                       netif_stop_queue(netdev);
+               }
+       }
+       schedule_work(&adapter->link_chg_task);
+}
+
+static void atl1e_del_timer(struct atl1e_adapter *adapter)
+{
+       del_timer_sync(&adapter->phy_config_timer);
+}
+
+static void atl1e_cancel_work(struct atl1e_adapter *adapter)
+{
+       cancel_work_sync(&adapter->reset_task);
+       cancel_work_sync(&adapter->link_chg_task);
+}
+
+/*
+ * atl1e_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl1e_tx_timeout(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       /* Do the reset outside of interrupt context */
+       schedule_work(&adapter->reset_task);
+}
+
+/*
+ * atl1e_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 atl1e_set_multi(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       struct netdev_hw_addr *ha;
+       u32 mac_ctrl_data = 0;
+       u32 hash_value;
+
+       /* Check for Promiscuous and All Multicast modes */
+       mac_ctrl_data = AT_READ_REG(hw, REG_MAC_CTRL);
+
+       if (netdev->flags & IFF_PROMISC) {
+               mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+       } else if (netdev->flags & IFF_ALLMULTI) {
+               mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+               mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
+       } else {
+               mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+       }
+
+       AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+       /* clear the old settings from the multicast hash table */
+       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+       /* comoute mc addresses' hash value ,and put it into hash table */
+       netdev_for_each_mc_addr(ha, netdev) {
+               hash_value = atl1e_hash_mc_addr(hw, ha->addr);
+               atl1e_hash_set(hw, hash_value);
+       }
+}
+
+static void __atl1e_vlan_mode(u32 features, u32 *mac_ctrl_data)
+{
+       if (features & NETIF_F_HW_VLAN_RX) {
+               /* enable VLAN tag insert/strip */
+               *mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+       } else {
+               /* disable VLAN tag insert/strip */
+               *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
+       }
+}
+
+static void atl1e_vlan_mode(struct net_device *netdev, u32 features)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       u32 mac_ctrl_data = 0;
+
+       netdev_dbg(adapter->netdev, "%s\n", __func__);
+
+       atl1e_irq_disable(adapter);
+       mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
+       __atl1e_vlan_mode(features, &mac_ctrl_data);
+       AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
+       atl1e_irq_enable(adapter);
+}
+
+static void atl1e_restore_vlan(struct atl1e_adapter *adapter)
+{
+       netdev_dbg(adapter->netdev, "%s\n", __func__);
+       atl1e_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+/*
+ * atl1e_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 atl1e_set_mac_addr(struct net_device *netdev, void *p)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       if (netif_running(netdev))
+               return -EBUSY;
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+       atl1e_hw_set_mac_addr(&adapter->hw);
+
+       return 0;
+}
+
+static u32 atl1e_fix_features(struct net_device *netdev, u32 features)
+{
+       /*
+        * Since there is no support for separate rx/tx vlan accel
+        * enable/disable make sure tx flag is always in same state as rx.
+        */
+       if (features & NETIF_F_HW_VLAN_RX)
+               features |= NETIF_F_HW_VLAN_TX;
+       else
+               features &= ~NETIF_F_HW_VLAN_TX;
+
+       return features;
+}
+
+static int atl1e_set_features(struct net_device *netdev, u32 features)
+{
+       u32 changed = netdev->features ^ features;
+
+       if (changed & NETIF_F_HW_VLAN_RX)
+               atl1e_vlan_mode(netdev, features);
+
+       return 0;
+}
+
+/*
+ * atl1e_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1e_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       int old_mtu   = netdev->mtu;
+       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+                       (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+               netdev_warn(adapter->netdev, "invalid MTU setting\n");
+               return -EINVAL;
+       }
+       /* set MTU */
+       if (old_mtu != new_mtu && netif_running(netdev)) {
+               while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+                       msleep(1);
+               netdev->mtu = new_mtu;
+               adapter->hw.max_frame_size = new_mtu;
+               adapter->hw.rx_jumbo_th = (max_frame + 7) >> 3;
+               atl1e_down(adapter);
+               atl1e_up(adapter);
+               clear_bit(__AT_RESETTING, &adapter->flags);
+       }
+       return 0;
+}
+
+/*
+ *  caller should hold mdio_lock
+ */
+static int atl1e_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       u16 result;
+
+       atl1e_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
+       return result;
+}
+
+static void atl1e_mdio_write(struct net_device *netdev, int phy_id,
+                            int reg_num, int val)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       atl1e_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
+}
+
+/*
+ * atl1e_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1e_mii_ioctl(struct net_device *netdev,
+                          struct ifreq *ifr, int cmd)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct mii_ioctl_data *data = if_mii(ifr);
+       unsigned long flags;
+       int retval = 0;
+
+       if (!netif_running(netdev))
+               return -EINVAL;
+
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = 0;
+               break;
+
+       case SIOCGMIIREG:
+               if (atl1e_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+                                   &data->val_out)) {
+                       retval = -EIO;
+                       goto out;
+               }
+               break;
+
+       case SIOCSMIIREG:
+               if (data->reg_num & ~(0x1F)) {
+                       retval = -EFAULT;
+                       goto out;
+               }
+
+               netdev_dbg(adapter->netdev, "<atl1e_mii_ioctl> write %x %x\n",
+                          data->reg_num, data->val_in);
+               if (atl1e_write_phy_reg(&adapter->hw,
+                                    data->reg_num, data->val_in)) {
+                       retval = -EIO;
+                       goto out;
+               }
+               break;
+
+       default:
+               retval = -EOPNOTSUPP;
+               break;
+       }
+out:
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+       return retval;
+
+}
+
+/*
+ * atl1e_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       switch (cmd) {
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               return atl1e_mii_ioctl(netdev, ifr, cmd);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static void atl1e_setup_pcicmd(struct pci_dev *pdev)
+{
+       u16 cmd;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+       cmd &= ~(PCI_COMMAND_INTX_DISABLE | PCI_COMMAND_IO);
+       cmd |=  (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+       pci_write_config_word(pdev, PCI_COMMAND, cmd);
+
+       /*
+        * some motherboards BIOS(PXE/EFI) driver may set PME
+        * while they transfer control to OS (Windows/Linux)
+        * so we should clear this bit before NIC work normally
+        */
+       pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0);
+       msleep(1);
+}
+
+/*
+ * atl1e_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ */
+static int __devinit atl1e_alloc_queues(struct atl1e_adapter *adapter)
+{
+       return 0;
+}
+
+/*
+ * atl1e_sw_init - Initialize general software structures (struct atl1e_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl1e_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 __devinit atl1e_sw_init(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw   = &adapter->hw;
+       struct pci_dev  *pdev = adapter->pdev;
+       u32 phy_status_data = 0;
+
+       adapter->wol = 0;
+       adapter->link_speed = SPEED_0;   /* hardware init */
+       adapter->link_duplex = FULL_DUPLEX;
+       adapter->num_rx_queues = 1;
+
+       /* PCI config space info */
+       hw->vendor_id = pdev->vendor;
+       hw->device_id = pdev->device;
+       hw->subsystem_vendor_id = pdev->subsystem_vendor;
+       hw->subsystem_id = pdev->subsystem_device;
+       hw->revision_id  = pdev->revision;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+       phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
+       /* nic type */
+       if (hw->revision_id >= 0xF0) {
+               hw->nic_type = athr_l2e_revB;
+       } else {
+               if (phy_status_data & PHY_STATUS_100M)
+                       hw->nic_type = athr_l1e;
+               else
+                       hw->nic_type = athr_l2e_revA;
+       }
+
+       phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
+
+       if (phy_status_data & PHY_STATUS_EMI_CA)
+               hw->emi_ca = true;
+       else
+               hw->emi_ca = false;
+
+       hw->phy_configured = false;
+       hw->preamble_len = 7;
+       hw->max_frame_size = adapter->netdev->mtu;
+       hw->rx_jumbo_th = (hw->max_frame_size + ETH_HLEN +
+                               VLAN_HLEN + ETH_FCS_LEN + 7) >> 3;
+
+       hw->rrs_type = atl1e_rrs_disable;
+       hw->indirect_tab = 0;
+       hw->base_cpu = 0;
+
+       /* need confirm */
+
+       hw->ict = 50000;                 /* 100ms */
+       hw->smb_timer = 200000;          /* 200ms  */
+       hw->tpd_burst = 5;
+       hw->rrd_thresh = 1;
+       hw->tpd_thresh = adapter->tx_ring.count / 2;
+       hw->rx_count_down = 4;  /* 2us resolution */
+       hw->tx_count_down = hw->imt * 4 / 3;
+       hw->dmar_block = atl1e_dma_req_1024;
+       hw->dmaw_block = atl1e_dma_req_1024;
+       hw->dmar_dly_cnt = 15;
+       hw->dmaw_dly_cnt = 4;
+
+       if (atl1e_alloc_queues(adapter)) {
+               netdev_err(adapter->netdev, "Unable to allocate memory for queues\n");
+               return -ENOMEM;
+       }
+
+       atomic_set(&adapter->irq_sem, 1);
+       spin_lock_init(&adapter->mdio_lock);
+       spin_lock_init(&adapter->tx_lock);
+
+       set_bit(__AT_DOWN, &adapter->flags);
+
+       return 0;
+}
+
+/*
+ * atl1e_clean_tx_ring - Free Tx-skb
+ * @adapter: board private structure
+ */
+static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
+                               &adapter->tx_ring;
+       struct atl1e_tx_buffer *tx_buffer = NULL;
+       struct pci_dev *pdev = adapter->pdev;
+       u16 index, ring_count;
+
+       if (tx_ring->desc == NULL || tx_ring->tx_buffer == NULL)
+               return;
+
+       ring_count = tx_ring->count;
+       /* first unmmap dma */
+       for (index = 0; index < ring_count; index++) {
+               tx_buffer = &tx_ring->tx_buffer[index];
+               if (tx_buffer->dma) {
+                       if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+                               pci_unmap_single(pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+                               pci_unmap_page(pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       tx_buffer->dma = 0;
+               }
+       }
+       /* second free skb */
+       for (index = 0; index < ring_count; index++) {
+               tx_buffer = &tx_ring->tx_buffer[index];
+               if (tx_buffer->skb) {
+                       dev_kfree_skb_any(tx_buffer->skb);
+                       tx_buffer->skb = NULL;
+               }
+       }
+       /* Zero out Tx-buffers */
+       memset(tx_ring->desc, 0, sizeof(struct atl1e_tpd_desc) *
+                               ring_count);
+       memset(tx_ring->tx_buffer, 0, sizeof(struct atl1e_tx_buffer) *
+                               ring_count);
+}
+
+/*
+ * atl1e_clean_rx_ring - Free rx-reservation skbs
+ * @adapter: board private structure
+ */
+static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter)
+{
+       struct atl1e_rx_ring *rx_ring =
+               (struct atl1e_rx_ring *)&adapter->rx_ring;
+       struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc;
+       u16 i, j;
+
+
+       if (adapter->ring_vir_addr == NULL)
+               return;
+       /* Zero out the descriptor ring */
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       if (rx_page_desc[i].rx_page[j].addr != NULL) {
+                               memset(rx_page_desc[i].rx_page[j].addr, 0,
+                                               rx_ring->real_page_size);
+                       }
+               }
+       }
+}
+
+static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size)
+{
+       *ring_size = ((u32)(adapter->tx_ring.count *
+                    sizeof(struct atl1e_tpd_desc) + 7
+                       /* tx ring, qword align */
+                    + adapter->rx_ring.real_page_size * AT_PAGE_NUM_PER_QUEUE *
+                       adapter->num_rx_queues + 31
+                       /* rx ring,  32 bytes align */
+                    + (1 + AT_PAGE_NUM_PER_QUEUE * adapter->num_rx_queues) *
+                       sizeof(u32) + 3));
+                       /* tx, rx cmd, dword align   */
+}
+
+static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
+{
+       struct atl1e_rx_ring *rx_ring = NULL;
+
+       rx_ring = &adapter->rx_ring;
+
+       rx_ring->real_page_size = adapter->rx_ring.page_size
+                                + adapter->hw.max_frame_size
+                                + ETH_HLEN + VLAN_HLEN
+                                + ETH_FCS_LEN;
+       rx_ring->real_page_size = roundup(rx_ring->real_page_size, 32);
+       atl1e_cal_ring_size(adapter, &adapter->ring_size);
+
+       adapter->ring_vir_addr = NULL;
+       adapter->rx_ring.desc = NULL;
+       rwlock_init(&adapter->tx_ring.tx_lock);
+}
+
+/*
+ * Read / Write Ptr Initialize:
+ */
+static void atl1e_init_ring_ptrs(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = NULL;
+       struct atl1e_rx_ring *rx_ring = NULL;
+       struct atl1e_rx_page_desc *rx_page_desc = NULL;
+       int i, j;
+
+       tx_ring = &adapter->tx_ring;
+       rx_ring = &adapter->rx_ring;
+       rx_page_desc = rx_ring->rx_page_desc;
+
+       tx_ring->next_to_use = 0;
+       atomic_set(&tx_ring->next_to_clean, 0);
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               rx_page_desc[i].rx_using  = 0;
+               rx_page_desc[i].rx_nxseq = 0;
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       *rx_page_desc[i].rx_page[j].write_offset_addr = 0;
+                       rx_page_desc[i].rx_page[j].read_offset = 0;
+               }
+       }
+}
+
+/*
+ * atl1e_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl1e_free_ring_resources(struct atl1e_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       atl1e_clean_tx_ring(adapter);
+       atl1e_clean_rx_ring(adapter);
+
+       if (adapter->ring_vir_addr) {
+               pci_free_consistent(pdev, adapter->ring_size,
+                               adapter->ring_vir_addr, adapter->ring_dma);
+               adapter->ring_vir_addr = NULL;
+       }
+
+       if (adapter->tx_ring.tx_buffer) {
+               kfree(adapter->tx_ring.tx_buffer);
+               adapter->tx_ring.tx_buffer = NULL;
+       }
+}
+
+/*
+ * atl1e_setup_mem_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       struct atl1e_tx_ring *tx_ring;
+       struct atl1e_rx_ring *rx_ring;
+       struct atl1e_rx_page_desc  *rx_page_desc;
+       int size, i, j;
+       u32 offset = 0;
+       int err = 0;
+
+       if (adapter->ring_vir_addr != NULL)
+               return 0; /* alloced already */
+
+       tx_ring = &adapter->tx_ring;
+       rx_ring = &adapter->rx_ring;
+
+       /* real ring DMA buffer */
+
+       size = adapter->ring_size;
+       adapter->ring_vir_addr = pci_alloc_consistent(pdev,
+                       adapter->ring_size, &adapter->ring_dma);
+
+       if (adapter->ring_vir_addr == NULL) {
+               netdev_err(adapter->netdev,
+                          "pci_alloc_consistent failed, size = D%d\n", size);
+               return -ENOMEM;
+       }
+
+       memset(adapter->ring_vir_addr, 0, adapter->ring_size);
+
+       rx_page_desc = rx_ring->rx_page_desc;
+
+       /* Init TPD Ring */
+       tx_ring->dma = roundup(adapter->ring_dma, 8);
+       offset = tx_ring->dma - adapter->ring_dma;
+       tx_ring->desc = adapter->ring_vir_addr + offset;
+       size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count);
+       tx_ring->tx_buffer = kzalloc(size, GFP_KERNEL);
+       if (tx_ring->tx_buffer == NULL) {
+               netdev_err(adapter->netdev, "kzalloc failed, size = D%d\n",
+                          size);
+               err = -ENOMEM;
+               goto failed;
+       }
+
+       /* Init RXF-Pages */
+       offset += (sizeof(struct atl1e_tpd_desc) * tx_ring->count);
+       offset = roundup(offset, 32);
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       rx_page_desc[i].rx_page[j].dma =
+                               adapter->ring_dma + offset;
+                       rx_page_desc[i].rx_page[j].addr =
+                               adapter->ring_vir_addr + offset;
+                       offset += rx_ring->real_page_size;
+               }
+       }
+
+       /* Init CMB dma address */
+       tx_ring->cmb_dma = adapter->ring_dma + offset;
+       tx_ring->cmb = adapter->ring_vir_addr + offset;
+       offset += sizeof(u32);
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       rx_page_desc[i].rx_page[j].write_offset_dma =
+                               adapter->ring_dma + offset;
+                       rx_page_desc[i].rx_page[j].write_offset_addr =
+                               adapter->ring_vir_addr + offset;
+                       offset += sizeof(u32);
+               }
+       }
+
+       if (unlikely(offset > adapter->ring_size)) {
+               netdev_err(adapter->netdev, "offset(%d) > ring size(%d) !!\n",
+                          offset, adapter->ring_size);
+               err = -1;
+               goto failed;
+       }
+
+       return 0;
+failed:
+       if (adapter->ring_vir_addr != NULL) {
+               pci_free_consistent(pdev, adapter->ring_size,
+                               adapter->ring_vir_addr, adapter->ring_dma);
+               adapter->ring_vir_addr = NULL;
+       }
+       return err;
+}
+
+static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter)
+{
+
+       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+       struct atl1e_rx_ring *rx_ring =
+                       (struct atl1e_rx_ring *)&adapter->rx_ring;
+       struct atl1e_tx_ring *tx_ring =
+                       (struct atl1e_tx_ring *)&adapter->tx_ring;
+       struct atl1e_rx_page_desc *rx_page_desc = NULL;
+       int i, j;
+
+       AT_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI,
+                       (u32)((adapter->ring_dma & AT_DMA_HI_ADDR_MASK) >> 32));
+       AT_WRITE_REG(hw, REG_TPD_BASE_ADDR_LO,
+                       (u32)((tx_ring->dma) & AT_DMA_LO_ADDR_MASK));
+       AT_WRITE_REG(hw, REG_TPD_RING_SIZE, (u16)(tx_ring->count));
+       AT_WRITE_REG(hw, REG_HOST_TX_CMB_LO,
+                       (u32)((tx_ring->cmb_dma) & AT_DMA_LO_ADDR_MASK));
+
+       rx_page_desc = rx_ring->rx_page_desc;
+       /* RXF Page Physical address / Page Length */
+       for (i = 0; i < AT_MAX_RECEIVE_QUEUE; i++) {
+               AT_WRITE_REG(hw, atl1e_rx_page_hi_addr_regs[i],
+                                (u32)((adapter->ring_dma &
+                                AT_DMA_HI_ADDR_MASK) >> 32));
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       u32 page_phy_addr;
+                       u32 offset_phy_addr;
+
+                       page_phy_addr = rx_page_desc[i].rx_page[j].dma;
+                       offset_phy_addr =
+                                  rx_page_desc[i].rx_page[j].write_offset_dma;
+
+                       AT_WRITE_REG(hw, atl1e_rx_page_lo_addr_regs[i][j],
+                                       page_phy_addr & AT_DMA_LO_ADDR_MASK);
+                       AT_WRITE_REG(hw, atl1e_rx_page_write_offset_regs[i][j],
+                                       offset_phy_addr & AT_DMA_LO_ADDR_MASK);
+                       AT_WRITE_REGB(hw, atl1e_rx_page_vld_regs[i][j], 1);
+               }
+       }
+       /* Page Length */
+       AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size);
+       /* Load all of base address above */
+       AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
+}
+
+static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+       u32 dev_ctrl_data = 0;
+       u32 max_pay_load = 0;
+       u32 jumbo_thresh = 0;
+       u32 extra_size = 0;     /* Jumbo frame threshold in QWORD unit */
+
+       /* configure TXQ param */
+       if (hw->nic_type != athr_l2e_revB) {
+               extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
+               if (hw->max_frame_size <= 1500) {
+                       jumbo_thresh = hw->max_frame_size + extra_size;
+               } else if (hw->max_frame_size < 6*1024) {
+                       jumbo_thresh =
+                               (hw->max_frame_size + extra_size) * 2 / 3;
+               } else {
+                       jumbo_thresh = (hw->max_frame_size + extra_size) / 2;
+               }
+               AT_WRITE_REG(hw, REG_TX_EARLY_TH, (jumbo_thresh + 7) >> 3);
+       }
+
+       dev_ctrl_data = AT_READ_REG(hw, REG_DEVICE_CTRL);
+
+       max_pay_load  = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) &
+                       DEVICE_CTRL_MAX_PAYLOAD_MASK;
+
+       hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
+
+       max_pay_load  = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) &
+                       DEVICE_CTRL_MAX_RREQ_SZ_MASK;
+       hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
+
+       if (hw->nic_type != athr_l2e_revB)
+               AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2,
+                             atl1e_pay_load_size[hw->dmar_block]);
+       /* enable TXQ */
+       AT_WRITE_REGW(hw, REG_TXQ_CTRL,
+                       (((u16)hw->tpd_burst & TXQ_CTRL_NUM_TPD_BURST_MASK)
+                        << TXQ_CTRL_NUM_TPD_BURST_SHIFT)
+                       | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN);
+}
+
+static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+       u32 rxf_len  = 0;
+       u32 rxf_low  = 0;
+       u32 rxf_high = 0;
+       u32 rxf_thresh_data = 0;
+       u32 rxq_ctrl_data = 0;
+
+       if (hw->nic_type != athr_l2e_revB) {
+               AT_WRITE_REGW(hw, REG_RXQ_JMBOSZ_RRDTIM,
+                             (u16)((hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) <<
+                             RXQ_JMBOSZ_TH_SHIFT |
+                             (1 & RXQ_JMBO_LKAH_MASK) <<
+                             RXQ_JMBO_LKAH_SHIFT));
+
+               rxf_len  = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
+               rxf_high = rxf_len * 4 / 5;
+               rxf_low  = rxf_len / 5;
+               rxf_thresh_data = ((rxf_high  & RXQ_RXF_PAUSE_TH_HI_MASK)
+                                 << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
+                                 ((rxf_low & RXQ_RXF_PAUSE_TH_LO_MASK)
+                                 << RXQ_RXF_PAUSE_TH_LO_SHIFT);
+
+               AT_WRITE_REG(hw, REG_RXQ_RXF_PAUSE_THRESH, rxf_thresh_data);
+       }
+
+       /* RRS */
+       AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
+       AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
+
+       if (hw->rrs_type & atl1e_rrs_ipv4)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4;
+
+       if (hw->rrs_type & atl1e_rrs_ipv4_tcp)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4_TCP;
+
+       if (hw->rrs_type & atl1e_rrs_ipv6)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6;
+
+       if (hw->rrs_type & atl1e_rrs_ipv6_tcp)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6_TCP;
+
+       if (hw->rrs_type != atl1e_rrs_disable)
+               rxq_ctrl_data |=
+                       (RXQ_CTRL_HASH_ENABLE | RXQ_CTRL_RSS_MODE_MQUESINT);
+
+       rxq_ctrl_data |= RXQ_CTRL_IPV6_XSUM_VERIFY_EN | RXQ_CTRL_PBA_ALIGN_32 |
+                        RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
+
+       AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
+}
+
+static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 dma_ctrl_data = 0;
+
+       dma_ctrl_data = DMA_CTRL_RXCMB_EN;
+       dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
+               << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
+       dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+               << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
+       dma_ctrl_data |= DMA_CTRL_DMAR_REQ_PRI | DMA_CTRL_DMAR_OUT_ORDER;
+       dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
+               << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
+       dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
+               << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
+
+       AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
+}
+
+static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
+{
+       u32 value;
+       struct atl1e_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+
+       /* Config MAC CTRL Register */
+       value = MAC_CTRL_TX_EN |
+               MAC_CTRL_RX_EN ;
+
+       if (FULL_DUPLEX == adapter->link_duplex)
+               value |= MAC_CTRL_DUPLX;
+
+       value |= ((u32)((SPEED_1000 == adapter->link_speed) ?
+                         MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) <<
+                         MAC_CTRL_SPEED_SHIFT);
+       value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+
+       value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+       value |= (((u32)adapter->hw.preamble_len &
+                 MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
+
+       __atl1e_vlan_mode(netdev->features, &value);
+
+       value |= MAC_CTRL_BC_EN;
+       if (netdev->flags & IFF_PROMISC)
+               value |= MAC_CTRL_PROMIS_EN;
+       if (netdev->flags & IFF_ALLMULTI)
+               value |= MAC_CTRL_MC_ALL_EN;
+
+       AT_WRITE_REG(hw, REG_MAC_CTRL, value);
+}
+
+/*
+ * atl1e_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl1e_configure(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = &adapter->hw;
+
+       u32 intr_status_data = 0;
+
+       /* clear interrupt status */
+       AT_WRITE_REG(hw, REG_ISR, ~0);
+
+       /* 1. set MAC Address */
+       atl1e_hw_set_mac_addr(hw);
+
+       /* 2. Init the Multicast HASH table done by set_muti */
+
+       /* 3. Clear any WOL status */
+       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+       /* 4. Descripter Ring BaseMem/Length/Read ptr/Write ptr
+        *    TPD Ring/SMB/RXF0 Page CMBs, they use the same
+        *    High 32bits memory */
+       atl1e_configure_des_ring(adapter);
+
+       /* 5. set Interrupt Moderator Timer */
+       AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, hw->imt);
+       AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER2_INIT, hw->imt);
+       AT_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_LED_MODE |
+                       MASTER_CTRL_ITIMER_EN | MASTER_CTRL_ITIMER2_EN);
+
+       /* 6. rx/tx threshold to trig interrupt */
+       AT_WRITE_REGW(hw, REG_TRIG_RRD_THRESH, hw->rrd_thresh);
+       AT_WRITE_REGW(hw, REG_TRIG_TPD_THRESH, hw->tpd_thresh);
+       AT_WRITE_REGW(hw, REG_TRIG_RXTIMER, hw->rx_count_down);
+       AT_WRITE_REGW(hw, REG_TRIG_TXTIMER, hw->tx_count_down);
+
+       /* 7. set Interrupt Clear Timer */
+       AT_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, hw->ict);
+
+       /* 8. set MTU */
+       AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
+                       VLAN_HLEN + ETH_FCS_LEN);
+
+       /* 9. config TXQ early tx threshold */
+       atl1e_configure_tx(adapter);
+
+       /* 10. config RXQ */
+       atl1e_configure_rx(adapter);
+
+       /* 11. config  DMA Engine */
+       atl1e_configure_dma(adapter);
+
+       /* 12. smb timer to trig interrupt */
+       AT_WRITE_REG(hw, REG_SMB_STAT_TIMER, hw->smb_timer);
+
+       intr_status_data = AT_READ_REG(hw, REG_ISR);
+       if (unlikely((intr_status_data & ISR_PHY_LINKDOWN) != 0)) {
+               netdev_err(adapter->netdev,
+                          "atl1e_configure failed, PCIE phy link down\n");
+               return -1;
+       }
+
+       AT_WRITE_REG(hw, REG_ISR, 0x7fffffff);
+       return 0;
+}
+
+/*
+ * atl1e_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 *atl1e_get_stats(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw_stats  *hw_stats = &adapter->hw_stats;
+       struct net_device_stats *net_stats = &netdev->stats;
+
+       net_stats->rx_packets = hw_stats->rx_ok;
+       net_stats->tx_packets = hw_stats->tx_ok;
+       net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
+       net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
+       net_stats->multicast  = hw_stats->rx_mcast;
+       net_stats->collisions = hw_stats->tx_1_col +
+                               hw_stats->tx_2_col * 2 +
+                               hw_stats->tx_late_col + hw_stats->tx_abort_col;
+
+       net_stats->rx_errors  = hw_stats->rx_frag + hw_stats->rx_fcs_err +
+                               hw_stats->rx_len_err + hw_stats->rx_sz_ov +
+                               hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
+       net_stats->rx_fifo_errors   = hw_stats->rx_rxf_ov;
+       net_stats->rx_length_errors = hw_stats->rx_len_err;
+       net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
+       net_stats->rx_frame_errors  = hw_stats->rx_align_err;
+       net_stats->rx_over_errors   = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+       net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+       net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
+                              hw_stats->tx_underrun + hw_stats->tx_trunc;
+       net_stats->tx_fifo_errors    = hw_stats->tx_underrun;
+       net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+       net_stats->tx_window_errors  = hw_stats->tx_late_col;
+
+       return net_stats;
+}
+
+static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
+{
+       u16 hw_reg_addr = 0;
+       unsigned long *stats_item = NULL;
+
+       /* update rx status */
+       hw_reg_addr = REG_MAC_RX_STATUS_BIN;
+       stats_item  = &adapter->hw_stats.rx_ok;
+       while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
+               *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
+               stats_item++;
+               hw_reg_addr += 4;
+       }
+       /* update tx status */
+       hw_reg_addr = REG_MAC_TX_STATUS_BIN;
+       stats_item  = &adapter->hw_stats.tx_ok;
+       while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
+               *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
+               stats_item++;
+               hw_reg_addr += 4;
+       }
+}
+
+static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter)
+{
+       u16 phy_data;
+
+       spin_lock(&adapter->mdio_lock);
+       atl1e_read_phy_reg(&adapter->hw, MII_INT_STATUS, &phy_data);
+       spin_unlock(&adapter->mdio_lock);
+}
+
+static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
+                                       &adapter->tx_ring;
+       struct atl1e_tx_buffer *tx_buffer = NULL;
+       u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX);
+       u16 next_to_clean = atomic_read(&tx_ring->next_to_clean);
+
+       while (next_to_clean != hw_next_to_clean) {
+               tx_buffer = &tx_ring->tx_buffer[next_to_clean];
+               if (tx_buffer->dma) {
+                       if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+                               pci_unmap_single(adapter->pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+                               pci_unmap_page(adapter->pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       tx_buffer->dma = 0;
+               }
+
+               if (tx_buffer->skb) {
+                       dev_kfree_skb_irq(tx_buffer->skb);
+                       tx_buffer->skb = NULL;
+               }
+
+               if (++next_to_clean == tx_ring->count)
+                       next_to_clean = 0;
+       }
+
+       atomic_set(&tx_ring->next_to_clean, next_to_clean);
+
+       if (netif_queue_stopped(adapter->netdev) &&
+                       netif_carrier_ok(adapter->netdev)) {
+               netif_wake_queue(adapter->netdev);
+       }
+
+       return true;
+}
+
+/*
+ * atl1e_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ */
+static irqreturn_t atl1e_intr(int irq, void *data)
+{
+       struct net_device *netdev  = data;
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       int max_ints = AT_MAX_INT_WORK;
+       int handled = IRQ_NONE;
+       u32 status;
+
+       do {
+               status = AT_READ_REG(hw, REG_ISR);
+               if ((status & IMR_NORMAL_MASK) == 0 ||
+                               (status & ISR_DIS_INT) != 0) {
+                       if (max_ints != AT_MAX_INT_WORK)
+                               handled = IRQ_HANDLED;
+                       break;
+               }
+               /* link event */
+               if (status & ISR_GPHY)
+                       atl1e_clear_phy_int(adapter);
+               /* Ack ISR */
+               AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+
+               handled = IRQ_HANDLED;
+               /* check if PCIE PHY Link down */
+               if (status & ISR_PHY_LINKDOWN) {
+                       netdev_err(adapter->netdev,
+                                  "pcie phy linkdown %x\n", status);
+                       if (netif_running(adapter->netdev)) {
+                               /* reset MAC */
+                               atl1e_irq_reset(adapter);
+                               schedule_work(&adapter->reset_task);
+                               break;
+                       }
+               }
+
+               /* check if DMA read/write error */
+               if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+                       netdev_err(adapter->netdev,
+                                  "PCIE DMA RW error (status = 0x%x)\n",
+                                  status);
+                       atl1e_irq_reset(adapter);
+                       schedule_work(&adapter->reset_task);
+                       break;
+               }
+
+               if (status & ISR_SMB)
+                       atl1e_update_hw_stats(adapter);
+
+               /* link event */
+               if (status & (ISR_GPHY | ISR_MANUAL)) {
+                       netdev->stats.tx_carrier_errors++;
+                       atl1e_link_chg_event(adapter);
+                       break;
+               }
+
+               /* transmit event */
+               if (status & ISR_TX_EVENT)
+                       atl1e_clean_tx_irq(adapter);
+
+               if (status & ISR_RX_EVENT) {
+                       /*
+                        * disable rx interrupts, without
+                        * the synchronize_irq bit
+                        */
+                       AT_WRITE_REG(hw, REG_IMR,
+                                    IMR_NORMAL_MASK & ~ISR_RX_EVENT);
+                       AT_WRITE_FLUSH(hw);
+                       if (likely(napi_schedule_prep(
+                                  &adapter->napi)))
+                               __napi_schedule(&adapter->napi);
+               }
+       } while (--max_ints > 0);
+       /* re-enable Interrupt*/
+       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+
+       return handled;
+}
+
+static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
+                 struct sk_buff *skb, struct atl1e_recv_ret_status *prrs)
+{
+       u8 *packet = (u8 *)(prrs + 1);
+       struct iphdr *iph;
+       u16 head_len = ETH_HLEN;
+       u16 pkt_flags;
+       u16 err_flags;
+
+       skb_checksum_none_assert(skb);
+       pkt_flags = prrs->pkt_flag;
+       err_flags = prrs->err_flag;
+       if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
+               ((pkt_flags & RRS_IS_TCP) || (pkt_flags & RRS_IS_UDP))) {
+               if (pkt_flags & RRS_IS_IPV4) {
+                       if (pkt_flags & RRS_IS_802_3)
+                               head_len += 8;
+                       iph = (struct iphdr *) (packet + head_len);
+                       if (iph->frag_off != 0 && !(pkt_flags & RRS_IS_IP_DF))
+                               goto hw_xsum;
+               }
+               if (!(err_flags & (RRS_ERR_IP_CSUM | RRS_ERR_L4_CSUM))) {
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       return;
+               }
+       }
+
+hw_xsum :
+       return;
+}
+
+static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter,
+                                              u8 que)
+{
+       struct atl1e_rx_page_desc *rx_page_desc =
+               (struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc;
+       u8 rx_using = rx_page_desc[que].rx_using;
+
+       return (struct atl1e_rx_page *)&(rx_page_desc[que].rx_page[rx_using]);
+}
+
+static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
+                  int *work_done, int work_to_do)
+{
+       struct net_device *netdev  = adapter->netdev;
+       struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *)
+                                        &adapter->rx_ring;
+       struct atl1e_rx_page_desc *rx_page_desc =
+               (struct atl1e_rx_page_desc *) rx_ring->rx_page_desc;
+       struct sk_buff *skb = NULL;
+       struct atl1e_rx_page *rx_page = atl1e_get_rx_page(adapter, que);
+       u32 packet_size, write_offset;
+       struct atl1e_recv_ret_status *prrs;
+
+       write_offset = *(rx_page->write_offset_addr);
+       if (likely(rx_page->read_offset < write_offset)) {
+               do {
+                       if (*work_done >= work_to_do)
+                               break;
+                       (*work_done)++;
+                       /* get new packet's  rrs */
+                       prrs = (struct atl1e_recv_ret_status *) (rx_page->addr +
+                                                rx_page->read_offset);
+                       /* check sequence number */
+                       if (prrs->seq_num != rx_page_desc[que].rx_nxseq) {
+                               netdev_err(netdev,
+                                          "rx sequence number error (rx=%d) (expect=%d)\n",
+                                          prrs->seq_num,
+                                          rx_page_desc[que].rx_nxseq);
+                               rx_page_desc[que].rx_nxseq++;
+                               /* just for debug use */
+                               AT_WRITE_REG(&adapter->hw, REG_DEBUG_DATA0,
+                                            (((u32)prrs->seq_num) << 16) |
+                                            rx_page_desc[que].rx_nxseq);
+                               goto fatal_err;
+                       }
+                       rx_page_desc[que].rx_nxseq++;
+
+                       /* error packet */
+                       if (prrs->pkt_flag & RRS_IS_ERR_FRAME) {
+                               if (prrs->err_flag & (RRS_ERR_BAD_CRC |
+                                       RRS_ERR_DRIBBLE | RRS_ERR_CODE |
+                                       RRS_ERR_TRUNC)) {
+                               /* hardware error, discard this packet*/
+                                       netdev_err(netdev,
+                                                  "rx packet desc error %x\n",
+                                                  *((u32 *)prrs + 1));
+                                       goto skip_pkt;
+                               }
+                       }
+
+                       packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
+                                       RRS_PKT_SIZE_MASK) - 4; /* CRC */
+                       skb = netdev_alloc_skb_ip_align(netdev, packet_size);
+                       if (skb == NULL) {
+                               netdev_warn(netdev,
+                                           "Memory squeeze, deferring packet\n");
+                               goto skip_pkt;
+                       }
+                       memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
+                       skb_put(skb, packet_size);
+                       skb->protocol = eth_type_trans(skb, netdev);
+                       atl1e_rx_checksum(adapter, skb, prrs);
+
+                       if (prrs->pkt_flag & RRS_IS_VLAN_TAG) {
+                               u16 vlan_tag = (prrs->vtag >> 4) |
+                                              ((prrs->vtag & 7) << 13) |
+                                              ((prrs->vtag & 8) << 9);
+                               netdev_dbg(netdev,
+                                          "RXD VLAN TAG<RRD>=0x%04x\n",
+                                          prrs->vtag);
+                               __vlan_hwaccel_put_tag(skb, vlan_tag);
+                       }
+                       netif_receive_skb(skb);
+
+skip_pkt:
+       /* skip current packet whether it's ok or not. */
+                       rx_page->read_offset +=
+                               (((u32)((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
+                               RRS_PKT_SIZE_MASK) +
+                               sizeof(struct atl1e_recv_ret_status) + 31) &
+                                               0xFFFFFFE0);
+
+                       if (rx_page->read_offset >= rx_ring->page_size) {
+                               /* mark this page clean */
+                               u16 reg_addr;
+                               u8  rx_using;
+
+                               rx_page->read_offset =
+                                       *(rx_page->write_offset_addr) = 0;
+                               rx_using = rx_page_desc[que].rx_using;
+                               reg_addr =
+                                       atl1e_rx_page_vld_regs[que][rx_using];
+                               AT_WRITE_REGB(&adapter->hw, reg_addr, 1);
+                               rx_page_desc[que].rx_using ^= 1;
+                               rx_page = atl1e_get_rx_page(adapter, que);
+                       }
+                       write_offset = *(rx_page->write_offset_addr);
+               } while (rx_page->read_offset < write_offset);
+       }
+
+       return;
+
+fatal_err:
+       if (!test_bit(__AT_DOWN, &adapter->flags))
+               schedule_work(&adapter->reset_task);
+}
+
+/*
+ * atl1e_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ */
+static int atl1e_clean(struct napi_struct *napi, int budget)
+{
+       struct atl1e_adapter *adapter =
+                       container_of(napi, struct atl1e_adapter, napi);
+       u32 imr_data;
+       int work_done = 0;
+
+       /* Keep link state information with original netdev */
+       if (!netif_carrier_ok(adapter->netdev))
+               goto quit_polling;
+
+       atl1e_clean_rx_irq(adapter, 0, &work_done, budget);
+
+       /* If no Tx and not enough Rx work done, exit the polling mode */
+       if (work_done < budget) {
+quit_polling:
+               napi_complete(napi);
+               imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
+               AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
+               /* test debug */
+               if (test_bit(__AT_DOWN, &adapter->flags)) {
+                       atomic_dec(&adapter->irq_sem);
+                       netdev_err(adapter->netdev,
+                                  "atl1e_clean is called when AT_DOWN\n");
+               }
+               /* reenable RX intr */
+               /*atl1e_irq_enable(adapter); */
+
+       }
+       return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void atl1e_netpoll(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       disable_irq(adapter->pdev->irq);
+       atl1e_intr(adapter->pdev->irq, netdev);
+       enable_irq(adapter->pdev->irq);
+}
+#endif
+
+static inline u16 atl1e_tpd_avail(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+       u16 next_to_use = 0;
+       u16 next_to_clean = 0;
+
+       next_to_clean = atomic_read(&tx_ring->next_to_clean);
+       next_to_use   = tx_ring->next_to_use;
+
+       return (u16)(next_to_clean > next_to_use) ?
+               (next_to_clean - next_to_use - 1) :
+               (tx_ring->count + next_to_clean - next_to_use - 1);
+}
+
+/*
+ * get next usable tpd
+ * Note: should call atl1e_tdp_avail to make sure
+ * there is enough tpd to use
+ */
+static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+       u16 next_to_use = 0;
+
+       next_to_use = tx_ring->next_to_use;
+       if (++tx_ring->next_to_use == tx_ring->count)
+               tx_ring->next_to_use = 0;
+
+       memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc));
+       return (struct atl1e_tpd_desc *)&tx_ring->desc[next_to_use];
+}
+
+static struct atl1e_tx_buffer *
+atl1e_get_tx_buffer(struct atl1e_adapter *adapter, struct atl1e_tpd_desc *tpd)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+
+       return &tx_ring->tx_buffer[tpd - tx_ring->desc];
+}
+
+/* Calculate the transmit packet descript needed*/
+static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
+{
+       int i = 0;
+       u16 tpd_req = 1;
+       u16 fg_size = 0;
+       u16 proto_hdr_len = 0;
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               fg_size = skb_shinfo(skb)->frags[i].size;
+               tpd_req += ((fg_size + MAX_TX_BUF_LEN - 1) >> MAX_TX_BUF_SHIFT);
+       }
+
+       if (skb_is_gso(skb)) {
+               if (skb->protocol == htons(ETH_P_IP) ||
+                  (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
+                       proto_hdr_len = skb_transport_offset(skb) +
+                                       tcp_hdrlen(skb);
+                       if (proto_hdr_len < skb_headlen(skb)) {
+                               tpd_req += ((skb_headlen(skb) - proto_hdr_len +
+                                          MAX_TX_BUF_LEN - 1) >>
+                                          MAX_TX_BUF_SHIFT);
+                       }
+               }
+
+       }
+       return tpd_req;
+}
+
+static int atl1e_tso_csum(struct atl1e_adapter *adapter,
+                      struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
+{
+       u8 hdr_len;
+       u32 real_len;
+       unsigned short offload_type;
+       int err;
+
+       if (skb_is_gso(skb)) {
+               if (skb_header_cloned(skb)) {
+                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+                       if (unlikely(err))
+                               return -1;
+               }
+               offload_type = skb_shinfo(skb)->gso_type;
+
+               if (offload_type & SKB_GSO_TCPV4) {
+                       real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
+                                       + ntohs(ip_hdr(skb)->tot_len));
+
+                       if (real_len < skb->len)
+                               pskb_trim(skb, real_len);
+
+                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+                       if (unlikely(skb->len == hdr_len)) {
+                               /* only xsum need */
+                               netdev_warn(adapter->netdev,
+                                           "IPV4 tso with zero data??\n");
+                               goto check_sum;
+                       } else {
+                               ip_hdr(skb)->check = 0;
+                               ip_hdr(skb)->tot_len = 0;
+                               tcp_hdr(skb)->check = ~csum_tcpudp_magic(
+                                                       ip_hdr(skb)->saddr,
+                                                       ip_hdr(skb)->daddr,
+                                                       0, IPPROTO_TCP, 0);
+                               tpd->word3 |= (ip_hdr(skb)->ihl &
+                                       TDP_V4_IPHL_MASK) <<
+                                       TPD_V4_IPHL_SHIFT;
+                               tpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+                                       TPD_TCPHDRLEN_MASK) <<
+                                       TPD_TCPHDRLEN_SHIFT;
+                               tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
+                                       TPD_MSS_MASK) << TPD_MSS_SHIFT;
+                               tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
+                       }
+                       return 0;
+               }
+       }
+
+check_sum:
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+               u8 css, cso;
+
+               cso = skb_checksum_start_offset(skb);
+               if (unlikely(cso & 0x1)) {
+                       netdev_err(adapter->netdev,
+                                  "payload offset should not ant event number\n");
+                       return -1;
+               } else {
+                       css = cso + skb->csum_offset;
+                       tpd->word3 |= (cso & TPD_PLOADOFFSET_MASK) <<
+                                       TPD_PLOADOFFSET_SHIFT;
+                       tpd->word3 |= (css & TPD_CCSUMOFFSET_MASK) <<
+                                       TPD_CCSUMOFFSET_SHIFT;
+                       tpd->word3 |= 1 << TPD_CC_SEGMENT_EN_SHIFT;
+               }
+       }
+
+       return 0;
+}
+
+static void atl1e_tx_map(struct atl1e_adapter *adapter,
+                     struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
+{
+       struct atl1e_tpd_desc *use_tpd = NULL;
+       struct atl1e_tx_buffer *tx_buffer = NULL;
+       u16 buf_len = skb_headlen(skb);
+       u16 map_len = 0;
+       u16 mapped_len = 0;
+       u16 hdr_len = 0;
+       u16 nr_frags;
+       u16 f;
+       int segment;
+
+       nr_frags = skb_shinfo(skb)->nr_frags;
+       segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
+       if (segment) {
+               /* TSO */
+               map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+               use_tpd = tpd;
+
+               tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
+               tx_buffer->length = map_len;
+               tx_buffer->dma = pci_map_single(adapter->pdev,
+                                       skb->data, hdr_len, PCI_DMA_TODEVICE);
+               ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
+               mapped_len += map_len;
+               use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
+               use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
+                       ((cpu_to_le32(tx_buffer->length) &
+                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
+       }
+
+       while (mapped_len < buf_len) {
+               /* mapped_len == 0, means we should use the first tpd,
+                  which is given by caller  */
+               if (mapped_len == 0) {
+                       use_tpd = tpd;
+               } else {
+                       use_tpd = atl1e_get_tpd(adapter);
+                       memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
+               }
+               tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
+               tx_buffer->skb = NULL;
+
+               tx_buffer->length = map_len =
+                       ((buf_len - mapped_len) >= MAX_TX_BUF_LEN) ?
+                       MAX_TX_BUF_LEN : (buf_len - mapped_len);
+               tx_buffer->dma =
+                       pci_map_single(adapter->pdev, skb->data + mapped_len,
+                                       map_len, PCI_DMA_TODEVICE);
+               ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
+               mapped_len  += map_len;
+               use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
+               use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
+                       ((cpu_to_le32(tx_buffer->length) &
+                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
+       }
+
+       for (f = 0; f < nr_frags; f++) {
+               struct skb_frag_struct *frag;
+               u16 i;
+               u16 seg_num;
+
+               frag = &skb_shinfo(skb)->frags[f];
+               buf_len = frag->size;
+
+               seg_num = (buf_len + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
+               for (i = 0; i < seg_num; i++) {
+                       use_tpd = atl1e_get_tpd(adapter);
+                       memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
+
+                       tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
+                       BUG_ON(tx_buffer->skb);
+
+                       tx_buffer->skb = NULL;
+                       tx_buffer->length =
+                               (buf_len > MAX_TX_BUF_LEN) ?
+                               MAX_TX_BUF_LEN : buf_len;
+                       buf_len -= tx_buffer->length;
+
+                       tx_buffer->dma =
+                               pci_map_page(adapter->pdev, frag->page,
+                                               frag->page_offset +
+                                               (i * MAX_TX_BUF_LEN),
+                                               tx_buffer->length,
+                                               PCI_DMA_TODEVICE);
+                       ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
+                       use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
+                       use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
+                                       ((cpu_to_le32(tx_buffer->length) &
+                                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
+               }
+       }
+
+       if ((tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK)
+               /* note this one is a tcp header */
+               tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
+       /* The last tpd */
+
+       use_tpd->word3 |= 1 << TPD_EOP_SHIFT;
+       /* The last buffer info contain the skb address,
+          so it will be free after unmap */
+       tx_buffer->skb = skb;
+}
+
+static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
+                          struct atl1e_tpd_desc *tpd)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+       /* Force memory writes to complete before letting h/w
+        * know there are new descriptors to fetch.  (Only
+        * applicable for weak-ordered memory model archs,
+        * such as IA-64). */
+       wmb();
+       AT_WRITE_REG(&adapter->hw, REG_MB_TPD_PROD_IDX, tx_ring->next_to_use);
+}
+
+static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
+                                         struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
+       u16 tpd_req = 1;
+       struct atl1e_tpd_desc *tpd;
+
+       if (test_bit(__AT_DOWN, &adapter->flags)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       if (unlikely(skb->len <= 0)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+       tpd_req = atl1e_cal_tdp_req(skb);
+       if (!spin_trylock_irqsave(&adapter->tx_lock, flags))
+               return NETDEV_TX_LOCKED;
+
+       if (atl1e_tpd_avail(adapter) < tpd_req) {
+               /* no enough descriptor, just stop queue */
+               netif_stop_queue(netdev);
+               spin_unlock_irqrestore(&adapter->tx_lock, flags);
+               return NETDEV_TX_BUSY;
+       }
+
+       tpd = atl1e_get_tpd(adapter);
+
+       if (vlan_tx_tag_present(skb)) {
+               u16 vlan_tag = vlan_tx_tag_get(skb);
+               u16 atl1e_vlan_tag;
+
+               tpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
+               AT_VLAN_TAG_TO_TPD_TAG(vlan_tag, atl1e_vlan_tag);
+               tpd->word2 |= (atl1e_vlan_tag & TPD_VLANTAG_MASK) <<
+                               TPD_VLAN_SHIFT;
+       }
+
+       if (skb->protocol == htons(ETH_P_8021Q))
+               tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
+
+       if (skb_network_offset(skb) != ETH_HLEN)
+               tpd->word3 |= 1 << TPD_ETHTYPE_SHIFT; /* 802.3 frame */
+
+       /* do TSO and check sum */
+       if (atl1e_tso_csum(adapter, skb, tpd) != 0) {
+               spin_unlock_irqrestore(&adapter->tx_lock, flags);
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       atl1e_tx_map(adapter, skb, tpd);
+       atl1e_tx_queue(adapter, tpd_req, tpd);
+
+       netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+       spin_unlock_irqrestore(&adapter->tx_lock, flags);
+       return NETDEV_TX_OK;
+}
+
+static void atl1e_free_irq(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       free_irq(adapter->pdev->irq, netdev);
+
+       if (adapter->have_msi)
+               pci_disable_msi(adapter->pdev);
+}
+
+static int atl1e_request_irq(struct atl1e_adapter *adapter)
+{
+       struct pci_dev    *pdev   = adapter->pdev;
+       struct net_device *netdev = adapter->netdev;
+       int flags = 0;
+       int err = 0;
+
+       adapter->have_msi = true;
+       err = pci_enable_msi(adapter->pdev);
+       if (err) {
+               netdev_dbg(adapter->netdev,
+                          "Unable to allocate MSI interrupt Error: %d\n", err);
+               adapter->have_msi = false;
+       } else
+               netdev->irq = pdev->irq;
+
+
+       if (!adapter->have_msi)
+               flags |= IRQF_SHARED;
+       err = request_irq(adapter->pdev->irq, atl1e_intr, flags,
+                       netdev->name, netdev);
+       if (err) {
+               netdev_dbg(adapter->netdev,
+                          "Unable to allocate interrupt Error: %d\n", err);
+               if (adapter->have_msi)
+                       pci_disable_msi(adapter->pdev);
+               return err;
+       }
+       netdev_dbg(adapter->netdev, "atl1e_request_irq OK\n");
+       return err;
+}
+
+int atl1e_up(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int err = 0;
+       u32 val;
+
+       /* hardware has been reset, we need to reload some things */
+       err = atl1e_init_hw(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               return err;
+       }
+       atl1e_init_ring_ptrs(adapter);
+       atl1e_set_multi(netdev);
+       atl1e_restore_vlan(adapter);
+
+       if (atl1e_configure(adapter)) {
+               err = -EIO;
+               goto err_up;
+       }
+
+       clear_bit(__AT_DOWN, &adapter->flags);
+       napi_enable(&adapter->napi);
+       atl1e_irq_enable(adapter);
+       val = AT_READ_REG(&adapter->hw, REG_MASTER_CTRL);
+       AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
+                     val | MASTER_CTRL_MANUAL_INT);
+
+err_up:
+       return err;
+}
+
+void atl1e_down(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       /* signal that we're down so the interrupt handler does not
+        * reschedule our watchdog timer */
+       set_bit(__AT_DOWN, &adapter->flags);
+
+       netif_stop_queue(netdev);
+
+       /* reset MAC to disable all RX/TX */
+       atl1e_reset_hw(&adapter->hw);
+       msleep(1);
+
+       napi_disable(&adapter->napi);
+       atl1e_del_timer(adapter);
+       atl1e_irq_disable(adapter);
+
+       netif_carrier_off(netdev);
+       adapter->link_speed = SPEED_0;
+       adapter->link_duplex = -1;
+       atl1e_clean_tx_ring(adapter);
+       atl1e_clean_rx_ring(adapter);
+}
+
+/*
+ * atl1e_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * 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 atl1e_open(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       int err;
+
+       /* disallow open during test */
+       if (test_bit(__AT_TESTING, &adapter->flags))
+               return -EBUSY;
+
+       /* allocate rx/tx dma buffer & descriptors */
+       atl1e_init_ring_resources(adapter);
+       err = atl1e_setup_ring_resources(adapter);
+       if (unlikely(err))
+               return err;
+
+       err = atl1e_request_irq(adapter);
+       if (unlikely(err))
+               goto err_req_irq;
+
+       err = atl1e_up(adapter);
+       if (unlikely(err))
+               goto err_up;
+
+       return 0;
+
+err_up:
+       atl1e_free_irq(adapter);
+err_req_irq:
+       atl1e_free_ring_resources(adapter);
+       atl1e_reset_hw(&adapter->hw);
+
+       return err;
+}
+
+/*
+ * atl1e_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * 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 atl1e_close(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+       atl1e_down(adapter);
+       atl1e_free_irq(adapter);
+       atl1e_free_ring_resources(adapter);
+
+       return 0;
+}
+
+static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 ctrl = 0;
+       u32 mac_ctrl_data = 0;
+       u32 wol_ctrl_data = 0;
+       u16 mii_advertise_data = 0;
+       u16 mii_bmsr_data = 0;
+       u16 mii_intr_status_data = 0;
+       u32 wufc = adapter->wol;
+       u32 i;
+#ifdef CONFIG_PM
+       int retval = 0;
+#endif
+
+       if (netif_running(netdev)) {
+               WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+               atl1e_down(adapter);
+       }
+       netif_device_detach(netdev);
+
+#ifdef CONFIG_PM
+       retval = pci_save_state(pdev);
+       if (retval)
+               return retval;
+#endif
+
+       if (wufc) {
+               /* get link status */
+               atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+               atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+
+               mii_advertise_data = ADVERTISE_10HALF;
+
+               if ((atl1e_write_phy_reg(hw, MII_CTRL1000, 0) != 0) ||
+                   (atl1e_write_phy_reg(hw,
+                          MII_ADVERTISE, mii_advertise_data) != 0) ||
+                   (atl1e_phy_commit(hw)) != 0) {
+                       netdev_dbg(adapter->netdev, "set phy register failed\n");
+                       goto wol_dis;
+               }
+
+               hw->phy_configured = false; /* re-init PHY when resume */
+
+               /* turn on magic packet wol */
+               if (wufc & AT_WUFC_MAG)
+                       wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+
+               if (wufc & AT_WUFC_LNKC) {
+               /* if orignal link status is link, just wait for retrive link */
+                       if (mii_bmsr_data & BMSR_LSTATUS) {
+                               for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
+                                       msleep(100);
+                                       atl1e_read_phy_reg(hw, MII_BMSR,
+                                                       (u16 *)&mii_bmsr_data);
+                                       if (mii_bmsr_data & BMSR_LSTATUS)
+                                               break;
+                               }
+
+                               if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
+                                       netdev_dbg(adapter->netdev,
+                                                  "Link may change when suspend\n");
+                       }
+                       wol_ctrl_data |=  WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
+                       /* only link up can wake up */
+                       if (atl1e_write_phy_reg(hw, MII_INT_CTRL, 0x400) != 0) {
+                               netdev_dbg(adapter->netdev,
+                                          "read write phy register failed\n");
+                               goto wol_dis;
+                       }
+               }
+               /* clear phy interrupt */
+               atl1e_read_phy_reg(hw, MII_INT_STATUS, &mii_intr_status_data);
+               /* Config MAC Ctrl register */
+               mac_ctrl_data = MAC_CTRL_RX_EN;
+               /* set to 10/100M halt duplex */
+               mac_ctrl_data |= MAC_CTRL_SPEED_10_100 << MAC_CTRL_SPEED_SHIFT;
+               mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
+                                MAC_CTRL_PRMLEN_MASK) <<
+                                MAC_CTRL_PRMLEN_SHIFT);
+
+               __atl1e_vlan_mode(netdev->features, &mac_ctrl_data);
+
+               /* magic packet maybe Broadcast&multicast&Unicast frame */
+               if (wufc & AT_WUFC_MAG)
+                       mac_ctrl_data |= MAC_CTRL_BC_EN;
+
+               netdev_dbg(adapter->netdev, "suspend MAC=0x%x\n",
+                          mac_ctrl_data);
+
+               AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
+               AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+               /* pcie patch */
+               ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
+               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+               AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+               goto suspend_exit;
+       }
+wol_dis:
+
+       /* WOL disabled */
+       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+       /* pcie patch */
+       ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
+       ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+       AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+
+       atl1e_force_ps(hw);
+       hw->phy_configured = false; /* re-init PHY when resume */
+
+       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+
+suspend_exit:
+
+       if (netif_running(netdev))
+               atl1e_free_irq(adapter);
+
+       pci_disable_device(pdev);
+
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int atl1e_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       u32 err;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               netdev_err(adapter->netdev,
+                          "Cannot enable PCI device from suspend\n");
+               return err;
+       }
+
+       pci_set_master(pdev);
+
+       AT_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+
+       if (netif_running(netdev)) {
+               err = atl1e_request_irq(adapter);
+               if (err)
+                       return err;
+       }
+
+       atl1e_reset_hw(&adapter->hw);
+
+       if (netif_running(netdev))
+               atl1e_up(adapter);
+
+       netif_device_attach(netdev);
+
+       return 0;
+}
+#endif
+
+static void atl1e_shutdown(struct pci_dev *pdev)
+{
+       atl1e_suspend(pdev, PMSG_SUSPEND);
+}
+
+static const struct net_device_ops atl1e_netdev_ops = {
+       .ndo_open               = atl1e_open,
+       .ndo_stop               = atl1e_close,
+       .ndo_start_xmit         = atl1e_xmit_frame,
+       .ndo_get_stats          = atl1e_get_stats,
+       .ndo_set_multicast_list = atl1e_set_multi,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = atl1e_set_mac_addr,
+       .ndo_fix_features       = atl1e_fix_features,
+       .ndo_set_features       = atl1e_set_features,
+       .ndo_change_mtu         = atl1e_change_mtu,
+       .ndo_do_ioctl           = atl1e_ioctl,
+       .ndo_tx_timeout         = atl1e_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = atl1e_netpoll,
+#endif
+
+};
+
+static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
+{
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+       pci_set_drvdata(pdev, netdev);
+
+       netdev->irq  = pdev->irq;
+       netdev->netdev_ops = &atl1e_netdev_ops;
+
+       netdev->watchdog_timeo = AT_TX_WATCHDOG;
+       atl1e_set_ethtool_ops(netdev);
+
+       netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
+                             NETIF_F_HW_VLAN_RX;
+       netdev->features = netdev->hw_features | NETIF_F_LLTX |
+                          NETIF_F_HW_VLAN_TX;
+
+       return 0;
+}
+
+/*
+ * atl1e_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl1e_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl1e_probe 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 __devinit atl1e_probe(struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
+{
+       struct net_device *netdev;
+       struct atl1e_adapter *adapter = NULL;
+       static int cards_found;
+
+       int err = 0;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "cannot enable PCI device\n");
+               return err;
+       }
+
+       /*
+        * The atl1e chip can DMA to 64-bit addresses, but it uses a single
+        * shared register for the high 32 bits, so only a single, aligned,
+        * 4 GB physical address range can be used at a time.
+        *
+        * Supporting 64-bit DMA on this hardware is more trouble than it's
+        * worth.  It is far easier to limit to 32-bit DMA than update
+        * various kernel subsystems to support the mechanics required by a
+        * fixed-high-32-bit system.
+        */
+       if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+           (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
+               dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
+               goto err_dma;
+       }
+
+       err = pci_request_regions(pdev, atl1e_driver_name);
+       if (err) {
+               dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+               goto err_pci_reg;
+       }
+
+       pci_set_master(pdev);
+
+       netdev = alloc_etherdev(sizeof(struct atl1e_adapter));
+       if (netdev == NULL) {
+               err = -ENOMEM;
+               dev_err(&pdev->dev, "etherdev alloc failed\n");
+               goto err_alloc_etherdev;
+       }
+
+       err = atl1e_init_netdev(netdev, pdev);
+       if (err) {
+               netdev_err(netdev, "init netdevice failed\n");
+               goto err_init_netdev;
+       }
+       adapter = netdev_priv(netdev);
+       adapter->bd_number = cards_found;
+       adapter->netdev = netdev;
+       adapter->pdev = pdev;
+       adapter->hw.adapter = adapter;
+       adapter->hw.hw_addr = pci_iomap(pdev, BAR_0, 0);
+       if (!adapter->hw.hw_addr) {
+               err = -EIO;
+               netdev_err(netdev, "cannot map device registers\n");
+               goto err_ioremap;
+       }
+       netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
+
+       /* init mii data */
+       adapter->mii.dev = netdev;
+       adapter->mii.mdio_read  = atl1e_mdio_read;
+       adapter->mii.mdio_write = atl1e_mdio_write;
+       adapter->mii.phy_id_mask = 0x1f;
+       adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
+
+       netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64);
+
+       init_timer(&adapter->phy_config_timer);
+       adapter->phy_config_timer.function = atl1e_phy_config;
+       adapter->phy_config_timer.data = (unsigned long) adapter;
+
+       /* get user settings */
+       atl1e_check_options(adapter);
+       /*
+        * Mark all PCI regions associated with PCI device
+        * pdev as being reserved by owner atl1e_driver_name
+        * Enables bus-mastering on the device and calls
+        * pcibios_set_master to do the needed arch specific settings
+        */
+       atl1e_setup_pcicmd(pdev);
+       /* setup the private structure */
+       err = atl1e_sw_init(adapter);
+       if (err) {
+               netdev_err(netdev, "net device private data init failed\n");
+               goto err_sw_init;
+       }
+
+       /* Init GPHY as early as possible due to power saving issue  */
+       atl1e_phy_init(&adapter->hw);
+       /* reset the controller to
+        * put the device in a known good starting state */
+       err = atl1e_reset_hw(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               goto err_reset;
+       }
+
+       if (atl1e_read_mac_addr(&adapter->hw) != 0) {
+               err = -EIO;
+               netdev_err(netdev, "get mac address failed\n");
+               goto err_eeprom;
+       }
+
+       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+       netdev_dbg(netdev, "mac address : %pM\n", adapter->hw.mac_addr);
+
+       INIT_WORK(&adapter->reset_task, atl1e_reset_task);
+       INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
+       err = register_netdev(netdev);
+       if (err) {
+               netdev_err(netdev, "register netdevice failed\n");
+               goto err_register;
+       }
+
+       /* assume we have no link for now */
+       netif_stop_queue(netdev);
+       netif_carrier_off(netdev);
+
+       cards_found++;
+
+       return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+err_eeprom:
+       iounmap(adapter->hw.hw_addr);
+err_init_netdev:
+err_ioremap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+       pci_disable_device(pdev);
+       return err;
+}
+
+/*
+ * atl1e_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl1e_remove 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 __devexit atl1e_remove(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       /*
+        * flush_scheduled work may reschedule our watchdog task, so
+        * explicitly disable watchdog tasks from being rescheduled
+        */
+       set_bit(__AT_DOWN, &adapter->flags);
+
+       atl1e_del_timer(adapter);
+       atl1e_cancel_work(adapter);
+
+       unregister_netdev(netdev);
+       atl1e_free_ring_resources(adapter);
+       atl1e_force_ps(&adapter->hw);
+       iounmap(adapter->hw.hw_addr);
+       pci_release_regions(pdev);
+       free_netdev(netdev);
+       pci_disable_device(pdev);
+}
+
+/*
+ * atl1e_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t
+atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       netif_device_detach(netdev);
+
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+
+       if (netif_running(netdev))
+               atl1e_down(adapter);
+
+       pci_disable_device(pdev);
+
+       /* Request a slot slot reset. */
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/*
+ * atl1e_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       if (pci_enable_device(pdev)) {
+               netdev_err(adapter->netdev,
+                          "Cannot re-enable PCI device after reset\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+       pci_set_master(pdev);
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       atl1e_reset_hw(&adapter->hw);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/*
+ * atl1e_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * 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 atl1e_resume routine.
+ */
+static void atl1e_io_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       if (netif_running(netdev)) {
+               if (atl1e_up(adapter)) {
+                       netdev_err(adapter->netdev,
+                                  "can't bring device back up after reset\n");
+                       return;
+               }
+       }
+
+       netif_device_attach(netdev);
+}
+
+static struct pci_error_handlers atl1e_err_handler = {
+       .error_detected = atl1e_io_error_detected,
+       .slot_reset = atl1e_io_slot_reset,
+       .resume = atl1e_io_resume,
+};
+
+static struct pci_driver atl1e_driver = {
+       .name     = atl1e_driver_name,
+       .id_table = atl1e_pci_tbl,
+       .probe    = atl1e_probe,
+       .remove   = __devexit_p(atl1e_remove),
+       /* Power Management Hooks */
+#ifdef CONFIG_PM
+       .suspend  = atl1e_suspend,
+       .resume   = atl1e_resume,
+#endif
+       .shutdown = atl1e_shutdown,
+       .err_handler = &atl1e_err_handler
+};
+
+/*
+ * atl1e_init_module - Driver Registration Routine
+ *
+ * atl1e_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl1e_init_module(void)
+{
+       return pci_register_driver(&atl1e_driver);
+}
+
+/*
+ * atl1e_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl1e_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl1e_exit_module(void)
+{
+       pci_unregister_driver(&atl1e_driver);
+}
+
+module_init(atl1e_init_module);
+module_exit(atl1e_exit_module);
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_param.c b/drivers/net/ethernet/atheros/atl1e/atl1e_param.c
new file mode 100644 (file)
index 0000000..0ce60b6
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#include <linux/netdevice.h>
+
+#include "atl1e.h"
+
+/* This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+
+#define ATL1E_MAX_NIC 32
+
+#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 ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET }
+
+#define ATL1E_PARAM(x, desc) \
+       static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
+       static unsigned int num_##x; \
+       module_param_array_named(x, x, int, &num_##x, 0); \
+       MODULE_PARM_DESC(x, desc);
+
+/* Transmit Memory count
+ *
+ * Valid Range: 64-2048
+ *
+ * Default Value: 128
+ */
+#define ATL1E_MIN_TX_DESC_CNT          32
+#define ATL1E_MAX_TX_DESC_CNT          1020
+#define ATL1E_DEFAULT_TX_DESC_CNT      128
+ATL1E_PARAM(tx_desc_cnt, "Transmit description count");
+
+/* Receive Memory Block Count
+ *
+ * Valid Range: 16-512
+ *
+ * Default Value: 128
+ */
+#define ATL1E_MIN_RX_MEM_SIZE          8    /* 8KB   */
+#define ATL1E_MAX_RX_MEM_SIZE          1024 /* 1MB   */
+#define ATL1E_DEFAULT_RX_MEM_SIZE      256  /* 128KB */
+ATL1E_PARAM(rx_mem_size, "memory size of rx buffer(KB)");
+
+/* User Specified MediaType Override
+ *
+ * Valid Range: 0-5
+ *  - 0    - auto-negotiate at all supported speeds
+ *  - 1    - only link at 100Mbps Full Duplex
+ *  - 2    - only link at 100Mbps Half Duplex
+ *  - 3    - only link at 10Mbps Full Duplex
+ *  - 4    - only link at 10Mbps Half Duplex
+ * Default Value: 0
+ */
+
+ATL1E_PARAM(media_type, "MediaType Select");
+
+/* Interrupt Moderate Timer in units of 2 us
+ *
+ * Valid Range: 10-65535
+ *
+ * Default Value: 45000(90ms)
+ */
+#define INT_MOD_DEFAULT_CNT             100 /* 200us */
+#define INT_MOD_MAX_CNT                 65000
+#define INT_MOD_MIN_CNT                 50
+ATL1E_PARAM(int_mod_timer, "Interrupt Moderator Timer");
+
+#define AUTONEG_ADV_DEFAULT  0x2F
+#define AUTONEG_ADV_MASK     0x2F
+#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
+
+#define FLASH_VENDOR_DEFAULT    0
+#define FLASH_VENDOR_MIN        0
+#define FLASH_VENDOR_MAX        2
+
+struct atl1e_option {
+       enum { enable_option, range_option, list_option } type;
+       char *name;
+       char *err;
+       int  def;
+       union {
+               struct { /* range_option info */
+                       int min;
+                       int max;
+               } r;
+               struct { /* list_option info */
+                       int nr;
+                       struct atl1e_opt_list { int i; char *str; } *p;
+               } l;
+       } arg;
+};
+
+static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct atl1e_adapter *adapter)
+{
+       if (*value == OPTION_UNSET) {
+               *value = opt->def;
+               return 0;
+       }
+
+       switch (opt->type) {
+       case enable_option:
+               switch (*value) {
+               case OPTION_ENABLED:
+                       netdev_info(adapter->netdev,
+                                   "%s Enabled\n", opt->name);
+                       return 0;
+               case OPTION_DISABLED:
+                       netdev_info(adapter->netdev,
+                                   "%s Disabled\n", opt->name);
+                       return 0;
+               }
+               break;
+       case range_option:
+               if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+                       netdev_info(adapter->netdev, "%s set to %i\n",
+                                   opt->name, *value);
+                       return 0;
+               }
+               break;
+       case list_option:{
+                       int i;
+                       struct atl1e_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')
+                                               netdev_info(adapter->netdev,
+                                                           "%s\n", ent->str);
+                                       return 0;
+                               }
+                       }
+                       break;
+               }
+       default:
+               BUG();
+       }
+
+       netdev_info(adapter->netdev, "Invalid %s specified (%i) %s\n",
+                   opt->name, *value, opt->err);
+       *value = opt->def;
+       return -1;
+}
+
+/*
+ * atl1e_check_options - Range Checking for Command Line Parameters
+ * @adapter: board private structure
+ *
+ * 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 __devinit atl1e_check_options(struct atl1e_adapter *adapter)
+{
+       int bd = adapter->bd_number;
+
+       if (bd >= ATL1E_MAX_NIC) {
+               netdev_notice(adapter->netdev,
+                             "no configuration for board #%i\n", bd);
+               netdev_notice(adapter->netdev,
+                             "Using defaults for all values\n");
+       }
+
+       {               /* Transmit Ring Size */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Transmit Ddescription Count",
+                       .err  = "using default of "
+                               __MODULE_STRING(ATL1E_DEFAULT_TX_DESC_CNT),
+                       .def  = ATL1E_DEFAULT_TX_DESC_CNT,
+                       .arg  = { .r = { .min = ATL1E_MIN_TX_DESC_CNT,
+                                        .max = ATL1E_MAX_TX_DESC_CNT} }
+               };
+               int val;
+               if (num_tx_desc_cnt > bd) {
+                       val = tx_desc_cnt[bd];
+                       atl1e_validate_option(&val, &opt, adapter);
+                       adapter->tx_ring.count = (u16) val & 0xFFFC;
+               } else
+                       adapter->tx_ring.count = (u16)opt.def;
+       }
+
+       {               /* Receive Memory Block Count */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Memory size of rx buffer(KB)",
+                       .err  = "using default of "
+                               __MODULE_STRING(ATL1E_DEFAULT_RX_MEM_SIZE),
+                       .def  = ATL1E_DEFAULT_RX_MEM_SIZE,
+                       .arg  = { .r = { .min = ATL1E_MIN_RX_MEM_SIZE,
+                                        .max = ATL1E_MAX_RX_MEM_SIZE} }
+               };
+               int val;
+               if (num_rx_mem_size > bd) {
+                       val = rx_mem_size[bd];
+                       atl1e_validate_option(&val, &opt, adapter);
+                       adapter->rx_ring.page_size = (u32)val * 1024;
+               } else {
+                       adapter->rx_ring.page_size = (u32)opt.def * 1024;
+               }
+       }
+
+       {               /* Interrupt Moderate Timer */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Interrupt Moderate Timer",
+                       .err  = "using default of "
+                               __MODULE_STRING(INT_MOD_DEFAULT_CNT),
+                       .def  = INT_MOD_DEFAULT_CNT,
+                       .arg  = { .r = { .min = INT_MOD_MIN_CNT,
+                                        .max = INT_MOD_MAX_CNT} }
+               } ;
+               int val;
+               if (num_int_mod_timer > bd) {
+                       val = int_mod_timer[bd];
+                       atl1e_validate_option(&val, &opt, adapter);
+                       adapter->hw.imt = (u16) val;
+               } else
+                       adapter->hw.imt = (u16)(opt.def);
+       }
+
+       {               /* MediaType */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Speed/Duplex Selection",
+                       .err  = "using default of "
+                               __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR),
+                       .def  = MEDIA_TYPE_AUTO_SENSOR,
+                       .arg  = { .r = { .min = MEDIA_TYPE_AUTO_SENSOR,
+                                        .max = MEDIA_TYPE_10M_HALF} }
+               } ;
+               int val;
+               if (num_media_type > bd) {
+                       val = media_type[bd];
+                       atl1e_validate_option(&val, &opt, adapter);
+                       adapter->hw.media_type = (u16) val;
+               } else
+                       adapter->hw.media_type = (u16)(opt.def);
+
+       }
+}
diff --git a/drivers/net/ethernet/atheros/atlx/Makefile b/drivers/net/ethernet/atheros/atlx/Makefile
new file mode 100644 (file)
index 0000000..e4f6022
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ATL1)     += atl1.o
+obj-$(CONFIG_ATL2)     += atl2.o
+
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
new file mode 100644 (file)
index 0000000..97e6954
--- /dev/null
@@ -0,0 +1,3675 @@
+/*
+ * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+ * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ *
+ * Contact Information:
+ * Xiong Huang <xiong.huang@atheros.com>
+ * Jie Yang <jie.yang@atheros.com>
+ * Chris Snook <csnook@redhat.com>
+ * Jay Cliburn <jcliburn@gmail.com>
+ *
+ * This version is adapted from the Attansic reference driver.
+ *
+ * TODO:
+ * Add more ethtool functions.
+ * Fix abstruse irq enable/disable condition described here:
+ *     http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2
+ *
+ * NEEDS TESTING:
+ * VLAN
+ * multicast
+ * promiscuous mode
+ * interrupt coalescing
+ * SMP torture testing
+ */
+
+#include <linux/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/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/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/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/tcp.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include <net/checksum.h>
+
+#include "atl1.h"
+
+#define ATLX_DRIVER_VERSION "2.1.3"
+MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, "
+             "Chris Snook <csnook@redhat.com>, "
+             "Jay Cliburn <jcliburn@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATLX_DRIVER_VERSION);
+
+/* Temporary hack for merging atl1 and atl2 */
+#include "atlx.c"
+
+static const struct ethtool_ops atl1_ethtool_ops;
+
+/*
+ * This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+#define ATL1_MAX_NIC 4
+
+#define OPTION_UNSET    -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED  1
+
+#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }
+
+/*
+ * Interrupt Moderate Timer in units of 2 us
+ *
+ * Valid Range: 10-65535
+ *
+ * Default Value: 100 (200us)
+ */
+static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
+static unsigned int num_int_mod_timer;
+module_param_array_named(int_mod_timer, int_mod_timer, int,
+       &num_int_mod_timer, 0);
+MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
+
+#define DEFAULT_INT_MOD_CNT    100     /* 200us */
+#define MAX_INT_MOD_CNT                65000
+#define MIN_INT_MOD_CNT                50
+
+struct atl1_option {
+       enum { enable_option, range_option, list_option } type;
+       char *name;
+       char *err;
+       int def;
+       union {
+               struct {        /* range_option info */
+                       int min;
+                       int max;
+               } r;
+               struct {        /* list_option info */
+                       int nr;
+                       struct atl1_opt_list {
+                               int i;
+                               char *str;
+                       } *p;
+               } l;
+       } arg;
+};
+
+static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
+       struct pci_dev *pdev)
+{
+       if (*value == OPTION_UNSET) {
+               *value = opt->def;
+               return 0;
+       }
+
+       switch (opt->type) {
+       case enable_option:
+               switch (*value) {
+               case OPTION_ENABLED:
+                       dev_info(&pdev->dev, "%s enabled\n", opt->name);
+                       return 0;
+               case OPTION_DISABLED:
+                       dev_info(&pdev->dev, "%s disabled\n", opt->name);
+                       return 0;
+               }
+               break;
+       case range_option:
+               if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+                       dev_info(&pdev->dev, "%s set to %i\n", opt->name,
+                               *value);
+                       return 0;
+               }
+               break;
+       case list_option:{
+                       int i;
+                       struct atl1_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')
+                                               dev_info(&pdev->dev, "%s\n",
+                                                       ent->str);
+                                       return 0;
+                               }
+                       }
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
+               opt->name, *value, opt->err);
+       *value = opt->def;
+       return -1;
+}
+
+/*
+ * atl1_check_options - Range Checking for Command Line Parameters
+ * @adapter: board private structure
+ *
+ * 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.
+ */
+static void __devinit atl1_check_options(struct atl1_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       int bd = adapter->bd_number;
+       if (bd >= ATL1_MAX_NIC) {
+               dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
+               dev_notice(&pdev->dev, "using defaults for all values\n");
+       }
+       {                       /* Interrupt Moderate Timer */
+               struct atl1_option opt = {
+                       .type = range_option,
+                       .name = "Interrupt Moderator Timer",
+                       .err = "using default of "
+                               __MODULE_STRING(DEFAULT_INT_MOD_CNT),
+                       .def = DEFAULT_INT_MOD_CNT,
+                       .arg = {.r = {.min = MIN_INT_MOD_CNT,
+                                       .max = MAX_INT_MOD_CNT} }
+               };
+               int val;
+               if (num_int_mod_timer > bd) {
+                       val = int_mod_timer[bd];
+                       atl1_validate_option(&val, &opt, pdev);
+                       adapter->imt = (u16) val;
+               } else
+                       adapter->imt = (u16) (opt.def);
+       }
+}
+
+/*
+ * atl1_pci_tbl - PCI Device ID Table
+ */
+static DEFINE_PCI_DEVICE_TABLE(atl1_pci_tbl) = {
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1)},
+       /* required last entry */
+       {0,}
+};
+MODULE_DEVICE_TABLE(pci, atl1_pci_tbl);
+
+static const u32 atl1_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
+       NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
+
+static int debug = -1;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Message level (0=none,...,16=all)");
+
+/*
+ * 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)
+ */
+static s32 atl1_reset_hw(struct atl1_hw *hw)
+{
+       struct pci_dev *pdev = hw->back->pdev;
+       struct atl1_adapter *adapter = hw->back;
+       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) {
+               if (netif_msg_hw(adapter))
+                       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
+ */
+static 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;
+               }
+       }
+
+       /* 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
+ */
+static 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
+ */
+static 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
+ */
+static 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
+ */
+static 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);
+}
+
+/*
+ * 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;
+       struct atl1_adapter *adapter = hw->back;
+       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! */
+               if (netif_msg_hw(adapter))
+                       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) {
+                       if (netif_msg_hw(adapter))
+                               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
+ */
+static 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;
+       struct atl1_adapter *adapter = hw->back;
+       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) {
+               if (netif_msg_link(adapter))
+                       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) {
+               if (netif_msg_link(adapter))
+                       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.
+ */
+static 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
+ */
+static s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
+{
+       struct pci_dev *pdev = hw->back->pdev;
+       struct atl1_adapter *adapter = hw->back;
+       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:
+               if (netif_msg_hw(adapter))
+                       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;
+}
+
+static 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));
+}
+
+/*
+ * atl1_sw_init - Initialize general software structures (struct atl1_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl1_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 __devinit atl1_sw_init(struct atl1_adapter *adapter)
+{
+       struct atl1_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+
+       hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+       hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+
+       adapter->wol = 0;
+       device_set_wakeup_enable(&adapter->pdev->dev, false);
+       adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
+       adapter->ict = 50000;           /* 100ms */
+       adapter->link_speed = SPEED_0;  /* hardware init */
+       adapter->link_duplex = FULL_DUPLEX;
+
+       hw->phy_configured = false;
+       hw->preamble_len = 7;
+       hw->ipgt = 0x60;
+       hw->min_ifg = 0x50;
+       hw->ipgr1 = 0x40;
+       hw->ipgr2 = 0x60;
+       hw->max_retry = 0xf;
+       hw->lcol = 0x37;
+       hw->jam_ipg = 7;
+       hw->rfd_burst = 8;
+       hw->rrd_burst = 8;
+       hw->rfd_fetch_gap = 1;
+       hw->rx_jumbo_th = adapter->rx_buffer_len / 8;
+       hw->rx_jumbo_lkah = 1;
+       hw->rrd_ret_timer = 16;
+       hw->tpd_burst = 4;
+       hw->tpd_fetch_th = 16;
+       hw->txf_burst = 0x100;
+       hw->tx_jumbo_task_th = (hw->max_frame_size + 7) >> 3;
+       hw->tpd_fetch_gap = 1;
+       hw->rcb_value = atl1_rcb_64;
+       hw->dma_ord = atl1_dma_ord_enh;
+       hw->dmar_block = atl1_dma_req_256;
+       hw->dmaw_block = atl1_dma_req_256;
+       hw->cmb_rrd = 4;
+       hw->cmb_tpd = 4;
+       hw->cmb_rx_timer = 1;   /* about 2us */
+       hw->cmb_tx_timer = 1;   /* about 2us */
+       hw->smb_timer = 100000; /* about 200ms */
+
+       spin_lock_init(&adapter->lock);
+       spin_lock_init(&adapter->mb_lock);
+
+       return 0;
+}
+
+static int mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       u16 result;
+
+       atl1_read_phy_reg(&adapter->hw, reg_num & 0x1f, &result);
+
+       return result;
+}
+
+static void mdio_write(struct net_device *netdev, int phy_id, int reg_num,
+       int val)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+
+       atl1_write_phy_reg(&adapter->hw, reg_num, val);
+}
+
+/*
+ * atl1_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
+       int retval;
+
+       if (!netif_running(netdev))
+               return -EINVAL;
+
+       spin_lock_irqsave(&adapter->lock, flags);
+       retval = generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);
+       spin_unlock_irqrestore(&adapter->lock, flags);
+
+       return retval;
+}
+
+/*
+ * atl1_setup_mem_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
+{
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
+       struct atl1_ring_header *ring_header = &adapter->ring_header;
+       struct pci_dev *pdev = adapter->pdev;
+       int size;
+       u8 offset = 0;
+
+       size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count);
+       tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
+       if (unlikely(!tpd_ring->buffer_info)) {
+               if (netif_msg_drv(adapter))
+                       dev_err(&pdev->dev, "kzalloc failed , size = D%d\n",
+                               size);
+               goto err_nomem;
+       }
+       rfd_ring->buffer_info =
+               (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
+
+       /*
+        * real ring DMA buffer
+        * each ring/block may need up to 8 bytes for alignment, hence the
+        * additional 40 bytes tacked onto the end.
+        */
+       ring_header->size = size =
+               sizeof(struct tx_packet_desc) * tpd_ring->count
+               + sizeof(struct rx_free_desc) * rfd_ring->count
+               + sizeof(struct rx_return_desc) * rrd_ring->count
+               + sizeof(struct coals_msg_block)
+               + sizeof(struct stats_msg_block)
+               + 40;
+
+       ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
+               &ring_header->dma);
+       if (unlikely(!ring_header->desc)) {
+               if (netif_msg_drv(adapter))
+                       dev_err(&pdev->dev, "pci_alloc_consistent failed\n");
+               goto err_nomem;
+       }
+
+       memset(ring_header->desc, 0, ring_header->size);
+
+       /* init TPD ring */
+       tpd_ring->dma = ring_header->dma;
+       offset = (tpd_ring->dma & 0x7) ? (8 - (ring_header->dma & 0x7)) : 0;
+       tpd_ring->dma += offset;
+       tpd_ring->desc = (u8 *) ring_header->desc + offset;
+       tpd_ring->size = sizeof(struct tx_packet_desc) * tpd_ring->count;
+
+       /* init RFD ring */
+       rfd_ring->dma = tpd_ring->dma + tpd_ring->size;
+       offset = (rfd_ring->dma & 0x7) ? (8 - (rfd_ring->dma & 0x7)) : 0;
+       rfd_ring->dma += offset;
+       rfd_ring->desc = (u8 *) tpd_ring->desc + (tpd_ring->size + offset);
+       rfd_ring->size = sizeof(struct rx_free_desc) * rfd_ring->count;
+
+
+       /* init RRD ring */
+       rrd_ring->dma = rfd_ring->dma + rfd_ring->size;
+       offset = (rrd_ring->dma & 0x7) ? (8 - (rrd_ring->dma & 0x7)) : 0;
+       rrd_ring->dma += offset;
+       rrd_ring->desc = (u8 *) rfd_ring->desc + (rfd_ring->size + offset);
+       rrd_ring->size = sizeof(struct rx_return_desc) * rrd_ring->count;
+
+
+       /* init CMB */
+       adapter->cmb.dma = rrd_ring->dma + rrd_ring->size;
+       offset = (adapter->cmb.dma & 0x7) ? (8 - (adapter->cmb.dma & 0x7)) : 0;
+       adapter->cmb.dma += offset;
+       adapter->cmb.cmb = (struct coals_msg_block *)
+               ((u8 *) rrd_ring->desc + (rrd_ring->size + offset));
+
+       /* init SMB */
+       adapter->smb.dma = adapter->cmb.dma + sizeof(struct coals_msg_block);
+       offset = (adapter->smb.dma & 0x7) ? (8 - (adapter->smb.dma & 0x7)) : 0;
+       adapter->smb.dma += offset;
+       adapter->smb.smb = (struct stats_msg_block *)
+               ((u8 *) adapter->cmb.cmb +
+               (sizeof(struct coals_msg_block) + offset));
+
+       return 0;
+
+err_nomem:
+       kfree(tpd_ring->buffer_info);
+       return -ENOMEM;
+}
+
+static void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
+{
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
+
+       atomic_set(&tpd_ring->next_to_use, 0);
+       atomic_set(&tpd_ring->next_to_clean, 0);
+
+       rfd_ring->next_to_clean = 0;
+       atomic_set(&rfd_ring->next_to_use, 0);
+
+       rrd_ring->next_to_use = 0;
+       atomic_set(&rrd_ring->next_to_clean, 0);
+}
+
+/*
+ * atl1_clean_rx_ring - Free RFD Buffers
+ * @adapter: board private structure
+ */
+static void atl1_clean_rx_ring(struct atl1_adapter *adapter)
+{
+       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
+       struct atl1_buffer *buffer_info;
+       struct pci_dev *pdev = adapter->pdev;
+       unsigned long size;
+       unsigned int i;
+
+       /* Free all the Rx ring sk_buffs */
+       for (i = 0; i < rfd_ring->count; i++) {
+               buffer_info = &rfd_ring->buffer_info[i];
+               if (buffer_info->dma) {
+                       pci_unmap_page(pdev, buffer_info->dma,
+                               buffer_info->length, PCI_DMA_FROMDEVICE);
+                       buffer_info->dma = 0;
+               }
+               if (buffer_info->skb) {
+                       dev_kfree_skb(buffer_info->skb);
+                       buffer_info->skb = NULL;
+               }
+       }
+
+       size = sizeof(struct atl1_buffer) * rfd_ring->count;
+       memset(rfd_ring->buffer_info, 0, size);
+
+       /* Zero out the descriptor ring */
+       memset(rfd_ring->desc, 0, rfd_ring->size);
+
+       rfd_ring->next_to_clean = 0;
+       atomic_set(&rfd_ring->next_to_use, 0);
+
+       rrd_ring->next_to_use = 0;
+       atomic_set(&rrd_ring->next_to_clean, 0);
+}
+
+/*
+ * atl1_clean_tx_ring - Free Tx Buffers
+ * @adapter: board private structure
+ */
+static void atl1_clean_tx_ring(struct atl1_adapter *adapter)
+{
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       struct atl1_buffer *buffer_info;
+       struct pci_dev *pdev = adapter->pdev;
+       unsigned long size;
+       unsigned int i;
+
+       /* Free all the Tx ring sk_buffs */
+       for (i = 0; i < tpd_ring->count; i++) {
+               buffer_info = &tpd_ring->buffer_info[i];
+               if (buffer_info->dma) {
+                       pci_unmap_page(pdev, buffer_info->dma,
+                               buffer_info->length, PCI_DMA_TODEVICE);
+                       buffer_info->dma = 0;
+               }
+       }
+
+       for (i = 0; i < tpd_ring->count; i++) {
+               buffer_info = &tpd_ring->buffer_info[i];
+               if (buffer_info->skb) {
+                       dev_kfree_skb_any(buffer_info->skb);
+                       buffer_info->skb = NULL;
+               }
+       }
+
+       size = sizeof(struct atl1_buffer) * tpd_ring->count;
+       memset(tpd_ring->buffer_info, 0, size);
+
+       /* Zero out the descriptor ring */
+       memset(tpd_ring->desc, 0, tpd_ring->size);
+
+       atomic_set(&tpd_ring->next_to_use, 0);
+       atomic_set(&tpd_ring->next_to_clean, 0);
+}
+
+/*
+ * atl1_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl1_free_ring_resources(struct atl1_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
+       struct atl1_ring_header *ring_header = &adapter->ring_header;
+
+       atl1_clean_tx_ring(adapter);
+       atl1_clean_rx_ring(adapter);
+
+       kfree(tpd_ring->buffer_info);
+       pci_free_consistent(pdev, ring_header->size, ring_header->desc,
+               ring_header->dma);
+
+       tpd_ring->buffer_info = NULL;
+       tpd_ring->desc = NULL;
+       tpd_ring->dma = 0;
+
+       rfd_ring->buffer_info = NULL;
+       rfd_ring->desc = NULL;
+       rfd_ring->dma = 0;
+
+       rrd_ring->desc = NULL;
+       rrd_ring->dma = 0;
+
+       adapter->cmb.dma = 0;
+       adapter->cmb.cmb = NULL;
+
+       adapter->smb.dma = 0;
+       adapter->smb.smb = NULL;
+}
+
+static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
+{
+       u32 value;
+       struct atl1_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       /* Config MAC CTRL Register */
+       value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN;
+       /* duplex */
+       if (FULL_DUPLEX == adapter->link_duplex)
+               value |= MAC_CTRL_DUPLX;
+       /* speed */
+       value |= ((u32) ((SPEED_1000 == adapter->link_speed) ?
+                        MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) <<
+                 MAC_CTRL_SPEED_SHIFT);
+       /* flow control */
+       value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+       /* PAD & CRC */
+       value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+       /* preamble length */
+       value |= (((u32) adapter->hw.preamble_len
+                  & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
+       /* vlan */
+       __atlx_vlan_mode(netdev->features, &value);
+       /* rx checksum
+          if (adapter->rx_csum)
+          value |= MAC_CTRL_RX_CHKSUM_EN;
+        */
+       /* filter mode */
+       value |= MAC_CTRL_BC_EN;
+       if (netdev->flags & IFF_PROMISC)
+               value |= MAC_CTRL_PROMIS_EN;
+       else if (netdev->flags & IFF_ALLMULTI)
+               value |= MAC_CTRL_MC_ALL_EN;
+       /* value |= MAC_CTRL_LOOPBACK; */
+       iowrite32(value, hw->hw_addr + REG_MAC_CTRL);
+}
+
+static u32 atl1_check_link(struct atl1_adapter *adapter)
+{
+       struct atl1_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       u32 ret_val;
+       u16 speed, duplex, phy_data;
+       int reconfig = 0;
+
+       /* 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 (netif_msg_link(adapter))
+                               dev_info(&adapter->pdev->dev, "link is down\n");
+                       adapter->link_speed = SPEED_0;
+                       netif_carrier_off(netdev);
+               }
+               return 0;
+       }
+
+       /* Link Up */
+       ret_val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
+       if (ret_val)
+               return ret_val;
+
+       switch (hw->media_type) {
+       case MEDIA_TYPE_1000M_FULL:
+               if (speed != SPEED_1000 || duplex != FULL_DUPLEX)
+                       reconfig = 1;
+               break;
+       case MEDIA_TYPE_100M_FULL:
+               if (speed != SPEED_100 || duplex != FULL_DUPLEX)
+                       reconfig = 1;
+               break;
+       case MEDIA_TYPE_100M_HALF:
+               if (speed != SPEED_100 || duplex != HALF_DUPLEX)
+                       reconfig = 1;
+               break;
+       case MEDIA_TYPE_10M_FULL:
+               if (speed != SPEED_10 || duplex != FULL_DUPLEX)
+                       reconfig = 1;
+               break;
+       case MEDIA_TYPE_10M_HALF:
+               if (speed != SPEED_10 || duplex != HALF_DUPLEX)
+                       reconfig = 1;
+               break;
+       }
+
+       /* link result is our setting */
+       if (!reconfig) {
+               if (adapter->link_speed != speed ||
+                   adapter->link_duplex != duplex) {
+                       adapter->link_speed = speed;
+                       adapter->link_duplex = duplex;
+                       atl1_setup_mac_ctrl(adapter);
+                       if (netif_msg_link(adapter))
+                               dev_info(&adapter->pdev->dev,
+                                       "%s link is up %d Mbps %s\n",
+                                       netdev->name, adapter->link_speed,
+                                       adapter->link_duplex == FULL_DUPLEX ?
+                                       "full duplex" : "half duplex");
+               }
+               if (!netif_carrier_ok(netdev)) {
+                       /* Link down -> Up */
+                       netif_carrier_on(netdev);
+               }
+               return 0;
+       }
+
+       /* change original link status */
+       if (netif_carrier_ok(netdev)) {
+               adapter->link_speed = SPEED_0;
+               netif_carrier_off(netdev);
+               netif_stop_queue(netdev);
+       }
+
+       if (hw->media_type != MEDIA_TYPE_AUTO_SENSOR &&
+           hw->media_type != MEDIA_TYPE_1000M_FULL) {
+               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);
+               return 0;
+       }
+
+       /* auto-neg, insert timer to re-config phy */
+       if (!adapter->phy_timer_pending) {
+               adapter->phy_timer_pending = true;
+               mod_timer(&adapter->phy_config_timer,
+                         round_jiffies(jiffies + 3 * HZ));
+       }
+
+       return 0;
+}
+
+static void set_flow_ctrl_old(struct atl1_adapter *adapter)
+{
+       u32 hi, lo, value;
+
+       /* RFD Flow Control */
+       value = adapter->rfd_ring.count;
+       hi = value / 16;
+       if (hi < 2)
+               hi = 2;
+       lo = value * 7 / 8;
+
+       value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
+               ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
+       iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RXF_PAUSE_THRESH);
+
+       /* RRD Flow Control */
+       value = adapter->rrd_ring.count;
+       lo = value / 16;
+       hi = value * 7 / 8;
+       if (lo < 2)
+               lo = 2;
+       value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) |
+               ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
+       iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RRD_PAUSE_THRESH);
+}
+
+static void set_flow_ctrl_new(struct atl1_hw *hw)
+{
+       u32 hi, lo, value;
+
+       /* RXF Flow Control */
+       value = ioread32(hw->hw_addr + REG_SRAM_RXF_LEN);
+       lo = value / 16;
+       if (lo < 192)
+               lo = 192;
+       hi = value * 7 / 8;
+       if (hi < lo)
+               hi = lo + 16;
+       value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
+               ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
+       iowrite32(value, hw->hw_addr + REG_RXQ_RXF_PAUSE_THRESH);
+
+       /* RRD Flow Control */
+       value = ioread32(hw->hw_addr + REG_SRAM_RRD_LEN);
+       lo = value / 8;
+       hi = value * 7 / 8;
+       if (lo < 2)
+               lo = 2;
+       if (hi < lo)
+               hi = lo + 3;
+       value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) |
+               ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
+       iowrite32(value, hw->hw_addr + REG_RXQ_RRD_PAUSE_THRESH);
+}
+
+/*
+ * atl1_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static u32 atl1_configure(struct atl1_adapter *adapter)
+{
+       struct atl1_hw *hw = &adapter->hw;
+       u32 value;
+
+       /* clear interrupt status */
+       iowrite32(0xffffffff, adapter->hw.hw_addr + REG_ISR);
+
+       /* set MAC Address */
+       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);
+       value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1]));
+       iowrite32(value, hw->hw_addr + (REG_MAC_STA_ADDR + 4));
+
+       /* tx / rx ring */
+
+       /* HI base address */
+       iowrite32((u32) ((adapter->tpd_ring.dma & 0xffffffff00000000ULL) >> 32),
+               hw->hw_addr + REG_DESC_BASE_ADDR_HI);
+       /* LO base address */
+       iowrite32((u32) (adapter->rfd_ring.dma & 0x00000000ffffffffULL),
+               hw->hw_addr + REG_DESC_RFD_ADDR_LO);
+       iowrite32((u32) (adapter->rrd_ring.dma & 0x00000000ffffffffULL),
+               hw->hw_addr + REG_DESC_RRD_ADDR_LO);
+       iowrite32((u32) (adapter->tpd_ring.dma & 0x00000000ffffffffULL),
+               hw->hw_addr + REG_DESC_TPD_ADDR_LO);
+       iowrite32((u32) (adapter->cmb.dma & 0x00000000ffffffffULL),
+               hw->hw_addr + REG_DESC_CMB_ADDR_LO);
+       iowrite32((u32) (adapter->smb.dma & 0x00000000ffffffffULL),
+               hw->hw_addr + REG_DESC_SMB_ADDR_LO);
+
+       /* element count */
+       value = adapter->rrd_ring.count;
+       value <<= 16;
+       value += adapter->rfd_ring.count;
+       iowrite32(value, hw->hw_addr + REG_DESC_RFD_RRD_RING_SIZE);
+       iowrite32(adapter->tpd_ring.count, hw->hw_addr +
+               REG_DESC_TPD_RING_SIZE);
+
+       /* Load Ptr */
+       iowrite32(1, hw->hw_addr + REG_LOAD_PTR);
+
+       /* config Mailbox */
+       value = ((atomic_read(&adapter->tpd_ring.next_to_use)
+                 & MB_TPD_PROD_INDX_MASK) << MB_TPD_PROD_INDX_SHIFT) |
+               ((atomic_read(&adapter->rrd_ring.next_to_clean)
+               & MB_RRD_CONS_INDX_MASK) << MB_RRD_CONS_INDX_SHIFT) |
+               ((atomic_read(&adapter->rfd_ring.next_to_use)
+               & MB_RFD_PROD_INDX_MASK) << MB_RFD_PROD_INDX_SHIFT);
+       iowrite32(value, hw->hw_addr + REG_MAILBOX);
+
+       /* config IPG/IFG */
+       value = (((u32) hw->ipgt & MAC_IPG_IFG_IPGT_MASK)
+                << MAC_IPG_IFG_IPGT_SHIFT) |
+               (((u32) hw->min_ifg & MAC_IPG_IFG_MIFG_MASK)
+               << MAC_IPG_IFG_MIFG_SHIFT) |
+               (((u32) hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK)
+               << MAC_IPG_IFG_IPGR1_SHIFT) |
+               (((u32) hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK)
+               << MAC_IPG_IFG_IPGR2_SHIFT);
+       iowrite32(value, hw->hw_addr + REG_MAC_IPG_IFG);
+
+       /* config  Half-Duplex Control */
+       value = ((u32) hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) |
+               (((u32) hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK)
+               << MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) |
+               MAC_HALF_DUPLX_CTRL_EXC_DEF_EN |
+               (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) |
+               (((u32) hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK)
+               << MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT);
+       iowrite32(value, hw->hw_addr + REG_MAC_HALF_DUPLX_CTRL);
+
+       /* set Interrupt Moderator Timer */
+       iowrite16(adapter->imt, hw->hw_addr + REG_IRQ_MODU_TIMER_INIT);
+       iowrite32(MASTER_CTRL_ITIMER_EN, hw->hw_addr + REG_MASTER_CTRL);
+
+       /* set Interrupt Clear Timer */
+       iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER);
+
+       /* set max frame size hw will accept */
+       iowrite32(hw->max_frame_size, hw->hw_addr + REG_MTU);
+
+       /* jumbo size & rrd retirement timer */
+       value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK)
+                << RXQ_JMBOSZ_TH_SHIFT) |
+               (((u32) hw->rx_jumbo_lkah & RXQ_JMBO_LKAH_MASK)
+               << RXQ_JMBO_LKAH_SHIFT) |
+               (((u32) hw->rrd_ret_timer & RXQ_RRD_TIMER_MASK)
+               << RXQ_RRD_TIMER_SHIFT);
+       iowrite32(value, hw->hw_addr + REG_RXQ_JMBOSZ_RRDTIM);
+
+       /* Flow Control */
+       switch (hw->dev_rev) {
+       case 0x8001:
+       case 0x9001:
+       case 0x9002:
+       case 0x9003:
+               set_flow_ctrl_old(adapter);
+               break;
+       default:
+               set_flow_ctrl_new(hw);
+               break;
+       }
+
+       /* config TXQ */
+       value = (((u32) hw->tpd_burst & TXQ_CTRL_TPD_BURST_NUM_MASK)
+                << TXQ_CTRL_TPD_BURST_NUM_SHIFT) |
+               (((u32) hw->txf_burst & TXQ_CTRL_TXF_BURST_NUM_MASK)
+               << TXQ_CTRL_TXF_BURST_NUM_SHIFT) |
+               (((u32) hw->tpd_fetch_th & TXQ_CTRL_TPD_FETCH_TH_MASK)
+               << TXQ_CTRL_TPD_FETCH_TH_SHIFT) | TXQ_CTRL_ENH_MODE |
+               TXQ_CTRL_EN;
+       iowrite32(value, hw->hw_addr + REG_TXQ_CTRL);
+
+       /* min tpd fetch gap & tx jumbo packet size threshold for taskoffload */
+       value = (((u32) hw->tx_jumbo_task_th & TX_JUMBO_TASK_TH_MASK)
+               << TX_JUMBO_TASK_TH_SHIFT) |
+               (((u32) hw->tpd_fetch_gap & TX_TPD_MIN_IPG_MASK)
+               << TX_TPD_MIN_IPG_SHIFT);
+       iowrite32(value, hw->hw_addr + REG_TX_JUMBO_TASK_TH_TPD_IPG);
+
+       /* config RXQ */
+       value = (((u32) hw->rfd_burst & RXQ_CTRL_RFD_BURST_NUM_MASK)
+               << RXQ_CTRL_RFD_BURST_NUM_SHIFT) |
+               (((u32) hw->rrd_burst & RXQ_CTRL_RRD_BURST_THRESH_MASK)
+               << RXQ_CTRL_RRD_BURST_THRESH_SHIFT) |
+               (((u32) hw->rfd_fetch_gap & RXQ_CTRL_RFD_PREF_MIN_IPG_MASK)
+               << RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT) | RXQ_CTRL_CUT_THRU_EN |
+               RXQ_CTRL_EN;
+       iowrite32(value, hw->hw_addr + REG_RXQ_CTRL);
+
+       /* config DMA Engine */
+       value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
+               << DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
+               ((((u32) hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+               << DMA_CTRL_DMAW_BURST_LEN_SHIFT) | DMA_CTRL_DMAR_EN |
+               DMA_CTRL_DMAW_EN;
+       value |= (u32) hw->dma_ord;
+       if (atl1_rcb_128 == hw->rcb_value)
+               value |= DMA_CTRL_RCB_VALUE;
+       iowrite32(value, hw->hw_addr + REG_DMA_CTRL);
+
+       /* config CMB / SMB */
+       value = (hw->cmb_tpd > adapter->tpd_ring.count) ?
+               hw->cmb_tpd : adapter->tpd_ring.count;
+       value <<= 16;
+       value |= hw->cmb_rrd;
+       iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TH);
+       value = hw->cmb_rx_timer | ((u32) hw->cmb_tx_timer << 16);
+       iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TIMER);
+       iowrite32(hw->smb_timer, hw->hw_addr + REG_SMB_TIMER);
+
+       /* --- enable CMB / SMB */
+       value = CSMB_CTRL_CMB_EN | CSMB_CTRL_SMB_EN;
+       iowrite32(value, hw->hw_addr + REG_CSMB_CTRL);
+
+       value = ioread32(adapter->hw.hw_addr + REG_ISR);
+       if (unlikely((value & ISR_PHY_LINKDOWN) != 0))
+               value = 1;      /* config failed */
+       else
+               value = 0;
+
+       /* clear all interrupt status */
+       iowrite32(0x3fffffff, adapter->hw.hw_addr + REG_ISR);
+       iowrite32(0, adapter->hw.hw_addr + REG_ISR);
+       return value;
+}
+
+/*
+ * atl1_pcie_patch - Patch for PCIE module
+ */
+static void atl1_pcie_patch(struct atl1_adapter *adapter)
+{
+       u32 value;
+
+       /* much vendor magic here */
+       value = 0x6500;
+       iowrite32(value, adapter->hw.hw_addr + 0x12FC);
+       /* pcie flow control mode change */
+       value = ioread32(adapter->hw.hw_addr + 0x1008);
+       value |= 0x8000;
+       iowrite32(value, adapter->hw.hw_addr + 0x1008);
+}
+
+/*
+ * When ACPI resume on some VIA MotherBoard, the Interrupt Disable bit/0x400
+ * on PCI Command register is disable.
+ * The function enable this bit.
+ * Brackett, 2006/03/15
+ */
+static void atl1_via_workaround(struct atl1_adapter *adapter)
+{
+       unsigned long value;
+
+       value = ioread16(adapter->hw.hw_addr + PCI_COMMAND);
+       if (value & PCI_COMMAND_INTX_DISABLE)
+               value &= ~PCI_COMMAND_INTX_DISABLE;
+       iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
+}
+
+static void atl1_inc_smb(struct atl1_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct stats_msg_block *smb = adapter->smb.smb;
+
+       /* Fill out the OS statistics structure */
+       adapter->soft_stats.rx_packets += smb->rx_ok;
+       adapter->soft_stats.tx_packets += smb->tx_ok;
+       adapter->soft_stats.rx_bytes += smb->rx_byte_cnt;
+       adapter->soft_stats.tx_bytes += smb->tx_byte_cnt;
+       adapter->soft_stats.multicast += smb->rx_mcast;
+       adapter->soft_stats.collisions += (smb->tx_1_col + smb->tx_2_col * 2 +
+               smb->tx_late_col + smb->tx_abort_col * adapter->hw.max_retry);
+
+       /* Rx Errors */
+       adapter->soft_stats.rx_errors += (smb->rx_frag + smb->rx_fcs_err +
+               smb->rx_len_err + smb->rx_sz_ov + smb->rx_rxf_ov +
+               smb->rx_rrd_ov + smb->rx_align_err);
+       adapter->soft_stats.rx_fifo_errors += smb->rx_rxf_ov;
+       adapter->soft_stats.rx_length_errors += smb->rx_len_err;
+       adapter->soft_stats.rx_crc_errors += smb->rx_fcs_err;
+       adapter->soft_stats.rx_frame_errors += smb->rx_align_err;
+       adapter->soft_stats.rx_missed_errors += (smb->rx_rrd_ov +
+               smb->rx_rxf_ov);
+
+       adapter->soft_stats.rx_pause += smb->rx_pause;
+       adapter->soft_stats.rx_rrd_ov += smb->rx_rrd_ov;
+       adapter->soft_stats.rx_trunc += smb->rx_sz_ov;
+
+       /* Tx Errors */
+       adapter->soft_stats.tx_errors += (smb->tx_late_col +
+               smb->tx_abort_col + smb->tx_underrun + smb->tx_trunc);
+       adapter->soft_stats.tx_fifo_errors += smb->tx_underrun;
+       adapter->soft_stats.tx_aborted_errors += smb->tx_abort_col;
+       adapter->soft_stats.tx_window_errors += smb->tx_late_col;
+
+       adapter->soft_stats.excecol += smb->tx_abort_col;
+       adapter->soft_stats.deffer += smb->tx_defer;
+       adapter->soft_stats.scc += smb->tx_1_col;
+       adapter->soft_stats.mcc += smb->tx_2_col;
+       adapter->soft_stats.latecol += smb->tx_late_col;
+       adapter->soft_stats.tx_underun += smb->tx_underrun;
+       adapter->soft_stats.tx_trunc += smb->tx_trunc;
+       adapter->soft_stats.tx_pause += smb->tx_pause;
+
+       netdev->stats.rx_packets = adapter->soft_stats.rx_packets;
+       netdev->stats.tx_packets = adapter->soft_stats.tx_packets;
+       netdev->stats.rx_bytes = adapter->soft_stats.rx_bytes;
+       netdev->stats.tx_bytes = adapter->soft_stats.tx_bytes;
+       netdev->stats.multicast = adapter->soft_stats.multicast;
+       netdev->stats.collisions = adapter->soft_stats.collisions;
+       netdev->stats.rx_errors = adapter->soft_stats.rx_errors;
+       netdev->stats.rx_over_errors =
+               adapter->soft_stats.rx_missed_errors;
+       netdev->stats.rx_length_errors =
+               adapter->soft_stats.rx_length_errors;
+       netdev->stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
+       netdev->stats.rx_frame_errors =
+               adapter->soft_stats.rx_frame_errors;
+       netdev->stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
+       netdev->stats.rx_missed_errors =
+               adapter->soft_stats.rx_missed_errors;
+       netdev->stats.tx_errors = adapter->soft_stats.tx_errors;
+       netdev->stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
+       netdev->stats.tx_aborted_errors =
+               adapter->soft_stats.tx_aborted_errors;
+       netdev->stats.tx_window_errors =
+               adapter->soft_stats.tx_window_errors;
+       netdev->stats.tx_carrier_errors =
+               adapter->soft_stats.tx_carrier_errors;
+}
+
+static void atl1_update_mailbox(struct atl1_adapter *adapter)
+{
+       unsigned long flags;
+       u32 tpd_next_to_use;
+       u32 rfd_next_to_use;
+       u32 rrd_next_to_clean;
+       u32 value;
+
+       spin_lock_irqsave(&adapter->mb_lock, flags);
+
+       tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
+       rfd_next_to_use = atomic_read(&adapter->rfd_ring.next_to_use);
+       rrd_next_to_clean = atomic_read(&adapter->rrd_ring.next_to_clean);
+
+       value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
+               MB_RFD_PROD_INDX_SHIFT) |
+               ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
+               MB_RRD_CONS_INDX_SHIFT) |
+               ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
+               MB_TPD_PROD_INDX_SHIFT);
+       iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
+
+       spin_unlock_irqrestore(&adapter->mb_lock, flags);
+}
+
+static void atl1_clean_alloc_flag(struct atl1_adapter *adapter,
+       struct rx_return_desc *rrd, u16 offset)
+{
+       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+
+       while (rfd_ring->next_to_clean != (rrd->buf_indx + offset)) {
+               rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced = 0;
+               if (++rfd_ring->next_to_clean == rfd_ring->count) {
+                       rfd_ring->next_to_clean = 0;
+               }
+       }
+}
+
+static void atl1_update_rfd_index(struct atl1_adapter *adapter,
+       struct rx_return_desc *rrd)
+{
+       u16 num_buf;
+
+       num_buf = (rrd->xsz.xsum_sz.pkt_size + adapter->rx_buffer_len - 1) /
+               adapter->rx_buffer_len;
+       if (rrd->num_buf == num_buf)
+               /* clean alloc flag for bad rrd */
+               atl1_clean_alloc_flag(adapter, rrd, num_buf);
+}
+
+static void atl1_rx_checksum(struct atl1_adapter *adapter,
+       struct rx_return_desc *rrd, struct sk_buff *skb)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       /*
+        * The L1 hardware contains a bug that erroneously sets the
+        * PACKET_FLAG_ERR and ERR_FLAG_L4_CHKSUM bits whenever a
+        * fragmented IP packet is received, even though the packet
+        * is perfectly valid and its checksum is correct. There's
+        * no way to distinguish between one of these good packets
+        * and a packet that actually contains a TCP/UDP checksum
+        * error, so all we can do is allow it to be handed up to
+        * the higher layers and let it be sorted out there.
+        */
+
+       skb_checksum_none_assert(skb);
+
+       if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
+               if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
+                                       ERR_FLAG_CODE | ERR_FLAG_OV)) {
+                       adapter->hw_csum_err++;
+                       if (netif_msg_rx_err(adapter))
+                               dev_printk(KERN_DEBUG, &pdev->dev,
+                                       "rx checksum error\n");
+                       return;
+               }
+       }
+
+       /* not IPv4 */
+       if (!(rrd->pkt_flg & PACKET_FLAG_IPV4))
+               /* checksum is invalid, but it's not an IPv4 pkt, so ok */
+               return;
+
+       /* IPv4 packet */
+       if (likely(!(rrd->err_flg &
+               (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM)))) {
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               adapter->hw_csum_good++;
+               return;
+       }
+}
+
+/*
+ * atl1_alloc_rx_buffers - Replace used receive buffers
+ * @adapter: address of board private structure
+ */
+static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
+{
+       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+       struct pci_dev *pdev = adapter->pdev;
+       struct page *page;
+       unsigned long offset;
+       struct atl1_buffer *buffer_info, *next_info;
+       struct sk_buff *skb;
+       u16 num_alloc = 0;
+       u16 rfd_next_to_use, next_next;
+       struct rx_free_desc *rfd_desc;
+
+       next_next = rfd_next_to_use = atomic_read(&rfd_ring->next_to_use);
+       if (++next_next == rfd_ring->count)
+               next_next = 0;
+       buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+       next_info = &rfd_ring->buffer_info[next_next];
+
+       while (!buffer_info->alloced && !next_info->alloced) {
+               if (buffer_info->skb) {
+                       buffer_info->alloced = 1;
+                       goto next;
+               }
+
+               rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
+
+               skb = netdev_alloc_skb_ip_align(adapter->netdev,
+                                               adapter->rx_buffer_len);
+               if (unlikely(!skb)) {
+                       /* Better luck next round */
+                       adapter->netdev->stats.rx_dropped++;
+                       break;
+               }
+
+               buffer_info->alloced = 1;
+               buffer_info->skb = skb;
+               buffer_info->length = (u16) adapter->rx_buffer_len;
+               page = virt_to_page(skb->data);
+               offset = (unsigned long)skb->data & ~PAGE_MASK;
+               buffer_info->dma = pci_map_page(pdev, page, offset,
+                                               adapter->rx_buffer_len,
+                                               PCI_DMA_FROMDEVICE);
+               rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+               rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len);
+               rfd_desc->coalese = 0;
+
+next:
+               rfd_next_to_use = next_next;
+               if (unlikely(++next_next == rfd_ring->count))
+                       next_next = 0;
+
+               buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+               next_info = &rfd_ring->buffer_info[next_next];
+               num_alloc++;
+       }
+
+       if (num_alloc) {
+               /*
+                * Force memory writes to complete before letting h/w
+                * know there are new descriptors to fetch.  (Only
+                * applicable for weak-ordered memory model archs,
+                * such as IA-64).
+                */
+               wmb();
+               atomic_set(&rfd_ring->next_to_use, (int)rfd_next_to_use);
+       }
+       return num_alloc;
+}
+
+static void atl1_intr_rx(struct atl1_adapter *adapter)
+{
+       int i, count;
+       u16 length;
+       u16 rrd_next_to_clean;
+       u32 value;
+       struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+       struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
+       struct atl1_buffer *buffer_info;
+       struct rx_return_desc *rrd;
+       struct sk_buff *skb;
+
+       count = 0;
+
+       rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
+
+       while (1) {
+               rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
+               i = 1;
+               if (likely(rrd->xsz.valid)) {   /* packet valid */
+chk_rrd:
+                       /* check rrd status */
+                       if (likely(rrd->num_buf == 1))
+                               goto rrd_ok;
+                       else if (netif_msg_rx_err(adapter)) {
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "unexpected RRD buffer count\n");
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "rx_buf_len = %d\n",
+                                       adapter->rx_buffer_len);
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "RRD num_buf = %d\n",
+                                       rrd->num_buf);
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "RRD pkt_len = %d\n",
+                                       rrd->xsz.xsum_sz.pkt_size);
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "RRD pkt_flg = 0x%08X\n",
+                                       rrd->pkt_flg);
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "RRD err_flg = 0x%08X\n",
+                                       rrd->err_flg);
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "RRD vlan_tag = 0x%08X\n",
+                                       rrd->vlan_tag);
+                       }
+
+                       /* rrd seems to be bad */
+                       if (unlikely(i-- > 0)) {
+                               /* rrd may not be DMAed completely */
+                               udelay(1);
+                               goto chk_rrd;
+                       }
+                       /* bad rrd */
+                       if (netif_msg_rx_err(adapter))
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "bad RRD\n");
+                       /* see if update RFD index */
+                       if (rrd->num_buf > 1)
+                               atl1_update_rfd_index(adapter, rrd);
+
+                       /* update rrd */
+                       rrd->xsz.valid = 0;
+                       if (++rrd_next_to_clean == rrd_ring->count)
+                               rrd_next_to_clean = 0;
+                       count++;
+                       continue;
+               } else {        /* current rrd still not be updated */
+
+                       break;
+               }
+rrd_ok:
+               /* clean alloc flag for bad rrd */
+               atl1_clean_alloc_flag(adapter, rrd, 0);
+
+               buffer_info = &rfd_ring->buffer_info[rrd->buf_indx];
+               if (++rfd_ring->next_to_clean == rfd_ring->count)
+                       rfd_ring->next_to_clean = 0;
+
+               /* update rrd next to clean */
+               if (++rrd_next_to_clean == rrd_ring->count)
+                       rrd_next_to_clean = 0;
+               count++;
+
+               if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
+                       if (!(rrd->err_flg &
+                               (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM
+                               | ERR_FLAG_LEN))) {
+                               /* packet error, don't need upstream */
+                               buffer_info->alloced = 0;
+                               rrd->xsz.valid = 0;
+                               continue;
+                       }
+               }
+
+               /* Good Receive */
+               pci_unmap_page(adapter->pdev, buffer_info->dma,
+                              buffer_info->length, PCI_DMA_FROMDEVICE);
+               buffer_info->dma = 0;
+               skb = buffer_info->skb;
+               length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size);
+
+               skb_put(skb, length - ETH_FCS_LEN);
+
+               /* Receive Checksum Offload */
+               atl1_rx_checksum(adapter, rrd, skb);
+               skb->protocol = eth_type_trans(skb, adapter->netdev);
+
+               if (rrd->pkt_flg & PACKET_FLAG_VLAN_INS) {
+                       u16 vlan_tag = (rrd->vlan_tag >> 4) |
+                                       ((rrd->vlan_tag & 7) << 13) |
+                                       ((rrd->vlan_tag & 8) << 9);
+
+                       __vlan_hwaccel_put_tag(skb, vlan_tag);
+               }
+               netif_rx(skb);
+
+               /* let protocol layer free skb */
+               buffer_info->skb = NULL;
+               buffer_info->alloced = 0;
+               rrd->xsz.valid = 0;
+       }
+
+       atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean);
+
+       atl1_alloc_rx_buffers(adapter);
+
+       /* update mailbox ? */
+       if (count) {
+               u32 tpd_next_to_use;
+               u32 rfd_next_to_use;
+
+               spin_lock(&adapter->mb_lock);
+
+               tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
+               rfd_next_to_use =
+                   atomic_read(&adapter->rfd_ring.next_to_use);
+               rrd_next_to_clean =
+                   atomic_read(&adapter->rrd_ring.next_to_clean);
+               value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
+                       MB_RFD_PROD_INDX_SHIFT) |
+                        ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
+                       MB_RRD_CONS_INDX_SHIFT) |
+                        ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
+                       MB_TPD_PROD_INDX_SHIFT);
+               iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
+               spin_unlock(&adapter->mb_lock);
+       }
+}
+
+static void atl1_intr_tx(struct atl1_adapter *adapter)
+{
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       struct atl1_buffer *buffer_info;
+       u16 sw_tpd_next_to_clean;
+       u16 cmb_tpd_next_to_clean;
+
+       sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+       cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
+
+       while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
+               buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
+               if (buffer_info->dma) {
+                       pci_unmap_page(adapter->pdev, buffer_info->dma,
+                                      buffer_info->length, PCI_DMA_TODEVICE);
+                       buffer_info->dma = 0;
+               }
+
+               if (buffer_info->skb) {
+                       dev_kfree_skb_irq(buffer_info->skb);
+                       buffer_info->skb = NULL;
+               }
+
+               if (++sw_tpd_next_to_clean == tpd_ring->count)
+                       sw_tpd_next_to_clean = 0;
+       }
+       atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean);
+
+       if (netif_queue_stopped(adapter->netdev) &&
+           netif_carrier_ok(adapter->netdev))
+               netif_wake_queue(adapter->netdev);
+}
+
+static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
+{
+       u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+       u16 next_to_use = atomic_read(&tpd_ring->next_to_use);
+       return (next_to_clean > next_to_use) ?
+               next_to_clean - next_to_use - 1 :
+               tpd_ring->count + next_to_clean - next_to_use - 1;
+}
+
+static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
+       struct tx_packet_desc *ptpd)
+{
+       u8 hdr_len, ip_off;
+       u32 real_len;
+       int err;
+
+       if (skb_shinfo(skb)->gso_size) {
+               if (skb_header_cloned(skb)) {
+                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+                       if (unlikely(err))
+                               return -1;
+               }
+
+               if (skb->protocol == htons(ETH_P_IP)) {
+                       struct iphdr *iph = ip_hdr(skb);
+
+                       real_len = (((unsigned char *)iph - skb->data) +
+                               ntohs(iph->tot_len));
+                       if (real_len < skb->len)
+                               pskb_trim(skb, real_len);
+                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+                       if (skb->len == hdr_len) {
+                               iph->check = 0;
+                               tcp_hdr(skb)->check =
+                                       ~csum_tcpudp_magic(iph->saddr,
+                                       iph->daddr, tcp_hdrlen(skb),
+                                       IPPROTO_TCP, 0);
+                               ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
+                                       TPD_IPHL_SHIFT;
+                               ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+                                       TPD_TCPHDRLEN_MASK) <<
+                                       TPD_TCPHDRLEN_SHIFT;
+                               ptpd->word3 |= 1 << TPD_IP_CSUM_SHIFT;
+                               ptpd->word3 |= 1 << TPD_TCP_CSUM_SHIFT;
+                               return 1;
+                       }
+
+                       iph->check = 0;
+                       tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
+                                       iph->daddr, 0, IPPROTO_TCP, 0);
+                       ip_off = (unsigned char *)iph -
+                               (unsigned char *) skb_network_header(skb);
+                       if (ip_off == 8) /* 802.3-SNAP frame */
+                               ptpd->word3 |= 1 << TPD_ETHTYPE_SHIFT;
+                       else if (ip_off != 0)
+                               return -2;
+
+                       ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
+                               TPD_IPHL_SHIFT;
+                       ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+                               TPD_TCPHDRLEN_MASK) << TPD_TCPHDRLEN_SHIFT;
+                       ptpd->word3 |= (skb_shinfo(skb)->gso_size &
+                               TPD_MSS_MASK) << TPD_MSS_SHIFT;
+                       ptpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
+                       return 3;
+               }
+       }
+       return false;
+}
+
+static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
+       struct tx_packet_desc *ptpd)
+{
+       u8 css, cso;
+
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+               css = skb_checksum_start_offset(skb);
+               cso = css + (u8) skb->csum_offset;
+               if (unlikely(css & 0x1)) {
+                       /* L1 hardware requires an even number here */
+                       if (netif_msg_tx_err(adapter))
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "payload offset not an even number\n");
+                       return -1;
+               }
+               ptpd->word3 |= (css & TPD_PLOADOFFSET_MASK) <<
+                       TPD_PLOADOFFSET_SHIFT;
+               ptpd->word3 |= (cso & TPD_CCSUMOFFSET_MASK) <<
+                       TPD_CCSUMOFFSET_SHIFT;
+               ptpd->word3 |= 1 << TPD_CUST_CSUM_EN_SHIFT;
+               return true;
+       }
+       return 0;
+}
+
+static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
+       struct tx_packet_desc *ptpd)
+{
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       struct atl1_buffer *buffer_info;
+       u16 buf_len = skb->len;
+       struct page *page;
+       unsigned long offset;
+       unsigned int nr_frags;
+       unsigned int f;
+       int retval;
+       u16 next_to_use;
+       u16 data_len;
+       u8 hdr_len;
+
+       buf_len -= skb->data_len;
+       nr_frags = skb_shinfo(skb)->nr_frags;
+       next_to_use = atomic_read(&tpd_ring->next_to_use);
+       buffer_info = &tpd_ring->buffer_info[next_to_use];
+       BUG_ON(buffer_info->skb);
+       /* put skb in last TPD */
+       buffer_info->skb = NULL;
+
+       retval = (ptpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
+       if (retval) {
+               /* TSO */
+               hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+               buffer_info->length = hdr_len;
+               page = virt_to_page(skb->data);
+               offset = (unsigned long)skb->data & ~PAGE_MASK;
+               buffer_info->dma = pci_map_page(adapter->pdev, page,
+                                               offset, hdr_len,
+                                               PCI_DMA_TODEVICE);
+
+               if (++next_to_use == tpd_ring->count)
+                       next_to_use = 0;
+
+               if (buf_len > hdr_len) {
+                       int i, nseg;
+
+                       data_len = buf_len - hdr_len;
+                       nseg = (data_len + ATL1_MAX_TX_BUF_LEN - 1) /
+                               ATL1_MAX_TX_BUF_LEN;
+                       for (i = 0; i < nseg; i++) {
+                               buffer_info =
+                                   &tpd_ring->buffer_info[next_to_use];
+                               buffer_info->skb = NULL;
+                               buffer_info->length =
+                                   (ATL1_MAX_TX_BUF_LEN >=
+                                    data_len) ? ATL1_MAX_TX_BUF_LEN : data_len;
+                               data_len -= buffer_info->length;
+                               page = virt_to_page(skb->data +
+                                       (hdr_len + i * ATL1_MAX_TX_BUF_LEN));
+                               offset = (unsigned long)(skb->data +
+                                       (hdr_len + i * ATL1_MAX_TX_BUF_LEN)) &
+                                       ~PAGE_MASK;
+                               buffer_info->dma = pci_map_page(adapter->pdev,
+                                       page, offset, buffer_info->length,
+                                       PCI_DMA_TODEVICE);
+                               if (++next_to_use == tpd_ring->count)
+                                       next_to_use = 0;
+                       }
+               }
+       } else {
+               /* not TSO */
+               buffer_info->length = buf_len;
+               page = virt_to_page(skb->data);
+               offset = (unsigned long)skb->data & ~PAGE_MASK;
+               buffer_info->dma = pci_map_page(adapter->pdev, page,
+                       offset, buf_len, PCI_DMA_TODEVICE);
+               if (++next_to_use == tpd_ring->count)
+                       next_to_use = 0;
+       }
+
+       for (f = 0; f < nr_frags; f++) {
+               struct skb_frag_struct *frag;
+               u16 i, nseg;
+
+               frag = &skb_shinfo(skb)->frags[f];
+               buf_len = frag->size;
+
+               nseg = (buf_len + ATL1_MAX_TX_BUF_LEN - 1) /
+                       ATL1_MAX_TX_BUF_LEN;
+               for (i = 0; i < nseg; i++) {
+                       buffer_info = &tpd_ring->buffer_info[next_to_use];
+                       BUG_ON(buffer_info->skb);
+
+                       buffer_info->skb = NULL;
+                       buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
+                               ATL1_MAX_TX_BUF_LEN : buf_len;
+                       buf_len -= buffer_info->length;
+                       buffer_info->dma = pci_map_page(adapter->pdev,
+                               frag->page,
+                               frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN),
+                               buffer_info->length, PCI_DMA_TODEVICE);
+
+                       if (++next_to_use == tpd_ring->count)
+                               next_to_use = 0;
+               }
+       }
+
+       /* last tpd's buffer-info */
+       buffer_info->skb = skb;
+}
+
+static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
+       struct tx_packet_desc *ptpd)
+{
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       struct atl1_buffer *buffer_info;
+       struct tx_packet_desc *tpd;
+       u16 j;
+       u32 val;
+       u16 next_to_use = (u16) atomic_read(&tpd_ring->next_to_use);
+
+       for (j = 0; j < count; j++) {
+               buffer_info = &tpd_ring->buffer_info[next_to_use];
+               tpd = ATL1_TPD_DESC(&adapter->tpd_ring, next_to_use);
+               if (tpd != ptpd)
+                       memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
+               tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+               tpd->word2 &= ~(TPD_BUFLEN_MASK << TPD_BUFLEN_SHIFT);
+               tpd->word2 |= (cpu_to_le16(buffer_info->length) &
+                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
+
+               /*
+                * if this is the first packet in a TSO chain, set
+                * TPD_HDRFLAG, otherwise, clear it.
+                */
+               val = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) &
+                       TPD_SEGMENT_EN_MASK;
+               if (val) {
+                       if (!j)
+                               tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
+                       else
+                               tpd->word3 &= ~(1 << TPD_HDRFLAG_SHIFT);
+               }
+
+               if (j == (count - 1))
+                       tpd->word3 |= 1 << TPD_EOP_SHIFT;
+
+               if (++next_to_use == tpd_ring->count)
+                       next_to_use = 0;
+       }
+       /*
+        * Force memory writes to complete before letting h/w
+        * know there are new descriptors to fetch.  (Only
+        * applicable for weak-ordered memory model archs,
+        * such as IA-64).
+        */
+       wmb();
+
+       atomic_set(&tpd_ring->next_to_use, next_to_use);
+}
+
+static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
+                                        struct net_device *netdev)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+       int len;
+       int tso;
+       int count = 1;
+       int ret_val;
+       struct tx_packet_desc *ptpd;
+       u16 frag_size;
+       u16 vlan_tag;
+       unsigned int nr_frags = 0;
+       unsigned int mss = 0;
+       unsigned int f;
+       unsigned int proto_hdr_len;
+
+       len = skb_headlen(skb);
+
+       if (unlikely(skb->len <= 0)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       nr_frags = skb_shinfo(skb)->nr_frags;
+       for (f = 0; f < nr_frags; f++) {
+               frag_size = skb_shinfo(skb)->frags[f].size;
+               if (frag_size)
+                       count += (frag_size + ATL1_MAX_TX_BUF_LEN - 1) /
+                               ATL1_MAX_TX_BUF_LEN;
+       }
+
+       mss = skb_shinfo(skb)->gso_size;
+       if (mss) {
+               if (skb->protocol == htons(ETH_P_IP)) {
+                       proto_hdr_len = (skb_transport_offset(skb) +
+                                        tcp_hdrlen(skb));
+                       if (unlikely(proto_hdr_len > len)) {
+                               dev_kfree_skb_any(skb);
+                               return NETDEV_TX_OK;
+                       }
+                       /* need additional TPD ? */
+                       if (proto_hdr_len != len)
+                               count += (len - proto_hdr_len +
+                                       ATL1_MAX_TX_BUF_LEN - 1) /
+                                       ATL1_MAX_TX_BUF_LEN;
+               }
+       }
+
+       if (atl1_tpd_avail(&adapter->tpd_ring) < count) {
+               /* not enough descriptors */
+               netif_stop_queue(netdev);
+               if (netif_msg_tx_queued(adapter))
+                       dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                               "tx busy\n");
+               return NETDEV_TX_BUSY;
+       }
+
+       ptpd = ATL1_TPD_DESC(tpd_ring,
+               (u16) atomic_read(&tpd_ring->next_to_use));
+       memset(ptpd, 0, sizeof(struct tx_packet_desc));
+
+       if (vlan_tx_tag_present(skb)) {
+               vlan_tag = vlan_tx_tag_get(skb);
+               vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
+                       ((vlan_tag >> 9) & 0x8);
+               ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
+               ptpd->word2 |= (vlan_tag & TPD_VLANTAG_MASK) <<
+                       TPD_VLANTAG_SHIFT;
+       }
+
+       tso = atl1_tso(adapter, skb, ptpd);
+       if (tso < 0) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       if (!tso) {
+               ret_val = atl1_tx_csum(adapter, skb, ptpd);
+               if (ret_val < 0) {
+                       dev_kfree_skb_any(skb);
+                       return NETDEV_TX_OK;
+               }
+       }
+
+       atl1_tx_map(adapter, skb, ptpd);
+       atl1_tx_queue(adapter, count, ptpd);
+       atl1_update_mailbox(adapter);
+       mmiowb();
+       return NETDEV_TX_OK;
+}
+
+/*
+ * atl1_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ */
+static irqreturn_t atl1_intr(int irq, void *data)
+{
+       struct atl1_adapter *adapter = netdev_priv(data);
+       u32 status;
+       int max_ints = 10;
+
+       status = adapter->cmb.cmb->int_stats;
+       if (!status)
+               return IRQ_NONE;
+
+       do {
+               /* clear CMB interrupt status at once */
+               adapter->cmb.cmb->int_stats = 0;
+
+               if (status & ISR_GPHY)  /* clear phy status */
+                       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);
+
+               /* check if SMB intr */
+               if (status & ISR_SMB)
+                       atl1_inc_smb(adapter);
+
+               /* check if PCIE PHY Link down */
+               if (status & ISR_PHY_LINKDOWN) {
+                       if (netif_msg_intr(adapter))
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "pcie phy link down %x\n", status);
+                       if (netif_running(adapter->netdev)) {   /* reset MAC */
+                               iowrite32(0, adapter->hw.hw_addr + REG_IMR);
+                               schedule_work(&adapter->pcie_dma_to_rst_task);
+                               return IRQ_HANDLED;
+                       }
+               }
+
+               /* check if DMA read/write error ? */
+               if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+                       if (netif_msg_intr(adapter))
+                               dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+                                       "pcie DMA r/w error (status = 0x%x)\n",
+                                       status);
+                       iowrite32(0, adapter->hw.hw_addr + REG_IMR);
+                       schedule_work(&adapter->pcie_dma_to_rst_task);
+                       return IRQ_HANDLED;
+               }
+
+               /* link event */
+               if (status & ISR_GPHY) {
+                       adapter->soft_stats.tx_carrier_errors++;
+                       atl1_check_for_link(adapter);
+               }
+
+               /* transmit event */
+               if (status & ISR_CMB_TX)
+                       atl1_intr_tx(adapter);
+
+               /* rx exception */
+               if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
+                       ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
+                       ISR_HOST_RRD_OV | ISR_CMB_RX))) {
+                       if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
+                               ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
+                               ISR_HOST_RRD_OV))
+                               if (netif_msg_intr(adapter))
+                                       dev_printk(KERN_DEBUG,
+                                               &adapter->pdev->dev,
+                                               "rx exception, ISR = 0x%x\n",
+                                               status);
+                       atl1_intr_rx(adapter);
+               }
+
+               if (--max_ints < 0)
+                       break;
+
+       } while ((status = adapter->cmb.cmb->int_stats));
+
+       /* re-enable Interrupt */
+       iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
+       return IRQ_HANDLED;
+}
+
+
+/*
+ * atl1_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1_phy_config(unsigned long data)
+{
+       struct atl1_adapter *adapter = (struct atl1_adapter *)data;
+       struct atl1_hw *hw = &adapter->hw;
+       unsigned long flags;
+
+       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_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);
+}
+
+/*
+ * Orphaned vendor comment left intact here:
+ * <vendor comment>
+ * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
+ * will assert. We do soft reset <0x1400=1> according
+ * with the SPEC. BUT, it seemes that PCIE or DMA
+ * state-machine will not be reset. DMAR_TO_INT will
+ * assert again and again.
+ * </vendor comment>
+ */
+
+static int atl1_reset(struct atl1_adapter *adapter)
+{
+       int ret;
+       ret = atl1_reset_hw(&adapter->hw);
+       if (ret)
+               return ret;
+       return atl1_init_hw(&adapter->hw);
+}
+
+static s32 atl1_up(struct atl1_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int err;
+       int irq_flags = 0;
+
+       /* hardware has been reset, we need to reload some things */
+       atlx_set_multi(netdev);
+       atl1_init_ring_ptrs(adapter);
+       atlx_restore_vlan(adapter);
+       err = atl1_alloc_rx_buffers(adapter);
+       if (unlikely(!err))
+               /* no RX BUFFER allocated */
+               return -ENOMEM;
+
+       if (unlikely(atl1_configure(adapter))) {
+               err = -EIO;
+               goto err_up;
+       }
+
+       err = pci_enable_msi(adapter->pdev);
+       if (err) {
+               if (netif_msg_ifup(adapter))
+                       dev_info(&adapter->pdev->dev,
+                               "Unable to enable MSI: %d\n", err);
+               irq_flags |= IRQF_SHARED;
+       }
+
+       err = request_irq(adapter->pdev->irq, atl1_intr, irq_flags,
+                       netdev->name, netdev);
+       if (unlikely(err))
+               goto err_up;
+
+       atlx_irq_enable(adapter);
+       atl1_check_link(adapter);
+       netif_start_queue(netdev);
+       return 0;
+
+err_up:
+       pci_disable_msi(adapter->pdev);
+       /* free rx_buffers */
+       atl1_clean_rx_ring(adapter);
+       return err;
+}
+
+static void atl1_down(struct atl1_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       netif_stop_queue(netdev);
+       del_timer_sync(&adapter->phy_config_timer);
+       adapter->phy_timer_pending = false;
+
+       atlx_irq_disable(adapter);
+       free_irq(adapter->pdev->irq, netdev);
+       pci_disable_msi(adapter->pdev);
+       atl1_reset_hw(&adapter->hw);
+       adapter->cmb.cmb->int_stats = 0;
+
+       adapter->link_speed = SPEED_0;
+       adapter->link_duplex = -1;
+       netif_carrier_off(netdev);
+
+       atl1_clean_tx_ring(adapter);
+       atl1_clean_rx_ring(adapter);
+}
+
+static void atl1_tx_timeout_task(struct work_struct *work)
+{
+       struct atl1_adapter *adapter =
+               container_of(work, struct atl1_adapter, tx_timeout_task);
+       struct net_device *netdev = adapter->netdev;
+
+       netif_device_detach(netdev);
+       atl1_down(adapter);
+       atl1_up(adapter);
+       netif_device_attach(netdev);
+}
+
+/*
+ * atl1_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       int old_mtu = netdev->mtu;
+       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+           (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+               if (netif_msg_link(adapter))
+                       dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+               return -EINVAL;
+       }
+
+       adapter->hw.max_frame_size = max_frame;
+       adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3;
+       adapter->rx_buffer_len = (max_frame + 7) & ~7;
+       adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8;
+
+       netdev->mtu = new_mtu;
+       if ((old_mtu != new_mtu) && netif_running(netdev)) {
+               atl1_down(adapter);
+               atl1_up(adapter);
+       }
+
+       return 0;
+}
+
+/*
+ * atl1_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * 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 atl1_open(struct net_device *netdev)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       int err;
+
+       netif_carrier_off(netdev);
+
+       /* allocate transmit descriptors */
+       err = atl1_setup_ring_resources(adapter);
+       if (err)
+               return err;
+
+       err = atl1_up(adapter);
+       if (err)
+               goto err_up;
+
+       return 0;
+
+err_up:
+       atl1_reset(adapter);
+       return err;
+}
+
+/*
+ * atl1_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * 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 atl1_close(struct net_device *netdev)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       atl1_down(adapter);
+       atl1_free_ring_resources(adapter);
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int atl1_suspend(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       struct atl1_hw *hw = &adapter->hw;
+       u32 ctrl = 0;
+       u32 wufc = adapter->wol;
+       u32 val;
+       u16 speed;
+       u16 duplex;
+
+       netif_device_detach(netdev);
+       if (netif_running(netdev))
+               atl1_down(adapter);
+
+       atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
+       atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
+       val = ctrl & BMSR_LSTATUS;
+       if (val)
+               wufc &= ~ATLX_WUFC_LNKC;
+       if (!wufc)
+               goto disable_wol;
+
+       if (val) {
+               val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
+               if (val) {
+                       if (netif_msg_ifdown(adapter))
+                               dev_printk(KERN_DEBUG, &pdev->dev,
+                                       "error getting speed/duplex\n");
+                       goto disable_wol;
+               }
+
+               ctrl = 0;
+
+               /* enable magic packet WOL */
+               if (wufc & ATLX_WUFC_MAG)
+                       ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
+               iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
+               ioread32(hw->hw_addr + REG_WOL_CTRL);
+
+               /* configure the mac */
+               ctrl = MAC_CTRL_RX_EN;
+               ctrl |= ((u32)((speed == SPEED_1000) ? MAC_CTRL_SPEED_1000 :
+                       MAC_CTRL_SPEED_10_100) << MAC_CTRL_SPEED_SHIFT);
+               if (duplex == FULL_DUPLEX)
+                       ctrl |= MAC_CTRL_DUPLX;
+               ctrl |= (((u32)adapter->hw.preamble_len &
+                       MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
+               __atlx_vlan_mode(netdev->features, &ctrl);
+               if (wufc & ATLX_WUFC_MAG)
+                       ctrl |= MAC_CTRL_BC_EN;
+               iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
+               ioread32(hw->hw_addr + REG_MAC_CTRL);
+
+               /* poke the PHY */
+               ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+               iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
+               ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+       } else {
+               ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
+               iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
+               ioread32(hw->hw_addr + REG_WOL_CTRL);
+               iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
+               ioread32(hw->hw_addr + REG_MAC_CTRL);
+               hw->phy_configured = false;
+       }
+
+       return 0;
+
+ disable_wol:
+       iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
+       ioread32(hw->hw_addr + REG_WOL_CTRL);
+       ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+       ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+       iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
+       ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
+       hw->phy_configured = false;
+
+       return 0;
+}
+
+static int atl1_resume(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+
+       iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
+
+       atl1_reset_hw(&adapter->hw);
+
+       if (netif_running(netdev)) {
+               adapter->cmb.cmb->int_stats = 0;
+               atl1_up(adapter);
+       }
+       netif_device_attach(netdev);
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(atl1_pm_ops, atl1_suspend, atl1_resume);
+#define ATL1_PM_OPS    (&atl1_pm_ops)
+
+#else
+
+static int atl1_suspend(struct device *dev) { return 0; }
+
+#define ATL1_PM_OPS    NULL
+#endif
+
+static void atl1_shutdown(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+
+       atl1_suspend(&pdev->dev);
+       pci_wake_from_d3(pdev, adapter->wol);
+       pci_set_power_state(pdev, PCI_D3hot);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void atl1_poll_controller(struct net_device *netdev)
+{
+       disable_irq(netdev->irq);
+       atl1_intr(netdev->irq, netdev);
+       enable_irq(netdev->irq);
+}
+#endif
+
+static const struct net_device_ops atl1_netdev_ops = {
+       .ndo_open               = atl1_open,
+       .ndo_stop               = atl1_close,
+       .ndo_start_xmit         = atl1_xmit_frame,
+       .ndo_set_multicast_list = atlx_set_multi,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = atl1_set_mac,
+       .ndo_change_mtu         = atl1_change_mtu,
+       .ndo_fix_features       = atlx_fix_features,
+       .ndo_set_features       = atlx_set_features,
+       .ndo_do_ioctl           = atlx_ioctl,
+       .ndo_tx_timeout         = atlx_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = atl1_poll_controller,
+#endif
+};
+
+/*
+ * atl1_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl1_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl1_probe 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 __devinit atl1_probe(struct pci_dev *pdev,
+       const struct pci_device_id *ent)
+{
+       struct net_device *netdev;
+       struct atl1_adapter *adapter;
+       static int cards_found = 0;
+       int err;
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+
+       /*
+        * The atl1 chip can DMA to 64-bit addresses, but it uses a single
+        * shared register for the high 32 bits, so only a single, aligned,
+        * 4 GB physical address range can be used at a time.
+        *
+        * Supporting 64-bit DMA on this hardware is more trouble than it's
+        * worth.  It is far easier to limit to 32-bit DMA than update
+        * various kernel subsystems to support the mechanics required by a
+        * fixed-high-32-bit system.
+        */
+       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (err) {
+               dev_err(&pdev->dev, "no usable DMA configuration\n");
+               goto err_dma;
+       }
+       /*
+        * Mark all PCI regions associated with PCI device
+        * pdev as being reserved by owner 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
+        * pcibios_set_master to do the needed arch specific settings
+        */
+       pci_set_master(pdev);
+
+       netdev = alloc_etherdev(sizeof(struct atl1_adapter));
+       if (!netdev) {
+               err = -ENOMEM;
+               goto err_alloc_etherdev;
+       }
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+
+       pci_set_drvdata(pdev, netdev);
+       adapter = netdev_priv(netdev);
+       adapter->netdev = netdev;
+       adapter->pdev = pdev;
+       adapter->hw.back = adapter;
+       adapter->msg_enable = netif_msg_init(debug, atl1_default_msg);
+
+       adapter->hw.hw_addr = pci_iomap(pdev, 0, 0);
+       if (!adapter->hw.hw_addr) {
+               err = -EIO;
+               goto err_pci_iomap;
+       }
+       /* get device revision number */
+       adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
+               (REG_MASTER_CTRL + 2));
+       if (netif_msg_probe(adapter))
+               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;
+       adapter->tpd_ring.count = ATL1_DEFAULT_TPD;
+
+       adapter->mii.dev = netdev;
+       adapter->mii.mdio_read = mdio_read;
+       adapter->mii.mdio_write = mdio_write;
+       adapter->mii.phy_id_mask = 0x1f;
+       adapter->mii.reg_num_mask = 0x1f;
+
+       netdev->netdev_ops = &atl1_netdev_ops;
+       netdev->watchdog_timeo = 5 * HZ;
+
+       netdev->ethtool_ops = &atl1_ethtool_ops;
+       adapter->bd_number = cards_found;
+
+       /* setup the private structure */
+       err = atl1_sw_init(adapter);
+       if (err)
+               goto err_common;
+
+       netdev->features = NETIF_F_HW_CSUM;
+       netdev->features |= NETIF_F_SG;
+       netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
+
+       netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO |
+                             NETIF_F_HW_VLAN_RX;
+
+       /* is this valid? see atl1_setup_mac_ctrl() */
+       netdev->features |= NETIF_F_RXCSUM;
+
+       /*
+        * patch for some L1 of old version,
+        * the final version of L1 may not need these
+        * patches
+        */
+       /* atl1_pcie_patch(adapter); */
+
+       /* really reset GPHY core */
+       iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
+
+       /*
+        * reset the controller to
+        * put the device in a known good starting state
+        */
+       if (atl1_reset_hw(&adapter->hw)) {
+               err = -EIO;
+               goto err_common;
+       }
+
+       /* copy the MAC address out of the EEPROM */
+       atl1_read_mac_addr(&adapter->hw);
+       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+
+       if (!is_valid_ether_addr(netdev->dev_addr)) {
+               err = -EIO;
+               goto err_common;
+       }
+
+       atl1_check_options(adapter);
+
+       /* pre-init the MAC, and setup link */
+       err = atl1_init_hw(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               goto err_common;
+       }
+
+       atl1_pcie_patch(adapter);
+       /* assume we have no link for now */
+       netif_carrier_off(netdev);
+
+       setup_timer(&adapter->phy_config_timer, atl1_phy_config,
+                   (unsigned long)adapter);
+       adapter->phy_timer_pending = false;
+
+       INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
+
+       INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
+
+       INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
+
+       err = register_netdev(netdev);
+       if (err)
+               goto err_common;
+
+       cards_found++;
+       atl1_via_workaround(adapter);
+       return 0;
+
+err_common:
+       pci_iounmap(pdev, adapter->hw.hw_addr);
+err_pci_iomap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       pci_release_regions(pdev);
+err_dma:
+err_request_regions:
+       pci_disable_device(pdev);
+       return err;
+}
+
+/*
+ * atl1_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl1_remove 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 __devexit atl1_remove(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1_adapter *adapter;
+       /* Device not available. Return. */
+       if (!netdev)
+               return;
+
+       adapter = netdev_priv(netdev);
+
+       /*
+        * 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.
+        */
+       if (memcmp(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN)) {
+               memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr,
+                       ETH_ALEN);
+               atl1_set_mac_addr(&adapter->hw);
+       }
+
+       iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
+       unregister_netdev(netdev);
+       pci_iounmap(pdev, adapter->hw.hw_addr);
+       pci_release_regions(pdev);
+       free_netdev(netdev);
+       pci_disable_device(pdev);
+}
+
+static struct pci_driver atl1_driver = {
+       .name = ATLX_DRIVER_NAME,
+       .id_table = atl1_pci_tbl,
+       .probe = atl1_probe,
+       .remove = __devexit_p(atl1_remove),
+       .shutdown = atl1_shutdown,
+       .driver.pm = ATL1_PM_OPS,
+};
+
+/*
+ * atl1_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl1_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl1_exit_module(void)
+{
+       pci_unregister_driver(&atl1_driver);
+}
+
+/*
+ * atl1_init_module - Driver Registration Routine
+ *
+ * atl1_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl1_init_module(void)
+{
+       return pci_register_driver(&atl1_driver);
+}
+
+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)},
+       {"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);
+               ethtool_cmd_speed_set(ecmd, link_speed);
+               if (link_duplex == FULL_DUPLEX)
+                       ecmd->duplex = DUPLEX_FULL;
+               else
+                       ecmd->duplex = DUPLEX_HALF;
+       } else {
+               ethtool_cmd_speed_set(ecmd, -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)) {
+               if (netif_msg_link(adapter))
+                       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 {
+               u32 speed = ethtool_cmd_speed(ecmd);
+               if (speed == SPEED_1000) {
+                       if (ecmd->duplex != DUPLEX_FULL) {
+                               if (netif_msg_link(adapter))
+                                       dev_warn(&adapter->pdev->dev,
+                                               "1000M half is invalid\n");
+                               ret_val = -EINVAL;
+                               goto exit_sset;
+                       }
+                       hw->media_type = MEDIA_TYPE_1000M_FULL;
+               } else if (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;
+               if (netif_msg_link(adapter))
+                       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)) {
+               if (netif_msg_link(adapter))
+                       dev_dbg(&adapter->pdev->dev,
+                               "ethtool starting adapter\n");
+               atl1_up(adapter);
+       } else if (!ret_val) {
+               if (netif_msg_link(adapter))
+                       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);
+
+       strlcpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
+       strlcpy(drvinfo->version, ATLX_DRIVER_VERSION,
+               sizeof(drvinfo->version));
+       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcpy(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_MAGIC;
+       wol->wolopts = 0;
+       if (adapter->wol & ATLX_WUFC_MAG)
+               wol->wolopts |= WAKE_MAGIC;
+}
+
+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_UCAST | WAKE_MCAST | WAKE_BCAST |
+               WAKE_ARP | WAKE_MAGICSECURE))
+               return -EOPNOTSUPP;
+       adapter->wol = 0;
+       if (wol->wolopts & WAKE_MAGIC)
+               adapter->wol |= ATLX_WUFC_MAG;
+
+       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+       return 0;
+}
+
+static u32 atl1_get_msglevel(struct net_device *netdev)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       return adapter->msg_enable;
+}
+
+static void atl1_set_msglevel(struct net_device *netdev, u32 value)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       adapter->msg_enable = value;
+}
+
+static int atl1_get_regs_len(struct net_device *netdev)
+{
+       return ATL1_REG_COUNT * sizeof(u32);
+}
+
+static void atl1_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
+       void *p)
+{
+       struct atl1_adapter *adapter = netdev_priv(netdev);
+       struct atl1_hw *hw = &adapter->hw;
+       unsigned int i;
+       u32 *regbuf = p;
+
+       for (i = 0; i < ATL1_REG_COUNT; i++) {
+               /*
+                * This switch statement avoids reserved regions
+                * of register space.
+                */
+               switch (i) {
+               case 6 ... 9:
+               case 14:
+               case 29 ... 31:
+               case 34 ... 63:
+               case 75 ... 127:
+               case 136 ... 1023:
+               case 1027 ... 1087:
+               case 1091 ... 1151:
+               case 1194 ... 1195:
+               case 1200 ... 1201:
+               case 1206 ... 1213:
+               case 1216 ... 1279:
+               case 1290 ... 1311:
+               case 1323 ... 1343:
+               case 1358 ... 1359:
+               case 1368 ... 1375:
+               case 1378 ... 1383:
+               case 1388 ... 1391:
+               case 1393 ... 1395:
+               case 1402 ... 1403:
+               case 1410 ... 1471:
+               case 1522 ... 1535:
+                       /* reserved region; don't read it */
+                       regbuf[i] = 0;
+                       break;
+               default:
+                       /* unreserved region */
+                       regbuf[i] = ioread32(hw->hw_addr + (i * sizeof(u32)));
+               }
+       }
+}
+
+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;
+       struct atl1_smb smb;
+       struct atl1_cmb cmb;
+       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;
+               /*
+                * Save SMB and CMB, since atl1_free_ring_resources
+                * will clear them.
+                */
+               smb = adapter->smb;
+               cmb = adapter->cmb;
+               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;
+               adapter->smb = smb;
+               adapter->cmb = cmb;
+
+               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;
+}
+
+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;
+}
+
+static 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_msglevel           = atl1_get_msglevel,
+       .set_msglevel           = atl1_set_msglevel,
+       .get_regs_len           = atl1_get_regs_len,
+       .get_regs               = atl1_get_regs,
+       .get_ringparam          = atl1_get_ringparam,
+       .set_ringparam          = atl1_set_ringparam,
+       .get_pauseparam         = atl1_get_pauseparam,
+       .set_pauseparam         = atl1_set_pauseparam,
+       .get_link               = ethtool_op_get_link,
+       .get_strings            = atl1_get_strings,
+       .nway_reset             = atl1_nway_reset,
+       .get_ethtool_stats      = atl1_get_ethtool_stats,
+       .get_sset_count         = atl1_get_sset_count,
+};
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h
new file mode 100644 (file)
index 0000000..109d6da
--- /dev/null
@@ -0,0 +1,792 @@
+/*
+ * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+ * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#ifndef ATL1_H
+#define ATL1_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"
+
+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 */
+static u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
+static void atl1_hash_set(struct atl1_hw *hw, u32 hash_value);
+static void atl1_set_mac_addr(struct atl1_hw *hw);
+static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
+       int cmd);
+static u32 atl1_check_link(struct atl1_adapter *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                       0x800
+
+/* CMB/SMB Control Register */
+#define REG_CSMB_CTRL                          0x15D0
+#define CSMB_CTRL_CMB_NOW                      1
+#define CSMB_CTRL_SMB_NOW                      2
+#define CSMB_CTRL_CMB_EN                       4
+#define CSMB_CTRL_SMB_EN                       8
+
+/* CMB DMA Write Threshold Register */
+#define REG_CMB_WRITE_TH                       0x15D4
+#define CMB_RRD_TH_SHIFT                       0
+#define CMB_RRD_TH_MASK                                0x7FF
+#define CMB_TPD_TH_SHIFT                       16
+#define CMB_TPD_TH_MASK                                0x7FF
+
+/* RX/TX count-down timer to trigger CMB-write. 2us resolution. */
+#define REG_CMB_WRITE_TIMER                    0x15D8
+#define CMB_RX_TM_SHIFT                                0
+#define CMB_RX_TM_MASK                         0xFFFF
+#define CMB_TX_TM_SHIFT                                16
+#define CMB_TX_TM_MASK                         0xFFFF
+
+/* Number of packet received since last CMB write */
+#define REG_CMB_RX_PKT_CNT                     0x15DC
+
+/* Number of packet transmitted since last CMB write */
+#define REG_CMB_TX_PKT_CNT                     0x15E0
+
+/* SMB auto DMA timer register */
+#define REG_SMB_TIMER                          0x15E4
+
+/* Mailbox Register */
+#define REG_MAILBOX                            0x15F0
+#define MB_RFD_PROD_INDX_SHIFT                 0
+#define MB_RFD_PROD_INDX_MASK                  0x7FF
+#define MB_RRD_CONS_INDX_SHIFT                 11
+#define MB_RRD_CONS_INDX_MASK                  0x7FF
+#define MB_TPD_PROD_INDX_SHIFT                 22
+#define MB_TPD_PROD_INDX_MASK                  0x3FF
+
+/* Interrupt Status Register */
+#define ISR_SMB                                        0x1
+#define ISR_TIMER                              0x2
+#define ISR_MANUAL                             0x4
+#define ISR_RXF_OV                             0x8
+#define ISR_RFD_UNRUN                          0x10
+#define ISR_RRD_OV                             0x20
+#define ISR_TXF_UNRUN                          0x40
+#define ISR_LINK                               0x80
+#define ISR_HOST_RFD_UNRUN                     0x100
+#define ISR_HOST_RRD_OV                                0x200
+#define ISR_DMAR_TO_RST                                0x400
+#define ISR_DMAW_TO_RST                                0x800
+#define ISR_GPHY                               0x1000
+#define ISR_RX_PKT                             0x10000
+#define ISR_TX_PKT                             0x20000
+#define ISR_TX_DMA                             0x40000
+#define ISR_RX_DMA                             0x80000
+#define ISR_CMB_RX                             0x100000
+#define ISR_CMB_TX                             0x200000
+#define ISR_MAC_RX                             0x400000
+#define ISR_MAC_TX                             0x800000
+#define ISR_DIS_SMB                            0x20000000
+#define ISR_DIS_DMA                            0x40000000
+
+/* Normal Interrupt mask  */
+#define IMR_NORMAL_MASK        (\
+       ISR_SMB         |\
+       ISR_GPHY        |\
+       ISR_PHY_LINKDOWN|\
+       ISR_DMAR_TO_RST |\
+       ISR_DMAW_TO_RST |\
+       ISR_CMB_TX      |\
+       ISR_CMB_RX)
+
+/* Debug Interrupt Mask  (enable all interrupt) */
+#define IMR_DEBUG_MASK (\
+       ISR_SMB         |\
+       ISR_TIMER       |\
+       ISR_MANUAL      |\
+       ISR_RXF_OV      |\
+       ISR_RFD_UNRUN   |\
+       ISR_RRD_OV      |\
+       ISR_TXF_UNRUN   |\
+       ISR_LINK        |\
+       ISR_CMB_TX      |\
+       ISR_CMB_RX      |\
+       ISR_RX_PKT      |\
+       ISR_TX_PKT      |\
+       ISR_MAC_RX      |\
+       ISR_MAC_TX)
+
+#define MEDIA_TYPE_1000M_FULL                  1
+#define MEDIA_TYPE_100M_FULL                   2
+#define MEDIA_TYPE_100M_HALF                   3
+#define MEDIA_TYPE_10M_FULL                    4
+#define MEDIA_TYPE_10M_HALF                    5
+
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT                0x002F  /* All but 1000-Half */
+
+#define MAX_JUMBO_FRAME_SIZE                   10240
+
+#define ATL1_EEDUMP_LEN                                48
+
+/* Statistics counters collected by the MAC */
+struct stats_msg_block {
+       /* rx */
+       u32 rx_ok;              /* good RX packets */
+       u32 rx_bcast;           /* good RX broadcast packets */
+       u32 rx_mcast;           /* good RX multicast packets */
+       u32 rx_pause;           /* RX pause frames */
+       u32 rx_ctrl;            /* RX control packets other than pause frames */
+       u32 rx_fcs_err;         /* RX packets with bad FCS */
+       u32 rx_len_err;         /* RX packets with length != actual size */
+       u32 rx_byte_cnt;        /* good bytes received. FCS is NOT included */
+       u32 rx_runt;            /* RX packets < 64 bytes with good FCS */
+       u32 rx_frag;            /* RX packets < 64 bytes with bad FCS */
+       u32 rx_sz_64;           /* 64 byte RX packets */
+       u32 rx_sz_65_127;
+       u32 rx_sz_128_255;
+       u32 rx_sz_256_511;
+       u32 rx_sz_512_1023;
+       u32 rx_sz_1024_1518;
+       u32 rx_sz_1519_max;     /* 1519 byte to MTU RX packets */
+       u32 rx_sz_ov;           /* truncated RX packets > MTU */
+       u32 rx_rxf_ov;          /* frames dropped due to RX FIFO overflow */
+       u32 rx_rrd_ov;          /* frames dropped due to RRD overflow */
+       u32 rx_align_err;       /* alignment errors */
+       u32 rx_bcast_byte_cnt;  /* RX broadcast bytes, excluding FCS */
+       u32 rx_mcast_byte_cnt;  /* RX multicast bytes, excluding FCS */
+       u32 rx_err_addr;        /* packets dropped due to address filtering */
+
+       /* tx */
+       u32 tx_ok;              /* good TX packets */
+       u32 tx_bcast;           /* good TX broadcast packets */
+       u32 tx_mcast;           /* good TX multicast packets */
+       u32 tx_pause;           /* TX pause frames */
+       u32 tx_exc_defer;       /* TX packets deferred excessively */
+       u32 tx_ctrl;            /* TX control frames, excluding pause frames */
+       u32 tx_defer;           /* TX packets deferred */
+       u32 tx_byte_cnt;        /* bytes transmitted, FCS is NOT included */
+       u32 tx_sz_64;           /* 64 byte TX packets */
+       u32 tx_sz_65_127;
+       u32 tx_sz_128_255;
+       u32 tx_sz_256_511;
+       u32 tx_sz_512_1023;
+       u32 tx_sz_1024_1518;
+       u32 tx_sz_1519_max;     /* 1519 byte to MTU TX packets */
+       u32 tx_1_col;           /* packets TX after a single collision */
+       u32 tx_2_col;           /* packets TX after multiple collisions */
+       u32 tx_late_col;        /* TX packets with late collisions */
+       u32 tx_abort_col;       /* TX packets aborted w/excessive collisions */
+       u32 tx_underrun;        /* TX packets aborted due to TX FIFO underrun
+                                * or TRD FIFO underrun */
+       u32 tx_rd_eop;          /* reads beyond the EOP into the next frame
+                                * when TRD was not written timely */
+       u32 tx_len_err;         /* TX packets where length != actual size */
+       u32 tx_trunc;           /* TX packets truncated due to size > MTU */
+       u32 tx_bcast_byte;      /* broadcast bytes transmitted, excluding FCS */
+       u32 tx_mcast_byte;      /* multicast bytes transmitted, excluding FCS */
+       u32 smb_updated;        /* 1: SMB Updated. This is used by software to
+                                * indicate the statistics update. Software
+                                * should clear this bit after retrieving the
+                                * statistics information. */
+};
+
+/* Coalescing Message Block */
+struct coals_msg_block {
+       u32 int_stats;          /* interrupt status */
+       u16 rrd_prod_idx;       /* TRD Producer Index. */
+       u16 rfd_cons_idx;       /* RFD Consumer Index. */
+       u16 update;             /* Selene sets this bit every time it DMAs the
+                                * CMB to host memory. Software should clear
+                                * this bit when CMB info is processed. */
+       u16 tpd_cons_idx;       /* TPD Consumer Index. */
+};
+
+/* RRD descriptor */
+struct rx_return_desc {
+       u8 num_buf;     /* Number of RFD buffers used by the received packet */
+       u8 resved;
+       u16 buf_indx;   /* RFD Index of the first buffer */
+       union {
+               u32 valid;
+               struct {
+                       u16 rx_chksum;
+                       u16 pkt_size;
+               } xsum_sz;
+       } xsz;
+
+       u16 pkt_flg;    /* Packet flags */
+       u16 err_flg;    /* Error flags */
+       u16 resved2;
+       u16 vlan_tag;   /* VLAN TAG */
+};
+
+#define PACKET_FLAG_ETH_TYPE   0x0080
+#define PACKET_FLAG_VLAN_INS   0x0100
+#define PACKET_FLAG_ERR                0x0200
+#define PACKET_FLAG_IPV4       0x0400
+#define PACKET_FLAG_UDP                0x0800
+#define PACKET_FLAG_TCP                0x1000
+#define PACKET_FLAG_BCAST      0x2000
+#define PACKET_FLAG_MCAST      0x4000
+#define PACKET_FLAG_PAUSE      0x8000
+
+#define ERR_FLAG_CRC           0x0001
+#define ERR_FLAG_CODE          0x0002
+#define ERR_FLAG_DRIBBLE       0x0004
+#define ERR_FLAG_RUNT          0x0008
+#define ERR_FLAG_OV            0x0010
+#define ERR_FLAG_TRUNC         0x0020
+#define ERR_FLAG_IP_CHKSUM     0x0040
+#define ERR_FLAG_L4_CHKSUM     0x0080
+#define ERR_FLAG_LEN           0x0100
+#define ERR_FLAG_DES_ADDR      0x0200
+
+/* RFD descriptor */
+struct rx_free_desc {
+       __le64 buffer_addr;     /* Address of the descriptor's data buffer */
+       __le16 buf_len;         /* Size of the receive buffer in host memory */
+       u16 coalese;            /* Update consumer index to host after the
+                                * reception of this frame */
+       /* __packed is required */
+} __packed;
+
+/*
+ * The L1 transmit packet descriptor is comprised of four 32-bit words.
+ *
+ *     31                                      0
+ *     +---------------------------------------+
+ *      |      Word 0: Buffer addr lo          |
+ *      +---------------------------------------+
+ *      |      Word 1: Buffer addr hi          |
+ *      +---------------------------------------+
+ *      |              Word 2                  |
+ *      +---------------------------------------+
+ *      |              Word 3                  |
+ *      +---------------------------------------+
+ *
+ * Words 0 and 1 combine to form a 64-bit buffer address.
+ *
+ * Word 2 is self explanatory in the #define block below.
+ *
+ * Word 3 has two forms, depending upon the state of bits 3 and 4.
+ * If bits 3 and 4 are both zero, then bits 14:31 are unused by the
+ * hardware.  Otherwise, if either bit 3 or 4 is set, the definition
+ * of bits 14:31 vary according to the following depiction.
+ *
+ *     0       End of packet                   0       End of packet
+ *     1       Coalesce                        1       Coalesce
+ *     2       Insert VLAN tag                 2       Insert VLAN tag
+ *     3       Custom csum enable = 0          3       Custom csum enable = 1
+ *     4       Segment enable = 1              4       Segment enable = 0
+ *     5       Generate IP checksum            5       Generate IP checksum
+ *     6       Generate TCP checksum           6       Generate TCP checksum
+ *     7       Generate UDP checksum           7       Generate UDP checksum
+ *     8       VLAN tagged                     8       VLAN tagged
+ *     9       Ethernet frame type             9       Ethernet frame type
+ *     10-+                                    10-+
+ *     11 |    IP hdr length (10:13)           11 |    IP hdr length (10:13)
+ *     12 |    (num 32-bit words)              12 |    (num 32-bit words)
+ *     13-+                                    13-+
+ *     14-+                                    14      Unused
+ *     15 |    TCP hdr length (14:17)          15      Unused
+ *     16 |    (num 32-bit words)              16-+
+ *     17-+                                    17 |
+ *     18      Header TPD flag                 18 |
+ *     19-+                                    19 |    Payload offset
+ *     20 |                                    20 |        (16:23)
+ *     21 |                                    21 |
+ *     22 |                                    22 |
+ *     23 |                                    23-+
+ *     24 |                                    24-+
+ *     25 |    MSS (19:31)                     25 |
+ *     26 |                                    26 |
+ *     27 |                                    27 |    Custom csum offset
+ *     28 |                                    28 |         (24:31)
+ *     29 |                                    29 |
+ *     30 |                                    30 |
+ *     31-+                                    31-+
+ */
+
+/* tpd word 2 */
+#define TPD_BUFLEN_MASK                0x3FFF
+#define TPD_BUFLEN_SHIFT       0
+#define TPD_DMAINT_MASK                0x0001
+#define TPD_DMAINT_SHIFT       14
+#define TPD_PKTNT_MASK         0x0001
+#define TPD_PKTINT_SHIFT       15
+#define TPD_VLANTAG_MASK       0xFFFF
+#define TPD_VLANTAG_SHIFT      16
+
+/* tpd word 3 bits 0:13 */
+#define TPD_EOP_MASK           0x0001
+#define TPD_EOP_SHIFT          0
+#define TPD_COALESCE_MASK      0x0001
+#define TPD_COALESCE_SHIFT     1
+#define TPD_INS_VL_TAG_MASK    0x0001
+#define TPD_INS_VL_TAG_SHIFT   2
+#define TPD_CUST_CSUM_EN_MASK  0x0001
+#define TPD_CUST_CSUM_EN_SHIFT 3
+#define TPD_SEGMENT_EN_MASK    0x0001
+#define TPD_SEGMENT_EN_SHIFT   4
+#define TPD_IP_CSUM_MASK       0x0001
+#define TPD_IP_CSUM_SHIFT      5
+#define TPD_TCP_CSUM_MASK      0x0001
+#define TPD_TCP_CSUM_SHIFT     6
+#define TPD_UDP_CSUM_MASK      0x0001
+#define TPD_UDP_CSUM_SHIFT     7
+#define TPD_VL_TAGGED_MASK     0x0001
+#define TPD_VL_TAGGED_SHIFT    8
+#define TPD_ETHTYPE_MASK       0x0001
+#define TPD_ETHTYPE_SHIFT      9
+#define TPD_IPHL_MASK          0x000F
+#define TPD_IPHL_SHIFT         10
+
+/* tpd word 3 bits 14:31 if segment enabled */
+#define TPD_TCPHDRLEN_MASK     0x000F
+#define TPD_TCPHDRLEN_SHIFT    14
+#define TPD_HDRFLAG_MASK       0x0001
+#define TPD_HDRFLAG_SHIFT      18
+#define TPD_MSS_MASK           0x1FFF
+#define TPD_MSS_SHIFT          19
+
+/* tpd word 3 bits 16:31 if custom csum enabled */
+#define TPD_PLOADOFFSET_MASK   0x00FF
+#define TPD_PLOADOFFSET_SHIFT  16
+#define TPD_CCSUMOFFSET_MASK   0x00FF
+#define TPD_CCSUMOFFSET_SHIFT  24
+
+struct tx_packet_desc {
+       __le64 buffer_addr;
+       __le32 word2;
+       __le32 word3;
+};
+
+/* DMA Order Settings */
+enum atl1_dma_order {
+       atl1_dma_ord_in = 1,
+       atl1_dma_ord_enh = 2,
+       atl1_dma_ord_out = 4
+};
+
+enum atl1_dma_rcb {
+       atl1_rcb_64 = 0,
+       atl1_rcb_128 = 1
+};
+
+enum atl1_dma_req_block {
+       atl1_dma_req_128 = 0,
+       atl1_dma_req_256 = 1,
+       atl1_dma_req_512 = 2,
+       atl1_dma_req_1024 = 3,
+       atl1_dma_req_2048 = 4,
+       atl1_dma_req_4096 = 5
+};
+
+#define ATL1_MAX_INTR          3
+#define ATL1_MAX_TX_BUF_LEN    0x3000  /* 12288 bytes */
+
+#define ATL1_DEFAULT_TPD       256
+#define ATL1_MAX_TPD           1024
+#define ATL1_MIN_TPD           64
+#define ATL1_DEFAULT_RFD       512
+#define ATL1_MIN_RFD           128
+#define ATL1_MAX_RFD           2048
+#define ATL1_REG_COUNT         1538
+
+#define ATL1_GET_DESC(R, i, type)      (&(((type *)((R)->desc))[i]))
+#define ATL1_RFD_DESC(R, i)    ATL1_GET_DESC(R, i, struct rx_free_desc)
+#define ATL1_TPD_DESC(R, i)    ATL1_GET_DESC(R, i, struct tx_packet_desc)
+#define ATL1_RRD_DESC(R, i)    ATL1_GET_DESC(R, i, struct rx_return_desc)
+
+/*
+ * atl1_ring_header represents a single, contiguous block of DMA space
+ * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
+ * message blocks (cmb, smb) described below
+ */
+struct atl1_ring_header {
+       void *desc;             /* virtual address */
+       dma_addr_t dma;         /* physical address*/
+       unsigned int size;      /* length in bytes */
+};
+
+/*
+ * atl1_buffer is wrapper around a pointer to a socket buffer
+ * so a DMA handle can be stored along with the skb
+ */
+struct atl1_buffer {
+       struct sk_buff *skb;    /* socket buffer */
+       u16 length;             /* rx buffer length */
+       u16 alloced;            /* 1 if skb allocated */
+       dma_addr_t dma;
+};
+
+/* transmit packet descriptor (tpd) ring */
+struct atl1_tpd_ring {
+       void *desc;             /* descriptor ring virtual address */
+       dma_addr_t dma;         /* descriptor ring physical address */
+       u16 size;               /* descriptor ring length in bytes */
+       u16 count;              /* number of descriptors in the ring */
+       u16 hw_idx;             /* hardware index */
+       atomic_t next_to_clean;
+       atomic_t next_to_use;
+       struct atl1_buffer *buffer_info;
+};
+
+/* receive free descriptor (rfd) ring */
+struct atl1_rfd_ring {
+       void *desc;             /* descriptor ring virtual address */
+       dma_addr_t dma;         /* descriptor ring physical address */
+       u16 size;               /* descriptor ring length in bytes */
+       u16 count;              /* number of descriptors in the ring */
+       atomic_t next_to_use;
+       u16 next_to_clean;
+       struct atl1_buffer *buffer_info;
+};
+
+/* receive return descriptor (rrd) ring */
+struct atl1_rrd_ring {
+       void *desc;             /* descriptor ring virtual address */
+       dma_addr_t dma;         /* descriptor ring physical address */
+       unsigned int size;      /* descriptor ring length in bytes */
+       u16 count;              /* number of descriptors in the ring */
+       u16 next_to_use;
+       atomic_t next_to_clean;
+};
+
+/* coalescing message block (cmb) */
+struct atl1_cmb {
+       struct coals_msg_block *cmb;
+       dma_addr_t dma;
+};
+
+/* statistics message block (smb) */
+struct atl1_smb {
+       struct stats_msg_block *smb;
+       dma_addr_t dma;
+};
+
+/* Statistics counters */
+struct atl1_sft_stats {
+       u64 rx_packets;
+       u64 tx_packets;
+       u64 rx_bytes;
+       u64 tx_bytes;
+       u64 multicast;
+       u64 collisions;
+       u64 rx_errors;
+       u64 rx_length_errors;
+       u64 rx_crc_errors;
+       u64 rx_frame_errors;
+       u64 rx_fifo_errors;
+       u64 rx_missed_errors;
+       u64 tx_errors;
+       u64 tx_fifo_errors;
+       u64 tx_aborted_errors;
+       u64 tx_window_errors;
+       u64 tx_carrier_errors;
+       u64 tx_pause;           /* TX pause frames */
+       u64 excecol;            /* TX packets w/ excessive collisions */
+       u64 deffer;             /* TX packets deferred */
+       u64 scc;                /* packets TX after a single collision */
+       u64 mcc;                /* packets TX after multiple collisions */
+       u64 latecol;            /* TX packets w/ late collisions */
+       u64 tx_underun;         /* TX packets aborted due to TX FIFO underrun
+                                * or TRD FIFO underrun */
+       u64 tx_trunc;           /* TX packets truncated due to size > MTU */
+       u64 rx_pause;           /* num Pause packets received. */
+       u64 rx_rrd_ov;
+       u64 rx_trunc;
+};
+
+/* hardware structure */
+struct atl1_hw {
+       u8 __iomem *hw_addr;
+       struct atl1_adapter *back;
+       enum atl1_dma_order dma_ord;
+       enum atl1_dma_rcb rcb_value;
+       enum atl1_dma_req_block dmar_block;
+       enum atl1_dma_req_block dmaw_block;
+       u8 preamble_len;
+       u8 max_retry;
+       u8 jam_ipg;             /* IPG to start JAM for collision based flow
+                                * control in half-duplex mode. In units of
+                                * 8-bit time */
+       u8 ipgt;                /* Desired back to back inter-packet gap.
+                                * The default is 96-bit time */
+       u8 min_ifg;             /* Minimum number of IFG to enforce in between
+                                * receive frames. Frame gap below such IFP
+                                * is dropped */
+       u8 ipgr1;               /* 64bit Carrier-Sense window */
+       u8 ipgr2;               /* 96-bit IPG window */
+       u8 tpd_burst;           /* Number of TPD to prefetch in cache-aligned
+                                * burst. Each TPD is 16 bytes long */
+       u8 rfd_burst;           /* Number of RFD to prefetch in cache-aligned
+                                * burst. Each RFD is 12 bytes long */
+       u8 rfd_fetch_gap;
+       u8 rrd_burst;           /* Threshold number of RRDs that can be retired
+                                * in a burst. Each RRD is 16 bytes long */
+       u8 tpd_fetch_th;
+       u8 tpd_fetch_gap;
+       u16 tx_jumbo_task_th;
+       u16 txf_burst;          /* Number of data bytes to read in a cache-
+                                * aligned burst. Each SRAM entry is 8 bytes */
+       u16 rx_jumbo_th;        /* Jumbo packet size for non-VLAN packet. VLAN
+                                * packets should add 4 bytes */
+       u16 rx_jumbo_lkah;
+       u16 rrd_ret_timer;      /* RRD retirement timer. Decrement by 1 after
+                                * every 512ns passes. */
+       u16 lcol;               /* Collision Window */
+
+       u16 cmb_tpd;
+       u16 cmb_rrd;
+       u16 cmb_rx_timer;
+       u16 cmb_tx_timer;
+       u32 smb_timer;
+       u16 media_type;
+       u16 autoneg_advertised;
+
+       u16 mii_autoneg_adv_reg;
+       u16 mii_1000t_ctrl_reg;
+
+       u32 max_frame_size;
+       u32 min_frame_size;
+
+       u16 dev_rev;
+
+       /* spi flash */
+       u8 flash_vendor;
+
+       u8 mac_addr[ETH_ALEN];
+       u8 perm_mac_addr[ETH_ALEN];
+
+       bool phy_configured;
+};
+
+struct atl1_adapter {
+       struct net_device *netdev;
+       struct pci_dev *pdev;
+
+       struct atl1_sft_stats soft_stats;
+       u32 rx_buffer_len;
+       u32 wol;
+       u16 link_speed;
+       u16 link_duplex;
+       spinlock_t lock;
+       struct work_struct tx_timeout_task;
+       struct work_struct link_chg_task;
+       struct work_struct pcie_dma_to_rst_task;
+
+       struct timer_list phy_config_timer;
+       bool phy_timer_pending;
+
+       /* all descriptor rings' memory */
+       struct atl1_ring_header ring_header;
+
+       /* TX */
+       struct atl1_tpd_ring tpd_ring;
+       spinlock_t mb_lock;
+
+       /* RX */
+       struct atl1_rfd_ring rfd_ring;
+       struct atl1_rrd_ring rrd_ring;
+       u64 hw_csum_err;
+       u64 hw_csum_good;
+       u32 msg_enable;
+       u16 imt;                /* interrupt moderator timer (2us resolution) */
+       u16 ict;                /* interrupt clear timer (2us resolution */
+       struct mii_if_info mii; /* MII interface info */
+
+       u32 bd_number;          /* board number */
+       bool pci_using_64;
+       struct atl1_hw hw;
+       struct atl1_smb smb;
+       struct atl1_cmb cmb;
+};
+
+#endif /* ATL1_H */
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
new file mode 100644 (file)
index 0000000..d4f7dda
--- /dev/null
@@ -0,0 +1,3119 @@
+/*
+ * Copyright(c) 2006 - 2007 Atheros Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2008 Chris Snook <csnook@redhat.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#include <linux/atomic.h>
+#include <linux/crc32.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/hardirq.h>
+#include <linux/if_vlan.h>
+#include <linux/in.h>
+#include <linux/interrupt.h>
+#include <linux/ip.h>
+#include <linux/irqflags.h>
+#include <linux/irqreturn.h>
+#include <linux/mii.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/pm.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/tcp.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "atl2.h"
+
+#define ATL2_DRV_VERSION "2.2.3"
+
+static const char atl2_driver_name[] = "atl2";
+static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver";
+static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation.";
+static const char atl2_driver_version[] = ATL2_DRV_VERSION;
+
+MODULE_AUTHOR("Atheros Corporation <xiong.huang@atheros.com>, Chris Snook <csnook@redhat.com>");
+MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATL2_DRV_VERSION);
+
+/*
+ * atl2_pci_tbl - PCI Device ID Table
+ */
+static DEFINE_PCI_DEVICE_TABLE(atl2_pci_tbl) = {
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2)},
+       /* required last entry */
+       {0,}
+};
+MODULE_DEVICE_TABLE(pci, atl2_pci_tbl);
+
+static void atl2_set_ethtool_ops(struct net_device *netdev);
+
+static void atl2_check_options(struct atl2_adapter *adapter);
+
+/*
+ * atl2_sw_init - Initialize general software structures (struct atl2_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl2_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 __devinit atl2_sw_init(struct atl2_adapter *adapter)
+{
+       struct atl2_hw *hw = &adapter->hw;
+       struct pci_dev *pdev = adapter->pdev;
+
+       /* PCI config space info */
+       hw->vendor_id = pdev->vendor;
+       hw->device_id = pdev->device;
+       hw->subsystem_vendor_id = pdev->subsystem_vendor;
+       hw->subsystem_id = pdev->subsystem_device;
+       hw->revision_id  = pdev->revision;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+       adapter->wol = 0;
+       adapter->ict = 50000;  /* ~100ms */
+       adapter->link_speed = SPEED_0;   /* hardware init */
+       adapter->link_duplex = FULL_DUPLEX;
+
+       hw->phy_configured = false;
+       hw->preamble_len = 7;
+       hw->ipgt = 0x60;
+       hw->min_ifg = 0x50;
+       hw->ipgr1 = 0x40;
+       hw->ipgr2 = 0x60;
+       hw->retry_buf = 2;
+       hw->max_retry = 0xf;
+       hw->lcol = 0x37;
+       hw->jam_ipg = 7;
+       hw->fc_rxd_hi = 0;
+       hw->fc_rxd_lo = 0;
+       hw->max_frame_size = adapter->netdev->mtu;
+
+       spin_lock_init(&adapter->stats_lock);
+
+       set_bit(__ATL2_DOWN, &adapter->flags);
+
+       return 0;
+}
+
+/*
+ * atl2_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 atl2_set_multi(struct net_device *netdev)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+       struct netdev_hw_addr *ha;
+       u32 rctl;
+       u32 hash_value;
+
+       /* Check for Promiscuous and All Multicast modes */
+       rctl = ATL2_READ_REG(hw, 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);
+
+       ATL2_WRITE_REG(hw, REG_MAC_CTRL, rctl);
+
+       /* clear the old settings from the multicast hash table */
+       ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+       ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+       /* comoute mc addresses' hash value ,and put it into hash table */
+       netdev_for_each_mc_addr(ha, netdev) {
+               hash_value = atl2_hash_mc_addr(hw, ha->addr);
+               atl2_hash_set(hw, hash_value);
+       }
+}
+
+static void init_ring_ptrs(struct atl2_adapter *adapter)
+{
+       /* Read / Write Ptr Initialize: */
+       adapter->txd_write_ptr = 0;
+       atomic_set(&adapter->txd_read_ptr, 0);
+
+       adapter->rxd_read_ptr = 0;
+       adapter->rxd_write_ptr = 0;
+
+       atomic_set(&adapter->txs_write_ptr, 0);
+       adapter->txs_next_clear = 0;
+}
+
+/*
+ * atl2_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl2_configure(struct atl2_adapter *adapter)
+{
+       struct atl2_hw *hw = &adapter->hw;
+       u32 value;
+
+       /* clear interrupt status */
+       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0xffffffff);
+
+       /* set MAC Address */
+       value = (((u32)hw->mac_addr[2]) << 24) |
+               (((u32)hw->mac_addr[3]) << 16) |
+               (((u32)hw->mac_addr[4]) << 8) |
+               (((u32)hw->mac_addr[5]));
+       ATL2_WRITE_REG(hw, REG_MAC_STA_ADDR, value);
+       value = (((u32)hw->mac_addr[0]) << 8) |
+               (((u32)hw->mac_addr[1]));
+       ATL2_WRITE_REG(hw, (REG_MAC_STA_ADDR+4), value);
+
+       /* HI base address */
+       ATL2_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI,
+               (u32)((adapter->ring_dma & 0xffffffff00000000ULL) >> 32));
+
+       /* LO base address */
+       ATL2_WRITE_REG(hw, REG_TXD_BASE_ADDR_LO,
+               (u32)(adapter->txd_dma & 0x00000000ffffffffULL));
+       ATL2_WRITE_REG(hw, REG_TXS_BASE_ADDR_LO,
+               (u32)(adapter->txs_dma & 0x00000000ffffffffULL));
+       ATL2_WRITE_REG(hw, REG_RXD_BASE_ADDR_LO,
+               (u32)(adapter->rxd_dma & 0x00000000ffffffffULL));
+
+       /* element count */
+       ATL2_WRITE_REGW(hw, REG_TXD_MEM_SIZE, (u16)(adapter->txd_ring_size/4));
+       ATL2_WRITE_REGW(hw, REG_TXS_MEM_SIZE, (u16)adapter->txs_ring_size);
+       ATL2_WRITE_REGW(hw, REG_RXD_BUF_NUM,  (u16)adapter->rxd_ring_size);
+
+       /* config Internal SRAM */
+/*
+    ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_tx_end);
+    ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_rx_end);
+*/
+
+       /* config IPG/IFG */
+       value = (((u32)hw->ipgt & MAC_IPG_IFG_IPGT_MASK) <<
+               MAC_IPG_IFG_IPGT_SHIFT) |
+               (((u32)hw->min_ifg & MAC_IPG_IFG_MIFG_MASK) <<
+               MAC_IPG_IFG_MIFG_SHIFT) |
+               (((u32)hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK) <<
+               MAC_IPG_IFG_IPGR1_SHIFT)|
+               (((u32)hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK) <<
+               MAC_IPG_IFG_IPGR2_SHIFT);
+       ATL2_WRITE_REG(hw, REG_MAC_IPG_IFG, value);
+
+       /* config  Half-Duplex Control */
+       value = ((u32)hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) |
+               (((u32)hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK) <<
+               MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) |
+               MAC_HALF_DUPLX_CTRL_EXC_DEF_EN |
+               (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) |
+               (((u32)hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) <<
+               MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT);
+       ATL2_WRITE_REG(hw, REG_MAC_HALF_DUPLX_CTRL, value);
+
+       /* set Interrupt Moderator Timer */
+       ATL2_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, adapter->imt);
+       ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_ITIMER_EN);
+
+       /* set Interrupt Clear Timer */
+       ATL2_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, adapter->ict);
+
+       /* set MTU */
+       ATL2_WRITE_REG(hw, REG_MTU, adapter->netdev->mtu +
+               ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE);
+
+       /* 1590 */
+       ATL2_WRITE_REG(hw, REG_TX_CUT_THRESH, 0x177);
+
+       /* flow control */
+       ATL2_WRITE_REGW(hw, REG_PAUSE_ON_TH, hw->fc_rxd_hi);
+       ATL2_WRITE_REGW(hw, REG_PAUSE_OFF_TH, hw->fc_rxd_lo);
+
+       /* Init mailbox */
+       ATL2_WRITE_REGW(hw, REG_MB_TXD_WR_IDX, (u16)adapter->txd_write_ptr);
+       ATL2_WRITE_REGW(hw, REG_MB_RXD_RD_IDX, (u16)adapter->rxd_read_ptr);
+
+       /* enable DMA read/write */
+       ATL2_WRITE_REGB(hw, REG_DMAR, DMAR_EN);
+       ATL2_WRITE_REGB(hw, REG_DMAW, DMAW_EN);
+
+       value = ATL2_READ_REG(&adapter->hw, REG_ISR);
+       if ((value & ISR_PHY_LINKDOWN) != 0)
+               value = 1; /* config failed */
+       else
+               value = 0;
+
+       /* clear all interrupt status */
+       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0x3fffffff);
+       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0);
+       return value;
+}
+
+/*
+ * atl2_setup_ring_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static s32 atl2_setup_ring_resources(struct atl2_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       int size;
+       u8 offset = 0;
+
+       /* real ring DMA buffer */
+       adapter->ring_size = size =
+               adapter->txd_ring_size * 1 + 7 +        /* dword align */
+               adapter->txs_ring_size * 4 + 7 +        /* dword align */
+               adapter->rxd_ring_size * 1536 + 127;    /* 128bytes align */
+
+       adapter->ring_vir_addr = pci_alloc_consistent(pdev, size,
+               &adapter->ring_dma);
+       if (!adapter->ring_vir_addr)
+               return -ENOMEM;
+       memset(adapter->ring_vir_addr, 0, adapter->ring_size);
+
+       /* Init TXD Ring */
+       adapter->txd_dma = adapter->ring_dma ;
+       offset = (adapter->txd_dma & 0x7) ? (8 - (adapter->txd_dma & 0x7)) : 0;
+       adapter->txd_dma += offset;
+       adapter->txd_ring = adapter->ring_vir_addr + offset;
+
+       /* Init TXS Ring */
+       adapter->txs_dma = adapter->txd_dma + adapter->txd_ring_size;
+       offset = (adapter->txs_dma & 0x7) ? (8 - (adapter->txs_dma & 0x7)) : 0;
+       adapter->txs_dma += offset;
+       adapter->txs_ring = (struct tx_pkt_status *)
+               (((u8 *)adapter->txd_ring) + (adapter->txd_ring_size + offset));
+
+       /* Init RXD Ring */
+       adapter->rxd_dma = adapter->txs_dma + adapter->txs_ring_size * 4;
+       offset = (adapter->rxd_dma & 127) ?
+               (128 - (adapter->rxd_dma & 127)) : 0;
+       if (offset > 7)
+               offset -= 8;
+       else
+               offset += (128 - 8);
+
+       adapter->rxd_dma += offset;
+       adapter->rxd_ring = (struct rx_desc *) (((u8 *)adapter->txs_ring) +
+               (adapter->txs_ring_size * 4 + offset));
+
+/*
+ * Read / Write Ptr Initialize:
+ *      init_ring_ptrs(adapter);
+ */
+       return 0;
+}
+
+/*
+ * atl2_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl2_irq_enable(struct atl2_adapter *adapter)
+{
+       ATL2_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK);
+       ATL2_WRITE_FLUSH(&adapter->hw);
+}
+
+/*
+ * atl2_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl2_irq_disable(struct atl2_adapter *adapter)
+{
+    ATL2_WRITE_REG(&adapter->hw, REG_IMR, 0);
+    ATL2_WRITE_FLUSH(&adapter->hw);
+    synchronize_irq(adapter->pdev->irq);
+}
+
+static void __atl2_vlan_mode(u32 features, u32 *ctrl)
+{
+       if (features & NETIF_F_HW_VLAN_RX) {
+               /* enable VLAN tag insert/strip */
+               *ctrl |= MAC_CTRL_RMV_VLAN;
+       } else {
+               /* disable VLAN tag insert/strip */
+               *ctrl &= ~MAC_CTRL_RMV_VLAN;
+       }
+}
+
+static void atl2_vlan_mode(struct net_device *netdev, u32 features)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       u32 ctrl;
+
+       atl2_irq_disable(adapter);
+
+       ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL);
+       __atl2_vlan_mode(features, &ctrl);
+       ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl);
+
+       atl2_irq_enable(adapter);
+}
+
+static void atl2_restore_vlan(struct atl2_adapter *adapter)
+{
+       atl2_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+static u32 atl2_fix_features(struct net_device *netdev, u32 features)
+{
+       /*
+        * Since there is no support for separate rx/tx vlan accel
+        * enable/disable make sure tx flag is always in same state as rx.
+        */
+       if (features & NETIF_F_HW_VLAN_RX)
+               features |= NETIF_F_HW_VLAN_TX;
+       else
+               features &= ~NETIF_F_HW_VLAN_TX;
+
+       return features;
+}
+
+static int atl2_set_features(struct net_device *netdev, u32 features)
+{
+       u32 changed = netdev->features ^ features;
+
+       if (changed & NETIF_F_HW_VLAN_RX)
+               atl2_vlan_mode(netdev, features);
+
+       return 0;
+}
+
+static void atl2_intr_rx(struct atl2_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct rx_desc *rxd;
+       struct sk_buff *skb;
+
+       do {
+               rxd = adapter->rxd_ring+adapter->rxd_write_ptr;
+               if (!rxd->status.update)
+                       break; /* end of tx */
+
+               /* clear this flag at once */
+               rxd->status.update = 0;
+
+               if (rxd->status.ok && rxd->status.pkt_size >= 60) {
+                       int rx_size = (int)(rxd->status.pkt_size - 4);
+                       /* alloc new buffer */
+                       skb = netdev_alloc_skb_ip_align(netdev, rx_size);
+                       if (NULL == skb) {
+                               printk(KERN_WARNING
+                                       "%s: Mem squeeze, deferring packet.\n",
+                                       netdev->name);
+                               /*
+                                * Check that some rx space is free. If not,
+                                * free one and mark stats->rx_dropped++.
+                                */
+                               netdev->stats.rx_dropped++;
+                               break;
+                       }
+                       memcpy(skb->data, rxd->packet, rx_size);
+                       skb_put(skb, rx_size);
+                       skb->protocol = eth_type_trans(skb, netdev);
+                       if (rxd->status.vlan) {
+                               u16 vlan_tag = (rxd->status.vtag>>4) |
+                                       ((rxd->status.vtag&7) << 13) |
+                                       ((rxd->status.vtag&8) << 9);
+
+                               __vlan_hwaccel_put_tag(skb, vlan_tag);
+                       }
+                       netif_rx(skb);
+                       netdev->stats.rx_bytes += rx_size;
+                       netdev->stats.rx_packets++;
+               } else {
+                       netdev->stats.rx_errors++;
+
+                       if (rxd->status.ok && rxd->status.pkt_size <= 60)
+                               netdev->stats.rx_length_errors++;
+                       if (rxd->status.mcast)
+                               netdev->stats.multicast++;
+                       if (rxd->status.crc)
+                               netdev->stats.rx_crc_errors++;
+                       if (rxd->status.align)
+                               netdev->stats.rx_frame_errors++;
+               }
+
+               /* advance write ptr */
+               if (++adapter->rxd_write_ptr == adapter->rxd_ring_size)
+                       adapter->rxd_write_ptr = 0;
+       } while (1);
+
+       /* update mailbox? */
+       adapter->rxd_read_ptr = adapter->rxd_write_ptr;
+       ATL2_WRITE_REGW(&adapter->hw, REG_MB_RXD_RD_IDX, adapter->rxd_read_ptr);
+}
+
+static void atl2_intr_tx(struct atl2_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       u32 txd_read_ptr;
+       u32 txs_write_ptr;
+       struct tx_pkt_status *txs;
+       struct tx_pkt_header *txph;
+       int free_hole = 0;
+
+       do {
+               txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr);
+               txs = adapter->txs_ring + txs_write_ptr;
+               if (!txs->update)
+                       break; /* tx stop here */
+
+               free_hole = 1;
+               txs->update = 0;
+
+               if (++txs_write_ptr == adapter->txs_ring_size)
+                       txs_write_ptr = 0;
+               atomic_set(&adapter->txs_write_ptr, (int)txs_write_ptr);
+
+               txd_read_ptr = (u32) atomic_read(&adapter->txd_read_ptr);
+               txph = (struct tx_pkt_header *)
+                       (((u8 *)adapter->txd_ring) + txd_read_ptr);
+
+               if (txph->pkt_size != txs->pkt_size) {
+                       struct tx_pkt_status *old_txs = txs;
+                       printk(KERN_WARNING
+                               "%s: txs packet size not consistent with txd"
+                               " txd_:0x%08x, txs_:0x%08x!\n",
+                               adapter->netdev->name,
+                               *(u32 *)txph, *(u32 *)txs);
+                       printk(KERN_WARNING
+                               "txd read ptr: 0x%x\n",
+                               txd_read_ptr);
+                       txs = adapter->txs_ring + txs_write_ptr;
+                       printk(KERN_WARNING
+                               "txs-behind:0x%08x\n",
+                               *(u32 *)txs);
+                       if (txs_write_ptr < 2) {
+                               txs = adapter->txs_ring +
+                                       (adapter->txs_ring_size +
+                                       txs_write_ptr - 2);
+                       } else {
+                               txs = adapter->txs_ring + (txs_write_ptr - 2);
+                       }
+                       printk(KERN_WARNING
+                               "txs-before:0x%08x\n",
+                               *(u32 *)txs);
+                       txs = old_txs;
+               }
+
+                /* 4for TPH */
+               txd_read_ptr += (((u32)(txph->pkt_size) + 7) & ~3);
+               if (txd_read_ptr >= adapter->txd_ring_size)
+                       txd_read_ptr -= adapter->txd_ring_size;
+
+               atomic_set(&adapter->txd_read_ptr, (int)txd_read_ptr);
+
+               /* tx statistics: */
+               if (txs->ok) {
+                       netdev->stats.tx_bytes += txs->pkt_size;
+                       netdev->stats.tx_packets++;
+               }
+               else
+                       netdev->stats.tx_errors++;
+
+               if (txs->defer)
+                       netdev->stats.collisions++;
+               if (txs->abort_col)
+                       netdev->stats.tx_aborted_errors++;
+               if (txs->late_col)
+                       netdev->stats.tx_window_errors++;
+               if (txs->underun)
+                       netdev->stats.tx_fifo_errors++;
+       } while (1);
+
+       if (free_hole) {
+               if (netif_queue_stopped(adapter->netdev) &&
+                       netif_carrier_ok(adapter->netdev))
+                       netif_wake_queue(adapter->netdev);
+       }
+}
+
+static void atl2_check_for_link(struct atl2_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       u16 phy_data = 0;
+
+       spin_lock(&adapter->stats_lock);
+       atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       spin_unlock(&adapter->stats_lock);
+
+       /* notify upper layer link down ASAP */
+       if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */
+               if (netif_carrier_ok(netdev)) { /* old link state: Up */
+               printk(KERN_INFO "%s: %s NIC Link is Down\n",
+                       atl2_driver_name, netdev->name);
+               adapter->link_speed = SPEED_0;
+               netif_carrier_off(netdev);
+               netif_stop_queue(netdev);
+               }
+       }
+       schedule_work(&adapter->link_chg_task);
+}
+
+static inline void atl2_clear_phy_int(struct atl2_adapter *adapter)
+{
+       u16 phy_data;
+       spin_lock(&adapter->stats_lock);
+       atl2_read_phy_reg(&adapter->hw, 19, &phy_data);
+       spin_unlock(&adapter->stats_lock);
+}
+
+/*
+ * atl2_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ */
+static irqreturn_t atl2_intr(int irq, void *data)
+{
+       struct atl2_adapter *adapter = netdev_priv(data);
+       struct atl2_hw *hw = &adapter->hw;
+       u32 status;
+
+       status = ATL2_READ_REG(hw, REG_ISR);
+       if (0 == status)
+               return IRQ_NONE;
+
+       /* link event */
+       if (status & ISR_PHY)
+               atl2_clear_phy_int(adapter);
+
+       /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
+       ATL2_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+
+       /* check if PCIE PHY Link down */
+       if (status & ISR_PHY_LINKDOWN) {
+               if (netif_running(adapter->netdev)) { /* reset MAC */
+                       ATL2_WRITE_REG(hw, REG_ISR, 0);
+                       ATL2_WRITE_REG(hw, REG_IMR, 0);
+                       ATL2_WRITE_FLUSH(hw);
+                       schedule_work(&adapter->reset_task);
+                       return IRQ_HANDLED;
+               }
+       }
+
+       /* check if DMA read/write error? */
+       if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+               ATL2_WRITE_REG(hw, REG_ISR, 0);
+               ATL2_WRITE_REG(hw, REG_IMR, 0);
+               ATL2_WRITE_FLUSH(hw);
+               schedule_work(&adapter->reset_task);
+               return IRQ_HANDLED;
+       }
+
+       /* link event */
+       if (status & (ISR_PHY | ISR_MANUAL)) {
+               adapter->netdev->stats.tx_carrier_errors++;
+               atl2_check_for_link(adapter);
+       }
+
+       /* transmit event */
+       if (status & ISR_TX_EVENT)
+               atl2_intr_tx(adapter);
+
+       /* rx exception */
+       if (status & ISR_RX_EVENT)
+               atl2_intr_rx(adapter);
+
+       /* re-enable Interrupt */
+       ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0);
+       return IRQ_HANDLED;
+}
+
+static int atl2_request_irq(struct atl2_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int flags, err = 0;
+
+       flags = IRQF_SHARED;
+       adapter->have_msi = true;
+       err = pci_enable_msi(adapter->pdev);
+       if (err)
+               adapter->have_msi = false;
+
+       if (adapter->have_msi)
+               flags &= ~IRQF_SHARED;
+
+       return request_irq(adapter->pdev->irq, atl2_intr, flags, netdev->name,
+               netdev);
+}
+
+/*
+ * atl2_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl2_free_ring_resources(struct atl2_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr,
+               adapter->ring_dma);
+}
+
+/*
+ * atl2_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * 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 atl2_open(struct net_device *netdev)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       int err;
+       u32 val;
+
+       /* disallow open during test */
+       if (test_bit(__ATL2_TESTING, &adapter->flags))
+               return -EBUSY;
+
+       /* allocate transmit descriptors */
+       err = atl2_setup_ring_resources(adapter);
+       if (err)
+               return err;
+
+       err = atl2_init_hw(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               goto err_init_hw;
+       }
+
+       /* hardware has been reset, we need to reload some things */
+       atl2_set_multi(netdev);
+       init_ring_ptrs(adapter);
+
+       atl2_restore_vlan(adapter);
+
+       if (atl2_configure(adapter)) {
+               err = -EIO;
+               goto err_config;
+       }
+
+       err = atl2_request_irq(adapter);
+       if (err)
+               goto err_req_irq;
+
+       clear_bit(__ATL2_DOWN, &adapter->flags);
+
+       mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 4*HZ));
+
+       val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL);
+       ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
+               val | MASTER_CTRL_MANUAL_INT);
+
+       atl2_irq_enable(adapter);
+
+       return 0;
+
+err_init_hw:
+err_req_irq:
+err_config:
+       atl2_free_ring_resources(adapter);
+       atl2_reset_hw(&adapter->hw);
+
+       return err;
+}
+
+static void atl2_down(struct atl2_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       /* signal that we're down so the interrupt handler does not
+        * reschedule our watchdog timer */
+       set_bit(__ATL2_DOWN, &adapter->flags);
+
+       netif_tx_disable(netdev);
+
+       /* reset MAC to disable all RX/TX */
+       atl2_reset_hw(&adapter->hw);
+       msleep(1);
+
+       atl2_irq_disable(adapter);
+
+       del_timer_sync(&adapter->watchdog_timer);
+       del_timer_sync(&adapter->phy_config_timer);
+       clear_bit(0, &adapter->cfg_phy);
+
+       netif_carrier_off(netdev);
+       adapter->link_speed = SPEED_0;
+       adapter->link_duplex = -1;
+}
+
+static void atl2_free_irq(struct atl2_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       free_irq(adapter->pdev->irq, netdev);
+
+#ifdef CONFIG_PCI_MSI
+       if (adapter->have_msi)
+               pci_disable_msi(adapter->pdev);
+#endif
+}
+
+/*
+ * atl2_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * 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 atl2_close(struct net_device *netdev)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+
+       WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags));
+
+       atl2_down(adapter);
+       atl2_free_irq(adapter);
+       atl2_free_ring_resources(adapter);
+
+       return 0;
+}
+
+static inline int TxsFreeUnit(struct atl2_adapter *adapter)
+{
+       u32 txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr);
+
+       return (adapter->txs_next_clear >= txs_write_ptr) ?
+               (int) (adapter->txs_ring_size - adapter->txs_next_clear +
+               txs_write_ptr - 1) :
+               (int) (txs_write_ptr - adapter->txs_next_clear - 1);
+}
+
+static inline int TxdFreeBytes(struct atl2_adapter *adapter)
+{
+       u32 txd_read_ptr = (u32)atomic_read(&adapter->txd_read_ptr);
+
+       return (adapter->txd_write_ptr >= txd_read_ptr) ?
+               (int) (adapter->txd_ring_size - adapter->txd_write_ptr +
+               txd_read_ptr - 1) :
+               (int) (txd_read_ptr - adapter->txd_write_ptr - 1);
+}
+
+static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
+                                        struct net_device *netdev)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct tx_pkt_header *txph;
+       u32 offset, copy_len;
+       int txs_unused;
+       int txbuf_unused;
+
+       if (test_bit(__ATL2_DOWN, &adapter->flags)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       if (unlikely(skb->len <= 0)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       txs_unused = TxsFreeUnit(adapter);
+       txbuf_unused = TxdFreeBytes(adapter);
+
+       if (skb->len + sizeof(struct tx_pkt_header) + 4  > txbuf_unused ||
+               txs_unused < 1) {
+               /* not enough resources */
+               netif_stop_queue(netdev);
+               return NETDEV_TX_BUSY;
+       }
+
+       offset = adapter->txd_write_ptr;
+
+       txph = (struct tx_pkt_header *) (((u8 *)adapter->txd_ring) + offset);
+
+       *(u32 *)txph = 0;
+       txph->pkt_size = skb->len;
+
+       offset += 4;
+       if (offset >= adapter->txd_ring_size)
+               offset -= adapter->txd_ring_size;
+       copy_len = adapter->txd_ring_size - offset;
+       if (copy_len >= skb->len) {
+               memcpy(((u8 *)adapter->txd_ring) + offset, skb->data, skb->len);
+               offset += ((u32)(skb->len + 3) & ~3);
+       } else {
+               memcpy(((u8 *)adapter->txd_ring)+offset, skb->data, copy_len);
+               memcpy((u8 *)adapter->txd_ring, skb->data+copy_len,
+                       skb->len-copy_len);
+               offset = ((u32)(skb->len-copy_len + 3) & ~3);
+       }
+#ifdef NETIF_F_HW_VLAN_TX
+       if (vlan_tx_tag_present(skb)) {
+               u16 vlan_tag = vlan_tx_tag_get(skb);
+               vlan_tag = (vlan_tag << 4) |
+                       (vlan_tag >> 13) |
+                       ((vlan_tag >> 9) & 0x8);
+               txph->ins_vlan = 1;
+               txph->vlan = vlan_tag;
+       }
+#endif
+       if (offset >= adapter->txd_ring_size)
+               offset -= adapter->txd_ring_size;
+       adapter->txd_write_ptr = offset;
+
+       /* clear txs before send */
+       adapter->txs_ring[adapter->txs_next_clear].update = 0;
+       if (++adapter->txs_next_clear == adapter->txs_ring_size)
+               adapter->txs_next_clear = 0;
+
+       ATL2_WRITE_REGW(&adapter->hw, REG_MB_TXD_WR_IDX,
+               (adapter->txd_write_ptr >> 2));
+
+       mmiowb();
+       dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
+}
+
+/*
+ * atl2_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl2_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+
+       if ((new_mtu < 40) || (new_mtu > (ETH_DATA_LEN + VLAN_SIZE)))
+               return -EINVAL;
+
+       /* set MTU */
+       if (hw->max_frame_size != new_mtu) {
+               netdev->mtu = new_mtu;
+               ATL2_WRITE_REG(hw, REG_MTU, new_mtu + ENET_HEADER_SIZE +
+                       VLAN_SIZE + ETHERNET_FCS_SIZE);
+       }
+
+       return 0;
+}
+
+/*
+ * atl2_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 atl2_set_mac(struct net_device *netdev, void *p)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       if (netif_running(netdev))
+               return -EBUSY;
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+       atl2_set_mac_addr(&adapter->hw);
+
+       return 0;
+}
+
+/*
+ * atl2_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl2_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct mii_ioctl_data *data = if_mii(ifr);
+       unsigned long flags;
+
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = 0;
+               break;
+       case SIOCGMIIREG:
+               spin_lock_irqsave(&adapter->stats_lock, flags);
+               if (atl2_read_phy_reg(&adapter->hw,
+                       data->reg_num & 0x1F, &data->val_out)) {
+                       spin_unlock_irqrestore(&adapter->stats_lock, flags);
+                       return -EIO;
+               }
+               spin_unlock_irqrestore(&adapter->stats_lock, flags);
+               break;
+       case SIOCSMIIREG:
+               if (data->reg_num & ~(0x1F))
+                       return -EFAULT;
+               spin_lock_irqsave(&adapter->stats_lock, flags);
+               if (atl2_write_phy_reg(&adapter->hw, data->reg_num,
+                       data->val_in)) {
+                       spin_unlock_irqrestore(&adapter->stats_lock, flags);
+                       return -EIO;
+               }
+               spin_unlock_irqrestore(&adapter->stats_lock, flags);
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
+/*
+ * atl2_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl2_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       switch (cmd) {
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               return atl2_mii_ioctl(netdev, ifr, cmd);
+#ifdef ETHTOOL_OPS_COMPAT
+       case SIOCETHTOOL:
+               return ethtool_ioctl(ifr);
+#endif
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+/*
+ * atl2_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl2_tx_timeout(struct net_device *netdev)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+
+       /* Do the reset outside of interrupt context */
+       schedule_work(&adapter->reset_task);
+}
+
+/*
+ * atl2_watchdog - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl2_watchdog(unsigned long data)
+{
+       struct atl2_adapter *adapter = (struct atl2_adapter *) data;
+
+       if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
+               u32 drop_rxd, drop_rxs;
+               unsigned long flags;
+
+               spin_lock_irqsave(&adapter->stats_lock, flags);
+               drop_rxd = ATL2_READ_REG(&adapter->hw, REG_STS_RXD_OV);
+               drop_rxs = ATL2_READ_REG(&adapter->hw, REG_STS_RXS_OV);
+               spin_unlock_irqrestore(&adapter->stats_lock, flags);
+
+               adapter->netdev->stats.rx_over_errors += drop_rxd + drop_rxs;
+
+               /* Reset the timer */
+               mod_timer(&adapter->watchdog_timer,
+                         round_jiffies(jiffies + 4 * HZ));
+       }
+}
+
+/*
+ * atl2_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl2_phy_config(unsigned long data)
+{
+       struct atl2_adapter *adapter = (struct atl2_adapter *) data;
+       struct atl2_hw *hw = &adapter->hw;
+       unsigned long flags;
+
+       spin_lock_irqsave(&adapter->stats_lock, flags);
+       atl2_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
+       atl2_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN |
+               MII_CR_RESTART_AUTO_NEG);
+       spin_unlock_irqrestore(&adapter->stats_lock, flags);
+       clear_bit(0, &adapter->cfg_phy);
+}
+
+static int atl2_up(struct atl2_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int err = 0;
+       u32 val;
+
+       /* hardware has been reset, we need to reload some things */
+
+       err = atl2_init_hw(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               return err;
+       }
+
+       atl2_set_multi(netdev);
+       init_ring_ptrs(adapter);
+
+       atl2_restore_vlan(adapter);
+
+       if (atl2_configure(adapter)) {
+               err = -EIO;
+               goto err_up;
+       }
+
+       clear_bit(__ATL2_DOWN, &adapter->flags);
+
+       val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL);
+       ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val |
+               MASTER_CTRL_MANUAL_INT);
+
+       atl2_irq_enable(adapter);
+
+err_up:
+       return err;
+}
+
+static void atl2_reinit_locked(struct atl2_adapter *adapter)
+{
+       WARN_ON(in_interrupt());
+       while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags))
+               msleep(1);
+       atl2_down(adapter);
+       atl2_up(adapter);
+       clear_bit(__ATL2_RESETTING, &adapter->flags);
+}
+
+static void atl2_reset_task(struct work_struct *work)
+{
+       struct atl2_adapter *adapter;
+       adapter = container_of(work, struct atl2_adapter, reset_task);
+
+       atl2_reinit_locked(adapter);
+}
+
+static void atl2_setup_mac_ctrl(struct atl2_adapter *adapter)
+{
+       u32 value;
+       struct atl2_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+
+       /* Config MAC CTRL Register */
+       value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY;
+
+       /* duplex */
+       if (FULL_DUPLEX == adapter->link_duplex)
+               value |= MAC_CTRL_DUPLX;
+
+       /* flow control */
+       value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+
+       /* PAD & CRC */
+       value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+
+       /* preamble length */
+       value |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) <<
+               MAC_CTRL_PRMLEN_SHIFT);
+
+       /* vlan */
+       __atl2_vlan_mode(netdev->features, &value);
+
+       /* filter mode */
+       value |= MAC_CTRL_BC_EN;
+       if (netdev->flags & IFF_PROMISC)
+               value |= MAC_CTRL_PROMIS_EN;
+       else if (netdev->flags & IFF_ALLMULTI)
+               value |= MAC_CTRL_MC_ALL_EN;
+
+       /* half retry buffer */
+       value |= (((u32)(adapter->hw.retry_buf &
+               MAC_CTRL_HALF_LEFT_BUF_MASK)) << MAC_CTRL_HALF_LEFT_BUF_SHIFT);
+
+       ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
+}
+
+static int atl2_check_link(struct atl2_adapter *adapter)
+{
+       struct atl2_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       int ret_val;
+       u16 speed, duplex, phy_data;
+       int reconfig = 0;
+
+       /* MII_BMSR must read twise */
+       atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
+       atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
+       if (!(phy_data&BMSR_LSTATUS)) { /* link down */
+               if (netif_carrier_ok(netdev)) { /* old link state: Up */
+                       u32 value;
+                       /* disable rx */
+                       value = ATL2_READ_REG(hw, REG_MAC_CTRL);
+                       value &= ~MAC_CTRL_RX_EN;
+                       ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
+                       adapter->link_speed = SPEED_0;
+                       netif_carrier_off(netdev);
+                       netif_stop_queue(netdev);
+               }
+               return 0;
+       }
+
+       /* Link Up */
+       ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex);
+       if (ret_val)
+               return ret_val;
+       switch (hw->MediaType) {
+       case MEDIA_TYPE_100M_FULL:
+               if (speed  != SPEED_100 || duplex != FULL_DUPLEX)
+                       reconfig = 1;
+               break;
+       case MEDIA_TYPE_100M_HALF:
+               if (speed  != SPEED_100 || duplex != HALF_DUPLEX)
+                       reconfig = 1;
+               break;
+       case MEDIA_TYPE_10M_FULL:
+               if (speed != SPEED_10 || duplex != FULL_DUPLEX)
+                       reconfig = 1;
+               break;
+       case MEDIA_TYPE_10M_HALF:
+               if (speed  != SPEED_10 || duplex != HALF_DUPLEX)
+                       reconfig = 1;
+               break;
+       }
+       /* link result is our setting */
+       if (reconfig == 0) {
+               if (adapter->link_speed != speed ||
+                       adapter->link_duplex != duplex) {
+                       adapter->link_speed = speed;
+                       adapter->link_duplex = duplex;
+                       atl2_setup_mac_ctrl(adapter);
+                       printk(KERN_INFO "%s: %s NIC Link is Up<%d Mbps %s>\n",
+                               atl2_driver_name, netdev->name,
+                               adapter->link_speed,
+                               adapter->link_duplex == FULL_DUPLEX ?
+                                       "Full Duplex" : "Half Duplex");
+               }
+
+               if (!netif_carrier_ok(netdev)) { /* Link down -> Up */
+                       netif_carrier_on(netdev);
+                       netif_wake_queue(netdev);
+               }
+               return 0;
+       }
+
+       /* change original link status */
+       if (netif_carrier_ok(netdev)) {
+               u32 value;
+               /* disable rx */
+               value = ATL2_READ_REG(hw, REG_MAC_CTRL);
+               value &= ~MAC_CTRL_RX_EN;
+               ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
+
+               adapter->link_speed = SPEED_0;
+               netif_carrier_off(netdev);
+               netif_stop_queue(netdev);
+       }
+
+       /* auto-neg, insert timer to re-config phy
+        * (if interval smaller than 5 seconds, something strange) */
+       if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
+               if (!test_and_set_bit(0, &adapter->cfg_phy))
+                       mod_timer(&adapter->phy_config_timer,
+                                 round_jiffies(jiffies + 5 * HZ));
+       }
+
+       return 0;
+}
+
+/*
+ * atl2_link_chg_task - deal with link change event Out of interrupt context
+ * @netdev: network interface device structure
+ */
+static void atl2_link_chg_task(struct work_struct *work)
+{
+       struct atl2_adapter *adapter;
+       unsigned long flags;
+
+       adapter = container_of(work, struct atl2_adapter, link_chg_task);
+
+       spin_lock_irqsave(&adapter->stats_lock, flags);
+       atl2_check_link(adapter);
+       spin_unlock_irqrestore(&adapter->stats_lock, flags);
+}
+
+static void atl2_setup_pcicmd(struct pci_dev *pdev)
+{
+       u16 cmd;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+
+       if (cmd & PCI_COMMAND_INTX_DISABLE)
+               cmd &= ~PCI_COMMAND_INTX_DISABLE;
+       if (cmd & PCI_COMMAND_IO)
+               cmd &= ~PCI_COMMAND_IO;
+       if (0 == (cmd & PCI_COMMAND_MEMORY))
+               cmd |= PCI_COMMAND_MEMORY;
+       if (0 == (cmd & PCI_COMMAND_MASTER))
+               cmd |= PCI_COMMAND_MASTER;
+       pci_write_config_word(pdev, PCI_COMMAND, cmd);
+
+       /*
+        * some motherboards BIOS(PXE/EFI) driver may set PME
+        * while they transfer control to OS (Windows/Linux)
+        * so we should clear this bit before NIC work normally
+        */
+       pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void atl2_poll_controller(struct net_device *netdev)
+{
+       disable_irq(netdev->irq);
+       atl2_intr(netdev->irq, netdev);
+       enable_irq(netdev->irq);
+}
+#endif
+
+
+static const struct net_device_ops atl2_netdev_ops = {
+       .ndo_open               = atl2_open,
+       .ndo_stop               = atl2_close,
+       .ndo_start_xmit         = atl2_xmit_frame,
+       .ndo_set_multicast_list = atl2_set_multi,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = atl2_set_mac,
+       .ndo_change_mtu         = atl2_change_mtu,
+       .ndo_fix_features       = atl2_fix_features,
+       .ndo_set_features       = atl2_set_features,
+       .ndo_do_ioctl           = atl2_ioctl,
+       .ndo_tx_timeout         = atl2_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = atl2_poll_controller,
+#endif
+};
+
+/*
+ * atl2_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl2_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl2_probe 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 __devinit atl2_probe(struct pci_dev *pdev,
+       const struct pci_device_id *ent)
+{
+       struct net_device *netdev;
+       struct atl2_adapter *adapter;
+       static int cards_found;
+       unsigned long mmio_start;
+       int mmio_len;
+       int err;
+
+       cards_found = 0;
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+
+       /*
+        * atl2 is a shared-high-32-bit device, so we're stuck with 32-bit DMA
+        * until the kernel has the proper infrastructure to support 64-bit DMA
+        * on these devices.
+        */
+       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) &&
+               pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+               printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n");
+               goto err_dma;
+       }
+
+       /* Mark all PCI regions associated with PCI device
+        * pdev as being reserved by owner atl2_driver_name */
+       err = pci_request_regions(pdev, atl2_driver_name);
+       if (err)
+               goto err_pci_reg;
+
+       /* Enables bus-mastering on the device and calls
+        * pcibios_set_master to do the needed arch specific settings */
+       pci_set_master(pdev);
+
+       err = -ENOMEM;
+       netdev = alloc_etherdev(sizeof(struct atl2_adapter));
+       if (!netdev)
+               goto err_alloc_etherdev;
+
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+
+       pci_set_drvdata(pdev, netdev);
+       adapter = netdev_priv(netdev);
+       adapter->netdev = netdev;
+       adapter->pdev = pdev;
+       adapter->hw.back = adapter;
+
+       mmio_start = pci_resource_start(pdev, 0x0);
+       mmio_len = pci_resource_len(pdev, 0x0);
+
+       adapter->hw.mem_rang = (u32)mmio_len;
+       adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
+       if (!adapter->hw.hw_addr) {
+               err = -EIO;
+               goto err_ioremap;
+       }
+
+       atl2_setup_pcicmd(pdev);
+
+       netdev->netdev_ops = &atl2_netdev_ops;
+       atl2_set_ethtool_ops(netdev);
+       netdev->watchdog_timeo = 5 * HZ;
+       strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+       netdev->mem_start = mmio_start;
+       netdev->mem_end = mmio_start + mmio_len;
+       adapter->bd_number = cards_found;
+       adapter->pci_using_64 = false;
+
+       /* setup the private structure */
+       err = atl2_sw_init(adapter);
+       if (err)
+               goto err_sw_init;
+
+       err = -EIO;
+
+       netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_RX;
+       netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
+
+       /* Init PHY as early as possible due to power saving issue  */
+       atl2_phy_init(&adapter->hw);
+
+       /* reset the controller to
+        * put the device in a known good starting state */
+
+       if (atl2_reset_hw(&adapter->hw)) {
+               err = -EIO;
+               goto err_reset;
+       }
+
+       /* copy the MAC address out of the EEPROM */
+       atl2_read_mac_addr(&adapter->hw);
+       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+/* FIXME: do we still need this? */
+#ifdef ETHTOOL_GPERMADDR
+       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+
+       if (!is_valid_ether_addr(netdev->perm_addr)) {
+#else
+       if (!is_valid_ether_addr(netdev->dev_addr)) {
+#endif
+               err = -EIO;
+               goto err_eeprom;
+       }
+
+       atl2_check_options(adapter);
+
+       init_timer(&adapter->watchdog_timer);
+       adapter->watchdog_timer.function = atl2_watchdog;
+       adapter->watchdog_timer.data = (unsigned long) adapter;
+
+       init_timer(&adapter->phy_config_timer);
+       adapter->phy_config_timer.function = atl2_phy_config;
+       adapter->phy_config_timer.data = (unsigned long) adapter;
+
+       INIT_WORK(&adapter->reset_task, atl2_reset_task);
+       INIT_WORK(&adapter->link_chg_task, atl2_link_chg_task);
+
+       strcpy(netdev->name, "eth%d"); /* ?? */
+       err = register_netdev(netdev);
+       if (err)
+               goto err_register;
+
+       /* assume we have no link for now */
+       netif_carrier_off(netdev);
+       netif_stop_queue(netdev);
+
+       cards_found++;
+
+       return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+err_eeprom:
+       iounmap(adapter->hw.hw_addr);
+err_ioremap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+       pci_disable_device(pdev);
+       return err;
+}
+
+/*
+ * atl2_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl2_remove 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.
+ */
+/* FIXME: write the original MAC address back in case it was changed from a
+ * BIOS-set value, as in atl1 -- CHS */
+static void __devexit atl2_remove(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+
+       /* flush_scheduled work may reschedule our watchdog task, so
+        * explicitly disable watchdog tasks from being rescheduled  */
+       set_bit(__ATL2_DOWN, &adapter->flags);
+
+       del_timer_sync(&adapter->watchdog_timer);
+       del_timer_sync(&adapter->phy_config_timer);
+       cancel_work_sync(&adapter->reset_task);
+       cancel_work_sync(&adapter->link_chg_task);
+
+       unregister_netdev(netdev);
+
+       atl2_force_ps(&adapter->hw);
+
+       iounmap(adapter->hw.hw_addr);
+       pci_release_regions(pdev);
+
+       free_netdev(netdev);
+
+       pci_disable_device(pdev);
+}
+
+static int atl2_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+       u16 speed, duplex;
+       u32 ctrl = 0;
+       u32 wufc = adapter->wol;
+
+#ifdef CONFIG_PM
+       int retval = 0;
+#endif
+
+       netif_device_detach(netdev);
+
+       if (netif_running(netdev)) {
+               WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags));
+               atl2_down(adapter);
+       }
+
+#ifdef CONFIG_PM
+       retval = pci_save_state(pdev);
+       if (retval)
+               return retval;
+#endif
+
+       atl2_read_phy_reg(hw, MII_BMSR, (u16 *)&ctrl);
+       atl2_read_phy_reg(hw, MII_BMSR, (u16 *)&ctrl);
+       if (ctrl & BMSR_LSTATUS)
+               wufc &= ~ATLX_WUFC_LNKC;
+
+       if (0 != (ctrl & BMSR_LSTATUS) && 0 != wufc) {
+               u32 ret_val;
+               /* get current link speed & duplex */
+               ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex);
+               if (ret_val) {
+                       printk(KERN_DEBUG
+                               "%s: get speed&duplex error while suspend\n",
+                               atl2_driver_name);
+                       goto wol_dis;
+               }
+
+               ctrl = 0;
+
+               /* turn on magic packet wol */
+               if (wufc & ATLX_WUFC_MAG)
+                       ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
+
+               /* ignore Link Chg event when Link is up */
+               ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl);
+
+               /* Config MAC CTRL Register */
+               ctrl = MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY;
+               if (FULL_DUPLEX == adapter->link_duplex)
+                       ctrl |= MAC_CTRL_DUPLX;
+               ctrl |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+               ctrl |= (((u32)adapter->hw.preamble_len &
+                       MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
+               ctrl |= (((u32)(adapter->hw.retry_buf &
+                       MAC_CTRL_HALF_LEFT_BUF_MASK)) <<
+                       MAC_CTRL_HALF_LEFT_BUF_SHIFT);
+               if (wufc & ATLX_WUFC_MAG) {
+                       /* magic packet maybe Broadcast&multicast&Unicast */
+                       ctrl |= MAC_CTRL_BC_EN;
+               }
+
+               ATL2_WRITE_REG(hw, REG_MAC_CTRL, ctrl);
+
+               /* pcie patch */
+               ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
+               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+               ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+               ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
+               ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
+               ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
+
+               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+               goto suspend_exit;
+       }
+
+       if (0 == (ctrl&BMSR_LSTATUS) && 0 != (wufc&ATLX_WUFC_LNKC)) {
+               /* link is down, so only LINK CHG WOL event enable */
+               ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
+               ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl);
+               ATL2_WRITE_REG(hw, REG_MAC_CTRL, 0);
+
+               /* pcie patch */
+               ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
+               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+               ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+               ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
+               ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
+               ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
+
+               hw->phy_configured = false; /* re-init PHY when resume */
+
+               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+
+               goto suspend_exit;
+       }
+
+wol_dis:
+       /* WOL disabled */
+       ATL2_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+       /* pcie patch */
+       ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
+       ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+       ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+       ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
+       ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
+       ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
+
+       atl2_force_ps(hw);
+       hw->phy_configured = false; /* re-init PHY when resume */
+
+       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+
+suspend_exit:
+       if (netif_running(netdev))
+               atl2_free_irq(adapter);
+
+       pci_disable_device(pdev);
+
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int atl2_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       u32 err;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR
+                       "atl2: Cannot enable PCI device from suspend\n");
+               return err;
+       }
+
+       pci_set_master(pdev);
+
+       ATL2_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       ATL2_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+
+       if (netif_running(netdev)) {
+               err = atl2_request_irq(adapter);
+               if (err)
+                       return err;
+       }
+
+       atl2_reset_hw(&adapter->hw);
+
+       if (netif_running(netdev))
+               atl2_up(adapter);
+
+       netif_device_attach(netdev);
+
+       return 0;
+}
+#endif
+
+static void atl2_shutdown(struct pci_dev *pdev)
+{
+       atl2_suspend(pdev, PMSG_SUSPEND);
+}
+
+static struct pci_driver atl2_driver = {
+       .name     = atl2_driver_name,
+       .id_table = atl2_pci_tbl,
+       .probe    = atl2_probe,
+       .remove   = __devexit_p(atl2_remove),
+       /* Power Management Hooks */
+       .suspend  = atl2_suspend,
+#ifdef CONFIG_PM
+       .resume   = atl2_resume,
+#endif
+       .shutdown = atl2_shutdown,
+};
+
+/*
+ * atl2_init_module - Driver Registration Routine
+ *
+ * atl2_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl2_init_module(void)
+{
+       printk(KERN_INFO "%s - version %s\n", atl2_driver_string,
+               atl2_driver_version);
+       printk(KERN_INFO "%s\n", atl2_copyright);
+       return pci_register_driver(&atl2_driver);
+}
+module_init(atl2_init_module);
+
+/*
+ * atl2_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl2_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl2_exit_module(void)
+{
+       pci_unregister_driver(&atl2_driver);
+}
+module_exit(atl2_exit_module);
+
+static void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value)
+{
+       struct atl2_adapter *adapter = hw->back;
+       pci_read_config_word(adapter->pdev, reg, value);
+}
+
+static void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value)
+{
+       struct atl2_adapter *adapter = hw->back;
+       pci_write_config_word(adapter->pdev, reg, *value);
+}
+
+static int atl2_get_settings(struct net_device *netdev,
+       struct ethtool_cmd *ecmd)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+
+       ecmd->supported = (SUPPORTED_10baseT_Half |
+               SUPPORTED_10baseT_Full |
+               SUPPORTED_100baseT_Half |
+               SUPPORTED_100baseT_Full |
+               SUPPORTED_Autoneg |
+               SUPPORTED_TP);
+       ecmd->advertising = ADVERTISED_TP;
+
+       ecmd->advertising |= ADVERTISED_Autoneg;
+       ecmd->advertising |= hw->autoneg_advertised;
+
+       ecmd->port = PORT_TP;
+       ecmd->phy_address = 0;
+       ecmd->transceiver = XCVR_INTERNAL;
+
+       if (adapter->link_speed != SPEED_0) {
+               ethtool_cmd_speed_set(ecmd, adapter->link_speed);
+               if (adapter->link_duplex == FULL_DUPLEX)
+                       ecmd->duplex = DUPLEX_FULL;
+               else
+                       ecmd->duplex = DUPLEX_HALF;
+       } else {
+               ethtool_cmd_speed_set(ecmd, -1);
+               ecmd->duplex = -1;
+       }
+
+       ecmd->autoneg = AUTONEG_ENABLE;
+       return 0;
+}
+
+static int atl2_set_settings(struct net_device *netdev,
+       struct ethtool_cmd *ecmd)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+
+       while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags))
+               msleep(1);
+
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+#define MY_ADV_MASK    (ADVERTISE_10_HALF | \
+                        ADVERTISE_10_FULL | \
+                        ADVERTISE_100_HALF| \
+                        ADVERTISE_100_FULL)
+
+               if ((ecmd->advertising & MY_ADV_MASK) == MY_ADV_MASK) {
+                       hw->MediaType = MEDIA_TYPE_AUTO_SENSOR;
+                       hw->autoneg_advertised =  MY_ADV_MASK;
+               } else if ((ecmd->advertising & MY_ADV_MASK) ==
+                               ADVERTISE_100_FULL) {
+                       hw->MediaType = MEDIA_TYPE_100M_FULL;
+                       hw->autoneg_advertised = ADVERTISE_100_FULL;
+               } else if ((ecmd->advertising & MY_ADV_MASK) ==
+                               ADVERTISE_100_HALF) {
+                       hw->MediaType = MEDIA_TYPE_100M_HALF;
+                       hw->autoneg_advertised = ADVERTISE_100_HALF;
+               } else if ((ecmd->advertising & MY_ADV_MASK) ==
+                               ADVERTISE_10_FULL) {
+                       hw->MediaType = MEDIA_TYPE_10M_FULL;
+                       hw->autoneg_advertised = ADVERTISE_10_FULL;
+               }  else if ((ecmd->advertising & MY_ADV_MASK) ==
+                               ADVERTISE_10_HALF) {
+                       hw->MediaType = MEDIA_TYPE_10M_HALF;
+                       hw->autoneg_advertised = ADVERTISE_10_HALF;
+               } else {
+                       clear_bit(__ATL2_RESETTING, &adapter->flags);
+                       return -EINVAL;
+               }
+               ecmd->advertising = hw->autoneg_advertised |
+                       ADVERTISED_TP | ADVERTISED_Autoneg;
+       } else {
+               clear_bit(__ATL2_RESETTING, &adapter->flags);
+               return -EINVAL;
+       }
+
+       /* reset the link */
+       if (netif_running(adapter->netdev)) {
+               atl2_down(adapter);
+               atl2_up(adapter);
+       } else
+               atl2_reset_hw(&adapter->hw);
+
+       clear_bit(__ATL2_RESETTING, &adapter->flags);
+       return 0;
+}
+
+static u32 atl2_get_msglevel(struct net_device *netdev)
+{
+       return 0;
+}
+
+/*
+ * It's sane for this to be empty, but we might want to take advantage of this.
+ */
+static void atl2_set_msglevel(struct net_device *netdev, u32 data)
+{
+}
+
+static int atl2_get_regs_len(struct net_device *netdev)
+{
+#define ATL2_REGS_LEN 42
+       return sizeof(u32) * ATL2_REGS_LEN;
+}
+
+static void atl2_get_regs(struct net_device *netdev,
+       struct ethtool_regs *regs, void *p)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+       u32 *regs_buff = p;
+       u16 phy_data;
+
+       memset(p, 0, sizeof(u32) * ATL2_REGS_LEN);
+
+       regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
+
+       regs_buff[0]  = ATL2_READ_REG(hw, REG_VPD_CAP);
+       regs_buff[1]  = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
+       regs_buff[2]  = ATL2_READ_REG(hw, REG_SPI_FLASH_CONFIG);
+       regs_buff[3]  = ATL2_READ_REG(hw, REG_TWSI_CTRL);
+       regs_buff[4]  = ATL2_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
+       regs_buff[5]  = ATL2_READ_REG(hw, REG_MASTER_CTRL);
+       regs_buff[6]  = ATL2_READ_REG(hw, REG_MANUAL_TIMER_INIT);
+       regs_buff[7]  = ATL2_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
+       regs_buff[8]  = ATL2_READ_REG(hw, REG_PHY_ENABLE);
+       regs_buff[9]  = ATL2_READ_REG(hw, REG_CMBDISDMA_TIMER);
+       regs_buff[10] = ATL2_READ_REG(hw, REG_IDLE_STATUS);
+       regs_buff[11] = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+       regs_buff[12] = ATL2_READ_REG(hw, REG_SERDES_LOCK);
+       regs_buff[13] = ATL2_READ_REG(hw, REG_MAC_CTRL);
+       regs_buff[14] = ATL2_READ_REG(hw, REG_MAC_IPG_IFG);
+       regs_buff[15] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR);
+       regs_buff[16] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR+4);
+       regs_buff[17] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE);
+       regs_buff[18] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE+4);
+       regs_buff[19] = ATL2_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
+       regs_buff[20] = ATL2_READ_REG(hw, REG_MTU);
+       regs_buff[21] = ATL2_READ_REG(hw, REG_WOL_CTRL);
+       regs_buff[22] = ATL2_READ_REG(hw, REG_SRAM_TXRAM_END);
+       regs_buff[23] = ATL2_READ_REG(hw, REG_DESC_BASE_ADDR_HI);
+       regs_buff[24] = ATL2_READ_REG(hw, REG_TXD_BASE_ADDR_LO);
+       regs_buff[25] = ATL2_READ_REG(hw, REG_TXD_MEM_SIZE);
+       regs_buff[26] = ATL2_READ_REG(hw, REG_TXS_BASE_ADDR_LO);
+       regs_buff[27] = ATL2_READ_REG(hw, REG_TXS_MEM_SIZE);
+       regs_buff[28] = ATL2_READ_REG(hw, REG_RXD_BASE_ADDR_LO);
+       regs_buff[29] = ATL2_READ_REG(hw, REG_RXD_BUF_NUM);
+       regs_buff[30] = ATL2_READ_REG(hw, REG_DMAR);
+       regs_buff[31] = ATL2_READ_REG(hw, REG_TX_CUT_THRESH);
+       regs_buff[32] = ATL2_READ_REG(hw, REG_DMAW);
+       regs_buff[33] = ATL2_READ_REG(hw, REG_PAUSE_ON_TH);
+       regs_buff[34] = ATL2_READ_REG(hw, REG_PAUSE_OFF_TH);
+       regs_buff[35] = ATL2_READ_REG(hw, REG_MB_TXD_WR_IDX);
+       regs_buff[36] = ATL2_READ_REG(hw, REG_MB_RXD_RD_IDX);
+       regs_buff[38] = ATL2_READ_REG(hw, REG_ISR);
+       regs_buff[39] = ATL2_READ_REG(hw, REG_IMR);
+
+       atl2_read_phy_reg(hw, MII_BMCR, &phy_data);
+       regs_buff[40] = (u32)phy_data;
+       atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
+       regs_buff[41] = (u32)phy_data;
+}
+
+static int atl2_get_eeprom_len(struct net_device *netdev)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+
+       if (!atl2_check_eeprom_exist(&adapter->hw))
+               return 512;
+       else
+               return 0;
+}
+
+static int atl2_get_eeprom(struct net_device *netdev,
+       struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+       u32 *eeprom_buff;
+       int first_dword, last_dword;
+       int ret_val = 0;
+       int i;
+
+       if (eeprom->len == 0)
+               return -EINVAL;
+
+       if (atl2_check_eeprom_exist(hw))
+               return -EINVAL;
+
+       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+
+       first_dword = eeprom->offset >> 2;
+       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+       eeprom_buff = kmalloc(sizeof(u32) * (last_dword - first_dword + 1),
+               GFP_KERNEL);
+       if (!eeprom_buff)
+               return -ENOMEM;
+
+       for (i = first_dword; i < last_dword; i++) {
+               if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) {
+                       ret_val = -EIO;
+                       goto free;
+               }
+       }
+
+       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+               eeprom->len);
+free:
+       kfree(eeprom_buff);
+
+       return ret_val;
+}
+
+static int atl2_set_eeprom(struct net_device *netdev,
+       struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       struct atl2_hw *hw = &adapter->hw;
+       u32 *eeprom_buff;
+       u32 *ptr;
+       int max_len, first_dword, last_dword, ret_val = 0;
+       int i;
+
+       if (eeprom->len == 0)
+               return -EOPNOTSUPP;
+
+       if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+               return -EFAULT;
+
+       max_len = 512;
+
+       first_dword = eeprom->offset >> 2;
+       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+       eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+       if (!eeprom_buff)
+               return -ENOMEM;
+
+       ptr = eeprom_buff;
+
+       if (eeprom->offset & 3) {
+               /* need read/modify/write of first changed EEPROM word */
+               /* only the second byte of the word is being modified */
+               if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+               ptr++;
+       }
+       if (((eeprom->offset + eeprom->len) & 3)) {
+               /*
+                * need read/modify/write of last changed EEPROM word
+                * only the first byte of the word is being modified
+                */
+               if (!atl2_read_eeprom(hw, last_dword * 4,
+                                       &(eeprom_buff[last_dword - first_dword]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+       }
+
+       /* Device's eeprom is always little-endian, word addressable */
+       memcpy(ptr, bytes, eeprom->len);
+
+       for (i = 0; i < last_dword - first_dword + 1; i++) {
+               if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+       }
+ out:
+       kfree(eeprom_buff);
+       return ret_val;
+}
+
+static void atl2_get_drvinfo(struct net_device *netdev,
+       struct ethtool_drvinfo *drvinfo)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+
+       strncpy(drvinfo->driver,  atl2_driver_name, 32);
+       strncpy(drvinfo->version, atl2_driver_version, 32);
+       strncpy(drvinfo->fw_version, "L2", 32);
+       strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+       drvinfo->n_stats = 0;
+       drvinfo->testinfo_len = 0;
+       drvinfo->regdump_len = atl2_get_regs_len(netdev);
+       drvinfo->eedump_len = atl2_get_eeprom_len(netdev);
+}
+
+static void atl2_get_wol(struct net_device *netdev,
+       struct ethtool_wolinfo *wol)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+
+       wol->supported = 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;
+       if (adapter->wol & ATLX_WUFC_LNKC)
+               wol->wolopts |= WAKE_PHY;
+}
+
+static int atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+
+       if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
+               return -EOPNOTSUPP;
+
+       if (wol->wolopts & (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
+               return -EOPNOTSUPP;
+
+       /* these settings will always override what we currently have */
+       adapter->wol = 0;
+
+       if (wol->wolopts & WAKE_MAGIC)
+               adapter->wol |= ATLX_WUFC_MAG;
+       if (wol->wolopts & WAKE_PHY)
+               adapter->wol |= ATLX_WUFC_LNKC;
+
+       return 0;
+}
+
+static int atl2_nway_reset(struct net_device *netdev)
+{
+       struct atl2_adapter *adapter = netdev_priv(netdev);
+       if (netif_running(netdev))
+               atl2_reinit_locked(adapter);
+       return 0;
+}
+
+static const struct ethtool_ops atl2_ethtool_ops = {
+       .get_settings           = atl2_get_settings,
+       .set_settings           = atl2_set_settings,
+       .get_drvinfo            = atl2_get_drvinfo,
+       .get_regs_len           = atl2_get_regs_len,
+       .get_regs               = atl2_get_regs,
+       .get_wol                = atl2_get_wol,
+       .set_wol                = atl2_set_wol,
+       .get_msglevel           = atl2_get_msglevel,
+       .set_msglevel           = atl2_set_msglevel,
+       .nway_reset             = atl2_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_eeprom_len         = atl2_get_eeprom_len,
+       .get_eeprom             = atl2_get_eeprom,
+       .set_eeprom             = atl2_set_eeprom,
+};
+
+static void atl2_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops);
+}
+
+#define LBYTESWAP(a)  ((((a) & 0x00ff00ff) << 8) | \
+       (((a) & 0xff00ff00) >> 8))
+#define LONGSWAP(a)   ((LBYTESWAP(a) << 16) | (LBYTESWAP(a) >> 16))
+#define SHORTSWAP(a)  (((a) << 8) | ((a) >> 8))
+
+/*
+ * 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)
+ */
+static s32 atl2_reset_hw(struct atl2_hw *hw)
+{
+       u32 icr;
+       u16 pci_cfg_cmd_word;
+       int i;
+
+       /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
+       atl2_read_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word);
+       if ((pci_cfg_cmd_word &
+               (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) !=
+               (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) {
+               pci_cfg_cmd_word |=
+                       (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER);
+               atl2_write_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word);
+       }
+
+       /* Clear Interrupt mask to stop board from generating
+        * interrupts & Clear any pending interrupt events
+        */
+       /* FIXME */
+       /* ATL2_WRITE_REG(hw, REG_IMR, 0); */
+       /* ATL2_WRITE_REG(hw, REG_ISR, 0xffffffff); */
+
+       /* 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.
+        */
+       ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST);
+       wmb();
+       msleep(1); /* delay about 1ms */
+
+       /* Wait at least 10ms for All module to be Idle */
+       for (i = 0; i < 10; i++) {
+               icr = ATL2_READ_REG(hw, REG_IDLE_STATUS);
+               if (!icr)
+                       break;
+               msleep(1); /* delay 1 ms */
+               cpu_relax();
+       }
+
+       if (icr)
+               return icr;
+
+       return 0;
+}
+
+#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 struct atl2_spi_flash_dev flash_table[] =
+{
+/* MFR    WRSR  READ  PROGRAM WREN  WRDI  RDSR  RDID  SECTOR_ERASE CHIP_ERASE */
+{"Atmel", 0x0,  0x03, 0x02,   0x06, 0x04, 0x05, 0x15, 0x52,        0x62 },
+{"SST",   0x01, 0x03, 0x02,   0x06, 0x04, 0x05, 0x90, 0x20,        0x60 },
+{"ST",    0x01, 0x03, 0x02,   0x06, 0x04, 0x05, 0xAB, 0xD8,        0xC7 },
+};
+
+static bool atl2_spi_read(struct atl2_hw *hw, u32 addr, u32 *buf)
+{
+       int i;
+       u32 value;
+
+       ATL2_WRITE_REG(hw, REG_SPI_DATA, 0);
+       ATL2_WRITE_REG(hw, REG_SPI_ADDR, 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 |
+               (0x1 & SPI_FLASH_CTRL_INS_MASK) << SPI_FLASH_CTRL_INS_SHIFT;
+
+       ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+
+       value |= SPI_FLASH_CTRL_START;
+
+       ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+
+       for (i = 0; i < 10; i++) {
+               msleep(1);
+               value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
+               if (!(value & SPI_FLASH_CTRL_START))
+                       break;
+       }
+
+       if (value & SPI_FLASH_CTRL_START)
+               return false;
+
+       *buf = ATL2_READ_REG(hw, REG_SPI_DATA);
+
+       return true;
+}
+
+/*
+ * get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int get_permanent_address(struct atl2_hw *hw)
+{
+       u32 Addr[2];
+       u32 i, Control;
+       u16 Register;
+       u8  EthAddr[NODE_ADDRESS_SIZE];
+       bool KeyValid;
+
+       if (is_valid_ether_addr(hw->perm_mac_addr))
+               return 0;
+
+       Addr[0] = 0;
+       Addr[1] = 0;
+
+       if (!atl2_check_eeprom_exist(hw)) { /* eeprom exists */
+               Register = 0;
+               KeyValid = false;
+
+               /* Read out all EEPROM content */
+               i = 0;
+               while (1) {
+                       if (atl2_read_eeprom(hw, i + 0x100, &Control)) {
+                               if (KeyValid) {
+                                       if (Register == REG_MAC_STA_ADDR)
+                                               Addr[0] = Control;
+                                       else if (Register ==
+                                               (REG_MAC_STA_ADDR + 4))
+                                               Addr[1] = Control;
+                                       KeyValid = false;
+                               } else if ((Control & 0xff) == 0x5A) {
+                                       KeyValid = true;
+                                       Register = (u16) (Control >> 16);
+                               } else {
+                       /* assume data end while encount an invalid KEYWORD */
+                                       break;
+                               }
+                       } else {
+                               break; /* read error */
+                       }
+                       i += 4;
+               }
+
+               *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
+               *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *) &Addr[1]);
+
+               if (is_valid_ether_addr(EthAddr)) {
+                       memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE);
+                       return 0;
+               }
+               return 1;
+       }
+
+       /* see if SPI flash exists? */
+       Addr[0] = 0;
+       Addr[1] = 0;
+       Register = 0;
+       KeyValid = false;
+       i = 0;
+       while (1) {
+               if (atl2_spi_read(hw, i + 0x1f000, &Control)) {
+                       if (KeyValid) {
+                               if (Register == REG_MAC_STA_ADDR)
+                                       Addr[0] = Control;
+                               else if (Register == (REG_MAC_STA_ADDR + 4))
+                                       Addr[1] = Control;
+                               KeyValid = false;
+                       } else if ((Control & 0xff) == 0x5A) {
+                               KeyValid = true;
+                               Register = (u16) (Control >> 16);
+                       } else {
+                               break; /* data end */
+                       }
+               } else {
+                       break; /* read error */
+               }
+               i += 4;
+       }
+
+       *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
+       *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *)&Addr[1]);
+       if (is_valid_ether_addr(EthAddr)) {
+               memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE);
+               return 0;
+       }
+       /* maybe MAC-address is from BIOS */
+       Addr[0] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR);
+       Addr[1] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR + 4);
+       *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
+       *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *) &Addr[1]);
+
+       if (is_valid_ether_addr(EthAddr)) {
+               memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE);
+               return 0;
+       }
+
+       return 1;
+}
+
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static s32 atl2_read_mac_addr(struct atl2_hw *hw)
+{
+       u16 i;
+
+       if (get_permanent_address(hw)) {
+               /* for test */
+               /* FIXME: shouldn't we use random_ether_addr() here? */
+               hw->perm_mac_addr[0] = 0x00;
+               hw->perm_mac_addr[1] = 0x13;
+               hw->perm_mac_addr[2] = 0x74;
+               hw->perm_mac_addr[3] = 0x00;
+               hw->perm_mac_addr[4] = 0x5c;
+               hw->perm_mac_addr[5] = 0x38;
+       }
+
+       for (i = 0; i < NODE_ADDRESS_SIZE; 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
+ *
+ * atl2_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
+ */
+static u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr)
+{
+       u32 crc32, value;
+       int i;
+
+       value = 0;
+       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
+ */
+static void atl2_hash_set(struct atl2_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 = ATL2_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+       mta |= (1 << hash_bit);
+
+       ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+
+/*
+ * atl2_init_pcie - init PCIE module
+ */
+static void atl2_init_pcie(struct atl2_hw *hw)
+{
+    u32 value;
+    value = LTSSM_TEST_MODE_DEF;
+    ATL2_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value);
+
+    value = PCIE_DLL_TX_CTRL1_DEF;
+    ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, value);
+}
+
+static void atl2_init_flash_opcode(struct atl2_hw *hw)
+{
+       if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
+               hw->flash_vendor = 0; /* ATMEL */
+
+       /* Init OP table */
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_PROGRAM,
+               flash_table[hw->flash_vendor].cmdPROGRAM);
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_SC_ERASE,
+               flash_table[hw->flash_vendor].cmdSECTOR_ERASE);
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_CHIP_ERASE,
+               flash_table[hw->flash_vendor].cmdCHIP_ERASE);
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDID,
+               flash_table[hw->flash_vendor].cmdRDID);
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WREN,
+               flash_table[hw->flash_vendor].cmdWREN);
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDSR,
+               flash_table[hw->flash_vendor].cmdRDSR);
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WRSR,
+               flash_table[hw->flash_vendor].cmdWRSR);
+       ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_READ,
+               flash_table[hw->flash_vendor].cmdREAD);
+}
+
+/********************************************************************
+* 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.
+********************************************************************/
+static s32 atl2_init_hw(struct atl2_hw *hw)
+{
+       u32 ret_val = 0;
+
+       atl2_init_pcie(hw);
+
+       /* Zero out the Multicast HASH table */
+       /* clear the old settings from the multicast hash table */
+       ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+       ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+       atl2_init_flash_opcode(hw);
+
+       ret_val = atl2_phy_init(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
+ */
+static s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed,
+       u16 *duplex)
+{
+       s32 ret_val;
+       u16 phy_data;
+
+       /* Read PHY Specific Status Register (17) */
+       ret_val = atl2_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_100MBS:
+               *speed = SPEED_100;
+               break;
+       case MII_ATLX_PSSR_10MBS:
+               *speed = SPEED_10;
+               break;
+       default:
+               return ATLX_ERR_PHY_SPEED;
+               break;
+       }
+
+       if (phy_data & MII_ATLX_PSSR_DPLX)
+               *duplex = FULL_DUPLEX;
+       else
+               *duplex = HALF_DUPLEX;
+
+       return 0;
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+static s32 atl2_read_phy_reg(struct atl2_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;
+       ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+       wmb();
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+               wmb();
+       }
+       if (!(val & (MDIO_START | MDIO_BUSY))) {
+               *phy_data = (u16)val;
+               return 0;
+       }
+
+       return ATLX_ERR_PHY;
+}
+
+/*
+ * 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
+ */
+static s32 atl2_write_phy_reg(struct atl2_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;
+       ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+       wmb();
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+
+               wmb();
+       }
+
+       if (!(val & (MDIO_START | MDIO_BUSY)))
+               return 0;
+
+       return ATLX_ERR_PHY;
+}
+
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static s32 atl2_phy_setup_autoneg_adv(struct atl2_hw *hw)
+{
+       s32 ret_val;
+       s16 mii_autoneg_adv_reg;
+
+       /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+       mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
+
+       /* Need to parse autoneg_advertised  and set up
+        * the appropriate PHY registers.  First we will parse for
+        * autoneg_advertised software override.  Since we can advertise
+        * a plethora of combinations, we need to check each bit
+        * individually.
+        */
+
+       /* 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;
+
+       /* Need to parse MediaType and setup the
+        * appropriate PHY registers. */
+       switch (hw->MediaType) {
+       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);
+               hw->autoneg_advertised =
+                       ADVERTISE_10_HALF |
+                       ADVERTISE_10_FULL |
+                       ADVERTISE_100_HALF|
+                       ADVERTISE_100_FULL;
+               break;
+       case MEDIA_TYPE_100M_FULL:
+               mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_100_FULL;
+               break;
+       case MEDIA_TYPE_100M_HALF:
+               mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_100_HALF;
+               break;
+       case MEDIA_TYPE_10M_FULL:
+               mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_10_FULL;
+               break;
+       default:
+               mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_10_HALF;
+               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;
+
+       ret_val = atl2_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
+
+       if (ret_val)
+               return ret_val;
+
+       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 atl2_phy_commit(struct atl2_hw *hw)
+{
+       s32 ret_val;
+       u16 phy_data;
+
+       phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG;
+       ret_val = atl2_write_phy_reg(hw, MII_BMCR, phy_data);
+       if (ret_val) {
+               u32 val;
+               int i;
+               /* pcie serdes link may be down ! */
+               for (i = 0; i < 25; i++) {
+                       msleep(1);
+                       val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+                       if (!(val & (MDIO_START | MDIO_BUSY)))
+                               break;
+               }
+
+               if (0 != (val & (MDIO_START | MDIO_BUSY))) {
+                       printk(KERN_ERR "atl2: PCIe link down for at least 25ms !\n");
+                       return ret_val;
+               }
+       }
+       return 0;
+}
+
+static s32 atl2_phy_init(struct atl2_hw *hw)
+{
+       s32 ret_val;
+       u16 phy_val;
+
+       if (hw->phy_configured)
+               return 0;
+
+       /* Enable PHY */
+       ATL2_WRITE_REGW(hw, REG_PHY_ENABLE, 1);
+       ATL2_WRITE_FLUSH(hw);
+       msleep(1);
+
+       /* check if the PHY is in powersaving mode */
+       atl2_write_phy_reg(hw, MII_DBG_ADDR, 0);
+       atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val);
+
+       /* 024E / 124E 0r 0274 / 1274 ? */
+       if (phy_val & 0x1000) {
+               phy_val &= ~0x1000;
+               atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val);
+       }
+
+       msleep(1);
+
+       /*Enable PHY LinkChange Interrupt */
+       ret_val = atl2_write_phy_reg(hw, 18, 0xC00);
+       if (ret_val)
+               return ret_val;
+
+       /* setup AutoNeg parameters */
+       ret_val = atl2_phy_setup_autoneg_adv(hw);
+       if (ret_val)
+               return ret_val;
+
+       /* SW.Reset & En-Auto-Neg to restart Auto-Neg */
+       ret_val = atl2_phy_commit(hw);
+       if (ret_val)
+               return ret_val;
+
+       hw->phy_configured = true;
+
+       return ret_val;
+}
+
+static void atl2_set_mac_addr(struct atl2_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]));
+       ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+       /* hight dword */
+       value = (((u32)hw->mac_addr[0]) << 8) |
+               (((u32)hw->mac_addr[1]));
+       ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/*
+ * check_eeprom_exist
+ * return 0 if eeprom exist
+ */
+static int atl2_check_eeprom_exist(struct atl2_hw *hw)
+{
+       u32 value;
+
+       value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
+       if (value & SPI_FLASH_CTRL_EN_VPD) {
+               value &= ~SPI_FLASH_CTRL_EN_VPD;
+               ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+       }
+       value = ATL2_READ_REGW(hw, REG_PCIE_CAP_LIST);
+       return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
+}
+
+/* FIXME: This doesn't look right. -- CHS */
+static bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value)
+{
+       return true;
+}
+
+static bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue)
+{
+       int i;
+       u32    Control;
+
+       if (Offset & 0x3)
+               return false; /* address do not align */
+
+       ATL2_WRITE_REG(hw, REG_VPD_DATA, 0);
+       Control = (Offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
+       ATL2_WRITE_REG(hw, REG_VPD_CAP, Control);
+
+       for (i = 0; i < 10; i++) {
+               msleep(2);
+               Control = ATL2_READ_REG(hw, REG_VPD_CAP);
+               if (Control & VPD_CAP_VPD_FLAG)
+                       break;
+       }
+
+       if (Control & VPD_CAP_VPD_FLAG) {
+               *pValue = ATL2_READ_REG(hw, REG_VPD_DATA);
+               return true;
+       }
+       return false; /* timeout */
+}
+
+static void atl2_force_ps(struct atl2_hw *hw)
+{
+       u16 phy_val;
+
+       atl2_write_phy_reg(hw, MII_DBG_ADDR, 0);
+       atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val);
+       atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val | 0x1000);
+
+       atl2_write_phy_reg(hw, MII_DBG_ADDR, 2);
+       atl2_write_phy_reg(hw, MII_DBG_DATA, 0x3000);
+       atl2_write_phy_reg(hw, MII_DBG_ADDR, 3);
+       atl2_write_phy_reg(hw, MII_DBG_DATA, 0);
+}
+
+/* This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+#define ATL2_MAX_NIC 4
+
+#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 ATL2_PARAM_INIT {[0 ... ATL2_MAX_NIC] = OPTION_UNSET}
+#ifndef module_param_array
+/* Module Parameters are always initialized to -1, so that the driver
+ * can tell the difference between no user specified value or the
+ * user asking for the default value.
+ * The true default values are loaded in when atl2_check_options is called.
+ *
+ * This is a GCC extension to ANSI C.
+ * See the item "Labeled Elements in Initializers" in the section
+ * "Extensions to the C Language Family" of the GCC documentation.
+ */
+
+#define ATL2_PARAM(X, desc) \
+    static const int __devinitdata X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \
+    MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \
+    MODULE_PARM_DESC(X, desc);
+#else
+#define ATL2_PARAM(X, desc) \
+    static int __devinitdata X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \
+    static unsigned int num_##X; \
+    module_param_array_named(X, X, int, &num_##X, 0); \
+    MODULE_PARM_DESC(X, desc);
+#endif
+
+/*
+ * Transmit Memory Size
+ * Valid Range: 64-2048
+ * Default Value: 128
+ */
+#define ATL2_MIN_TX_MEMSIZE            4       /* 4KB */
+#define ATL2_MAX_TX_MEMSIZE            64      /* 64KB */
+#define ATL2_DEFAULT_TX_MEMSIZE                8       /* 8KB */
+ATL2_PARAM(TxMemSize, "Bytes of Transmit Memory");
+
+/*
+ * Receive Memory Block Count
+ * Valid Range: 16-512
+ * Default Value: 128
+ */
+#define ATL2_MIN_RXD_COUNT             16
+#define ATL2_MAX_RXD_COUNT             512
+#define ATL2_DEFAULT_RXD_COUNT         64
+ATL2_PARAM(RxMemBlock, "Number of receive memory block");
+
+/*
+ * User Specified MediaType Override
+ *
+ * Valid Range: 0-5
+ *  - 0    - auto-negotiate at all supported speeds
+ *  - 1    - only link at 1000Mbps Full Duplex
+ *  - 2    - only link at 100Mbps Full Duplex
+ *  - 3    - only link at 100Mbps Half Duplex
+ *  - 4    - only link at 10Mbps Full Duplex
+ *  - 5    - only link at 10Mbps Half Duplex
+ * Default Value: 0
+ */
+ATL2_PARAM(MediaType, "MediaType Select");
+
+/*
+ * Interrupt Moderate Timer in units of 2048 ns (~2 us)
+ * Valid Range: 10-65535
+ * Default Value: 45000(90ms)
+ */
+#define INT_MOD_DEFAULT_CNT    100 /* 200us */
+#define INT_MOD_MAX_CNT                65000
+#define INT_MOD_MIN_CNT                50
+ATL2_PARAM(IntModTimer, "Interrupt Moderator Timer");
+
+/*
+ * FlashVendor
+ * Valid Range: 0-2
+ * 0 - Atmel
+ * 1 - SST
+ * 2 - ST
+ */
+ATL2_PARAM(FlashVendor, "SPI Flash Vendor");
+
+#define AUTONEG_ADV_DEFAULT    0x2F
+#define AUTONEG_ADV_MASK       0x2F
+#define FLOW_CONTROL_DEFAULT   FLOW_CONTROL_FULL
+
+#define FLASH_VENDOR_DEFAULT   0
+#define FLASH_VENDOR_MIN       0
+#define FLASH_VENDOR_MAX       2
+
+struct atl2_option {
+       enum { enable_option, range_option, list_option } type;
+       char *name;
+       char *err;
+       int  def;
+       union {
+               struct { /* range_option info */
+                       int min;
+                       int max;
+               } r;
+               struct { /* list_option info */
+                       int nr;
+                       struct atl2_opt_list { int i; char *str; } *p;
+               } l;
+       } arg;
+};
+
+static int __devinit atl2_validate_option(int *value, struct atl2_option *opt)
+{
+       int i;
+       struct atl2_opt_list *ent;
+
+       if (*value == OPTION_UNSET) {
+               *value = opt->def;
+               return 0;
+       }
+
+       switch (opt->type) {
+       case enable_option:
+               switch (*value) {
+               case OPTION_ENABLED:
+                       printk(KERN_INFO "%s Enabled\n", opt->name);
+                       return 0;
+                       break;
+               case OPTION_DISABLED:
+                       printk(KERN_INFO "%s Disabled\n", opt->name);
+                       return 0;
+                       break;
+               }
+               break;
+       case range_option:
+               if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+                       printk(KERN_INFO "%s set to %i\n", opt->name, *value);
+                       return 0;
+               }
+               break;
+       case list_option:
+               for (i = 0; i < opt->arg.l.nr; i++) {
+                       ent = &opt->arg.l.p[i];
+                       if (*value == ent->i) {
+                               if (ent->str[0] != '\0')
+                                       printk(KERN_INFO "%s\n", ent->str);
+                       return 0;
+                       }
+               }
+               break;
+       default:
+               BUG();
+       }
+
+       printk(KERN_INFO "Invalid %s specified (%i) %s\n",
+               opt->name, *value, opt->err);
+       *value = opt->def;
+       return -1;
+}
+
+/*
+ * atl2_check_options - Range Checking for Command Line Parameters
+ * @adapter: board private structure
+ *
+ * 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.
+ */
+static void __devinit atl2_check_options(struct atl2_adapter *adapter)
+{
+       int val;
+       struct atl2_option opt;
+       int bd = adapter->bd_number;
+       if (bd >= ATL2_MAX_NIC) {
+               printk(KERN_NOTICE "Warning: no configuration for board #%i\n",
+                       bd);
+               printk(KERN_NOTICE "Using defaults for all values\n");
+#ifndef module_param_array
+               bd = ATL2_MAX_NIC;
+#endif
+       }
+
+       /* Bytes of Transmit Memory */
+       opt.type = range_option;
+       opt.name = "Bytes of Transmit Memory";
+       opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_TX_MEMSIZE);
+       opt.def = ATL2_DEFAULT_TX_MEMSIZE;
+       opt.arg.r.min = ATL2_MIN_TX_MEMSIZE;
+       opt.arg.r.max = ATL2_MAX_TX_MEMSIZE;
+#ifdef module_param_array
+       if (num_TxMemSize > bd) {
+#endif
+               val = TxMemSize[bd];
+               atl2_validate_option(&val, &opt);
+               adapter->txd_ring_size = ((u32) val) * 1024;
+#ifdef module_param_array
+       } else
+               adapter->txd_ring_size = ((u32)opt.def) * 1024;
+#endif
+       /* txs ring size: */
+       adapter->txs_ring_size = adapter->txd_ring_size / 128;
+       if (adapter->txs_ring_size > 160)
+               adapter->txs_ring_size = 160;
+
+       /* Receive Memory Block Count */
+       opt.type = range_option;
+       opt.name = "Number of receive memory block";
+       opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_RXD_COUNT);
+       opt.def = ATL2_DEFAULT_RXD_COUNT;
+       opt.arg.r.min = ATL2_MIN_RXD_COUNT;
+       opt.arg.r.max = ATL2_MAX_RXD_COUNT;
+#ifdef module_param_array
+       if (num_RxMemBlock > bd) {
+#endif
+               val = RxMemBlock[bd];
+               atl2_validate_option(&val, &opt);
+               adapter->rxd_ring_size = (u32)val;
+               /* FIXME */
+               /* ((u16)val)&~1; */    /* even number */
+#ifdef module_param_array
+       } else
+               adapter->rxd_ring_size = (u32)opt.def;
+#endif
+       /* init RXD Flow control value */
+       adapter->hw.fc_rxd_hi = (adapter->rxd_ring_size / 8) * 7;
+       adapter->hw.fc_rxd_lo = (ATL2_MIN_RXD_COUNT / 8) >
+               (adapter->rxd_ring_size / 12) ? (ATL2_MIN_RXD_COUNT / 8) :
+               (adapter->rxd_ring_size / 12);
+
+       /* Interrupt Moderate Timer */
+       opt.type = range_option;
+       opt.name = "Interrupt Moderate Timer";
+       opt.err = "using default of " __MODULE_STRING(INT_MOD_DEFAULT_CNT);
+       opt.def = INT_MOD_DEFAULT_CNT;
+       opt.arg.r.min = INT_MOD_MIN_CNT;
+       opt.arg.r.max = INT_MOD_MAX_CNT;
+#ifdef module_param_array
+       if (num_IntModTimer > bd) {
+#endif
+               val = IntModTimer[bd];
+               atl2_validate_option(&val, &opt);
+               adapter->imt = (u16) val;
+#ifdef module_param_array
+       } else
+               adapter->imt = (u16)(opt.def);
+#endif
+       /* Flash Vendor */
+       opt.type = range_option;
+       opt.name = "SPI Flash Vendor";
+       opt.err = "using default of " __MODULE_STRING(FLASH_VENDOR_DEFAULT);
+       opt.def = FLASH_VENDOR_DEFAULT;
+       opt.arg.r.min = FLASH_VENDOR_MIN;
+       opt.arg.r.max = FLASH_VENDOR_MAX;
+#ifdef module_param_array
+       if (num_FlashVendor > bd) {
+#endif
+               val = FlashVendor[bd];
+               atl2_validate_option(&val, &opt);
+               adapter->hw.flash_vendor = (u8) val;
+#ifdef module_param_array
+       } else
+               adapter->hw.flash_vendor = (u8)(opt.def);
+#endif
+       /* MediaType */
+       opt.type = range_option;
+       opt.name = "Speed/Duplex Selection";
+       opt.err = "using default of " __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR);
+       opt.def = MEDIA_TYPE_AUTO_SENSOR;
+       opt.arg.r.min = MEDIA_TYPE_AUTO_SENSOR;
+       opt.arg.r.max = MEDIA_TYPE_10M_HALF;
+#ifdef module_param_array
+       if (num_MediaType > bd) {
+#endif
+               val = MediaType[bd];
+               atl2_validate_option(&val, &opt);
+               adapter->hw.MediaType = (u16) val;
+#ifdef module_param_array
+       } else
+               adapter->hw.MediaType = (u16)(opt.def);
+#endif
+}
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.h b/drivers/net/ethernet/atheros/atlx/atl2.h
new file mode 100644 (file)
index 0000000..bf9016e
--- /dev/null
@@ -0,0 +1,525 @@
+/* atl2.h -- atl2 driver definitions
+ *
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ * Copyright(c) 2006 xiong huang <xiong.huang@atheros.com>
+ * Copyright(c) 2007 Chris Snook <csnook@redhat.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#ifndef _ATL2_H_
+#define _ATL2_H_
+
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+
+#ifndef _ATL2_HW_H_
+#define _ATL2_HW_H_
+
+#ifndef _ATL2_OSDEP_H_
+#define _ATL2_OSDEP_H_
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+
+#include "atlx.h"
+
+#ifdef ETHTOOL_OPS_COMPAT
+extern int ethtool_ioctl(struct ifreq *ifr);
+#endif
+
+#define PCI_COMMAND_REGISTER   PCI_COMMAND
+#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
+#define ETH_ADDR_LEN           ETH_ALEN
+
+#define ATL2_WRITE_REG(a, reg, value) (iowrite32((value), \
+       ((a)->hw_addr + (reg))))
+
+#define ATL2_WRITE_FLUSH(a) (ioread32((a)->hw_addr))
+
+#define ATL2_READ_REG(a, reg) (ioread32((a)->hw_addr + (reg)))
+
+#define ATL2_WRITE_REGB(a, reg, value) (iowrite8((value), \
+       ((a)->hw_addr + (reg))))
+
+#define ATL2_READ_REGB(a, reg) (ioread8((a)->hw_addr + (reg)))
+
+#define ATL2_WRITE_REGW(a, reg, value) (iowrite16((value), \
+       ((a)->hw_addr + (reg))))
+
+#define ATL2_READ_REGW(a, reg) (ioread16((a)->hw_addr + (reg)))
+
+#define ATL2_WRITE_REG_ARRAY(a, reg, offset, value) \
+       (iowrite32((value), (((a)->hw_addr + (reg)) + ((offset) << 2))))
+
+#define ATL2_READ_REG_ARRAY(a, reg, offset) \
+       (ioread32(((a)->hw_addr + (reg)) + ((offset) << 2)))
+
+#endif /* _ATL2_OSDEP_H_ */
+
+struct atl2_adapter;
+struct atl2_hw;
+
+/* function prototype */
+static s32 atl2_reset_hw(struct atl2_hw *hw);
+static s32 atl2_read_mac_addr(struct atl2_hw *hw);
+static s32 atl2_init_hw(struct atl2_hw *hw);
+static s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed,
+       u16 *duplex);
+static u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr);
+static void atl2_hash_set(struct atl2_hw *hw, u32 hash_value);
+static s32 atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data);
+static s32 atl2_write_phy_reg(struct atl2_hw *hw, u32 reg_addr, u16 phy_data);
+static void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value);
+static void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value);
+static void atl2_set_mac_addr(struct atl2_hw *hw);
+static bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue);
+static bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value);
+static s32 atl2_phy_init(struct atl2_hw *hw);
+static int atl2_check_eeprom_exist(struct atl2_hw *hw);
+static void atl2_force_ps(struct atl2_hw *hw);
+
+/* register definition */
+
+/* Block IDLE Status Register */
+#define IDLE_STATUS_RXMAC      1       /* 1: RXMAC is non-IDLE */
+#define IDLE_STATUS_TXMAC      2       /* 1: TXMAC is non-IDLE */
+#define IDLE_STATUS_DMAR       8       /* 1: DMAR is non-IDLE */
+#define IDLE_STATUS_DMAW       4       /* 1: DMAW is non-IDLE */
+
+/* MDIO Control Register */
+#define MDIO_WAIT_TIMES                10
+
+/* MAC Control Register */
+#define MAC_CTRL_DBG_TX_BKPRESURE      0x100000        /* 1: TX max backoff */
+#define MAC_CTRL_MACLP_CLK_PHY         0x8000000       /* 1: 25MHz from phy */
+#define MAC_CTRL_HALF_LEFT_BUF_SHIFT   28
+#define MAC_CTRL_HALF_LEFT_BUF_MASK    0xF             /* MAC retry buf x32B */
+
+/* Internal SRAM Partition Register */
+#define REG_SRAM_TXRAM_END     0x1500  /* Internal tail address of TXRAM
+                                        * default: 2byte*1024 */
+#define REG_SRAM_RXRAM_END     0x1502  /* Internal tail address of RXRAM
+                                        * default: 2byte*1024 */
+
+/* Descriptor Control register */
+#define REG_TXD_BASE_ADDR_LO   0x1544  /* The base address of the Transmit
+                                        * Data Mem low 32-bit(dword align) */
+#define REG_TXD_MEM_SIZE       0x1548  /* Transmit Data Memory size(by
+                                        * double word , max 256KB) */
+#define REG_TXS_BASE_ADDR_LO   0x154C  /* The base address of the Transmit
+                                        * Status Memory low 32-bit(dword word
+                                        * align) */
+#define REG_TXS_MEM_SIZE       0x1550  /* double word unit, max 4*2047
+                                        * bytes. */
+#define REG_RXD_BASE_ADDR_LO   0x1554  /* The base address of the Transmit
+                                        * Status Memory low 32-bit(unit 8
+                                        * bytes) */
+#define REG_RXD_BUF_NUM                0x1558  /* Receive Data & Status Memory buffer
+                                        * number (unit 1536bytes, max
+                                        * 1536*2047) */
+
+/* DMAR Control Register */
+#define REG_DMAR       0x1580
+#define     DMAR_EN    0x1     /* 1: Enable DMAR */
+
+/* TX Cur-Through (early tx threshold) Control Register */
+#define REG_TX_CUT_THRESH      0x1590  /* TxMac begin transmit packet
+                                        * threshold(unit word) */
+
+/* DMAW Control Register */
+#define REG_DMAW       0x15A0
+#define     DMAW_EN    0x1
+
+/* Flow control register */
+#define REG_PAUSE_ON_TH                0x15A8  /* RXD high watermark of overflow
+                                        * threshold configuration register */
+#define REG_PAUSE_OFF_TH       0x15AA  /* RXD lower watermark of overflow
+                                        * threshold configuration register */
+
+/* Mailbox Register */
+#define REG_MB_TXD_WR_IDX      0x15f0  /* double word align */
+#define REG_MB_RXD_RD_IDX      0x15F4  /* RXD Read index (unit: 1536byets) */
+
+/* Interrupt Status Register */
+#define ISR_TIMER      1       /* Interrupt when Timer counts down to zero */
+#define ISR_MANUAL     2       /* Software manual interrupt, for debug. Set
+                                * when SW_MAN_INT_EN is set in Table 51
+                                * Selene Master Control Register
+                                * (Offset 0x1400). */
+#define ISR_RXF_OV     4       /* RXF overflow interrupt */
+#define ISR_TXF_UR     8       /* TXF underrun interrupt */
+#define ISR_TXS_OV     0x10    /* Internal transmit status buffer full
+                                * interrupt */
+#define ISR_RXS_OV     0x20    /* Internal receive status buffer full
+                                * interrupt */
+#define ISR_LINK_CHG   0x40    /* Link Status Change Interrupt */
+#define ISR_HOST_TXD_UR        0x80
+#define ISR_HOST_RXD_OV        0x100   /* Host rx data memory full , one pulse */
+#define ISR_DMAR_TO_RST        0x200   /* DMAR op timeout interrupt. SW should
+                                * do Reset */
+#define ISR_DMAW_TO_RST        0x400
+#define ISR_PHY                0x800   /* phy interrupt */
+#define ISR_TS_UPDATE  0x10000 /* interrupt after new tx pkt status written
+                                * to host */
+#define ISR_RS_UPDATE  0x20000 /* interrupt ater new rx pkt status written
+                                * to host. */
+#define ISR_TX_EARLY   0x40000 /* interrupt when txmac begin transmit one
+                                * packet */
+
+#define ISR_TX_EVENT (ISR_TXF_UR | ISR_TXS_OV | ISR_HOST_TXD_UR |\
+       ISR_TS_UPDATE | ISR_TX_EARLY)
+#define ISR_RX_EVENT (ISR_RXF_OV | ISR_RXS_OV | ISR_HOST_RXD_OV |\
+        ISR_RS_UPDATE)
+
+#define IMR_NORMAL_MASK                (\
+       /*ISR_LINK_CHG          |*/\
+       ISR_MANUAL              |\
+       ISR_DMAR_TO_RST         |\
+       ISR_DMAW_TO_RST         |\
+       ISR_PHY                 |\
+       ISR_PHY_LINKDOWN        |\
+       ISR_TS_UPDATE           |\
+       ISR_RS_UPDATE)
+
+/* Receive MAC Statistics Registers */
+#define REG_STS_RX_PAUSE       0x1700  /* Num pause packets received */
+#define REG_STS_RXD_OV         0x1704  /* Num frames dropped due to RX
+                                        * FIFO overflow */
+#define REG_STS_RXS_OV         0x1708  /* Num frames dropped due to RX
+                                        * Status Buffer Overflow */
+#define REG_STS_RX_FILTER      0x170C  /* Num packets dropped due to
+                                        * address filtering */
+
+/* MII definitions */
+
+/* PHY Common Register */
+#define MII_SMARTSPEED 0x14
+#define MII_DBG_ADDR   0x1D
+#define MII_DBG_DATA   0x1E
+
+/* PCI Command Register Bit Definitions */
+#define PCI_REG_COMMAND                0x04
+#define CMD_IO_SPACE           0x0001
+#define CMD_MEMORY_SPACE       0x0002
+#define CMD_BUS_MASTER         0x0004
+
+#define MEDIA_TYPE_100M_FULL   1
+#define MEDIA_TYPE_100M_HALF   2
+#define MEDIA_TYPE_10M_FULL    3
+#define MEDIA_TYPE_10M_HALF    4
+
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT        0x000F  /* Everything */
+
+/* The size (in bytes) of a ethernet packet */
+#define ENET_HEADER_SIZE               14
+#define MAXIMUM_ETHERNET_FRAME_SIZE    1518    /* with FCS */
+#define MINIMUM_ETHERNET_FRAME_SIZE    64      /* with FCS */
+#define ETHERNET_FCS_SIZE              4
+#define MAX_JUMBO_FRAME_SIZE           0x2000
+#define VLAN_SIZE                                               4
+
+struct tx_pkt_header {
+       unsigned pkt_size:11;
+       unsigned:4;                     /* reserved */
+       unsigned ins_vlan:1;            /* txmac should insert vlan */
+       unsigned short vlan;            /* vlan tag */
+};
+/* FIXME: replace above bitfields with MASK/SHIFT defines below */
+#define TX_PKT_HEADER_SIZE_MASK                0x7FF
+#define TX_PKT_HEADER_SIZE_SHIFT       0
+#define TX_PKT_HEADER_INS_VLAN_MASK    0x1
+#define TX_PKT_HEADER_INS_VLAN_SHIFT   15
+#define TX_PKT_HEADER_VLAN_TAG_MASK    0xFFFF
+#define TX_PKT_HEADER_VLAN_TAG_SHIFT   16
+
+struct tx_pkt_status {
+       unsigned pkt_size:11;
+       unsigned:5;             /* reserved */
+       unsigned ok:1;          /* current packet transmitted without error */
+       unsigned bcast:1;       /* broadcast packet */
+       unsigned mcast:1;       /* multicast packet */
+       unsigned pause:1;       /* transmiited a pause frame */
+       unsigned ctrl:1;
+       unsigned defer:1;       /* current packet is xmitted with defer */
+       unsigned exc_defer:1;
+       unsigned single_col:1;
+       unsigned multi_col:1;
+       unsigned late_col:1;
+       unsigned abort_col:1;
+       unsigned underun:1;     /* current packet is aborted
+                                * due to txram underrun */
+       unsigned:3;             /* reserved */
+       unsigned update:1;      /* always 1'b1 in tx_status_buf */
+};
+/* FIXME: replace above bitfields with MASK/SHIFT defines below */
+#define TX_PKT_STATUS_SIZE_MASK                0x7FF
+#define TX_PKT_STATUS_SIZE_SHIFT       0
+#define TX_PKT_STATUS_OK_MASK          0x1
+#define TX_PKT_STATUS_OK_SHIFT         16
+#define TX_PKT_STATUS_BCAST_MASK       0x1
+#define TX_PKT_STATUS_BCAST_SHIFT      17
+#define TX_PKT_STATUS_MCAST_MASK       0x1
+#define TX_PKT_STATUS_MCAST_SHIFT      18
+#define TX_PKT_STATUS_PAUSE_MASK       0x1
+#define TX_PKT_STATUS_PAUSE_SHIFT      19
+#define TX_PKT_STATUS_CTRL_MASK                0x1
+#define TX_PKT_STATUS_CTRL_SHIFT       20
+#define TX_PKT_STATUS_DEFER_MASK       0x1
+#define TX_PKT_STATUS_DEFER_SHIFT      21
+#define TX_PKT_STATUS_EXC_DEFER_MASK   0x1
+#define TX_PKT_STATUS_EXC_DEFER_SHIFT  22
+#define TX_PKT_STATUS_SINGLE_COL_MASK  0x1
+#define TX_PKT_STATUS_SINGLE_COL_SHIFT 23
+#define TX_PKT_STATUS_MULTI_COL_MASK   0x1
+#define TX_PKT_STATUS_MULTI_COL_SHIFT  24
+#define TX_PKT_STATUS_LATE_COL_MASK    0x1
+#define TX_PKT_STATUS_LATE_COL_SHIFT   25
+#define TX_PKT_STATUS_ABORT_COL_MASK   0x1
+#define TX_PKT_STATUS_ABORT_COL_SHIFT  26
+#define TX_PKT_STATUS_UNDERRUN_MASK    0x1
+#define TX_PKT_STATUS_UNDERRUN_SHIFT   27
+#define TX_PKT_STATUS_UPDATE_MASK      0x1
+#define TX_PKT_STATUS_UPDATE_SHIFT     31
+
+struct rx_pkt_status {
+       unsigned pkt_size:11;   /* packet size, max 2047 bytes */
+       unsigned:5;             /* reserved */
+       unsigned ok:1;          /* current packet received ok without error */
+       unsigned bcast:1;       /* current packet is broadcast */
+       unsigned mcast:1;       /* current packet is multicast */
+       unsigned pause:1;
+       unsigned ctrl:1;
+       unsigned crc:1;         /* received a packet with crc error */
+       unsigned code:1;        /* received a packet with code error */
+       unsigned runt:1;        /* received a packet less than 64 bytes
+                                * with good crc */
+       unsigned frag:1;        /* received a packet less than 64 bytes
+                                * with bad crc */
+       unsigned trunc:1;       /* current frame truncated due to rxram full */
+       unsigned align:1;       /* this packet is alignment error */
+       unsigned vlan:1;        /* this packet has vlan */
+       unsigned:3;             /* reserved */
+       unsigned update:1;
+       unsigned short vtag;    /* vlan tag */
+       unsigned:16;
+};
+/* FIXME: replace above bitfields with MASK/SHIFT defines below */
+#define RX_PKT_STATUS_SIZE_MASK                0x7FF
+#define RX_PKT_STATUS_SIZE_SHIFT       0
+#define RX_PKT_STATUS_OK_MASK          0x1
+#define RX_PKT_STATUS_OK_SHIFT         16
+#define RX_PKT_STATUS_BCAST_MASK       0x1
+#define RX_PKT_STATUS_BCAST_SHIFT      17
+#define RX_PKT_STATUS_MCAST_MASK       0x1
+#define RX_PKT_STATUS_MCAST_SHIFT      18
+#define RX_PKT_STATUS_PAUSE_MASK       0x1
+#define RX_PKT_STATUS_PAUSE_SHIFT      19
+#define RX_PKT_STATUS_CTRL_MASK                0x1
+#define RX_PKT_STATUS_CTRL_SHIFT       20
+#define RX_PKT_STATUS_CRC_MASK         0x1
+#define RX_PKT_STATUS_CRC_SHIFT                21
+#define RX_PKT_STATUS_CODE_MASK                0x1
+#define RX_PKT_STATUS_CODE_SHIFT       22
+#define RX_PKT_STATUS_RUNT_MASK                0x1
+#define RX_PKT_STATUS_RUNT_SHIFT       23
+#define RX_PKT_STATUS_FRAG_MASK                0x1
+#define RX_PKT_STATUS_FRAG_SHIFT       24
+#define RX_PKT_STATUS_TRUNK_MASK       0x1
+#define RX_PKT_STATUS_TRUNK_SHIFT      25
+#define RX_PKT_STATUS_ALIGN_MASK       0x1
+#define RX_PKT_STATUS_ALIGN_SHIFT      26
+#define RX_PKT_STATUS_VLAN_MASK                0x1
+#define RX_PKT_STATUS_VLAN_SHIFT       27
+#define RX_PKT_STATUS_UPDATE_MASK      0x1
+#define RX_PKT_STATUS_UPDATE_SHIFT     31
+#define RX_PKT_STATUS_VLAN_TAG_MASK    0xFFFF
+#define RX_PKT_STATUS_VLAN_TAG_SHIFT   32
+
+struct rx_desc {
+       struct rx_pkt_status    status;
+       unsigned char           packet[1536-sizeof(struct rx_pkt_status)];
+};
+
+enum atl2_speed_duplex {
+       atl2_10_half = 0,
+       atl2_10_full = 1,
+       atl2_100_half = 2,
+       atl2_100_full = 3
+};
+
+struct atl2_spi_flash_dev {
+       const char *manu_name;  /* manufacturer id */
+       /* op-code */
+       u8 cmdWRSR;
+       u8 cmdREAD;
+       u8 cmdPROGRAM;
+       u8 cmdWREN;
+       u8 cmdWRDI;
+       u8 cmdRDSR;
+       u8 cmdRDID;
+       u8 cmdSECTOR_ERASE;
+       u8 cmdCHIP_ERASE;
+};
+
+/* Structure containing variables used by the shared code (atl2_hw.c) */
+struct atl2_hw {
+       u8 __iomem *hw_addr;
+       void *back;
+
+       u8 preamble_len;
+       u8 max_retry;          /* Retransmission maximum, afterwards the
+                               * packet will be discarded. */
+       u8 jam_ipg;            /* IPG to start JAM for collision based flow
+                               * control in half-duplex mode. In unit of
+                               * 8-bit time. */
+       u8 ipgt;               /* Desired back to back inter-packet gap. The
+                               * default is 96-bit time. */
+       u8 min_ifg;            /* Minimum number of IFG to enforce in between
+                               * RX frames. Frame gap below such IFP is
+                               * dropped. */
+       u8 ipgr1;              /* 64bit Carrier-Sense window */
+       u8 ipgr2;              /* 96-bit IPG window */
+       u8 retry_buf;          /* When half-duplex mode, should hold some
+                               * bytes for mac retry . (8*4bytes unit) */
+
+       u16 fc_rxd_hi;
+       u16 fc_rxd_lo;
+       u16 lcol;              /* Collision Window */
+       u16 max_frame_size;
+
+       u16 MediaType;
+       u16 autoneg_advertised;
+       u16 pci_cmd_word;
+
+       u16 mii_autoneg_adv_reg;
+
+       u32 mem_rang;
+       u32 txcw;
+       u32 mc_filter_type;
+       u32 num_mc_addrs;
+       u32 collision_delta;
+       u32 tx_packet_delta;
+       u16 phy_spd_default;
+
+       u16 device_id;
+       u16 vendor_id;
+       u16 subsystem_id;
+       u16 subsystem_vendor_id;
+       u8 revision_id;
+
+       /* spi flash */
+       u8 flash_vendor;
+
+       u8 dma_fairness;
+       u8 mac_addr[NODE_ADDRESS_SIZE];
+       u8 perm_mac_addr[NODE_ADDRESS_SIZE];
+
+       /* FIXME */
+       /* bool phy_preamble_sup; */
+       bool phy_configured;
+};
+
+#endif /* _ATL2_HW_H_ */
+
+struct atl2_ring_header {
+    /* pointer to the descriptor ring memory */
+    void *desc;
+    /* physical address of the descriptor ring */
+    dma_addr_t dma;
+    /* length of descriptor ring in bytes */
+    unsigned int size;
+};
+
+/* board specific private data structure */
+struct atl2_adapter {
+       /* OS defined structs */
+       struct net_device *netdev;
+       struct pci_dev *pdev;
+       u32 wol;
+       u16 link_speed;
+       u16 link_duplex;
+
+       spinlock_t stats_lock;
+
+       struct work_struct reset_task;
+       struct work_struct link_chg_task;
+       struct timer_list watchdog_timer;
+       struct timer_list phy_config_timer;
+
+       unsigned long cfg_phy;
+       bool mac_disabled;
+
+       /* All Descriptor memory */
+       dma_addr_t      ring_dma;
+       void            *ring_vir_addr;
+       int             ring_size;
+
+       struct tx_pkt_header    *txd_ring;
+       dma_addr_t      txd_dma;
+
+       struct tx_pkt_status    *txs_ring;
+       dma_addr_t      txs_dma;
+
+       struct rx_desc  *rxd_ring;
+       dma_addr_t      rxd_dma;
+
+       u32 txd_ring_size;         /* bytes per unit */
+       u32 txs_ring_size;         /* dwords per unit */
+       u32 rxd_ring_size;         /* 1536 bytes per unit */
+
+       /* read /write ptr: */
+       /* host */
+       u32 txd_write_ptr;
+       u32 txs_next_clear;
+       u32 rxd_read_ptr;
+
+       /* nic */
+       atomic_t txd_read_ptr;
+       atomic_t txs_write_ptr;
+       u32 rxd_write_ptr;
+
+       /* Interrupt Moderator timer ( 2us resolution) */
+       u16 imt;
+       /* Interrupt Clear timer (2us resolution) */
+       u16 ict;
+
+       unsigned long flags;
+       /* structs defined in atl2_hw.h */
+       u32 bd_number;     /* board number */
+       bool pci_using_64;
+       bool have_msi;
+       struct atl2_hw hw;
+
+       u32 usr_cmd;
+       /* FIXME */
+       /* u32 regs_buff[ATL2_REGS_LEN]; */
+       u32 pci_state[16];
+
+       u32 *config_space;
+};
+
+enum atl2_state_t {
+       __ATL2_TESTING,
+       __ATL2_RESETTING,
+       __ATL2_DOWN
+};
+
+#endif /* _ATL2_H_ */
diff --git a/drivers/net/ethernet/atheros/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c
new file mode 100644 (file)
index 0000000..aabcf4b
--- /dev/null
@@ -0,0 +1,269 @@
+/* atlx.c -- common functions for Attansic network drivers
+ *
+ * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+ * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+/* Including this file like a header is a temporary hack, I promise. -- CHS */
+#ifndef ATLX_C
+#define ATLX_C
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/if.h>
+#include <linux/netdevice.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "atlx.h"
+
+static s32 atlx_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data);
+static u32 atlx_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
+static void atlx_set_mac_addr(struct atl1_hw *hw);
+
+static struct atlx_spi_flash_dev flash_table[] = {
+/*     MFR_NAME  WRSR  READ  PRGM  WREN  WRDI  RDSR  RDID  SEC_ERS CHIP_ERS */
+       {"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52,   0x62},
+       {"SST",   0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20,   0x60},
+       {"ST",    0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8,   0xC7},
+};
+
+static int atlx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       switch (cmd) {
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               return atlx_mii_ioctl(netdev, ifr, cmd);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+/*
+ * atlx_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 atlx_set_mac(struct net_device *netdev, void *p)
+{
+       struct atlx_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);
+
+       atlx_set_mac_addr(&adapter->hw);
+       return 0;
+}
+
+static void atlx_check_for_link(struct atlx_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       u16 phy_data = 0;
+
+       spin_lock(&adapter->lock);
+       adapter->phy_timer_pending = false;
+       atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       atlx_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);
+               }
+       }
+       schedule_work(&adapter->link_chg_task);
+}
+
+/*
+ * atlx_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 atlx_set_multi(struct net_device *netdev)
+{
+       struct atlx_adapter *adapter = netdev_priv(netdev);
+       struct atlx_hw *hw = &adapter->hw;
+       struct netdev_hw_addr *ha;
+       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 */
+       netdev_for_each_mc_addr(ha, netdev) {
+               hash_value = atlx_hash_mc_addr(hw, ha->addr);
+               atlx_hash_set(hw, hash_value);
+       }
+}
+
+/*
+ * atlx_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static void atlx_irq_enable(struct atlx_adapter *adapter)
+{
+       iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
+       ioread32(adapter->hw.hw_addr + REG_IMR);
+}
+
+/*
+ * atlx_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static void atlx_irq_disable(struct atlx_adapter *adapter)
+{
+       iowrite32(0, adapter->hw.hw_addr + REG_IMR);
+       ioread32(adapter->hw.hw_addr + REG_IMR);
+       synchronize_irq(adapter->pdev->irq);
+}
+
+static void atlx_clear_phy_int(struct atlx_adapter *adapter)
+{
+       u16 phy_data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&adapter->lock, flags);
+       atlx_read_phy_reg(&adapter->hw, 19, &phy_data);
+       spin_unlock_irqrestore(&adapter->lock, flags);
+}
+
+/*
+ * atlx_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atlx_tx_timeout(struct net_device *netdev)
+{
+       struct atlx_adapter *adapter = netdev_priv(netdev);
+       /* Do the reset outside of interrupt context */
+       schedule_work(&adapter->tx_timeout_task);
+}
+
+/*
+ * atlx_link_chg_task - deal with link change event Out of interrupt context
+ */
+static void atlx_link_chg_task(struct work_struct *work)
+{
+       struct atlx_adapter *adapter;
+       unsigned long flags;
+
+       adapter = container_of(work, struct atlx_adapter, link_chg_task);
+
+       spin_lock_irqsave(&adapter->lock, flags);
+       atlx_check_link(adapter);
+       spin_unlock_irqrestore(&adapter->lock, flags);
+}
+
+static void __atlx_vlan_mode(u32 features, u32 *ctrl)
+{
+       if (features & NETIF_F_HW_VLAN_RX) {
+               /* enable VLAN tag insert/strip */
+               *ctrl |= MAC_CTRL_RMV_VLAN;
+       } else {
+               /* disable VLAN tag insert/strip */
+               *ctrl &= ~MAC_CTRL_RMV_VLAN;
+       }
+}
+
+static void atlx_vlan_mode(struct net_device *netdev, u32 features)
+{
+       struct atlx_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
+       u32 ctrl;
+
+       spin_lock_irqsave(&adapter->lock, flags);
+       /* atlx_irq_disable(adapter); FIXME: confirm/remove */
+       ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
+       __atlx_vlan_mode(features, &ctrl);
+       iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
+       /* atlx_irq_enable(adapter); FIXME */
+       spin_unlock_irqrestore(&adapter->lock, flags);
+}
+
+static void atlx_restore_vlan(struct atlx_adapter *adapter)
+{
+       atlx_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+static u32 atlx_fix_features(struct net_device *netdev, u32 features)
+{
+       /*
+        * Since there is no support for separate rx/tx vlan accel
+        * enable/disable make sure tx flag is always in same state as rx.
+        */
+       if (features & NETIF_F_HW_VLAN_RX)
+               features |= NETIF_F_HW_VLAN_TX;
+       else
+               features &= ~NETIF_F_HW_VLAN_TX;
+
+       return features;
+}
+
+static int atlx_set_features(struct net_device *netdev, u32 features)
+{
+       u32 changed = netdev->features ^ features;
+
+       if (changed & NETIF_F_HW_VLAN_RX)
+               atlx_vlan_mode(netdev, features);
+
+       return 0;
+}
+
+#endif /* ATLX_C */
diff --git a/drivers/net/ethernet/atheros/atlx/atlx.h b/drivers/net/ethernet/atheros/atlx/atlx.h
new file mode 100644 (file)
index 0000000..14054b7
--- /dev/null
@@ -0,0 +1,503 @@
+/* atlx_hw.h -- common hardware definitions for Attansic network drivers
+ *
+ * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
+ * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
+ * Copyright(c) 2006 - 2008 Jay Cliburn <jcliburn@gmail.com>
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+#ifndef ATLX_H
+#define ATLX_H
+
+#include <linux/module.h>
+#include <linux/types.h>
+
+#define ATLX_ERR_PHY                   2
+#define ATLX_ERR_PHY_SPEED             7
+#define ATLX_ERR_PHY_RES               8
+
+#define SPEED_0                                0xffff
+#define SPEED_10                       10
+#define SPEED_100                      100
+#define SPEED_1000                     1000
+#define HALF_DUPLEX                    1
+#define FULL_DUPLEX                    2
+
+#define MEDIA_TYPE_AUTO_SENSOR         0
+
+/* register definitions */
+#define REG_PM_CTRLSTAT                        0x44
+
+#define REG_PCIE_CAP_LIST              0x58
+
+#define REG_VPD_CAP                    0x6C
+#define VPD_CAP_ID_MASK                        0xFF
+#define VPD_CAP_ID_SHIFT               0
+#define VPD_CAP_NEXT_PTR_MASK          0xFF
+#define VPD_CAP_NEXT_PTR_SHIFT         8
+#define VPD_CAP_VPD_ADDR_MASK          0x7FFF
+#define VPD_CAP_VPD_ADDR_SHIFT         16
+#define VPD_CAP_VPD_FLAG               0x80000000
+
+#define REG_VPD_DATA                   0x70
+
+#define REG_SPI_FLASH_CTRL             0x200
+#define SPI_FLASH_CTRL_STS_NON_RDY     0x1
+#define SPI_FLASH_CTRL_STS_WEN         0x2
+#define SPI_FLASH_CTRL_STS_WPEN                0x80
+#define SPI_FLASH_CTRL_DEV_STS_MASK    0xFF
+#define SPI_FLASH_CTRL_DEV_STS_SHIFT   0
+#define SPI_FLASH_CTRL_INS_MASK                0x7
+#define SPI_FLASH_CTRL_INS_SHIFT       8
+#define SPI_FLASH_CTRL_START           0x800
+#define SPI_FLASH_CTRL_EN_VPD          0x2000
+#define SPI_FLASH_CTRL_LDSTART         0x8000
+#define SPI_FLASH_CTRL_CS_HI_MASK      0x3
+#define SPI_FLASH_CTRL_CS_HI_SHIFT     16
+#define SPI_FLASH_CTRL_CS_HOLD_MASK    0x3
+#define SPI_FLASH_CTRL_CS_HOLD_SHIFT   18
+#define SPI_FLASH_CTRL_CLK_LO_MASK     0x3
+#define SPI_FLASH_CTRL_CLK_LO_SHIFT    20
+#define SPI_FLASH_CTRL_CLK_HI_MASK     0x3
+#define SPI_FLASH_CTRL_CLK_HI_SHIFT    22
+#define SPI_FLASH_CTRL_CS_SETUP_MASK   0x3
+#define SPI_FLASH_CTRL_CS_SETUP_SHIFT  24
+#define SPI_FLASH_CTRL_EROM_PGSZ_MASK  0x3
+#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26
+#define SPI_FLASH_CTRL_WAIT_READY      0x10000000
+
+#define REG_SPI_ADDR                   0x204
+
+#define REG_SPI_DATA                   0x208
+
+#define REG_SPI_FLASH_CONFIG           0x20C
+#define SPI_FLASH_CONFIG_LD_ADDR_MASK  0xFFFFFF
+#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0
+#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3
+#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT        24
+#define SPI_FLASH_CONFIG_LD_EXIST      0x4000000
+
+#define REG_SPI_FLASH_OP_PROGRAM       0x210
+#define REG_SPI_FLASH_OP_SC_ERASE      0x211
+#define REG_SPI_FLASH_OP_CHIP_ERASE    0x212
+#define REG_SPI_FLASH_OP_RDID          0x213
+#define REG_SPI_FLASH_OP_WREN          0x214
+#define REG_SPI_FLASH_OP_RDSR          0x215
+#define REG_SPI_FLASH_OP_WRSR          0x216
+#define REG_SPI_FLASH_OP_READ          0x217
+
+#define REG_TWSI_CTRL                  0x218
+#define TWSI_CTRL_LD_OFFSET_MASK       0xFF
+#define TWSI_CTRL_LD_OFFSET_SHIFT      0
+#define TWSI_CTRL_LD_SLV_ADDR_MASK     0x7
+#define TWSI_CTRL_LD_SLV_ADDR_SHIFT    8
+#define TWSI_CTRL_SW_LDSTART           0x800
+#define TWSI_CTRL_HW_LDSTART           0x1000
+#define TWSI_CTRL_SMB_SLV_ADDR_MASK    0x7F
+#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT   15
+#define TWSI_CTRL_LD_EXIST             0x400000
+#define TWSI_CTRL_READ_FREQ_SEL_MASK   0x3
+#define TWSI_CTRL_READ_FREQ_SEL_SHIFT  23
+#define TWSI_CTRL_FREQ_SEL_100K                0
+#define TWSI_CTRL_FREQ_SEL_200K                1
+#define TWSI_CTRL_FREQ_SEL_300K                2
+#define TWSI_CTRL_FREQ_SEL_400K                3
+#define TWSI_CTRL_SMB_SLV_ADDR         /* FIXME: define or remove */
+#define TWSI_CTRL_WRITE_FREQ_SEL_MASK  0x3
+#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24
+
+#define REG_PCIE_DEV_MISC_CTRL                 0x21C
+#define PCIE_DEV_MISC_CTRL_EXT_PIPE            0x2
+#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS                0x1
+#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST                0x4
+#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN       0x8
+#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN      0x10
+
+#define REG_PCIE_PHYMISC               0x1000
+#define PCIE_PHYMISC_FORCE_RCV_DET     0x4
+
+#define REG_PCIE_DLL_TX_CTRL1          0x1104
+#define PCIE_DLL_TX_CTRL1_SEL_NOR_CLK  0x400
+#define PCIE_DLL_TX_CTRL1_DEF          0x568
+
+#define REG_LTSSM_TEST_MODE            0x12FC
+#define LTSSM_TEST_MODE_DEF            0x6500
+
+/* Master Control Register */
+#define REG_MASTER_CTRL                        0x1400
+#define MASTER_CTRL_SOFT_RST           0x1
+#define MASTER_CTRL_MTIMER_EN          0x2
+#define MASTER_CTRL_ITIMER_EN          0x4
+#define MASTER_CTRL_MANUAL_INT         0x8
+#define MASTER_CTRL_REV_NUM_SHIFT      16
+#define MASTER_CTRL_REV_NUM_MASK       0xFF
+#define MASTER_CTRL_DEV_ID_SHIFT       24
+#define MASTER_CTRL_DEV_ID_MASK                0xFF
+
+/* Timer Initial Value Register */
+#define REG_MANUAL_TIMER_INIT          0x1404
+
+/* IRQ Moderator Timer Initial Value Register */
+#define REG_IRQ_MODU_TIMER_INIT                0x1408
+
+#define REG_PHY_ENABLE                 0x140C
+
+/* IRQ Anti-Lost Timer Initial Value Register */
+#define REG_CMBDISDMA_TIMER            0x140E
+
+/* Block IDLE Status Register */
+#define REG_IDLE_STATUS                        0x1410
+
+/* MDIO Control Register */
+#define REG_MDIO_CTRL                  0x1414
+#define MDIO_DATA_MASK                 0xFFFF
+#define MDIO_DATA_SHIFT                        0
+#define MDIO_REG_ADDR_MASK             0x1F
+#define MDIO_REG_ADDR_SHIFT            16
+#define MDIO_RW                                0x200000
+#define MDIO_SUP_PREAMBLE              0x400000
+#define MDIO_START                     0x800000
+#define MDIO_CLK_SEL_SHIFT             24
+#define MDIO_CLK_25_4                  0
+#define MDIO_CLK_25_6                  2
+#define MDIO_CLK_25_8                  3
+#define MDIO_CLK_25_10                 4
+#define MDIO_CLK_25_14                 5
+#define MDIO_CLK_25_20                 6
+#define MDIO_CLK_25_28                 7
+#define MDIO_BUSY                      0x8000000
+
+/* MII PHY Status Register */
+#define REG_PHY_STATUS                 0x1418
+
+/* BIST Control and Status Register0 (for the Packet Memory) */
+#define REG_BIST0_CTRL                 0x141C
+#define BIST0_NOW                      0x1
+#define BIST0_SRAM_FAIL                        0x2
+#define BIST0_FUSE_FLAG                        0x4
+#define REG_BIST1_CTRL                 0x1420
+#define BIST1_NOW                      0x1
+#define BIST1_SRAM_FAIL                        0x2
+#define BIST1_FUSE_FLAG                        0x4
+
+/* SerDes Lock Detect Control and Status Register */
+#define REG_SERDES_LOCK                        0x1424
+#define SERDES_LOCK_DETECT             1
+#define SERDES_LOCK_DETECT_EN          2
+
+/* MAC Control Register */
+#define REG_MAC_CTRL                   0x1480
+#define MAC_CTRL_TX_EN                 1
+#define MAC_CTRL_RX_EN                 2
+#define MAC_CTRL_TX_FLOW               4
+#define MAC_CTRL_RX_FLOW               8
+#define MAC_CTRL_LOOPBACK              0x10
+#define MAC_CTRL_DUPLX                 0x20
+#define MAC_CTRL_ADD_CRC               0x40
+#define MAC_CTRL_PAD                   0x80
+#define MAC_CTRL_LENCHK                        0x100
+#define MAC_CTRL_HUGE_EN               0x200
+#define MAC_CTRL_PRMLEN_SHIFT          10
+#define MAC_CTRL_PRMLEN_MASK           0xF
+#define MAC_CTRL_RMV_VLAN              0x4000
+#define MAC_CTRL_PROMIS_EN             0x8000
+#define MAC_CTRL_MC_ALL_EN             0x2000000
+#define MAC_CTRL_BC_EN                 0x4000000
+
+/* MAC IPG/IFG Control Register */
+#define REG_MAC_IPG_IFG                        0x1484
+#define MAC_IPG_IFG_IPGT_SHIFT         0
+#define MAC_IPG_IFG_IPGT_MASK          0x7F
+#define MAC_IPG_IFG_MIFG_SHIFT         8
+#define MAC_IPG_IFG_MIFG_MASK          0xFF
+#define MAC_IPG_IFG_IPGR1_SHIFT                16
+#define MAC_IPG_IFG_IPGR1_MASK         0x7F
+#define MAC_IPG_IFG_IPGR2_SHIFT                24
+#define MAC_IPG_IFG_IPGR2_MASK         0x7F
+
+/* MAC STATION ADDRESS */
+#define REG_MAC_STA_ADDR               0x1488
+
+/* Hash table for multicast address */
+#define REG_RX_HASH_TABLE              0x1490
+
+/* MAC Half-Duplex Control Register */
+#define REG_MAC_HALF_DUPLX_CTRL                        0x1498
+#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT         0
+#define MAC_HALF_DUPLX_CTRL_LCOL_MASK          0x3FF
+#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT                12
+#define MAC_HALF_DUPLX_CTRL_RETRY_MASK         0xF
+#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN         0x10000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_C          0x20000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_P          0x40000
+#define MAC_HALF_DUPLX_CTRL_ABEBE              0x80000
+#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT                20
+#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK         0xF
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT       24
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK                0xF
+
+/* Maximum Frame Length Control Register */
+#define REG_MTU                                0x149C
+
+/* Wake-On-Lan control register */
+#define REG_WOL_CTRL                   0x14A0
+#define WOL_PATTERN_EN                 0x1
+#define WOL_PATTERN_PME_EN             0x2
+#define WOL_MAGIC_EN                   0x4
+#define WOL_MAGIC_PME_EN               0x8
+#define WOL_LINK_CHG_EN                        0x10
+#define WOL_LINK_CHG_PME_EN            0x20
+#define WOL_PATTERN_ST                 0x100
+#define WOL_MAGIC_ST                   0x200
+#define WOL_LINKCHG_ST                 0x400
+#define WOL_PT0_EN                     0x10000
+#define WOL_PT1_EN                     0x20000
+#define WOL_PT2_EN                     0x40000
+#define WOL_PT3_EN                     0x80000
+#define WOL_PT4_EN                     0x100000
+#define WOL_PT0_MATCH                  0x1000000
+#define WOL_PT1_MATCH                  0x2000000
+#define WOL_PT2_MATCH                  0x4000000
+#define WOL_PT3_MATCH                  0x8000000
+#define WOL_PT4_MATCH                  0x10000000
+
+/* Internal SRAM Partition Register, high 32 bits */
+#define REG_SRAM_RFD_ADDR              0x1500
+
+/* Descriptor Control register, high 32 bits */
+#define REG_DESC_BASE_ADDR_HI          0x1540
+
+/* Interrupt Status Register */
+#define REG_ISR                                0x1600
+#define ISR_UR_DETECTED                        0x1000000
+#define ISR_FERR_DETECTED              0x2000000
+#define ISR_NFERR_DETECTED             0x4000000
+#define ISR_CERR_DETECTED              0x8000000
+#define ISR_PHY_LINKDOWN               0x10000000
+#define ISR_DIS_INT                    0x80000000
+
+/* Interrupt Mask Register */
+#define REG_IMR                                0x1604
+
+#define REG_RFD_RRD_IDX                        0x1800
+#define REG_TPD_IDX                    0x1804
+
+/* MII definitions */
+
+/* PHY Common Register */
+#define MII_ATLX_CR                    0x09
+#define MII_ATLX_SR                    0x0A
+#define MII_ATLX_ESR                   0x0F
+#define MII_ATLX_PSCR                  0x10
+#define MII_ATLX_PSSR                  0x11
+
+/* 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_MASK              0x2040
+#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  /* Ext 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 stat 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 */
+
+/* Link partner ability register */
+#define MII_LPA_SLCT                   0x001f  /* Same as advertise selector */
+#define MII_LPA_10HALF                 0x0020  /* Can do 10mbps half-duplex */
+#define MII_LPA_10FULL                 0x0040  /* Can do 10mbps full-duplex */
+#define MII_LPA_100HALF                        0x0080  /* Can do 100mbps half-duplex */
+#define MII_LPA_100FULL                        0x0100  /* Can do 100mbps full-duplex */
+#define MII_LPA_100BASE4               0x0200  /* 100BASE-T4 */
+#define MII_LPA_PAUSE                  0x0400  /* PAUSE */
+#define MII_LPA_ASYPAUSE               0x0800  /* Asymmetrical PAUSE */
+#define MII_LPA_RFAULT                 0x2000  /* Link partner faulted */
+#define MII_LPA_LPACK                  0x4000  /* Link partner acked us */
+#define MII_LPA_NPAGE                  0x8000  /* Next page bit */
+
+/* Autoneg Advertisement Register */
+#define MII_AR_SELECTOR_FIELD          0x0001  /* IEEE 802.3 CSMA/CD */
+#define MII_AR_10T_HD_CAPS             0x0020  /* 10T   Half Duplex Capable */
+#define MII_AR_10T_FD_CAPS             0x0040  /* 10T   Full Duplex Capable */
+#define MII_AR_100TX_HD_CAPS           0x0080  /* 100TX Half Duplex Capable */
+#define MII_AR_100TX_FD_CAPS           0x0100  /* 100TX Full Duplex Capable */
+#define MII_AR_100T4_CAPS              0x0200  /* 100T4 Capable */
+#define MII_AR_PAUSE                   0x0400  /* Pause operation desired */
+#define MII_AR_ASM_DIR                 0x0800  /* Asymmetric Pause Dir bit */
+#define MII_AR_REMOTE_FAULT            0x2000  /* Remote Fault detected */
+#define MII_AR_NEXT_PAGE               0x8000  /* Next Page ability support */
+#define MII_AR_SPEED_MASK              0x01E0
+#define MII_AR_DEFAULT_CAP_MASK                0x0DE0
+
+/* 1000BASE-T Control Register */
+#define MII_ATLX_CR_1000T_HD_CAPS      0x0100  /* Adv 1000T HD cap */
+#define MII_ATLX_CR_1000T_FD_CAPS      0x0200  /* Adv 1000T FD cap */
+#define MII_ATLX_CR_1000T_REPEATER_DTE 0x0400  /* 1=Repeater/switch device,
+                                                * 0=DTE device */
+#define MII_ATLX_CR_1000T_MS_VALUE     0x0800  /* 1=Config PHY as Master,
+                                                * 0=Configure PHY as Slave */
+#define MII_ATLX_CR_1000T_MS_ENABLE    0x1000  /* 1=Man Master/Slave config,
+                                                * 0=Auto Master/Slave config
+                                                */
+#define MII_ATLX_CR_1000T_TEST_MODE_NORMAL     0x0000  /* Normal Operation */
+#define MII_ATLX_CR_1000T_TEST_MODE_1  0x2000  /* Transmit Waveform test */
+#define MII_ATLX_CR_1000T_TEST_MODE_2  0x4000  /* Master Xmit Jitter test */
+#define MII_ATLX_CR_1000T_TEST_MODE_3  0x6000  /* Slave Xmit Jitter test */
+#define MII_ATLX_CR_1000T_TEST_MODE_4  0x8000  /* Xmitter Distortion test */
+#define MII_ATLX_CR_1000T_SPEED_MASK   0x0300
+#define MII_ATLX_CR_1000T_DEFAULT_CAP_MASK     0x0300
+
+/* 1000BASE-T Status Register */
+#define MII_ATLX_SR_1000T_LP_HD_CAPS   0x0400  /* LP is 1000T HD capable */
+#define MII_ATLX_SR_1000T_LP_FD_CAPS   0x0800  /* LP is 1000T FD capable */
+#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS     0x1000  /* Remote receiver OK */
+#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS      0x2000  /* Local receiver OK */
+#define MII_ATLX_SR_1000T_MS_CONFIG_RES                0x4000  /* 1=Local TX is Master
+                                                        * 0=Slave
+                                                        */
+#define MII_ATLX_SR_1000T_MS_CONFIG_FAULT      0x8000  /* Master/Slave config
+                                                        * fault */
+#define MII_ATLX_SR_1000T_REMOTE_RX_STATUS_SHIFT       12
+#define MII_ATLX_SR_1000T_LOCAL_RX_STATUS_SHIFT                13
+
+/* Extended Status Register */
+#define MII_ATLX_ESR_1000T_HD_CAPS     0x1000  /* 1000T HD capable */
+#define MII_ATLX_ESR_1000T_FD_CAPS     0x2000  /* 1000T FD capable */
+#define MII_ATLX_ESR_1000X_HD_CAPS     0x4000  /* 1000X HD capable */
+#define MII_ATLX_ESR_1000X_FD_CAPS     0x8000  /* 1000X FD capable */
+
+/* ATLX PHY Specific Control Register */
+#define MII_ATLX_PSCR_JABBER_DISABLE   0x0001  /* 1=Jabber Func disabled */
+#define MII_ATLX_PSCR_POLARITY_REVERSAL        0x0002  /* 1=Polarity Reversal enbld */
+#define MII_ATLX_PSCR_SQE_TEST         0x0004  /* 1=SQE Test enabled */
+#define MII_ATLX_PSCR_MAC_POWERDOWN    0x0008
+#define MII_ATLX_PSCR_CLK125_DISABLE   0x0010  /* 1=CLK125 low
+                                                * 0=CLK125 toggling
+                                                */
+#define MII_ATLX_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5,
+                                                * Manual MDI configuration
+                                                */
+#define MII_ATLX_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
+#define MII_ATLX_PSCR_AUTO_X_1000T     0x0040  /* 1000BASE-T: Auto crossover
+                                                * 100BASE-TX/10BASE-T: MDI
+                                                * Mode */
+#define MII_ATLX_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled
+                                                * all speeds.
+                                                */
+#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE     0x0080  /* 1=Enable Extended
+                                                        * 10BASE-T distance
+                                                        * (Lower 10BASE-T RX
+                                                        * Threshold)
+                                                        * 0=Normal 10BASE-T RX
+                                                        * Threshold
+                                                        */
+#define MII_ATLX_PSCR_MII_5BIT_ENABLE  0x0100  /* 1=5-Bit interface in
+                                                * 100BASE-TX
+                                                * 0=MII interface in
+                                                * 100BASE-TX
+                                                */
+#define MII_ATLX_PSCR_SCRAMBLER_DISABLE        0x0200  /* 1=Scrambler dsbl */
+#define MII_ATLX_PSCR_FORCE_LINK_GOOD  0x0400  /* 1=Force link good */
+#define MII_ATLX_PSCR_ASSERT_CRS_ON_TX 0x0800  /* 1=Assert CRS on Transmit */
+#define MII_ATLX_PSCR_POLARITY_REVERSAL_SHIFT          1
+#define MII_ATLX_PSCR_AUTO_X_MODE_SHIFT                        5
+#define MII_ATLX_PSCR_10BT_EXT_DIST_ENABLE_SHIFT       7
+
+/* ATLX PHY Specific Status Register */
+#define MII_ATLX_PSSR_SPD_DPLX_RESOLVED        0x0800  /* 1=Speed & Duplex resolved */
+#define MII_ATLX_PSSR_DPLX             0x2000  /* 1=Duplex 0=Half Duplex */
+#define MII_ATLX_PSSR_SPEED            0xC000  /* Speed, bits 14:15 */
+#define MII_ATLX_PSSR_10MBS            0x0000  /* 00=10Mbs */
+#define MII_ATLX_PSSR_100MBS           0x4000  /* 01=100Mbs */
+#define MII_ATLX_PSSR_1000MBS          0x8000  /* 10=1000Mbs */
+
+#define MII_DBG_ADDR                   0x1D
+#define MII_DBG_DATA                   0x1E
+
+/* PCI Command Register Bit Definitions */
+#define PCI_REG_COMMAND                        0x04    /* PCI Command Register */
+#define CMD_IO_SPACE                   0x0001
+#define CMD_MEMORY_SPACE               0x0002
+#define CMD_BUS_MASTER                 0x0004
+
+/* Wake Up Filter Control */
+#define ATLX_WUFC_LNKC 0x00000001      /* Link Status Change Wakeup Enable */
+#define ATLX_WUFC_MAG  0x00000002      /* Magic Packet Wakeup Enable */
+#define ATLX_WUFC_EX   0x00000004      /* Directed Exact Wakeup Enable */
+#define ATLX_WUFC_MC   0x00000008      /* Multicast Wakeup Enable */
+#define ATLX_WUFC_BC   0x00000010      /* Broadcast Wakeup Enable */
+
+#define ADVERTISE_10_HALF              0x0001
+#define ADVERTISE_10_FULL              0x0002
+#define ADVERTISE_100_HALF             0x0004
+#define ADVERTISE_100_FULL             0x0008
+#define ADVERTISE_1000_HALF            0x0010
+#define ADVERTISE_1000_FULL            0x0020
+#define AUTONEG_ADVERTISE_10_100_ALL   0x000F  /* All 10/100 speeds */
+#define AUTONEG_ADVERTISE_10_ALL       0x0003  /* 10Mbps Full & Half speeds */
+
+#define PHY_AUTO_NEG_TIME              45      /* 4.5 Seconds */
+#define PHY_FORCE_TIME                 20      /* 2.0 Seconds */
+
+/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA */
+#define EEPROM_SUM                     0xBABA
+#define NODE_ADDRESS_SIZE              6
+
+struct atlx_spi_flash_dev {
+       const char *manu_name;  /* manufacturer id */
+       /* op-code */
+       u8 cmd_wrsr;
+       u8 cmd_read;
+       u8 cmd_program;
+       u8 cmd_wren;
+       u8 cmd_wrdi;
+       u8 cmd_rdsr;
+       u8 cmd_rdid;
+       u8 cmd_sector_erase;
+       u8 cmd_chip_erase;
+};
+
+#endif /* ATLX_H */