Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 25 Oct 2011 11:25:22 +0000 (13:25 +0200)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 25 Oct 2011 11:25:22 +0000 (13:25 +0200)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1745 commits)
  dp83640: free packet queues on remove
  dp83640: use proper function to free transmit time stamping packets
  ipv6: Do not use routes from locally generated RAs
  |PATCH net-next] tg3: add tx_dropped counter
  be2net: don't create multiple RX/TX rings in multi channel mode
  be2net: don't create multiple TXQs in BE2
  be2net: refactor VF setup/teardown code into be_vf_setup/clear()
  be2net: add vlan/rx-mode/flow-control config to be_setup()
  net_sched: cls_flow: use skb_header_pointer()
  ipv4: avoid useless call of the function check_peer_pmtu
  TCP: remove TCP_DEBUG
  net: Fix driver name for mdio-gpio.c
  ipv4: tcp: fix TOS value in ACK messages sent from TIME_WAIT
  rtnetlink: Add missing manual netlink notification in dev_change_net_namespaces
  ipv4: fix ipsec forward performance regression
  jme: fix irq storm after suspend/resume
  route: fix ICMP redirect validation
  net: hold sock reference while processing tx timestamps
  tcp: md5: add more const attributes
  Add ethtool -g support to virtio_net
  ...

Fix up conflicts in:
 - drivers/net/Kconfig:
The split-up generated a trivial conflict with removal of a
stale reference to Documentation/networking/net-modules.txt.
Remove it from the new location instead.
 - fs/sysfs/dir.c:
Fairly nasty conflicts with the sysfs rb-tree usage, conflicting
with Eric Biederman's changes for tagged directories.

28 files changed:
1  2 
MAINTAINERS
drivers/net/ethernet/atheros/atlx/atl1.c
drivers/net/ethernet/broadcom/bnx2.h
drivers/net/ethernet/dec/tulip/21142.c
drivers/net/ethernet/dec/tulip/eeprom.c
drivers/net/ethernet/dec/tulip/interrupt.c
drivers/net/ethernet/dec/tulip/media.c
drivers/net/ethernet/dec/tulip/pnic.c
drivers/net/ethernet/dec/tulip/pnic2.c
drivers/net/ethernet/dec/tulip/timer.c
drivers/net/ethernet/dec/tulip/tulip.h
drivers/net/ethernet/dec/tulip/tulip_core.c
drivers/net/ethernet/intel/igb/e1000_mbx.c
drivers/net/ethernet/intel/igbvf/mbx.c
drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
drivers/net/ethernet/intel/ixgbevf/mbx.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/micrel/ks8695net.c
drivers/net/ethernet/smsc/Kconfig
drivers/net/ethernet/tile/tilepro.c
drivers/net/wireless/rtlwifi/pci.c
drivers/scsi/fcoe/fcoe.c
drivers/xen/xen-pciback/xenbus.c
fs/sysfs/dir.c
fs/sysfs/inode.c
include/linux/device.h
include/linux/netdevice.h
net/core/dev.c

diff --cc MAINTAINERS
Simple merge
index 0000000,0405261..33a4e35
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,3668 +1,3668 @@@
+ /*
+  * 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 */
++              /* enable GPHY LinkChange Interrupt */
+               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++) {
+               const struct skb_frag_struct *frag;
+               u16 i, nseg;
+               frag = &skb_shinfo(skb)->frags[f];
+               buf_len = skb_frag_size(frag);
+               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 = skb_frag_dma_map(&adapter->pdev->dev,
+                               frag, i * ATL1_MAX_TX_BUF_LEN,
+                               buffer_info->length, DMA_TO_DEVICE);
+                       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 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++) {
+               unsigned int f_size = skb_frag_size(&skb_shinfo(skb)->frags[f]);
+               count += (f_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_rx_mode        = 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_pending = rxdr->count;
+       ring->tx_pending = txdr->count;
+ }
+ 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,
+ };
index 0000000,fc50d42..99d31a7
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,7388 +1,7388 @@@
+ /* bnx2.h: Broadcom NX2 network driver.
+  *
+  * Copyright (c) 2004-2011 Broadcom Corporation
+  *
+  * 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.
+  *
+  * Written by: Michael Chan  (mchan@broadcom.com)
+  */
+ #ifndef BNX2_H
+ #define BNX2_H
+ /* Hardware data structures and register definitions automatically
+  * generated from RTL code. Do not modify.
+  */
+ /*
+  *  tx_bd definition
+  */
+ struct tx_bd {
+       u32 tx_bd_haddr_hi;
+       u32 tx_bd_haddr_lo;
+       u32 tx_bd_mss_nbytes;
+               #define TX_BD_TCP6_OFF2_SHL             (14)
+       u32 tx_bd_vlan_tag_flags;
+               #define TX_BD_FLAGS_CONN_FAULT          (1<<0)
+               #define TX_BD_FLAGS_TCP6_OFF0_MSK       (3<<1)
+               #define TX_BD_FLAGS_TCP6_OFF0_SHL       (1)
+               #define TX_BD_FLAGS_TCP_UDP_CKSUM       (1<<1)
+               #define TX_BD_FLAGS_IP_CKSUM            (1<<2)
+               #define TX_BD_FLAGS_VLAN_TAG            (1<<3)
+               #define TX_BD_FLAGS_COAL_NOW            (1<<4)
+               #define TX_BD_FLAGS_DONT_GEN_CRC        (1<<5)
+               #define TX_BD_FLAGS_END                 (1<<6)
+               #define TX_BD_FLAGS_START               (1<<7)
+               #define TX_BD_FLAGS_SW_OPTION_WORD      (0x1f<<8)
+               #define TX_BD_FLAGS_TCP6_OFF4_SHL       (12)
+               #define TX_BD_FLAGS_SW_FLAGS            (1<<13)
+               #define TX_BD_FLAGS_SW_SNAP             (1<<14)
+               #define TX_BD_FLAGS_SW_LSO              (1<<15)
+ };
+ /*
+  *  rx_bd definition
+  */
+ struct rx_bd {
+       u32 rx_bd_haddr_hi;
+       u32 rx_bd_haddr_lo;
+       u32 rx_bd_len;
+       u32 rx_bd_flags;
+               #define RX_BD_FLAGS_NOPUSH              (1<<0)
+               #define RX_BD_FLAGS_DUMMY               (1<<1)
+               #define RX_BD_FLAGS_END                 (1<<2)
+               #define RX_BD_FLAGS_START               (1<<3)
+ };
+ #define BNX2_RX_ALIGN                 16
+ /*
+  *  status_block definition
+  */
+ struct status_block {
+       u32 status_attn_bits;
+               #define STATUS_ATTN_BITS_LINK_STATE             (1L<<0)
+               #define STATUS_ATTN_BITS_TX_SCHEDULER_ABORT     (1L<<1)
+               #define STATUS_ATTN_BITS_TX_BD_READ_ABORT       (1L<<2)
+               #define STATUS_ATTN_BITS_TX_BD_CACHE_ABORT      (1L<<3)
+               #define STATUS_ATTN_BITS_TX_PROCESSOR_ABORT     (1L<<4)
+               #define STATUS_ATTN_BITS_TX_DMA_ABORT           (1L<<5)
+               #define STATUS_ATTN_BITS_TX_PATCHUP_ABORT       (1L<<6)
+               #define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT     (1L<<7)
+               #define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT    (1L<<8)
+               #define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT        (1L<<9)
+               #define STATUS_ATTN_BITS_RX_MBUF_ABORT          (1L<<10)
+               #define STATUS_ATTN_BITS_RX_LOOKUP_ABORT        (1L<<11)
+               #define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT     (1L<<12)
+               #define STATUS_ATTN_BITS_RX_V2P_ABORT           (1L<<13)
+               #define STATUS_ATTN_BITS_RX_BD_CACHE_ABORT      (1L<<14)
+               #define STATUS_ATTN_BITS_RX_DMA_ABORT           (1L<<15)
+               #define STATUS_ATTN_BITS_COMPLETION_ABORT       (1L<<16)
+               #define STATUS_ATTN_BITS_HOST_COALESCE_ABORT    (1L<<17)
+               #define STATUS_ATTN_BITS_MAILBOX_QUEUE_ABORT    (1L<<18)
+               #define STATUS_ATTN_BITS_CONTEXT_ABORT          (1L<<19)
+               #define STATUS_ATTN_BITS_CMD_SCHEDULER_ABORT    (1L<<20)
+               #define STATUS_ATTN_BITS_CMD_PROCESSOR_ABORT    (1L<<21)
+               #define STATUS_ATTN_BITS_MGMT_PROCESSOR_ABORT   (1L<<22)
+               #define STATUS_ATTN_BITS_MAC_ABORT              (1L<<23)
+               #define STATUS_ATTN_BITS_TIMER_ABORT            (1L<<24)
+               #define STATUS_ATTN_BITS_DMAE_ABORT             (1L<<25)
+               #define STATUS_ATTN_BITS_FLSH_ABORT             (1L<<26)
+               #define STATUS_ATTN_BITS_GRC_ABORT              (1L<<27)
+               #define STATUS_ATTN_BITS_EPB_ERROR              (1L<<30)
+               #define STATUS_ATTN_BITS_PARITY_ERROR           (1L<<31)
+       u32 status_attn_bits_ack;
+ #if defined(__BIG_ENDIAN)
+       u16 status_tx_quick_consumer_index0;
+       u16 status_tx_quick_consumer_index1;
+       u16 status_tx_quick_consumer_index2;
+       u16 status_tx_quick_consumer_index3;
+       u16 status_rx_quick_consumer_index0;
+       u16 status_rx_quick_consumer_index1;
+       u16 status_rx_quick_consumer_index2;
+       u16 status_rx_quick_consumer_index3;
+       u16 status_rx_quick_consumer_index4;
+       u16 status_rx_quick_consumer_index5;
+       u16 status_rx_quick_consumer_index6;
+       u16 status_rx_quick_consumer_index7;
+       u16 status_rx_quick_consumer_index8;
+       u16 status_rx_quick_consumer_index9;
+       u16 status_rx_quick_consumer_index10;
+       u16 status_rx_quick_consumer_index11;
+       u16 status_rx_quick_consumer_index12;
+       u16 status_rx_quick_consumer_index13;
+       u16 status_rx_quick_consumer_index14;
+       u16 status_rx_quick_consumer_index15;
+       u16 status_completion_producer_index;
+       u16 status_cmd_consumer_index;
+       u16 status_idx;
+       u8 status_unused;
+       u8 status_blk_num;
+ #elif defined(__LITTLE_ENDIAN)
+       u16 status_tx_quick_consumer_index1;
+       u16 status_tx_quick_consumer_index0;
+       u16 status_tx_quick_consumer_index3;
+       u16 status_tx_quick_consumer_index2;
+       u16 status_rx_quick_consumer_index1;
+       u16 status_rx_quick_consumer_index0;
+       u16 status_rx_quick_consumer_index3;
+       u16 status_rx_quick_consumer_index2;
+       u16 status_rx_quick_consumer_index5;
+       u16 status_rx_quick_consumer_index4;
+       u16 status_rx_quick_consumer_index7;
+       u16 status_rx_quick_consumer_index6;
+       u16 status_rx_quick_consumer_index9;
+       u16 status_rx_quick_consumer_index8;
+       u16 status_rx_quick_consumer_index11;
+       u16 status_rx_quick_consumer_index10;
+       u16 status_rx_quick_consumer_index13;
+       u16 status_rx_quick_consumer_index12;
+       u16 status_rx_quick_consumer_index15;
+       u16 status_rx_quick_consumer_index14;
+       u16 status_cmd_consumer_index;
+       u16 status_completion_producer_index;
+       u8 status_blk_num;
+       u8 status_unused;
+       u16 status_idx;
+ #endif
+ };
+ /*
+  *  status_block definition
+  */
+ struct status_block_msix {
+ #if defined(__BIG_ENDIAN)
+       u16 status_tx_quick_consumer_index;
+       u16 status_rx_quick_consumer_index;
+       u16 status_completion_producer_index;
+       u16 status_cmd_consumer_index;
+       u32 status_unused;
+       u16 status_idx;
+       u8 status_unused2;
+       u8 status_blk_num;
+ #elif defined(__LITTLE_ENDIAN)
+       u16 status_rx_quick_consumer_index;
+       u16 status_tx_quick_consumer_index;
+       u16 status_cmd_consumer_index;
+       u16 status_completion_producer_index;
+       u32 status_unused;
+       u8 status_blk_num;
+       u8 status_unused2;
+       u16 status_idx;
+ #endif
+ };
+ #define BNX2_SBLK_MSIX_ALIGN_SIZE     128
+ /*
+  *  statistics_block definition
+  */
+ struct statistics_block {
+       u32 stat_IfHCInOctets_hi;
+       u32 stat_IfHCInOctets_lo;
+       u32 stat_IfHCInBadOctets_hi;
+       u32 stat_IfHCInBadOctets_lo;
+       u32 stat_IfHCOutOctets_hi;
+       u32 stat_IfHCOutOctets_lo;
+       u32 stat_IfHCOutBadOctets_hi;
+       u32 stat_IfHCOutBadOctets_lo;
+       u32 stat_IfHCInUcastPkts_hi;
+       u32 stat_IfHCInUcastPkts_lo;
+       u32 stat_IfHCInMulticastPkts_hi;
+       u32 stat_IfHCInMulticastPkts_lo;
+       u32 stat_IfHCInBroadcastPkts_hi;
+       u32 stat_IfHCInBroadcastPkts_lo;
+       u32 stat_IfHCOutUcastPkts_hi;
+       u32 stat_IfHCOutUcastPkts_lo;
+       u32 stat_IfHCOutMulticastPkts_hi;
+       u32 stat_IfHCOutMulticastPkts_lo;
+       u32 stat_IfHCOutBroadcastPkts_hi;
+       u32 stat_IfHCOutBroadcastPkts_lo;
+       u32 stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
+       u32 stat_Dot3StatsCarrierSenseErrors;
+       u32 stat_Dot3StatsFCSErrors;
+       u32 stat_Dot3StatsAlignmentErrors;
+       u32 stat_Dot3StatsSingleCollisionFrames;
+       u32 stat_Dot3StatsMultipleCollisionFrames;
+       u32 stat_Dot3StatsDeferredTransmissions;
+       u32 stat_Dot3StatsExcessiveCollisions;
+       u32 stat_Dot3StatsLateCollisions;
+       u32 stat_EtherStatsCollisions;
+       u32 stat_EtherStatsFragments;
+       u32 stat_EtherStatsJabbers;
+       u32 stat_EtherStatsUndersizePkts;
+       u32 stat_EtherStatsOverrsizePkts;
+       u32 stat_EtherStatsPktsRx64Octets;
+       u32 stat_EtherStatsPktsRx65Octetsto127Octets;
+       u32 stat_EtherStatsPktsRx128Octetsto255Octets;
+       u32 stat_EtherStatsPktsRx256Octetsto511Octets;
+       u32 stat_EtherStatsPktsRx512Octetsto1023Octets;
+       u32 stat_EtherStatsPktsRx1024Octetsto1522Octets;
+       u32 stat_EtherStatsPktsRx1523Octetsto9022Octets;
+       u32 stat_EtherStatsPktsTx64Octets;
+       u32 stat_EtherStatsPktsTx65Octetsto127Octets;
+       u32 stat_EtherStatsPktsTx128Octetsto255Octets;
+       u32 stat_EtherStatsPktsTx256Octetsto511Octets;
+       u32 stat_EtherStatsPktsTx512Octetsto1023Octets;
+       u32 stat_EtherStatsPktsTx1024Octetsto1522Octets;
+       u32 stat_EtherStatsPktsTx1523Octetsto9022Octets;
+       u32 stat_XonPauseFramesReceived;
+       u32 stat_XoffPauseFramesReceived;
+       u32 stat_OutXonSent;
+       u32 stat_OutXoffSent;
+       u32 stat_FlowControlDone;
+       u32 stat_MacControlFramesReceived;
+       u32 stat_XoffStateEntered;
+       u32 stat_IfInFramesL2FilterDiscards;
+       u32 stat_IfInRuleCheckerDiscards;
+       u32 stat_IfInFTQDiscards;
+       u32 stat_IfInMBUFDiscards;
+       u32 stat_IfInRuleCheckerP4Hit;
+       u32 stat_CatchupInRuleCheckerDiscards;
+       u32 stat_CatchupInFTQDiscards;
+       u32 stat_CatchupInMBUFDiscards;
+       u32 stat_CatchupInRuleCheckerP4Hit;
+       u32 stat_GenStat00;
+       u32 stat_GenStat01;
+       u32 stat_GenStat02;
+       u32 stat_GenStat03;
+       u32 stat_GenStat04;
+       u32 stat_GenStat05;
+       u32 stat_GenStat06;
+       u32 stat_GenStat07;
+       u32 stat_GenStat08;
+       u32 stat_GenStat09;
+       u32 stat_GenStat10;
+       u32 stat_GenStat11;
+       u32 stat_GenStat12;
+       u32 stat_GenStat13;
+       u32 stat_GenStat14;
+       u32 stat_GenStat15;
+       u32 stat_FwRxDrop;
+ };
+ /*
+  *  l2_fhdr definition
+  */
+ struct l2_fhdr {
+       u32 l2_fhdr_status;
+               #define L2_FHDR_STATUS_RULE_CLASS       (0x7<<0)
+               #define L2_FHDR_STATUS_RULE_P2          (1<<3)
+               #define L2_FHDR_STATUS_RULE_P3          (1<<4)
+               #define L2_FHDR_STATUS_RULE_P4          (1<<5)
+               #define L2_FHDR_STATUS_L2_VLAN_TAG      (1<<6)
+               #define L2_FHDR_STATUS_L2_LLC_SNAP      (1<<7)
+               #define L2_FHDR_STATUS_RSS_HASH         (1<<8)
+               #define L2_FHDR_STATUS_IP_DATAGRAM      (1<<13)
+               #define L2_FHDR_STATUS_TCP_SEGMENT      (1<<14)
+               #define L2_FHDR_STATUS_UDP_DATAGRAM     (1<<15)
+               #define L2_FHDR_STATUS_SPLIT            (1<<16)
+               #define L2_FHDR_ERRORS_BAD_CRC          (1<<17)
+               #define L2_FHDR_ERRORS_PHY_DECODE       (1<<18)
+               #define L2_FHDR_ERRORS_ALIGNMENT        (1<<19)
+               #define L2_FHDR_ERRORS_TOO_SHORT        (1<<20)
+               #define L2_FHDR_ERRORS_GIANT_FRAME      (1<<21)
+               #define L2_FHDR_ERRORS_TCP_XSUM         (1<<28)
+               #define L2_FHDR_ERRORS_UDP_XSUM         (1<<31)
+               #define L2_FHDR_STATUS_USE_RXHASH       \
+                       (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_RSS_HASH)
+       u32 l2_fhdr_hash;
+ #if defined(__BIG_ENDIAN)
+       u16 l2_fhdr_pkt_len;
+       u16 l2_fhdr_vlan_tag;
+       u16 l2_fhdr_ip_xsum;
+       u16 l2_fhdr_tcp_udp_xsum;
+ #elif defined(__LITTLE_ENDIAN)
+       u16 l2_fhdr_vlan_tag;
+       u16 l2_fhdr_pkt_len;
+       u16 l2_fhdr_tcp_udp_xsum;
+       u16 l2_fhdr_ip_xsum;
+ #endif
+ };
+ #define BNX2_RX_OFFSET                (sizeof(struct l2_fhdr) + 2)
+ /*
+  *  l2_context definition
+  */
+ #define BNX2_L2CTX_TYPE                                       0x00000000
+ #define BNX2_L2CTX_TYPE_SIZE_L2                                ((0xc0/0x20)<<16)
+ #define BNX2_L2CTX_TYPE_TYPE                           (0xf<<28)
+ #define BNX2_L2CTX_TYPE_TYPE_EMPTY                     (0<<28)
+ #define BNX2_L2CTX_TYPE_TYPE_L2                                (1<<28)
+ #define BNX2_L2CTX_TX_HOST_BIDX                               0x00000088
+ #define BNX2_L2CTX_EST_NBD                            0x00000088
+ #define BNX2_L2CTX_CMD_TYPE                           0x00000088
+ #define BNX2_L2CTX_CMD_TYPE_TYPE                       (0xf<<24)
+ #define BNX2_L2CTX_CMD_TYPE_TYPE_L2                    (0<<24)
+ #define BNX2_L2CTX_CMD_TYPE_TYPE_TCP                   (1<<24)
+ #define BNX2_L2CTX_TX_HOST_BSEQ                               0x00000090
+ #define BNX2_L2CTX_TSCH_BSEQ                          0x00000094
+ #define BNX2_L2CTX_TBDR_BSEQ                          0x00000098
+ #define BNX2_L2CTX_TBDR_BOFF                          0x0000009c
+ #define BNX2_L2CTX_TBDR_BIDX                          0x0000009c
+ #define BNX2_L2CTX_TBDR_BHADDR_HI                     0x000000a0
+ #define BNX2_L2CTX_TBDR_BHADDR_LO                     0x000000a4
+ #define BNX2_L2CTX_TXP_BOFF                           0x000000a8
+ #define BNX2_L2CTX_TXP_BIDX                           0x000000a8
+ #define BNX2_L2CTX_TXP_BSEQ                           0x000000ac
+ #define BNX2_L2CTX_TYPE_XI                            0x00000080
+ #define BNX2_L2CTX_CMD_TYPE_XI                                0x00000240
+ #define BNX2_L2CTX_TBDR_BHADDR_HI_XI                  0x00000258
+ #define BNX2_L2CTX_TBDR_BHADDR_LO_XI                  0x0000025c
+ /*
+  *  l2_bd_chain_context definition
+  */
+ #define BNX2_L2CTX_BD_PRE_READ                                0x00000000
+ #define BNX2_L2CTX_CTX_SIZE                           0x00000000
+ #define BNX2_L2CTX_CTX_TYPE                           0x00000000
+ #define BNX2_L2CTX_FLOW_CTRL_ENABLE                    0x000000ff
+ #define BNX2_L2CTX_CTX_TYPE_SIZE_L2                    ((0x20/20)<<16)
+ #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE            (0xf<<28)
+ #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED  (0<<28)
+ #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE      (1<<28)
+ #define BNX2_L2CTX_HOST_BDIDX                         0x00000004
+ #define BNX2_L2CTX_L5_STATUSB_NUM_SHIFT                        16
+ #define BNX2_L2CTX_L2_STATUSB_NUM_SHIFT                        24
+ #define BNX2_L2CTX_L5_STATUSB_NUM(sb_id)              \
+       (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L5_STATUSB_NUM_SHIFT) : 0)
+ #define BNX2_L2CTX_L2_STATUSB_NUM(sb_id)              \
+       (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT) : 0)
+ #define BNX2_L2CTX_HOST_BSEQ                          0x00000008
+ #define BNX2_L2CTX_NX_BSEQ                            0x0000000c
+ #define BNX2_L2CTX_NX_BDHADDR_HI                      0x00000010
+ #define BNX2_L2CTX_NX_BDHADDR_LO                      0x00000014
+ #define BNX2_L2CTX_NX_BDIDX                           0x00000018
+ #define BNX2_L2CTX_HOST_PG_BDIDX                      0x00000044
+ #define BNX2_L2CTX_PG_BUF_SIZE                                0x00000048
+ #define BNX2_L2CTX_RBDC_KEY                           0x0000004c
+ #define BNX2_L2CTX_RBDC_JUMBO_KEY                      0x3ffe
+ #define BNX2_L2CTX_NX_PG_BDHADDR_HI                   0x00000050
+ #define BNX2_L2CTX_NX_PG_BDHADDR_LO                   0x00000054
+ /*
+  *  pci_config_l definition
+  *  offset: 0000
+  */
+ #define BNX2_PCICFG_MSI_CONTROL                               0x00000058
+ #define BNX2_PCICFG_MSI_CONTROL_ENABLE                         (1L<<16)
+ #define BNX2_PCICFG_MISC_CONFIG                               0x00000068
+ #define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP       (1L<<2)
+ #define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP    (1L<<3)
+ #define BNX2_PCICFG_MISC_CONFIG_RESERVED1              (1L<<4)
+ #define BNX2_PCICFG_MISC_CONFIG_CLOCK_CTL_ENA          (1L<<5)
+ #define BNX2_PCICFG_MISC_CONFIG_TARGET_GRC_WORD_SWAP   (1L<<6)
+ #define BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA                 (1L<<7)
+ #define BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ           (1L<<8)
+ #define BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY           (1L<<9)
+ #define BNX2_PCICFG_MISC_CONFIG_GRC_WIN1_SWAP_EN       (1L<<10)
+ #define BNX2_PCICFG_MISC_CONFIG_GRC_WIN2_SWAP_EN       (1L<<11)
+ #define BNX2_PCICFG_MISC_CONFIG_GRC_WIN3_SWAP_EN       (1L<<12)
+ #define BNX2_PCICFG_MISC_CONFIG_ASIC_METAL_REV                 (0xffL<<16)
+ #define BNX2_PCICFG_MISC_CONFIG_ASIC_BASE_REV          (0xfL<<24)
+ #define BNX2_PCICFG_MISC_CONFIG_ASIC_ID                        (0xfL<<28)
+ #define BNX2_PCICFG_MISC_STATUS                               0x0000006c
+ #define BNX2_PCICFG_MISC_STATUS_INTA_VALUE             (1L<<0)
+ #define BNX2_PCICFG_MISC_STATUS_32BIT_DET              (1L<<1)
+ #define BNX2_PCICFG_MISC_STATUS_M66EN                  (1L<<2)
+ #define BNX2_PCICFG_MISC_STATUS_PCIX_DET               (1L<<3)
+ #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED             (0x3L<<4)
+ #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_66          (0L<<4)
+ #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_100                 (1L<<4)
+ #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_133                 (2L<<4)
+ #define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_PCI_MODE    (3L<<4)
+ #define BNX2_PCICFG_MISC_STATUS_BAD_MEM_WRITE_BE       (1L<<8)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS            0x00000070
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET     (0xfL<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ       (0L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ       (1L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ       (2L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ       (3L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ       (4L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ       (5L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ       (6L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ      (7L<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW         (0xfL<<0)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE    (1L<<6)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT        (1L<<7)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC    (0x7L<<8)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF      (0L<<8)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12         (1L<<8)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6  (2L<<8)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62         (4L<<8)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_MIN_POWER   (1L<<11)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED  (0xfL<<12)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100      (0L<<12)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80       (1L<<12)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50       (2L<<12)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40       (4L<<12)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25       (8L<<12)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP   (1L<<16)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_17         (1L<<17)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_18         (1L<<18)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_19         (1L<<19)
+ #define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED    (0xfffL<<20)
+ #define BNX2_PCICFG_REG_WINDOW_ADDRESS                        0x00000078
+ #define BNX2_PCICFG_REG_WINDOW_ADDRESS_VAL             (0xfffffL<<2)
+ #define BNX2_PCICFG_REG_WINDOW                                0x00000080
+ #define BNX2_PCICFG_INT_ACK_CMD                               0x00000084
+ #define BNX2_PCICFG_INT_ACK_CMD_INDEX                  (0xffffL<<0)
+ #define BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID            (1L<<16)
+ #define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM       (1L<<17)
+ #define BNX2_PCICFG_INT_ACK_CMD_MASK_INT               (1L<<18)
+ #define BNX2_PCICFG_INT_ACK_CMD_INTERRUPT_NUM          (0xfL<<24)
+ #define BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT          24
+ #define BNX2_PCICFG_STATUS_BIT_SET_CMD                        0x00000088
+ #define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD              0x0000008c
+ #define BNX2_PCICFG_MAILBOX_QUEUE_ADDR                        0x00000090
+ #define BNX2_PCICFG_MAILBOX_QUEUE_DATA                        0x00000094
+ #define BNX2_PCICFG_DEVICE_CONTROL                    0x000000b4
+ #define BNX2_PCICFG_DEVICE_STATUS_NO_PEND              ((1L<<5)<<16)
+ /*
+  *  pci_reg definition
+  *  offset: 0x400
+  */
+ #define BNX2_PCI_GRC_WINDOW_ADDR                      0x00000400
+ #define BNX2_PCI_GRC_WINDOW_ADDR_VALUE                         (0x1ffL<<13)
+ #define BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN               (1L<<31)
+ #define BNX2_PCI_GRC_WINDOW2_BASE                      0xc000
+ #define BNX2_PCI_GRC_WINDOW3_BASE                      0xe000
+ #define BNX2_PCI_CONFIG_1                             0x00000404
+ #define BNX2_PCI_CONFIG_1_RESERVED0                    (0xffL<<0)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY                        (0x7L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_OFF            (0L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_16             (1L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_32             (2L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_64             (3L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_128            (4L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_256            (5L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_512            (6L<<8)
+ #define BNX2_PCI_CONFIG_1_READ_BOUNDARY_1024           (7L<<8)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY               (0x7L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_OFF           (0L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_16            (1L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_32            (2L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_64            (3L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_128           (4L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_256           (5L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_512           (6L<<11)
+ #define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_1024          (7L<<11)
+ #define BNX2_PCI_CONFIG_1_RESERVED1                    (0x3ffffL<<14)
+ #define BNX2_PCI_CONFIG_2                             0x00000408
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE                    (0xfL<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_DISABLED           (0L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_64K                        (1L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_128K               (2L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_256K               (3L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_512K               (4L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_1M                         (5L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_2M                         (6L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_4M                         (7L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_8M                         (8L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_16M                        (9L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_32M                        (10L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_64M                        (11L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_128M               (12L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_256M               (13L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_512M               (14L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_SIZE_1G                         (15L<<0)
+ #define BNX2_PCI_CONFIG_2_BAR1_64ENA                   (1L<<4)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_RETRY                        (1L<<5)
+ #define BNX2_PCI_CONFIG_2_CFG_CYCLE_RETRY              (1L<<6)
+ #define BNX2_PCI_CONFIG_2_FIRST_CFG_DONE               (1L<<7)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE                         (0xffL<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED                (0L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1K              (1L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2K              (2L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4K              (3L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8K              (4L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16K             (5L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_32K             (6L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_64K             (7L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_128K            (8L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_256K            (9L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_512K            (10L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1M              (11L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2M              (12L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4M              (13L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8M              (14L<<8)
+ #define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16M             (15L<<8)
+ #define BNX2_PCI_CONFIG_2_MAX_SPLIT_LIMIT              (0x1fL<<16)
+ #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT               (0x3L<<21)
+ #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_512           (0L<<21)
+ #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_1K            (1L<<21)
+ #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_2K            (2L<<21)
+ #define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_4K            (3L<<21)
+ #define BNX2_PCI_CONFIG_2_FORCE_32_BIT_MSTR            (1L<<23)
+ #define BNX2_PCI_CONFIG_2_FORCE_32_BIT_TGT             (1L<<24)
+ #define BNX2_PCI_CONFIG_2_KEEP_REQ_ASSERT              (1L<<25)
+ #define BNX2_PCI_CONFIG_2_RESERVED0                    (0x3fL<<26)
+ #define BNX2_PCI_CONFIG_2_BAR_PREFETCH_XI              (1L<<16)
+ #define BNX2_PCI_CONFIG_2_RESERVED0_XI                         (0x7fffL<<17)
+ #define BNX2_PCI_CONFIG_3                             0x0000040c
+ #define BNX2_PCI_CONFIG_3_STICKY_BYTE                  (0xffL<<0)
+ #define BNX2_PCI_CONFIG_3_REG_STICKY_BYTE              (0xffL<<8)
+ #define BNX2_PCI_CONFIG_3_FORCE_PME                    (1L<<24)
+ #define BNX2_PCI_CONFIG_3_PME_STATUS                   (1L<<25)
+ #define BNX2_PCI_CONFIG_3_PME_ENABLE                   (1L<<26)
+ #define BNX2_PCI_CONFIG_3_PM_STATE                     (0x3L<<27)
+ #define BNX2_PCI_CONFIG_3_VAUX_PRESET                  (1L<<30)
+ #define BNX2_PCI_CONFIG_3_PCI_POWER                    (1L<<31)
+ #define BNX2_PCI_PM_DATA_A                            0x00000410
+ #define BNX2_PCI_PM_DATA_A_PM_DATA_0_PRG               (0xffL<<0)
+ #define BNX2_PCI_PM_DATA_A_PM_DATA_1_PRG               (0xffL<<8)
+ #define BNX2_PCI_PM_DATA_A_PM_DATA_2_PRG               (0xffL<<16)
+ #define BNX2_PCI_PM_DATA_A_PM_DATA_3_PRG               (0xffL<<24)
+ #define BNX2_PCI_PM_DATA_B                            0x00000414
+ #define BNX2_PCI_PM_DATA_B_PM_DATA_4_PRG               (0xffL<<0)
+ #define BNX2_PCI_PM_DATA_B_PM_DATA_5_PRG               (0xffL<<8)
+ #define BNX2_PCI_PM_DATA_B_PM_DATA_6_PRG               (0xffL<<16)
+ #define BNX2_PCI_PM_DATA_B_PM_DATA_7_PRG               (0xffL<<24)
+ #define BNX2_PCI_SWAP_DIAG0                           0x00000418
+ #define BNX2_PCI_SWAP_DIAG1                           0x0000041c
+ #define BNX2_PCI_EXP_ROM_ADDR                         0x00000420
+ #define BNX2_PCI_EXP_ROM_ADDR_ADDRESS                  (0x3fffffL<<2)
+ #define BNX2_PCI_EXP_ROM_ADDR_REQ                      (1L<<31)
+ #define BNX2_PCI_EXP_ROM_DATA                         0x00000424
+ #define BNX2_PCI_VPD_INTF                             0x00000428
+ #define BNX2_PCI_VPD_INTF_INTF_REQ                     (1L<<0)
+ #define BNX2_PCI_VPD_ADDR_FLAG                                0x0000042c
+ #define BNX2_PCI_VPD_ADDR_FLAG_MSK                    0x0000ffff
+ #define BNX2_PCI_VPD_ADDR_FLAG_SL                     0L
+ #define BNX2_PCI_VPD_ADDR_FLAG_ADDRESS                         (0x1fffL<<2)
+ #define BNX2_PCI_VPD_ADDR_FLAG_WR                      (1L<<15)
+ #define BNX2_PCI_VPD_DATA                             0x00000430
+ #define BNX2_PCI_ID_VAL1                              0x00000434
+ #define BNX2_PCI_ID_VAL1_DEVICE_ID                     (0xffffL<<0)
+ #define BNX2_PCI_ID_VAL1_VENDOR_ID                     (0xffffL<<16)
+ #define BNX2_PCI_ID_VAL2                              0x00000438
+ #define BNX2_PCI_ID_VAL2_SUBSYSTEM_VENDOR_ID           (0xffffL<<0)
+ #define BNX2_PCI_ID_VAL2_SUBSYSTEM_ID                  (0xffffL<<16)
+ #define BNX2_PCI_ID_VAL3                              0x0000043c
+ #define BNX2_PCI_ID_VAL3_CLASS_CODE                    (0xffffffL<<0)
+ #define BNX2_PCI_ID_VAL3_REVISION_ID                   (0xffL<<24)
+ #define BNX2_PCI_ID_VAL4                              0x00000440
+ #define BNX2_PCI_ID_VAL4_CAP_ENA                       (0xfL<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_0                     (0L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_1                     (1L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_2                     (2L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_3                     (3L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_4                     (4L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_5                     (5L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_6                     (6L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_7                     (7L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_8                     (8L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_9                     (9L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_10                    (10L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_11                    (11L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_12                    (12L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_13                    (13L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_14                    (14L<<0)
+ #define BNX2_PCI_ID_VAL4_CAP_ENA_15                    (15L<<0)
+ #define BNX2_PCI_ID_VAL4_RESERVED0                     (0x3L<<4)
+ #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG                  (0x3L<<6)
+ #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_0                        (0L<<6)
+ #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_1                        (1L<<6)
+ #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_2                        (2L<<6)
+ #define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_3                        (3L<<6)
+ #define BNX2_PCI_ID_VAL4_MSI_PV_MASK_CAP               (1L<<8)
+ #define BNX2_PCI_ID_VAL4_MSI_LIMIT                     (0x7L<<9)
+ #define BNX2_PCI_ID_VAL4_MULTI_MSG_CAP                         (0x7L<<12)
+ #define BNX2_PCI_ID_VAL4_MSI_ENABLE                    (1L<<15)
+ #define BNX2_PCI_ID_VAL4_MAX_64_ADVERTIZE              (1L<<16)
+ #define BNX2_PCI_ID_VAL4_MAX_133_ADVERTIZE             (1L<<17)
+ #define BNX2_PCI_ID_VAL4_RESERVED2                     (0x7L<<18)
+ #define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE_B21       (0x3L<<21)
+ #define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE_B21            (0x3L<<23)
+ #define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE_B0                (1L<<25)
+ #define BNX2_PCI_ID_VAL4_MAX_MEM_READ_SIZE_B10                 (0x3L<<26)
+ #define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE_B0             (1L<<28)
+ #define BNX2_PCI_ID_VAL4_RESERVED3                     (0x7L<<29)
+ #define BNX2_PCI_ID_VAL4_RESERVED3_XI                  (0xffffL<<16)
+ #define BNX2_PCI_ID_VAL5                              0x00000444
+ #define BNX2_PCI_ID_VAL5_D1_SUPPORT                    (1L<<0)
+ #define BNX2_PCI_ID_VAL5_D2_SUPPORT                    (1L<<1)
+ #define BNX2_PCI_ID_VAL5_PME_IN_D0                     (1L<<2)
+ #define BNX2_PCI_ID_VAL5_PME_IN_D1                     (1L<<3)
+ #define BNX2_PCI_ID_VAL5_PME_IN_D2                     (1L<<4)
+ #define BNX2_PCI_ID_VAL5_PME_IN_D3_HOT                         (1L<<5)
+ #define BNX2_PCI_ID_VAL5_RESERVED0_TE                  (0x3ffffffL<<6)
+ #define BNX2_PCI_ID_VAL5_PM_VERSION_XI                         (0x7L<<6)
+ #define BNX2_PCI_ID_VAL5_NO_SOFT_RESET_XI              (1L<<9)
+ #define BNX2_PCI_ID_VAL5_RESERVED0_XI                  (0x3fffffL<<10)
+ #define BNX2_PCI_PCIX_EXTENDED_STATUS                 0x00000448
+ #define BNX2_PCI_PCIX_EXTENDED_STATUS_NO_SNOOP                 (1L<<8)
+ #define BNX2_PCI_PCIX_EXTENDED_STATUS_LONG_BURST       (1L<<9)
+ #define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_CLASS     (0xfL<<16)
+ #define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_IDX       (0xffL<<24)
+ #define BNX2_PCI_ID_VAL6                              0x0000044c
+ #define BNX2_PCI_ID_VAL6_MAX_LAT                       (0xffL<<0)
+ #define BNX2_PCI_ID_VAL6_MIN_GNT                       (0xffL<<8)
+ #define BNX2_PCI_ID_VAL6_BIST                          (0xffL<<16)
+ #define BNX2_PCI_ID_VAL6_RESERVED0                     (0xffL<<24)
+ #define BNX2_PCI_MSI_DATA                             0x00000450
+ #define BNX2_PCI_MSI_DATA_MSI_DATA                     (0xffffL<<0)
+ #define BNX2_PCI_MSI_ADDR_H                           0x00000454
+ #define BNX2_PCI_MSI_ADDR_L                           0x00000458
+ #define BNX2_PCI_MSI_ADDR_L_VAL                                (0x3fffffffL<<2)
+ #define BNX2_PCI_CFG_ACCESS_CMD                               0x0000045c
+ #define BNX2_PCI_CFG_ACCESS_CMD_ADR                    (0x3fL<<2)
+ #define BNX2_PCI_CFG_ACCESS_CMD_RD_REQ                         (1L<<27)
+ #define BNX2_PCI_CFG_ACCESS_CMD_WR_REQ                         (0xfL<<28)
+ #define BNX2_PCI_CFG_ACCESS_DATA                      0x00000460
+ #define BNX2_PCI_MSI_MASK                             0x00000464
+ #define BNX2_PCI_MSI_MASK_MSI_MASK                     (0xffffffffL<<0)
+ #define BNX2_PCI_MSI_PEND                             0x00000468
+ #define BNX2_PCI_MSI_PEND_MSI_PEND                     (0xffffffffL<<0)
+ #define BNX2_PCI_PM_DATA_C                            0x0000046c
+ #define BNX2_PCI_PM_DATA_C_PM_DATA_8_PRG               (0xffL<<0)
+ #define BNX2_PCI_PM_DATA_C_RESERVED0                   (0xffffffL<<8)
+ #define BNX2_PCI_MSIX_CONTROL                         0x000004c0
+ #define BNX2_PCI_MSIX_CONTROL_MSIX_TBL_SIZ             (0x7ffL<<0)
+ #define BNX2_PCI_MSIX_CONTROL_RESERVED0                        (0x1fffffL<<11)
+ #define BNX2_PCI_MSIX_TBL_OFF_BIR                     0x000004c4
+ #define BNX2_PCI_MSIX_TBL_OFF_BIR_MSIX_TBL_BIR                 (0x7L<<0)
+ #define BNX2_PCI_MSIX_TBL_OFF_BIR_MSIX_TBL_OFF                 (0x1fffffffL<<3)
+ #define BNX2_PCI_MSIX_PBA_OFF_BIT                     0x000004c8
+ #define BNX2_PCI_MSIX_PBA_OFF_BIT_MSIX_PBA_BIR                 (0x7L<<0)
+ #define BNX2_PCI_MSIX_PBA_OFF_BIT_MSIX_PBA_OFF                 (0x1fffffffL<<3)
+ #define BNX2_PCI_PCIE_CAPABILITY                      0x000004d0
+ #define BNX2_PCI_PCIE_CAPABILITY_INTERRUPT_MSG_NUM     (0x1fL<<0)
+ #define BNX2_PCI_PCIE_CAPABILITY_COMPLY_PCIE_1_1       (1L<<5)
+ #define BNX2_PCI_DEVICE_CAPABILITY                    0x000004d4
+ #define BNX2_PCI_DEVICE_CAPABILITY_MAX_PL_SIZ_SUPPORTED        (0x7L<<0)
+ #define BNX2_PCI_DEVICE_CAPABILITY_EXTENDED_TAG_SUPPORT        (1L<<5)
+ #define BNX2_PCI_DEVICE_CAPABILITY_L0S_ACCEPTABLE_LATENCY      (0x7L<<6)
+ #define BNX2_PCI_DEVICE_CAPABILITY_L1_ACCEPTABLE_LATENCY       (0x7L<<9)
+ #define BNX2_PCI_DEVICE_CAPABILITY_ROLE_BASED_ERR_RPT  (1L<<15)
+ #define BNX2_PCI_LINK_CAPABILITY                      0x000004dc
+ #define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_SPEED                (0xfL<<0)
+ #define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_SPEED_0001   (1L<<0)
+ #define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_SPEED_0010   (1L<<0)
+ #define BNX2_PCI_LINK_CAPABILITY_MAX_LINK_WIDTH                (0x1fL<<4)
+ #define BNX2_PCI_LINK_CAPABILITY_CLK_POWER_MGMT                (1L<<9)
+ #define BNX2_PCI_LINK_CAPABILITY_ASPM_SUPPORT          (0x3L<<10)
+ #define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_LAT          (0x7L<<12)
+ #define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_LAT_101      (5L<<12)
+ #define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_LAT_110      (6L<<12)
+ #define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_LAT           (0x7L<<15)
+ #define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_LAT_001       (1L<<15)
+ #define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_LAT_010       (2L<<15)
+ #define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_COMM_LAT     (0x7L<<18)
+ #define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_COMM_LAT_101         (5L<<18)
+ #define BNX2_PCI_LINK_CAPABILITY_L0S_EXIT_COMM_LAT_110         (6L<<18)
+ #define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_COMM_LAT      (0x7L<<21)
+ #define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_COMM_LAT_001  (1L<<21)
+ #define BNX2_PCI_LINK_CAPABILITY_L1_EXIT_COMM_LAT_010  (2L<<21)
+ #define BNX2_PCI_LINK_CAPABILITY_PORT_NUM              (0xffL<<24)
+ #define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2             0x000004e4
+ #define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2_CMPL_TO_RANGE_SUPP   (0xfL<<0)
+ #define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2_CMPL_TO_DISABL_SUPP  (1L<<4)
+ #define BNX2_PCI_PCIE_DEVICE_CAPABILITY_2_RESERVED     (0x7ffffffL<<5)
+ #define BNX2_PCI_PCIE_LINK_CAPABILITY_2                       0x000004e8
+ #define BNX2_PCI_PCIE_LINK_CAPABILITY_2_RESERVED       (0xffffffffL<<0)
+ #define BNX2_PCI_GRC_WINDOW1_ADDR                     0x00000610
+ #define BNX2_PCI_GRC_WINDOW1_ADDR_VALUE                        (0x1ffL<<13)
+ #define BNX2_PCI_GRC_WINDOW2_ADDR                     0x00000614
+ #define BNX2_PCI_GRC_WINDOW2_ADDR_VALUE                        (0x1ffL<<13)
+ #define BNX2_PCI_GRC_WINDOW3_ADDR                     0x00000618
+ #define BNX2_PCI_GRC_WINDOW3_ADDR_VALUE                        (0x1ffL<<13)
+ #define BNX2_MSIX_TABLE_ADDR                           0x318000
+ #define BNX2_MSIX_PBA_ADDR                             0x31c000
+ /*
+  *  misc_reg definition
+  *  offset: 0x800
+  */
+ #define BNX2_MISC_COMMAND                             0x00000800
+ #define BNX2_MISC_COMMAND_ENABLE_ALL                   (1L<<0)
+ #define BNX2_MISC_COMMAND_DISABLE_ALL                  (1L<<1)
+ #define BNX2_MISC_COMMAND_SW_RESET                     (1L<<4)
+ #define BNX2_MISC_COMMAND_POR_RESET                    (1L<<5)
+ #define BNX2_MISC_COMMAND_HD_RESET                     (1L<<6)
+ #define BNX2_MISC_COMMAND_CMN_SW_RESET                         (1L<<7)
+ #define BNX2_MISC_COMMAND_PAR_ERROR                    (1L<<8)
+ #define BNX2_MISC_COMMAND_CS16_ERR                     (1L<<9)
+ #define BNX2_MISC_COMMAND_CS16_ERR_LOC                         (0xfL<<12)
+ #define BNX2_MISC_COMMAND_PAR_ERR_RAM                  (0x7fL<<16)
+ #define BNX2_MISC_COMMAND_POWERDOWN_EVENT              (1L<<23)
+ #define BNX2_MISC_COMMAND_SW_SHUTDOWN                  (1L<<24)
+ #define BNX2_MISC_COMMAND_SHUTDOWN_EN                  (1L<<25)
+ #define BNX2_MISC_COMMAND_DINTEG_ATTN_EN               (1L<<26)
+ #define BNX2_MISC_COMMAND_PCIE_LINK_IN_L23             (1L<<27)
+ #define BNX2_MISC_COMMAND_PCIE_DIS                     (1L<<28)
+ #define BNX2_MISC_CFG                                 0x00000804
+ #define BNX2_MISC_CFG_GRC_TMOUT                                (1L<<0)
+ #define BNX2_MISC_CFG_NVM_WR_EN                                (0x3L<<1)
+ #define BNX2_MISC_CFG_NVM_WR_EN_PROTECT                        (0L<<1)
+ #define BNX2_MISC_CFG_NVM_WR_EN_PCI                    (1L<<1)
+ #define BNX2_MISC_CFG_NVM_WR_EN_ALLOW                  (2L<<1)
+ #define BNX2_MISC_CFG_NVM_WR_EN_ALLOW2                         (3L<<1)
+ #define BNX2_MISC_CFG_BIST_EN                          (1L<<3)
+ #define BNX2_MISC_CFG_CK25_OUT_ALT_SRC                         (1L<<4)
+ #define BNX2_MISC_CFG_RESERVED5_TE                     (1L<<5)
+ #define BNX2_MISC_CFG_RESERVED6_TE                     (1L<<6)
+ #define BNX2_MISC_CFG_CLK_CTL_OVERRIDE                         (1L<<7)
+ #define BNX2_MISC_CFG_LEDMODE                          (0x7L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_MAC                      (0L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY1_TE                  (1L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY2_TE                  (2L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY3_TE                  (3L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY4_TE                  (4L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY5_TE                  (5L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY6_TE                  (6L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY7_TE                  (7L<<8)
+ #define BNX2_MISC_CFG_MCP_GRC_TMOUT_TE                         (1L<<11)
+ #define BNX2_MISC_CFG_DBU_GRC_TMOUT_TE                         (1L<<12)
+ #define BNX2_MISC_CFG_LEDMODE_XI                       (0xfL<<8)
+ #define BNX2_MISC_CFG_LEDMODE_MAC_XI                   (0L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY1_XI                  (1L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY2_XI                  (2L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY3_XI                  (3L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_MAC2_XI                  (4L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY4_XI                  (5L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY5_XI                  (6L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY6_XI                  (7L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_MAC3_XI                  (8L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY7_XI                  (9L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY8_XI                  (10L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY9_XI                  (11L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_MAC4_XI                  (12L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY10_XI                         (13L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_PHY11_XI                         (14L<<8)
+ #define BNX2_MISC_CFG_LEDMODE_UNUSED_XI                        (15L<<8)
+ #define BNX2_MISC_CFG_PORT_SELECT_XI                   (1L<<13)
+ #define BNX2_MISC_CFG_PARITY_MODE_XI                   (1L<<14)
+ #define BNX2_MISC_ID                                  0x00000808
+ #define BNX2_MISC_ID_BOND_ID                           (0xfL<<0)
+ #define BNX2_MISC_ID_BOND_ID_X                                 (0L<<0)
+ #define BNX2_MISC_ID_BOND_ID_C                                 (3L<<0)
+ #define BNX2_MISC_ID_BOND_ID_S                                 (12L<<0)
+ #define BNX2_MISC_ID_CHIP_METAL                                (0xffL<<4)
+ #define BNX2_MISC_ID_CHIP_REV                          (0xfL<<12)
+ #define BNX2_MISC_ID_CHIP_NUM                          (0xffffL<<16)
+ #define BNX2_MISC_ENABLE_STATUS_BITS                  0x0000080c
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_SCHEDULER_ENABLE       (1L<<0)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_READ_ENABLE         (1L<<1)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_CACHE_ENABLE        (1L<<2)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_PROCESSOR_ENABLE       (1L<<3)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_DMA_ENABLE     (1L<<4)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_PATCHUP_ENABLE         (1L<<5)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_PAYLOAD_Q_ENABLE       (1L<<6)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_HEADER_Q_ENABLE        (1L<<7)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TX_ASSEMBLER_ENABLE       (1L<<8)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_EMAC_ENABLE       (1L<<9)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_MAC_ENABLE      (1L<<10)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_CATCHUP_ENABLE  (1L<<11)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_MBUF_ENABLE    (1L<<12)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_LOOKUP_ENABLE  (1L<<13)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_PROCESSOR_ENABLE       (1L<<14)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE     (1L<<15)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_BD_CACHE_ENABLE        (1L<<16)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RX_DMA_ENABLE     (1L<<17)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_COMPLETION_ENABLE         (1L<<18)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_HOST_COALESCE_ENABLE      (1L<<19)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_MAILBOX_QUEUE_ENABLE      (1L<<20)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE    (1L<<21)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_CMD_SCHEDULER_ENABLE      (1L<<22)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_CMD_PROCESSOR_ENABLE      (1L<<23)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_MGMT_PROCESSOR_ENABLE     (1L<<24)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_TIMER_ENABLE      (1L<<25)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_DMA_ENGINE_ENABLE         (1L<<26)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_UMP_ENABLE                (1L<<27)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RV2P_CMD_SCHEDULER_ENABLE         (1L<<28)
+ #define BNX2_MISC_ENABLE_STATUS_BITS_RSVD_FUTURE_ENABLE        (0x7L<<29)
+ #define BNX2_MISC_ENABLE_SET_BITS                     0x00000810
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_SCHEDULER_ENABLE  (1L<<0)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_BD_READ_ENABLE    (1L<<1)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_BD_CACHE_ENABLE   (1L<<2)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_PROCESSOR_ENABLE  (1L<<3)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_DMA_ENABLE                (1L<<4)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_PATCHUP_ENABLE    (1L<<5)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_PAYLOAD_Q_ENABLE  (1L<<6)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE   (1L<<7)
+ #define BNX2_MISC_ENABLE_SET_BITS_TX_ASSEMBLER_ENABLE  (1L<<8)
+ #define BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE          (1L<<9)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE         (1L<<10)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_CATCHUP_ENABLE     (1L<<11)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE       (1L<<12)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_LOOKUP_ENABLE     (1L<<13)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_PROCESSOR_ENABLE  (1L<<14)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_V2P_ENABLE                (1L<<15)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_BD_CACHE_ENABLE   (1L<<16)
+ #define BNX2_MISC_ENABLE_SET_BITS_RX_DMA_ENABLE                (1L<<17)
+ #define BNX2_MISC_ENABLE_SET_BITS_COMPLETION_ENABLE    (1L<<18)
+ #define BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE         (1L<<19)
+ #define BNX2_MISC_ENABLE_SET_BITS_MAILBOX_QUEUE_ENABLE         (1L<<20)
+ #define BNX2_MISC_ENABLE_SET_BITS_CONTEXT_ENABLE       (1L<<21)
+ #define BNX2_MISC_ENABLE_SET_BITS_CMD_SCHEDULER_ENABLE         (1L<<22)
+ #define BNX2_MISC_ENABLE_SET_BITS_CMD_PROCESSOR_ENABLE         (1L<<23)
+ #define BNX2_MISC_ENABLE_SET_BITS_MGMT_PROCESSOR_ENABLE        (1L<<24)
+ #define BNX2_MISC_ENABLE_SET_BITS_TIMER_ENABLE                 (1L<<25)
+ #define BNX2_MISC_ENABLE_SET_BITS_DMA_ENGINE_ENABLE    (1L<<26)
+ #define BNX2_MISC_ENABLE_SET_BITS_UMP_ENABLE           (1L<<27)
+ #define BNX2_MISC_ENABLE_SET_BITS_RV2P_CMD_SCHEDULER_ENABLE    (1L<<28)
+ #define BNX2_MISC_ENABLE_SET_BITS_RSVD_FUTURE_ENABLE   (0x7L<<29)
+ #define BNX2_MISC_ENABLE_CLR_BITS                     0x00000814
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_SCHEDULER_ENABLE  (1L<<0)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_READ_ENABLE    (1L<<1)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_CACHE_ENABLE   (1L<<2)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_PROCESSOR_ENABLE  (1L<<3)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE                (1L<<4)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_PATCHUP_ENABLE    (1L<<5)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_PAYLOAD_Q_ENABLE  (1L<<6)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_HEADER_Q_ENABLE   (1L<<7)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TX_ASSEMBLER_ENABLE  (1L<<8)
+ #define BNX2_MISC_ENABLE_CLR_BITS_EMAC_ENABLE          (1L<<9)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_MAC_ENABLE         (1L<<10)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_CATCHUP_ENABLE     (1L<<11)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_MBUF_ENABLE       (1L<<12)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_LOOKUP_ENABLE     (1L<<13)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_PROCESSOR_ENABLE  (1L<<14)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_V2P_ENABLE                (1L<<15)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_BD_CACHE_ENABLE   (1L<<16)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE                (1L<<17)
+ #define BNX2_MISC_ENABLE_CLR_BITS_COMPLETION_ENABLE    (1L<<18)
+ #define BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE         (1L<<19)
+ #define BNX2_MISC_ENABLE_CLR_BITS_MAILBOX_QUEUE_ENABLE         (1L<<20)
+ #define BNX2_MISC_ENABLE_CLR_BITS_CONTEXT_ENABLE       (1L<<21)
+ #define BNX2_MISC_ENABLE_CLR_BITS_CMD_SCHEDULER_ENABLE         (1L<<22)
+ #define BNX2_MISC_ENABLE_CLR_BITS_CMD_PROCESSOR_ENABLE         (1L<<23)
+ #define BNX2_MISC_ENABLE_CLR_BITS_MGMT_PROCESSOR_ENABLE        (1L<<24)
+ #define BNX2_MISC_ENABLE_CLR_BITS_TIMER_ENABLE                 (1L<<25)
+ #define BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE    (1L<<26)
+ #define BNX2_MISC_ENABLE_CLR_BITS_UMP_ENABLE           (1L<<27)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RV2P_CMD_SCHEDULER_ENABLE    (1L<<28)
+ #define BNX2_MISC_ENABLE_CLR_BITS_RSVD_FUTURE_ENABLE   (0x7L<<29)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS                  0x00000818
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET   (0xfL<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ     (0L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ     (1L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ     (2L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ     (3L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ     (4L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ     (5L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ     (6L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ    (7L<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW       (0xfL<<0)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE  (1L<<6)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT      (1L<<7)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC  (0x7L<<8)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF    (0L<<8)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12       (1L<<8)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6        (2L<<8)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62       (4L<<8)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED0_XI      (0x7L<<8)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_MIN_POWER                 (1L<<11)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED        (0xfL<<12)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100    (0L<<12)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80     (1L<<12)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50     (2L<<12)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40     (4L<<12)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25     (8L<<12)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED1_XI      (0xfL<<12)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP         (1L<<16)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_17_TE    (1L<<17)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_18_TE    (1L<<18)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_19_TE    (1L<<19)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_TE       (0xfffL<<20)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_MGMT_XI      (1L<<17)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED2_XI      (0x3fL<<18)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_VCO_XI       (0x7L<<24)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED3_XI      (1L<<27)
+ #define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_XI     (0xfL<<28)
+ #define BNX2_MISC_SPIO                                        0x0000081c
+ #define BNX2_MISC_SPIO_VALUE                           (0xffL<<0)
+ #define BNX2_MISC_SPIO_SET                             (0xffL<<8)
+ #define BNX2_MISC_SPIO_CLR                             (0xffL<<16)
+ #define BNX2_MISC_SPIO_FLOAT                           (0xffL<<24)
+ #define BNX2_MISC_SPIO_INT                            0x00000820
+ #define BNX2_MISC_SPIO_INT_INT_STATE_TE                        (0xfL<<0)
+ #define BNX2_MISC_SPIO_INT_OLD_VALUE_TE                        (0xfL<<8)
+ #define BNX2_MISC_SPIO_INT_OLD_SET_TE                  (0xfL<<16)
+ #define BNX2_MISC_SPIO_INT_OLD_CLR_TE                  (0xfL<<24)
+ #define BNX2_MISC_SPIO_INT_INT_STATE_XI                        (0xffL<<0)
+ #define BNX2_MISC_SPIO_INT_OLD_VALUE_XI                        (0xffL<<8)
+ #define BNX2_MISC_SPIO_INT_OLD_SET_XI                  (0xffL<<16)
+ #define BNX2_MISC_SPIO_INT_OLD_CLR_XI                  (0xffL<<24)
+ #define BNX2_MISC_CONFIG_LFSR                         0x00000824
+ #define BNX2_MISC_CONFIG_LFSR_DIV                      (0xffffL<<0)
+ #define BNX2_MISC_LFSR_MASK_BITS                      0x00000828
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_SCHEDULER_ENABLE   (1L<<0)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_BD_READ_ENABLE     (1L<<1)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_BD_CACHE_ENABLE    (1L<<2)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_PROCESSOR_ENABLE   (1L<<3)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_DMA_ENABLE                 (1L<<4)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_PATCHUP_ENABLE     (1L<<5)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_PAYLOAD_Q_ENABLE   (1L<<6)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_HEADER_Q_ENABLE    (1L<<7)
+ #define BNX2_MISC_LFSR_MASK_BITS_TX_ASSEMBLER_ENABLE   (1L<<8)
+ #define BNX2_MISC_LFSR_MASK_BITS_EMAC_ENABLE           (1L<<9)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_MAC_ENABLE  (1L<<10)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_CATCHUP_ENABLE      (1L<<11)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_MBUF_ENABLE                (1L<<12)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_LOOKUP_ENABLE      (1L<<13)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_PROCESSOR_ENABLE   (1L<<14)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_V2P_ENABLE                 (1L<<15)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_BD_CACHE_ENABLE    (1L<<16)
+ #define BNX2_MISC_LFSR_MASK_BITS_RX_DMA_ENABLE                 (1L<<17)
+ #define BNX2_MISC_LFSR_MASK_BITS_COMPLETION_ENABLE     (1L<<18)
+ #define BNX2_MISC_LFSR_MASK_BITS_HOST_COALESCE_ENABLE  (1L<<19)
+ #define BNX2_MISC_LFSR_MASK_BITS_MAILBOX_QUEUE_ENABLE  (1L<<20)
+ #define BNX2_MISC_LFSR_MASK_BITS_CONTEXT_ENABLE                (1L<<21)
+ #define BNX2_MISC_LFSR_MASK_BITS_CMD_SCHEDULER_ENABLE  (1L<<22)
+ #define BNX2_MISC_LFSR_MASK_BITS_CMD_PROCESSOR_ENABLE  (1L<<23)
+ #define BNX2_MISC_LFSR_MASK_BITS_MGMT_PROCESSOR_ENABLE         (1L<<24)
+ #define BNX2_MISC_LFSR_MASK_BITS_TIMER_ENABLE          (1L<<25)
+ #define BNX2_MISC_LFSR_MASK_BITS_DMA_ENGINE_ENABLE     (1L<<26)
+ #define BNX2_MISC_LFSR_MASK_BITS_UMP_ENABLE            (1L<<27)
+ #define BNX2_MISC_LFSR_MASK_BITS_RV2P_CMD_SCHEDULER_ENABLE     (1L<<28)
+ #define BNX2_MISC_LFSR_MASK_BITS_RSVD_FUTURE_ENABLE    (0x7L<<29)
+ #define BNX2_MISC_ARB_REQ0                            0x0000082c
+ #define BNX2_MISC_ARB_REQ1                            0x00000830
+ #define BNX2_MISC_ARB_REQ2                            0x00000834
+ #define BNX2_MISC_ARB_REQ3                            0x00000838
+ #define BNX2_MISC_ARB_REQ4                            0x0000083c
+ #define BNX2_MISC_ARB_FREE0                           0x00000840
+ #define BNX2_MISC_ARB_FREE1                           0x00000844
+ #define BNX2_MISC_ARB_FREE2                           0x00000848
+ #define BNX2_MISC_ARB_FREE3                           0x0000084c
+ #define BNX2_MISC_ARB_FREE4                           0x00000850
+ #define BNX2_MISC_ARB_REQ_STATUS0                     0x00000854
+ #define BNX2_MISC_ARB_REQ_STATUS1                     0x00000858
+ #define BNX2_MISC_ARB_REQ_STATUS2                     0x0000085c
+ #define BNX2_MISC_ARB_REQ_STATUS3                     0x00000860
+ #define BNX2_MISC_ARB_REQ_STATUS4                     0x00000864
+ #define BNX2_MISC_ARB_GNT0                            0x00000868
+ #define BNX2_MISC_ARB_GNT0_0                           (0x7L<<0)
+ #define BNX2_MISC_ARB_GNT0_1                           (0x7L<<4)
+ #define BNX2_MISC_ARB_GNT0_2                           (0x7L<<8)
+ #define BNX2_MISC_ARB_GNT0_3                           (0x7L<<12)
+ #define BNX2_MISC_ARB_GNT0_4                           (0x7L<<16)
+ #define BNX2_MISC_ARB_GNT0_5                           (0x7L<<20)
+ #define BNX2_MISC_ARB_GNT0_6                           (0x7L<<24)
+ #define BNX2_MISC_ARB_GNT0_7                           (0x7L<<28)
+ #define BNX2_MISC_ARB_GNT1                            0x0000086c
+ #define BNX2_MISC_ARB_GNT1_8                           (0x7L<<0)
+ #define BNX2_MISC_ARB_GNT1_9                           (0x7L<<4)
+ #define BNX2_MISC_ARB_GNT1_10                          (0x7L<<8)
+ #define BNX2_MISC_ARB_GNT1_11                          (0x7L<<12)
+ #define BNX2_MISC_ARB_GNT1_12                          (0x7L<<16)
+ #define BNX2_MISC_ARB_GNT1_13                          (0x7L<<20)
+ #define BNX2_MISC_ARB_GNT1_14                          (0x7L<<24)
+ #define BNX2_MISC_ARB_GNT1_15                          (0x7L<<28)
+ #define BNX2_MISC_ARB_GNT2                            0x00000870
+ #define BNX2_MISC_ARB_GNT2_16                          (0x7L<<0)
+ #define BNX2_MISC_ARB_GNT2_17                          (0x7L<<4)
+ #define BNX2_MISC_ARB_GNT2_18                          (0x7L<<8)
+ #define BNX2_MISC_ARB_GNT2_19                          (0x7L<<12)
+ #define BNX2_MISC_ARB_GNT2_20                          (0x7L<<16)
+ #define BNX2_MISC_ARB_GNT2_21                          (0x7L<<20)
+ #define BNX2_MISC_ARB_GNT2_22                          (0x7L<<24)
+ #define BNX2_MISC_ARB_GNT2_23                          (0x7L<<28)
+ #define BNX2_MISC_ARB_GNT3                            0x00000874
+ #define BNX2_MISC_ARB_GNT3_24                          (0x7L<<0)
+ #define BNX2_MISC_ARB_GNT3_25                          (0x7L<<4)
+ #define BNX2_MISC_ARB_GNT3_26                          (0x7L<<8)
+ #define BNX2_MISC_ARB_GNT3_27                          (0x7L<<12)
+ #define BNX2_MISC_ARB_GNT3_28                          (0x7L<<16)
+ #define BNX2_MISC_ARB_GNT3_29                          (0x7L<<20)
+ #define BNX2_MISC_ARB_GNT3_30                          (0x7L<<24)
+ #define BNX2_MISC_ARB_GNT3_31                          (0x7L<<28)
+ #define BNX2_MISC_RESERVED1                           0x00000878
+ #define BNX2_MISC_RESERVED1_MISC_RESERVED1_VALUE       (0x3fL<<0)
+ #define BNX2_MISC_RESERVED2                           0x0000087c
+ #define BNX2_MISC_RESERVED2_PCIE_DIS                   (1L<<0)
+ #define BNX2_MISC_RESERVED2_LINK_IN_L23                        (1L<<1)
+ #define BNX2_MISC_SM_ASF_CONTROL                      0x00000880
+ #define BNX2_MISC_SM_ASF_CONTROL_ASF_RST               (1L<<0)
+ #define BNX2_MISC_SM_ASF_CONTROL_TSC_EN                        (1L<<1)
+ #define BNX2_MISC_SM_ASF_CONTROL_WG_TO                         (1L<<2)
+ #define BNX2_MISC_SM_ASF_CONTROL_HB_TO                         (1L<<3)
+ #define BNX2_MISC_SM_ASF_CONTROL_PA_TO                         (1L<<4)
+ #define BNX2_MISC_SM_ASF_CONTROL_PL_TO                         (1L<<5)
+ #define BNX2_MISC_SM_ASF_CONTROL_RT_TO                         (1L<<6)
+ #define BNX2_MISC_SM_ASF_CONTROL_SMB_EVENT             (1L<<7)
+ #define BNX2_MISC_SM_ASF_CONTROL_STRETCH_EN            (1L<<8)
+ #define BNX2_MISC_SM_ASF_CONTROL_STRETCH_PULSE                 (1L<<9)
+ #define BNX2_MISC_SM_ASF_CONTROL_RES                   (0x3L<<10)
+ #define BNX2_MISC_SM_ASF_CONTROL_SMB_EN                        (1L<<12)
+ #define BNX2_MISC_SM_ASF_CONTROL_SMB_BB_EN             (1L<<13)
+ #define BNX2_MISC_SM_ASF_CONTROL_SMB_NO_ADDR_FILT      (1L<<14)
+ #define BNX2_MISC_SM_ASF_CONTROL_SMB_AUTOREAD          (1L<<15)
+ #define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR1                 (0x7fL<<16)
+ #define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR2                 (0x7fL<<23)
+ #define BNX2_MISC_SM_ASF_CONTROL_EN_NIC_SMB_ADDR_0     (1L<<30)
+ #define BNX2_MISC_SM_ASF_CONTROL_SMB_EARLY_ATTN                (1L<<31)
+ #define BNX2_MISC_SMB_IN                              0x00000884
+ #define BNX2_MISC_SMB_IN_DAT_IN                                (0xffL<<0)
+ #define BNX2_MISC_SMB_IN_RDY                           (1L<<8)
+ #define BNX2_MISC_SMB_IN_DONE                          (1L<<9)
+ #define BNX2_MISC_SMB_IN_FIRSTBYTE                     (1L<<10)
+ #define BNX2_MISC_SMB_IN_STATUS                                (0x7L<<11)
+ #define BNX2_MISC_SMB_IN_STATUS_OK                     (0x0L<<11)
+ #define BNX2_MISC_SMB_IN_STATUS_PEC                    (0x1L<<11)
+ #define BNX2_MISC_SMB_IN_STATUS_OFLOW                  (0x2L<<11)
+ #define BNX2_MISC_SMB_IN_STATUS_STOP                   (0x3L<<11)
+ #define BNX2_MISC_SMB_IN_STATUS_TIMEOUT                        (0x4L<<11)
+ #define BNX2_MISC_SMB_OUT                             0x00000888
+ #define BNX2_MISC_SMB_OUT_DAT_OUT                      (0xffL<<0)
+ #define BNX2_MISC_SMB_OUT_RDY                          (1L<<8)
+ #define BNX2_MISC_SMB_OUT_START                                (1L<<9)
+ #define BNX2_MISC_SMB_OUT_LAST                                 (1L<<10)
+ #define BNX2_MISC_SMB_OUT_ACC_TYPE                     (1L<<11)
+ #define BNX2_MISC_SMB_OUT_ENB_PEC                      (1L<<12)
+ #define BNX2_MISC_SMB_OUT_GET_RX_LEN                   (1L<<13)
+ #define BNX2_MISC_SMB_OUT_SMB_READ_LEN                         (0x3fL<<14)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS               (0xfL<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_OK            (0L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_NACK    (1L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_UFLOW                 (2L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_STOP          (3L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_TIMEOUT       (4L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_LOST    (5L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_BADACK                (6L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_NACK      (9L<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_LOST      (0xdL<<20)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_SLAVEMODE            (1L<<24)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_EN               (1L<<25)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_IN               (1L<<26)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_EN               (1L<<27)
+ #define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_IN               (1L<<28)
+ #define BNX2_MISC_SMB_WATCHDOG                                0x0000088c
+ #define BNX2_MISC_SMB_WATCHDOG_WATCHDOG                        (0xffffL<<0)
+ #define BNX2_MISC_SMB_HEARTBEAT                               0x00000890
+ #define BNX2_MISC_SMB_HEARTBEAT_HEARTBEAT              (0xffffL<<0)
+ #define BNX2_MISC_SMB_POLL_ASF                                0x00000894
+ #define BNX2_MISC_SMB_POLL_ASF_POLL_ASF                        (0xffffL<<0)
+ #define BNX2_MISC_SMB_POLL_LEGACY                     0x00000898
+ #define BNX2_MISC_SMB_POLL_LEGACY_POLL_LEGACY          (0xffffL<<0)
+ #define BNX2_MISC_SMB_RETRAN                          0x0000089c
+ #define BNX2_MISC_SMB_RETRAN_RETRAN                    (0xffL<<0)
+ #define BNX2_MISC_SMB_TIMESTAMP                               0x000008a0
+ #define BNX2_MISC_SMB_TIMESTAMP_TIMESTAMP              (0xffffffffL<<0)
+ #define BNX2_MISC_PERR_ENA0                           0x000008a4
+ #define BNX2_MISC_PERR_ENA0_COM_MISC_CTXC              (1L<<0)
+ #define BNX2_MISC_PERR_ENA0_COM_MISC_REGF              (1L<<1)
+ #define BNX2_MISC_PERR_ENA0_COM_MISC_SCPAD             (1L<<2)
+ #define BNX2_MISC_PERR_ENA0_CP_MISC_CTXC               (1L<<3)
+ #define BNX2_MISC_PERR_ENA0_CP_MISC_REGF               (1L<<4)
+ #define BNX2_MISC_PERR_ENA0_CP_MISC_SCPAD              (1L<<5)
+ #define BNX2_MISC_PERR_ENA0_CS_MISC_TMEM               (1L<<6)
+ #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM0             (1L<<7)
+ #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM1             (1L<<8)
+ #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM2             (1L<<9)
+ #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM3             (1L<<10)
+ #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM4             (1L<<11)
+ #define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM5             (1L<<12)
+ #define BNX2_MISC_PERR_ENA0_CTX_MISC_PGTBL             (1L<<13)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR0              (1L<<14)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR1              (1L<<15)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR2              (1L<<16)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR3              (1L<<17)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR4              (1L<<18)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW0              (1L<<19)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW1              (1L<<20)
+ #define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW2              (1L<<21)
+ #define BNX2_MISC_PERR_ENA0_HC_MISC_DMA                        (1L<<22)
+ #define BNX2_MISC_PERR_ENA0_MCP_MISC_REGF              (1L<<23)
+ #define BNX2_MISC_PERR_ENA0_MCP_MISC_SCPAD             (1L<<24)
+ #define BNX2_MISC_PERR_ENA0_MQ_MISC_CTX                        (1L<<25)
+ #define BNX2_MISC_PERR_ENA0_RBDC_MISC                  (1L<<26)
+ #define BNX2_MISC_PERR_ENA0_RBUF_MISC_MB               (1L<<27)
+ #define BNX2_MISC_PERR_ENA0_RBUF_MISC_PTR              (1L<<28)
+ #define BNX2_MISC_PERR_ENA0_RDE_MISC_RPC               (1L<<29)
+ #define BNX2_MISC_PERR_ENA0_RDE_MISC_RPM               (1L<<30)
+ #define BNX2_MISC_PERR_ENA0_RV2P_MISC_CB0REGS          (1L<<31)
+ #define BNX2_MISC_PERR_ENA0_COM_DMAE_PERR_EN_XI                (1L<<0)
+ #define BNX2_MISC_PERR_ENA0_CP_DMAE_PERR_EN_XI                 (1L<<1)
+ #define BNX2_MISC_PERR_ENA0_RPM_ACPIBEMEM_PERR_EN_XI   (1L<<2)
+ #define BNX2_MISC_PERR_ENA0_CTX_USAGE_CNT_PERR_EN_XI   (1L<<3)
+ #define BNX2_MISC_PERR_ENA0_CTX_PGTBL_PERR_EN_XI       (1L<<4)
+ #define BNX2_MISC_PERR_ENA0_CTX_CACHE_PERR_EN_XI       (1L<<5)
+ #define BNX2_MISC_PERR_ENA0_CTX_MIRROR_PERR_EN_XI      (1L<<6)
+ #define BNX2_MISC_PERR_ENA0_COM_CTXC_PERR_EN_XI                (1L<<7)
+ #define BNX2_MISC_PERR_ENA0_COM_SCPAD_PERR_EN_XI       (1L<<8)
+ #define BNX2_MISC_PERR_ENA0_CP_CTXC_PERR_EN_XI                 (1L<<9)
+ #define BNX2_MISC_PERR_ENA0_CP_SCPAD_PERR_EN_XI                (1L<<10)
+ #define BNX2_MISC_PERR_ENA0_RXP_RBUFC_PERR_EN_XI       (1L<<11)
+ #define BNX2_MISC_PERR_ENA0_RXP_CTXC_PERR_EN_XI                (1L<<12)
+ #define BNX2_MISC_PERR_ENA0_RXP_SCPAD_PERR_EN_XI       (1L<<13)
+ #define BNX2_MISC_PERR_ENA0_TPAT_SCPAD_PERR_EN_XI      (1L<<14)
+ #define BNX2_MISC_PERR_ENA0_TXP_CTXC_PERR_EN_XI                (1L<<15)
+ #define BNX2_MISC_PERR_ENA0_TXP_SCPAD_PERR_EN_XI       (1L<<16)
+ #define BNX2_MISC_PERR_ENA0_CS_TMEM_PERR_EN_XI                 (1L<<17)
+ #define BNX2_MISC_PERR_ENA0_MQ_CTX_PERR_EN_XI          (1L<<18)
+ #define BNX2_MISC_PERR_ENA0_RPM_DFIFOMEM_PERR_EN_XI    (1L<<19)
+ #define BNX2_MISC_PERR_ENA0_RPC_DFIFOMEM_PERR_EN_XI    (1L<<20)
+ #define BNX2_MISC_PERR_ENA0_RBUF_PTRMEM_PERR_EN_XI     (1L<<21)
+ #define BNX2_MISC_PERR_ENA0_RBUF_DATAMEM_PERR_EN_XI    (1L<<22)
+ #define BNX2_MISC_PERR_ENA0_RV2P_P2IRAM_PERR_EN_XI     (1L<<23)
+ #define BNX2_MISC_PERR_ENA0_RV2P_P1IRAM_PERR_EN_XI     (1L<<24)
+ #define BNX2_MISC_PERR_ENA0_RV2P_CB1REGS_PERR_EN_XI    (1L<<25)
+ #define BNX2_MISC_PERR_ENA0_RV2P_CB0REGS_PERR_EN_XI    (1L<<26)
+ #define BNX2_MISC_PERR_ENA0_TPBUF_PERR_EN_XI           (1L<<27)
+ #define BNX2_MISC_PERR_ENA0_THBUF_PERR_EN_XI           (1L<<28)
+ #define BNX2_MISC_PERR_ENA0_TDMA_PERR_EN_XI            (1L<<29)
+ #define BNX2_MISC_PERR_ENA0_TBDC_PERR_EN_XI            (1L<<30)
+ #define BNX2_MISC_PERR_ENA0_TSCH_LR_PERR_EN_XI                 (1L<<31)
+ #define BNX2_MISC_PERR_ENA1                           0x000008a8
+ #define BNX2_MISC_PERR_ENA1_RV2P_MISC_CB1REGS          (1L<<0)
+ #define BNX2_MISC_PERR_ENA1_RV2P_MISC_P1IRAM           (1L<<1)
+ #define BNX2_MISC_PERR_ENA1_RV2P_MISC_P2IRAM           (1L<<2)
+ #define BNX2_MISC_PERR_ENA1_RXP_MISC_CTXC              (1L<<3)
+ #define BNX2_MISC_PERR_ENA1_RXP_MISC_REGF              (1L<<4)
+ #define BNX2_MISC_PERR_ENA1_RXP_MISC_SCPAD             (1L<<5)
+ #define BNX2_MISC_PERR_ENA1_RXP_MISC_RBUFC             (1L<<6)
+ #define BNX2_MISC_PERR_ENA1_TBDC_MISC                  (1L<<7)
+ #define BNX2_MISC_PERR_ENA1_TDMA_MISC                  (1L<<8)
+ #define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB0             (1L<<9)
+ #define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB1             (1L<<10)
+ #define BNX2_MISC_PERR_ENA1_TPAT_MISC_REGF             (1L<<11)
+ #define BNX2_MISC_PERR_ENA1_TPAT_MISC_SCPAD            (1L<<12)
+ #define BNX2_MISC_PERR_ENA1_TPBUF_MISC_MB              (1L<<13)
+ #define BNX2_MISC_PERR_ENA1_TSCH_MISC_LR               (1L<<14)
+ #define BNX2_MISC_PERR_ENA1_TXP_MISC_CTXC              (1L<<15)
+ #define BNX2_MISC_PERR_ENA1_TXP_MISC_REGF              (1L<<16)
+ #define BNX2_MISC_PERR_ENA1_TXP_MISC_SCPAD             (1L<<17)
+ #define BNX2_MISC_PERR_ENA1_UMP_MISC_FIORX             (1L<<18)
+ #define BNX2_MISC_PERR_ENA1_UMP_MISC_FIOTX             (1L<<19)
+ #define BNX2_MISC_PERR_ENA1_UMP_MISC_RX                        (1L<<20)
+ #define BNX2_MISC_PERR_ENA1_UMP_MISC_TX                        (1L<<21)
+ #define BNX2_MISC_PERR_ENA1_RDMAQ_MISC                         (1L<<22)
+ #define BNX2_MISC_PERR_ENA1_CSQ_MISC                   (1L<<23)
+ #define BNX2_MISC_PERR_ENA1_CPQ_MISC                   (1L<<24)
+ #define BNX2_MISC_PERR_ENA1_MCPQ_MISC                  (1L<<25)
+ #define BNX2_MISC_PERR_ENA1_RV2PMQ_MISC                        (1L<<26)
+ #define BNX2_MISC_PERR_ENA1_RV2PPQ_MISC                        (1L<<27)
+ #define BNX2_MISC_PERR_ENA1_RV2PTQ_MISC                        (1L<<28)
+ #define BNX2_MISC_PERR_ENA1_RXPQ_MISC                  (1L<<29)
+ #define BNX2_MISC_PERR_ENA1_RXPCQ_MISC                         (1L<<30)
+ #define BNX2_MISC_PERR_ENA1_RLUPQ_MISC                         (1L<<31)
+ #define BNX2_MISC_PERR_ENA1_RBDC_PERR_EN_XI            (1L<<0)
+ #define BNX2_MISC_PERR_ENA1_RDMA_DFIFO_PERR_EN_XI      (1L<<2)
+ #define BNX2_MISC_PERR_ENA1_HC_STATS_PERR_EN_XI                (1L<<3)
+ #define BNX2_MISC_PERR_ENA1_HC_MSIX_PERR_EN_XI                 (1L<<4)
+ #define BNX2_MISC_PERR_ENA1_HC_PRODUCSTB_PERR_EN_XI    (1L<<5)
+ #define BNX2_MISC_PERR_ENA1_HC_CONSUMSTB_PERR_EN_XI    (1L<<6)
+ #define BNX2_MISC_PERR_ENA1_TPATQ_PERR_EN_XI           (1L<<7)
+ #define BNX2_MISC_PERR_ENA1_MCPQ_PERR_EN_XI            (1L<<8)
+ #define BNX2_MISC_PERR_ENA1_TDMAQ_PERR_EN_XI           (1L<<9)
+ #define BNX2_MISC_PERR_ENA1_TXPQ_PERR_EN_XI            (1L<<10)
+ #define BNX2_MISC_PERR_ENA1_COMTQ_PERR_EN_XI           (1L<<11)
+ #define BNX2_MISC_PERR_ENA1_COMQ_PERR_EN_XI            (1L<<12)
+ #define BNX2_MISC_PERR_ENA1_RLUPQ_PERR_EN_XI           (1L<<13)
+ #define BNX2_MISC_PERR_ENA1_RXPQ_PERR_EN_XI            (1L<<14)
+ #define BNX2_MISC_PERR_ENA1_RV2PPQ_PERR_EN_XI          (1L<<15)
+ #define BNX2_MISC_PERR_ENA1_RDMAQ_PERR_EN_XI           (1L<<16)
+ #define BNX2_MISC_PERR_ENA1_TASQ_PERR_EN_XI            (1L<<17)
+ #define BNX2_MISC_PERR_ENA1_TBDRQ_PERR_EN_XI           (1L<<18)
+ #define BNX2_MISC_PERR_ENA1_TSCHQ_PERR_EN_XI           (1L<<19)
+ #define BNX2_MISC_PERR_ENA1_COMXQ_PERR_EN_XI           (1L<<20)
+ #define BNX2_MISC_PERR_ENA1_RXPCQ_PERR_EN_XI           (1L<<21)
+ #define BNX2_MISC_PERR_ENA1_RV2PTQ_PERR_EN_XI          (1L<<22)
+ #define BNX2_MISC_PERR_ENA1_RV2PMQ_PERR_EN_XI          (1L<<23)
+ #define BNX2_MISC_PERR_ENA1_CPQ_PERR_EN_XI             (1L<<24)
+ #define BNX2_MISC_PERR_ENA1_CSQ_PERR_EN_XI             (1L<<25)
+ #define BNX2_MISC_PERR_ENA1_RLUP_CID_PERR_EN_XI                (1L<<26)
+ #define BNX2_MISC_PERR_ENA1_RV2PCS_TMEM_PERR_EN_XI     (1L<<27)
+ #define BNX2_MISC_PERR_ENA1_RV2PCSQ_PERR_EN_XI                 (1L<<28)
+ #define BNX2_MISC_PERR_ENA1_MQ_IDX_PERR_EN_XI          (1L<<29)
+ #define BNX2_MISC_PERR_ENA2                           0x000008ac
+ #define BNX2_MISC_PERR_ENA2_COMQ_MISC                  (1L<<0)
+ #define BNX2_MISC_PERR_ENA2_COMXQ_MISC                         (1L<<1)
+ #define BNX2_MISC_PERR_ENA2_COMTQ_MISC                         (1L<<2)
+ #define BNX2_MISC_PERR_ENA2_TSCHQ_MISC                         (1L<<3)
+ #define BNX2_MISC_PERR_ENA2_TBDRQ_MISC                         (1L<<4)
+ #define BNX2_MISC_PERR_ENA2_TXPQ_MISC                  (1L<<5)
+ #define BNX2_MISC_PERR_ENA2_TDMAQ_MISC                         (1L<<6)
+ #define BNX2_MISC_PERR_ENA2_TPATQ_MISC                         (1L<<7)
+ #define BNX2_MISC_PERR_ENA2_TASQ_MISC                  (1L<<8)
+ #define BNX2_MISC_PERR_ENA2_TGT_FIFO_PERR_EN_XI                (1L<<0)
+ #define BNX2_MISC_PERR_ENA2_UMP_TX_PERR_EN_XI          (1L<<1)
+ #define BNX2_MISC_PERR_ENA2_UMP_RX_PERR_EN_XI          (1L<<2)
+ #define BNX2_MISC_PERR_ENA2_MCP_ROM_PERR_EN_XI                 (1L<<3)
+ #define BNX2_MISC_PERR_ENA2_MCP_SCPAD_PERR_EN_XI       (1L<<4)
+ #define BNX2_MISC_PERR_ENA2_HB_MEM_PERR_EN_XI          (1L<<5)
+ #define BNX2_MISC_PERR_ENA2_PCIE_REPLAY_PERR_EN_XI     (1L<<6)
+ #define BNX2_MISC_DEBUG_VECTOR_SEL                    0x000008b0
+ #define BNX2_MISC_DEBUG_VECTOR_SEL_0                   (0xfffL<<0)
+ #define BNX2_MISC_DEBUG_VECTOR_SEL_1                   (0xfffL<<12)
+ #define BNX2_MISC_DEBUG_VECTOR_SEL_1_XI                        (0xfffL<<15)
+ #define BNX2_MISC_VREG_CONTROL                                0x000008b4
+ #define BNX2_MISC_VREG_CONTROL_1_2                     (0xfL<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_XI             (0xfL<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS14_XI      (0L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS12_XI      (1L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS10_XI      (2L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS8_XI       (3L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS6_XI       (4L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS4_XI       (5L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_PLUS2_XI       (6L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_NOM_XI                 (7L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS2_XI      (8L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS4_XI      (9L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS6_XI      (10L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS8_XI      (11L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS10_XI     (12L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS12_XI     (13L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS14_XI     (14L<<0)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MAIN_MINUS16_XI     (15L<<0)
+ #define BNX2_MISC_VREG_CONTROL_2_5                     (0xfL<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_PLUS14              (0L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_PLUS12              (1L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_PLUS10              (2L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_PLUS8               (3L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_PLUS6               (4L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_PLUS4               (5L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_PLUS2               (6L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_NOM                         (7L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS2              (8L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS4              (9L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS6              (10L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS8              (11L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS10             (12L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS12             (13L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS14             (14L<<4)
+ #define BNX2_MISC_VREG_CONTROL_2_5_MINUS16             (15L<<4)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT                        (0xfL<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS14                 (0L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS12                 (1L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS10                 (2L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS8          (3L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS6          (4L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS4          (5L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_PLUS2          (6L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_NOM            (7L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS2                 (8L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS4                 (9L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS6                 (10L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS8                 (11L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS10                (12L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS12                (13L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS14                (14L<<8)
+ #define BNX2_MISC_VREG_CONTROL_1_0_MGMT_MINUS16                (15L<<8)
+ #define BNX2_MISC_FINAL_CLK_CTL_VAL                   0x000008b8
+ #define BNX2_MISC_FINAL_CLK_CTL_VAL_MISC_FINAL_CLK_CTL_VAL     (0x3ffffffL<<6)
+ #define BNX2_MISC_GP_HW_CTL0                          0x000008bc
+ #define BNX2_MISC_GP_HW_CTL0_TX_DRIVE                  (1L<<0)
+ #define BNX2_MISC_GP_HW_CTL0_RMII_MODE                         (1L<<1)
+ #define BNX2_MISC_GP_HW_CTL0_RMII_CRSDV_SEL            (1L<<2)
+ #define BNX2_MISC_GP_HW_CTL0_RVMII_MODE                        (1L<<3)
+ #define BNX2_MISC_GP_HW_CTL0_FLASH_SAMP_SCLK_NEGEDGE_TE        (1L<<4)
+ #define BNX2_MISC_GP_HW_CTL0_HIDDEN_REVISION_ID_TE     (1L<<5)
+ #define BNX2_MISC_GP_HW_CTL0_HC_CNTL_TMOUT_CTR_RST_TE  (1L<<6)
+ #define BNX2_MISC_GP_HW_CTL0_RESERVED1_XI              (0x7L<<4)
+ #define BNX2_MISC_GP_HW_CTL0_ENA_CORE_RST_ON_MAIN_PWR_GOING_AWAY       (1L<<7)
+ #define BNX2_MISC_GP_HW_CTL0_ENA_SEL_VAUX_B_IN_L2_TE   (1L<<8)
+ #define BNX2_MISC_GP_HW_CTL0_GRC_BNK_FREE_FIX_TE       (1L<<9)
+ #define BNX2_MISC_GP_HW_CTL0_LED_ACT_SEL_TE            (1L<<10)
+ #define BNX2_MISC_GP_HW_CTL0_RESERVED2_XI              (0x7L<<8)
+ #define BNX2_MISC_GP_HW_CTL0_UP1_DEF0                  (1L<<11)
+ #define BNX2_MISC_GP_HW_CTL0_FIBER_MODE_DIS_DEF                (1L<<12)
+ #define BNX2_MISC_GP_HW_CTL0_FORCE2500_DEF             (1L<<13)
+ #define BNX2_MISC_GP_HW_CTL0_AUTODETECT_DIS_DEF                (1L<<14)
+ #define BNX2_MISC_GP_HW_CTL0_PARALLEL_DETECT_DEF       (1L<<15)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI               (0xfL<<16)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_3MA           (0L<<16)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_2P5MA                 (1L<<16)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_2P0MA                 (3L<<16)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_1P5MA                 (5L<<16)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_1P0MA                 (7L<<16)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_DAI_PWRDN                 (15L<<16)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PRE2DIS           (1L<<20)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PRE1DIS           (1L<<21)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT              (0x3L<<22)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_M6P          (0L<<22)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_M0P          (1L<<22)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_P0P          (2L<<22)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_CTAT_P6P          (3L<<22)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT              (0x3L<<24)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_M6P          (0L<<24)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_M0P          (1L<<24)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_P0P          (2L<<24)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_PTAT_P6P          (3L<<24)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ          (0x3L<<26)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_240UA    (0L<<26)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_160UA    (1L<<26)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_400UA    (2L<<26)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_IAMP_ADJ_320UA    (3L<<26)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ                 (0x3L<<28)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_240UA   (0L<<28)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_160UA   (1L<<28)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_400UA   (2L<<28)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_ICBUF_ADJ_320UA   (3L<<28)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ          (0x3L<<30)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P57     (0L<<30)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P45     (1L<<30)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P62     (2L<<30)
+ #define BNX2_MISC_GP_HW_CTL0_OSCCTRL_XTAL_ADJ_1P66     (3L<<30)
+ #define BNX2_MISC_GP_HW_CTL1                          0x000008c0
+ #define BNX2_MISC_GP_HW_CTL1_1_ATTN_BTN_PRSNT_TE       (1L<<0)
+ #define BNX2_MISC_GP_HW_CTL1_1_ATTN_IND_PRSNT_TE       (1L<<1)
+ #define BNX2_MISC_GP_HW_CTL1_1_PWR_IND_PRSNT_TE                (1L<<2)
+ #define BNX2_MISC_GP_HW_CTL1_0_PCIE_LOOPBACK_TE                (1L<<3)
+ #define BNX2_MISC_GP_HW_CTL1_RESERVED_SOFT_XI          (0xffffL<<0)
+ #define BNX2_MISC_GP_HW_CTL1_RESERVED_HARD_XI          (0xffffL<<16)
+ #define BNX2_MISC_NEW_HW_CTL                          0x000008c4
+ #define BNX2_MISC_NEW_HW_CTL_MAIN_POR_BYPASS           (1L<<0)
+ #define BNX2_MISC_NEW_HW_CTL_RINGOSC_ENABLE            (1L<<1)
+ #define BNX2_MISC_NEW_HW_CTL_RINGOSC_SEL0              (1L<<2)
+ #define BNX2_MISC_NEW_HW_CTL_RINGOSC_SEL1              (1L<<3)
+ #define BNX2_MISC_NEW_HW_CTL_RESERVED_SHARED           (0xfffL<<4)
+ #define BNX2_MISC_NEW_HW_CTL_RESERVED_SPLIT            (0xffffL<<16)
+ #define BNX2_MISC_NEW_CORE_CTL                                0x000008c8
+ #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS    (1L<<0)
+ #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ                (1L<<1)
+ #define BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE              (1L<<16)
+ #define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN            (0x3fffL<<2)
+ #define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC             (0xffffL<<16)
+ #define BNX2_MISC_ECO_HW_CTL                          0x000008cc
+ #define BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN                (1L<<0)
+ #define BNX2_MISC_ECO_HW_CTL_RESERVED_SOFT             (0x7fffL<<1)
+ #define BNX2_MISC_ECO_HW_CTL_RESERVED_HARD             (0xffffL<<16)
+ #define BNX2_MISC_ECO_CORE_CTL                                0x000008d0
+ #define BNX2_MISC_ECO_CORE_CTL_RESERVED_SOFT           (0xffffL<<0)
+ #define BNX2_MISC_ECO_CORE_CTL_RESERVED_HARD           (0xffffL<<16)
+ #define BNX2_MISC_PPIO                                        0x000008d4
+ #define BNX2_MISC_PPIO_VALUE                           (0xfL<<0)
+ #define BNX2_MISC_PPIO_SET                             (0xfL<<8)
+ #define BNX2_MISC_PPIO_CLR                             (0xfL<<16)
+ #define BNX2_MISC_PPIO_FLOAT                           (0xfL<<24)
+ #define BNX2_MISC_PPIO_INT                            0x000008d8
+ #define BNX2_MISC_PPIO_INT_INT_STATE                   (0xfL<<0)
+ #define BNX2_MISC_PPIO_INT_OLD_VALUE                   (0xfL<<8)
+ #define BNX2_MISC_PPIO_INT_OLD_SET                     (0xfL<<16)
+ #define BNX2_MISC_PPIO_INT_OLD_CLR                     (0xfL<<24)
+ #define BNX2_MISC_RESET_NUMS                          0x000008dc
+ #define BNX2_MISC_RESET_NUMS_NUM_HARD_RESETS           (0x7L<<0)
+ #define BNX2_MISC_RESET_NUMS_NUM_PCIE_RESETS           (0x7L<<4)
+ #define BNX2_MISC_RESET_NUMS_NUM_PERSTB_RESETS                 (0x7L<<8)
+ #define BNX2_MISC_RESET_NUMS_NUM_CMN_RESETS            (0x7L<<12)
+ #define BNX2_MISC_RESET_NUMS_NUM_PORT_RESETS           (0x7L<<16)
+ #define BNX2_MISC_CS16_ERR                            0x000008e0
+ #define BNX2_MISC_CS16_ERR_ENA_PCI                     (1L<<0)
+ #define BNX2_MISC_CS16_ERR_ENA_RDMA                    (1L<<1)
+ #define BNX2_MISC_CS16_ERR_ENA_TDMA                    (1L<<2)
+ #define BNX2_MISC_CS16_ERR_ENA_EMAC                    (1L<<3)
+ #define BNX2_MISC_CS16_ERR_ENA_CTX                     (1L<<4)
+ #define BNX2_MISC_CS16_ERR_ENA_TBDR                    (1L<<5)
+ #define BNX2_MISC_CS16_ERR_ENA_RBDC                    (1L<<6)
+ #define BNX2_MISC_CS16_ERR_ENA_COM                     (1L<<7)
+ #define BNX2_MISC_CS16_ERR_ENA_CP                      (1L<<8)
+ #define BNX2_MISC_CS16_ERR_STA_PCI                     (1L<<16)
+ #define BNX2_MISC_CS16_ERR_STA_RDMA                    (1L<<17)
+ #define BNX2_MISC_CS16_ERR_STA_TDMA                    (1L<<18)
+ #define BNX2_MISC_CS16_ERR_STA_EMAC                    (1L<<19)
+ #define BNX2_MISC_CS16_ERR_STA_CTX                     (1L<<20)
+ #define BNX2_MISC_CS16_ERR_STA_TBDR                    (1L<<21)
+ #define BNX2_MISC_CS16_ERR_STA_RBDC                    (1L<<22)
+ #define BNX2_MISC_CS16_ERR_STA_COM                     (1L<<23)
+ #define BNX2_MISC_CS16_ERR_STA_CP                      (1L<<24)
+ #define BNX2_MISC_SPIO_EVENT                          0x000008e4
+ #define BNX2_MISC_SPIO_EVENT_ENABLE                    (0xffL<<0)
+ #define BNX2_MISC_PPIO_EVENT                          0x000008e8
+ #define BNX2_MISC_PPIO_EVENT_ENABLE                    (0xfL<<0)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL                     0x000008ec
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID              (0xffL<<0)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_X            (0L<<0)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C            (3L<<0)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_S            (12L<<0)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP       (0x7L<<8)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PORT_SWAP_PIN                (1L<<11)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES1_SIGDET       (1L<<12)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES0_SIGDET       (1L<<13)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY1_SIGDET          (1L<<14)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY0_SIGDET          (1L<<15)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_LCPLL_RST            (1L<<16)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES1_RST          (1L<<17)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_SERDES0_RST          (1L<<18)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY1_RST             (1L<<19)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY0_RST             (1L<<20)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL             (0x7L<<21)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PORT_SWAP            (1L<<24)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE       (1L<<25)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ      (0xfL<<26)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_SER1_IDDQ    (1L<<26)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_SER0_IDDQ    (2L<<26)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_PHY1_IDDQ    (4L<<26)
+ #define BNX2_MISC_DUAL_MEDIA_CTRL_PHY_SERDES_IDDQ_PHY0_IDDQ    (8L<<26)
+ #define BNX2_MISC_OTP_CMD1                            0x000008f0
+ #define BNX2_MISC_OTP_CMD1_FMODE                       (0x7L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_IDLE                  (0L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_WRITE                         (1L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_INIT                  (2L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_SET                   (3L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_RST                   (4L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_VERIFY                        (5L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_RESERVED0             (6L<<0)
+ #define BNX2_MISC_OTP_CMD1_FMODE_RESERVED1             (7L<<0)
+ #define BNX2_MISC_OTP_CMD1_USEPINS                     (1L<<8)
+ #define BNX2_MISC_OTP_CMD1_PROGSEL                     (1L<<9)
+ #define BNX2_MISC_OTP_CMD1_PROGSTART                   (1L<<10)
+ #define BNX2_MISC_OTP_CMD1_PCOUNT                      (0x7L<<16)
+ #define BNX2_MISC_OTP_CMD1_PBYP                                (1L<<19)
+ #define BNX2_MISC_OTP_CMD1_VSEL                                (0xfL<<20)
+ #define BNX2_MISC_OTP_CMD1_TM                          (0x7L<<27)
+ #define BNX2_MISC_OTP_CMD1_SADBYP                      (1L<<30)
+ #define BNX2_MISC_OTP_CMD1_DEBUG                       (1L<<31)
+ #define BNX2_MISC_OTP_CMD2                            0x000008f4
+ #define BNX2_MISC_OTP_CMD2_OTP_ROM_ADDR                        (0x3ffL<<0)
+ #define BNX2_MISC_OTP_CMD2_DOSEL                       (0x7fL<<16)
+ #define BNX2_MISC_OTP_CMD2_DOSEL_0                     (0L<<16)
+ #define BNX2_MISC_OTP_CMD2_DOSEL_1                     (1L<<16)
+ #define BNX2_MISC_OTP_CMD2_DOSEL_127                   (127L<<16)
+ #define BNX2_MISC_OTP_STATUS                          0x000008f8
+ #define BNX2_MISC_OTP_STATUS_DATA                      (0xffL<<0)
+ #define BNX2_MISC_OTP_STATUS_VALID                     (1L<<8)
+ #define BNX2_MISC_OTP_STATUS_BUSY                      (1L<<9)
+ #define BNX2_MISC_OTP_STATUS_BUSYSM                    (1L<<10)
+ #define BNX2_MISC_OTP_STATUS_DONE                      (1L<<11)
+ #define BNX2_MISC_OTP_SHIFT1_CMD                      0x000008fc
+ #define BNX2_MISC_OTP_SHIFT1_CMD_RESET_MODE_N          (1L<<0)
+ #define BNX2_MISC_OTP_SHIFT1_CMD_SHIFT_DONE            (1L<<1)
+ #define BNX2_MISC_OTP_SHIFT1_CMD_SHIFT_START           (1L<<2)
+ #define BNX2_MISC_OTP_SHIFT1_CMD_LOAD_DATA             (1L<<3)
+ #define BNX2_MISC_OTP_SHIFT1_CMD_SHIFT_SELECT          (0x1fL<<8)
+ #define BNX2_MISC_OTP_SHIFT1_DATA                     0x00000900
+ #define BNX2_MISC_OTP_SHIFT2_CMD                      0x00000904
+ #define BNX2_MISC_OTP_SHIFT2_CMD_RESET_MODE_N          (1L<<0)
+ #define BNX2_MISC_OTP_SHIFT2_CMD_SHIFT_DONE            (1L<<1)
+ #define BNX2_MISC_OTP_SHIFT2_CMD_SHIFT_START           (1L<<2)
+ #define BNX2_MISC_OTP_SHIFT2_CMD_LOAD_DATA             (1L<<3)
+ #define BNX2_MISC_OTP_SHIFT2_CMD_SHIFT_SELECT          (0x1fL<<8)
+ #define BNX2_MISC_OTP_SHIFT2_DATA                     0x00000908
+ #define BNX2_MISC_BIST_CS0                            0x0000090c
+ #define BNX2_MISC_BIST_CS0_MBIST_EN                    (1L<<0)
+ #define BNX2_MISC_BIST_CS0_BIST_SETUP                  (0x3L<<1)
+ #define BNX2_MISC_BIST_CS0_MBIST_ASYNC_RESET           (1L<<3)
+ #define BNX2_MISC_BIST_CS0_MBIST_DONE                  (1L<<8)
+ #define BNX2_MISC_BIST_CS0_MBIST_GO                    (1L<<9)
+ #define BNX2_MISC_BIST_CS0_BIST_OVERRIDE               (1L<<31)
+ #define BNX2_MISC_BIST_MEMSTATUS0                     0x00000910
+ #define BNX2_MISC_BIST_CS1                            0x00000914
+ #define BNX2_MISC_BIST_CS1_MBIST_EN                    (1L<<0)
+ #define BNX2_MISC_BIST_CS1_BIST_SETUP                  (0x3L<<1)
+ #define BNX2_MISC_BIST_CS1_MBIST_ASYNC_RESET           (1L<<3)
+ #define BNX2_MISC_BIST_CS1_MBIST_DONE                  (1L<<8)
+ #define BNX2_MISC_BIST_CS1_MBIST_GO                    (1L<<9)
+ #define BNX2_MISC_BIST_MEMSTATUS1                     0x00000918
+ #define BNX2_MISC_BIST_CS2                            0x0000091c
+ #define BNX2_MISC_BIST_CS2_MBIST_EN                    (1L<<0)
+ #define BNX2_MISC_BIST_CS2_BIST_SETUP                  (0x3L<<1)
+ #define BNX2_MISC_BIST_CS2_MBIST_ASYNC_RESET           (1L<<3)
+ #define BNX2_MISC_BIST_CS2_MBIST_DONE                  (1L<<8)
+ #define BNX2_MISC_BIST_CS2_MBIST_GO                    (1L<<9)
+ #define BNX2_MISC_BIST_MEMSTATUS2                     0x00000920
+ #define BNX2_MISC_BIST_CS3                            0x00000924
+ #define BNX2_MISC_BIST_CS3_MBIST_EN                    (1L<<0)
+ #define BNX2_MISC_BIST_CS3_BIST_SETUP                  (0x3L<<1)
+ #define BNX2_MISC_BIST_CS3_MBIST_ASYNC_RESET           (1L<<3)
+ #define BNX2_MISC_BIST_CS3_MBIST_DONE                  (1L<<8)
+ #define BNX2_MISC_BIST_CS3_MBIST_GO                    (1L<<9)
+ #define BNX2_MISC_BIST_MEMSTATUS3                     0x00000928
+ #define BNX2_MISC_BIST_CS4                            0x0000092c
+ #define BNX2_MISC_BIST_CS4_MBIST_EN                    (1L<<0)
+ #define BNX2_MISC_BIST_CS4_BIST_SETUP                  (0x3L<<1)
+ #define BNX2_MISC_BIST_CS4_MBIST_ASYNC_RESET           (1L<<3)
+ #define BNX2_MISC_BIST_CS4_MBIST_DONE                  (1L<<8)
+ #define BNX2_MISC_BIST_CS4_MBIST_GO                    (1L<<9)
+ #define BNX2_MISC_BIST_MEMSTATUS4                     0x00000930
+ #define BNX2_MISC_BIST_CS5                            0x00000934
+ #define BNX2_MISC_BIST_CS5_MBIST_EN                    (1L<<0)
+ #define BNX2_MISC_BIST_CS5_BIST_SETUP                  (0x3L<<1)
+ #define BNX2_MISC_BIST_CS5_MBIST_ASYNC_RESET           (1L<<3)
+ #define BNX2_MISC_BIST_CS5_MBIST_DONE                  (1L<<8)
+ #define BNX2_MISC_BIST_CS5_MBIST_GO                    (1L<<9)
+ #define BNX2_MISC_BIST_MEMSTATUS5                     0x00000938
+ #define BNX2_MISC_MEM_TM0                             0x0000093c
+ #define BNX2_MISC_MEM_TM0_PCIE_REPLAY_TM               (0xfL<<0)
+ #define BNX2_MISC_MEM_TM0_MCP_SCPAD                    (0xfL<<8)
+ #define BNX2_MISC_MEM_TM0_UMP_TM                       (0xffL<<16)
+ #define BNX2_MISC_MEM_TM0_HB_MEM_TM                    (0xfL<<24)
+ #define BNX2_MISC_USPLL_CTRL                          0x00000940
+ #define BNX2_MISC_USPLL_CTRL_PH_DET_DIS                        (1L<<0)
+ #define BNX2_MISC_USPLL_CTRL_FREQ_DET_DIS              (1L<<1)
+ #define BNX2_MISC_USPLL_CTRL_LCPX                      (0x3fL<<2)
+ #define BNX2_MISC_USPLL_CTRL_RX                                (0x3L<<8)
+ #define BNX2_MISC_USPLL_CTRL_VC_EN                     (1L<<10)
+ #define BNX2_MISC_USPLL_CTRL_VCO_MG                    (0x3L<<11)
+ #define BNX2_MISC_USPLL_CTRL_KVCO_XF                   (0x7L<<13)
+ #define BNX2_MISC_USPLL_CTRL_KVCO_XS                   (0x7L<<16)
+ #define BNX2_MISC_USPLL_CTRL_TESTD_EN                  (1L<<19)
+ #define BNX2_MISC_USPLL_CTRL_TESTD_SEL                         (0x7L<<20)
+ #define BNX2_MISC_USPLL_CTRL_TESTA_EN                  (1L<<23)
+ #define BNX2_MISC_USPLL_CTRL_TESTA_SEL                         (0x3L<<24)
+ #define BNX2_MISC_USPLL_CTRL_ATTEN_FREF                        (1L<<26)
+ #define BNX2_MISC_USPLL_CTRL_DIGITAL_RST               (1L<<27)
+ #define BNX2_MISC_USPLL_CTRL_ANALOG_RST                        (1L<<28)
+ #define BNX2_MISC_USPLL_CTRL_LOCK                      (1L<<29)
+ #define BNX2_MISC_PERR_STATUS0                                0x00000944
+ #define BNX2_MISC_PERR_STATUS0_COM_DMAE_PERR           (1L<<0)
+ #define BNX2_MISC_PERR_STATUS0_CP_DMAE_PERR            (1L<<1)
+ #define BNX2_MISC_PERR_STATUS0_RPM_ACPIBEMEM_PERR      (1L<<2)
+ #define BNX2_MISC_PERR_STATUS0_CTX_USAGE_CNT_PERR      (1L<<3)
+ #define BNX2_MISC_PERR_STATUS0_CTX_PGTBL_PERR          (1L<<4)
+ #define BNX2_MISC_PERR_STATUS0_CTX_CACHE_PERR          (1L<<5)
+ #define BNX2_MISC_PERR_STATUS0_CTX_MIRROR_PERR                 (1L<<6)
+ #define BNX2_MISC_PERR_STATUS0_COM_CTXC_PERR           (1L<<7)
+ #define BNX2_MISC_PERR_STATUS0_COM_SCPAD_PERR          (1L<<8)
+ #define BNX2_MISC_PERR_STATUS0_CP_CTXC_PERR            (1L<<9)
+ #define BNX2_MISC_PERR_STATUS0_CP_SCPAD_PERR           (1L<<10)
+ #define BNX2_MISC_PERR_STATUS0_RXP_RBUFC_PERR          (1L<<11)
+ #define BNX2_MISC_PERR_STATUS0_RXP_CTXC_PERR           (1L<<12)
+ #define BNX2_MISC_PERR_STATUS0_RXP_SCPAD_PERR          (1L<<13)
+ #define BNX2_MISC_PERR_STATUS0_TPAT_SCPAD_PERR                 (1L<<14)
+ #define BNX2_MISC_PERR_STATUS0_TXP_CTXC_PERR           (1L<<15)
+ #define BNX2_MISC_PERR_STATUS0_TXP_SCPAD_PERR          (1L<<16)
+ #define BNX2_MISC_PERR_STATUS0_CS_TMEM_PERR            (1L<<17)
+ #define BNX2_MISC_PERR_STATUS0_MQ_CTX_PERR             (1L<<18)
+ #define BNX2_MISC_PERR_STATUS0_RPM_DFIFOMEM_PERR       (1L<<19)
+ #define BNX2_MISC_PERR_STATUS0_RPC_DFIFOMEM_PERR       (1L<<20)
+ #define BNX2_MISC_PERR_STATUS0_RBUF_PTRMEM_PERR                (1L<<21)
+ #define BNX2_MISC_PERR_STATUS0_RBUF_DATAMEM_PERR       (1L<<22)
+ #define BNX2_MISC_PERR_STATUS0_RV2P_P2IRAM_PERR                (1L<<23)
+ #define BNX2_MISC_PERR_STATUS0_RV2P_P1IRAM_PERR                (1L<<24)
+ #define BNX2_MISC_PERR_STATUS0_RV2P_CB1REGS_PERR       (1L<<25)
+ #define BNX2_MISC_PERR_STATUS0_RV2P_CB0REGS_PERR       (1L<<26)
+ #define BNX2_MISC_PERR_STATUS0_TPBUF_PERR              (1L<<27)
+ #define BNX2_MISC_PERR_STATUS0_THBUF_PERR              (1L<<28)
+ #define BNX2_MISC_PERR_STATUS0_TDMA_PERR               (1L<<29)
+ #define BNX2_MISC_PERR_STATUS0_TBDC_PERR               (1L<<30)
+ #define BNX2_MISC_PERR_STATUS0_TSCH_LR_PERR            (1L<<31)
+ #define BNX2_MISC_PERR_STATUS1                                0x00000948
+ #define BNX2_MISC_PERR_STATUS1_RBDC_PERR               (1L<<0)
+ #define BNX2_MISC_PERR_STATUS1_RDMA_DFIFO_PERR                 (1L<<2)
+ #define BNX2_MISC_PERR_STATUS1_HC_STATS_PERR           (1L<<3)
+ #define BNX2_MISC_PERR_STATUS1_HC_MSIX_PERR            (1L<<4)
+ #define BNX2_MISC_PERR_STATUS1_HC_PRODUCSTB_PERR       (1L<<5)
+ #define BNX2_MISC_PERR_STATUS1_HC_CONSUMSTB_PERR       (1L<<6)
+ #define BNX2_MISC_PERR_STATUS1_TPATQ_PERR              (1L<<7)
+ #define BNX2_MISC_PERR_STATUS1_MCPQ_PERR               (1L<<8)
+ #define BNX2_MISC_PERR_STATUS1_TDMAQ_PERR              (1L<<9)
+ #define BNX2_MISC_PERR_STATUS1_TXPQ_PERR               (1L<<10)
+ #define BNX2_MISC_PERR_STATUS1_COMTQ_PERR              (1L<<11)
+ #define BNX2_MISC_PERR_STATUS1_COMQ_PERR               (1L<<12)
+ #define BNX2_MISC_PERR_STATUS1_RLUPQ_PERR              (1L<<13)
+ #define BNX2_MISC_PERR_STATUS1_RXPQ_PERR               (1L<<14)
+ #define BNX2_MISC_PERR_STATUS1_RV2PPQ_PERR             (1L<<15)
+ #define BNX2_MISC_PERR_STATUS1_RDMAQ_PERR              (1L<<16)
+ #define BNX2_MISC_PERR_STATUS1_TASQ_PERR               (1L<<17)
+ #define BNX2_MISC_PERR_STATUS1_TBDRQ_PERR              (1L<<18)
+ #define BNX2_MISC_PERR_STATUS1_TSCHQ_PERR              (1L<<19)
+ #define BNX2_MISC_PERR_STATUS1_COMXQ_PERR              (1L<<20)
+ #define BNX2_MISC_PERR_STATUS1_RXPCQ_PERR              (1L<<21)
+ #define BNX2_MISC_PERR_STATUS1_RV2PTQ_PERR             (1L<<22)
+ #define BNX2_MISC_PERR_STATUS1_RV2PMQ_PERR             (1L<<23)
+ #define BNX2_MISC_PERR_STATUS1_CPQ_PERR                        (1L<<24)
+ #define BNX2_MISC_PERR_STATUS1_CSQ_PERR                        (1L<<25)
+ #define BNX2_MISC_PERR_STATUS1_RLUP_CID_PERR           (1L<<26)
+ #define BNX2_MISC_PERR_STATUS1_RV2PCS_TMEM_PERR                (1L<<27)
+ #define BNX2_MISC_PERR_STATUS1_RV2PCSQ_PERR            (1L<<28)
+ #define BNX2_MISC_PERR_STATUS1_MQ_IDX_PERR             (1L<<29)
+ #define BNX2_MISC_PERR_STATUS2                                0x0000094c
+ #define BNX2_MISC_PERR_STATUS2_TGT_FIFO_PERR           (1L<<0)
+ #define BNX2_MISC_PERR_STATUS2_UMP_TX_PERR             (1L<<1)
+ #define BNX2_MISC_PERR_STATUS2_UMP_RX_PERR             (1L<<2)
+ #define BNX2_MISC_PERR_STATUS2_MCP_ROM_PERR            (1L<<3)
+ #define BNX2_MISC_PERR_STATUS2_MCP_SCPAD_PERR          (1L<<4)
+ #define BNX2_MISC_PERR_STATUS2_HB_MEM_PERR             (1L<<5)
+ #define BNX2_MISC_PERR_STATUS2_PCIE_REPLAY_PERR                (1L<<6)
+ #define BNX2_MISC_LCPLL_CTRL0                         0x00000950
+ #define BNX2_MISC_LCPLL_CTRL0_OAC                      (0x7L<<0)
+ #define BNX2_MISC_LCPLL_CTRL0_OAC_NEGTWENTY            (0L<<0)
+ #define BNX2_MISC_LCPLL_CTRL0_OAC_ZERO                         (1L<<0)
+ #define BNX2_MISC_LCPLL_CTRL0_OAC_TWENTY               (3L<<0)
+ #define BNX2_MISC_LCPLL_CTRL0_OAC_FORTY                        (7L<<0)
+ #define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL                         (0x7L<<3)
+ #define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_360             (0L<<3)
+ #define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_480             (1L<<3)
+ #define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_600             (3L<<3)
+ #define BNX2_MISC_LCPLL_CTRL0_ICP_CTRL_720             (7L<<3)
+ #define BNX2_MISC_LCPLL_CTRL0_BIAS_CTRL                        (0x3L<<6)
+ #define BNX2_MISC_LCPLL_CTRL0_PLL_OBSERVE              (0x7L<<8)
+ #define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL                         (0x3L<<11)
+ #define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL_0               (0L<<11)
+ #define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL_1               (1L<<11)
+ #define BNX2_MISC_LCPLL_CTRL0_VTH_CTRL_2               (2L<<11)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLSEQSTART              (1L<<13)
+ #define BNX2_MISC_LCPLL_CTRL0_RESERVED                         (1L<<14)
+ #define BNX2_MISC_LCPLL_CTRL0_CAPRETRY_EN              (1L<<15)
+ #define BNX2_MISC_LCPLL_CTRL0_FREQMONITOR_EN           (1L<<16)
+ #define BNX2_MISC_LCPLL_CTRL0_FREQDETRESTART_EN                (1L<<17)
+ #define BNX2_MISC_LCPLL_CTRL0_FREQDETRETRY_EN          (1L<<18)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLFORCEFDONE_EN                 (1L<<19)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLFORCEFDONE            (1L<<20)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLFORCEFPASS            (1L<<21)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPDONE_EN       (1L<<22)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPDONE          (1L<<23)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPPASS_EN       (1L<<24)
+ #define BNX2_MISC_LCPLL_CTRL0_PLLFORCECAPPASS          (1L<<25)
+ #define BNX2_MISC_LCPLL_CTRL0_CAPRESTART               (1L<<26)
+ #define BNX2_MISC_LCPLL_CTRL0_CAPSELECTM_EN            (1L<<27)
+ #define BNX2_MISC_LCPLL_CTRL1                         0x00000954
+ #define BNX2_MISC_LCPLL_CTRL1_CAPSELECTM               (0x1fL<<0)
+ #define BNX2_MISC_LCPLL_CTRL1_CAPFORCESLOWDOWN_EN      (1L<<5)
+ #define BNX2_MISC_LCPLL_CTRL1_CAPFORCESLOWDOWN                 (1L<<6)
+ #define BNX2_MISC_LCPLL_CTRL1_SLOWDN_XOR               (1L<<7)
+ #define BNX2_MISC_LCPLL_STATUS                                0x00000958
+ #define BNX2_MISC_LCPLL_STATUS_FREQDONE_SM             (1L<<0)
+ #define BNX2_MISC_LCPLL_STATUS_FREQPASS_SM             (1L<<1)
+ #define BNX2_MISC_LCPLL_STATUS_PLLSEQDONE              (1L<<2)
+ #define BNX2_MISC_LCPLL_STATUS_PLLSEQPASS              (1L<<3)
+ #define BNX2_MISC_LCPLL_STATUS_PLLSTATE                        (0x7L<<4)
+ #define BNX2_MISC_LCPLL_STATUS_CAPSTATE                        (0x7L<<7)
+ #define BNX2_MISC_LCPLL_STATUS_CAPSELECT               (0x1fL<<10)
+ #define BNX2_MISC_LCPLL_STATUS_SLOWDN_INDICATOR                (1L<<15)
+ #define BNX2_MISC_LCPLL_STATUS_SLOWDN_INDICATOR_0      (0L<<15)
+ #define BNX2_MISC_LCPLL_STATUS_SLOWDN_INDICATOR_1      (1L<<15)
+ #define BNX2_MISC_OSCFUNDS_CTRL                               0x0000095c
+ #define BNX2_MISC_OSCFUNDS_CTRL_FREQ_MON               (1L<<5)
+ #define BNX2_MISC_OSCFUNDS_CTRL_FREQ_MON_OFF           (0L<<5)
+ #define BNX2_MISC_OSCFUNDS_CTRL_FREQ_MON_ON            (1L<<5)
+ #define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM             (0x3L<<6)
+ #define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_0           (0L<<6)
+ #define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_1           (1L<<6)
+ #define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_2           (2L<<6)
+ #define BNX2_MISC_OSCFUNDS_CTRL_XTAL_ADJCM_3           (3L<<6)
+ #define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ              (0x3L<<8)
+ #define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_0            (0L<<8)
+ #define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_1            (1L<<8)
+ #define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_2            (2L<<8)
+ #define BNX2_MISC_OSCFUNDS_CTRL_ICBUF_ADJ_3            (3L<<8)
+ #define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ               (0x3L<<10)
+ #define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_0             (0L<<10)
+ #define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_1             (1L<<10)
+ #define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_2             (2L<<10)
+ #define BNX2_MISC_OSCFUNDS_CTRL_IAMP_ADJ_3             (3L<<10)
+ /*
+  *  nvm_reg definition
+  *  offset: 0x6400
+  */
+ #define BNX2_NVM_COMMAND                              0x00006400
+ #define BNX2_NVM_COMMAND_RST                           (1L<<0)
+ #define BNX2_NVM_COMMAND_DONE                          (1L<<3)
+ #define BNX2_NVM_COMMAND_DOIT                          (1L<<4)
+ #define BNX2_NVM_COMMAND_WR                            (1L<<5)
+ #define BNX2_NVM_COMMAND_ERASE                                 (1L<<6)
+ #define BNX2_NVM_COMMAND_FIRST                                 (1L<<7)
+ #define BNX2_NVM_COMMAND_LAST                          (1L<<8)
+ #define BNX2_NVM_COMMAND_WREN                          (1L<<16)
+ #define BNX2_NVM_COMMAND_WRDI                          (1L<<17)
+ #define BNX2_NVM_COMMAND_EWSR                          (1L<<18)
+ #define BNX2_NVM_COMMAND_WRSR                          (1L<<19)
+ #define BNX2_NVM_COMMAND_RD_ID                                 (1L<<20)
+ #define BNX2_NVM_COMMAND_RD_STATUS                     (1L<<21)
+ #define BNX2_NVM_COMMAND_MODE_256                      (1L<<22)
+ #define BNX2_NVM_STATUS                                       0x00006404
+ #define BNX2_NVM_STATUS_PI_FSM_STATE                   (0xfL<<0)
+ #define BNX2_NVM_STATUS_EE_FSM_STATE                   (0xfL<<4)
+ #define BNX2_NVM_STATUS_EQ_FSM_STATE                   (0xfL<<8)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_XI               (0x1fL<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_IDLE_XI      (0L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD0_XI      (1L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD1_XI      (2L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD_FINISH0_XI       (3L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CMD_FINISH1_XI       (4L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_ADDR0_XI     (5L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WRITE_DATA0_XI       (6L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WRITE_DATA1_XI       (7L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WRITE_DATA2_XI       (8L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_DATA0_XI        (9L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_DATA1_XI        (10L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_DATA2_XI        (11L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID0_XI         (12L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID1_XI         (13L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID2_XI         (14L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID3_XI         (15L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_READ_STATUS_RDID4_XI         (16L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_CHECK_BUSY0_XI       (17L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_ST_WREN_XI   (18L<<0)
+ #define BNX2_NVM_STATUS_SPI_FSM_STATE_SPI_WAIT_XI      (19L<<0)
+ #define BNX2_NVM_WRITE                                        0x00006408
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE                         (0xffffffffL<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_BIT_BANG                (0L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EECLK           (1L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EEDATA          (2L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SCLK            (4L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_CS_B            (8L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SO              (16L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SI              (32L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SI_XI           (1L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SO_XI           (2L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_CS_B_XI                 (4L<<0)
+ #define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SCLK_XI                 (8L<<0)
+ #define BNX2_NVM_ADDR                                 0x0000640c
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE                   (0xffffffL<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_BIT_BANG          (0L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EECLK             (1L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EEDATA            (2L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SCLK              (4L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_CS_B              (8L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SO                        (16L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SI                        (32L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SI_XI             (1L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SO_XI             (2L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_CS_B_XI           (4L<<0)
+ #define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SCLK_XI           (8L<<0)
+ #define BNX2_NVM_READ                                 0x00006410
+ #define BNX2_NVM_READ_NVM_READ_VALUE                   (0xffffffffL<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_BIT_BANG          (0L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_EECLK             (1L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_EEDATA            (2L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_SCLK              (4L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_CS_B              (8L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_SO                        (16L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_SI                        (32L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_SI_XI             (1L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_SO_XI             (2L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_CS_B_XI           (4L<<0)
+ #define BNX2_NVM_READ_NVM_READ_VALUE_SCLK_XI           (8L<<0)
+ #define BNX2_NVM_CFG1                                 0x00006414
+ #define BNX2_NVM_CFG1_FLASH_MODE                       (1L<<0)
+ #define BNX2_NVM_CFG1_BUFFER_MODE                      (1L<<1)
+ #define BNX2_NVM_CFG1_PASS_MODE                                (1L<<2)
+ #define BNX2_NVM_CFG1_BITBANG_MODE                     (1L<<3)
+ #define BNX2_NVM_CFG1_STATUS_BIT                       (0x7L<<4)
+ #define BNX2_NVM_CFG1_STATUS_BIT_FLASH_RDY             (0L<<4)
+ #define BNX2_NVM_CFG1_STATUS_BIT_BUFFER_RDY            (7L<<4)
+ #define BNX2_NVM_CFG1_SPI_CLK_DIV                      (0xfL<<7)
+ #define BNX2_NVM_CFG1_SEE_CLK_DIV                      (0x7ffL<<11)
+ #define BNX2_NVM_CFG1_STRAP_CONTROL_0                  (1L<<23)
+ #define BNX2_NVM_CFG1_PROTECT_MODE                     (1L<<24)
+ #define BNX2_NVM_CFG1_FLASH_SIZE                       (1L<<25)
+ #define BNX2_NVM_CFG1_FW_USTRAP_1                      (1L<<26)
+ #define BNX2_NVM_CFG1_FW_USTRAP_0                      (1L<<27)
+ #define BNX2_NVM_CFG1_FW_USTRAP_2                      (1L<<28)
+ #define BNX2_NVM_CFG1_FW_USTRAP_3                      (1L<<29)
+ #define BNX2_NVM_CFG1_FW_FLASH_TYPE_EN                         (1L<<30)
+ #define BNX2_NVM_CFG1_COMPAT_BYPASSS                   (1L<<31)
+ #define BNX2_NVM_CFG2                                 0x00006418
+ #define BNX2_NVM_CFG2_ERASE_CMD                                (0xffL<<0)
+ #define BNX2_NVM_CFG2_DUMMY                            (0xffL<<8)
+ #define BNX2_NVM_CFG2_STATUS_CMD                       (0xffL<<16)
+ #define BNX2_NVM_CFG2_READ_ID                          (0xffL<<24)
+ #define BNX2_NVM_CFG3                                 0x0000641c
+ #define BNX2_NVM_CFG3_BUFFER_RD_CMD                    (0xffL<<0)
+ #define BNX2_NVM_CFG3_WRITE_CMD                                (0xffL<<8)
+ #define BNX2_NVM_CFG3_BUFFER_WRITE_CMD                         (0xffL<<16)
+ #define BNX2_NVM_CFG3_READ_CMD                                 (0xffL<<24)
+ #define BNX2_NVM_SW_ARB                                       0x00006420
+ #define BNX2_NVM_SW_ARB_ARB_REQ_SET0                   (1L<<0)
+ #define BNX2_NVM_SW_ARB_ARB_REQ_SET1                   (1L<<1)
+ #define BNX2_NVM_SW_ARB_ARB_REQ_SET2                   (1L<<2)
+ #define BNX2_NVM_SW_ARB_ARB_REQ_SET3                   (1L<<3)
+ #define BNX2_NVM_SW_ARB_ARB_REQ_CLR0                   (1L<<4)
+ #define BNX2_NVM_SW_ARB_ARB_REQ_CLR1                   (1L<<5)
+ #define BNX2_NVM_SW_ARB_ARB_REQ_CLR2                   (1L<<6)
+ #define BNX2_NVM_SW_ARB_ARB_REQ_CLR3                   (1L<<7)
+ #define BNX2_NVM_SW_ARB_ARB_ARB0                       (1L<<8)
+ #define BNX2_NVM_SW_ARB_ARB_ARB1                       (1L<<9)
+ #define BNX2_NVM_SW_ARB_ARB_ARB2                       (1L<<10)
+ #define BNX2_NVM_SW_ARB_ARB_ARB3                       (1L<<11)
+ #define BNX2_NVM_SW_ARB_REQ0                           (1L<<12)
+ #define BNX2_NVM_SW_ARB_REQ1                           (1L<<13)
+ #define BNX2_NVM_SW_ARB_REQ2                           (1L<<14)
+ #define BNX2_NVM_SW_ARB_REQ3                           (1L<<15)
+ #define BNX2_NVM_ACCESS_ENABLE                                0x00006424
+ #define BNX2_NVM_ACCESS_ENABLE_EN                      (1L<<0)
+ #define BNX2_NVM_ACCESS_ENABLE_WR_EN                   (1L<<1)
+ #define BNX2_NVM_WRITE1                                       0x00006428
+ #define BNX2_NVM_WRITE1_WREN_CMD                       (0xffL<<0)
+ #define BNX2_NVM_WRITE1_WRDI_CMD                       (0xffL<<8)
+ #define BNX2_NVM_WRITE1_SR_DATA                                (0xffL<<16)
+ #define BNX2_NVM_CFG4                                 0x0000642c
+ #define BNX2_NVM_CFG4_FLASH_SIZE                       (0x7L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_1MBIT                         (0L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_2MBIT                         (1L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_4MBIT                         (2L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_8MBIT                         (3L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_16MBIT                        (4L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_32MBIT                        (5L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_64MBIT                        (6L<<0)
+ #define BNX2_NVM_CFG4_FLASH_SIZE_128MBIT               (7L<<0)
+ #define BNX2_NVM_CFG4_FLASH_VENDOR                     (1L<<3)
+ #define BNX2_NVM_CFG4_FLASH_VENDOR_ST                  (0L<<3)
+ #define BNX2_NVM_CFG4_FLASH_VENDOR_ATMEL               (1L<<3)
+ #define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC           (0x3L<<4)
+ #define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT8      (0L<<4)
+ #define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT9      (1L<<4)
+ #define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT10     (2L<<4)
+ #define BNX2_NVM_CFG4_MODE_256_EMPTY_BIT_LOC_BIT11     (3L<<4)
+ #define BNX2_NVM_CFG4_STATUS_BIT_POLARITY              (1L<<6)
+ #define BNX2_NVM_CFG4_RESERVED                                 (0x1ffffffL<<7)
+ #define BNX2_NVM_RECONFIG                             0x00006430
+ #define BNX2_NVM_RECONFIG_ORIG_STRAP_VALUE             (0xfL<<0)
+ #define BNX2_NVM_RECONFIG_ORIG_STRAP_VALUE_ST          (0L<<0)
+ #define BNX2_NVM_RECONFIG_ORIG_STRAP_VALUE_ATMEL       (1L<<0)
+ #define BNX2_NVM_RECONFIG_RECONFIG_STRAP_VALUE                 (0xfL<<4)
+ #define BNX2_NVM_RECONFIG_RESERVED                     (0x7fffffL<<8)
+ #define BNX2_NVM_RECONFIG_RECONFIG_DONE                        (1L<<31)
+ /*
+  *  dma_reg definition
+  *  offset: 0xc00
+  */
+ #define BNX2_DMA_COMMAND                              0x00000c00
+ #define BNX2_DMA_COMMAND_ENABLE                                (1L<<0)
+ #define BNX2_DMA_STATUS                                       0x00000c04
+ #define BNX2_DMA_STATUS_PAR_ERROR_STATE                        (1L<<0)
+ #define BNX2_DMA_STATUS_READ_TRANSFERS_STAT            (1L<<16)
+ #define BNX2_DMA_STATUS_READ_DELAY_PCI_CLKS_STAT       (1L<<17)
+ #define BNX2_DMA_STATUS_BIG_READ_TRANSFERS_STAT                (1L<<18)
+ #define BNX2_DMA_STATUS_BIG_READ_DELAY_PCI_CLKS_STAT   (1L<<19)
+ #define BNX2_DMA_STATUS_BIG_READ_RETRY_AFTER_DATA_STAT         (1L<<20)
+ #define BNX2_DMA_STATUS_WRITE_TRANSFERS_STAT           (1L<<21)
+ #define BNX2_DMA_STATUS_WRITE_DELAY_PCI_CLKS_STAT      (1L<<22)
+ #define BNX2_DMA_STATUS_BIG_WRITE_TRANSFERS_STAT       (1L<<23)
+ #define BNX2_DMA_STATUS_BIG_WRITE_DELAY_PCI_CLKS_STAT  (1L<<24)
+ #define BNX2_DMA_STATUS_BIG_WRITE_RETRY_AFTER_DATA_STAT        (1L<<25)
+ #define BNX2_DMA_STATUS_GLOBAL_ERR_XI                  (1L<<0)
+ #define BNX2_DMA_STATUS_BME_XI                                 (1L<<4)
+ #define BNX2_DMA_CONFIG                                       0x00000c08
+ #define BNX2_DMA_CONFIG_DATA_BYTE_SWAP                         (1L<<0)
+ #define BNX2_DMA_CONFIG_DATA_WORD_SWAP                         (1L<<1)
+ #define BNX2_DMA_CONFIG_CNTL_BYTE_SWAP                         (1L<<4)
+ #define BNX2_DMA_CONFIG_CNTL_WORD_SWAP                         (1L<<5)
+ #define BNX2_DMA_CONFIG_ONE_DMA                                (1L<<6)
+ #define BNX2_DMA_CONFIG_CNTL_TWO_DMA                   (1L<<7)
+ #define BNX2_DMA_CONFIG_CNTL_FPGA_MODE                         (1L<<8)
+ #define BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA             (1L<<10)
+ #define BNX2_DMA_CONFIG_CNTL_PCI_COMP_DLY              (1L<<11)
+ #define BNX2_DMA_CONFIG_NO_RCHANS_IN_USE               (0xfL<<12)
+ #define BNX2_DMA_CONFIG_NO_WCHANS_IN_USE               (0xfL<<16)
+ #define BNX2_DMA_CONFIG_PCI_CLK_CMP_BITS               (0x7L<<20)
+ #define BNX2_DMA_CONFIG_PCI_FAST_CLK_CMP               (1L<<23)
+ #define BNX2_DMA_CONFIG_BIG_SIZE                       (0xfL<<24)
+ #define BNX2_DMA_CONFIG_BIG_SIZE_NONE                  (0x0L<<24)
+ #define BNX2_DMA_CONFIG_BIG_SIZE_64                    (0x1L<<24)
+ #define BNX2_DMA_CONFIG_BIG_SIZE_128                   (0x2L<<24)
+ #define BNX2_DMA_CONFIG_BIG_SIZE_256                   (0x4L<<24)
+ #define BNX2_DMA_CONFIG_BIG_SIZE_512                   (0x8L<<24)
+ #define BNX2_DMA_CONFIG_DAT_WBSWAP_MODE_XI             (0x3L<<0)
+ #define BNX2_DMA_CONFIG_CTL_WBSWAP_MODE_XI             (0x3L<<4)
+ #define BNX2_DMA_CONFIG_MAX_PL_XI                      (0x7L<<12)
+ #define BNX2_DMA_CONFIG_MAX_PL_128B_XI                         (0L<<12)
+ #define BNX2_DMA_CONFIG_MAX_PL_256B_XI                         (1L<<12)
+ #define BNX2_DMA_CONFIG_MAX_PL_512B_XI                         (2L<<12)
+ #define BNX2_DMA_CONFIG_MAX_PL_EN_XI                   (1L<<15)
+ #define BNX2_DMA_CONFIG_MAX_RRS_XI                     (0x7L<<16)
+ #define BNX2_DMA_CONFIG_MAX_RRS_128B_XI                        (0L<<16)
+ #define BNX2_DMA_CONFIG_MAX_RRS_256B_XI                        (1L<<16)
+ #define BNX2_DMA_CONFIG_MAX_RRS_512B_XI                        (2L<<16)
+ #define BNX2_DMA_CONFIG_MAX_RRS_1024B_XI               (3L<<16)
+ #define BNX2_DMA_CONFIG_MAX_RRS_2048B_XI               (4L<<16)
+ #define BNX2_DMA_CONFIG_MAX_RRS_4096B_XI               (5L<<16)
+ #define BNX2_DMA_CONFIG_MAX_RRS_EN_XI                  (1L<<19)
+ #define BNX2_DMA_CONFIG_NO_64SWAP_EN_XI                        (1L<<31)
+ #define BNX2_DMA_BLACKOUT                             0x00000c0c
+ #define BNX2_DMA_BLACKOUT_RD_RETRY_BLACKOUT            (0xffL<<0)
+ #define BNX2_DMA_BLACKOUT_2ND_RD_RETRY_BLACKOUT                (0xffL<<8)
+ #define BNX2_DMA_BLACKOUT_WR_RETRY_BLACKOUT            (0xffL<<16)
+ #define BNX2_DMA_READ_MASTER_SETTING_0                        0x00000c10
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_NO_SNOOP   (1L<<0)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_RELAX_ORDER        (1L<<1)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_PRIORITY   (1L<<2)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_TRAFFIC_CLASS      (0x7L<<4)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TBDC_PARAM_EN   (1L<<7)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_NO_SNOOP   (1L<<8)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_RELAX_ORDER        (1L<<9)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_PRIORITY   (1L<<10)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_TRAFFIC_CLASS      (0x7L<<12)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_RBDC_PARAM_EN   (1L<<15)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_NO_SNOOP   (1L<<16)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_RELAX_ORDER        (1L<<17)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_PRIORITY   (1L<<18)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_TRAFFIC_CLASS      (0x7L<<20)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_TDMA_PARAM_EN   (1L<<23)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_CTX_NO_SNOOP    (1L<<24)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_CTX_RELAX_ORDER         (1L<<25)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_CTX_PRIORITY    (1L<<26)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_CTX_TRAFFIC_CLASS       (0x7L<<28)
+ #define BNX2_DMA_READ_MASTER_SETTING_0_CTX_PARAM_EN    (1L<<31)
+ #define BNX2_DMA_READ_MASTER_SETTING_1                        0x00000c14
+ #define BNX2_DMA_READ_MASTER_SETTING_1_COM_NO_SNOOP    (1L<<0)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_COM_RELAX_ORDER         (1L<<1)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_COM_PRIORITY    (1L<<2)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_COM_TRAFFIC_CLASS       (0x7L<<4)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_COM_PARAM_EN    (1L<<7)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_CP_NO_SNOOP     (1L<<8)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_CP_RELAX_ORDER  (1L<<9)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_CP_PRIORITY     (1L<<10)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_CP_TRAFFIC_CLASS        (0x7L<<12)
+ #define BNX2_DMA_READ_MASTER_SETTING_1_CP_PARAM_EN     (1L<<15)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0                       0x00000c18
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_NO_SNOOP    (1L<<0)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_RELAX_ORDER         (1L<<1)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_PRIORITY    (1L<<2)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_CS_VLD      (1L<<3)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_TRAFFIC_CLASS       (0x7L<<4)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_HC_PARAM_EN    (1L<<7)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_NO_SNOOP  (1L<<8)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_RELAX_ORDER       (1L<<9)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_PRIORITY  (1L<<10)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_CS_VLD    (1L<<11)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_TRAFFIC_CLASS     (0x7L<<12)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_RDMA_PARAM_EN  (1L<<15)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_NO_SNOOP   (1L<<24)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_RELAX_ORDER        (1L<<25)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_PRIORITY   (1L<<26)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_CS_VLD     (1L<<27)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_TRAFFIC_CLASS      (0x7L<<28)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_0_CTX_PARAM_EN   (1L<<31)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1                       0x00000c1c
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_NO_SNOOP   (1L<<0)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_RELAX_ORDER        (1L<<1)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_PRIORITY   (1L<<2)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_CS_VLD     (1L<<3)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_TRAFFIC_CLASS      (0x7L<<4)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_COM_PARAM_EN   (1L<<7)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_NO_SNOOP    (1L<<8)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_RELAX_ORDER         (1L<<9)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_PRIORITY    (1L<<10)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_CS_VLD      (1L<<11)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_TRAFFIC_CLASS       (0x7L<<12)
+ #define BNX2_DMA_WRITE_MASTER_SETTING_1_CP_PARAM_EN    (1L<<15)
+ #define BNX2_DMA_ARBITER                              0x00000c20
+ #define BNX2_DMA_ARBITER_NUM_READS                     (0x7L<<0)
+ #define BNX2_DMA_ARBITER_WR_ARB_MODE                   (1L<<4)
+ #define BNX2_DMA_ARBITER_WR_ARB_MODE_STRICT            (0L<<4)
+ #define BNX2_DMA_ARBITER_WR_ARB_MODE_RND_RBN           (1L<<4)
+ #define BNX2_DMA_ARBITER_RD_ARB_MODE                   (0x3L<<5)
+ #define BNX2_DMA_ARBITER_RD_ARB_MODE_STRICT            (0L<<5)
+ #define BNX2_DMA_ARBITER_RD_ARB_MODE_RND_RBN           (1L<<5)
+ #define BNX2_DMA_ARBITER_RD_ARB_MODE_WGT_RND_RBN       (2L<<5)
+ #define BNX2_DMA_ARBITER_ALT_MODE_EN                   (1L<<8)
+ #define BNX2_DMA_ARBITER_RR_MODE                       (1L<<9)
+ #define BNX2_DMA_ARBITER_TIMER_MODE                    (1L<<10)
+ #define BNX2_DMA_ARBITER_OUSTD_READ_REQ                        (0xfL<<12)
+ #define BNX2_DMA_ARB_TIMERS                           0x00000c24
+ #define BNX2_DMA_ARB_TIMERS_RD_DRR_WAIT_TIME           (0xffL<<0)
+ #define BNX2_DMA_ARB_TIMERS_TM_MIN_TIMEOUT             (0xffL<<12)
+ #define BNX2_DMA_ARB_TIMERS_TM_MAX_TIMEOUT             (0xfffL<<20)
+ #define BNX2_DMA_DEBUG_VECT_PEEK                      0x00000c2c
+ #define BNX2_DMA_DEBUG_VECT_PEEK_1_VALUE               (0x7ffL<<0)
+ #define BNX2_DMA_DEBUG_VECT_PEEK_1_PEEK_EN             (1L<<11)
+ #define BNX2_DMA_DEBUG_VECT_PEEK_1_SEL                         (0xfL<<12)
+ #define BNX2_DMA_DEBUG_VECT_PEEK_2_VALUE               (0x7ffL<<16)
+ #define BNX2_DMA_DEBUG_VECT_PEEK_2_PEEK_EN             (1L<<27)
+ #define BNX2_DMA_DEBUG_VECT_PEEK_2_SEL                         (0xfL<<28)
+ #define BNX2_DMA_TAG_RAM_00                           0x00000c30
+ #define BNX2_DMA_TAG_RAM_00_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_00_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_00_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_00_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_00_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_00_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_00_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_00_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_00_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_00_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_00_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_00_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_00_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_00_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_01                           0x00000c34
+ #define BNX2_DMA_TAG_RAM_01_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_01_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_01_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_01_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_01_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_01_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_01_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_01_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_01_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_01_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_01_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_01_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_01_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_01_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_02                           0x00000c38
+ #define BNX2_DMA_TAG_RAM_02_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_02_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_02_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_02_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_02_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_02_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_02_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_02_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_02_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_02_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_02_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_02_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_02_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_02_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_03                           0x00000c3c
+ #define BNX2_DMA_TAG_RAM_03_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_03_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_03_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_03_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_03_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_03_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_03_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_03_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_03_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_03_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_03_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_03_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_03_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_03_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_04                           0x00000c40
+ #define BNX2_DMA_TAG_RAM_04_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_04_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_04_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_04_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_04_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_04_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_04_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_04_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_04_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_04_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_04_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_04_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_04_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_04_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_05                           0x00000c44
+ #define BNX2_DMA_TAG_RAM_05_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_05_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_05_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_05_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_05_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_05_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_05_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_05_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_05_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_05_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_05_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_05_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_05_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_05_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_06                           0x00000c48
+ #define BNX2_DMA_TAG_RAM_06_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_06_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_06_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_06_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_06_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_06_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_06_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_06_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_06_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_06_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_06_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_06_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_06_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_06_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_07                           0x00000c4c
+ #define BNX2_DMA_TAG_RAM_07_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_07_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_07_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_07_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_07_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_07_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_07_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_07_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_07_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_07_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_07_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_07_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_07_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_07_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_08                           0x00000c50
+ #define BNX2_DMA_TAG_RAM_08_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_08_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_08_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_08_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_08_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_08_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_08_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_08_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_08_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_08_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_08_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_08_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_08_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_08_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_09                           0x00000c54
+ #define BNX2_DMA_TAG_RAM_09_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_09_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_09_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_09_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_09_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_09_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_09_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_09_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_09_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_09_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_09_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_09_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_09_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_09_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_10                           0x00000c58
+ #define BNX2_DMA_TAG_RAM_10_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_10_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_10_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_10_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_10_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_10_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_10_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_10_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_10_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_10_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_10_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_10_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_10_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_10_VALID                      (1L<<10)
+ #define BNX2_DMA_TAG_RAM_11                           0x00000c5c
+ #define BNX2_DMA_TAG_RAM_11_CHANNEL                    (0xfL<<0)
+ #define BNX2_DMA_TAG_RAM_11_MASTER                     (0x7L<<4)
+ #define BNX2_DMA_TAG_RAM_11_MASTER_CTX                         (0L<<4)
+ #define BNX2_DMA_TAG_RAM_11_MASTER_RBDC                        (1L<<4)
+ #define BNX2_DMA_TAG_RAM_11_MASTER_TBDC                        (2L<<4)
+ #define BNX2_DMA_TAG_RAM_11_MASTER_COM                         (3L<<4)
+ #define BNX2_DMA_TAG_RAM_11_MASTER_CP                  (4L<<4)
+ #define BNX2_DMA_TAG_RAM_11_MASTER_TDMA                        (5L<<4)
+ #define BNX2_DMA_TAG_RAM_11_SWAP                       (0x3L<<7)
+ #define BNX2_DMA_TAG_RAM_11_SWAP_CONFIG                        (0L<<7)
+ #define BNX2_DMA_TAG_RAM_11_SWAP_DATA                  (1L<<7)
+ #define BNX2_DMA_TAG_RAM_11_SWAP_CONTROL               (2L<<7)
+ #define BNX2_DMA_TAG_RAM_11_FUNCTION                   (1L<<9)
+ #define BNX2_DMA_TAG_RAM_11_VALID                      (1L<<10)
+ #define BNX2_DMA_RCHAN_STAT_22                                0x00000c60
+ #define BNX2_DMA_RCHAN_STAT_30                                0x00000c64
+ #define BNX2_DMA_RCHAN_STAT_31                                0x00000c68
+ #define BNX2_DMA_RCHAN_STAT_32                                0x00000c6c
+ #define BNX2_DMA_RCHAN_STAT_40                                0x00000c70
+ #define BNX2_DMA_RCHAN_STAT_41                                0x00000c74
+ #define BNX2_DMA_RCHAN_STAT_42                                0x00000c78
+ #define BNX2_DMA_RCHAN_STAT_50                                0x00000c7c
+ #define BNX2_DMA_RCHAN_STAT_51                                0x00000c80
+ #define BNX2_DMA_RCHAN_STAT_52                                0x00000c84
+ #define BNX2_DMA_RCHAN_STAT_60                                0x00000c88
+ #define BNX2_DMA_RCHAN_STAT_61                                0x00000c8c
+ #define BNX2_DMA_RCHAN_STAT_62                                0x00000c90
+ #define BNX2_DMA_RCHAN_STAT_70                                0x00000c94
+ #define BNX2_DMA_RCHAN_STAT_71                                0x00000c98
+ #define BNX2_DMA_RCHAN_STAT_72                                0x00000c9c
+ #define BNX2_DMA_WCHAN_STAT_00                                0x00000ca0
+ #define BNX2_DMA_WCHAN_STAT_00_WCHAN_STA_HOST_ADDR_LOW         (0xffffffffL<<0)
+ #define BNX2_DMA_WCHAN_STAT_01                                0x00000ca4
+ #define BNX2_DMA_WCHAN_STAT_01_WCHAN_STA_HOST_ADDR_HIGH        (0xffffffffL<<0)
+ #define BNX2_DMA_WCHAN_STAT_02                                0x00000ca8
+ #define BNX2_DMA_WCHAN_STAT_02_LENGTH                  (0xffffL<<0)
+ #define BNX2_DMA_WCHAN_STAT_02_WORD_SWAP               (1L<<16)
+ #define BNX2_DMA_WCHAN_STAT_02_BYTE_SWAP               (1L<<17)
+ #define BNX2_DMA_WCHAN_STAT_02_PRIORITY_LVL            (1L<<18)
+ #define BNX2_DMA_WCHAN_STAT_10                                0x00000cac
+ #define BNX2_DMA_WCHAN_STAT_11                                0x00000cb0
+ #define BNX2_DMA_WCHAN_STAT_12                                0x00000cb4
+ #define BNX2_DMA_WCHAN_STAT_20                                0x00000cb8
+ #define BNX2_DMA_WCHAN_STAT_21                                0x00000cbc
+ #define BNX2_DMA_WCHAN_STAT_22                                0x00000cc0
+ #define BNX2_DMA_WCHAN_STAT_30                                0x00000cc4
+ #define BNX2_DMA_WCHAN_STAT_31                                0x00000cc8
+ #define BNX2_DMA_WCHAN_STAT_32                                0x00000ccc
+ #define BNX2_DMA_WCHAN_STAT_40                                0x00000cd0
+ #define BNX2_DMA_WCHAN_STAT_41                                0x00000cd4
+ #define BNX2_DMA_WCHAN_STAT_42                                0x00000cd8
+ #define BNX2_DMA_WCHAN_STAT_50                                0x00000cdc
+ #define BNX2_DMA_WCHAN_STAT_51                                0x00000ce0
+ #define BNX2_DMA_WCHAN_STAT_52                                0x00000ce4
+ #define BNX2_DMA_WCHAN_STAT_60                                0x00000ce8
+ #define BNX2_DMA_WCHAN_STAT_61                                0x00000cec
+ #define BNX2_DMA_WCHAN_STAT_62                                0x00000cf0
+ #define BNX2_DMA_WCHAN_STAT_70                                0x00000cf4
+ #define BNX2_DMA_WCHAN_STAT_71                                0x00000cf8
+ #define BNX2_DMA_WCHAN_STAT_72                                0x00000cfc
+ #define BNX2_DMA_ARB_STAT_00                          0x00000d00
+ #define BNX2_DMA_ARB_STAT_00_MASTER                    (0xffffL<<0)
+ #define BNX2_DMA_ARB_STAT_00_MASTER_ENC                        (0xffL<<16)
+ #define BNX2_DMA_ARB_STAT_00_CUR_BINMSTR               (0xffL<<24)
+ #define BNX2_DMA_ARB_STAT_01                          0x00000d04
+ #define BNX2_DMA_ARB_STAT_01_LPR_RPTR                  (0xfL<<0)
+ #define BNX2_DMA_ARB_STAT_01_LPR_WPTR                  (0xfL<<4)
+ #define BNX2_DMA_ARB_STAT_01_LPB_RPTR                  (0xfL<<8)
+ #define BNX2_DMA_ARB_STAT_01_LPB_WPTR                  (0xfL<<12)
+ #define BNX2_DMA_ARB_STAT_01_HPR_RPTR                  (0xfL<<16)
+ #define BNX2_DMA_ARB_STAT_01_HPR_WPTR                  (0xfL<<20)
+ #define BNX2_DMA_ARB_STAT_01_HPB_RPTR                  (0xfL<<24)
+ #define BNX2_DMA_ARB_STAT_01_HPB_WPTR                  (0xfL<<28)
+ #define BNX2_DMA_FUSE_CTRL0_CMD                               0x00000f00
+ #define BNX2_DMA_FUSE_CTRL0_CMD_PWRUP_DONE             (1L<<0)
+ #define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT_DONE             (1L<<1)
+ #define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT                  (1L<<2)
+ #define BNX2_DMA_FUSE_CTRL0_CMD_LOAD                   (1L<<3)
+ #define BNX2_DMA_FUSE_CTRL0_CMD_SEL                    (0xfL<<8)
+ #define BNX2_DMA_FUSE_CTRL0_DATA                      0x00000f04
+ #define BNX2_DMA_FUSE_CTRL1_CMD                               0x00000f08
+ #define BNX2_DMA_FUSE_CTRL1_CMD_PWRUP_DONE             (1L<<0)
+ #define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT_DONE             (1L<<1)
+ #define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT                  (1L<<2)
+ #define BNX2_DMA_FUSE_CTRL1_CMD_LOAD                   (1L<<3)
+ #define BNX2_DMA_FUSE_CTRL1_CMD_SEL                    (0xfL<<8)
+ #define BNX2_DMA_FUSE_CTRL1_DATA                      0x00000f0c
+ #define BNX2_DMA_FUSE_CTRL2_CMD                               0x00000f10
+ #define BNX2_DMA_FUSE_CTRL2_CMD_PWRUP_DONE             (1L<<0)
+ #define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT_DONE             (1L<<1)
+ #define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT                  (1L<<2)
+ #define BNX2_DMA_FUSE_CTRL2_CMD_LOAD                   (1L<<3)
+ #define BNX2_DMA_FUSE_CTRL2_CMD_SEL                    (0xfL<<8)
+ #define BNX2_DMA_FUSE_CTRL2_DATA                      0x00000f14
+ /*
+  *  context_reg definition
+  *  offset: 0x1000
+  */
+ #define BNX2_CTX_COMMAND                              0x00001000
+ #define BNX2_CTX_COMMAND_ENABLED                       (1L<<0)
+ #define BNX2_CTX_COMMAND_DISABLE_USAGE_CNT             (1L<<1)
+ #define BNX2_CTX_COMMAND_DISABLE_PLRU                  (1L<<2)
+ #define BNX2_CTX_COMMAND_DISABLE_COMBINE_READ          (1L<<3)
+ #define BNX2_CTX_COMMAND_FLUSH_AHEAD                   (0x1fL<<8)
+ #define BNX2_CTX_COMMAND_MEM_INIT                      (1L<<13)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE                     (0xfL<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_256                         (0L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_512                         (1L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_1K                  (2L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_2K                  (3L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_4K                  (4L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_8K                  (5L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_16K                         (6L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_32K                         (7L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_64K                         (8L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_128K                        (9L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_256K                        (10L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_512K                        (11L<<16)
+ #define BNX2_CTX_COMMAND_PAGE_SIZE_1M                  (12L<<16)
+ #define BNX2_CTX_STATUS                                       0x00001004
+ #define BNX2_CTX_STATUS_LOCK_WAIT                      (1L<<0)
+ #define BNX2_CTX_STATUS_READ_STAT                      (1L<<16)
+ #define BNX2_CTX_STATUS_WRITE_STAT                     (1L<<17)
+ #define BNX2_CTX_STATUS_ACC_STALL_STAT                         (1L<<18)
+ #define BNX2_CTX_STATUS_LOCK_STALL_STAT                        (1L<<19)
+ #define BNX2_CTX_STATUS_EXT_READ_STAT                  (1L<<20)
+ #define BNX2_CTX_STATUS_EXT_WRITE_STAT                         (1L<<21)
+ #define BNX2_CTX_STATUS_MISS_STAT                      (1L<<22)
+ #define BNX2_CTX_STATUS_HIT_STAT                       (1L<<23)
+ #define BNX2_CTX_STATUS_DEAD_LOCK                      (1L<<24)
+ #define BNX2_CTX_STATUS_USAGE_CNT_ERR                  (1L<<25)
+ #define BNX2_CTX_STATUS_INVALID_PAGE                   (1L<<26)
+ #define BNX2_CTX_VIRT_ADDR                            0x00001008
+ #define BNX2_CTX_VIRT_ADDR_VIRT_ADDR                   (0x7fffL<<6)
+ #define BNX2_CTX_PAGE_TBL                             0x0000100c
+ #define BNX2_CTX_PAGE_TBL_PAGE_TBL                     (0x3fffL<<6)
+ #define BNX2_CTX_DATA_ADR                             0x00001010
+ #define BNX2_CTX_DATA_ADR_DATA_ADR                     (0x7ffffL<<2)
+ #define BNX2_CTX_DATA                                 0x00001014
+ #define BNX2_CTX_LOCK                                 0x00001018
+ #define BNX2_CTX_LOCK_TYPE                             (0x7L<<0)
+ #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_VOID              (0x0L<<0)
+ #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_PROTOCOL          (0x1L<<0)
+ #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TX                        (0x2L<<0)
+ #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TIMER             (0x4L<<0)
+ #define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_COMPLETE          (0x7L<<0)
+ #define BNX2_CTX_LOCK_TYPE_VOID_XI                     (0L<<0)
+ #define BNX2_CTX_LOCK_TYPE_PROTOCOL_XI                         (1L<<0)
+ #define BNX2_CTX_LOCK_TYPE_TX_XI                       (2L<<0)
+ #define BNX2_CTX_LOCK_TYPE_TIMER_XI                    (4L<<0)
+ #define BNX2_CTX_LOCK_TYPE_COMPLETE_XI                         (7L<<0)
+ #define BNX2_CTX_LOCK_CID_VALUE                                (0x3fffL<<7)
+ #define BNX2_CTX_LOCK_GRANTED                          (1L<<26)
+ #define BNX2_CTX_LOCK_MODE                             (0x7L<<27)
+ #define BNX2_CTX_LOCK_MODE_UNLOCK                      (0x0L<<27)
+ #define BNX2_CTX_LOCK_MODE_IMMEDIATE                   (0x1L<<27)
+ #define BNX2_CTX_LOCK_MODE_SURE                                (0x2L<<27)
+ #define BNX2_CTX_LOCK_STATUS                           (1L<<30)
+ #define BNX2_CTX_LOCK_REQ                              (1L<<31)
+ #define BNX2_CTX_CTX_CTRL                             0x0000101c
+ #define BNX2_CTX_CTX_CTRL_CTX_ADDR                     (0x7ffffL<<2)
+ #define BNX2_CTX_CTX_CTRL_MOD_USAGE_CNT                        (0x3L<<21)
+ #define BNX2_CTX_CTX_CTRL_NO_RAM_ACC                   (1L<<23)
+ #define BNX2_CTX_CTX_CTRL_PREFETCH_SIZE                        (0x3L<<24)
+ #define BNX2_CTX_CTX_CTRL_ATTR                                 (1L<<26)
+ #define BNX2_CTX_CTX_CTRL_WRITE_REQ                    (1L<<30)
+ #define BNX2_CTX_CTX_CTRL_READ_REQ                     (1L<<31)
+ #define BNX2_CTX_CTX_DATA                             0x00001020
+ #define BNX2_CTX_ACCESS_STATUS                                0x00001040
+ #define BNX2_CTX_ACCESS_STATUS_MASTERENCODED           (0xfL<<0)
+ #define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYSM          (0x3L<<10)
+ #define BNX2_CTX_ACCESS_STATUS_PAGETABLEINITSM                 (0x3L<<12)
+ #define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYINITSM      (0x3L<<14)
+ #define BNX2_CTX_ACCESS_STATUS_QUALIFIED_REQUEST       (0x7ffL<<17)
+ #define BNX2_CTX_ACCESS_STATUS_CAMMASTERENCODED_XI     (0x1fL<<0)
+ #define BNX2_CTX_ACCESS_STATUS_CACHEMASTERENCODED_XI   (0x1fL<<5)
+ #define BNX2_CTX_ACCESS_STATUS_REQUEST_XI              (0x3fffffL<<10)
+ #define BNX2_CTX_DBG_LOCK_STATUS                      0x00001044
+ #define BNX2_CTX_DBG_LOCK_STATUS_SM                    (0x3ffL<<0)
+ #define BNX2_CTX_DBG_LOCK_STATUS_MATCH                         (0x3ffL<<22)
+ #define BNX2_CTX_CACHE_CTRL_STATUS                    0x00001048
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RFIFO_OVERFLOW      (1L<<0)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_INVALID_READ_COMP   (1L<<1)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_FLUSH_START                 (1L<<6)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_FREE_ENTRY_CNT      (0x3fL<<7)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_CACHE_ENTRY_NEEDED  (0x3fL<<13)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN0_ACTIVE     (1L<<19)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN1_ACTIVE     (1L<<20)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN2_ACTIVE     (1L<<21)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN3_ACTIVE     (1L<<22)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN4_ACTIVE     (1L<<23)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN5_ACTIVE     (1L<<24)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN6_ACTIVE     (1L<<25)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN7_ACTIVE     (1L<<26)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN8_ACTIVE     (1L<<27)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN9_ACTIVE     (1L<<28)
+ #define BNX2_CTX_CACHE_CTRL_STATUS_RD_CHAN10_ACTIVE    (1L<<29)
+ #define BNX2_CTX_CACHE_CTRL_SM_STATUS                 0x0000104c
+ #define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_DWC           (0x7L<<0)
+ #define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_WFIFOC                (0x7L<<3)
+ #define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_RTAGC                 (0x7L<<6)
+ #define BNX2_CTX_CACHE_CTRL_SM_STATUS_CS_RFIFOC                (0x7L<<9)
+ #define BNX2_CTX_CACHE_CTRL_SM_STATUS_INVALID_BLK_ADDR         (0x7fffL<<16)
+ #define BNX2_CTX_CACHE_STATUS                         0x00001050
+ #define BNX2_CTX_CACHE_STATUS_HELD_ENTRIES             (0x3ffL<<0)
+ #define BNX2_CTX_CACHE_STATUS_MAX_HELD_ENTRIES                 (0x3ffL<<16)
+ #define BNX2_CTX_DMA_STATUS                           0x00001054
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN0_STATUS            (0x3L<<0)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN1_STATUS            (0x3L<<2)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN2_STATUS            (0x3L<<4)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN3_STATUS            (0x3L<<6)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN4_STATUS            (0x3L<<8)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN5_STATUS            (0x3L<<10)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN6_STATUS            (0x3L<<12)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN7_STATUS            (0x3L<<14)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN8_STATUS            (0x3L<<16)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN9_STATUS            (0x3L<<18)
+ #define BNX2_CTX_DMA_STATUS_RD_CHAN10_STATUS           (0x3L<<20)
+ #define BNX2_CTX_REP_STATUS                           0x00001058
+ #define BNX2_CTX_REP_STATUS_ERROR_ENTRY                        (0x3ffL<<0)
+ #define BNX2_CTX_REP_STATUS_ERROR_CLIENT_ID            (0x1fL<<10)
+ #define BNX2_CTX_REP_STATUS_USAGE_CNT_MAX_ERR          (1L<<16)
+ #define BNX2_CTX_REP_STATUS_USAGE_CNT_MIN_ERR          (1L<<17)
+ #define BNX2_CTX_REP_STATUS_USAGE_CNT_MISS_ERR                 (1L<<18)
+ #define BNX2_CTX_CKSUM_ERROR_STATUS                   0x0000105c
+ #define BNX2_CTX_CKSUM_ERROR_STATUS_CALCULATED                 (0xffffL<<0)
+ #define BNX2_CTX_CKSUM_ERROR_STATUS_EXPECTED           (0xffffL<<16)
+ #define BNX2_CTX_CHNL_LOCK_STATUS_0                   0x00001080
+ #define BNX2_CTX_CHNL_LOCK_STATUS_0_CID                        (0x3fffL<<0)
+ #define BNX2_CTX_CHNL_LOCK_STATUS_0_TYPE               (0x3L<<14)
+ #define BNX2_CTX_CHNL_LOCK_STATUS_0_MODE               (1L<<16)
+ #define BNX2_CTX_CHNL_LOCK_STATUS_0_MODE_XI            (1L<<14)
+ #define BNX2_CTX_CHNL_LOCK_STATUS_0_TYPE_XI            (0x7L<<15)
+ #define BNX2_CTX_CHNL_LOCK_STATUS_1                   0x00001084
+ #define BNX2_CTX_CHNL_LOCK_STATUS_2                   0x00001088
+ #define BNX2_CTX_CHNL_LOCK_STATUS_3                   0x0000108c
+ #define BNX2_CTX_CHNL_LOCK_STATUS_4                   0x00001090
+ #define BNX2_CTX_CHNL_LOCK_STATUS_5                   0x00001094
+ #define BNX2_CTX_CHNL_LOCK_STATUS_6                   0x00001098
+ #define BNX2_CTX_CHNL_LOCK_STATUS_7                   0x0000109c
+ #define BNX2_CTX_CHNL_LOCK_STATUS_8                   0x000010a0
+ #define BNX2_CTX_CHNL_LOCK_STATUS_9                   0x000010a4
+ #define BNX2_CTX_CACHE_DATA                           0x000010c4
+ #define BNX2_CTX_HOST_PAGE_TBL_CTRL                   0x000010c8
+ #define BNX2_CTX_HOST_PAGE_TBL_CTRL_PAGE_TBL_ADDR      (0x1ffL<<0)
+ #define BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ          (1L<<30)
+ #define BNX2_CTX_HOST_PAGE_TBL_CTRL_READ_REQ           (1L<<31)
+ #define BNX2_CTX_HOST_PAGE_TBL_DATA0                  0x000010cc
+ #define BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID             (1L<<0)
+ #define BNX2_CTX_HOST_PAGE_TBL_DATA0_VALUE             (0xffffffL<<8)
+ #define BNX2_CTX_HOST_PAGE_TBL_DATA1                  0x000010d0
+ #define BNX2_CTX_CAM_CTRL                             0x000010d4
+ #define BNX2_CTX_CAM_CTRL_CAM_ADDR                     (0x3ffL<<0)
+ #define BNX2_CTX_CAM_CTRL_RESET                                (1L<<27)
+ #define BNX2_CTX_CAM_CTRL_INVALIDATE                   (1L<<28)
+ #define BNX2_CTX_CAM_CTRL_SEARCH                       (1L<<29)
+ #define BNX2_CTX_CAM_CTRL_WRITE_REQ                    (1L<<30)
+ #define BNX2_CTX_CAM_CTRL_READ_REQ                     (1L<<31)
+ /*
+  *  emac_reg definition
+  *  offset: 0x1400
+  */
+ #define BNX2_EMAC_MODE                                        0x00001400
+ #define BNX2_EMAC_MODE_RESET                           (1L<<0)
+ #define BNX2_EMAC_MODE_HALF_DUPLEX                     (1L<<1)
+ #define BNX2_EMAC_MODE_PORT                            (0x3L<<2)
+ #define BNX2_EMAC_MODE_PORT_NONE                       (0L<<2)
+ #define BNX2_EMAC_MODE_PORT_MII                                (1L<<2)
+ #define BNX2_EMAC_MODE_PORT_GMII                       (2L<<2)
+ #define BNX2_EMAC_MODE_PORT_MII_10M                    (3L<<2)
+ #define BNX2_EMAC_MODE_MAC_LOOP                                (1L<<4)
+ #define BNX2_EMAC_MODE_25G_MODE                                (1L<<5)
+ #define BNX2_EMAC_MODE_TAGGED_MAC_CTL                  (1L<<7)
+ #define BNX2_EMAC_MODE_TX_BURST                                (1L<<8)
+ #define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA              (1L<<9)
+ #define BNX2_EMAC_MODE_EXT_LINK_POL                    (1L<<10)
+ #define BNX2_EMAC_MODE_FORCE_LINK                      (1L<<11)
+ #define BNX2_EMAC_MODE_SERDES_MODE                     (1L<<12)
+ #define BNX2_EMAC_MODE_BOND_OVRD                       (1L<<13)
+ #define BNX2_EMAC_MODE_MPKT                            (1L<<18)
+ #define BNX2_EMAC_MODE_MPKT_RCVD                       (1L<<19)
+ #define BNX2_EMAC_MODE_ACPI_RCVD                       (1L<<20)
+ #define BNX2_EMAC_STATUS                              0x00001404
+ #define BNX2_EMAC_STATUS_LINK                          (1L<<11)
+ #define BNX2_EMAC_STATUS_LINK_CHANGE                   (1L<<12)
+ #define BNX2_EMAC_STATUS_SERDES_AUTONEG_COMPLETE       (1L<<13)
+ #define BNX2_EMAC_STATUS_SERDES_AUTONEG_CHANGE                 (1L<<14)
+ #define BNX2_EMAC_STATUS_SERDES_NXT_PG_CHANGE          (1L<<16)
+ #define BNX2_EMAC_STATUS_SERDES_RX_CONFIG_IS_0                 (1L<<17)
+ #define BNX2_EMAC_STATUS_SERDES_RX_CONFIG_IS_0_CHANGE  (1L<<18)
+ #define BNX2_EMAC_STATUS_MI_COMPLETE                   (1L<<22)
+ #define BNX2_EMAC_STATUS_MI_INT                                (1L<<23)
+ #define BNX2_EMAC_STATUS_AP_ERROR                      (1L<<24)
+ #define BNX2_EMAC_STATUS_PARITY_ERROR_STATE            (1L<<31)
+ #define BNX2_EMAC_ATTENTION_ENA                               0x00001408
+ #define BNX2_EMAC_ATTENTION_ENA_LINK                   (1L<<11)
+ #define BNX2_EMAC_ATTENTION_ENA_AUTONEG_CHANGE                 (1L<<14)
+ #define BNX2_EMAC_ATTENTION_ENA_NXT_PG_CHANGE          (1L<<16)
+ #define BNX2_EMAC_ATTENTION_ENA_SERDES_RX_CONFIG_IS_0_CHANGE   (1L<<18)
+ #define BNX2_EMAC_ATTENTION_ENA_MI_COMPLETE            (1L<<22)
+ #define BNX2_EMAC_ATTENTION_ENA_MI_INT                         (1L<<23)
+ #define BNX2_EMAC_ATTENTION_ENA_AP_ERROR               (1L<<24)
+ #define BNX2_EMAC_LED                                 0x0000140c
+ #define BNX2_EMAC_LED_OVERRIDE                                 (1L<<0)
+ #define BNX2_EMAC_LED_1000MB_OVERRIDE                  (1L<<1)
+ #define BNX2_EMAC_LED_100MB_OVERRIDE                   (1L<<2)
+ #define BNX2_EMAC_LED_10MB_OVERRIDE                    (1L<<3)
+ #define BNX2_EMAC_LED_TRAFFIC_OVERRIDE                         (1L<<4)
+ #define BNX2_EMAC_LED_BLNK_TRAFFIC                     (1L<<5)
+ #define BNX2_EMAC_LED_TRAFFIC                          (1L<<6)
+ #define BNX2_EMAC_LED_1000MB                           (1L<<7)
+ #define BNX2_EMAC_LED_100MB                            (1L<<8)
+ #define BNX2_EMAC_LED_10MB                             (1L<<9)
+ #define BNX2_EMAC_LED_TRAFFIC_STAT                     (1L<<10)
+ #define BNX2_EMAC_LED_2500MB                           (1L<<11)
+ #define BNX2_EMAC_LED_2500MB_OVERRIDE                  (1L<<12)
+ #define BNX2_EMAC_LED_ACTIVITY_SEL                     (0x3L<<17)
+ #define BNX2_EMAC_LED_ACTIVITY_SEL_0                   (0L<<17)
+ #define BNX2_EMAC_LED_ACTIVITY_SEL_1                   (1L<<17)
+ #define BNX2_EMAC_LED_ACTIVITY_SEL_2                   (2L<<17)
+ #define BNX2_EMAC_LED_ACTIVITY_SEL_3                   (3L<<17)
+ #define BNX2_EMAC_LED_BLNK_RATE                                (0xfffL<<19)
+ #define BNX2_EMAC_LED_BLNK_RATE_ENA                    (1L<<31)
+ #define BNX2_EMAC_MAC_MATCH0                          0x00001410
+ #define BNX2_EMAC_MAC_MATCH1                          0x00001414
+ #define BNX2_EMAC_MAC_MATCH2                          0x00001418
+ #define BNX2_EMAC_MAC_MATCH3                          0x0000141c
+ #define BNX2_EMAC_MAC_MATCH4                          0x00001420
+ #define BNX2_EMAC_MAC_MATCH5                          0x00001424
+ #define BNX2_EMAC_MAC_MATCH6                          0x00001428
+ #define BNX2_EMAC_MAC_MATCH7                          0x0000142c
+ #define BNX2_EMAC_MAC_MATCH8                          0x00001430
+ #define BNX2_EMAC_MAC_MATCH9                          0x00001434
+ #define BNX2_EMAC_MAC_MATCH10                         0x00001438
+ #define BNX2_EMAC_MAC_MATCH11                         0x0000143c
+ #define BNX2_EMAC_MAC_MATCH12                         0x00001440
+ #define BNX2_EMAC_MAC_MATCH13                         0x00001444
+ #define BNX2_EMAC_MAC_MATCH14                         0x00001448
+ #define BNX2_EMAC_MAC_MATCH15                         0x0000144c
+ #define BNX2_EMAC_MAC_MATCH16                         0x00001450
+ #define BNX2_EMAC_MAC_MATCH17                         0x00001454
+ #define BNX2_EMAC_MAC_MATCH18                         0x00001458
+ #define BNX2_EMAC_MAC_MATCH19                         0x0000145c
+ #define BNX2_EMAC_MAC_MATCH20                         0x00001460
+ #define BNX2_EMAC_MAC_MATCH21                         0x00001464
+ #define BNX2_EMAC_MAC_MATCH22                         0x00001468
+ #define BNX2_EMAC_MAC_MATCH23                         0x0000146c
+ #define BNX2_EMAC_MAC_MATCH24                         0x00001470
+ #define BNX2_EMAC_MAC_MATCH25                         0x00001474
+ #define BNX2_EMAC_MAC_MATCH26                         0x00001478
+ #define BNX2_EMAC_MAC_MATCH27                         0x0000147c
+ #define BNX2_EMAC_MAC_MATCH28                         0x00001480
+ #define BNX2_EMAC_MAC_MATCH29                         0x00001484
+ #define BNX2_EMAC_MAC_MATCH30                         0x00001488
+ #define BNX2_EMAC_MAC_MATCH31                         0x0000148c
+ #define BNX2_EMAC_BACKOFF_SEED                                0x00001498
+ #define BNX2_EMAC_BACKOFF_SEED_EMAC_BACKOFF_SEED       (0x3ffL<<0)
+ #define BNX2_EMAC_RX_MTU_SIZE                         0x0000149c
+ #define BNX2_EMAC_RX_MTU_SIZE_MTU_SIZE                         (0xffffL<<0)
+ #define BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA                        (1L<<31)
+ #define BNX2_EMAC_SERDES_CNTL                         0x000014a4
+ #define BNX2_EMAC_SERDES_CNTL_RXR                      (0x7L<<0)
+ #define BNX2_EMAC_SERDES_CNTL_RXG                      (0x3L<<3)
+ #define BNX2_EMAC_SERDES_CNTL_RXCKSEL                  (1L<<6)
+ #define BNX2_EMAC_SERDES_CNTL_TXBIAS                   (0x7L<<7)
+ #define BNX2_EMAC_SERDES_CNTL_BGMAX                    (1L<<10)
+ #define BNX2_EMAC_SERDES_CNTL_BGMIN                    (1L<<11)
+ #define BNX2_EMAC_SERDES_CNTL_TXMODE                   (1L<<12)
+ #define BNX2_EMAC_SERDES_CNTL_TXEDGE                   (1L<<13)
+ #define BNX2_EMAC_SERDES_CNTL_SERDES_MODE              (1L<<14)
+ #define BNX2_EMAC_SERDES_CNTL_PLLTEST                  (1L<<15)
+ #define BNX2_EMAC_SERDES_CNTL_CDET_EN                  (1L<<16)
+ #define BNX2_EMAC_SERDES_CNTL_TBI_LBK                  (1L<<17)
+ #define BNX2_EMAC_SERDES_CNTL_REMOTE_LBK               (1L<<18)
+ #define BNX2_EMAC_SERDES_CNTL_REV_PHASE                        (1L<<19)
+ #define BNX2_EMAC_SERDES_CNTL_REGCTL12                         (0x3L<<20)
+ #define BNX2_EMAC_SERDES_CNTL_REGCTL25                         (0x3L<<22)
+ #define BNX2_EMAC_SERDES_STATUS                               0x000014a8
+ #define BNX2_EMAC_SERDES_STATUS_RX_STAT                        (0xffL<<0)
+ #define BNX2_EMAC_SERDES_STATUS_COMMA_DET              (1L<<8)
+ #define BNX2_EMAC_MDIO_COMM                           0x000014ac
+ #define BNX2_EMAC_MDIO_COMM_DATA                       (0xffffL<<0)
+ #define BNX2_EMAC_MDIO_COMM_REG_ADDR                   (0x1fL<<16)
+ #define BNX2_EMAC_MDIO_COMM_PHY_ADDR                   (0x1fL<<21)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND                    (0x3L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_0                (0L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_ADDRESS            (0L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE              (1L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_READ               (2L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE_22_XI                (1L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE_45_XI                (1L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_READ_22_XI                 (2L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_READ_INC_45_XI     (2L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_3                (3L<<26)
+ #define BNX2_EMAC_MDIO_COMM_COMMAND_READ_45            (3L<<26)
+ #define BNX2_EMAC_MDIO_COMM_FAIL                       (1L<<28)
+ #define BNX2_EMAC_MDIO_COMM_START_BUSY                         (1L<<29)
+ #define BNX2_EMAC_MDIO_COMM_DISEXT                     (1L<<30)
+ #define BNX2_EMAC_MDIO_STATUS                         0x000014b0
+ #define BNX2_EMAC_MDIO_STATUS_LINK                     (1L<<0)
+ #define BNX2_EMAC_MDIO_STATUS_10MB                     (1L<<1)
+ #define BNX2_EMAC_MDIO_MODE                           0x000014b4
+ #define BNX2_EMAC_MDIO_MODE_SHORT_PREAMBLE             (1L<<1)
+ #define BNX2_EMAC_MDIO_MODE_AUTO_POLL                  (1L<<4)
+ #define BNX2_EMAC_MDIO_MODE_BIT_BANG                   (1L<<8)
+ #define BNX2_EMAC_MDIO_MODE_MDIO                       (1L<<9)
+ #define BNX2_EMAC_MDIO_MODE_MDIO_OE                    (1L<<10)
+ #define BNX2_EMAC_MDIO_MODE_MDC                                (1L<<11)
+ #define BNX2_EMAC_MDIO_MODE_MDINT                      (1L<<12)
+ #define BNX2_EMAC_MDIO_MODE_EXT_MDINT                  (1L<<13)
+ #define BNX2_EMAC_MDIO_MODE_CLOCK_CNT                  (0x1fL<<16)
+ #define BNX2_EMAC_MDIO_MODE_CLOCK_CNT_XI               (0x3fL<<16)
+ #define BNX2_EMAC_MDIO_MODE_CLAUSE_45_XI               (1L<<31)
+ #define BNX2_EMAC_MDIO_AUTO_STATUS                    0x000014b8
+ #define BNX2_EMAC_MDIO_AUTO_STATUS_AUTO_ERR            (1L<<0)
+ #define BNX2_EMAC_TX_MODE                             0x000014bc
+ #define BNX2_EMAC_TX_MODE_RESET                                (1L<<0)
+ #define BNX2_EMAC_TX_MODE_CS16_TEST                    (1L<<2)
+ #define BNX2_EMAC_TX_MODE_EXT_PAUSE_EN                         (1L<<3)
+ #define BNX2_EMAC_TX_MODE_FLOW_EN                      (1L<<4)
+ #define BNX2_EMAC_TX_MODE_BIG_BACKOFF                  (1L<<5)
+ #define BNX2_EMAC_TX_MODE_LONG_PAUSE                   (1L<<6)
+ #define BNX2_EMAC_TX_MODE_LINK_AWARE                   (1L<<7)
+ #define BNX2_EMAC_TX_STATUS                           0x000014c0
+ #define BNX2_EMAC_TX_STATUS_XOFFED                     (1L<<0)
+ #define BNX2_EMAC_TX_STATUS_XOFF_SENT                  (1L<<1)
+ #define BNX2_EMAC_TX_STATUS_XON_SENT                   (1L<<2)
+ #define BNX2_EMAC_TX_STATUS_LINK_UP                    (1L<<3)
+ #define BNX2_EMAC_TX_STATUS_UNDERRUN                   (1L<<4)
+ #define BNX2_EMAC_TX_STATUS_CS16_ERROR                         (1L<<5)
+ #define BNX2_EMAC_TX_LENGTHS                          0x000014c4
+ #define BNX2_EMAC_TX_LENGTHS_SLOT                      (0xffL<<0)
+ #define BNX2_EMAC_TX_LENGTHS_IPG                       (0xfL<<8)
+ #define BNX2_EMAC_TX_LENGTHS_IPG_CRS                   (0x3L<<12)
+ #define BNX2_EMAC_RX_MODE                             0x000014c8
+ #define BNX2_EMAC_RX_MODE_RESET                                (1L<<0)
+ #define BNX2_EMAC_RX_MODE_FLOW_EN                      (1L<<2)
+ #define BNX2_EMAC_RX_MODE_KEEP_MAC_CONTROL             (1L<<3)
+ #define BNX2_EMAC_RX_MODE_KEEP_PAUSE                   (1L<<4)
+ #define BNX2_EMAC_RX_MODE_ACCEPT_OVERSIZE              (1L<<5)
+ #define BNX2_EMAC_RX_MODE_ACCEPT_RUNTS                         (1L<<6)
+ #define BNX2_EMAC_RX_MODE_LLC_CHK                      (1L<<7)
+ #define BNX2_EMAC_RX_MODE_PROMISCUOUS                  (1L<<8)
+ #define BNX2_EMAC_RX_MODE_NO_CRC_CHK                   (1L<<9)
+ #define BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG                        (1L<<10)
+ #define BNX2_EMAC_RX_MODE_FILT_BROADCAST               (1L<<11)
+ #define BNX2_EMAC_RX_MODE_SORT_MODE                    (1L<<12)
+ #define BNX2_EMAC_RX_STATUS                           0x000014cc
+ #define BNX2_EMAC_RX_STATUS_FFED                       (1L<<0)
+ #define BNX2_EMAC_RX_STATUS_FF_RECEIVED                        (1L<<1)
+ #define BNX2_EMAC_RX_STATUS_N_RECEIVED                         (1L<<2)
+ #define BNX2_EMAC_MULTICAST_HASH0                     0x000014d0
+ #define BNX2_EMAC_MULTICAST_HASH1                     0x000014d4
+ #define BNX2_EMAC_MULTICAST_HASH2                     0x000014d8
+ #define BNX2_EMAC_MULTICAST_HASH3                     0x000014dc
+ #define BNX2_EMAC_MULTICAST_HASH4                     0x000014e0
+ #define BNX2_EMAC_MULTICAST_HASH5                     0x000014e4
+ #define BNX2_EMAC_MULTICAST_HASH6                     0x000014e8
+ #define BNX2_EMAC_MULTICAST_HASH7                     0x000014ec
+ #define BNX2_EMAC_CKSUM_ERROR_STATUS                  0x000014f0
+ #define BNX2_EMAC_CKSUM_ERROR_STATUS_CALCULATED                (0xffffL<<0)
+ #define BNX2_EMAC_CKSUM_ERROR_STATUS_EXPECTED          (0xffffL<<16)
+ #define BNX2_EMAC_RX_STAT_IFHCINOCTETS                        0x00001500
+ #define BNX2_EMAC_RX_STAT_IFHCINBADOCTETS             0x00001504
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSFRAGMENTS         0x00001508
+ #define BNX2_EMAC_RX_STAT_IFHCINUCASTPKTS             0x0000150c
+ #define BNX2_EMAC_RX_STAT_IFHCINMULTICASTPKTS         0x00001510
+ #define BNX2_EMAC_RX_STAT_IFHCINBROADCASTPKTS         0x00001514
+ #define BNX2_EMAC_RX_STAT_DOT3STATSFCSERRORS          0x00001518
+ #define BNX2_EMAC_RX_STAT_DOT3STATSALIGNMENTERRORS    0x0000151c
+ #define BNX2_EMAC_RX_STAT_DOT3STATSCARRIERSENSEERRORS 0x00001520
+ #define BNX2_EMAC_RX_STAT_XONPAUSEFRAMESRECEIVED      0x00001524
+ #define BNX2_EMAC_RX_STAT_XOFFPAUSEFRAMESRECEIVED     0x00001528
+ #define BNX2_EMAC_RX_STAT_MACCONTROLFRAMESRECEIVED    0x0000152c
+ #define BNX2_EMAC_RX_STAT_XOFFSTATEENTERED            0x00001530
+ #define BNX2_EMAC_RX_STAT_DOT3STATSFRAMESTOOLONG      0x00001534
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSJABBERS           0x00001538
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSUNDERSIZEPKTS     0x0000153c
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS64OCTETS      0x00001540
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS   0x00001544
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS  0x00001548
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS  0x0000154c
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001550
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS        0x00001554
+ #define BNX2_EMAC_RX_STAT_ETHERSTATSPKTSOVER1522OCTETS        0x00001558
+ #define BNX2_EMAC_RXMAC_DEBUG0                                0x0000155c
+ #define BNX2_EMAC_RXMAC_DEBUG1                                0x00001560
+ #define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_NE_BYTE_COUNT    (1L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_OUT_RANGE                (1L<<1)
+ #define BNX2_EMAC_RXMAC_DEBUG1_BAD_CRC                         (1L<<2)
+ #define BNX2_EMAC_RXMAC_DEBUG1_RX_ERROR                        (1L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG1_ALIGN_ERROR             (1L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG1_LAST_DATA               (1L<<5)
+ #define BNX2_EMAC_RXMAC_DEBUG1_ODD_BYTE_START          (1L<<6)
+ #define BNX2_EMAC_RXMAC_DEBUG1_BYTE_COUNT              (0xffffL<<7)
+ #define BNX2_EMAC_RXMAC_DEBUG1_SLOT_TIME               (0xffL<<23)
+ #define BNX2_EMAC_RXMAC_DEBUG2                                0x00001564
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE                        (0x7L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_IDLE           (0x0L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SFD            (0x1L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DATA           (0x2L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SKEEP          (0x3L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_EXT            (0x4L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DROP           (0x5L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SDROP          (0x6L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_FC             (0x7L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE               (0xfL<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_IDLE          (0x0L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA0                 (0x1L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA1                 (0x2L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA2                 (0x3L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA3                 (0x4L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_ABORT                 (0x5L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_WAIT          (0x6L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_STATUS                (0x7L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_LAST          (0x8L<<3)
+ #define BNX2_EMAC_RXMAC_DEBUG2_BYTE_IN                         (0xffL<<7)
+ #define BNX2_EMAC_RXMAC_DEBUG2_FALSEC                  (1L<<15)
+ #define BNX2_EMAC_RXMAC_DEBUG2_TAGGED                  (1L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE             (1L<<18)
+ #define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_IDLE                (0L<<18)
+ #define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_PAUSED      (1L<<18)
+ #define BNX2_EMAC_RXMAC_DEBUG2_SE_COUNTER              (0xfL<<19)
+ #define BNX2_EMAC_RXMAC_DEBUG2_QUANTA                  (0x1fL<<23)
+ #define BNX2_EMAC_RXMAC_DEBUG3                                0x00001568
+ #define BNX2_EMAC_RXMAC_DEBUG3_PAUSE_CTR               (0xffffL<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG3_TMP_PAUSE_CTR           (0xffffL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4                                0x0000156c
+ #define BNX2_EMAC_RXMAC_DEBUG4_TYPE_FIELD              (0xffffL<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE              (0x3fL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_IDLE                 (0x0L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC2                (0x1L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC3                (0x2L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UNI          (0x3L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC3                (0x5L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA1                 (0x6L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC2                (0x7L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA2                 (0x7L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA3                 (0x8L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC2          (0x9L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC3          (0xaL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT1       (0xeL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT2       (0xfL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MCHECK       (0x10L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC           (0x11L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC2          (0x12L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC3          (0x13L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA1                 (0x14L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA2                 (0x15L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA3                 (0x16L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BTYPE                (0x17L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC           (0x18L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PTYPE                (0x19L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_CMD          (0x1aL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MAC          (0x1bL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_LATCH                (0x1cL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XOFF                 (0x1dL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XON          (0x1eL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PAUSED       (0x1fL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_NPAUSED      (0x20L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TTYPE                (0x21L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TVAL                 (0x22L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA1                 (0x23L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA2                 (0x24L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA3                 (0x25L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTYPE                (0x26L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTTYPE       (0x27L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTVAL                (0x28L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MTYPE                (0x29L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_DROP                 (0x2aL<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG4_DROP_PKT                        (1L<<22)
+ #define BNX2_EMAC_RXMAC_DEBUG4_SLOT_FILLED             (1L<<23)
+ #define BNX2_EMAC_RXMAC_DEBUG4_FALSE_CARRIER           (1L<<24)
+ #define BNX2_EMAC_RXMAC_DEBUG4_LAST_DATA               (1L<<25)
+ #define BNX2_EMAC_RXMAC_DEBUG4_SFD_FOUND               (1L<<26)
+ #define BNX2_EMAC_RXMAC_DEBUG4_ADVANCE                         (1L<<27)
+ #define BNX2_EMAC_RXMAC_DEBUG4_START                   (1L<<28)
+ #define BNX2_EMAC_RXMAC_DEBUG5                                0x00001570
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM                        (0x7L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_IDLE           (0L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_EOF       (1L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_STAT      (2L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4FCRC   (3L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4RDE    (4L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4ALL    (5L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_1WD_WAIT_STAT  (6L<<0)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1              (0x7L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_VDW          (0x0L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_STAT                 (0x1L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_AEOF                 (0x2L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_NEOF                 (0x3L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SOF          (0x4L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SAEOF                (0x6L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SNEOF                (0x7L<<4)
+ #define BNX2_EMAC_RXMAC_DEBUG5_EOF_DETECTED            (1L<<7)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF0              (0x7L<<8)
+ #define BNX2_EMAC_RXMAC_DEBUG5_RPM_IDI_FIFO_FULL       (1L<<11)
+ #define BNX2_EMAC_RXMAC_DEBUG5_LOAD_CCODE              (1L<<12)
+ #define BNX2_EMAC_RXMAC_DEBUG5_LOAD_DATA               (1L<<13)
+ #define BNX2_EMAC_RXMAC_DEBUG5_LOAD_STAT               (1L<<14)
+ #define BNX2_EMAC_RXMAC_DEBUG5_CLR_STAT                        (1L<<15)
+ #define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_CCODE           (0x3L<<16)
+ #define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_ACCEPT          (1L<<19)
+ #define BNX2_EMAC_RXMAC_DEBUG5_FMLEN                   (0xfffL<<20)
+ #define BNX2_EMAC_RX_STAT_FALSECARRIERERRORS          0x00001574
+ #define BNX2_EMAC_RX_STAT_AC0                         0x00001580
+ #define BNX2_EMAC_RX_STAT_AC1                         0x00001584
+ #define BNX2_EMAC_RX_STAT_AC2                         0x00001588
+ #define BNX2_EMAC_RX_STAT_AC3                         0x0000158c
+ #define BNX2_EMAC_RX_STAT_AC4                         0x00001590
+ #define BNX2_EMAC_RX_STAT_AC5                         0x00001594
+ #define BNX2_EMAC_RX_STAT_AC6                         0x00001598
+ #define BNX2_EMAC_RX_STAT_AC7                         0x0000159c
+ #define BNX2_EMAC_RX_STAT_AC8                         0x000015a0
+ #define BNX2_EMAC_RX_STAT_AC9                         0x000015a4
+ #define BNX2_EMAC_RX_STAT_AC10                                0x000015a8
+ #define BNX2_EMAC_RX_STAT_AC11                                0x000015ac
+ #define BNX2_EMAC_RX_STAT_AC12                                0x000015b0
+ #define BNX2_EMAC_RX_STAT_AC13                                0x000015b4
+ #define BNX2_EMAC_RX_STAT_AC14                                0x000015b8
+ #define BNX2_EMAC_RX_STAT_AC15                                0x000015bc
+ #define BNX2_EMAC_RX_STAT_AC16                                0x000015c0
+ #define BNX2_EMAC_RX_STAT_AC17                                0x000015c4
+ #define BNX2_EMAC_RX_STAT_AC18                                0x000015c8
+ #define BNX2_EMAC_RX_STAT_AC19                                0x000015cc
+ #define BNX2_EMAC_RX_STAT_AC20                                0x000015d0
+ #define BNX2_EMAC_RX_STAT_AC21                                0x000015d4
+ #define BNX2_EMAC_RX_STAT_AC22                                0x000015d8
+ #define BNX2_EMAC_RXMAC_SUC_DBG_OVERRUNVEC            0x000015dc
+ #define BNX2_EMAC_RX_STAT_AC_28                               0x000015f4
+ #define BNX2_EMAC_TX_STAT_IFHCOUTOCTETS                       0x00001600
+ #define BNX2_EMAC_TX_STAT_IFHCOUTBADOCTETS            0x00001604
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSCOLLISIONS                0x00001608
+ #define BNX2_EMAC_TX_STAT_OUTXONSENT                  0x0000160c
+ #define BNX2_EMAC_TX_STAT_OUTXOFFSENT                 0x00001610
+ #define BNX2_EMAC_TX_STAT_FLOWCONTROLDONE             0x00001614
+ #define BNX2_EMAC_TX_STAT_DOT3STATSSINGLECOLLISIONFRAMES      0x00001618
+ #define BNX2_EMAC_TX_STAT_DOT3STATSMULTIPLECOLLISIONFRAMES    0x0000161c
+ #define BNX2_EMAC_TX_STAT_DOT3STATSDEFERREDTRANSMISSIONS      0x00001620
+ #define BNX2_EMAC_TX_STAT_DOT3STATSEXCESSIVECOLLISIONS        0x00001624
+ #define BNX2_EMAC_TX_STAT_DOT3STATSLATECOLLISIONS     0x00001628
+ #define BNX2_EMAC_TX_STAT_IFHCOUTUCASTPKTS            0x0000162c
+ #define BNX2_EMAC_TX_STAT_IFHCOUTMULTICASTPKTS                0x00001630
+ #define BNX2_EMAC_TX_STAT_IFHCOUTBROADCASTPKTS                0x00001634
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS64OCTETS      0x00001638
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS   0x0000163c
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS  0x00001640
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS  0x00001644
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001648
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS        0x0000164c
+ #define BNX2_EMAC_TX_STAT_ETHERSTATSPKTSOVER1522OCTETS        0x00001650
+ #define BNX2_EMAC_TX_STAT_DOT3STATSINTERNALMACTRANSMITERRORS  0x00001654
+ #define BNX2_EMAC_TXMAC_DEBUG0                                0x00001658
+ #define BNX2_EMAC_TXMAC_DEBUG1                                0x0000165c
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE               (0xfL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_IDLE          (0x0L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_START0                (0x1L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA0                 (0x4L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA1                 (0x5L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA2                 (0x6L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA3                 (0x7L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT0                 (0x8L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT1                 (0x9L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG1_CRS_ENABLE              (1L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG1_BAD_CRC                         (1L<<5)
+ #define BNX2_EMAC_TXMAC_DEBUG1_SE_COUNTER              (0xfL<<6)
+ #define BNX2_EMAC_TXMAC_DEBUG1_SEND_PAUSE              (1L<<10)
+ #define BNX2_EMAC_TXMAC_DEBUG1_LATE_COLLISION          (1L<<11)
+ #define BNX2_EMAC_TXMAC_DEBUG1_MAX_DEFER               (1L<<12)
+ #define BNX2_EMAC_TXMAC_DEBUG1_DEFERRED                        (1L<<13)
+ #define BNX2_EMAC_TXMAC_DEBUG1_ONE_BYTE                        (1L<<14)
+ #define BNX2_EMAC_TXMAC_DEBUG1_IPG_TIME                        (0xfL<<15)
+ #define BNX2_EMAC_TXMAC_DEBUG1_SLOT_TIME               (0xffL<<19)
+ #define BNX2_EMAC_TXMAC_DEBUG2                                0x00001660
+ #define BNX2_EMAC_TXMAC_DEBUG2_BACK_OFF                        (0x3ffL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG2_BYTE_COUNT              (0xffffL<<10)
+ #define BNX2_EMAC_TXMAC_DEBUG2_COL_COUNT               (0x1fL<<26)
+ #define BNX2_EMAC_TXMAC_DEBUG2_COL_BIT                         (1L<<31)
+ #define BNX2_EMAC_TXMAC_DEBUG3                                0x00001664
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE                        (0xfL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_IDLE           (0x0L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE1           (0x1L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE2           (0x2L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SFD            (0x3L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_DATA           (0x4L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC1           (0x5L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC2           (0x6L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EXT            (0x7L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATB          (0x8L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATG          (0x9L<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_JAM            (0xaL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EJAM           (0xbL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BJAM           (0xcL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SWAIT          (0xdL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BACKOFF                (0xeL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE              (0x7L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_IDLE                 (0x0L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_WAIT                 (0x1L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_UNI          (0x2L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_MC           (0x3L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC2          (0x4L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC3          (0x5L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC           (0x6L<<4)
+ #define BNX2_EMAC_TXMAC_DEBUG3_CRS_DONE                        (1L<<7)
+ #define BNX2_EMAC_TXMAC_DEBUG3_XOFF                    (1L<<8)
+ #define BNX2_EMAC_TXMAC_DEBUG3_SE_COUNTER              (0xfL<<9)
+ #define BNX2_EMAC_TXMAC_DEBUG3_QUANTA_COUNTER          (0x1fL<<13)
+ #define BNX2_EMAC_TXMAC_DEBUG4                                0x00001668
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_COUNTER           (0xffffL<<0)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE             (0xfL<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_IDLE                (0x0L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA1                (0x2L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA2                (0x3L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC3                (0x4L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC2                (0x5L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA3                (0x6L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC1                (0x7L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC1                (0x8L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC2                (0x9L<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TIME                (0xaL<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TYPE                (0xcL<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_WAIT                (0xdL<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CMD                 (0xeL<<16)
+ #define BNX2_EMAC_TXMAC_DEBUG4_STATS0_VALID            (1L<<20)
+ #define BNX2_EMAC_TXMAC_DEBUG4_APPEND_CRC              (1L<<21)
+ #define BNX2_EMAC_TXMAC_DEBUG4_SLOT_FILLED             (1L<<22)
+ #define BNX2_EMAC_TXMAC_DEBUG4_MAX_DEFER               (1L<<23)
+ #define BNX2_EMAC_TXMAC_DEBUG4_SEND_EXTEND             (1L<<24)
+ #define BNX2_EMAC_TXMAC_DEBUG4_SEND_PADDING            (1L<<25)
+ #define BNX2_EMAC_TXMAC_DEBUG4_EOF_LOC                         (1L<<26)
+ #define BNX2_EMAC_TXMAC_DEBUG4_COLLIDING               (1L<<27)
+ #define BNX2_EMAC_TXMAC_DEBUG4_COL_IN                  (1L<<28)
+ #define BNX2_EMAC_TXMAC_DEBUG4_BURSTING                        (1L<<29)
+ #define BNX2_EMAC_TXMAC_DEBUG4_ADVANCE                         (1L<<30)
+ #define BNX2_EMAC_TXMAC_DEBUG4_GO                      (1L<<31)
+ #define BNX2_EMAC_TX_STAT_AC0                         0x00001680
+ #define BNX2_EMAC_TX_STAT_AC1                         0x00001684
+ #define BNX2_EMAC_TX_STAT_AC2                         0x00001688
+ #define BNX2_EMAC_TX_STAT_AC3                         0x0000168c
+ #define BNX2_EMAC_TX_STAT_AC4                         0x00001690
+ #define BNX2_EMAC_TX_STAT_AC5                         0x00001694
+ #define BNX2_EMAC_TX_STAT_AC6                         0x00001698
+ #define BNX2_EMAC_TX_STAT_AC7                         0x0000169c
+ #define BNX2_EMAC_TX_STAT_AC8                         0x000016a0
+ #define BNX2_EMAC_TX_STAT_AC9                         0x000016a4
+ #define BNX2_EMAC_TX_STAT_AC10                                0x000016a8
+ #define BNX2_EMAC_TX_STAT_AC11                                0x000016ac
+ #define BNX2_EMAC_TX_STAT_AC12                                0x000016b0
+ #define BNX2_EMAC_TX_STAT_AC13                                0x000016b4
+ #define BNX2_EMAC_TX_STAT_AC14                                0x000016b8
+ #define BNX2_EMAC_TX_STAT_AC15                                0x000016bc
+ #define BNX2_EMAC_TX_STAT_AC16                                0x000016c0
+ #define BNX2_EMAC_TX_STAT_AC17                                0x000016c4
+ #define BNX2_EMAC_TX_STAT_AC18                                0x000016c8
+ #define BNX2_EMAC_TX_STAT_AC19                                0x000016cc
+ #define BNX2_EMAC_TX_STAT_AC20                                0x000016d0
+ #define BNX2_EMAC_TXMAC_SUC_DBG_OVERRUNVEC            0x000016d8
+ #define BNX2_EMAC_TX_RATE_LIMIT_CTRL                  0x000016fc
+ #define BNX2_EMAC_TX_RATE_LIMIT_CTRL_TX_THROTTLE_INC   (0x7fL<<0)
+ #define BNX2_EMAC_TX_RATE_LIMIT_CTRL_TX_THROTTLE_NUM   (0x7fL<<16)
+ #define BNX2_EMAC_TX_RATE_LIMIT_CTRL_RATE_LIMITER_EN   (1L<<31)
+ /*
+  *  rpm_reg definition
+  *  offset: 0x1800
+  */
+ #define BNX2_RPM_COMMAND                              0x00001800
+ #define BNX2_RPM_COMMAND_ENABLED                       (1L<<0)
+ #define BNX2_RPM_COMMAND_OVERRUN_ABORT                         (1L<<4)
+ #define BNX2_RPM_STATUS                                       0x00001804
+ #define BNX2_RPM_STATUS_MBUF_WAIT                      (1L<<0)
+ #define BNX2_RPM_STATUS_FREE_WAIT                      (1L<<1)
+ #define BNX2_RPM_CONFIG                                       0x00001808
+ #define BNX2_RPM_CONFIG_NO_PSD_HDR_CKSUM               (1L<<0)
+ #define BNX2_RPM_CONFIG_ACPI_ENA                       (1L<<1)
+ #define BNX2_RPM_CONFIG_ACPI_KEEP                      (1L<<2)
+ #define BNX2_RPM_CONFIG_MP_KEEP                                (1L<<3)
+ #define BNX2_RPM_CONFIG_SORT_VECT_VAL                  (0xfL<<4)
+ #define BNX2_RPM_CONFIG_DISABLE_WOL_ASSERT             (1L<<30)
+ #define BNX2_RPM_CONFIG_IGNORE_VLAN                    (1L<<31)
+ #define BNX2_RPM_MGMT_PKT_CTRL                                0x0000180c
+ #define BNX2_RPM_MGMT_PKT_CTRL_MGMT_SORT               (0xfL<<0)
+ #define BNX2_RPM_MGMT_PKT_CTRL_MGMT_RULE               (0xfL<<4)
+ #define BNX2_RPM_MGMT_PKT_CTRL_MGMT_DISCARD_EN                 (1L<<30)
+ #define BNX2_RPM_MGMT_PKT_CTRL_MGMT_EN                         (1L<<31)
+ #define BNX2_RPM_VLAN_MATCH0                          0x00001810
+ #define BNX2_RPM_VLAN_MATCH0_RPM_VLAN_MTCH0_VALUE      (0xfffL<<0)
+ #define BNX2_RPM_VLAN_MATCH1                          0x00001814
+ #define BNX2_RPM_VLAN_MATCH1_RPM_VLAN_MTCH1_VALUE      (0xfffL<<0)
+ #define BNX2_RPM_VLAN_MATCH2                          0x00001818
+ #define BNX2_RPM_VLAN_MATCH2_RPM_VLAN_MTCH2_VALUE      (0xfffL<<0)
+ #define BNX2_RPM_VLAN_MATCH3                          0x0000181c
+ #define BNX2_RPM_VLAN_MATCH3_RPM_VLAN_MTCH3_VALUE      (0xfffL<<0)
+ #define BNX2_RPM_SORT_USER0                           0x00001820
+ #define BNX2_RPM_SORT_USER0_PM_EN                      (0xffffL<<0)
+ #define BNX2_RPM_SORT_USER0_BC_EN                      (1L<<16)
+ #define BNX2_RPM_SORT_USER0_MC_EN                      (1L<<17)
+ #define BNX2_RPM_SORT_USER0_MC_HSH_EN                  (1L<<18)
+ #define BNX2_RPM_SORT_USER0_PROM_EN                    (1L<<19)
+ #define BNX2_RPM_SORT_USER0_VLAN_EN                    (0xfL<<20)
+ #define BNX2_RPM_SORT_USER0_PROM_VLAN                  (1L<<24)
+ #define BNX2_RPM_SORT_USER0_VLAN_NOTMATCH              (1L<<25)
+ #define BNX2_RPM_SORT_USER0_ENA                                (1L<<31)
+ #define BNX2_RPM_SORT_USER1                           0x00001824
+ #define BNX2_RPM_SORT_USER1_PM_EN                      (0xffffL<<0)
+ #define BNX2_RPM_SORT_USER1_BC_EN                      (1L<<16)
+ #define BNX2_RPM_SORT_USER1_MC_EN                      (1L<<17)
+ #define BNX2_RPM_SORT_USER1_MC_HSH_EN                  (1L<<18)
+ #define BNX2_RPM_SORT_USER1_PROM_EN                    (1L<<19)
+ #define BNX2_RPM_SORT_USER1_VLAN_EN                    (0xfL<<20)
+ #define BNX2_RPM_SORT_USER1_PROM_VLAN                  (1L<<24)
+ #define BNX2_RPM_SORT_USER1_ENA                                (1L<<31)
+ #define BNX2_RPM_SORT_USER2                           0x00001828
+ #define BNX2_RPM_SORT_USER2_PM_EN                      (0xffffL<<0)
+ #define BNX2_RPM_SORT_USER2_BC_EN                      (1L<<16)
+ #define BNX2_RPM_SORT_USER2_MC_EN                      (1L<<17)
+ #define BNX2_RPM_SORT_USER2_MC_HSH_EN                  (1L<<18)
+ #define BNX2_RPM_SORT_USER2_PROM_EN                    (1L<<19)
+ #define BNX2_RPM_SORT_USER2_VLAN_EN                    (0xfL<<20)
+ #define BNX2_RPM_SORT_USER2_PROM_VLAN                  (1L<<24)
+ #define BNX2_RPM_SORT_USER2_ENA                                (1L<<31)
+ #define BNX2_RPM_SORT_USER3                           0x0000182c
+ #define BNX2_RPM_SORT_USER3_PM_EN                      (0xffffL<<0)
+ #define BNX2_RPM_SORT_USER3_BC_EN                      (1L<<16)
+ #define BNX2_RPM_SORT_USER3_MC_EN                      (1L<<17)
+ #define BNX2_RPM_SORT_USER3_MC_HSH_EN                  (1L<<18)
+ #define BNX2_RPM_SORT_USER3_PROM_EN                    (1L<<19)
+ #define BNX2_RPM_SORT_USER3_VLAN_EN                    (0xfL<<20)
+ #define BNX2_RPM_SORT_USER3_PROM_VLAN                  (1L<<24)
+ #define BNX2_RPM_SORT_USER3_ENA                                (1L<<31)
+ #define BNX2_RPM_STAT_L2_FILTER_DISCARDS              0x00001840
+ #define BNX2_RPM_STAT_RULE_CHECKER_DISCARDS           0x00001844
+ #define BNX2_RPM_STAT_IFINFTQDISCARDS                 0x00001848
+ #define BNX2_RPM_STAT_IFINMBUFDISCARD                 0x0000184c
+ #define BNX2_RPM_STAT_RULE_CHECKER_P4_HIT             0x00001850
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0         0x00001854
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION0_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1         0x00001858
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION1_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2         0x0000185c
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION2_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3         0x00001860
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION3_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4         0x00001864
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION4_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5         0x00001868
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION5_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6         0x0000186c
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION6_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7         0x00001870
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER_LEN  (0xffL<<0)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER      (0xffL<<16)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER_LEN_TYPE     (1L<<30)
+ #define BNX2_RPM_IPV6_PROGRAMMABLE_EXTENSION7_NEXT_HEADER_EN   (1L<<31)
+ #define BNX2_RPM_STAT_AC0                             0x00001880
+ #define BNX2_RPM_STAT_AC1                             0x00001884
+ #define BNX2_RPM_STAT_AC2                             0x00001888
+ #define BNX2_RPM_STAT_AC3                             0x0000188c
+ #define BNX2_RPM_STAT_AC4                             0x00001890
+ #define BNX2_RPM_RC_CNTL_16                           0x000018e0
+ #define BNX2_RPM_RC_CNTL_16_OFFSET                     (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_16_CLASS                      (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_16_PRIORITY                   (1L<<11)
+ #define BNX2_RPM_RC_CNTL_16_P4                                 (1L<<12)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE                   (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE_START             (0L<<13)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE_IP                        (1L<<13)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE_TCP               (2L<<13)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE_UDP               (3L<<13)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE_DATA              (4L<<13)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE_TCP_UDP           (5L<<13)
+ #define BNX2_RPM_RC_CNTL_16_HDR_TYPE_ICMPV6            (6L<<13)
+ #define BNX2_RPM_RC_CNTL_16_COMP                       (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_16_COMP_EQUAL                         (0L<<16)
+ #define BNX2_RPM_RC_CNTL_16_COMP_NEQUAL                        (1L<<16)
+ #define BNX2_RPM_RC_CNTL_16_COMP_GREATER               (2L<<16)
+ #define BNX2_RPM_RC_CNTL_16_COMP_LESS                  (3L<<16)
+ #define BNX2_RPM_RC_CNTL_16_MAP                                (1L<<18)
+ #define BNX2_RPM_RC_CNTL_16_SBIT                       (1L<<19)
+ #define BNX2_RPM_RC_CNTL_16_CMDSEL                     (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_16_DISCARD                    (1L<<25)
+ #define BNX2_RPM_RC_CNTL_16_MASK                       (1L<<26)
+ #define BNX2_RPM_RC_CNTL_16_P1                                 (1L<<27)
+ #define BNX2_RPM_RC_CNTL_16_P2                                 (1L<<28)
+ #define BNX2_RPM_RC_CNTL_16_P3                                 (1L<<29)
+ #define BNX2_RPM_RC_CNTL_16_NBIT                       (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_16                     0x000018e4
+ #define BNX2_RPM_RC_VALUE_MASK_16_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_16_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_17                           0x000018e8
+ #define BNX2_RPM_RC_CNTL_17_OFFSET                     (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_17_CLASS                      (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_17_PRIORITY                   (1L<<11)
+ #define BNX2_RPM_RC_CNTL_17_P4                                 (1L<<12)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE                   (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE_START             (0L<<13)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE_IP                        (1L<<13)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE_TCP               (2L<<13)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE_UDP               (3L<<13)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE_DATA              (4L<<13)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE_TCP_UDP           (5L<<13)
+ #define BNX2_RPM_RC_CNTL_17_HDR_TYPE_ICMPV6            (6L<<13)
+ #define BNX2_RPM_RC_CNTL_17_COMP                       (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_17_COMP_EQUAL                         (0L<<16)
+ #define BNX2_RPM_RC_CNTL_17_COMP_NEQUAL                        (1L<<16)
+ #define BNX2_RPM_RC_CNTL_17_COMP_GREATER               (2L<<16)
+ #define BNX2_RPM_RC_CNTL_17_COMP_LESS                  (3L<<16)
+ #define BNX2_RPM_RC_CNTL_17_MAP                                (1L<<18)
+ #define BNX2_RPM_RC_CNTL_17_SBIT                       (1L<<19)
+ #define BNX2_RPM_RC_CNTL_17_CMDSEL                     (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_17_DISCARD                    (1L<<25)
+ #define BNX2_RPM_RC_CNTL_17_MASK                       (1L<<26)
+ #define BNX2_RPM_RC_CNTL_17_P1                                 (1L<<27)
+ #define BNX2_RPM_RC_CNTL_17_P2                                 (1L<<28)
+ #define BNX2_RPM_RC_CNTL_17_P3                                 (1L<<29)
+ #define BNX2_RPM_RC_CNTL_17_NBIT                       (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_17                     0x000018ec
+ #define BNX2_RPM_RC_VALUE_MASK_17_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_17_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_18                           0x000018f0
+ #define BNX2_RPM_RC_CNTL_18_OFFSET                     (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_18_CLASS                      (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_18_PRIORITY                   (1L<<11)
+ #define BNX2_RPM_RC_CNTL_18_P4                                 (1L<<12)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE                   (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE_START             (0L<<13)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE_IP                        (1L<<13)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE_TCP               (2L<<13)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE_UDP               (3L<<13)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE_DATA              (4L<<13)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE_TCP_UDP           (5L<<13)
+ #define BNX2_RPM_RC_CNTL_18_HDR_TYPE_ICMPV6            (6L<<13)
+ #define BNX2_RPM_RC_CNTL_18_COMP                       (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_18_COMP_EQUAL                         (0L<<16)
+ #define BNX2_RPM_RC_CNTL_18_COMP_NEQUAL                        (1L<<16)
+ #define BNX2_RPM_RC_CNTL_18_COMP_GREATER               (2L<<16)
+ #define BNX2_RPM_RC_CNTL_18_COMP_LESS                  (3L<<16)
+ #define BNX2_RPM_RC_CNTL_18_MAP                                (1L<<18)
+ #define BNX2_RPM_RC_CNTL_18_SBIT                       (1L<<19)
+ #define BNX2_RPM_RC_CNTL_18_CMDSEL                     (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_18_DISCARD                    (1L<<25)
+ #define BNX2_RPM_RC_CNTL_18_MASK                       (1L<<26)
+ #define BNX2_RPM_RC_CNTL_18_P1                                 (1L<<27)
+ #define BNX2_RPM_RC_CNTL_18_P2                                 (1L<<28)
+ #define BNX2_RPM_RC_CNTL_18_P3                                 (1L<<29)
+ #define BNX2_RPM_RC_CNTL_18_NBIT                       (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_18                     0x000018f4
+ #define BNX2_RPM_RC_VALUE_MASK_18_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_18_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_19                           0x000018f8
+ #define BNX2_RPM_RC_CNTL_19_OFFSET                     (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_19_CLASS                      (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_19_PRIORITY                   (1L<<11)
+ #define BNX2_RPM_RC_CNTL_19_P4                                 (1L<<12)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE                   (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE_START             (0L<<13)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE_IP                        (1L<<13)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE_TCP               (2L<<13)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE_UDP               (3L<<13)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE_DATA              (4L<<13)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE_TCP_UDP           (5L<<13)
+ #define BNX2_RPM_RC_CNTL_19_HDR_TYPE_ICMPV6            (6L<<13)
+ #define BNX2_RPM_RC_CNTL_19_COMP                       (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_19_COMP_EQUAL                         (0L<<16)
+ #define BNX2_RPM_RC_CNTL_19_COMP_NEQUAL                        (1L<<16)
+ #define BNX2_RPM_RC_CNTL_19_COMP_GREATER               (2L<<16)
+ #define BNX2_RPM_RC_CNTL_19_COMP_LESS                  (3L<<16)
+ #define BNX2_RPM_RC_CNTL_19_MAP                                (1L<<18)
+ #define BNX2_RPM_RC_CNTL_19_SBIT                       (1L<<19)
+ #define BNX2_RPM_RC_CNTL_19_CMDSEL                     (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_19_DISCARD                    (1L<<25)
+ #define BNX2_RPM_RC_CNTL_19_MASK                       (1L<<26)
+ #define BNX2_RPM_RC_CNTL_19_P1                                 (1L<<27)
+ #define BNX2_RPM_RC_CNTL_19_P2                                 (1L<<28)
+ #define BNX2_RPM_RC_CNTL_19_P3                                 (1L<<29)
+ #define BNX2_RPM_RC_CNTL_19_NBIT                       (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_19                     0x000018fc
+ #define BNX2_RPM_RC_VALUE_MASK_19_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_19_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_0                            0x00001900
+ #define BNX2_RPM_RC_CNTL_0_OFFSET                      (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_0_CLASS                       (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_0_PRIORITY                    (1L<<11)
+ #define BNX2_RPM_RC_CNTL_0_P4                          (1L<<12)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE                    (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_START              (0L<<13)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_IP                         (1L<<13)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_TCP                        (2L<<13)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_UDP                        (3L<<13)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_DATA               (4L<<13)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_TCP_UDP            (5L<<13)
+ #define BNX2_RPM_RC_CNTL_0_HDR_TYPE_ICMPV6             (6L<<13)
+ #define BNX2_RPM_RC_CNTL_0_COMP                                (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_0_COMP_EQUAL                  (0L<<16)
+ #define BNX2_RPM_RC_CNTL_0_COMP_NEQUAL                         (1L<<16)
+ #define BNX2_RPM_RC_CNTL_0_COMP_GREATER                        (2L<<16)
+ #define BNX2_RPM_RC_CNTL_0_COMP_LESS                   (3L<<16)
+ #define BNX2_RPM_RC_CNTL_0_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_0_SBIT                                (1L<<19)
+ #define BNX2_RPM_RC_CNTL_0_CMDSEL                      (0xfL<<20)
+ #define BNX2_RPM_RC_CNTL_0_MAP                                 (1L<<24)
+ #define BNX2_RPM_RC_CNTL_0_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_0_DISCARD                     (1L<<25)
+ #define BNX2_RPM_RC_CNTL_0_MASK                                (1L<<26)
+ #define BNX2_RPM_RC_CNTL_0_P1                          (1L<<27)
+ #define BNX2_RPM_RC_CNTL_0_P2                          (1L<<28)
+ #define BNX2_RPM_RC_CNTL_0_P3                          (1L<<29)
+ #define BNX2_RPM_RC_CNTL_0_NBIT                                (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_0                      0x00001904
+ #define BNX2_RPM_RC_VALUE_MASK_0_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_0_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_1                            0x00001908
+ #define BNX2_RPM_RC_CNTL_1_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_1_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_1_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_1_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_1_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_1_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_1_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_1_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_1_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_1_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_1_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_1_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_1_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_1_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_1_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_1_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_1_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_1_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_1_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_1_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_1_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_1                      0x0000190c
+ #define BNX2_RPM_RC_VALUE_MASK_1_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_1_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_2                            0x00001910
+ #define BNX2_RPM_RC_CNTL_2_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_2_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_2_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_2_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_2_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_2_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_2_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_2_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_2_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_2_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_2_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_2_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_2_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_2_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_2_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_2_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_2_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_2_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_2_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_2_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_2_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_2                      0x00001914
+ #define BNX2_RPM_RC_VALUE_MASK_2_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_2_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_3                            0x00001918
+ #define BNX2_RPM_RC_CNTL_3_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_3_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_3_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_3_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_3_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_3_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_3_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_3_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_3_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_3_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_3_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_3_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_3_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_3_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_3_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_3_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_3_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_3_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_3_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_3_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_3_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_3                      0x0000191c
+ #define BNX2_RPM_RC_VALUE_MASK_3_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_3_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_4                            0x00001920
+ #define BNX2_RPM_RC_CNTL_4_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_4_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_4_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_4_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_4_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_4_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_4_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_4_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_4_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_4_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_4_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_4_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_4_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_4_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_4_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_4_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_4_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_4_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_4_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_4_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_4_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_4                      0x00001924
+ #define BNX2_RPM_RC_VALUE_MASK_4_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_4_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_5                            0x00001928
+ #define BNX2_RPM_RC_CNTL_5_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_5_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_5_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_5_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_5_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_5_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_5_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_5_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_5_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_5_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_5_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_5_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_5_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_5_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_5_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_5_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_5_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_5_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_5_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_5_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_5_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_5                      0x0000192c
+ #define BNX2_RPM_RC_VALUE_MASK_5_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_5_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_6                            0x00001930
+ #define BNX2_RPM_RC_CNTL_6_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_6_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_6_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_6_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_6_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_6_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_6_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_6_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_6_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_6_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_6_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_6_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_6_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_6_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_6_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_6_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_6_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_6_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_6_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_6_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_6_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_6                      0x00001934
+ #define BNX2_RPM_RC_VALUE_MASK_6_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_6_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_7                            0x00001938
+ #define BNX2_RPM_RC_CNTL_7_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_7_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_7_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_7_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_7_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_7_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_7_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_7_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_7_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_7_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_7_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_7_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_7_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_7_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_7_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_7_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_7_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_7_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_7_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_7_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_7_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_7                      0x0000193c
+ #define BNX2_RPM_RC_VALUE_MASK_7_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_7_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_8                            0x00001940
+ #define BNX2_RPM_RC_CNTL_8_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_8_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_8_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_8_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_8_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_8_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_8_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_8_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_8_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_8_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_8_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_8_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_8_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_8_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_8_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_8_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_8_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_8_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_8_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_8_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_8_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_8                      0x00001944
+ #define BNX2_RPM_RC_VALUE_MASK_8_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_8_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_9                            0x00001948
+ #define BNX2_RPM_RC_CNTL_9_A                           (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_9_B                           (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_9_OFFSET_XI                   (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_9_CLASS_XI                    (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_9_PRIORITY_XI                         (1L<<11)
+ #define BNX2_RPM_RC_CNTL_9_P4_XI                       (1L<<12)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_XI                         (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_START_XI           (0L<<13)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_IP_XI              (1L<<13)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_TCP_XI             (2L<<13)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_UDP_XI             (3L<<13)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_DATA_XI            (4L<<13)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_TCP_UDP_XI                 (5L<<13)
+ #define BNX2_RPM_RC_CNTL_9_HDR_TYPE_ICMPV6_XI          (6L<<13)
+ #define BNX2_RPM_RC_CNTL_9_COMP_XI                     (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_9_COMP_EQUAL_XI               (0L<<16)
+ #define BNX2_RPM_RC_CNTL_9_COMP_NEQUAL_XI              (1L<<16)
+ #define BNX2_RPM_RC_CNTL_9_COMP_GREATER_XI             (2L<<16)
+ #define BNX2_RPM_RC_CNTL_9_COMP_LESS_XI                        (3L<<16)
+ #define BNX2_RPM_RC_CNTL_9_MAP_XI                      (1L<<18)
+ #define BNX2_RPM_RC_CNTL_9_SBIT_XI                     (1L<<19)
+ #define BNX2_RPM_RC_CNTL_9_CMDSEL_XI                   (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_9_DISCARD_XI                  (1L<<25)
+ #define BNX2_RPM_RC_CNTL_9_MASK_XI                     (1L<<26)
+ #define BNX2_RPM_RC_CNTL_9_P1_XI                       (1L<<27)
+ #define BNX2_RPM_RC_CNTL_9_P2_XI                       (1L<<28)
+ #define BNX2_RPM_RC_CNTL_9_P3_XI                       (1L<<29)
+ #define BNX2_RPM_RC_CNTL_9_NBIT_XI                     (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_9                      0x0000194c
+ #define BNX2_RPM_RC_VALUE_MASK_9_VALUE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_9_MASK                  (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_10                           0x00001950
+ #define BNX2_RPM_RC_CNTL_10_A                          (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_10_B                          (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_10_OFFSET_XI                  (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_10_CLASS_XI                   (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_10_PRIORITY_XI                        (1L<<11)
+ #define BNX2_RPM_RC_CNTL_10_P4_XI                      (1L<<12)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_XI                        (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_START_XI          (0L<<13)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_IP_XI             (1L<<13)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_TCP_XI            (2L<<13)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_UDP_XI            (3L<<13)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_DATA_XI           (4L<<13)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_TCP_UDP_XI                (5L<<13)
+ #define BNX2_RPM_RC_CNTL_10_HDR_TYPE_ICMPV6_XI                 (6L<<13)
+ #define BNX2_RPM_RC_CNTL_10_COMP_XI                    (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_10_COMP_EQUAL_XI              (0L<<16)
+ #define BNX2_RPM_RC_CNTL_10_COMP_NEQUAL_XI             (1L<<16)
+ #define BNX2_RPM_RC_CNTL_10_COMP_GREATER_XI            (2L<<16)
+ #define BNX2_RPM_RC_CNTL_10_COMP_LESS_XI               (3L<<16)
+ #define BNX2_RPM_RC_CNTL_10_MAP_XI                     (1L<<18)
+ #define BNX2_RPM_RC_CNTL_10_SBIT_XI                    (1L<<19)
+ #define BNX2_RPM_RC_CNTL_10_CMDSEL_XI                  (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_10_DISCARD_XI                         (1L<<25)
+ #define BNX2_RPM_RC_CNTL_10_MASK_XI                    (1L<<26)
+ #define BNX2_RPM_RC_CNTL_10_P1_XI                      (1L<<27)
+ #define BNX2_RPM_RC_CNTL_10_P2_XI                      (1L<<28)
+ #define BNX2_RPM_RC_CNTL_10_P3_XI                      (1L<<29)
+ #define BNX2_RPM_RC_CNTL_10_NBIT_XI                    (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_10                     0x00001954
+ #define BNX2_RPM_RC_VALUE_MASK_10_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_10_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_11                           0x00001958
+ #define BNX2_RPM_RC_CNTL_11_A                          (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_11_B                          (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_11_OFFSET_XI                  (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_11_CLASS_XI                   (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_11_PRIORITY_XI                        (1L<<11)
+ #define BNX2_RPM_RC_CNTL_11_P4_XI                      (1L<<12)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_XI                        (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_START_XI          (0L<<13)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_IP_XI             (1L<<13)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_TCP_XI            (2L<<13)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_UDP_XI            (3L<<13)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_DATA_XI           (4L<<13)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_TCP_UDP_XI                (5L<<13)
+ #define BNX2_RPM_RC_CNTL_11_HDR_TYPE_ICMPV6_XI                 (6L<<13)
+ #define BNX2_RPM_RC_CNTL_11_COMP_XI                    (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_11_COMP_EQUAL_XI              (0L<<16)
+ #define BNX2_RPM_RC_CNTL_11_COMP_NEQUAL_XI             (1L<<16)
+ #define BNX2_RPM_RC_CNTL_11_COMP_GREATER_XI            (2L<<16)
+ #define BNX2_RPM_RC_CNTL_11_COMP_LESS_XI               (3L<<16)
+ #define BNX2_RPM_RC_CNTL_11_MAP_XI                     (1L<<18)
+ #define BNX2_RPM_RC_CNTL_11_SBIT_XI                    (1L<<19)
+ #define BNX2_RPM_RC_CNTL_11_CMDSEL_XI                  (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_11_DISCARD_XI                         (1L<<25)
+ #define BNX2_RPM_RC_CNTL_11_MASK_XI                    (1L<<26)
+ #define BNX2_RPM_RC_CNTL_11_P1_XI                      (1L<<27)
+ #define BNX2_RPM_RC_CNTL_11_P2_XI                      (1L<<28)
+ #define BNX2_RPM_RC_CNTL_11_P3_XI                      (1L<<29)
+ #define BNX2_RPM_RC_CNTL_11_NBIT_XI                    (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_11                     0x0000195c
+ #define BNX2_RPM_RC_VALUE_MASK_11_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_11_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_12                           0x00001960
+ #define BNX2_RPM_RC_CNTL_12_A                          (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_12_B                          (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_12_OFFSET_XI                  (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_12_CLASS_XI                   (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_12_PRIORITY_XI                        (1L<<11)
+ #define BNX2_RPM_RC_CNTL_12_P4_XI                      (1L<<12)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_XI                        (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_START_XI          (0L<<13)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_IP_XI             (1L<<13)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_TCP_XI            (2L<<13)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_UDP_XI            (3L<<13)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_DATA_XI           (4L<<13)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_TCP_UDP_XI                (5L<<13)
+ #define BNX2_RPM_RC_CNTL_12_HDR_TYPE_ICMPV6_XI                 (6L<<13)
+ #define BNX2_RPM_RC_CNTL_12_COMP_XI                    (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_12_COMP_EQUAL_XI              (0L<<16)
+ #define BNX2_RPM_RC_CNTL_12_COMP_NEQUAL_XI             (1L<<16)
+ #define BNX2_RPM_RC_CNTL_12_COMP_GREATER_XI            (2L<<16)
+ #define BNX2_RPM_RC_CNTL_12_COMP_LESS_XI               (3L<<16)
+ #define BNX2_RPM_RC_CNTL_12_MAP_XI                     (1L<<18)
+ #define BNX2_RPM_RC_CNTL_12_SBIT_XI                    (1L<<19)
+ #define BNX2_RPM_RC_CNTL_12_CMDSEL_XI                  (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_12_DISCARD_XI                         (1L<<25)
+ #define BNX2_RPM_RC_CNTL_12_MASK_XI                    (1L<<26)
+ #define BNX2_RPM_RC_CNTL_12_P1_XI                      (1L<<27)
+ #define BNX2_RPM_RC_CNTL_12_P2_XI                      (1L<<28)
+ #define BNX2_RPM_RC_CNTL_12_P3_XI                      (1L<<29)
+ #define BNX2_RPM_RC_CNTL_12_NBIT_XI                    (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_12                     0x00001964
+ #define BNX2_RPM_RC_VALUE_MASK_12_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_12_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_13                           0x00001968
+ #define BNX2_RPM_RC_CNTL_13_A                          (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_13_B                          (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_13_OFFSET_XI                  (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_13_CLASS_XI                   (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_13_PRIORITY_XI                        (1L<<11)
+ #define BNX2_RPM_RC_CNTL_13_P4_XI                      (1L<<12)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_XI                        (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_START_XI          (0L<<13)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_IP_XI             (1L<<13)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_TCP_XI            (2L<<13)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_UDP_XI            (3L<<13)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_DATA_XI           (4L<<13)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_TCP_UDP_XI                (5L<<13)
+ #define BNX2_RPM_RC_CNTL_13_HDR_TYPE_ICMPV6_XI                 (6L<<13)
+ #define BNX2_RPM_RC_CNTL_13_COMP_XI                    (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_13_COMP_EQUAL_XI              (0L<<16)
+ #define BNX2_RPM_RC_CNTL_13_COMP_NEQUAL_XI             (1L<<16)
+ #define BNX2_RPM_RC_CNTL_13_COMP_GREATER_XI            (2L<<16)
+ #define BNX2_RPM_RC_CNTL_13_COMP_LESS_XI               (3L<<16)
+ #define BNX2_RPM_RC_CNTL_13_MAP_XI                     (1L<<18)
+ #define BNX2_RPM_RC_CNTL_13_SBIT_XI                    (1L<<19)
+ #define BNX2_RPM_RC_CNTL_13_CMDSEL_XI                  (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_13_DISCARD_XI                         (1L<<25)
+ #define BNX2_RPM_RC_CNTL_13_MASK_XI                    (1L<<26)
+ #define BNX2_RPM_RC_CNTL_13_P1_XI                      (1L<<27)
+ #define BNX2_RPM_RC_CNTL_13_P2_XI                      (1L<<28)
+ #define BNX2_RPM_RC_CNTL_13_P3_XI                      (1L<<29)
+ #define BNX2_RPM_RC_CNTL_13_NBIT_XI                    (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_13                     0x0000196c
+ #define BNX2_RPM_RC_VALUE_MASK_13_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_13_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_14                           0x00001970
+ #define BNX2_RPM_RC_CNTL_14_A                          (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_14_B                          (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_14_OFFSET_XI                  (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_14_CLASS_XI                   (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_14_PRIORITY_XI                        (1L<<11)
+ #define BNX2_RPM_RC_CNTL_14_P4_XI                      (1L<<12)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_XI                        (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_START_XI          (0L<<13)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_IP_XI             (1L<<13)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_TCP_XI            (2L<<13)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_UDP_XI            (3L<<13)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_DATA_XI           (4L<<13)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_TCP_UDP_XI                (5L<<13)
+ #define BNX2_RPM_RC_CNTL_14_HDR_TYPE_ICMPV6_XI                 (6L<<13)
+ #define BNX2_RPM_RC_CNTL_14_COMP_XI                    (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_14_COMP_EQUAL_XI              (0L<<16)
+ #define BNX2_RPM_RC_CNTL_14_COMP_NEQUAL_XI             (1L<<16)
+ #define BNX2_RPM_RC_CNTL_14_COMP_GREATER_XI            (2L<<16)
+ #define BNX2_RPM_RC_CNTL_14_COMP_LESS_XI               (3L<<16)
+ #define BNX2_RPM_RC_CNTL_14_MAP_XI                     (1L<<18)
+ #define BNX2_RPM_RC_CNTL_14_SBIT_XI                    (1L<<19)
+ #define BNX2_RPM_RC_CNTL_14_CMDSEL_XI                  (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_14_DISCARD_XI                         (1L<<25)
+ #define BNX2_RPM_RC_CNTL_14_MASK_XI                    (1L<<26)
+ #define BNX2_RPM_RC_CNTL_14_P1_XI                      (1L<<27)
+ #define BNX2_RPM_RC_CNTL_14_P2_XI                      (1L<<28)
+ #define BNX2_RPM_RC_CNTL_14_P3_XI                      (1L<<29)
+ #define BNX2_RPM_RC_CNTL_14_NBIT_XI                    (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_14                     0x00001974
+ #define BNX2_RPM_RC_VALUE_MASK_14_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_14_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CNTL_15                           0x00001978
+ #define BNX2_RPM_RC_CNTL_15_A                          (0x3ffffL<<0)
+ #define BNX2_RPM_RC_CNTL_15_B                          (0xfffL<<19)
+ #define BNX2_RPM_RC_CNTL_15_OFFSET_XI                  (0xffL<<0)
+ #define BNX2_RPM_RC_CNTL_15_CLASS_XI                   (0x7L<<8)
+ #define BNX2_RPM_RC_CNTL_15_PRIORITY_XI                        (1L<<11)
+ #define BNX2_RPM_RC_CNTL_15_P4_XI                      (1L<<12)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_XI                        (0x7L<<13)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_START_XI          (0L<<13)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_IP_XI             (1L<<13)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_TCP_XI            (2L<<13)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_UDP_XI            (3L<<13)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_DATA_XI           (4L<<13)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_TCP_UDP_XI                (5L<<13)
+ #define BNX2_RPM_RC_CNTL_15_HDR_TYPE_ICMPV6_XI                 (6L<<13)
+ #define BNX2_RPM_RC_CNTL_15_COMP_XI                    (0x3L<<16)
+ #define BNX2_RPM_RC_CNTL_15_COMP_EQUAL_XI              (0L<<16)
+ #define BNX2_RPM_RC_CNTL_15_COMP_NEQUAL_XI             (1L<<16)
+ #define BNX2_RPM_RC_CNTL_15_COMP_GREATER_XI            (2L<<16)
+ #define BNX2_RPM_RC_CNTL_15_COMP_LESS_XI               (3L<<16)
+ #define BNX2_RPM_RC_CNTL_15_MAP_XI                     (1L<<18)
+ #define BNX2_RPM_RC_CNTL_15_SBIT_XI                    (1L<<19)
+ #define BNX2_RPM_RC_CNTL_15_CMDSEL_XI                  (0x1fL<<20)
+ #define BNX2_RPM_RC_CNTL_15_DISCARD_XI                         (1L<<25)
+ #define BNX2_RPM_RC_CNTL_15_MASK_XI                    (1L<<26)
+ #define BNX2_RPM_RC_CNTL_15_P1_XI                      (1L<<27)
+ #define BNX2_RPM_RC_CNTL_15_P2_XI                      (1L<<28)
+ #define BNX2_RPM_RC_CNTL_15_P3_XI                      (1L<<29)
+ #define BNX2_RPM_RC_CNTL_15_NBIT_XI                    (1L<<30)
+ #define BNX2_RPM_RC_VALUE_MASK_15                     0x0000197c
+ #define BNX2_RPM_RC_VALUE_MASK_15_VALUE                        (0xffffL<<0)
+ #define BNX2_RPM_RC_VALUE_MASK_15_MASK                         (0xffffL<<16)
+ #define BNX2_RPM_RC_CONFIG                            0x00001980
+ #define BNX2_RPM_RC_CONFIG_RULE_ENABLE                         (0xffffL<<0)
+ #define BNX2_RPM_RC_CONFIG_RULE_ENABLE_XI              (0xfffffL<<0)
+ #define BNX2_RPM_RC_CONFIG_DEF_CLASS                   (0x7L<<24)
+ #define BNX2_RPM_RC_CONFIG_KNUM_OVERWRITE              (1L<<31)
+ #define BNX2_RPM_DEBUG0                                       0x00001984
+ #define BNX2_RPM_DEBUG0_FM_BCNT                                (0xffffL<<0)
+ #define BNX2_RPM_DEBUG0_T_DATA_OFST_VLD                        (1L<<16)
+ #define BNX2_RPM_DEBUG0_T_UDP_OFST_VLD                         (1L<<17)
+ #define BNX2_RPM_DEBUG0_T_TCP_OFST_VLD                         (1L<<18)
+ #define BNX2_RPM_DEBUG0_T_IP_OFST_VLD                  (1L<<19)
+ #define BNX2_RPM_DEBUG0_IP_MORE_FRGMT                  (1L<<20)
+ #define BNX2_RPM_DEBUG0_T_IP_NO_TCP_UDP_HDR            (1L<<21)
+ #define BNX2_RPM_DEBUG0_LLC_SNAP                       (1L<<22)
+ #define BNX2_RPM_DEBUG0_FM_STARTED                     (1L<<23)
+ #define BNX2_RPM_DEBUG0_DONE                           (1L<<24)
+ #define BNX2_RPM_DEBUG0_WAIT_4_DONE                    (1L<<25)
+ #define BNX2_RPM_DEBUG0_USE_TPBUF_CKSUM                        (1L<<26)
+ #define BNX2_RPM_DEBUG0_RX_NO_PSD_HDR_CKSUM            (1L<<27)
+ #define BNX2_RPM_DEBUG0_IGNORE_VLAN                    (1L<<28)
+ #define BNX2_RPM_DEBUG0_RP_ENA_ACTIVE                  (1L<<31)
+ #define BNX2_RPM_DEBUG1                                       0x00001988
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST                     (0xffffL<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_IDLE                        (0L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_ALL                (1L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IPLLC      (2L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_IP                 (4L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IP                 (8L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP_START            (16L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP                  (32L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_TCP                         (64L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_UDP                         (128L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_AH                  (256L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP                         (512L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP_PAYLOAD                 (1024L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_DATA                        (2048L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRY           (0x2000L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRYOUT                (0x4000L<<0)
+ #define BNX2_RPM_DEBUG1_FSM_CUR_ST_LATCH_RESULT                (0x8000L<<0)
+ #define BNX2_RPM_DEBUG1_HDR_BCNT                       (0x7ffL<<16)
+ #define BNX2_RPM_DEBUG1_UNKNOWN_ETYPE_D                        (1L<<28)
+ #define BNX2_RPM_DEBUG1_VLAN_REMOVED_D2                        (1L<<29)
+ #define BNX2_RPM_DEBUG1_VLAN_REMOVED_D1                        (1L<<30)
+ #define BNX2_RPM_DEBUG1_EOF_0XTRA_WD                   (1L<<31)
+ #define BNX2_RPM_DEBUG2                                       0x0000198c
+ #define BNX2_RPM_DEBUG2_CMD_HIT_VEC                    (0xffffL<<0)
+ #define BNX2_RPM_DEBUG2_IP_BCNT                                (0xffL<<16)
+ #define BNX2_RPM_DEBUG2_THIS_CMD_M4                    (1L<<24)
+ #define BNX2_RPM_DEBUG2_THIS_CMD_M3                    (1L<<25)
+ #define BNX2_RPM_DEBUG2_THIS_CMD_M2                    (1L<<26)
+ #define BNX2_RPM_DEBUG2_THIS_CMD_M1                    (1L<<27)
+ #define BNX2_RPM_DEBUG2_IPIPE_EMPTY                    (1L<<28)
+ #define BNX2_RPM_DEBUG2_FM_DISCARD                     (1L<<29)
+ #define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D2             (1L<<30)
+ #define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D1             (1L<<31)
+ #define BNX2_RPM_DEBUG3                                       0x00001990
+ #define BNX2_RPM_DEBUG3_AVAIL_MBUF_PTR                         (0x1ffL<<0)
+ #define BNX2_RPM_DEBUG3_RDE_RLUPQ_WR_REQ_INT           (1L<<9)
+ #define BNX2_RPM_DEBUG3_RDE_RBUF_WR_LAST_INT           (1L<<10)
+ #define BNX2_RPM_DEBUG3_RDE_RBUF_WR_REQ_INT            (1L<<11)
+ #define BNX2_RPM_DEBUG3_RDE_RBUF_FREE_REQ              (1L<<12)
+ #define BNX2_RPM_DEBUG3_RDE_RBUF_ALLOC_REQ             (1L<<13)
+ #define BNX2_RPM_DEBUG3_DFSM_MBUF_NOTAVAIL             (1L<<14)
+ #define BNX2_RPM_DEBUG3_RBUF_RDE_SOF_DROP              (1L<<15)
+ #define BNX2_RPM_DEBUG3_DFIFO_VLD_ENTRY_CT             (0xfL<<16)
+ #define BNX2_RPM_DEBUG3_RDE_SRC_FIFO_ALMFULL           (1L<<21)
+ #define BNX2_RPM_DEBUG3_DROP_NXT_VLD                   (1L<<22)
+ #define BNX2_RPM_DEBUG3_DROP_NXT                       (1L<<23)
+ #define BNX2_RPM_DEBUG3_FTQ_FSM                                (0x3L<<24)
+ #define BNX2_RPM_DEBUG3_FTQ_FSM_IDLE                   (0x0L<<24)
+ #define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_ACK               (0x1L<<24)
+ #define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_FREE              (0x2L<<24)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM                    (0x3L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_SOF           (0x0L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_GET_MBUF           (0x1L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_DMA_DATA           (0x2L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DATA          (0x3L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_EOF           (0x4L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_MF_ACK                (0x5L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DROP_NXT_VLD  (0x6L<<26)
+ #define BNX2_RPM_DEBUG3_MBWRITE_FSM_DONE               (0x7L<<26)
+ #define BNX2_RPM_DEBUG3_MBFREE_FSM                     (1L<<29)
+ #define BNX2_RPM_DEBUG3_MBFREE_FSM_IDLE                        (0L<<29)
+ #define BNX2_RPM_DEBUG3_MBFREE_FSM_WAIT_ACK            (1L<<29)
+ #define BNX2_RPM_DEBUG3_MBALLOC_FSM                    (1L<<30)
+ #define BNX2_RPM_DEBUG3_MBALLOC_FSM_ET_MBUF            (0x0L<<30)
+ #define BNX2_RPM_DEBUG3_MBALLOC_FSM_IVE_MBUF           (0x1L<<30)
+ #define BNX2_RPM_DEBUG3_CCODE_EOF_ERROR                        (1L<<31)
+ #define BNX2_RPM_DEBUG4                                       0x00001994
+ #define BNX2_RPM_DEBUG4_DFSM_MBUF_CLUSTER              (0x1ffffffL<<0)
+ #define BNX2_RPM_DEBUG4_DFIFO_CUR_CCODE                        (0x7L<<25)
+ #define BNX2_RPM_DEBUG4_MBWRITE_FSM                    (0x7L<<28)
+ #define BNX2_RPM_DEBUG4_DFIFO_EMPTY                    (1L<<31)
+ #define BNX2_RPM_DEBUG5                                       0x00001998
+ #define BNX2_RPM_DEBUG5_RDROP_WPTR                     (0x1fL<<0)
+ #define BNX2_RPM_DEBUG5_RDROP_ACPI_RPTR                        (0x1fL<<5)
+ #define BNX2_RPM_DEBUG5_RDROP_MC_RPTR                  (0x1fL<<10)
+ #define BNX2_RPM_DEBUG5_RDROP_RC_RPTR                  (0x1fL<<15)
+ #define BNX2_RPM_DEBUG5_RDROP_ACPI_EMPTY               (1L<<20)
+ #define BNX2_RPM_DEBUG5_RDROP_MC_EMPTY                         (1L<<21)
+ #define BNX2_RPM_DEBUG5_RDROP_AEOF_VEC_AT_RDROP_MC_RPTR        (1L<<22)
+ #define BNX2_RPM_DEBUG5_HOLDREG_WOL_DROP_INT           (1L<<23)
+ #define BNX2_RPM_DEBUG5_HOLDREG_DISCARD                        (1L<<24)
+ #define BNX2_RPM_DEBUG5_HOLDREG_MBUF_NOTAVAIL          (1L<<25)
+ #define BNX2_RPM_DEBUG5_HOLDREG_MC_EMPTY               (1L<<26)
+ #define BNX2_RPM_DEBUG5_HOLDREG_RC_EMPTY               (1L<<27)
+ #define BNX2_RPM_DEBUG5_HOLDREG_FC_EMPTY               (1L<<28)
+ #define BNX2_RPM_DEBUG5_HOLDREG_ACPI_EMPTY             (1L<<29)
+ #define BNX2_RPM_DEBUG5_HOLDREG_FULL_T                         (1L<<30)
+ #define BNX2_RPM_DEBUG5_HOLDREG_RD                     (1L<<31)
+ #define BNX2_RPM_DEBUG6                                       0x0000199c
+ #define BNX2_RPM_DEBUG6_ACPI_VEC                       (0xffffL<<0)
+ #define BNX2_RPM_DEBUG6_VEC                            (0xffffL<<16)
+ #define BNX2_RPM_DEBUG7                                       0x000019a0
+ #define BNX2_RPM_DEBUG7_RPM_DBG7_LAST_CRC              (0xffffffffL<<0)
+ #define BNX2_RPM_DEBUG8                                       0x000019a4
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM                    (0xfL<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_IDLE               (0L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W1_ADDR                (1L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W2_ADDR                (2L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W3_ADDR                (3L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_WAIT_THBUF     (4L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_DATA            (5L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W0_ADDR            (6L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W1_ADDR            (7L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W2_ADDR            (8L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_ADDR            (9L<<0)
+ #define BNX2_RPM_DEBUG8_PS_ACPI_FSM_WAIT_THBUF                 (10L<<0)
+ #define BNX2_RPM_DEBUG8_COMPARE_AT_W0                  (1L<<4)
+ #define BNX2_RPM_DEBUG8_COMPARE_AT_W3_DATA             (1L<<5)
+ #define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_WAIT            (1L<<6)
+ #define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W3              (1L<<7)
+ #define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W2              (1L<<8)
+ #define BNX2_RPM_DEBUG8_EOF_W_LTEQ6_VLDBYTES           (1L<<9)
+ #define BNX2_RPM_DEBUG8_EOF_W_LTEQ4_VLDBYTES           (1L<<10)
+ #define BNX2_RPM_DEBUG8_NXT_EOF_W_12_VLDBYTES          (1L<<11)
+ #define BNX2_RPM_DEBUG8_EOF_DET                                (1L<<12)
+ #define BNX2_RPM_DEBUG8_SOF_DET                                (1L<<13)
+ #define BNX2_RPM_DEBUG8_WAIT_4_SOF                     (1L<<14)
+ #define BNX2_RPM_DEBUG8_ALL_DONE                       (1L<<15)
+ #define BNX2_RPM_DEBUG8_THBUF_ADDR                     (0x7fL<<16)
+ #define BNX2_RPM_DEBUG8_BYTE_CTR                       (0xffL<<24)
+ #define BNX2_RPM_DEBUG9                                       0x000019a8
+ #define BNX2_RPM_DEBUG9_OUTFIFO_COUNT                  (0x7L<<0)
+ #define BNX2_RPM_DEBUG9_RDE_ACPI_RDY                   (1L<<3)
+ #define BNX2_RPM_DEBUG9_VLD_RD_ENTRY_CT                        (0x7L<<4)
+ #define BNX2_RPM_DEBUG9_OUTFIFO_OVERRUN_OCCURRED       (1L<<28)
+ #define BNX2_RPM_DEBUG9_INFIFO_OVERRUN_OCCURRED                (1L<<29)
+ #define BNX2_RPM_DEBUG9_ACPI_MATCH_INT                         (1L<<30)
+ #define BNX2_RPM_DEBUG9_ACPI_ENABLE_SYN                        (1L<<31)
+ #define BNX2_RPM_DEBUG9_BEMEM_R_XI                     (0x1fL<<0)
+ #define BNX2_RPM_DEBUG9_EO_XI                          (1L<<5)
+ #define BNX2_RPM_DEBUG9_AEOF_DE_XI                     (1L<<6)
+ #define BNX2_RPM_DEBUG9_SO_XI                          (1L<<7)
+ #define BNX2_RPM_DEBUG9_WD64_CT_XI                     (0x1fL<<8)
+ #define BNX2_RPM_DEBUG9_EOF_VLDBYTE_XI                         (0x7L<<13)
+ #define BNX2_RPM_DEBUG9_ACPI_RDE_PAT_ID_XI             (0xfL<<16)
+ #define BNX2_RPM_DEBUG9_CALCRC_RESULT_XI               (0x3ffL<<20)
+ #define BNX2_RPM_DEBUG9_DATA_IN_VL_XI                  (1L<<30)
+ #define BNX2_RPM_DEBUG9_CALCRC_BUFFER_VLD_XI           (1L<<31)
+ #define BNX2_RPM_ACPI_DBG_BUF_W00                     0x000019c0
+ #define BNX2_RPM_ACPI_DBG_BUF_W01                     0x000019c4
+ #define BNX2_RPM_ACPI_DBG_BUF_W02                     0x000019c8
+ #define BNX2_RPM_ACPI_DBG_BUF_W03                     0x000019cc
+ #define BNX2_RPM_ACPI_DBG_BUF_W10                     0x000019d0
+ #define BNX2_RPM_ACPI_DBG_BUF_W11                     0x000019d4
+ #define BNX2_RPM_ACPI_DBG_BUF_W12                     0x000019d8
+ #define BNX2_RPM_ACPI_DBG_BUF_W13                     0x000019dc
+ #define BNX2_RPM_ACPI_DBG_BUF_W20                     0x000019e0
+ #define BNX2_RPM_ACPI_DBG_BUF_W21                     0x000019e4
+ #define BNX2_RPM_ACPI_DBG_BUF_W22                     0x000019e8
+ #define BNX2_RPM_ACPI_DBG_BUF_W23                     0x000019ec
+ #define BNX2_RPM_ACPI_DBG_BUF_W30                     0x000019f0
+ #define BNX2_RPM_ACPI_DBG_BUF_W31                     0x000019f4
+ #define BNX2_RPM_ACPI_DBG_BUF_W32                     0x000019f8
+ #define BNX2_RPM_ACPI_DBG_BUF_W33                     0x000019fc
+ #define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL                        0x00001a00
+ #define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_BYTE_ADDRESS    (0xffffL<<0)
+ #define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_DEBUGRD                 (1L<<28)
+ #define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_MODE            (1L<<29)
+ #define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_INIT            (1L<<30)
+ #define BNX2_RPM_ACPI_BYTE_ENABLE_CTRL_WR              (1L<<31)
+ #define BNX2_RPM_ACPI_PATTERN_CTRL                    0x00001a04
+ #define BNX2_RPM_ACPI_PATTERN_CTRL_PATTERN_ID          (0xfL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CTRL_CRC_SM_CLR          (1L<<30)
+ #define BNX2_RPM_ACPI_PATTERN_CTRL_WR                  (1L<<31)
+ #define BNX2_RPM_ACPI_DATA                            0x00001a08
+ #define BNX2_RPM_ACPI_DATA_PATTERN_BE                  (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_LEN0                    0x00001a0c
+ #define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN3                (0xffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN2                (0xffL<<8)
+ #define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN1                (0xffL<<16)
+ #define BNX2_RPM_ACPI_PATTERN_LEN0_PATTERN_LEN0                (0xffL<<24)
+ #define BNX2_RPM_ACPI_PATTERN_LEN1                    0x00001a10
+ #define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN7                (0xffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN6                (0xffL<<8)
+ #define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN5                (0xffL<<16)
+ #define BNX2_RPM_ACPI_PATTERN_LEN1_PATTERN_LEN4                (0xffL<<24)
+ #define BNX2_RPM_ACPI_PATTERN_CRC0                    0x00001a18
+ #define BNX2_RPM_ACPI_PATTERN_CRC0_PATTERN_CRC0                (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CRC1                    0x00001a1c
+ #define BNX2_RPM_ACPI_PATTERN_CRC1_PATTERN_CRC1                (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CRC2                    0x00001a20
+ #define BNX2_RPM_ACPI_PATTERN_CRC2_PATTERN_CRC2                (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CRC3                    0x00001a24
+ #define BNX2_RPM_ACPI_PATTERN_CRC3_PATTERN_CRC3                (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CRC4                    0x00001a28
+ #define BNX2_RPM_ACPI_PATTERN_CRC4_PATTERN_CRC4                (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CRC5                    0x00001a2c
+ #define BNX2_RPM_ACPI_PATTERN_CRC5_PATTERN_CRC5                (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CRC6                    0x00001a30
+ #define BNX2_RPM_ACPI_PATTERN_CRC6_PATTERN_CRC6                (0xffffffffL<<0)
+ #define BNX2_RPM_ACPI_PATTERN_CRC7                    0x00001a34
+ #define BNX2_RPM_ACPI_PATTERN_CRC7_PATTERN_CRC7                (0xffffffffL<<0)
+ /*
+  *  rlup_reg definition
+  *  offset: 0x2000
+  */
+ #define BNX2_RLUP_RSS_CONFIG                          0x0000201c
+ #define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_XI          (0x3L<<0)
+ #define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI      (0L<<0)
+ #define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI      (1L<<0)
+ #define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_IP_ONLY_XI  (2L<<0)
+ #define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_RES_XI      (3L<<0)
+ #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_XI          (0x3L<<2)
+ #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI      (0L<<2)
+ #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_ALL_XI      (1L<<2)
+ #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_IP_ONLY_XI  (2L<<2)
+ #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_RES_XI      (3L<<2)
+ #define BNX2_RLUP_RSS_COMMAND                         0x00002048
+ #define BNX2_RLUP_RSS_COMMAND_RSS_IND_TABLE_ADDR       (0xfUL<<0)
+ #define BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK           (0xffUL<<4)
+ #define BNX2_RLUP_RSS_COMMAND_WRITE                    (1UL<<12)
+ #define BNX2_RLUP_RSS_COMMAND_READ                     (1UL<<13)
+ #define BNX2_RLUP_RSS_COMMAND_HASH_MASK                        (0x7UL<<14)
+ #define BNX2_RLUP_RSS_DATA                            0x0000204c
+ /*
+  *  rbuf_reg definition
+  *  offset: 0x200000
+  */
+ #define BNX2_RBUF_COMMAND                             0x00200000
+ #define BNX2_RBUF_COMMAND_ENABLED                      (1L<<0)
+ #define BNX2_RBUF_COMMAND_FREE_INIT                    (1L<<1)
+ #define BNX2_RBUF_COMMAND_RAM_INIT                     (1L<<2)
+ #define BNX2_RBUF_COMMAND_PKT_OFFSET_OVFL              (1L<<3)
+ #define BNX2_RBUF_COMMAND_OVER_FREE                    (1L<<4)
+ #define BNX2_RBUF_COMMAND_ALLOC_REQ                    (1L<<5)
+ #define BNX2_RBUF_COMMAND_EN_PRI_CHNGE_TE              (1L<<6)
+ #define BNX2_RBUF_COMMAND_CU_ISOLATE_XI                        (1L<<5)
+ #define BNX2_RBUF_COMMAND_EN_PRI_CHANGE_XI             (1L<<6)
+ #define BNX2_RBUF_COMMAND_GRC_ENDIAN_CONV_DIS_XI       (1L<<7)
+ #define BNX2_RBUF_STATUS1                             0x00200004
+ #define BNX2_RBUF_STATUS1_FREE_COUNT                   (0x3ffL<<0)
+ #define BNX2_RBUF_STATUS2                             0x00200008
+ #define BNX2_RBUF_STATUS2_FREE_TAIL                    (0x1ffL<<0)
+ #define BNX2_RBUF_STATUS2_FREE_HEAD                    (0x1ffL<<16)
+ #define BNX2_RBUF_CONFIG                              0x0020000c
+ #define BNX2_RBUF_CONFIG_XOFF_TRIP                     (0x3ffL<<0)
+ #define BNX2_RBUF_CONFIG_XOFF_TRIP_VAL(mtu)            \
+       ((((mtu) - 1500) * 31 / 1000) + 54)
+ #define BNX2_RBUF_CONFIG_XON_TRIP                      (0x3ffL<<16)
+ #define BNX2_RBUF_CONFIG_XON_TRIP_VAL(mtu)             \
+       ((((mtu) - 1500) * 39 / 1000) + 66)
+ #define BNX2_RBUF_CONFIG_VAL(mtu)                      \
+       (BNX2_RBUF_CONFIG_XOFF_TRIP_VAL(mtu) |           \
+       (BNX2_RBUF_CONFIG_XON_TRIP_VAL(mtu) << 16))
+ #define BNX2_RBUF_FW_BUF_ALLOC                                0x00200010
+ #define BNX2_RBUF_FW_BUF_ALLOC_VALUE                   (0x1ffL<<7)
+ #define BNX2_RBUF_FW_BUF_ALLOC_TYPE                    (1L<<16)
+ #define BNX2_RBUF_FW_BUF_ALLOC_ALLOC_REQ               (1L<<31)
+ #define BNX2_RBUF_FW_BUF_FREE                         0x00200014
+ #define BNX2_RBUF_FW_BUF_FREE_COUNT                    (0x7fL<<0)
+ #define BNX2_RBUF_FW_BUF_FREE_TAIL                     (0x1ffL<<7)
+ #define BNX2_RBUF_FW_BUF_FREE_HEAD                     (0x1ffL<<16)
+ #define BNX2_RBUF_FW_BUF_FREE_TYPE                     (1L<<25)
+ #define BNX2_RBUF_FW_BUF_FREE_FREE_REQ                         (1L<<31)
+ #define BNX2_RBUF_FW_BUF_SEL                          0x00200018
+ #define BNX2_RBUF_FW_BUF_SEL_COUNT                     (0x7fL<<0)
+ #define BNX2_RBUF_FW_BUF_SEL_TAIL                      (0x1ffL<<7)
+ #define BNX2_RBUF_FW_BUF_SEL_HEAD                      (0x1ffL<<16)
+ #define BNX2_RBUF_FW_BUF_SEL_SEL_REQ                   (1L<<31)
+ #define BNX2_RBUF_CONFIG2                             0x0020001c
+ #define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP                        (0x3ffL<<0)
+ #define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP_VAL(mtu)       \
+       ((((mtu) - 1500) * 4 / 1000) + 5)
+ #define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP                        (0x3ffL<<16)
+ #define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP_VAL(mtu)       \
+       ((((mtu) - 1500) * 2 / 100) + 30)
+ #define BNX2_RBUF_CONFIG2_VAL(mtu)                     \
+       (BNX2_RBUF_CONFIG2_MAC_DROP_TRIP_VAL(mtu) |      \
+       (BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP_VAL(mtu) << 16))
+ #define BNX2_RBUF_CONFIG3                             0x00200020
+ #define BNX2_RBUF_CONFIG3_CU_DROP_TRIP                         (0x3ffL<<0)
+ #define BNX2_RBUF_CONFIG3_CU_DROP_TRIP_VAL(mtu)                \
+       ((((mtu) - 1500) * 12 / 1000) + 18)
+ #define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP                         (0x3ffL<<16)
+ #define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP_VAL(mtu)                \
+       ((((mtu) - 1500) * 2 / 100) + 30)
+ #define BNX2_RBUF_CONFIG3_VAL(mtu)                     \
+       (BNX2_RBUF_CONFIG3_CU_DROP_TRIP_VAL(mtu) |       \
+       (BNX2_RBUF_CONFIG3_CU_KEEP_TRIP_VAL(mtu) << 16))
+ #define BNX2_RBUF_PKT_DATA                            0x00208000
+ #define BNX2_RBUF_CLIST_DATA                          0x00210000
+ #define BNX2_RBUF_BUF_DATA                            0x00220000
+ /*
+  *  rv2p_reg definition
+  *  offset: 0x2800
+  */
+ #define BNX2_RV2P_COMMAND                             0x00002800
+ #define BNX2_RV2P_COMMAND_ENABLED                      (1L<<0)
+ #define BNX2_RV2P_COMMAND_PROC1_INTRPT                         (1L<<1)
+ #define BNX2_RV2P_COMMAND_PROC2_INTRPT                         (1L<<2)
+ #define BNX2_RV2P_COMMAND_ABORT0                       (1L<<4)
+ #define BNX2_RV2P_COMMAND_ABORT1                       (1L<<5)
+ #define BNX2_RV2P_COMMAND_ABORT2                       (1L<<6)
+ #define BNX2_RV2P_COMMAND_ABORT3                       (1L<<7)
+ #define BNX2_RV2P_COMMAND_ABORT4                       (1L<<8)
+ #define BNX2_RV2P_COMMAND_ABORT5                       (1L<<9)
+ #define BNX2_RV2P_COMMAND_PROC1_RESET                  (1L<<16)
+ #define BNX2_RV2P_COMMAND_PROC2_RESET                  (1L<<17)
+ #define BNX2_RV2P_COMMAND_CTXIF_RESET                  (1L<<18)
+ #define BNX2_RV2P_STATUS                              0x00002804
+ #define BNX2_RV2P_STATUS_ALWAYS_0                      (1L<<0)
+ #define BNX2_RV2P_STATUS_RV2P_GEN_STAT0_CNT            (1L<<8)
+ #define BNX2_RV2P_STATUS_RV2P_GEN_STAT1_CNT            (1L<<9)
+ #define BNX2_RV2P_STATUS_RV2P_GEN_STAT2_CNT            (1L<<10)
+ #define BNX2_RV2P_STATUS_RV2P_GEN_STAT3_CNT            (1L<<11)
+ #define BNX2_RV2P_STATUS_RV2P_GEN_STAT4_CNT            (1L<<12)
+ #define BNX2_RV2P_STATUS_RV2P_GEN_STAT5_CNT            (1L<<13)
+ #define BNX2_RV2P_CONFIG                              0x00002808
+ #define BNX2_RV2P_CONFIG_STALL_PROC1                   (1L<<0)
+ #define BNX2_RV2P_CONFIG_STALL_PROC2                   (1L<<1)
+ #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT0                 (1L<<8)
+ #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT1                 (1L<<9)
+ #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT2                 (1L<<10)
+ #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT3                 (1L<<11)
+ #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT4                 (1L<<12)
+ #define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT5                 (1L<<13)
+ #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT0                 (1L<<16)
+ #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT1                 (1L<<17)
+ #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT2                 (1L<<18)
+ #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT3                 (1L<<19)
+ #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT4                 (1L<<20)
+ #define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT5                 (1L<<21)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE                     (0xfL<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_256                         (0L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_512                         (1L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_1K                  (2L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_2K                  (3L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_4K                  (4L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_8K                  (5L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_16K                         (6L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_32K                         (7L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_64K                         (8L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_128K                        (9L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_256K                        (10L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_512K                        (11L<<24)
+ #define BNX2_RV2P_CONFIG_PAGE_SIZE_1M                  (12L<<24)
+ #define BNX2_RV2P_GEN_BFR_ADDR_0                      0x00002810
+ #define BNX2_RV2P_GEN_BFR_ADDR_0_VALUE                         (0xffffL<<16)
+ #define BNX2_RV2P_GEN_BFR_ADDR_1                      0x00002814
+ #define BNX2_RV2P_GEN_BFR_ADDR_1_VALUE                         (0xffffL<<16)
+ #define BNX2_RV2P_GEN_BFR_ADDR_2                      0x00002818
+ #define BNX2_RV2P_GEN_BFR_ADDR_2_VALUE                         (0xffffL<<16)
+ #define BNX2_RV2P_GEN_BFR_ADDR_3                      0x0000281c
+ #define BNX2_RV2P_GEN_BFR_ADDR_3_VALUE                         (0xffffL<<16)
+ #define BNX2_RV2P_INSTR_HIGH                          0x00002830
+ #define BNX2_RV2P_INSTR_HIGH_HIGH                      (0x1fL<<0)
+ #define BNX2_RV2P_INSTR_LOW                           0x00002834
+ #define BNX2_RV2P_INSTR_LOW_LOW                                (0xffffffffL<<0)
+ #define BNX2_RV2P_PROC1_ADDR_CMD                      0x00002838
+ #define BNX2_RV2P_PROC1_ADDR_CMD_ADD                   (0x3ffL<<0)
+ #define BNX2_RV2P_PROC1_ADDR_CMD_RDWR                  (1L<<31)
+ #define BNX2_RV2P_PROC2_ADDR_CMD                      0x0000283c
+ #define BNX2_RV2P_PROC2_ADDR_CMD_ADD                   (0x3ffL<<0)
+ #define BNX2_RV2P_PROC2_ADDR_CMD_RDWR                  (1L<<31)
+ #define BNX2_RV2P_PROC1_GRC_DEBUG                     0x00002840
+ #define BNX2_RV2P_PROC2_GRC_DEBUG                     0x00002844
+ #define BNX2_RV2P_GRC_PROC_DEBUG                      0x00002848
+ #define BNX2_RV2P_DEBUG_VECT_PEEK                     0x0000284c
+ #define BNX2_RV2P_DEBUG_VECT_PEEK_1_VALUE              (0x7ffL<<0)
+ #define BNX2_RV2P_DEBUG_VECT_PEEK_1_PEEK_EN            (1L<<11)
+ #define BNX2_RV2P_DEBUG_VECT_PEEK_1_SEL                        (0xfL<<12)
+ #define BNX2_RV2P_DEBUG_VECT_PEEK_2_VALUE              (0x7ffL<<16)
+ #define BNX2_RV2P_DEBUG_VECT_PEEK_2_PEEK_EN            (1L<<27)
+ #define BNX2_RV2P_DEBUG_VECT_PEEK_2_SEL                        (0xfL<<28)
+ #define BNX2_RV2P_MPFE_PFE_CTL                                0x00002afc
+ #define BNX2_RV2P_MPFE_PFE_CTL_INC_USAGE_CNT           (1L<<0)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE                        (0xfL<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_0              (0L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_1              (1L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_2              (2L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_3              (3L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_4              (4L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_5              (5L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_6              (6L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_7              (7L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_8              (8L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_9              (9L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_10             (10L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_11             (11L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_12             (12L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_13             (13L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_14             (14L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_SIZE_15             (15L<<4)
+ #define BNX2_RV2P_MPFE_PFE_CTL_PFE_COUNT               (0xfL<<12)
+ #define BNX2_RV2P_MPFE_PFE_CTL_OFFSET                  (0x1ffL<<16)
+ #define BNX2_RV2P_RV2PPQ                              0x00002b40
+ #define BNX2_RV2P_PFTQ_CMD                            0x00002b78
+ #define BNX2_RV2P_PFTQ_CMD_OFFSET                      (0x3ffL<<0)
+ #define BNX2_RV2P_PFTQ_CMD_WR_TOP                      (1L<<10)
+ #define BNX2_RV2P_PFTQ_CMD_WR_TOP_0                    (0L<<10)
+ #define BNX2_RV2P_PFTQ_CMD_WR_TOP_1                    (1L<<10)
+ #define BNX2_RV2P_PFTQ_CMD_SFT_RESET                   (1L<<25)
+ #define BNX2_RV2P_PFTQ_CMD_RD_DATA                     (1L<<26)
+ #define BNX2_RV2P_PFTQ_CMD_ADD_INTERVEN                        (1L<<27)
+ #define BNX2_RV2P_PFTQ_CMD_ADD_DATA                    (1L<<28)
+ #define BNX2_RV2P_PFTQ_CMD_INTERVENE_CLR               (1L<<29)
+ #define BNX2_RV2P_PFTQ_CMD_POP                                 (1L<<30)
+ #define BNX2_RV2P_PFTQ_CMD_BUSY                                (1L<<31)
+ #define BNX2_RV2P_PFTQ_CTL                            0x00002b7c
+ #define BNX2_RV2P_PFTQ_CTL_INTERVENE                   (1L<<0)
+ #define BNX2_RV2P_PFTQ_CTL_OVERFLOW                    (1L<<1)
+ #define BNX2_RV2P_PFTQ_CTL_FORCE_INTERVENE             (1L<<2)
+ #define BNX2_RV2P_PFTQ_CTL_MAX_DEPTH                   (0x3ffL<<12)
+ #define BNX2_RV2P_PFTQ_CTL_CUR_DEPTH                   (0x3ffL<<22)
+ #define BNX2_RV2P_RV2PTQ                              0x00002b80
+ #define BNX2_RV2P_TFTQ_CMD                            0x00002bb8
+ #define BNX2_RV2P_TFTQ_CMD_OFFSET                      (0x3ffL<<0)
+ #define BNX2_RV2P_TFTQ_CMD_WR_TOP                      (1L<<10)
+ #define BNX2_RV2P_TFTQ_CMD_WR_TOP_0                    (0L<<10)
+ #define BNX2_RV2P_TFTQ_CMD_WR_TOP_1                    (1L<<10)
+ #define BNX2_RV2P_TFTQ_CMD_SFT_RESET                   (1L<<25)
+ #define BNX2_RV2P_TFTQ_CMD_RD_DATA                     (1L<<26)
+ #define BNX2_RV2P_TFTQ_CMD_ADD_INTERVEN                        (1L<<27)
+ #define BNX2_RV2P_TFTQ_CMD_ADD_DATA                    (1L<<28)
+ #define BNX2_RV2P_TFTQ_CMD_INTERVENE_CLR               (1L<<29)
+ #define BNX2_RV2P_TFTQ_CMD_POP                                 (1L<<30)
+ #define BNX2_RV2P_TFTQ_CMD_BUSY                                (1L<<31)
+ #define BNX2_RV2P_TFTQ_CTL                            0x00002bbc
+ #define BNX2_RV2P_TFTQ_CTL_INTERVENE                   (1L<<0)
+ #define BNX2_RV2P_TFTQ_CTL_OVERFLOW                    (1L<<1)
+ #define BNX2_RV2P_TFTQ_CTL_FORCE_INTERVENE             (1L<<2)
+ #define BNX2_RV2P_TFTQ_CTL_MAX_DEPTH                   (0x3ffL<<12)
+ #define BNX2_RV2P_TFTQ_CTL_CUR_DEPTH                   (0x3ffL<<22)
+ #define BNX2_RV2P_RV2PMQ                              0x00002bc0
+ #define BNX2_RV2P_MFTQ_CMD                            0x00002bf8
+ #define BNX2_RV2P_MFTQ_CMD_OFFSET                      (0x3ffL<<0)
+ #define BNX2_RV2P_MFTQ_CMD_WR_TOP                      (1L<<10)
+ #define BNX2_RV2P_MFTQ_CMD_WR_TOP_0                    (0L<<10)
+ #define BNX2_RV2P_MFTQ_CMD_WR_TOP_1                    (1L<<10)
+ #define BNX2_RV2P_MFTQ_CMD_SFT_RESET                   (1L<<25)
+ #define BNX2_RV2P_MFTQ_CMD_RD_DATA                     (1L<<26)
+ #define BNX2_RV2P_MFTQ_CMD_ADD_INTERVEN                        (1L<<27)
+ #define BNX2_RV2P_MFTQ_CMD_ADD_DATA                    (1L<<28)
+ #define BNX2_RV2P_MFTQ_CMD_INTERVENE_CLR               (1L<<29)
+ #define BNX2_RV2P_MFTQ_CMD_POP                                 (1L<<30)
+ #define BNX2_RV2P_MFTQ_CMD_BUSY                                (1L<<31)
+ #define BNX2_RV2P_MFTQ_CTL                            0x00002bfc
+ #define BNX2_RV2P_MFTQ_CTL_INTERVENE                   (1L<<0)
+ #define BNX2_RV2P_MFTQ_CTL_OVERFLOW                    (1L<<1)
+ #define BNX2_RV2P_MFTQ_CTL_FORCE_INTERVENE             (1L<<2)
+ #define BNX2_RV2P_MFTQ_CTL_MAX_DEPTH                   (0x3ffL<<12)
+ #define BNX2_RV2P_MFTQ_CTL_CUR_DEPTH                   (0x3ffL<<22)
+ /*
+  *  mq_reg definition
+  *  offset: 0x3c00
+  */
+ #define BNX2_MQ_COMMAND                                       0x00003c00
+ #define BNX2_MQ_COMMAND_ENABLED                                (1L<<0)
+ #define BNX2_MQ_COMMAND_INIT                           (1L<<1)
+ #define BNX2_MQ_COMMAND_OVERFLOW                       (1L<<4)
+ #define BNX2_MQ_COMMAND_WR_ERROR                       (1L<<5)
+ #define BNX2_MQ_COMMAND_RD_ERROR                       (1L<<6)
+ #define BNX2_MQ_COMMAND_IDB_CFG_ERROR                  (1L<<7)
+ #define BNX2_MQ_COMMAND_IDB_OVERFLOW                   (1L<<10)
+ #define BNX2_MQ_COMMAND_NO_BIN_ERROR                   (1L<<11)
+ #define BNX2_MQ_COMMAND_NO_MAP_ERROR                   (1L<<12)
+ #define BNX2_MQ_STATUS                                        0x00003c04
+ #define BNX2_MQ_STATUS_CTX_ACCESS_STAT                         (1L<<16)
+ #define BNX2_MQ_STATUS_CTX_ACCESS64_STAT               (1L<<17)
+ #define BNX2_MQ_STATUS_PCI_STALL_STAT                  (1L<<18)
+ #define BNX2_MQ_STATUS_IDB_OFLOW_STAT                  (1L<<19)
+ #define BNX2_MQ_CONFIG                                        0x00003c08
+ #define BNX2_MQ_CONFIG_TX_HIGH_PRI                     (1L<<0)
+ #define BNX2_MQ_CONFIG_HALT_DIS                                (1L<<1)
+ #define BNX2_MQ_CONFIG_BIN_MQ_MODE                     (1L<<2)
+ #define BNX2_MQ_CONFIG_DIS_IDB_DROP                    (1L<<3)
+ #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE                        (0x7L<<4)
+ #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256            (0L<<4)
+ #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_512            (1L<<4)
+ #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_1K             (2L<<4)
+ #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_2K             (3L<<4)
+ #define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_4K             (4L<<4)
+ #define BNX2_MQ_CONFIG_MAX_DEPTH                       (0x7fL<<8)
+ #define BNX2_MQ_CONFIG_CUR_DEPTH                       (0x7fL<<20)
+ #define BNX2_MQ_ENQUEUE1                              0x00003c0c
+ #define BNX2_MQ_ENQUEUE1_OFFSET                                (0x3fL<<2)
+ #define BNX2_MQ_ENQUEUE1_CID                           (0x3fffL<<8)
+ #define BNX2_MQ_ENQUEUE1_BYTE_MASK                     (0xfL<<24)
+ #define BNX2_MQ_ENQUEUE1_KNL_MODE                      (1L<<28)
+ #define BNX2_MQ_ENQUEUE2                              0x00003c10
+ #define BNX2_MQ_BAD_WR_ADDR                           0x00003c14
+ #define BNX2_MQ_BAD_RD_ADDR                           0x00003c18
+ #define BNX2_MQ_KNL_BYP_WIND_START                    0x00003c1c
+ #define BNX2_MQ_KNL_BYP_WIND_START_VALUE               (0xfffffL<<12)
+ #define BNX2_MQ_KNL_WIND_END                          0x00003c20
+ #define BNX2_MQ_KNL_WIND_END_VALUE                     (0xffffffL<<8)
+ #define BNX2_MQ_KNL_WRITE_MASK1                               0x00003c24
+ #define BNX2_MQ_KNL_TX_MASK1                          0x00003c28
+ #define BNX2_MQ_KNL_CMD_MASK1                         0x00003c2c
+ #define BNX2_MQ_KNL_COND_ENQUEUE_MASK1                        0x00003c30
+ #define BNX2_MQ_KNL_RX_V2P_MASK1                      0x00003c34
+ #define BNX2_MQ_KNL_WRITE_MASK2                               0x00003c38
+ #define BNX2_MQ_KNL_TX_MASK2                          0x00003c3c
+ #define BNX2_MQ_KNL_CMD_MASK2                         0x00003c40
+ #define BNX2_MQ_KNL_COND_ENQUEUE_MASK2                        0x00003c44
+ #define BNX2_MQ_KNL_RX_V2P_MASK2                      0x00003c48
+ #define BNX2_MQ_KNL_BYP_WRITE_MASK1                   0x00003c4c
+ #define BNX2_MQ_KNL_BYP_TX_MASK1                      0x00003c50
+ #define BNX2_MQ_KNL_BYP_CMD_MASK1                     0x00003c54
+ #define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK1            0x00003c58
+ #define BNX2_MQ_KNL_BYP_RX_V2P_MASK1                  0x00003c5c
+ #define BNX2_MQ_KNL_BYP_WRITE_MASK2                   0x00003c60
+ #define BNX2_MQ_KNL_BYP_TX_MASK2                      0x00003c64
+ #define BNX2_MQ_KNL_BYP_CMD_MASK2                     0x00003c68
+ #define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK2            0x00003c6c
+ #define BNX2_MQ_KNL_BYP_RX_V2P_MASK2                  0x00003c70
+ #define BNX2_MQ_MEM_WR_ADDR                           0x00003c74
+ #define BNX2_MQ_MEM_WR_ADDR_VALUE                      (0x3fL<<0)
+ #define BNX2_MQ_MEM_WR_DATA0                          0x00003c78
+ #define BNX2_MQ_MEM_WR_DATA0_VALUE                     (0xffffffffL<<0)
+ #define BNX2_MQ_MEM_WR_DATA1                          0x00003c7c
+ #define BNX2_MQ_MEM_WR_DATA1_VALUE                     (0xffffffffL<<0)
+ #define BNX2_MQ_MEM_WR_DATA2                          0x00003c80
+ #define BNX2_MQ_MEM_WR_DATA2_VALUE                     (0x3fffffffL<<0)
+ #define BNX2_MQ_MEM_WR_DATA2_VALUE_XI                  (0x7fffffffL<<0)
+ #define BNX2_MQ_MEM_RD_ADDR                           0x00003c84
+ #define BNX2_MQ_MEM_RD_ADDR_VALUE                      (0x3fL<<0)
+ #define BNX2_MQ_MEM_RD_DATA0                          0x00003c88
+ #define BNX2_MQ_MEM_RD_DATA0_VALUE                     (0xffffffffL<<0)
+ #define BNX2_MQ_MEM_RD_DATA1                          0x00003c8c
+ #define BNX2_MQ_MEM_RD_DATA1_VALUE                     (0xffffffffL<<0)
+ #define BNX2_MQ_MEM_RD_DATA2                          0x00003c90
+ #define BNX2_MQ_MEM_RD_DATA2_VALUE                     (0x3fffffffL<<0)
+ #define BNX2_MQ_MEM_RD_DATA2_VALUE_XI                  (0x7fffffffL<<0)
+ #define BNX2_MQ_MAP_L2_3                              0x00003d2c
+ #define BNX2_MQ_MAP_L2_3_MQ_OFFSET                     (0xffL<<0)
+ #define BNX2_MQ_MAP_L2_3_SZ                            (0x3L<<8)
+ #define BNX2_MQ_MAP_L2_3_CTX_OFFSET                    (0x2ffL<<10)
+ #define BNX2_MQ_MAP_L2_3_BIN_OFFSET                    (0x7L<<23)
+ #define BNX2_MQ_MAP_L2_3_ARM                           (0x3L<<26)
+ #define BNX2_MQ_MAP_L2_3_ENA                           (0x1L<<31)
+ #define BNX2_MQ_MAP_L2_3_DEFAULT                       0x82004646
+ #define BNX2_MQ_MAP_L2_5                              0x00003d34
+ #define BNX2_MQ_MAP_L2_5_ARM                           (0x3L<<26)
+ /*
+  *  tsch_reg definition
+  *  offset: 0x4c00
+  */
+ #define BNX2_TSCH_TSS_CFG                             0x00004c1c
+ #define BNX2_TSCH_TSS_CFG_TSS_START_CID                        (0x7ffL<<8)
+ #define BNX2_TSCH_TSS_CFG_NUM_OF_TSS_CON               (0xfL<<24)
+ /*
+  *  tbdr_reg definition
+  *  offset: 0x5000
+  */
+ #define BNX2_TBDR_COMMAND                             0x00005000
+ #define BNX2_TBDR_COMMAND_ENABLE                       (1L<<0)
+ #define BNX2_TBDR_COMMAND_SOFT_RST                     (1L<<1)
+ #define BNX2_TBDR_COMMAND_MSTR_ABORT                   (1L<<4)
+ #define BNX2_TBDR_STATUS                              0x00005004
+ #define BNX2_TBDR_STATUS_DMA_WAIT                      (1L<<0)
+ #define BNX2_TBDR_STATUS_FTQ_WAIT                      (1L<<1)
+ #define BNX2_TBDR_STATUS_FIFO_OVERFLOW                         (1L<<2)
+ #define BNX2_TBDR_STATUS_FIFO_UNDERFLOW                        (1L<<3)
+ #define BNX2_TBDR_STATUS_SEARCHMISS_ERROR              (1L<<4)
+ #define BNX2_TBDR_STATUS_FTQ_ENTRY_CNT                         (1L<<5)
+ #define BNX2_TBDR_STATUS_BURST_CNT                     (1L<<6)
+ #define BNX2_TBDR_CONFIG                              0x00005008
+ #define BNX2_TBDR_CONFIG_MAX_BDS                       (0xffL<<0)
+ #define BNX2_TBDR_CONFIG_SWAP_MODE                     (1L<<8)
+ #define BNX2_TBDR_CONFIG_PRIORITY                      (1L<<9)
+ #define BNX2_TBDR_CONFIG_CACHE_NEXT_PAGE_PTRS          (1L<<10)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE                     (0xfL<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_256                         (0L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_512                         (1L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_1K                  (2L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_2K                  (3L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_4K                  (4L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_8K                  (5L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_16K                         (6L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_32K                         (7L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_64K                         (8L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_128K                        (9L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_256K                        (10L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_512K                        (11L<<24)
+ #define BNX2_TBDR_CONFIG_PAGE_SIZE_1M                  (12L<<24)
+ #define BNX2_TBDR_DEBUG_VECT_PEEK                     0x0000500c
+ #define BNX2_TBDR_DEBUG_VECT_PEEK_1_VALUE              (0x7ffL<<0)
+ #define BNX2_TBDR_DEBUG_VECT_PEEK_1_PEEK_EN            (1L<<11)
+ #define BNX2_TBDR_DEBUG_VECT_PEEK_1_SEL                        (0xfL<<12)
+ #define BNX2_TBDR_DEBUG_VECT_PEEK_2_VALUE              (0x7ffL<<16)
+ #define BNX2_TBDR_DEBUG_VECT_PEEK_2_PEEK_EN            (1L<<27)
+ #define BNX2_TBDR_DEBUG_VECT_PEEK_2_SEL                        (0xfL<<28)
+ #define BNX2_TBDR_CKSUM_ERROR_STATUS                  0x00005010
+ #define BNX2_TBDR_CKSUM_ERROR_STATUS_CALCULATED                (0xffffL<<0)
+ #define BNX2_TBDR_CKSUM_ERROR_STATUS_EXPECTED          (0xffffL<<16)
+ #define BNX2_TBDR_TBDRQ                                       0x000053c0
+ #define BNX2_TBDR_FTQ_CMD                             0x000053f8
+ #define BNX2_TBDR_FTQ_CMD_OFFSET                       (0x3ffL<<0)
+ #define BNX2_TBDR_FTQ_CMD_WR_TOP                       (1L<<10)
+ #define BNX2_TBDR_FTQ_CMD_WR_TOP_0                     (0L<<10)
+ #define BNX2_TBDR_FTQ_CMD_WR_TOP_1                     (1L<<10)
+ #define BNX2_TBDR_FTQ_CMD_SFT_RESET                    (1L<<25)
+ #define BNX2_TBDR_FTQ_CMD_RD_DATA                      (1L<<26)
+ #define BNX2_TBDR_FTQ_CMD_ADD_INTERVEN                         (1L<<27)
+ #define BNX2_TBDR_FTQ_CMD_ADD_DATA                     (1L<<28)
+ #define BNX2_TBDR_FTQ_CMD_INTERVENE_CLR                        (1L<<29)
+ #define BNX2_TBDR_FTQ_CMD_POP                          (1L<<30)
+ #define BNX2_TBDR_FTQ_CMD_BUSY                                 (1L<<31)
+ #define BNX2_TBDR_FTQ_CTL                             0x000053fc
+ #define BNX2_TBDR_FTQ_CTL_INTERVENE                    (1L<<0)
+ #define BNX2_TBDR_FTQ_CTL_OVERFLOW                     (1L<<1)
+ #define BNX2_TBDR_FTQ_CTL_FORCE_INTERVENE              (1L<<2)
+ #define BNX2_TBDR_FTQ_CTL_MAX_DEPTH                    (0x3ffL<<12)
+ #define BNX2_TBDR_FTQ_CTL_CUR_DEPTH                    (0x3ffL<<22)
+ /*
+  *  tdma_reg definition
+  *  offset: 0x5c00
+  */
+ #define BNX2_TDMA_COMMAND                             0x00005c00
+ #define BNX2_TDMA_COMMAND_ENABLED                      (1L<<0)
+ #define BNX2_TDMA_COMMAND_MASTER_ABORT                         (1L<<4)
+ #define BNX2_TDMA_COMMAND_CS16_ERR                     (1L<<5)
+ #define BNX2_TDMA_COMMAND_BAD_L2_LENGTH_ABORT          (1L<<7)
+ #define BNX2_TDMA_COMMAND_MASK_CS1                     (1L<<20)
+ #define BNX2_TDMA_COMMAND_MASK_CS2                     (1L<<21)
+ #define BNX2_TDMA_COMMAND_MASK_CS3                     (1L<<22)
+ #define BNX2_TDMA_COMMAND_MASK_CS4                     (1L<<23)
+ #define BNX2_TDMA_COMMAND_FORCE_ILOCK_CKERR            (1L<<24)
+ #define BNX2_TDMA_COMMAND_OFIFO_CLR                    (1L<<30)
+ #define BNX2_TDMA_COMMAND_IFIFO_CLR                    (1L<<31)
+ #define BNX2_TDMA_STATUS                              0x00005c04
+ #define BNX2_TDMA_STATUS_DMA_WAIT                      (1L<<0)
+ #define BNX2_TDMA_STATUS_PAYLOAD_WAIT                  (1L<<1)
+ #define BNX2_TDMA_STATUS_PATCH_FTQ_WAIT                        (1L<<2)
+ #define BNX2_TDMA_STATUS_LOCK_WAIT                     (1L<<3)
+ #define BNX2_TDMA_STATUS_FTQ_ENTRY_CNT                         (1L<<16)
+ #define BNX2_TDMA_STATUS_BURST_CNT                     (1L<<17)
+ #define BNX2_TDMA_STATUS_MAX_IFIFO_DEPTH               (0x3fL<<20)
+ #define BNX2_TDMA_STATUS_OFIFO_OVERFLOW                        (1L<<30)
+ #define BNX2_TDMA_STATUS_IFIFO_OVERFLOW                        (1L<<31)
+ #define BNX2_TDMA_CONFIG                              0x00005c08
+ #define BNX2_TDMA_CONFIG_ONE_DMA                       (1L<<0)
+ #define BNX2_TDMA_CONFIG_ONE_RECORD                    (1L<<1)
+ #define BNX2_TDMA_CONFIG_NUM_DMA_CHAN                  (0x3L<<2)
+ #define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_0                        (0L<<2)
+ #define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_1                        (1L<<2)
+ #define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_2                        (2L<<2)
+ #define BNX2_TDMA_CONFIG_NUM_DMA_CHAN_3                        (3L<<2)
+ #define BNX2_TDMA_CONFIG_LIMIT_SZ                      (0xfL<<4)
+ #define BNX2_TDMA_CONFIG_LIMIT_SZ_64                   (0L<<4)
+ #define BNX2_TDMA_CONFIG_LIMIT_SZ_128                  (0x4L<<4)
+ #define BNX2_TDMA_CONFIG_LIMIT_SZ_256                  (0x6L<<4)
+ #define BNX2_TDMA_CONFIG_LIMIT_SZ_512                  (0x8L<<4)
+ #define BNX2_TDMA_CONFIG_LINE_SZ                       (0xfL<<8)
+ #define BNX2_TDMA_CONFIG_LINE_SZ_64                    (0L<<8)
+ #define BNX2_TDMA_CONFIG_LINE_SZ_128                   (4L<<8)
+ #define BNX2_TDMA_CONFIG_LINE_SZ_256                   (6L<<8)
+ #define BNX2_TDMA_CONFIG_LINE_SZ_512                   (8L<<8)
+ #define BNX2_TDMA_CONFIG_ALIGN_ENA                     (1L<<15)
+ #define BNX2_TDMA_CONFIG_CHK_L2_BD                     (1L<<16)
+ #define BNX2_TDMA_CONFIG_CMPL_ENTRY                    (1L<<17)
+ #define BNX2_TDMA_CONFIG_OFIFO_CMP                     (1L<<19)
+ #define BNX2_TDMA_CONFIG_OFIFO_CMP_3                   (0L<<19)
+ #define BNX2_TDMA_CONFIG_OFIFO_CMP_2                   (1L<<19)
+ #define BNX2_TDMA_CONFIG_FIFO_CMP                      (0xfL<<20)
+ #define BNX2_TDMA_CONFIG_IFIFO_DEPTH_XI                        (0x7L<<20)
+ #define BNX2_TDMA_CONFIG_IFIFO_DEPTH_0_XI              (0L<<20)
+ #define BNX2_TDMA_CONFIG_IFIFO_DEPTH_4_XI              (1L<<20)
+ #define BNX2_TDMA_CONFIG_IFIFO_DEPTH_8_XI              (2L<<20)
+ #define BNX2_TDMA_CONFIG_IFIFO_DEPTH_16_XI             (3L<<20)
+ #define BNX2_TDMA_CONFIG_IFIFO_DEPTH_32_XI             (4L<<20)
+ #define BNX2_TDMA_CONFIG_IFIFO_DEPTH_64_XI             (5L<<20)
+ #define BNX2_TDMA_CONFIG_FIFO_CMP_EN_XI                        (1L<<23)
+ #define BNX2_TDMA_CONFIG_BYTES_OST_XI                  (0x7L<<24)
+ #define BNX2_TDMA_CONFIG_BYTES_OST_512_XI              (0L<<24)
+ #define BNX2_TDMA_CONFIG_BYTES_OST_1024_XI             (1L<<24)
+ #define BNX2_TDMA_CONFIG_BYTES_OST_2048_XI             (2L<<24)
+ #define BNX2_TDMA_CONFIG_BYTES_OST_4096_XI             (3L<<24)
+ #define BNX2_TDMA_CONFIG_BYTES_OST_8192_XI             (4L<<24)
+ #define BNX2_TDMA_CONFIG_BYTES_OST_16384_XI            (5L<<24)
+ #define BNX2_TDMA_CONFIG_HC_BYPASS_XI                  (1L<<27)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_XI                   (0x7L<<28)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_128_XI               (0L<<28)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_256_XI               (1L<<28)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_512_XI               (2L<<28)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_1024_XI              (3L<<28)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_2048_XI              (4L<<28)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_4096_XI              (5L<<28)
+ #define BNX2_TDMA_CONFIG_LCL_MRRS_EN_XI                        (1L<<31)
+ #define BNX2_TDMA_PAYLOAD_PROD                                0x00005c0c
+ #define BNX2_TDMA_PAYLOAD_PROD_VALUE                   (0x1fffL<<3)
+ #define BNX2_TDMA_DBG_WATCHDOG                                0x00005c10
+ #define BNX2_TDMA_DBG_TRIGGER                         0x00005c14
+ #define BNX2_TDMA_DMAD_FSM                            0x00005c80
+ #define BNX2_TDMA_DMAD_FSM_BD_INVLD                    (1L<<0)
+ #define BNX2_TDMA_DMAD_FSM_PUSH                                (0xfL<<4)
+ #define BNX2_TDMA_DMAD_FSM_ARB_TBDC                    (0x3L<<8)
+ #define BNX2_TDMA_DMAD_FSM_ARB_CTX                     (1L<<12)
+ #define BNX2_TDMA_DMAD_FSM_DR_INTF                     (1L<<16)
+ #define BNX2_TDMA_DMAD_FSM_DMAD                                (0x7L<<20)
+ #define BNX2_TDMA_DMAD_FSM_BD                          (0xfL<<24)
+ #define BNX2_TDMA_DMAD_STATUS                         0x00005c84
+ #define BNX2_TDMA_DMAD_STATUS_RHOLD_PUSH_ENTRY                 (0x3L<<0)
+ #define BNX2_TDMA_DMAD_STATUS_RHOLD_DMAD_ENTRY                 (0x3L<<4)
+ #define BNX2_TDMA_DMAD_STATUS_RHOLD_BD_ENTRY           (0x3L<<8)
+ #define BNX2_TDMA_DMAD_STATUS_IFTQ_ENUM                        (0xfL<<12)
+ #define BNX2_TDMA_DR_INTF_FSM                         0x00005c88
+ #define BNX2_TDMA_DR_INTF_FSM_L2_COMP                  (0x3L<<0)
+ #define BNX2_TDMA_DR_INTF_FSM_TPATQ                    (0x7L<<4)
+ #define BNX2_TDMA_DR_INTF_FSM_TPBUF                    (0x3L<<8)
+ #define BNX2_TDMA_DR_INTF_FSM_DR_BUF                   (0x7L<<12)
+ #define BNX2_TDMA_DR_INTF_FSM_DMAD                     (0x7L<<16)
+ #define BNX2_TDMA_DR_INTF_STATUS                      0x00005c8c
+ #define BNX2_TDMA_DR_INTF_STATUS_HOLE_PHASE            (0x7L<<0)
+ #define BNX2_TDMA_DR_INTF_STATUS_DATA_AVAIL            (0x3L<<4)
+ #define BNX2_TDMA_DR_INTF_STATUS_SHIFT_ADDR            (0x7L<<8)
+ #define BNX2_TDMA_DR_INTF_STATUS_NXT_PNTR              (0xfL<<12)
+ #define BNX2_TDMA_DR_INTF_STATUS_BYTE_COUNT            (0x7L<<16)
+ #define BNX2_TDMA_PUSH_FSM                            0x00005c90
+ #define BNX2_TDMA_BD_IF_DEBUG                         0x00005c94
+ #define BNX2_TDMA_DMAD_IF_DEBUG                               0x00005c98
+ #define BNX2_TDMA_CTX_IF_DEBUG                                0x00005c9c
+ #define BNX2_TDMA_TPBUF_IF_DEBUG                      0x00005ca0
+ #define BNX2_TDMA_DR_IF_DEBUG                         0x00005ca4
+ #define BNX2_TDMA_TPATQ_IF_DEBUG                      0x00005ca8
+ #define BNX2_TDMA_TDMA_ILOCK_CKSUM                    0x00005cac
+ #define BNX2_TDMA_TDMA_ILOCK_CKSUM_CALCULATED          (0xffffL<<0)
+ #define BNX2_TDMA_TDMA_ILOCK_CKSUM_EXPECTED            (0xffffL<<16)
+ #define BNX2_TDMA_TDMA_PCIE_CKSUM                     0x00005cb0
+ #define BNX2_TDMA_TDMA_PCIE_CKSUM_CALCULATED           (0xffffL<<0)
+ #define BNX2_TDMA_TDMA_PCIE_CKSUM_EXPECTED             (0xffffL<<16)
+ #define BNX2_TDMA_TDMAQ                                       0x00005fc0
+ #define BNX2_TDMA_FTQ_CMD                             0x00005ff8
+ #define BNX2_TDMA_FTQ_CMD_OFFSET                       (0x3ffL<<0)
+ #define BNX2_TDMA_FTQ_CMD_WR_TOP                       (1L<<10)
+ #define BNX2_TDMA_FTQ_CMD_WR_TOP_0                     (0L<<10)
+ #define BNX2_TDMA_FTQ_CMD_WR_TOP_1                     (1L<<10)
+ #define BNX2_TDMA_FTQ_CMD_SFT_RESET                    (1L<<25)
+ #define BNX2_TDMA_FTQ_CMD_RD_DATA                      (1L<<26)
+ #define BNX2_TDMA_FTQ_CMD_ADD_INTERVEN                         (1L<<27)
+ #define BNX2_TDMA_FTQ_CMD_ADD_DATA                     (1L<<28)
+ #define BNX2_TDMA_FTQ_CMD_INTERVENE_CLR                        (1L<<29)
+ #define BNX2_TDMA_FTQ_CMD_POP                          (1L<<30)
+ #define BNX2_TDMA_FTQ_CMD_BUSY                                 (1L<<31)
+ #define BNX2_TDMA_FTQ_CTL                             0x00005ffc
+ #define BNX2_TDMA_FTQ_CTL_INTERVENE                    (1L<<0)
+ #define BNX2_TDMA_FTQ_CTL_OVERFLOW                     (1L<<1)
+ #define BNX2_TDMA_FTQ_CTL_FORCE_INTERVENE              (1L<<2)
+ #define BNX2_TDMA_FTQ_CTL_MAX_DEPTH                    (0x3ffL<<12)
+ #define BNX2_TDMA_FTQ_CTL_CUR_DEPTH                    (0x3ffL<<22)
+ /*
+  *  hc_reg definition
+  *  offset: 0x6800
+  */
+ #define BNX2_HC_COMMAND                                       0x00006800
+ #define BNX2_HC_COMMAND_ENABLE                                 (1L<<0)
+ #define BNX2_HC_COMMAND_SKIP_ABORT                     (1L<<4)
+ #define BNX2_HC_COMMAND_COAL_NOW                       (1L<<16)
+ #define BNX2_HC_COMMAND_COAL_NOW_WO_INT                        (1L<<17)
+ #define BNX2_HC_COMMAND_STATS_NOW                      (1L<<18)
+ #define BNX2_HC_COMMAND_FORCE_INT                      (0x3L<<19)
+ #define BNX2_HC_COMMAND_FORCE_INT_NULL                         (0L<<19)
+ #define BNX2_HC_COMMAND_FORCE_INT_HIGH                         (1L<<19)
+ #define BNX2_HC_COMMAND_FORCE_INT_LOW                  (2L<<19)
+ #define BNX2_HC_COMMAND_FORCE_INT_FREE                         (3L<<19)
+ #define BNX2_HC_COMMAND_CLR_STAT_NOW                   (1L<<21)
+ #define BNX2_HC_COMMAND_MAIN_PWR_INT                   (1L<<22)
+ #define BNX2_HC_COMMAND_COAL_ON_NEXT_EVENT             (1L<<27)
+ #define BNX2_HC_STATUS                                        0x00006804
+ #define BNX2_HC_STATUS_MASTER_ABORT                    (1L<<0)
+ #define BNX2_HC_STATUS_PARITY_ERROR_STATE              (1L<<1)
+ #define BNX2_HC_STATUS_PCI_CLK_CNT_STAT                        (1L<<16)
+ #define BNX2_HC_STATUS_CORE_CLK_CNT_STAT               (1L<<17)
+ #define BNX2_HC_STATUS_NUM_STATUS_BLOCKS_STAT          (1L<<18)
+ #define BNX2_HC_STATUS_NUM_INT_GEN_STAT                        (1L<<19)
+ #define BNX2_HC_STATUS_NUM_INT_MBOX_WR_STAT            (1L<<20)
+ #define BNX2_HC_STATUS_CORE_CLKS_TO_HW_INTACK_STAT     (1L<<23)
+ #define BNX2_HC_STATUS_CORE_CLKS_TO_SW_INTACK_STAT     (1L<<24)
+ #define BNX2_HC_STATUS_CORE_CLKS_DURING_SW_INTACK_STAT         (1L<<25)
+ #define BNX2_HC_CONFIG                                        0x00006808
+ #define BNX2_HC_CONFIG_COLLECT_STATS                   (1L<<0)
+ #define BNX2_HC_CONFIG_RX_TMR_MODE                     (1L<<1)
+ #define BNX2_HC_CONFIG_TX_TMR_MODE                     (1L<<2)
+ #define BNX2_HC_CONFIG_COM_TMR_MODE                    (1L<<3)
+ #define BNX2_HC_CONFIG_CMD_TMR_MODE                    (1L<<4)
+ #define BNX2_HC_CONFIG_STATISTIC_PRIORITY              (1L<<5)
+ #define BNX2_HC_CONFIG_STATUS_PRIORITY                         (1L<<6)
+ #define BNX2_HC_CONFIG_STAT_MEM_ADDR                   (0xffL<<8)
+ #define BNX2_HC_CONFIG_PER_MODE                                (1L<<16)
+ #define BNX2_HC_CONFIG_ONE_SHOT                                (1L<<17)
+ #define BNX2_HC_CONFIG_USE_INT_PARAM                   (1L<<18)
+ #define BNX2_HC_CONFIG_SET_MASK_AT_RD                  (1L<<19)
+ #define BNX2_HC_CONFIG_PER_COLLECT_LIMIT               (0xfL<<20)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC                     (0x7L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_64B                         (0L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_128B                        (1L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_256B                        (2L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_512B                        (3L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_1024B               (4L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_2048B               (5L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_4096B               (6L<<24)
+ #define BNX2_HC_CONFIG_SB_ADDR_INC_8192B               (7L<<24)
+ #define BNX2_HC_CONFIG_GEN_STAT_AVG_INTR               (1L<<29)
+ #define BNX2_HC_CONFIG_UNMASK_ALL                      (1L<<30)
+ #define BNX2_HC_CONFIG_TX_SEL                          (1L<<31)
+ #define BNX2_HC_ATTN_BITS_ENABLE                      0x0000680c
+ #define BNX2_HC_STATUS_ADDR_L                         0x00006810
+ #define BNX2_HC_STATUS_ADDR_H                         0x00006814
+ #define BNX2_HC_STATISTICS_ADDR_L                     0x00006818
+ #define BNX2_HC_STATISTICS_ADDR_H                     0x0000681c
+ #define BNX2_HC_TX_QUICK_CONS_TRIP                    0x00006820
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_VALUE               (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_INT                         (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP                                0x00006824
+ #define BNX2_HC_COMP_PROD_TRIP_VALUE                   (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_INT                     (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP                    0x00006828
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_VALUE               (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_INT                         (0xffL<<16)
+ #define BNX2_HC_RX_TICKS                              0x0000682c
+ #define BNX2_HC_RX_TICKS_VALUE                                 (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_INT                           (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS                              0x00006830
+ #define BNX2_HC_TX_TICKS_VALUE                                 (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_INT                           (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS                             0x00006834
+ #define BNX2_HC_COM_TICKS_VALUE                                (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_INT                          (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS                             0x00006838
+ #define BNX2_HC_CMD_TICKS_VALUE                                (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_INT                          (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS                                0x0000683c
+ #define BNX2_HC_PERIODIC_TICKS_HC_PERIODIC_TICKS       (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_HC_INT_PERIODIC_TICKS   (0xffffL<<16)
+ #define BNX2_HC_STAT_COLLECT_TICKS                    0x00006840
+ #define BNX2_HC_STAT_COLLECT_TICKS_HC_STAT_COLL_TICKS  (0xffL<<4)
+ #define BNX2_HC_STATS_TICKS                           0x00006844
+ #define BNX2_HC_STATS_TICKS_HC_STAT_TICKS              (0xffffL<<8)
+ #define BNX2_HC_STATS_INTERRUPT_STATUS                        0x00006848
+ #define BNX2_HC_STATS_INTERRUPT_STATUS_SB_STATUS       (0x1ffL<<0)
+ #define BNX2_HC_STATS_INTERRUPT_STATUS_INT_STATUS      (0x1ffL<<16)
+ #define BNX2_HC_STAT_MEM_DATA                         0x0000684c
+ #define BNX2_HC_STAT_GEN_SEL_0                                0x00006850
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0               (0x7fL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT0     (0L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT1     (1L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT2     (2L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT3     (3L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT4     (4L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT5     (5L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT6     (6L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT7     (7L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT8     (8L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT9     (9L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT10    (10L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT11    (11L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT0     (12L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT1     (13L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT2     (14L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT3     (15L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT4     (16L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT5     (17L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT6     (18L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT7     (19L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT0     (20L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT1     (21L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT2     (22L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT3     (23L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT4     (24L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT5     (25L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT6     (26L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT7     (27L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT8     (28L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT9     (29L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT10    (30L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT11    (31L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT0    (32L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT1    (33L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT2    (34L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT3    (35L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT0      (36L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT1      (37L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT2      (38L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT3      (39L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT4      (40L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT5      (41L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT6      (42L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT7      (43L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT0     (44L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT1     (45L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT2     (46L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT3     (47L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT4     (48L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT5     (49L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT6     (50L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT7     (51L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_PCI_CLK_CNT   (52L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CORE_CLK_CNT  (53L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS  (54L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN        (55L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR    (56L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK     (59L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK     (60L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK         (61L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_CMD_CNT  (62L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_SLOT_CNT         (63L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_CMD_CNT  (64L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_SLOT_CNT         (65L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT       (66L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT        (67L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT       (68L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT      (69L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT      (70L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT      (71L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT       (72L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT       (73L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT       (74L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT        (75L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT       (76L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT       (77L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT        (78L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT         (79L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT         (80L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT       (81L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT       (82L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT        (83L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT        (84L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_TRANSFERS_CNT       (85L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_DELAY_PCI_CLKS_CNT  (86L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_TRANSFERS_CNT   (87L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_DELAY_PCI_CLKS_CNT      (88L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_RETRY_AFTER_DATA_CNT    (89L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_TRANSFERS_CNT      (90L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_DELAY_PCI_CLKS_CNT         (91L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_TRANSFERS_CNT  (92L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_DELAY_PCI_CLKS_CNT     (93L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_RETRY_AFTER_DATA_CNT   (94L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_WR_CNT64  (95L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_RD_CNT64  (96L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_ACC_STALL_CLKS    (97L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_LOCK_STALL_CLKS   (98L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS_STAT   (99L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS64_STAT         (100L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_PCI_STALL_STAT    (101L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_FTQ_ENTRY_CNT    (102L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_BURST_CNT        (103L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_FTQ_ENTRY_CNT    (104L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_BURST_CNT        (105L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_FTQ_ENTRY_CNT    (106L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_BURST_CNT        (107L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUP_MATCH_CNT        (108L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_POLL_PASS_CNT     (109L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR1_CNT  (110L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR2_CNT  (111L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR3_CNT  (112L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR4_CNT  (113L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR5_CNT  (114L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT0    (115L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT1    (116L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT2    (117L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT3    (118L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT4    (119L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT5    (120L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC1_MISS       (121L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC2_MISS       (122L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_BURST_CNT        (127L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_1               (0x7fL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_2               (0x7fL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_3               (0x7fL<<24)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_XI            (0xffL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UMP_RX_FRAME_DROP_XI  (52L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S0_XI  (57L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S1_XI  (58L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S2_XI  (85L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S3_XI  (86L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S4_XI  (87L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S5_XI  (88L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S6_XI  (89L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S7_XI  (90L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S8_XI  (91L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S9_XI  (92L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_UNUSED_S10_XI         (93L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MQ_IDB_OFLOW_XI       (94L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_BLK_RD_CNT_XI     (123L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_BLK_WR_CNT_XI     (124L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_HITS_XI   (125L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_MISSES_XI         (126L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC1_XI  (128L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC1_XI        (129L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC1_XI    (130L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC1_XI     (131L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC1_XI     (132L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC1_XI         (133L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC2_XI  (134L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC2_XI        (135L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC2_XI    (136L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC2_XI     (137L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC2_XI     (138L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC2_XI         (139L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC3_XI  (140L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC3_XI        (141L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC3_XI    (142L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC3_XI     (143L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC3_XI     (144L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC3_XI         (145L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC4_XI  (146L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC4_XI        (147L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC4_XI    (148L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC4_XI     (149L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC4_XI     (150L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC4_XI         (151L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC5_XI  (152L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC5_XI        (153L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC5_XI    (154L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC5_XI     (155L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC5_XI     (156L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC5_XI         (157L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC6_XI  (158L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC6_XI        (159L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC6_XI    (160L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC6_XI     (161L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC6_XI     (162L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC6_XI         (163L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC7_XI  (164L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC7_XI        (165L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC7_XI    (166L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC7_XI     (167L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC7_XI     (168L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC7_XI         (169L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS_VEC8_XI  (170L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN_VEC8_XI        (171L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR_VEC8_XI    (172L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK_VEC8_XI     (173L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK_VEC8_XI     (174L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK_VEC8_XI         (175L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCS_CMD_CNT_XI     (176L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCS_SLOT_CNT_XI    (177L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI  (178L<<0)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_1_XI            (0xffL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_2_XI            (0xffL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_3_XI            (0xffL<<24)
+ #define BNX2_HC_STAT_GEN_SEL_1                                0x00006854
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_4               (0x7fL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_5               (0x7fL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_6               (0x7fL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_7               (0x7fL<<24)
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_4_XI            (0xffL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_5_XI            (0xffL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_6_XI            (0xffL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_7_XI            (0xffL<<24)
+ #define BNX2_HC_STAT_GEN_SEL_2                                0x00006858
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_8               (0x7fL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_9               (0x7fL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_10              (0x7fL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_11              (0x7fL<<24)
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_8_XI            (0xffL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_9_XI            (0xffL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_10_XI           (0xffL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_11_XI           (0xffL<<24)
+ #define BNX2_HC_STAT_GEN_SEL_3                                0x0000685c
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_12              (0x7fL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_13              (0x7fL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_14              (0x7fL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_15              (0x7fL<<24)
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_12_XI           (0xffL<<0)
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_13_XI           (0xffL<<8)
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_14_XI           (0xffL<<16)
+ #define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_15_XI           (0xffL<<24)
+ #define BNX2_HC_STAT_GEN_STAT0                                0x00006888
+ #define BNX2_HC_STAT_GEN_STAT1                                0x0000688c
+ #define BNX2_HC_STAT_GEN_STAT2                                0x00006890
+ #define BNX2_HC_STAT_GEN_STAT3                                0x00006894
+ #define BNX2_HC_STAT_GEN_STAT4                                0x00006898
+ #define BNX2_HC_STAT_GEN_STAT5                                0x0000689c
+ #define BNX2_HC_STAT_GEN_STAT6                                0x000068a0
+ #define BNX2_HC_STAT_GEN_STAT7                                0x000068a4
+ #define BNX2_HC_STAT_GEN_STAT8                                0x000068a8
+ #define BNX2_HC_STAT_GEN_STAT9                                0x000068ac
+ #define BNX2_HC_STAT_GEN_STAT10                               0x000068b0
+ #define BNX2_HC_STAT_GEN_STAT11                               0x000068b4
+ #define BNX2_HC_STAT_GEN_STAT12                               0x000068b8
+ #define BNX2_HC_STAT_GEN_STAT13                               0x000068bc
+ #define BNX2_HC_STAT_GEN_STAT14                               0x000068c0
+ #define BNX2_HC_STAT_GEN_STAT15                               0x000068c4
+ #define BNX2_HC_STAT_GEN_STAT_AC0                     0x000068c8
+ #define BNX2_HC_STAT_GEN_STAT_AC1                     0x000068cc
+ #define BNX2_HC_STAT_GEN_STAT_AC2                     0x000068d0
+ #define BNX2_HC_STAT_GEN_STAT_AC3                     0x000068d4
+ #define BNX2_HC_STAT_GEN_STAT_AC4                     0x000068d8
+ #define BNX2_HC_STAT_GEN_STAT_AC5                     0x000068dc
+ #define BNX2_HC_STAT_GEN_STAT_AC6                     0x000068e0
+ #define BNX2_HC_STAT_GEN_STAT_AC7                     0x000068e4
+ #define BNX2_HC_STAT_GEN_STAT_AC8                     0x000068e8
+ #define BNX2_HC_STAT_GEN_STAT_AC9                     0x000068ec
+ #define BNX2_HC_STAT_GEN_STAT_AC10                    0x000068f0
+ #define BNX2_HC_STAT_GEN_STAT_AC11                    0x000068f4
+ #define BNX2_HC_STAT_GEN_STAT_AC12                    0x000068f8
+ #define BNX2_HC_STAT_GEN_STAT_AC13                    0x000068fc
+ #define BNX2_HC_STAT_GEN_STAT_AC14                    0x00006900
+ #define BNX2_HC_STAT_GEN_STAT_AC15                    0x00006904
+ #define BNX2_HC_STAT_GEN_STAT_AC                      0x000068c8
+ #define BNX2_HC_VIS                                   0x00006908
+ #define BNX2_HC_VIS_STAT_BUILD_STATE                   (0xfL<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_IDLE              (0L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_START             (1L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_REQUEST           (2L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE64          (3L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE32          (4L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE_DONE       (5L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_DMA               (6L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_CONTROL       (7L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_LOW           (8L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_HIGH          (9L<<0)
+ #define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_DATA          (10L<<0)
+ #define BNX2_HC_VIS_DMA_STAT_STATE                     (0xfL<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_IDLE                        (0L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_PARAM                (1L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_DMA          (2L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP          (3L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_COMP                        (4L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_PARAM     (5L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_DMA       (6L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_1                (7L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_2                (8L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_WAIT                        (9L<<8)
+ #define BNX2_HC_VIS_DMA_STAT_STATE_ABORT               (15L<<8)
+ #define BNX2_HC_VIS_DMA_MSI_STATE                      (0x7L<<12)
+ #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE             (0x3L<<15)
+ #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_IDLE                (0L<<15)
+ #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_COUNT       (1L<<15)
+ #define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_START       (2L<<15)
+ #define BNX2_HC_VIS_1                                 0x0000690c
+ #define BNX2_HC_VIS_1_HW_INTACK_STATE                  (1L<<4)
+ #define BNX2_HC_VIS_1_HW_INTACK_STATE_IDLE             (0L<<4)
+ #define BNX2_HC_VIS_1_HW_INTACK_STATE_COUNT            (1L<<4)
+ #define BNX2_HC_VIS_1_SW_INTACK_STATE                  (1L<<5)
+ #define BNX2_HC_VIS_1_SW_INTACK_STATE_IDLE             (0L<<5)
+ #define BNX2_HC_VIS_1_SW_INTACK_STATE_COUNT            (1L<<5)
+ #define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE           (1L<<6)
+ #define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_IDLE      (0L<<6)
+ #define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_COUNT     (1L<<6)
+ #define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE              (1L<<7)
+ #define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_IDLE                 (0L<<7)
+ #define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_COUNT                (1L<<7)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE                         (0xfL<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_IDLE            (0L<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_DMA             (1L<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_UPDATE          (2L<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_ASSIGN          (3L<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_WAIT            (4L<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_UPDATE      (5L<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_ASSIGN      (6L<<17)
+ #define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_WAIT                (7L<<17)
+ #define BNX2_HC_VIS_1_RAM_WR_ARB_STATE                         (0x3L<<21)
+ #define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_NORMAL          (0L<<21)
+ #define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_CLEAR           (1L<<21)
+ #define BNX2_HC_VIS_1_INT_GEN_STATE                    (1L<<23)
+ #define BNX2_HC_VIS_1_INT_GEN_STATE_DLE                        (0L<<23)
+ #define BNX2_HC_VIS_1_INT_GEN_STATE_NTERRUPT           (1L<<23)
+ #define BNX2_HC_VIS_1_STAT_CHAN_ID                     (0x7L<<24)
+ #define BNX2_HC_VIS_1_INT_B                            (1L<<27)
+ #define BNX2_HC_DEBUG_VECT_PEEK                               0x00006910
+ #define BNX2_HC_DEBUG_VECT_PEEK_1_VALUE                        (0x7ffL<<0)
+ #define BNX2_HC_DEBUG_VECT_PEEK_1_PEEK_EN              (1L<<11)
+ #define BNX2_HC_DEBUG_VECT_PEEK_1_SEL                  (0xfL<<12)
+ #define BNX2_HC_DEBUG_VECT_PEEK_2_VALUE                        (0x7ffL<<16)
+ #define BNX2_HC_DEBUG_VECT_PEEK_2_PEEK_EN              (1L<<27)
+ #define BNX2_HC_DEBUG_VECT_PEEK_2_SEL                  (0xfL<<28)
+ #define BNX2_HC_COALESCE_NOW                          0x00006914
+ #define BNX2_HC_COALESCE_NOW_COAL_NOW                  (0x1ffL<<1)
+ #define BNX2_HC_COALESCE_NOW_COAL_NOW_WO_INT           (0x1ffL<<11)
+ #define BNX2_HC_COALESCE_NOW_COAL_ON_NXT_EVENT                 (0x1ffL<<21)
+ #define BNX2_HC_MSIX_BIT_VECTOR                               0x00006918
+ #define BNX2_HC_MSIX_BIT_VECTOR_VAL                    (0x1ffL<<0)
+ #define BNX2_HC_SB_CONFIG_1                           0x00006a00
+ #define BNX2_HC_SB_CONFIG_1_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_1_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_1_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_1_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_1_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_1_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_1_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_1_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_1                  0x00006a04
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_1_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_1_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_1                      0x00006a08
+ #define BNX2_HC_COMP_PROD_TRIP_1_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_1_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_1                  0x00006a0c
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_1_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_1_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_1                            0x00006a10
+ #define BNX2_HC_RX_TICKS_1_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_1_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_1                            0x00006a14
+ #define BNX2_HC_TX_TICKS_1_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_1_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_1                           0x00006a18
+ #define BNX2_HC_COM_TICKS_1_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_1_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_1                           0x00006a1c
+ #define BNX2_HC_CMD_TICKS_1_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_1_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_1                      0x00006a20
+ #define BNX2_HC_PERIODIC_TICKS_1_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_1_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_2                           0x00006a24
+ #define BNX2_HC_SB_CONFIG_2_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_2_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_2_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_2_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_2_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_2_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_2_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_2_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_2                  0x00006a28
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_2_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_2_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_2                      0x00006a2c
+ #define BNX2_HC_COMP_PROD_TRIP_2_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_2_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_2                  0x00006a30
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_2_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_2_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_2                            0x00006a34
+ #define BNX2_HC_RX_TICKS_2_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_2_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_2                            0x00006a38
+ #define BNX2_HC_TX_TICKS_2_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_2_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_2                           0x00006a3c
+ #define BNX2_HC_COM_TICKS_2_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_2_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_2                           0x00006a40
+ #define BNX2_HC_CMD_TICKS_2_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_2_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_2                      0x00006a44
+ #define BNX2_HC_PERIODIC_TICKS_2_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_2_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_3                           0x00006a48
+ #define BNX2_HC_SB_CONFIG_3_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_3_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_3_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_3_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_3_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_3_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_3_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_3_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_3                  0x00006a4c
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_3_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_3_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_3                      0x00006a50
+ #define BNX2_HC_COMP_PROD_TRIP_3_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_3_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_3                  0x00006a54
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_3_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_3_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_3                            0x00006a58
+ #define BNX2_HC_RX_TICKS_3_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_3_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_3                            0x00006a5c
+ #define BNX2_HC_TX_TICKS_3_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_3_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_3                           0x00006a60
+ #define BNX2_HC_COM_TICKS_3_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_3_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_3                           0x00006a64
+ #define BNX2_HC_CMD_TICKS_3_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_3_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_3                      0x00006a68
+ #define BNX2_HC_PERIODIC_TICKS_3_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_3_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_4                           0x00006a6c
+ #define BNX2_HC_SB_CONFIG_4_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_4_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_4_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_4_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_4_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_4_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_4_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_4_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_4                  0x00006a70
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_4_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_4_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_4                      0x00006a74
+ #define BNX2_HC_COMP_PROD_TRIP_4_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_4_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_4                  0x00006a78
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_4_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_4_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_4                            0x00006a7c
+ #define BNX2_HC_RX_TICKS_4_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_4_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_4                            0x00006a80
+ #define BNX2_HC_TX_TICKS_4_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_4_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_4                           0x00006a84
+ #define BNX2_HC_COM_TICKS_4_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_4_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_4                           0x00006a88
+ #define BNX2_HC_CMD_TICKS_4_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_4_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_4                      0x00006a8c
+ #define BNX2_HC_PERIODIC_TICKS_4_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_4_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_5                           0x00006a90
+ #define BNX2_HC_SB_CONFIG_5_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_5_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_5_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_5_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_5_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_5_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_5_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_5_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_5                  0x00006a94
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_5_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_5_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_5                      0x00006a98
+ #define BNX2_HC_COMP_PROD_TRIP_5_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_5_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_5                  0x00006a9c
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_5_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_5_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_5                            0x00006aa0
+ #define BNX2_HC_RX_TICKS_5_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_5_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_5                            0x00006aa4
+ #define BNX2_HC_TX_TICKS_5_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_5_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_5                           0x00006aa8
+ #define BNX2_HC_COM_TICKS_5_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_5_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_5                           0x00006aac
+ #define BNX2_HC_CMD_TICKS_5_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_5_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_5                      0x00006ab0
+ #define BNX2_HC_PERIODIC_TICKS_5_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_5_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_6                           0x00006ab4
+ #define BNX2_HC_SB_CONFIG_6_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_6_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_6_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_6_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_6_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_6_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_6_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_6_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_6                  0x00006ab8
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_6_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_6_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_6                      0x00006abc
+ #define BNX2_HC_COMP_PROD_TRIP_6_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_6_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_6                  0x00006ac0
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_6_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_6_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_6                            0x00006ac4
+ #define BNX2_HC_RX_TICKS_6_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_6_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_6                            0x00006ac8
+ #define BNX2_HC_TX_TICKS_6_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_6_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_6                           0x00006acc
+ #define BNX2_HC_COM_TICKS_6_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_6_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_6                           0x00006ad0
+ #define BNX2_HC_CMD_TICKS_6_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_6_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_6                      0x00006ad4
+ #define BNX2_HC_PERIODIC_TICKS_6_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_6_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_7                           0x00006ad8
+ #define BNX2_HC_SB_CONFIG_7_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_7_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_7_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_7_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_7_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_7_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_7_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_7_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_7                  0x00006adc
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_7_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_7_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_7                      0x00006ae0
+ #define BNX2_HC_COMP_PROD_TRIP_7_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_7_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_7                  0x00006ae4
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_7_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_7_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_7                            0x00006ae8
+ #define BNX2_HC_RX_TICKS_7_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_7_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_7                            0x00006aec
+ #define BNX2_HC_TX_TICKS_7_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_7_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_7                           0x00006af0
+ #define BNX2_HC_COM_TICKS_7_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_7_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_7                           0x00006af4
+ #define BNX2_HC_CMD_TICKS_7_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_7_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_7                      0x00006af8
+ #define BNX2_HC_PERIODIC_TICKS_7_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_7_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_8                           0x00006afc
+ #define BNX2_HC_SB_CONFIG_8_RX_TMR_MODE                        (1L<<1)
+ #define BNX2_HC_SB_CONFIG_8_TX_TMR_MODE                        (1L<<2)
+ #define BNX2_HC_SB_CONFIG_8_COM_TMR_MODE               (1L<<3)
+ #define BNX2_HC_SB_CONFIG_8_CMD_TMR_MODE               (1L<<4)
+ #define BNX2_HC_SB_CONFIG_8_PER_MODE                   (1L<<16)
+ #define BNX2_HC_SB_CONFIG_8_ONE_SHOT                   (1L<<17)
+ #define BNX2_HC_SB_CONFIG_8_USE_INT_PARAM              (1L<<18)
+ #define BNX2_HC_SB_CONFIG_8_PER_COLLECT_LIMIT          (0xfL<<20)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_8                  0x00006b00
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_8_VALUE             (0xffL<<0)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_8_INT               (0xffL<<16)
+ #define BNX2_HC_COMP_PROD_TRIP_8                      0x00006b04
+ #define BNX2_HC_COMP_PROD_TRIP_8_VALUE                         (0xffL<<0)
+ #define BNX2_HC_COMP_PROD_TRIP_8_INT                   (0xffL<<16)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_8                  0x00006b08
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_8_VALUE             (0xffL<<0)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_8_INT               (0xffL<<16)
+ #define BNX2_HC_RX_TICKS_8                            0x00006b0c
+ #define BNX2_HC_RX_TICKS_8_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_RX_TICKS_8_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_TX_TICKS_8                            0x00006b10
+ #define BNX2_HC_TX_TICKS_8_VALUE                       (0x3ffL<<0)
+ #define BNX2_HC_TX_TICKS_8_INT                                 (0x3ffL<<16)
+ #define BNX2_HC_COM_TICKS_8                           0x00006b14
+ #define BNX2_HC_COM_TICKS_8_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_COM_TICKS_8_INT                                (0x3ffL<<16)
+ #define BNX2_HC_CMD_TICKS_8                           0x00006b18
+ #define BNX2_HC_CMD_TICKS_8_VALUE                      (0x3ffL<<0)
+ #define BNX2_HC_CMD_TICKS_8_INT                                (0x3ffL<<16)
+ #define BNX2_HC_PERIODIC_TICKS_8                      0x00006b1c
+ #define BNX2_HC_PERIODIC_TICKS_8_HC_PERIODIC_TICKS     (0xffffL<<0)
+ #define BNX2_HC_PERIODIC_TICKS_8_HC_INT_PERIODIC_TICKS         (0xffffL<<16)
+ #define BNX2_HC_SB_CONFIG_SIZE        (BNX2_HC_SB_CONFIG_2 - BNX2_HC_SB_CONFIG_1)
+ #define BNX2_HC_COMP_PROD_TRIP_OFF    (BNX2_HC_COMP_PROD_TRIP_1 -     \
+                                        BNX2_HC_SB_CONFIG_1)
+ #define BNX2_HC_COM_TICKS_OFF (BNX2_HC_COM_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+ #define BNX2_HC_CMD_TICKS_OFF (BNX2_HC_CMD_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+ #define BNX2_HC_TX_QUICK_CONS_TRIP_OFF        (BNX2_HC_TX_QUICK_CONS_TRIP_1 - \
+                                        BNX2_HC_SB_CONFIG_1)
+ #define BNX2_HC_TX_TICKS_OFF  (BNX2_HC_TX_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+ #define BNX2_HC_RX_QUICK_CONS_TRIP_OFF        (BNX2_HC_RX_QUICK_CONS_TRIP_1 - \
+                                        BNX2_HC_SB_CONFIG_1)
+ #define BNX2_HC_RX_TICKS_OFF  (BNX2_HC_RX_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+ /*
+  *  txp_reg definition
+  *  offset: 0x40000
+  */
+ #define BNX2_TXP_CPU_MODE                             0x00045000
+ #define BNX2_TXP_CPU_MODE_LOCAL_RST                    (1L<<0)
+ #define BNX2_TXP_CPU_MODE_STEP_ENA                     (1L<<1)
+ #define BNX2_TXP_CPU_MODE_PAGE_0_DATA_ENA              (1L<<2)
+ #define BNX2_TXP_CPU_MODE_PAGE_0_INST_ENA              (1L<<3)
+ #define BNX2_TXP_CPU_MODE_MSG_BIT1                     (1L<<6)
+ #define BNX2_TXP_CPU_MODE_INTERRUPT_ENA                        (1L<<7)
+ #define BNX2_TXP_CPU_MODE_SOFT_HALT                    (1L<<10)
+ #define BNX2_TXP_CPU_MODE_BAD_DATA_HALT_ENA            (1L<<11)
+ #define BNX2_TXP_CPU_MODE_BAD_INST_HALT_ENA            (1L<<12)
+ #define BNX2_TXP_CPU_MODE_FIO_ABORT_HALT_ENA           (1L<<13)
+ #define BNX2_TXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA      (1L<<15)
+ #define BNX2_TXP_CPU_STATE                            0x00045004
+ #define BNX2_TXP_CPU_STATE_BREAKPOINT                  (1L<<0)
+ #define BNX2_TXP_CPU_STATE_BAD_INST_HALTED             (1L<<2)
+ #define BNX2_TXP_CPU_STATE_PAGE_0_DATA_HALTED          (1L<<3)
+ #define BNX2_TXP_CPU_STATE_PAGE_0_INST_HALTED          (1L<<4)
+ #define BNX2_TXP_CPU_STATE_BAD_DATA_ADDR_HALTED                (1L<<5)
+ #define BNX2_TXP_CPU_STATE_BAD_PC_HALTED               (1L<<6)
+ #define BNX2_TXP_CPU_STATE_ALIGN_HALTED                        (1L<<7)
+ #define BNX2_TXP_CPU_STATE_FIO_ABORT_HALTED            (1L<<8)
+ #define BNX2_TXP_CPU_STATE_SOFT_HALTED                         (1L<<10)
+ #define BNX2_TXP_CPU_STATE_SPAD_UNDERFLOW              (1L<<11)
 -#define BNX2_TXP_CPU_STATE_INTERRRUPT                  (1L<<12)
++#define BNX2_TXP_CPU_STATE_INTERRUPT                   (1L<<12)
+ #define BNX2_TXP_CPU_STATE_DATA_ACCESS_STALL           (1L<<14)
+ #define BNX2_TXP_CPU_STATE_INST_FETCH_STALL            (1L<<15)
+ #define BNX2_TXP_CPU_STATE_BLOCKED_READ                        (1L<<31)
+ #define BNX2_TXP_CPU_EVENT_MASK                               0x00045008
+ #define BNX2_TXP_CPU_EVENT_MASK_BREAKPOINT_MASK                (1L<<0)
+ #define BNX2_TXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK   (1L<<2)
+ #define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK        (1L<<3)
+ #define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK        (1L<<4)
+ #define BNX2_TXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK      (1L<<5)
+ #define BNX2_TXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK     (1L<<6)
+ #define BNX2_TXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK      (1L<<7)
+ #define BNX2_TXP_CPU_EVENT_MASK_FIO_ABORT_MASK                 (1L<<8)
+ #define BNX2_TXP_CPU_EVENT_MASK_SOFT_HALTED_MASK       (1L<<10)
+ #define BNX2_TXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK    (1L<<11)
+ #define BNX2_TXP_CPU_EVENT_MASK_INTERRUPT_MASK                 (1L<<12)
+ #define BNX2_TXP_CPU_PROGRAM_COUNTER                  0x0004501c
+ #define BNX2_TXP_CPU_INSTRUCTION                      0x00045020
+ #define BNX2_TXP_CPU_DATA_ACCESS                      0x00045024
+ #define BNX2_TXP_CPU_INTERRUPT_ENABLE                 0x00045028
+ #define BNX2_TXP_CPU_INTERRUPT_VECTOR                 0x0004502c
+ #define BNX2_TXP_CPU_INTERRUPT_SAVED_PC                       0x00045030
+ #define BNX2_TXP_CPU_HW_BREAKPOINT                    0x00045034
+ #define BNX2_TXP_CPU_HW_BREAKPOINT_DISABLE             (1L<<0)
+ #define BNX2_TXP_CPU_HW_BREAKPOINT_ADDRESS             (0x3fffffffL<<2)
+ #define BNX2_TXP_CPU_DEBUG_VECT_PEEK                  0x00045038
+ #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_VALUE           (0x7ffL<<0)
+ #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN                 (1L<<11)
+ #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_SEL             (0xfL<<12)
+ #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_VALUE           (0x7ffL<<16)
+ #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN                 (1L<<27)
+ #define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_SEL             (0xfL<<28)
+ #define BNX2_TXP_CPU_LAST_BRANCH_ADDR                 0x00045048
+ #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE             (1L<<1)
+ #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                (0L<<1)
+ #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH      (1L<<1)
+ #define BNX2_TXP_CPU_LAST_BRANCH_ADDR_LBA              (0x3fffffffL<<2)
+ #define BNX2_TXP_CPU_REG_FILE                         0x00045200
+ #define BNX2_TXP_TXPQ                                 0x000453c0
+ #define BNX2_TXP_FTQ_CMD                              0x000453f8
+ #define BNX2_TXP_FTQ_CMD_OFFSET                                (0x3ffL<<0)
+ #define BNX2_TXP_FTQ_CMD_WR_TOP                                (1L<<10)
+ #define BNX2_TXP_FTQ_CMD_WR_TOP_0                      (0L<<10)
+ #define BNX2_TXP_FTQ_CMD_WR_TOP_1                      (1L<<10)
+ #define BNX2_TXP_FTQ_CMD_SFT_RESET                     (1L<<25)
+ #define BNX2_TXP_FTQ_CMD_RD_DATA                       (1L<<26)
+ #define BNX2_TXP_FTQ_CMD_ADD_INTERVEN                  (1L<<27)
+ #define BNX2_TXP_FTQ_CMD_ADD_DATA                      (1L<<28)
+ #define BNX2_TXP_FTQ_CMD_INTERVENE_CLR                         (1L<<29)
+ #define BNX2_TXP_FTQ_CMD_POP                           (1L<<30)
+ #define BNX2_TXP_FTQ_CMD_BUSY                          (1L<<31)
+ #define BNX2_TXP_FTQ_CTL                              0x000453fc
+ #define BNX2_TXP_FTQ_CTL_INTERVENE                     (1L<<0)
+ #define BNX2_TXP_FTQ_CTL_OVERFLOW                      (1L<<1)
+ #define BNX2_TXP_FTQ_CTL_FORCE_INTERVENE               (1L<<2)
+ #define BNX2_TXP_FTQ_CTL_MAX_DEPTH                     (0x3ffL<<12)
+ #define BNX2_TXP_FTQ_CTL_CUR_DEPTH                     (0x3ffL<<22)
+ #define BNX2_TXP_SCRATCH                              0x00060000
+ /*
+  *  tpat_reg definition
+  *  offset: 0x80000
+  */
+ #define BNX2_TPAT_CPU_MODE                            0x00085000
+ #define BNX2_TPAT_CPU_MODE_LOCAL_RST                   (1L<<0)
+ #define BNX2_TPAT_CPU_MODE_STEP_ENA                    (1L<<1)
+ #define BNX2_TPAT_CPU_MODE_PAGE_0_DATA_ENA             (1L<<2)
+ #define BNX2_TPAT_CPU_MODE_PAGE_0_INST_ENA             (1L<<3)
+ #define BNX2_TPAT_CPU_MODE_MSG_BIT1                    (1L<<6)
+ #define BNX2_TPAT_CPU_MODE_INTERRUPT_ENA               (1L<<7)
+ #define BNX2_TPAT_CPU_MODE_SOFT_HALT                   (1L<<10)
+ #define BNX2_TPAT_CPU_MODE_BAD_DATA_HALT_ENA           (1L<<11)
+ #define BNX2_TPAT_CPU_MODE_BAD_INST_HALT_ENA           (1L<<12)
+ #define BNX2_TPAT_CPU_MODE_FIO_ABORT_HALT_ENA          (1L<<13)
+ #define BNX2_TPAT_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA     (1L<<15)
+ #define BNX2_TPAT_CPU_STATE                           0x00085004
+ #define BNX2_TPAT_CPU_STATE_BREAKPOINT                         (1L<<0)
+ #define BNX2_TPAT_CPU_STATE_BAD_INST_HALTED            (1L<<2)
+ #define BNX2_TPAT_CPU_STATE_PAGE_0_DATA_HALTED                 (1L<<3)
+ #define BNX2_TPAT_CPU_STATE_PAGE_0_INST_HALTED                 (1L<<4)
+ #define BNX2_TPAT_CPU_STATE_BAD_DATA_ADDR_HALTED       (1L<<5)
+ #define BNX2_TPAT_CPU_STATE_BAD_PC_HALTED              (1L<<6)
+ #define BNX2_TPAT_CPU_STATE_ALIGN_HALTED               (1L<<7)
+ #define BNX2_TPAT_CPU_STATE_FIO_ABORT_HALTED           (1L<<8)
+ #define BNX2_TPAT_CPU_STATE_SOFT_HALTED                        (1L<<10)
+ #define BNX2_TPAT_CPU_STATE_SPAD_UNDERFLOW             (1L<<11)
 -#define BNX2_TPAT_CPU_STATE_INTERRRUPT                         (1L<<12)
++#define BNX2_TPAT_CPU_STATE_INTERRUPT                  (1L<<12)
+ #define BNX2_TPAT_CPU_STATE_DATA_ACCESS_STALL          (1L<<14)
+ #define BNX2_TPAT_CPU_STATE_INST_FETCH_STALL           (1L<<15)
+ #define BNX2_TPAT_CPU_STATE_BLOCKED_READ               (1L<<31)
+ #define BNX2_TPAT_CPU_EVENT_MASK                      0x00085008
+ #define BNX2_TPAT_CPU_EVENT_MASK_BREAKPOINT_MASK       (1L<<0)
+ #define BNX2_TPAT_CPU_EVENT_MASK_BAD_INST_HALTED_MASK  (1L<<2)
+ #define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK       (1L<<3)
+ #define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK       (1L<<4)
+ #define BNX2_TPAT_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK     (1L<<5)
+ #define BNX2_TPAT_CPU_EVENT_MASK_BAD_PC_HALTED_MASK    (1L<<6)
+ #define BNX2_TPAT_CPU_EVENT_MASK_ALIGN_HALTED_MASK     (1L<<7)
+ #define BNX2_TPAT_CPU_EVENT_MASK_FIO_ABORT_MASK                (1L<<8)
+ #define BNX2_TPAT_CPU_EVENT_MASK_SOFT_HALTED_MASK      (1L<<10)
+ #define BNX2_TPAT_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK   (1L<<11)
+ #define BNX2_TPAT_CPU_EVENT_MASK_INTERRUPT_MASK                (1L<<12)
+ #define BNX2_TPAT_CPU_PROGRAM_COUNTER                 0x0008501c
+ #define BNX2_TPAT_CPU_INSTRUCTION                     0x00085020
+ #define BNX2_TPAT_CPU_DATA_ACCESS                     0x00085024
+ #define BNX2_TPAT_CPU_INTERRUPT_ENABLE                        0x00085028
+ #define BNX2_TPAT_CPU_INTERRUPT_VECTOR                        0x0008502c
+ #define BNX2_TPAT_CPU_INTERRUPT_SAVED_PC              0x00085030
+ #define BNX2_TPAT_CPU_HW_BREAKPOINT                   0x00085034
+ #define BNX2_TPAT_CPU_HW_BREAKPOINT_DISABLE            (1L<<0)
+ #define BNX2_TPAT_CPU_HW_BREAKPOINT_ADDRESS            (0x3fffffffL<<2)
+ #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK                 0x00085038
+ #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_VALUE          (0x7ffL<<0)
+ #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_PEEK_EN                (1L<<11)
+ #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_SEL            (0xfL<<12)
+ #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_VALUE          (0x7ffL<<16)
+ #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_PEEK_EN                (1L<<27)
+ #define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_SEL            (0xfL<<28)
+ #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR                        0x00085048
+ #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE            (1L<<1)
+ #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_JUMP       (0L<<1)
+ #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH     (1L<<1)
+ #define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_LBA             (0x3fffffffL<<2)
+ #define BNX2_TPAT_CPU_REG_FILE                                0x00085200
+ #define BNX2_TPAT_TPATQ                                       0x000853c0
+ #define BNX2_TPAT_FTQ_CMD                             0x000853f8
+ #define BNX2_TPAT_FTQ_CMD_OFFSET                       (0x3ffL<<0)
+ #define BNX2_TPAT_FTQ_CMD_WR_TOP                       (1L<<10)
+ #define BNX2_TPAT_FTQ_CMD_WR_TOP_0                     (0L<<10)
+ #define BNX2_TPAT_FTQ_CMD_WR_TOP_1                     (1L<<10)
+ #define BNX2_TPAT_FTQ_CMD_SFT_RESET                    (1L<<25)
+ #define BNX2_TPAT_FTQ_CMD_RD_DATA                      (1L<<26)
+ #define BNX2_TPAT_FTQ_CMD_ADD_INTERVEN                         (1L<<27)
+ #define BNX2_TPAT_FTQ_CMD_ADD_DATA                     (1L<<28)
+ #define BNX2_TPAT_FTQ_CMD_INTERVENE_CLR                        (1L<<29)
+ #define BNX2_TPAT_FTQ_CMD_POP                          (1L<<30)
+ #define BNX2_TPAT_FTQ_CMD_BUSY                                 (1L<<31)
+ #define BNX2_TPAT_FTQ_CTL                             0x000853fc
+ #define BNX2_TPAT_FTQ_CTL_INTERVENE                    (1L<<0)
+ #define BNX2_TPAT_FTQ_CTL_OVERFLOW                     (1L<<1)
+ #define BNX2_TPAT_FTQ_CTL_FORCE_INTERVENE              (1L<<2)
+ #define BNX2_TPAT_FTQ_CTL_MAX_DEPTH                    (0x3ffL<<12)
+ #define BNX2_TPAT_FTQ_CTL_CUR_DEPTH                    (0x3ffL<<22)
+ #define BNX2_TPAT_SCRATCH                             0x000a0000
+ /*
+  *  rxp_reg definition
+  *  offset: 0xc0000
+  */
+ #define BNX2_RXP_CPU_MODE                             0x000c5000
+ #define BNX2_RXP_CPU_MODE_LOCAL_RST                    (1L<<0)
+ #define BNX2_RXP_CPU_MODE_STEP_ENA                     (1L<<1)
+ #define BNX2_RXP_CPU_MODE_PAGE_0_DATA_ENA              (1L<<2)
+ #define BNX2_RXP_CPU_MODE_PAGE_0_INST_ENA              (1L<<3)
+ #define BNX2_RXP_CPU_MODE_MSG_BIT1                     (1L<<6)
+ #define BNX2_RXP_CPU_MODE_INTERRUPT_ENA                        (1L<<7)
+ #define BNX2_RXP_CPU_MODE_SOFT_HALT                    (1L<<10)
+ #define BNX2_RXP_CPU_MODE_BAD_DATA_HALT_ENA            (1L<<11)
+ #define BNX2_RXP_CPU_MODE_BAD_INST_HALT_ENA            (1L<<12)
+ #define BNX2_RXP_CPU_MODE_FIO_ABORT_HALT_ENA           (1L<<13)
+ #define BNX2_RXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA      (1L<<15)
+ #define BNX2_RXP_CPU_STATE                            0x000c5004
+ #define BNX2_RXP_CPU_STATE_BREAKPOINT                  (1L<<0)
+ #define BNX2_RXP_CPU_STATE_BAD_INST_HALTED             (1L<<2)
+ #define BNX2_RXP_CPU_STATE_PAGE_0_DATA_HALTED          (1L<<3)
+ #define BNX2_RXP_CPU_STATE_PAGE_0_INST_HALTED          (1L<<4)
+ #define BNX2_RXP_CPU_STATE_BAD_DATA_ADDR_HALTED                (1L<<5)
+ #define BNX2_RXP_CPU_STATE_BAD_PC_HALTED               (1L<<6)
+ #define BNX2_RXP_CPU_STATE_ALIGN_HALTED                        (1L<<7)
+ #define BNX2_RXP_CPU_STATE_FIO_ABORT_HALTED            (1L<<8)
+ #define BNX2_RXP_CPU_STATE_SOFT_HALTED                         (1L<<10)
+ #define BNX2_RXP_CPU_STATE_SPAD_UNDERFLOW              (1L<<11)
 -#define BNX2_RXP_CPU_STATE_INTERRRUPT                  (1L<<12)
++#define BNX2_RXP_CPU_STATE_INTERRUPT                   (1L<<12)
+ #define BNX2_RXP_CPU_STATE_DATA_ACCESS_STALL           (1L<<14)
+ #define BNX2_RXP_CPU_STATE_INST_FETCH_STALL            (1L<<15)
+ #define BNX2_RXP_CPU_STATE_BLOCKED_READ                        (1L<<31)
+ #define BNX2_RXP_CPU_EVENT_MASK                               0x000c5008
+ #define BNX2_RXP_CPU_EVENT_MASK_BREAKPOINT_MASK                (1L<<0)
+ #define BNX2_RXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK   (1L<<2)
+ #define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK        (1L<<3)
+ #define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK        (1L<<4)
+ #define BNX2_RXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK      (1L<<5)
+ #define BNX2_RXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK     (1L<<6)
+ #define BNX2_RXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK      (1L<<7)
+ #define BNX2_RXP_CPU_EVENT_MASK_FIO_ABORT_MASK                 (1L<<8)
+ #define BNX2_RXP_CPU_EVENT_MASK_SOFT_HALTED_MASK       (1L<<10)
+ #define BNX2_RXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK    (1L<<11)
+ #define BNX2_RXP_CPU_EVENT_MASK_INTERRUPT_MASK                 (1L<<12)
+ #define BNX2_RXP_CPU_PROGRAM_COUNTER                  0x000c501c
+ #define BNX2_RXP_CPU_INSTRUCTION                      0x000c5020
+ #define BNX2_RXP_CPU_DATA_ACCESS                      0x000c5024
+ #define BNX2_RXP_CPU_INTERRUPT_ENABLE                 0x000c5028
+ #define BNX2_RXP_CPU_INTERRUPT_VECTOR                 0x000c502c
+ #define BNX2_RXP_CPU_INTERRUPT_SAVED_PC                       0x000c5030
+ #define BNX2_RXP_CPU_HW_BREAKPOINT                    0x000c5034
+ #define BNX2_RXP_CPU_HW_BREAKPOINT_DISABLE             (1L<<0)
+ #define BNX2_RXP_CPU_HW_BREAKPOINT_ADDRESS             (0x3fffffffL<<2)
+ #define BNX2_RXP_CPU_DEBUG_VECT_PEEK                  0x000c5038
+ #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_VALUE           (0x7ffL<<0)
+ #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN                 (1L<<11)
+ #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_SEL             (0xfL<<12)
+ #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_VALUE           (0x7ffL<<16)
+ #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN                 (1L<<27)
+ #define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_SEL             (0xfL<<28)
+ #define BNX2_RXP_CPU_LAST_BRANCH_ADDR                 0x000c5048
+ #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE             (1L<<1)
+ #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                (0L<<1)
+ #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH      (1L<<1)
+ #define BNX2_RXP_CPU_LAST_BRANCH_ADDR_LBA              (0x3fffffffL<<2)
+ #define BNX2_RXP_CPU_REG_FILE                         0x000c5200
+ #define BNX2_RXP_PFE_PFE_CTL                          0x000c537c
+ #define BNX2_RXP_PFE_PFE_CTL_INC_USAGE_CNT             (1L<<0)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE                  (0xfL<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_0                        (0L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_1                        (1L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_2                        (2L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_3                        (3L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_4                        (4L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_5                        (5L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_6                        (6L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_7                        (7L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_8                        (8L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_9                        (9L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_10               (10L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_11               (11L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_12               (12L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_13               (13L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_14               (14L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_SIZE_15               (15L<<4)
+ #define BNX2_RXP_PFE_PFE_CTL_PFE_COUNT                         (0xfL<<12)
+ #define BNX2_RXP_PFE_PFE_CTL_OFFSET                    (0x1ffL<<16)
+ #define BNX2_RXP_RXPCQ                                        0x000c5380
+ #define BNX2_RXP_CFTQ_CMD                             0x000c53b8
+ #define BNX2_RXP_CFTQ_CMD_OFFSET                       (0x3ffL<<0)
+ #define BNX2_RXP_CFTQ_CMD_WR_TOP                       (1L<<10)
+ #define BNX2_RXP_CFTQ_CMD_WR_TOP_0                     (0L<<10)
+ #define BNX2_RXP_CFTQ_CMD_WR_TOP_1                     (1L<<10)
+ #define BNX2_RXP_CFTQ_CMD_SFT_RESET                    (1L<<25)
+ #define BNX2_RXP_CFTQ_CMD_RD_DATA                      (1L<<26)
+ #define BNX2_RXP_CFTQ_CMD_ADD_INTERVEN                         (1L<<27)
+ #define BNX2_RXP_CFTQ_CMD_ADD_DATA                     (1L<<28)
+ #define BNX2_RXP_CFTQ_CMD_INTERVENE_CLR                        (1L<<29)
+ #define BNX2_RXP_CFTQ_CMD_POP                          (1L<<30)
+ #define BNX2_RXP_CFTQ_CMD_BUSY                                 (1L<<31)
+ #define BNX2_RXP_CFTQ_CTL                             0x000c53bc
+ #define BNX2_RXP_CFTQ_CTL_INTERVENE                    (1L<<0)
+ #define BNX2_RXP_CFTQ_CTL_OVERFLOW                     (1L<<1)
+ #define BNX2_RXP_CFTQ_CTL_FORCE_INTERVENE              (1L<<2)
+ #define BNX2_RXP_CFTQ_CTL_MAX_DEPTH                    (0x3ffL<<12)
+ #define BNX2_RXP_CFTQ_CTL_CUR_DEPTH                    (0x3ffL<<22)
+ #define BNX2_RXP_RXPQ                                 0x000c53c0
+ #define BNX2_RXP_FTQ_CMD                              0x000c53f8
+ #define BNX2_RXP_FTQ_CMD_OFFSET                                (0x3ffL<<0)
+ #define BNX2_RXP_FTQ_CMD_WR_TOP                                (1L<<10)
+ #define BNX2_RXP_FTQ_CMD_WR_TOP_0                      (0L<<10)
+ #define BNX2_RXP_FTQ_CMD_WR_TOP_1                      (1L<<10)
+ #define BNX2_RXP_FTQ_CMD_SFT_RESET                     (1L<<25)
+ #define BNX2_RXP_FTQ_CMD_RD_DATA                       (1L<<26)
+ #define BNX2_RXP_FTQ_CMD_ADD_INTERVEN                  (1L<<27)
+ #define BNX2_RXP_FTQ_CMD_ADD_DATA                      (1L<<28)
+ #define BNX2_RXP_FTQ_CMD_INTERVENE_CLR                         (1L<<29)
+ #define BNX2_RXP_FTQ_CMD_POP                           (1L<<30)
+ #define BNX2_RXP_FTQ_CMD_BUSY                          (1L<<31)
+ #define BNX2_RXP_FTQ_CTL                              0x000c53fc
+ #define BNX2_RXP_FTQ_CTL_INTERVENE                     (1L<<0)
+ #define BNX2_RXP_FTQ_CTL_OVERFLOW                      (1L<<1)
+ #define BNX2_RXP_FTQ_CTL_FORCE_INTERVENE               (1L<<2)
+ #define BNX2_RXP_FTQ_CTL_MAX_DEPTH                     (0x3ffL<<12)
+ #define BNX2_RXP_FTQ_CTL_CUR_DEPTH                     (0x3ffL<<22)
+ #define BNX2_RXP_SCRATCH                              0x000e0000
+ #define BNX2_RXP_SCRATCH_RXP_FLOOD                     0x000e0024
+ #define BNX2_RXP_SCRATCH_RSS_TBL_SZ                    0x000e0038
+ #define BNX2_RXP_SCRATCH_RSS_TBL                       0x000e003c
+ #define BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES           128
+ /*
+  *  com_reg definition
+  *  offset: 0x100000
+  */
+ #define BNX2_COM_CKSUM_ERROR_STATUS                   0x00100000
+ #define BNX2_COM_CKSUM_ERROR_STATUS_CALCULATED                 (0xffffL<<0)
+ #define BNX2_COM_CKSUM_ERROR_STATUS_EXPECTED           (0xffffL<<16)
+ #define BNX2_COM_CPU_MODE                             0x00105000
+ #define BNX2_COM_CPU_MODE_LOCAL_RST                    (1L<<0)
+ #define BNX2_COM_CPU_MODE_STEP_ENA                     (1L<<1)
+ #define BNX2_COM_CPU_MODE_PAGE_0_DATA_ENA              (1L<<2)
+ #define BNX2_COM_CPU_MODE_PAGE_0_INST_ENA              (1L<<3)
+ #define BNX2_COM_CPU_MODE_MSG_BIT1                     (1L<<6)
+ #define BNX2_COM_CPU_MODE_INTERRUPT_ENA                        (1L<<7)
+ #define BNX2_COM_CPU_MODE_SOFT_HALT                    (1L<<10)
+ #define BNX2_COM_CPU_MODE_BAD_DATA_HALT_ENA            (1L<<11)
+ #define BNX2_COM_CPU_MODE_BAD_INST_HALT_ENA            (1L<<12)
+ #define BNX2_COM_CPU_MODE_FIO_ABORT_HALT_ENA           (1L<<13)
+ #define BNX2_COM_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA      (1L<<15)
+ #define BNX2_COM_CPU_STATE                            0x00105004
+ #define BNX2_COM_CPU_STATE_BREAKPOINT                  (1L<<0)
+ #define BNX2_COM_CPU_STATE_BAD_INST_HALTED             (1L<<2)
+ #define BNX2_COM_CPU_STATE_PAGE_0_DATA_HALTED          (1L<<3)
+ #define BNX2_COM_CPU_STATE_PAGE_0_INST_HALTED          (1L<<4)
+ #define BNX2_COM_CPU_STATE_BAD_DATA_ADDR_HALTED                (1L<<5)
+ #define BNX2_COM_CPU_STATE_BAD_PC_HALTED               (1L<<6)
+ #define BNX2_COM_CPU_STATE_ALIGN_HALTED                        (1L<<7)
+ #define BNX2_COM_CPU_STATE_FIO_ABORT_HALTED            (1L<<8)
+ #define BNX2_COM_CPU_STATE_SOFT_HALTED                         (1L<<10)
+ #define BNX2_COM_CPU_STATE_SPAD_UNDERFLOW              (1L<<11)
 -#define BNX2_COM_CPU_STATE_INTERRRUPT                  (1L<<12)
++#define BNX2_COM_CPU_STATE_INTERRUPT                   (1L<<12)
+ #define BNX2_COM_CPU_STATE_DATA_ACCESS_STALL           (1L<<14)
+ #define BNX2_COM_CPU_STATE_INST_FETCH_STALL            (1L<<15)
+ #define BNX2_COM_CPU_STATE_BLOCKED_READ                        (1L<<31)
+ #define BNX2_COM_CPU_EVENT_MASK                               0x00105008
+ #define BNX2_COM_CPU_EVENT_MASK_BREAKPOINT_MASK                (1L<<0)
+ #define BNX2_COM_CPU_EVENT_MASK_BAD_INST_HALTED_MASK   (1L<<2)
+ #define BNX2_COM_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK        (1L<<3)
+ #define BNX2_COM_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK        (1L<<4)
+ #define BNX2_COM_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK      (1L<<5)
+ #define BNX2_COM_CPU_EVENT_MASK_BAD_PC_HALTED_MASK     (1L<<6)
+ #define BNX2_COM_CPU_EVENT_MASK_ALIGN_HALTED_MASK      (1L<<7)
+ #define BNX2_COM_CPU_EVENT_MASK_FIO_ABORT_MASK                 (1L<<8)
+ #define BNX2_COM_CPU_EVENT_MASK_SOFT_HALTED_MASK       (1L<<10)
+ #define BNX2_COM_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK    (1L<<11)
+ #define BNX2_COM_CPU_EVENT_MASK_INTERRUPT_MASK                 (1L<<12)
+ #define BNX2_COM_CPU_PROGRAM_COUNTER                  0x0010501c
+ #define BNX2_COM_CPU_INSTRUCTION                      0x00105020
+ #define BNX2_COM_CPU_DATA_ACCESS                      0x00105024
+ #define BNX2_COM_CPU_INTERRUPT_ENABLE                 0x00105028
+ #define BNX2_COM_CPU_INTERRUPT_VECTOR                 0x0010502c
+ #define BNX2_COM_CPU_INTERRUPT_SAVED_PC                       0x00105030
+ #define BNX2_COM_CPU_HW_BREAKPOINT                    0x00105034
+ #define BNX2_COM_CPU_HW_BREAKPOINT_DISABLE             (1L<<0)
+ #define BNX2_COM_CPU_HW_BREAKPOINT_ADDRESS             (0x3fffffffL<<2)
+ #define BNX2_COM_CPU_DEBUG_VECT_PEEK                  0x00105038
+ #define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_VALUE           (0x7ffL<<0)
+ #define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_PEEK_EN                 (1L<<11)
+ #define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_SEL             (0xfL<<12)
+ #define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_VALUE           (0x7ffL<<16)
+ #define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_PEEK_EN                 (1L<<27)
+ #define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_SEL             (0xfL<<28)
+ #define BNX2_COM_CPU_LAST_BRANCH_ADDR                 0x00105048
+ #define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE             (1L<<1)
+ #define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                (0L<<1)
+ #define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH      (1L<<1)
+ #define BNX2_COM_CPU_LAST_BRANCH_ADDR_LBA              (0x3fffffffL<<2)
+ #define BNX2_COM_CPU_REG_FILE                         0x00105200
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL                    0x001052bc
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_INC_USAGE_CNT       (1L<<0)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE            (0xfL<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_0          (0L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_1          (1L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_2          (2L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_3          (3L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_4          (4L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_5          (5L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_6          (6L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_7          (7L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_8          (8L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_9          (9L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_10                 (10L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_11                 (11L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_12                 (12L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_13                 (13L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_14                 (14L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_SIZE_15                 (15L<<4)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_PFE_COUNT           (0xfL<<12)
+ #define BNX2_COM_COMTQ_PFE_PFE_CTL_OFFSET              (0x1ffL<<16)
+ #define BNX2_COM_COMXQ                                        0x00105340
+ #define BNX2_COM_COMXQ_FTQ_CMD                                0x00105378
+ #define BNX2_COM_COMXQ_FTQ_CMD_OFFSET                  (0x3ffL<<0)
+ #define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP                  (1L<<10)
+ #define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_0                        (0L<<10)
+ #define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_1                        (1L<<10)
+ #define BNX2_COM_COMXQ_FTQ_CMD_SFT_RESET               (1L<<25)
+ #define BNX2_COM_COMXQ_FTQ_CMD_RD_DATA                         (1L<<26)
+ #define BNX2_COM_COMXQ_FTQ_CMD_ADD_INTERVEN            (1L<<27)
+ #define BNX2_COM_COMXQ_FTQ_CMD_ADD_DATA                        (1L<<28)
+ #define BNX2_COM_COMXQ_FTQ_CMD_INTERVENE_CLR           (1L<<29)
+ #define BNX2_COM_COMXQ_FTQ_CMD_POP                     (1L<<30)
+ #define BNX2_COM_COMXQ_FTQ_CMD_BUSY                    (1L<<31)
+ #define BNX2_COM_COMXQ_FTQ_CTL                                0x0010537c
+ #define BNX2_COM_COMXQ_FTQ_CTL_INTERVENE               (1L<<0)
+ #define BNX2_COM_COMXQ_FTQ_CTL_OVERFLOW                        (1L<<1)
+ #define BNX2_COM_COMXQ_FTQ_CTL_FORCE_INTERVENE                 (1L<<2)
+ #define BNX2_COM_COMXQ_FTQ_CTL_MAX_DEPTH               (0x3ffL<<12)
+ #define BNX2_COM_COMXQ_FTQ_CTL_CUR_DEPTH               (0x3ffL<<22)
+ #define BNX2_COM_COMTQ                                        0x00105380
+ #define BNX2_COM_COMTQ_FTQ_CMD                                0x001053b8
+ #define BNX2_COM_COMTQ_FTQ_CMD_OFFSET                  (0x3ffL<<0)
+ #define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP                  (1L<<10)
+ #define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_0                        (0L<<10)
+ #define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_1                        (1L<<10)
+ #define BNX2_COM_COMTQ_FTQ_CMD_SFT_RESET               (1L<<25)
+ #define BNX2_COM_COMTQ_FTQ_CMD_RD_DATA                         (1L<<26)
+ #define BNX2_COM_COMTQ_FTQ_CMD_ADD_INTERVEN            (1L<<27)
+ #define BNX2_COM_COMTQ_FTQ_CMD_ADD_DATA                        (1L<<28)
+ #define BNX2_COM_COMTQ_FTQ_CMD_INTERVENE_CLR           (1L<<29)
+ #define BNX2_COM_COMTQ_FTQ_CMD_POP                     (1L<<30)
+ #define BNX2_COM_COMTQ_FTQ_CMD_BUSY                    (1L<<31)
+ #define BNX2_COM_COMTQ_FTQ_CTL                                0x001053bc
+ #define BNX2_COM_COMTQ_FTQ_CTL_INTERVENE               (1L<<0)
+ #define BNX2_COM_COMTQ_FTQ_CTL_OVERFLOW                        (1L<<1)
+ #define BNX2_COM_COMTQ_FTQ_CTL_FORCE_INTERVENE                 (1L<<2)
+ #define BNX2_COM_COMTQ_FTQ_CTL_MAX_DEPTH               (0x3ffL<<12)
+ #define BNX2_COM_COMTQ_FTQ_CTL_CUR_DEPTH               (0x3ffL<<22)
+ #define BNX2_COM_COMQ                                 0x001053c0
+ #define BNX2_COM_COMQ_FTQ_CMD                         0x001053f8
+ #define BNX2_COM_COMQ_FTQ_CMD_OFFSET                   (0x3ffL<<0)
+ #define BNX2_COM_COMQ_FTQ_CMD_WR_TOP                   (1L<<10)
+ #define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_0                         (0L<<10)
+ #define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_1                         (1L<<10)
+ #define BNX2_COM_COMQ_FTQ_CMD_SFT_RESET                        (1L<<25)
+ #define BNX2_COM_COMQ_FTQ_CMD_RD_DATA                  (1L<<26)
+ #define BNX2_COM_COMQ_FTQ_CMD_ADD_INTERVEN             (1L<<27)
+ #define BNX2_COM_COMQ_FTQ_CMD_ADD_DATA                         (1L<<28)
+ #define BNX2_COM_COMQ_FTQ_CMD_INTERVENE_CLR            (1L<<29)
+ #define BNX2_COM_COMQ_FTQ_CMD_POP                      (1L<<30)
+ #define BNX2_COM_COMQ_FTQ_CMD_BUSY                     (1L<<31)
+ #define BNX2_COM_COMQ_FTQ_CTL                         0x001053fc
+ #define BNX2_COM_COMQ_FTQ_CTL_INTERVENE                        (1L<<0)
+ #define BNX2_COM_COMQ_FTQ_CTL_OVERFLOW                         (1L<<1)
+ #define BNX2_COM_COMQ_FTQ_CTL_FORCE_INTERVENE          (1L<<2)
+ #define BNX2_COM_COMQ_FTQ_CTL_MAX_DEPTH                        (0x3ffL<<12)
+ #define BNX2_COM_COMQ_FTQ_CTL_CUR_DEPTH                        (0x3ffL<<22)
+ #define BNX2_COM_SCRATCH                              0x00120000
+ #define BNX2_FW_RX_LOW_LATENCY                                 0x00120058
+ #define BNX2_FW_RX_DROP_COUNT                          0x00120084
+ /*
+  *  cp_reg definition
+  *  offset: 0x180000
+  */
+ #define BNX2_CP_CKSUM_ERROR_STATUS                    0x00180000
+ #define BNX2_CP_CKSUM_ERROR_STATUS_CALCULATED          (0xffffL<<0)
+ #define BNX2_CP_CKSUM_ERROR_STATUS_EXPECTED            (0xffffL<<16)
+ #define BNX2_CP_CPU_MODE                              0x00185000
+ #define BNX2_CP_CPU_MODE_LOCAL_RST                     (1L<<0)
+ #define BNX2_CP_CPU_MODE_STEP_ENA                      (1L<<1)
+ #define BNX2_CP_CPU_MODE_PAGE_0_DATA_ENA               (1L<<2)
+ #define BNX2_CP_CPU_MODE_PAGE_0_INST_ENA               (1L<<3)
+ #define BNX2_CP_CPU_MODE_MSG_BIT1                      (1L<<6)
+ #define BNX2_CP_CPU_MODE_INTERRUPT_ENA                         (1L<<7)
+ #define BNX2_CP_CPU_MODE_SOFT_HALT                     (1L<<10)
+ #define BNX2_CP_CPU_MODE_BAD_DATA_HALT_ENA             (1L<<11)
+ #define BNX2_CP_CPU_MODE_BAD_INST_HALT_ENA             (1L<<12)
+ #define BNX2_CP_CPU_MODE_FIO_ABORT_HALT_ENA            (1L<<13)
+ #define BNX2_CP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA       (1L<<15)
+ #define BNX2_CP_CPU_STATE                             0x00185004
+ #define BNX2_CP_CPU_STATE_BREAKPOINT                   (1L<<0)
+ #define BNX2_CP_CPU_STATE_BAD_INST_HALTED              (1L<<2)
+ #define BNX2_CP_CPU_STATE_PAGE_0_DATA_HALTED           (1L<<3)
+ #define BNX2_CP_CPU_STATE_PAGE_0_INST_HALTED           (1L<<4)
+ #define BNX2_CP_CPU_STATE_BAD_DATA_ADDR_HALTED                 (1L<<5)
+ #define BNX2_CP_CPU_STATE_BAD_PC_HALTED                        (1L<<6)
+ #define BNX2_CP_CPU_STATE_ALIGN_HALTED                         (1L<<7)
+ #define BNX2_CP_CPU_STATE_FIO_ABORT_HALTED             (1L<<8)
+ #define BNX2_CP_CPU_STATE_SOFT_HALTED                  (1L<<10)
+ #define BNX2_CP_CPU_STATE_SPAD_UNDERFLOW               (1L<<11)
 -#define BNX2_CP_CPU_STATE_INTERRRUPT                   (1L<<12)
++#define BNX2_CP_CPU_STATE_INTERRUPT                    (1L<<12)
+ #define BNX2_CP_CPU_STATE_DATA_ACCESS_STALL            (1L<<14)
+ #define BNX2_CP_CPU_STATE_INST_FETCH_STALL             (1L<<15)
+ #define BNX2_CP_CPU_STATE_BLOCKED_READ                         (1L<<31)
+ #define BNX2_CP_CPU_EVENT_MASK                                0x00185008
+ #define BNX2_CP_CPU_EVENT_MASK_BREAKPOINT_MASK                 (1L<<0)
+ #define BNX2_CP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK    (1L<<2)
+ #define BNX2_CP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK         (1L<<3)
+ #define BNX2_CP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK         (1L<<4)
+ #define BNX2_CP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK       (1L<<5)
+ #define BNX2_CP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK      (1L<<6)
+ #define BNX2_CP_CPU_EVENT_MASK_ALIGN_HALTED_MASK       (1L<<7)
+ #define BNX2_CP_CPU_EVENT_MASK_FIO_ABORT_MASK          (1L<<8)
+ #define BNX2_CP_CPU_EVENT_MASK_SOFT_HALTED_MASK                (1L<<10)
+ #define BNX2_CP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK     (1L<<11)
+ #define BNX2_CP_CPU_EVENT_MASK_INTERRUPT_MASK          (1L<<12)
+ #define BNX2_CP_CPU_PROGRAM_COUNTER                   0x0018501c
+ #define BNX2_CP_CPU_INSTRUCTION                               0x00185020
+ #define BNX2_CP_CPU_DATA_ACCESS                               0x00185024
+ #define BNX2_CP_CPU_INTERRUPT_ENABLE                  0x00185028
+ #define BNX2_CP_CPU_INTERRUPT_VECTOR                  0x0018502c
+ #define BNX2_CP_CPU_INTERRUPT_SAVED_PC                        0x00185030
+ #define BNX2_CP_CPU_HW_BREAKPOINT                     0x00185034
+ #define BNX2_CP_CPU_HW_BREAKPOINT_DISABLE              (1L<<0)
+ #define BNX2_CP_CPU_HW_BREAKPOINT_ADDRESS              (0x3fffffffL<<2)
+ #define BNX2_CP_CPU_DEBUG_VECT_PEEK                   0x00185038
+ #define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_VALUE            (0x7ffL<<0)
+ #define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN          (1L<<11)
+ #define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_SEL              (0xfL<<12)
+ #define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_VALUE            (0x7ffL<<16)
+ #define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN          (1L<<27)
+ #define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_SEL              (0xfL<<28)
+ #define BNX2_CP_CPU_LAST_BRANCH_ADDR                  0x00185048
+ #define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE              (1L<<1)
+ #define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                 (0L<<1)
+ #define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH       (1L<<1)
+ #define BNX2_CP_CPU_LAST_BRANCH_ADDR_LBA               (0x3fffffffL<<2)
+ #define BNX2_CP_CPU_REG_FILE                          0x00185200
+ #define BNX2_CP_CPQ_PFE_PFE_CTL                               0x001853bc
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_INC_USAGE_CNT          (1L<<0)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE               (0xfL<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_0             (0L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_1             (1L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_2             (2L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_3             (3L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_4             (4L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_5             (5L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_6             (6L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_7             (7L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_8             (8L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_9             (9L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_10            (10L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_11            (11L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_12            (12L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_13            (13L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_14            (14L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_SIZE_15            (15L<<4)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_PFE_COUNT              (0xfL<<12)
+ #define BNX2_CP_CPQ_PFE_PFE_CTL_OFFSET                         (0x1ffL<<16)
+ #define BNX2_CP_CPQ                                   0x001853c0
+ #define BNX2_CP_CPQ_FTQ_CMD                           0x001853f8
+ #define BNX2_CP_CPQ_FTQ_CMD_OFFSET                     (0x3ffL<<0)
+ #define BNX2_CP_CPQ_FTQ_CMD_WR_TOP                     (1L<<10)
+ #define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_0                   (0L<<10)
+ #define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_1                   (1L<<10)
+ #define BNX2_CP_CPQ_FTQ_CMD_SFT_RESET                  (1L<<25)
+ #define BNX2_CP_CPQ_FTQ_CMD_RD_DATA                    (1L<<26)
+ #define BNX2_CP_CPQ_FTQ_CMD_ADD_INTERVEN               (1L<<27)
+ #define BNX2_CP_CPQ_FTQ_CMD_ADD_DATA                   (1L<<28)
+ #define BNX2_CP_CPQ_FTQ_CMD_INTERVENE_CLR              (1L<<29)
+ #define BNX2_CP_CPQ_FTQ_CMD_POP                                (1L<<30)
+ #define BNX2_CP_CPQ_FTQ_CMD_BUSY                       (1L<<31)
+ #define BNX2_CP_CPQ_FTQ_CTL                           0x001853fc
+ #define BNX2_CP_CPQ_FTQ_CTL_INTERVENE                  (1L<<0)
+ #define BNX2_CP_CPQ_FTQ_CTL_OVERFLOW                   (1L<<1)
+ #define BNX2_CP_CPQ_FTQ_CTL_FORCE_INTERVENE            (1L<<2)
+ #define BNX2_CP_CPQ_FTQ_CTL_MAX_DEPTH                  (0x3ffL<<12)
+ #define BNX2_CP_CPQ_FTQ_CTL_CUR_DEPTH                  (0x3ffL<<22)
+ #define BNX2_CP_SCRATCH                                       0x001a0000
+ #define BNX2_FW_MAX_ISCSI_CONN                                 0x001a0080
+ /*
+  *  mcp_reg definition
+  *  offset: 0x140000
+  */
+ #define BNX2_MCP_MCP_CONTROL                          0x00140080
+ #define BNX2_MCP_MCP_CONTROL_SMBUS_SEL                         (1L<<30)
+ #define BNX2_MCP_MCP_CONTROL_MCP_ISOLATE               (1L<<31)
+ #define BNX2_MCP_MCP_ATTENTION_STATUS                 0x00140084
+ #define BNX2_MCP_MCP_ATTENTION_STATUS_DRV_DOORBELL     (1L<<29)
+ #define BNX2_MCP_MCP_ATTENTION_STATUS_WATCHDOG_TIMEOUT         (1L<<30)
+ #define BNX2_MCP_MCP_ATTENTION_STATUS_CPU_EVENT                (1L<<31)
+ #define BNX2_MCP_MCP_HEARTBEAT_CONTROL                        0x00140088
+ #define BNX2_MCP_MCP_HEARTBEAT_CONTROL_MCP_HEARTBEAT_ENABLE    (1L<<31)
+ #define BNX2_MCP_MCP_HEARTBEAT_STATUS                 0x0014008c
+ #define BNX2_MCP_MCP_HEARTBEAT_STATUS_MCP_HEARTBEAT_PERIOD     (0x7ffL<<0)
+ #define BNX2_MCP_MCP_HEARTBEAT_STATUS_VALID            (1L<<31)
+ #define BNX2_MCP_MCP_HEARTBEAT                                0x00140090
+ #define BNX2_MCP_MCP_HEARTBEAT_MCP_HEARTBEAT_COUNT     (0x3fffffffL<<0)
+ #define BNX2_MCP_MCP_HEARTBEAT_MCP_HEARTBEAT_INC       (1L<<30)
+ #define BNX2_MCP_MCP_HEARTBEAT_MCP_HEARTBEAT_RESET     (1L<<31)
+ #define BNX2_MCP_WATCHDOG_RESET                               0x00140094
+ #define BNX2_MCP_WATCHDOG_RESET_WATCHDOG_RESET                 (1L<<31)
+ #define BNX2_MCP_WATCHDOG_CONTROL                     0x00140098
+ #define BNX2_MCP_WATCHDOG_CONTROL_WATCHDOG_TIMEOUT     (0xfffffffL<<0)
+ #define BNX2_MCP_WATCHDOG_CONTROL_WATCHDOG_ATTN                (1L<<29)
+ #define BNX2_MCP_WATCHDOG_CONTROL_MCP_RST_ENABLE       (1L<<30)
+ #define BNX2_MCP_WATCHDOG_CONTROL_WATCHDOG_ENABLE      (1L<<31)
+ #define BNX2_MCP_ACCESS_LOCK                          0x0014009c
+ #define BNX2_MCP_ACCESS_LOCK_LOCK                      (1L<<31)
+ #define BNX2_MCP_TOE_ID                                       0x001400a0
+ #define BNX2_MCP_TOE_ID_FUNCTION_ID                    (1L<<31)
+ #define BNX2_MCP_MAILBOX_CFG                          0x001400a4
+ #define BNX2_MCP_MAILBOX_CFG_MAILBOX_OFFSET            (0x3fffL<<0)
+ #define BNX2_MCP_MAILBOX_CFG_MAILBOX_SIZE              (0xfffL<<20)
+ #define BNX2_MCP_MAILBOX_CFG_OTHER_FUNC                       0x001400a8
+ #define BNX2_MCP_MAILBOX_CFG_OTHER_FUNC_MAILBOX_OFFSET         (0x3fffL<<0)
+ #define BNX2_MCP_MAILBOX_CFG_OTHER_FUNC_MAILBOX_SIZE   (0xfffL<<20)
+ #define BNX2_MCP_MCP_DOORBELL                         0x001400ac
+ #define BNX2_MCP_MCP_DOORBELL_MCP_DOORBELL             (1L<<31)
+ #define BNX2_MCP_DRIVER_DOORBELL                      0x001400b0
+ #define BNX2_MCP_DRIVER_DOORBELL_DRIVER_DOORBELL       (1L<<31)
+ #define BNX2_MCP_DRIVER_DOORBELL_OTHER_FUNC           0x001400b4
+ #define BNX2_MCP_DRIVER_DOORBELL_OTHER_FUNC_DRIVER_DOORBELL    (1L<<31)
+ #define BNX2_MCP_CPU_MODE                             0x00145000
+ #define BNX2_MCP_CPU_MODE_LOCAL_RST                    (1L<<0)
+ #define BNX2_MCP_CPU_MODE_STEP_ENA                     (1L<<1)
+ #define BNX2_MCP_CPU_MODE_PAGE_0_DATA_ENA              (1L<<2)
+ #define BNX2_MCP_CPU_MODE_PAGE_0_INST_ENA              (1L<<3)
+ #define BNX2_MCP_CPU_MODE_MSG_BIT1                     (1L<<6)
+ #define BNX2_MCP_CPU_MODE_INTERRUPT_ENA                        (1L<<7)
+ #define BNX2_MCP_CPU_MODE_SOFT_HALT                    (1L<<10)
+ #define BNX2_MCP_CPU_MODE_BAD_DATA_HALT_ENA            (1L<<11)
+ #define BNX2_MCP_CPU_MODE_BAD_INST_HALT_ENA            (1L<<12)
+ #define BNX2_MCP_CPU_MODE_FIO_ABORT_HALT_ENA           (1L<<13)
+ #define BNX2_MCP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA      (1L<<15)
+ #define BNX2_MCP_CPU_STATE                            0x00145004
+ #define BNX2_MCP_CPU_STATE_BREAKPOINT                  (1L<<0)
+ #define BNX2_MCP_CPU_STATE_BAD_INST_HALTED             (1L<<2)
+ #define BNX2_MCP_CPU_STATE_PAGE_0_DATA_HALTED          (1L<<3)
+ #define BNX2_MCP_CPU_STATE_PAGE_0_INST_HALTED          (1L<<4)
+ #define BNX2_MCP_CPU_STATE_BAD_DATA_ADDR_HALTED                (1L<<5)
+ #define BNX2_MCP_CPU_STATE_BAD_PC_HALTED               (1L<<6)
+ #define BNX2_MCP_CPU_STATE_ALIGN_HALTED                        (1L<<7)
+ #define BNX2_MCP_CPU_STATE_FIO_ABORT_HALTED            (1L<<8)
+ #define BNX2_MCP_CPU_STATE_SOFT_HALTED                         (1L<<10)
+ #define BNX2_MCP_CPU_STATE_SPAD_UNDERFLOW              (1L<<11)
 -#define BNX2_MCP_CPU_STATE_INTERRRUPT                  (1L<<12)
++#define BNX2_MCP_CPU_STATE_INTERRUPT                   (1L<<12)
+ #define BNX2_MCP_CPU_STATE_DATA_ACCESS_STALL           (1L<<14)
+ #define BNX2_MCP_CPU_STATE_INST_FETCH_STALL            (1L<<15)
+ #define BNX2_MCP_CPU_STATE_BLOCKED_READ                        (1L<<31)
+ #define BNX2_MCP_CPU_EVENT_MASK                               0x00145008
+ #define BNX2_MCP_CPU_EVENT_MASK_BREAKPOINT_MASK                (1L<<0)
+ #define BNX2_MCP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK   (1L<<2)
+ #define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK        (1L<<3)
+ #define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK        (1L<<4)
+ #define BNX2_MCP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK      (1L<<5)
+ #define BNX2_MCP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK     (1L<<6)
+ #define BNX2_MCP_CPU_EVENT_MASK_ALIGN_HALTED_MASK      (1L<<7)
+ #define BNX2_MCP_CPU_EVENT_MASK_FIO_ABORT_MASK                 (1L<<8)
+ #define BNX2_MCP_CPU_EVENT_MASK_SOFT_HALTED_MASK       (1L<<10)
+ #define BNX2_MCP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK    (1L<<11)
+ #define BNX2_MCP_CPU_EVENT_MASK_INTERRUPT_MASK                 (1L<<12)
+ #define BNX2_MCP_CPU_PROGRAM_COUNTER                  0x0014501c
+ #define BNX2_MCP_CPU_INSTRUCTION                      0x00145020
+ #define BNX2_MCP_CPU_DATA_ACCESS                      0x00145024
+ #define BNX2_MCP_CPU_INTERRUPT_ENABLE                 0x00145028
+ #define BNX2_MCP_CPU_INTERRUPT_VECTOR                 0x0014502c
+ #define BNX2_MCP_CPU_INTERRUPT_SAVED_PC                       0x00145030
+ #define BNX2_MCP_CPU_HW_BREAKPOINT                    0x00145034
+ #define BNX2_MCP_CPU_HW_BREAKPOINT_DISABLE             (1L<<0)
+ #define BNX2_MCP_CPU_HW_BREAKPOINT_ADDRESS             (0x3fffffffL<<2)
+ #define BNX2_MCP_CPU_DEBUG_VECT_PEEK                  0x00145038
+ #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_VALUE           (0x7ffL<<0)
+ #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN                 (1L<<11)
+ #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_SEL             (0xfL<<12)
+ #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_VALUE           (0x7ffL<<16)
+ #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN                 (1L<<27)
+ #define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_SEL             (0xfL<<28)
+ #define BNX2_MCP_CPU_LAST_BRANCH_ADDR                 0x00145048
+ #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE             (1L<<1)
+ #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP                (0L<<1)
+ #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH      (1L<<1)
+ #define BNX2_MCP_CPU_LAST_BRANCH_ADDR_LBA              (0x3fffffffL<<2)
+ #define BNX2_MCP_CPU_REG_FILE                         0x00145200
+ #define BNX2_MCP_MCPQ                                 0x001453c0
+ #define BNX2_MCP_MCPQ_FTQ_CMD                         0x001453f8
+ #define BNX2_MCP_MCPQ_FTQ_CMD_OFFSET                   (0x3ffL<<0)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP                   (1L<<10)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_0                         (0L<<10)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_1                         (1L<<10)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_SFT_RESET                        (1L<<25)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_RD_DATA                  (1L<<26)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_ADD_INTERVEN             (1L<<27)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_ADD_DATA                         (1L<<28)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_INTERVENE_CLR            (1L<<29)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_POP                      (1L<<30)
+ #define BNX2_MCP_MCPQ_FTQ_CMD_BUSY                     (1L<<31)
+ #define BNX2_MCP_MCPQ_FTQ_CTL                         0x001453fc
+ #define BNX2_MCP_MCPQ_FTQ_CTL_INTERVENE                        (1L<<0)
+ #define BNX2_MCP_MCPQ_FTQ_CTL_OVERFLOW                         (1L<<1)
+ #define BNX2_MCP_MCPQ_FTQ_CTL_FORCE_INTERVENE          (1L<<2)
+ #define BNX2_MCP_MCPQ_FTQ_CTL_MAX_DEPTH                        (0x3ffL<<12)
+ #define BNX2_MCP_MCPQ_FTQ_CTL_CUR_DEPTH                        (0x3ffL<<22)
+ #define BNX2_MCP_ROM                                  0x00150000
+ #define BNX2_MCP_SCRATCH                              0x00160000
+ #define BNX2_MCP_STATE_P1                              0x0016f9c8
+ #define BNX2_MCP_STATE_P0                              0x0016fdc8
+ #define BNX2_MCP_STATE_P1_5708                                 0x001699c8
+ #define BNX2_MCP_STATE_P0_5708                                 0x00169dc8
+ #define BNX2_SHM_HDR_SIGNATURE                                BNX2_MCP_SCRATCH
+ #define BNX2_SHM_HDR_SIGNATURE_SIG_MASK                        0xffff0000
+ #define BNX2_SHM_HDR_SIGNATURE_SIG                     0x53530000
+ #define BNX2_SHM_HDR_SIGNATURE_VER_MASK                        0x000000ff
+ #define BNX2_SHM_HDR_SIGNATURE_VER_ONE                         0x00000001
+ #define BNX2_SHM_HDR_ADDR_0                           BNX2_MCP_SCRATCH + 4
+ #define BNX2_SHM_HDR_ADDR_1                           BNX2_MCP_SCRATCH + 8
+ #define NUM_MC_HASH_REGISTERS   8
+ /* PHY_ID1: bits 31-16; PHY_ID2: bits 15-0.  */
+ #define PHY_BCM5706_PHY_ID                          0x00206160
+ #define PHY_ID(id)                                  ((id) & 0xfffffff0)
+ #define PHY_REV_ID(id)                              ((id) & 0xf)
+ /* 5708 Serdes PHY registers */
+ #define BCM5708S_BMCR_FORCE_2500              0x20
+ #define BCM5708S_UP1                          0xb
+ #define BCM5708S_UP1_2G5                      0x1
+ #define BCM5708S_BLK_ADDR                     0x1f
+ #define BCM5708S_BLK_ADDR_DIG                 0x0000
+ #define BCM5708S_BLK_ADDR_DIG3                        0x0002
+ #define BCM5708S_BLK_ADDR_TX_MISC             0x0005
+ /* Digital Block */
+ #define BCM5708S_1000X_CTL1                   0x10
+ #define BCM5708S_1000X_CTL1_FIBER_MODE                0x0001
+ #define BCM5708S_1000X_CTL1_AUTODET_EN                0x0010
+ #define BCM5708S_1000X_CTL2                   0x11
+ #define BCM5708S_1000X_CTL2_PLLEL_DET_EN      0x0001
+ #define BCM5708S_1000X_STAT1                  0x14
+ #define BCM5708S_1000X_STAT1_SGMII            0x0001
+ #define BCM5708S_1000X_STAT1_LINK             0x0002
+ #define BCM5708S_1000X_STAT1_FD                       0x0004
+ #define BCM5708S_1000X_STAT1_SPEED_MASK               0x0018
+ #define BCM5708S_1000X_STAT1_SPEED_10         0x0000
+ #define BCM5708S_1000X_STAT1_SPEED_100                0x0008
+ #define BCM5708S_1000X_STAT1_SPEED_1G         0x0010
+ #define BCM5708S_1000X_STAT1_SPEED_2G5                0x0018
+ #define BCM5708S_1000X_STAT1_TX_PAUSE         0x0020
+ #define BCM5708S_1000X_STAT1_RX_PAUSE         0x0040
+ /* Digital3 Block */
+ #define BCM5708S_DIG_3_0                      0x10
+ #define BCM5708S_DIG_3_0_USE_IEEE             0x0001
+ /* Tx/Misc Block */
+ #define BCM5708S_TX_ACTL1                     0x15
+ #define BCM5708S_TX_ACTL1_DRIVER_VCM          0x30
+ #define BCM5708S_TX_ACTL3                     0x17
+ #define MII_BNX2_DSP_RW_PORT                  0x15
+ #define MII_BNX2_DSP_ADDRESS                  0x17
+ #define MII_BNX2_DSP_EXPAND_REG                        0x0f00
+ #define MII_EXPAND_REG1                                 (MII_BNX2_DSP_EXPAND_REG | 1)
+ #define MII_EXPAND_REG1_RUDI_C                           0x20
+ #define MII_EXPAND_SERDES_CTL                   (MII_BNX2_DSP_EXPAND_REG | 3)
+ #define MII_BNX2_MISC_SHADOW                  0x1c
+ #define MISC_SHDW_AN_DBG                       0x6800
+ #define MISC_SHDW_AN_DBG_NOSYNC                         0x0002
+ #define MISC_SHDW_AN_DBG_RUDI_INVALID           0x0100
+ #define MISC_SHDW_MODE_CTL                     0x7c00
+ #define MISC_SHDW_MODE_CTL_SIG_DET              0x0010
+ #define MII_BNX2_BLK_ADDR                     0x1f
+ #define MII_BNX2_BLK_ADDR_IEEE0                        0x0000
+ #define MII_BNX2_BLK_ADDR_GP_STATUS            0x8120
+ #define MII_BNX2_GP_TOP_AN_STATUS1              0x1b
+ #define MII_BNX2_GP_TOP_AN_SPEED_MSK             0x3f00
+ #define MII_BNX2_GP_TOP_AN_SPEED_10              0x0000
+ #define MII_BNX2_GP_TOP_AN_SPEED_100             0x0100
+ #define MII_BNX2_GP_TOP_AN_SPEED_1G              0x0200
+ #define MII_BNX2_GP_TOP_AN_SPEED_2_5G            0x0300
+ #define MII_BNX2_GP_TOP_AN_SPEED_1GKV            0x0d00
+ #define MII_BNX2_GP_TOP_AN_FD                    0x8
+ #define MII_BNX2_BLK_ADDR_SERDES_DIG           0x8300
+ #define MII_BNX2_SERDES_DIG_1000XCTL1           0x10
+ #define MII_BNX2_SD_1000XCTL1_FIBER              0x01
+ #define MII_BNX2_SD_1000XCTL1_AUTODET            0x10
+ #define MII_BNX2_SERDES_DIG_MISC1               0x18
+ #define MII_BNX2_SD_MISC1_FORCE_MSK              0xf
+ #define MII_BNX2_SD_MISC1_FORCE_2_5G             0x0
+ #define MII_BNX2_SD_MISC1_FORCE                          0x10
+ #define MII_BNX2_BLK_ADDR_OVER1G               0x8320
+ #define MII_BNX2_OVER1G_UP1                     0x19
+ #define MII_BNX2_BLK_ADDR_BAM_NXTPG            0x8350
+ #define MII_BNX2_BAM_NXTPG_CTL                          0x10
+ #define MII_BNX2_NXTPG_CTL_BAM                           0x1
+ #define MII_BNX2_NXTPG_CTL_T2                    0x2
+ #define MII_BNX2_BLK_ADDR_CL73_USERB0          0x8370
+ #define MII_BNX2_CL73_BAM_CTL1                          0x12
+ #define MII_BNX2_CL73_BAM_EN                     0x8000
+ #define MII_BNX2_CL73_BAM_STA_MGR_EN             0x4000
+ #define MII_BNX2_CL73_BAM_NP_AFT_BP_EN                   0x2000
+ #define MII_BNX2_BLK_ADDR_AER                  0xffd0
+ #define MII_BNX2_AER_AER                        0x1e
+ #define MII_BNX2_AER_AER_AN_MMD                          0x3800
+ #define MII_BNX2_BLK_ADDR_COMBO_IEEEB0                 0xffe0
+ #define MIN_ETHERNET_PACKET_SIZE      60
+ #define MAX_ETHERNET_PACKET_SIZE      1514
+ #define MAX_ETHERNET_JUMBO_PACKET_SIZE        9014
+ #define BNX2_RX_COPY_THRESH           128
+ #define BNX2_MISC_ENABLE_DEFAULT      0x17ffffff
+ #define BNX2_START_UNICAST_ADDRESS_INDEX      4
+ #define BNX2_END_UNICAST_ADDRESS_INDEX                7
+ #define BNX2_MAX_UNICAST_ADDRESSES            (BNX2_END_UNICAST_ADDRESS_INDEX - \
+                                        BNX2_START_UNICAST_ADDRESS_INDEX + 1)
+ #define DMA_READ_CHANS        5
+ #define DMA_WRITE_CHANS       3
+ /* Use CPU native page size up to 16K for the ring sizes.  */
+ #if (PAGE_SHIFT > 14)
+ #define BCM_PAGE_BITS 14
+ #else
+ #define BCM_PAGE_BITS PAGE_SHIFT
+ #endif
+ #define BCM_PAGE_SIZE (1 << BCM_PAGE_BITS)
+ #define TX_DESC_CNT  (BCM_PAGE_SIZE / sizeof(struct tx_bd))
+ #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
+ #define MAX_RX_RINGS  8
+ #define MAX_RX_PG_RINGS       32
+ #define RX_DESC_CNT  (BCM_PAGE_SIZE / sizeof(struct rx_bd))
+ #define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
+ #define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
+ #define MAX_TOTAL_RX_PG_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_PG_RINGS)
+ #define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) ==                       \
+               (MAX_TX_DESC_CNT - 1)) ?                                \
+       (x) + 2 : (x) + 1
+ #define TX_RING_IDX(x) ((x) & MAX_TX_DESC_CNT)
+ #define NEXT_RX_BD(x) (((x) & (MAX_RX_DESC_CNT - 1)) ==                       \
+               (MAX_RX_DESC_CNT - 1)) ?                                \
+       (x) + 2 : (x) + 1
+ #define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
+ #define RX_PG_RING_IDX(x) ((x) & bp->rx_max_pg_ring_idx)
+ #define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4))
+ #define RX_IDX(x) ((x) & MAX_RX_DESC_CNT)
+ /* Context size. */
+ #define CTX_SHIFT                   7
+ #define CTX_SIZE                    (1 << CTX_SHIFT)
+ #define CTX_MASK                    (CTX_SIZE - 1)
+ #define GET_CID_ADDR(_cid)          ((_cid) << CTX_SHIFT)
+ #define GET_CID(_cid_addr)          ((_cid_addr) >> CTX_SHIFT)
+ #define PHY_CTX_SHIFT               6
+ #define PHY_CTX_SIZE                (1 << PHY_CTX_SHIFT)
+ #define PHY_CTX_MASK                (PHY_CTX_SIZE - 1)
+ #define GET_PCID_ADDR(_pcid)        ((_pcid) << PHY_CTX_SHIFT)
+ #define GET_PCID(_pcid_addr)        ((_pcid_addr) >> PHY_CTX_SHIFT)
+ #define MB_KERNEL_CTX_SHIFT         8
+ #define MB_KERNEL_CTX_SIZE          (1 << MB_KERNEL_CTX_SHIFT)
+ #define MB_KERNEL_CTX_MASK          (MB_KERNEL_CTX_SIZE - 1)
+ #define MB_GET_CID_ADDR(_cid)       (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT))
+ #define MAX_CID_CNT                 0x4000
+ #define MAX_CID_ADDR                (GET_CID_ADDR(MAX_CID_CNT))
+ #define INVALID_CID_ADDR            0xffffffff
+ #define TX_CID                16
+ #define TX_TSS_CID    32
+ #define RX_CID                0
+ #define RX_RSS_CID    4
+ #define RX_MAX_RSS_RINGS      7
+ #define RX_MAX_RINGS          (RX_MAX_RSS_RINGS + 1)
+ #define TX_MAX_TSS_RINGS      7
+ #define TX_MAX_RINGS          (TX_MAX_TSS_RINGS + 1)
+ #define MB_TX_CID_ADDR        MB_GET_CID_ADDR(TX_CID)
+ #define MB_RX_CID_ADDR        MB_GET_CID_ADDR(RX_CID)
+ struct sw_bd {
+       struct sk_buff          *skb;
+       struct l2_fhdr          *desc;
+       DEFINE_DMA_UNMAP_ADDR(mapping);
+ };
+ struct sw_pg {
+       struct page             *page;
+       DEFINE_DMA_UNMAP_ADDR(mapping);
+ };
+ struct sw_tx_bd {
+       struct sk_buff          *skb;
+       DEFINE_DMA_UNMAP_ADDR(mapping);
+       unsigned short          is_gso;
+       unsigned short          nr_frags;
+ };
+ #define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
+ #define SW_RXPG_RING_SIZE (sizeof(struct sw_pg) * RX_DESC_CNT)
+ #define RXBD_RING_SIZE (sizeof(struct rx_bd) * RX_DESC_CNT)
+ #define SW_TXBD_RING_SIZE (sizeof(struct sw_tx_bd) * TX_DESC_CNT)
+ #define TXBD_RING_SIZE (sizeof(struct tx_bd) * TX_DESC_CNT)
+ /* Buffered flash (Atmel: AT45DB011B) specific information */
+ #define SEEPROM_PAGE_BITS                     2
+ #define SEEPROM_PHY_PAGE_SIZE                 (1 << SEEPROM_PAGE_BITS)
+ #define SEEPROM_BYTE_ADDR_MASK                        (SEEPROM_PHY_PAGE_SIZE-1)
+ #define SEEPROM_PAGE_SIZE                     4
+ #define SEEPROM_TOTAL_SIZE                    65536
+ #define BUFFERED_FLASH_PAGE_BITS              9
+ #define BUFFERED_FLASH_PHY_PAGE_SIZE          (1 << BUFFERED_FLASH_PAGE_BITS)
+ #define BUFFERED_FLASH_BYTE_ADDR_MASK         (BUFFERED_FLASH_PHY_PAGE_SIZE-1)
+ #define BUFFERED_FLASH_PAGE_SIZE              264
+ #define BUFFERED_FLASH_TOTAL_SIZE             0x21000
+ #define SAIFUN_FLASH_PAGE_BITS                        8
+ #define SAIFUN_FLASH_PHY_PAGE_SIZE            (1 << SAIFUN_FLASH_PAGE_BITS)
+ #define SAIFUN_FLASH_BYTE_ADDR_MASK           (SAIFUN_FLASH_PHY_PAGE_SIZE-1)
+ #define SAIFUN_FLASH_PAGE_SIZE                        256
+ #define SAIFUN_FLASH_BASE_TOTAL_SIZE          65536
+ #define ST_MICRO_FLASH_PAGE_BITS              8
+ #define ST_MICRO_FLASH_PHY_PAGE_SIZE          (1 << ST_MICRO_FLASH_PAGE_BITS)
+ #define ST_MICRO_FLASH_BYTE_ADDR_MASK         (ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
+ #define ST_MICRO_FLASH_PAGE_SIZE              256
+ #define ST_MICRO_FLASH_BASE_TOTAL_SIZE                65536
+ #define BCM5709_FLASH_PAGE_BITS                       8
+ #define BCM5709_FLASH_PHY_PAGE_SIZE           (1 << BCM5709_FLASH_PAGE_BITS)
+ #define BCM5709_FLASH_BYTE_ADDR_MASK          (BCM5709_FLASH_PHY_PAGE_SIZE-1)
+ #define BCM5709_FLASH_PAGE_SIZE                       256
+ #define NVRAM_TIMEOUT_COUNT                   30000
+ #define FLASH_STRAP_MASK                      (BNX2_NVM_CFG1_FLASH_MODE   | \
+                                                BNX2_NVM_CFG1_BUFFER_MODE  | \
+                                                BNX2_NVM_CFG1_PROTECT_MODE | \
+                                                BNX2_NVM_CFG1_FLASH_SIZE)
+ #define FLASH_BACKUP_STRAP_MASK                       (0xf << 26)
+ struct flash_spec {
+       u32 strapping;
+       u32 config1;
+       u32 config2;
+       u32 config3;
+       u32 write1;
+       u32 flags;
+ #define BNX2_NV_BUFFERED      0x00000001
+ #define BNX2_NV_TRANSLATE     0x00000002
+ #define BNX2_NV_WREN          0x00000004
+       u32 page_bits;
+       u32 page_size;
+       u32 addr_mask;
+       u32 total_size;
+       u8  *name;
+ };
+ #define BNX2_MAX_MSIX_HW_VEC  9
+ #define BNX2_MAX_MSIX_VEC     9
+ #ifdef BCM_CNIC
+ #define BNX2_MIN_MSIX_VEC     2
+ #else
+ #define BNX2_MIN_MSIX_VEC     1
+ #endif
+ struct bnx2_irq {
+       irq_handler_t   handler;
+       unsigned int    vector;
+       u8              requested;
+       char            name[IFNAMSIZ + 2];
+ };
+ struct bnx2_tx_ring_info {
+       u32                     tx_prod_bseq;
+       u16                     tx_prod;
+       u32                     tx_bidx_addr;
+       u32                     tx_bseq_addr;
+       struct tx_bd            *tx_desc_ring;
+       struct sw_tx_bd         *tx_buf_ring;
+       u16                     tx_cons;
+       u16                     hw_tx_cons;
+       dma_addr_t              tx_desc_mapping;
+ };
+ struct bnx2_rx_ring_info {
+       u32                     rx_prod_bseq;
+       u16                     rx_prod;
+       u16                     rx_cons;
+       u32                     rx_bidx_addr;
+       u32                     rx_bseq_addr;
+       u32                     rx_pg_bidx_addr;
+       u16                     rx_pg_prod;
+       u16                     rx_pg_cons;
+       struct sw_bd            *rx_buf_ring;
+       struct rx_bd            *rx_desc_ring[MAX_RX_RINGS];
+       struct sw_pg            *rx_pg_ring;
+       struct rx_bd            *rx_pg_desc_ring[MAX_RX_PG_RINGS];
+       dma_addr_t              rx_desc_mapping[MAX_RX_RINGS];
+       dma_addr_t              rx_pg_desc_mapping[MAX_RX_PG_RINGS];
+ };
+ struct bnx2_napi {
+       struct napi_struct      napi            ____cacheline_aligned;
+       struct bnx2             *bp;
+       union {
+               struct status_block             *msi;
+               struct status_block_msix        *msix;
+       } status_blk;
+       u16                     *hw_tx_cons_ptr;
+       u16                     *hw_rx_cons_ptr;
+       u32                     last_status_idx;
+       u32                     int_num;
+ #ifdef BCM_CNIC
+       u32                     cnic_tag;
+       int                     cnic_present;
+ #endif
+       struct bnx2_rx_ring_info        rx_ring;
+       struct bnx2_tx_ring_info        tx_ring;
+ };
+ struct bnx2 {
+       /* Fields used in the tx and intr/napi performance paths are grouped */
+       /* together in the beginning of the structure. */
+       void __iomem            *regview;
+       struct net_device       *dev;
+       struct pci_dev          *pdev;
+       atomic_t                intr_sem;
+       u32                     flags;
+ #define BNX2_FLAG_PCIX                        0x00000001
+ #define BNX2_FLAG_PCI_32BIT           0x00000002
+ #define BNX2_FLAG_MSIX_CAP            0x00000004
+ #define BNX2_FLAG_NO_WOL              0x00000008
+ #define BNX2_FLAG_USING_MSI           0x00000020
+ #define BNX2_FLAG_ASF_ENABLE          0x00000040
+ #define BNX2_FLAG_MSI_CAP             0x00000080
+ #define BNX2_FLAG_ONE_SHOT_MSI                0x00000100
+ #define BNX2_FLAG_PCIE                        0x00000200
+ #define BNX2_FLAG_USING_MSIX          0x00000400
+ #define BNX2_FLAG_USING_MSI_OR_MSIX   (BNX2_FLAG_USING_MSI | \
+                                        BNX2_FLAG_USING_MSIX)
+ #define BNX2_FLAG_JUMBO_BROKEN                0x00000800
+ #define BNX2_FLAG_CAN_KEEP_VLAN               0x00001000
+ #define BNX2_FLAG_BROKEN_STATS                0x00002000
+ #define BNX2_FLAG_AER_ENABLED         0x00004000
+       struct bnx2_napi        bnx2_napi[BNX2_MAX_MSIX_VEC];
+       u32                     rx_buf_use_size;        /* useable size */
+       u32                     rx_buf_size;            /* with alignment */
+       u32                     rx_copy_thresh;
+       u32                     rx_jumbo_thresh;
+       u32                     rx_max_ring_idx;
+       u32                     rx_max_pg_ring_idx;
+       /* TX constants */
+       int             tx_ring_size;
+       u32             tx_wake_thresh;
+ #ifdef BCM_CNIC
+       struct cnic_ops __rcu   *cnic_ops;
+       void                    *cnic_data;
+ #endif
+       /* End of fields used in the performance code paths. */
+       unsigned int            current_interval;
+ #define BNX2_TIMER_INTERVAL           HZ
+ #define BNX2_SERDES_AN_TIMEOUT                (HZ / 3)
+ #define BNX2_SERDES_FORCED_TIMEOUT    (HZ / 10)
+       struct                  timer_list timer;
+       struct work_struct      reset_task;
+       /* Used to synchronize phy accesses. */
+       spinlock_t              phy_lock;
+       spinlock_t              indirect_lock;
+       u32                     phy_flags;
+ #define BNX2_PHY_FLAG_SERDES                  0x00000001
+ #define BNX2_PHY_FLAG_CRC_FIX                 0x00000002
+ #define BNX2_PHY_FLAG_PARALLEL_DETECT         0x00000004
+ #define BNX2_PHY_FLAG_2_5G_CAPABLE            0x00000008
+ #define BNX2_PHY_FLAG_INT_MODE_MASK           0x00000300
+ #define BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING   0x00000100
+ #define BNX2_PHY_FLAG_INT_MODE_LINK_READY     0x00000200
+ #define BNX2_PHY_FLAG_DIS_EARLY_DAC           0x00000400
+ #define BNX2_PHY_FLAG_REMOTE_PHY_CAP          0x00000800
+ #define BNX2_PHY_FLAG_FORCED_DOWN             0x00001000
+ #define BNX2_PHY_FLAG_NO_PARALLEL             0x00002000
+       u32                     mii_bmcr;
+       u32                     mii_bmsr;
+       u32                     mii_bmsr1;
+       u32                     mii_adv;
+       u32                     mii_lpa;
+       u32                     mii_up1;
+       u32                     chip_id;
+       /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
+ #define CHIP_NUM(bp)                  (((bp)->chip_id) & 0xffff0000)
+ #define CHIP_NUM_5706                 0x57060000
+ #define CHIP_NUM_5708                 0x57080000
+ #define CHIP_NUM_5709                 0x57090000
+ #define CHIP_REV(bp)                  (((bp)->chip_id) & 0x0000f000)
+ #define CHIP_REV_Ax                   0x00000000
+ #define CHIP_REV_Bx                   0x00001000
+ #define CHIP_REV_Cx                   0x00002000
+ #define CHIP_METAL(bp)                        (((bp)->chip_id) & 0x00000ff0)
+ #define CHIP_BONDING(bp)              (((bp)->chip_id) & 0x0000000f)
+ #define CHIP_ID(bp)                   (((bp)->chip_id) & 0xfffffff0)
+ #define CHIP_ID_5706_A0                       0x57060000
+ #define CHIP_ID_5706_A1                       0x57060010
+ #define CHIP_ID_5706_A2                       0x57060020
+ #define CHIP_ID_5708_A0                       0x57080000
+ #define CHIP_ID_5708_B0                       0x57081000
+ #define CHIP_ID_5708_B1                       0x57081010
+ #define CHIP_ID_5709_A0                       0x57090000
+ #define CHIP_ID_5709_A1                       0x57090010
+ #define CHIP_BOND_ID(bp)              (((bp)->chip_id) & 0xf)
+ /* A serdes chip will have the first bit of the bond id set. */
+ #define CHIP_BOND_ID_SERDES_BIT               0x01
+       u32                     phy_addr;
+       u32                     phy_id;
+       u16                     bus_speed_mhz;
+       u8                      wol;
+       u8                      pad;
+       u16                     fw_wr_seq;
+       u16                     fw_drv_pulse_wr_seq;
+       int                     rx_max_ring;
+       int                     rx_ring_size;
+       int                     rx_max_pg_ring;
+       int                     rx_pg_ring_size;
+       u16                     tx_quick_cons_trip;
+       u16                     tx_quick_cons_trip_int;
+       u16                     rx_quick_cons_trip;
+       u16                     rx_quick_cons_trip_int;
+       u16                     comp_prod_trip;
+       u16                     comp_prod_trip_int;
+       u16                     tx_ticks;
+       u16                     tx_ticks_int;
+       u16                     com_ticks;
+       u16                     com_ticks_int;
+       u16                     cmd_ticks;
+       u16                     cmd_ticks_int;
+       u16                     rx_ticks;
+       u16                     rx_ticks_int;
+       u32                     stats_ticks;
+       dma_addr_t              status_blk_mapping;
+       struct statistics_block *stats_blk;
+       struct statistics_block *temp_stats_blk;
+       dma_addr_t              stats_blk_mapping;
+       int                     ctx_pages;
+       void                    *ctx_blk[4];
+       dma_addr_t              ctx_blk_mapping[4];
+       u32                     hc_cmd;
+       u32                     rx_mode;
+       u16                     req_line_speed;
+       u8                      req_duplex;
+       u8                      phy_port;
+       u8                      link_up;
+       u16                     line_speed;
+       u8                      duplex;
+       u8                      flow_ctrl;      /* actual flow ctrl settings */
+                                               /* may be different from     */
+                                               /* req_flow_ctrl if autoneg  */
+       u32                     advertising;
+       u8                      req_flow_ctrl;  /* flow ctrl advertisement */
+                                               /* settings or forced      */
+                                               /* settings                */
+       u8                      autoneg;
+ #define AUTONEG_SPEED         1
+ #define AUTONEG_FLOW_CTRL     2
+       u8                      loopback;
+ #define MAC_LOOPBACK          1
+ #define PHY_LOOPBACK          2
+       u8                      serdes_an_pending;
+       u8                      mac_addr[8];
+       u32                     shmem_base;
+       char                    fw_version[32];
+       int                     pm_cap;
+       int                     pcix_cap;
+       const struct flash_spec *flash_info;
+       u32                     flash_size;
+       int                     status_stats_size;
+       struct bnx2_irq         irq_tbl[BNX2_MAX_MSIX_VEC];
+       int                     irq_nvecs;
+       u8                      num_tx_rings;
+       u8                      num_rx_rings;
+       u32                     leds_save;
+       u32                     idle_chk_status_idx;
+ #ifdef BCM_CNIC
+       struct mutex            cnic_lock;
+       struct cnic_eth_dev     cnic_eth_dev;
+ #endif
+       const struct firmware   *mips_firmware;
+       const struct firmware   *rv2p_firmware;
+ };
+ #define REG_RD(bp, offset)                                    \
+       readl(bp->regview + offset)
+ #define REG_WR(bp, offset, val)                                       \
+       writel(val, bp->regview + offset)
+ #define REG_WR16(bp, offset, val)                             \
+       writew(val, bp->regview + offset)
+ struct cpu_reg {
+       u32 mode;
+       u32 mode_value_halt;
+       u32 mode_value_sstep;
+       u32 state;
+       u32 state_value_clear;
+       u32 gpr0;
+       u32 evmask;
+       u32 pc;
+       u32 inst;
+       u32 bp;
+       u32 spad_base;
+       u32 mips_view_base;
+ };
+ struct bnx2_fw_file_section {
+       __be32 addr;
+       __be32 len;
+       __be32 offset;
+ };
+ struct bnx2_mips_fw_file_entry {
+       __be32 start_addr;
+       struct bnx2_fw_file_section text;
+       struct bnx2_fw_file_section data;
+       struct bnx2_fw_file_section rodata;
+ };
+ struct bnx2_rv2p_fw_file_entry {
+       struct bnx2_fw_file_section rv2p;
+       __be32 fixup[8];
+ };
+ struct bnx2_mips_fw_file {
+       struct bnx2_mips_fw_file_entry com;
+       struct bnx2_mips_fw_file_entry cp;
+       struct bnx2_mips_fw_file_entry rxp;
+       struct bnx2_mips_fw_file_entry tpat;
+       struct bnx2_mips_fw_file_entry txp;
+ };
+ struct bnx2_rv2p_fw_file {
+       struct bnx2_rv2p_fw_file_entry proc1;
+       struct bnx2_rv2p_fw_file_entry proc2;
+ };
+ #define RV2P_P1_FIXUP_PAGE_SIZE_IDX           0
+ #define RV2P_BD_PAGE_SIZE_MSK                 0xffff
+ #define RV2P_BD_PAGE_SIZE                     ((BCM_PAGE_SIZE / 16) - 1)
+ #define RV2P_PROC1                              0
+ #define RV2P_PROC2                              1
+ /* This value (in milliseconds) determines the frequency of the driver
+  * issuing the PULSE message code.  The firmware monitors this periodic
+  * pulse to determine when to switch to an OS-absent mode. */
+ #define BNX2_DRV_PULSE_PERIOD_MS                 250
+ /* This value (in milliseconds) determines how long the driver should
+  * wait for an acknowledgement from the firmware before timing out.  Once
+  * the firmware has timed out, the driver will assume there is no firmware
+  * running and there won't be any firmware-driver synchronization during a
+  * driver reset. */
+ #define BNX2_FW_ACK_TIME_OUT_MS                  1000
+ #define BNX2_DRV_RESET_SIGNATURE              0x00000000
+ #define BNX2_DRV_RESET_SIGNATURE_MAGIC                 0x4841564b /* HAVK */
+ //#define DRV_RESET_SIGNATURE_MAGIC            0x47495352 /* RSIG */
+ #define BNX2_DRV_MB                           0x00000004
+ #define BNX2_DRV_MSG_CODE                      0xff000000
+ #define BNX2_DRV_MSG_CODE_RESET                        0x01000000
+ #define BNX2_DRV_MSG_CODE_UNLOAD               0x02000000
+ #define BNX2_DRV_MSG_CODE_SHUTDOWN             0x03000000
+ #define BNX2_DRV_MSG_CODE_SUSPEND_WOL          0x04000000
+ #define BNX2_DRV_MSG_CODE_FW_TIMEOUT           0x05000000
+ #define BNX2_DRV_MSG_CODE_PULSE                        0x06000000
+ #define BNX2_DRV_MSG_CODE_DIAG                         0x07000000
+ #define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL       0x09000000
+ #define BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN                0x0b000000
+ #define BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE     0x0d000000
+ #define BNX2_DRV_MSG_CODE_CMD_SET_LINK                 0x10000000
+ #define BNX2_DRV_MSG_DATA                      0x00ff0000
+ #define BNX2_DRV_MSG_DATA_WAIT0                        0x00010000
+ #define BNX2_DRV_MSG_DATA_WAIT1                        0x00020000
+ #define BNX2_DRV_MSG_DATA_WAIT2                        0x00030000
+ #define BNX2_DRV_MSG_DATA_WAIT3                        0x00040000
+ #define BNX2_DRV_MSG_SEQ                       0x0000ffff
+ #define BNX2_FW_MB                            0x00000008
+ #define BNX2_FW_MSG_ACK                                0x0000ffff
+ #define BNX2_FW_MSG_STATUS_MASK                        0x00ff0000
+ #define BNX2_FW_MSG_STATUS_OK                  0x00000000
+ #define BNX2_FW_MSG_STATUS_FAILURE             0x00ff0000
+ #define BNX2_LINK_STATUS                      0x0000000c
+ #define BNX2_LINK_STATUS_INIT_VALUE            0xffffffff
+ #define BNX2_LINK_STATUS_LINK_UP               0x1
+ #define BNX2_LINK_STATUS_LINK_DOWN             0x0
+ #define BNX2_LINK_STATUS_SPEED_MASK            0x1e
+ #define BNX2_LINK_STATUS_AN_INCOMPLETE                 (0<<1)
+ #define BNX2_LINK_STATUS_10HALF                        (1<<1)
+ #define BNX2_LINK_STATUS_10FULL                        (2<<1)
+ #define BNX2_LINK_STATUS_100HALF               (3<<1)
+ #define BNX2_LINK_STATUS_100BASE_T4            (4<<1)
+ #define BNX2_LINK_STATUS_100FULL               (5<<1)
+ #define BNX2_LINK_STATUS_1000HALF              (6<<1)
+ #define BNX2_LINK_STATUS_1000FULL              (7<<1)
+ #define BNX2_LINK_STATUS_2500HALF              (8<<1)
+ #define BNX2_LINK_STATUS_2500FULL              (9<<1)
+ #define BNX2_LINK_STATUS_AN_ENABLED            (1<<5)
+ #define BNX2_LINK_STATUS_AN_COMPLETE           (1<<6)
+ #define BNX2_LINK_STATUS_PARALLEL_DET          (1<<7)
+ #define BNX2_LINK_STATUS_RESERVED              (1<<8)
+ #define BNX2_LINK_STATUS_PARTNER_AD_1000FULL   (1<<9)
+ #define BNX2_LINK_STATUS_PARTNER_AD_1000HALF   (1<<10)
+ #define BNX2_LINK_STATUS_PARTNER_AD_100BT4     (1<<11)
+ #define BNX2_LINK_STATUS_PARTNER_AD_100FULL    (1<<12)
+ #define BNX2_LINK_STATUS_PARTNER_AD_100HALF    (1<<13)
+ #define BNX2_LINK_STATUS_PARTNER_AD_10FULL     (1<<14)
+ #define BNX2_LINK_STATUS_PARTNER_AD_10HALF     (1<<15)
+ #define BNX2_LINK_STATUS_TX_FC_ENABLED                 (1<<16)
+ #define BNX2_LINK_STATUS_RX_FC_ENABLED                 (1<<17)
+ #define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP         (1<<18)
+ #define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP        (1<<19)
+ #define BNX2_LINK_STATUS_SERDES_LINK           (1<<20)
+ #define BNX2_LINK_STATUS_PARTNER_AD_2500FULL   (1<<21)
+ #define BNX2_LINK_STATUS_PARTNER_AD_2500HALF   (1<<22)
+ #define BNX2_LINK_STATUS_HEART_BEAT_EXPIRED    (1<<31)
+ #define BNX2_DRV_PULSE_MB                     0x00000010
+ #define BNX2_DRV_PULSE_SEQ_MASK                        0x00007fff
+ /* Indicate to the firmware not to go into the
+  * OS absent when it is not getting driver pulse.
+  * This is used for debugging. */
+ #define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE      0x00080000
+ #define BNX2_DRV_MB_ARG0                      0x00000014
+ #define BNX2_NETLINK_SET_LINK_SPEED_10HALF     (1<<0)
+ #define BNX2_NETLINK_SET_LINK_SPEED_10FULL     (1<<1)
+ #define BNX2_NETLINK_SET_LINK_SPEED_10                 \
+       (BNX2_NETLINK_SET_LINK_SPEED_10HALF |    \
+        BNX2_NETLINK_SET_LINK_SPEED_10FULL)
+ #define BNX2_NETLINK_SET_LINK_SPEED_100HALF    (1<<2)
+ #define BNX2_NETLINK_SET_LINK_SPEED_100FULL    (1<<3)
+ #define BNX2_NETLINK_SET_LINK_SPEED_100                \
+       (BNX2_NETLINK_SET_LINK_SPEED_100HALF |   \
+        BNX2_NETLINK_SET_LINK_SPEED_100FULL)
+ #define BNX2_NETLINK_SET_LINK_SPEED_1GHALF     (1<<4)
+ #define BNX2_NETLINK_SET_LINK_SPEED_1GFULL     (1<<5)
+ #define BNX2_NETLINK_SET_LINK_SPEED_2G5HALF    (1<<6)
+ #define BNX2_NETLINK_SET_LINK_SPEED_2G5FULL    (1<<7)
+ #define BNX2_NETLINK_SET_LINK_SPEED_10GHALF    (1<<8)
+ #define BNX2_NETLINK_SET_LINK_SPEED_10GFULL    (1<<9)
+ #define BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG   (1<<10)
+ #define BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE   (1<<11)
+ #define BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE     (1<<12)
+ #define BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE    (1<<13)
+ #define BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED         (1<<14)
+ #define BNX2_NETLINK_SET_LINK_PHY_RESET                (1<<15)
+ #define BNX2_DEV_INFO_SIGNATURE                       0x00000020
+ #define BNX2_DEV_INFO_SIGNATURE_MAGIC          0x44564900
+ #define BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK     0xffffff00
+ #define BNX2_DEV_INFO_FEATURE_CFG_VALID                0x01
+ #define BNX2_DEV_INFO_SECONDARY_PORT           0x80
+ #define BNX2_DEV_INFO_DRV_ALWAYS_ALIVE                 0x40
+ #define BNX2_SHARED_HW_CFG_PART_NUM           0x00000024
+ #define BNX2_SHARED_HW_CFG_POWER_DISSIPATED   0x00000034
+ #define BNX2_SHARED_HW_CFG_POWER_STATE_D3_MASK         0xff000000
+ #define BNX2_SHARED_HW_CFG_POWER_STATE_D2_MASK         0xff0000
+ #define BNX2_SHARED_HW_CFG_POWER_STATE_D1_MASK         0xff00
+ #define BNX2_SHARED_HW_CFG_POWER_STATE_D0_MASK         0xff
+ #define BNX2_SHARED_HW_CFG POWER_CONSUMED     0x00000038
+ #define BNX2_SHARED_HW_CFG_CONFIG             0x0000003c
+ #define BNX2_SHARED_HW_CFG_DESIGN_NIC          0
+ #define BNX2_SHARED_HW_CFG_DESIGN_LOM          0x1
+ #define BNX2_SHARED_HW_CFG_PHY_COPPER          0
+ #define BNX2_SHARED_HW_CFG_PHY_FIBER           0x2
+ #define BNX2_SHARED_HW_CFG_PHY_2_5G            0x20
+ #define BNX2_SHARED_HW_CFG_PHY_BACKPLANE       0x40
+ #define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS         8
+ #define BNX2_SHARED_HW_CFG_LED_MODE_MASK       0x300
+ #define BNX2_SHARED_HW_CFG_LED_MODE_MAC                0
+ #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY1      0x100
+ #define BNX2_SHARED_HW_CFG_LED_MODE_GPHY2      0x200
+ #define BNX2_SHARED_HW_CFG_GIG_LINK_ON_VAUX    0x8000
+ #define BNX2_SHARED_HW_CFG_CONFIG2            0x00000040
+ #define BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK      0x00fff000
+ #define BNX2_DEV_INFO_BC_REV                  0x0000004c
+ #define BNX2_PORT_HW_CFG_MAC_UPPER            0x00000050
+ #define BNX2_PORT_HW_CFG_UPPERMAC_MASK                 0xffff
+ #define BNX2_PORT_HW_CFG_MAC_LOWER            0x00000054
+ #define BNX2_PORT_HW_CFG_CONFIG                       0x00000058
+ #define BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK       0x0000ffff
+ #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK    0x001f0000
+ #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN      0x00000000
+ #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G      0x00030000
+ #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_2_5G    0x00040000
+ #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER      0x00000068
+ #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER      0x0000006c
+ #define BNX2_PORT_HW_CFG_IMD_MAC_B_UPPER      0x00000070
+ #define BNX2_PORT_HW_CFG_IMD_MAC_B_LOWER      0x00000074
+ #define BNX2_PORT_HW_CFG_ISCSI_MAC_UPPER      0x00000078
+ #define BNX2_PORT_HW_CFG_ISCSI_MAC_LOWER      0x0000007c
+ #define BNX2_DEV_INFO_PER_PORT_HW_CONFIG2     0x000000b4
+ #define BNX2_DEV_INFO_FORMAT_REV              0x000000c4
+ #define BNX2_DEV_INFO_FORMAT_REV_MASK          0xff000000
+ #define BNX2_DEV_INFO_FORMAT_REV_ID            ('A' << 24)
+ #define BNX2_SHARED_FEATURE                   0x000000c8
+ #define BNX2_SHARED_FEATURE_MASK               0xffffffff
+ #define BNX2_PORT_FEATURE                     0x000000d8
+ #define BNX2_PORT2_FEATURE                    0x00000014c
+ #define BNX2_PORT_FEATURE_WOL_ENABLED          0x01000000
+ #define BNX2_PORT_FEATURE_MBA_ENABLED          0x02000000
+ #define BNX2_PORT_FEATURE_ASF_ENABLED          0x04000000
+ #define BNX2_PORT_FEATURE_IMD_ENABLED          0x08000000
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_MASK       0xf
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_DISABLED   0x0
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_64K                0x1
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_128K       0x2
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_256K       0x3
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_512K       0x4
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_1M                 0x5
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_2M                 0x6
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_4M                 0x7
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_8M                 0x8
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_16M                0x9
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_32M                0xa
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_64M                0xb
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_128M       0xc
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_256M       0xd
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_512M       0xe
+ #define BNX2_PORT_FEATURE_BAR1_SIZE_1G                 0xf
+ #define BNX2_PORT_FEATURE_WOL                 0xdc
+ #define BNX2_PORT2_FEATURE_WOL                        0x150
+ #define BNX2_PORT_FEATURE_WOL_DEFAULT_SHIFT_BITS       4
+ #define BNX2_PORT_FEATURE_WOL_DEFAULT_MASK     0x30
+ #define BNX2_PORT_FEATURE_WOL_DEFAULT_DISABLE  0
+ #define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC    0x10
+ #define BNX2_PORT_FEATURE_WOL_DEFAULT_ACPI     0x20
+ #define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI   0x30
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_MASK  0xf
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_AUTONEG       0
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10HALF        1
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10FULL        2
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000HALF      5
+ #define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000FULL      6
+ #define BNX2_PORT_FEATURE_WOL_AUTONEG_ADVERTISE_1000   0x40
+ #define BNX2_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400
+ #define BNX2_PORT_FEATURE_WOL_RESERVED_ASYM_PAUSE_CAP  0x800
+ #define BNX2_PORT_FEATURE_MBA                 0xe0
+ #define BNX2_PORT2_FEATURE_MBA                        0x154
+ #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT_BITS       0
+ #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK     0x3
+ #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE      0
+ #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL      1
+ #define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP    2
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_SHIFT_BITS    2
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_MASK  0x3c
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_AUTONEG       0
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10HALF        0x4
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10FULL        0x8
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100HALF       0xc
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100FULL       0x10
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000HALF      0x14
+ #define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000FULL      0x18
+ #define BNX2_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE      0x40
+ #define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_S    0
+ #define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_B    0x80
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT_BITS  8
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK        0xff00
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED    0
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1K  0x100
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2K  0x200
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4K  0x300
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8K  0x400
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16K         0x500
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_32K         0x600
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_64K         0x700
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_128K        0x800
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_256K        0x900
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_512K        0xa00
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1M  0xb00
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2M  0xc00
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4M  0xd00
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8M  0xe00
+ #define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16M         0xf00
+ #define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT_BITS   16
+ #define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_MASK         0xf0000
+ #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT_BITS        20
+ #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK      0x300000
+ #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO      0
+ #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS       0x100000
+ #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H    0x200000
+ #define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H    0x300000
+ #define BNX2_PORT_FEATURE_IMD                 0xe4
+ #define BNX2_PORT2_FEATURE_IMD                        0x158
+ #define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_DEFAULT    0
+ #define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_ENABLE     1
+ #define BNX2_PORT_FEATURE_VLAN                        0xe8
+ #define BNX2_PORT2_FEATURE_VLAN                       0x15c
+ #define BNX2_PORT_FEATURE_MBA_VLAN_TAG_MASK    0xffff
+ #define BNX2_PORT_FEATURE_MBA_VLAN_ENABLE      0x10000
+ #define BNX2_MFW_VER_PTR                      0x00000014c
+ #define BNX2_BC_STATE_RESET_TYPE              0x000001c0
+ #define BNX2_BC_STATE_RESET_TYPE_SIG           0x00005254
+ #define BNX2_BC_STATE_RESET_TYPE_SIG_MASK      0x0000ffff
+ #define BNX2_BC_STATE_RESET_TYPE_NONE  (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         0x00010000)
+ #define BNX2_BC_STATE_RESET_TYPE_PCI   (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         0x00020000)
+ #define BNX2_BC_STATE_RESET_TYPE_VAUX  (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         0x00030000)
+ #define BNX2_BC_STATE_RESET_TYPE_DRV_MASK      DRV_MSG_CODE
+ #define BNX2_BC_STATE_RESET_TYPE_DRV_RESET (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                           DRV_MSG_CODE_RESET)
+ #define BNX2_BC_STATE_RESET_TYPE_DRV_UNLOAD (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                            DRV_MSG_CODE_UNLOAD)
+ #define BNX2_BC_STATE_RESET_TYPE_DRV_SHUTDOWN (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                              DRV_MSG_CODE_SHUTDOWN)
+ #define BNX2_BC_STATE_RESET_TYPE_DRV_WOL (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                         DRV_MSG_CODE_WOL)
+ #define BNX2_BC_STATE_RESET_TYPE_DRV_DIAG (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                          DRV_MSG_CODE_DIAG)
+ #define BNX2_BC_STATE_RESET_TYPE_VALUE(msg) (BNX2_BC_STATE_RESET_TYPE_SIG | \
+                                            (msg))
+ #define BNX2_BC_STATE                         0x000001c4
+ #define BNX2_BC_STATE_ERR_MASK                         0x0000ff00
+ #define BNX2_BC_STATE_SIGN                     0x42530000
+ #define BNX2_BC_STATE_SIGN_MASK                        0xffff0000
+ #define BNX2_BC_STATE_BC1_START                        (BNX2_BC_STATE_SIGN | 0x1)
+ #define BNX2_BC_STATE_GET_NVM_CFG1             (BNX2_BC_STATE_SIGN | 0x2)
+ #define BNX2_BC_STATE_PROG_BAR                         (BNX2_BC_STATE_SIGN | 0x3)
+ #define BNX2_BC_STATE_INIT_VID                         (BNX2_BC_STATE_SIGN | 0x4)
+ #define BNX2_BC_STATE_GET_NVM_CFG2             (BNX2_BC_STATE_SIGN | 0x5)
+ #define BNX2_BC_STATE_APPLY_WKARND             (BNX2_BC_STATE_SIGN | 0x6)
+ #define BNX2_BC_STATE_LOAD_BC2                         (BNX2_BC_STATE_SIGN | 0x7)
+ #define BNX2_BC_STATE_GOING_BC2                        (BNX2_BC_STATE_SIGN | 0x8)
+ #define BNX2_BC_STATE_GOING_DIAG               (BNX2_BC_STATE_SIGN | 0x9)
+ #define BNX2_BC_STATE_RT_FINAL_INIT            (BNX2_BC_STATE_SIGN | 0x81)
+ #define BNX2_BC_STATE_RT_WKARND                        (BNX2_BC_STATE_SIGN | 0x82)
+ #define BNX2_BC_STATE_RT_DRV_PULSE             (BNX2_BC_STATE_SIGN | 0x83)
+ #define BNX2_BC_STATE_RT_FIOEVTS               (BNX2_BC_STATE_SIGN | 0x84)
+ #define BNX2_BC_STATE_RT_DRV_CMD               (BNX2_BC_STATE_SIGN | 0x85)
+ #define BNX2_BC_STATE_RT_LOW_POWER             (BNX2_BC_STATE_SIGN | 0x86)
+ #define BNX2_BC_STATE_RT_SET_WOL               (BNX2_BC_STATE_SIGN | 0x87)
+ #define BNX2_BC_STATE_RT_OTHER_FW              (BNX2_BC_STATE_SIGN | 0x88)
+ #define BNX2_BC_STATE_RT_GOING_D3              (BNX2_BC_STATE_SIGN | 0x89)
+ #define BNX2_BC_STATE_ERR_BAD_VERSION          (BNX2_BC_STATE_SIGN | 0x0100)
+ #define BNX2_BC_STATE_ERR_BAD_BC2_CRC          (BNX2_BC_STATE_SIGN | 0x0200)
+ #define BNX2_BC_STATE_ERR_BC1_LOOP             (BNX2_BC_STATE_SIGN | 0x0300)
+ #define BNX2_BC_STATE_ERR_UNKNOWN_CMD          (BNX2_BC_STATE_SIGN | 0x0400)
+ #define BNX2_BC_STATE_ERR_DRV_DEAD             (BNX2_BC_STATE_SIGN | 0x0500)
+ #define BNX2_BC_STATE_ERR_NO_RXP               (BNX2_BC_STATE_SIGN | 0x0600)
+ #define BNX2_BC_STATE_ERR_TOO_MANY_RBUF                (BNX2_BC_STATE_SIGN | 0x0700)
+ #define BNX2_BC_STATE_CONDITION                       0x000001c8
+ #define BNX2_CONDITION_MFW_RUN_UNKNOWN                 0x00000000
+ #define BNX2_CONDITION_MFW_RUN_IPMI            0x00002000
+ #define BNX2_CONDITION_MFW_RUN_UMP             0x00004000
+ #define BNX2_CONDITION_MFW_RUN_NCSI            0x00006000
+ #define BNX2_CONDITION_MFW_RUN_NONE            0x0000e000
+ #define BNX2_CONDITION_MFW_RUN_MASK            0x0000e000
+ #define BNX2_BC_STATE_DEBUG_CMD                       0x1dc
+ #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE     0x42440000
+ #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK        0xffff0000
+ #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK         0xffff
+ #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_INFINITE         0xffff
+ #define BNX2_FW_EVT_CODE_MB                   0x354
+ #define BNX2_FW_EVT_CODE_SW_TIMER_EXPIRATION_EVENT 0x00000000
+ #define BNX2_FW_EVT_CODE_LINK_EVENT            0x00000001
+ #define BNX2_DRV_ACK_CAP_MB                   0x364
+ #define BNX2_DRV_ACK_CAP_SIGNATURE             0x35450000
+ #define BNX2_CAPABILITY_SIGNATURE_MASK                 0xFFFF0000
+ #define BNX2_FW_CAP_MB                                0x368
+ #define BNX2_FW_CAP_SIGNATURE                  0xaa550000
+ #define BNX2_FW_ACK_DRV_SIGNATURE              0x52500000
+ #define BNX2_FW_CAP_SIGNATURE_MASK             0xffff0000
+ #define BNX2_FW_CAP_REMOTE_PHY_CAPABLE                 0x00000001
+ #define BNX2_FW_CAP_REMOTE_PHY_PRESENT                 0x00000002
+ #define BNX2_FW_CAP_MFW_CAN_KEEP_VLAN          0x00000008
+ #define BNX2_FW_CAP_BC_CAN_KEEP_VLAN           0x00000010
+ #define BNX2_FW_CAP_CAN_KEEP_VLAN     (BNX2_FW_CAP_BC_CAN_KEEP_VLAN | \
+                                        BNX2_FW_CAP_MFW_CAN_KEEP_VLAN)
+ #define BNX2_RPHY_SIGNATURE                   0x36c
+ #define BNX2_RPHY_LOAD_SIGNATURE               0x5a5a5a5a
+ #define BNX2_RPHY_FLAGS                               0x370
+ #define BNX2_RPHY_SERDES_LINK                 0x374
+ #define BNX2_RPHY_COPPER_LINK                 0x378
+ #define BNX2_ISCSI_INITIATOR                  0x3dc
+ #define BNX2_ISCSI_INITIATOR_EN                        0x00080000
+ #define BNX2_ISCSI_MAX_CONN                   0x3e4
+ #define BNX2_ISCSI_MAX_CONN_MASK               0xffff0000
+ #define BNX2_ISCSI_MAX_CONN_SHIFT              16
+ #define HOST_VIEW_SHMEM_BASE                  0x167c00
+ #define DP_SHMEM_LINE(bp, offset)                                     \
+       netdev_err(bp->dev, "DEBUG: %08x: %08x %08x %08x %08x\n",       \
+                  offset,                                              \
+                  bnx2_shmem_rd(bp, offset),                           \
+                  bnx2_shmem_rd(bp, offset + 4),                       \
+                  bnx2_shmem_rd(bp, offset + 8),                       \
+                  bnx2_shmem_rd(bp, offset + 12))
+ #endif
index 0000000,092c3fa..25b8dee
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,260 +1,257 @@@
+ /*
+       drivers/net/tulip/21142.c
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
 -
+       DC21143 manual "21143 PCI/CardBus 10/100Mb/s Ethernet LAN Controller
+       Hardware Reference Manual" is currently available at :
+       http://developer.intel.com/design/network/manuals/278074.htm
+       Please submit bugs to http://bugzilla.kernel.org/ .
+ */
+ #include <linux/delay.h>
+ #include "tulip.h"
+ static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
+ u16 t21142_csr14[] =      { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
+ static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
+ /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
+    of available transceivers.  */
+ void t21142_media_task(struct work_struct *work)
+ {
+       struct tulip_private *tp =
+               container_of(work, struct tulip_private, media_work);
+       struct net_device *dev = tp->dev;
+       void __iomem *ioaddr = tp->base_addr;
+       int csr12 = ioread32(ioaddr + CSR12);
+       int next_tick = 60*HZ;
+       int new_csr6 = 0;
+       int csr14 = ioread32(ioaddr + CSR14);
+       /* CSR12[LS10,LS100] are not reliable during autonegotiation */
+       if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
+               csr12 |= 6;
+       if (tulip_debug > 2)
+               dev_info(&dev->dev, "21143 negotiation status %08x, %s\n",
+                        csr12, medianame[dev->if_port]);
+       if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+               if (tulip_check_duplex(dev) < 0) {
+                       netif_carrier_off(dev);
+                       next_tick = 3*HZ;
+               } else {
+                       netif_carrier_on(dev);
+                       next_tick = 60*HZ;
+               }
+       } else if (tp->nwayset) {
+               /* Don't screw up a negotiated session! */
+               if (tulip_debug > 1)
+                       dev_info(&dev->dev,
+                                "Using NWay-set %s media, csr12 %08x\n",
+                                medianame[dev->if_port], csr12);
+       } else if (tp->medialock) {
+                       ;
+       } else if (dev->if_port == 3) {
+               if (csr12 & 2) {        /* No 100mbps link beat, revert to 10mbps. */
+                       if (tulip_debug > 1)
+                               dev_info(&dev->dev,
+                                        "No 21143 100baseTx link beat, %08x, trying NWay\n",
+                                        csr12);
+                       t21142_start_nway(dev);
+                       next_tick = 3*HZ;
+               }
+       } else if ((csr12 & 0x7000) != 0x5000) {
+               /* Negotiation failed.  Search media types. */
+               if (tulip_debug > 1)
+                       dev_info(&dev->dev,
+                                "21143 negotiation failed, status %08x\n",
+                                csr12);
+               if (!(csr12 & 4)) {             /* 10mbps link beat good. */
+                       new_csr6 = 0x82420000;
+                       dev->if_port = 0;
+                       iowrite32(0, ioaddr + CSR13);
+                       iowrite32(0x0003FFFF, ioaddr + CSR14);
+                       iowrite16(t21142_csr15[dev->if_port], ioaddr + CSR15);
+                       iowrite32(t21142_csr13[dev->if_port], ioaddr + CSR13);
+               } else {
+                       /* Select 100mbps port to check for link beat. */
+                       new_csr6 = 0x83860000;
+                       dev->if_port = 3;
+                       iowrite32(0, ioaddr + CSR13);
+                       iowrite32(0x0003FFFF, ioaddr + CSR14);
+                       iowrite16(8, ioaddr + CSR15);
+                       iowrite32(1, ioaddr + CSR13);
+               }
+               if (tulip_debug > 1)
+                       dev_info(&dev->dev, "Testing new 21143 media %s\n",
+                                medianame[dev->if_port]);
+               if (new_csr6 != (tp->csr6 & ~0x00D5)) {
+                       tp->csr6 &= 0x00D5;
+                       tp->csr6 |= new_csr6;
+                       iowrite32(0x0301, ioaddr + CSR12);
+                       tulip_restart_rxtx(tp);
+               }
+               next_tick = 3*HZ;
+       }
+       /* mod_timer synchronizes us with potential add_timer calls
+        * from interrupts.
+        */
+       mod_timer(&tp->timer, RUN_AT(next_tick));
+ }
+ void t21142_start_nway(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int csr14 = ((tp->sym_advertise & 0x0780) << 9)  |
+               ((tp->sym_advertise & 0x0020) << 1) | 0xffbf;
+       dev->if_port = 0;
+       tp->nway = tp->mediasense = 1;
+       tp->nwayset = tp->lpar = 0;
+       if (tulip_debug > 1)
+               netdev_dbg(dev, "Restarting 21143 autonegotiation, csr14=%08x\n",
+                          csr14);
+       iowrite32(0x0001, ioaddr + CSR13);
+       udelay(100);
+       iowrite32(csr14, ioaddr + CSR14);
+       tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0);
+       iowrite32(tp->csr6, ioaddr + CSR6);
+       if (tp->mtable  &&  tp->mtable->csr15dir) {
+               iowrite32(tp->mtable->csr15dir, ioaddr + CSR15);
+               iowrite32(tp->mtable->csr15val, ioaddr + CSR15);
+       } else
+               iowrite16(0x0008, ioaddr + CSR15);
+       iowrite32(0x1301, ioaddr + CSR12);              /* Trigger NWAY. */
+ }
+ void t21142_lnk_change(struct net_device *dev, int csr5)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int csr12 = ioread32(ioaddr + CSR12);
+       int csr14 = ioread32(ioaddr + CSR14);
+       /* CSR12[LS10,LS100] are not reliable during autonegotiation */
+       if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
+               csr12 |= 6;
+       if (tulip_debug > 1)
+               dev_info(&dev->dev,
+                        "21143 link status interrupt %08x, CSR5 %x, %08x\n",
+                        csr12, csr5, csr14);
+       /* If NWay finished and we have a negotiated partner capability. */
+       if (tp->nway  &&  !tp->nwayset  &&  (csr12 & 0x7000) == 0x5000) {
+               int setup_done = 0;
+               int negotiated = tp->sym_advertise & (csr12 >> 16);
+               tp->lpar = csr12 >> 16;
+               tp->nwayset = 1;
+               /* If partner cannot negotiate, it is 10Mbps Half Duplex */
+               if (!(csr12 & 0x8000))          dev->if_port = 0;
+               else if (negotiated & 0x0100)   dev->if_port = 5;
+               else if (negotiated & 0x0080)   dev->if_port = 3;
+               else if (negotiated & 0x0040)   dev->if_port = 4;
+               else if (negotiated & 0x0020)   dev->if_port = 0;
+               else {
+                       tp->nwayset = 0;
+                       if ((csr12 & 2) == 0  &&  (tp->sym_advertise & 0x0180))
+                               dev->if_port = 3;
+               }
+               tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0;
+               if (tulip_debug > 1) {
+                       if (tp->nwayset)
+                               dev_info(&dev->dev,
+                                        "Switching to %s based on link negotiation %04x & %04x = %04x\n",
+                                        medianame[dev->if_port],
+                                        tp->sym_advertise, tp->lpar,
+                                        negotiated);
+                       else
+                               dev_info(&dev->dev,
+                                        "Autonegotiation failed, using %s, link beat status %04x\n",
+                                        medianame[dev->if_port], csr12);
+               }
+               if (tp->mtable) {
+                       int i;
+                       for (i = 0; i < tp->mtable->leafcount; i++)
+                               if (tp->mtable->mleaf[i].media == dev->if_port) {
+                                       int startup = ! ((tp->chip_id == DC21143 && (tp->revision == 48 || tp->revision == 65)));
+                                       tp->cur_index = i;
+                                       tulip_select_media(dev, startup);
+                                       setup_done = 1;
+                                       break;
+                               }
+               }
+               if ( ! setup_done) {
+                       tp->csr6 = (dev->if_port & 1 ? 0x838E0000 : 0x82420000) | (tp->csr6 & 0x20ff);
+                       if (tp->full_duplex)
+                               tp->csr6 |= 0x0200;
+                       iowrite32(1, ioaddr + CSR13);
+               }
+ #if 0                                                 /* Restart shouldn't be needed. */
+               iowrite32(tp->csr6 | RxOn, ioaddr + CSR6);
+               if (tulip_debug > 2)
+                       netdev_dbg(dev, " Restarting Tx and Rx, CSR5 is %08x\n",
+                                  ioread32(ioaddr + CSR5));
+ #endif
+               tulip_start_rxtx(tp);
+               if (tulip_debug > 2)
+                       netdev_dbg(dev, " Setting CSR6 %08x/%x CSR12 %08x\n",
+                                  tp->csr6, ioread32(ioaddr + CSR6),
+                                  ioread32(ioaddr + CSR12));
+       } else if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
+                   (dev->if_port == 3  ||  dev->if_port == 5) &&
+                   (csr12 & 2) == 2) ||
+                  (tp->nway && (csr5 & (TPLnkFail)))) {
+               /* Link blew? Maybe restart NWay. */
+               del_timer_sync(&tp->timer);
+               t21142_start_nway(dev);
+               tp->timer.expires = RUN_AT(3*HZ);
+               add_timer(&tp->timer);
+       } else if (dev->if_port == 3  ||  dev->if_port == 5) {
+               if (tulip_debug > 1)
+                       dev_info(&dev->dev, "21143 %s link beat %s\n",
+                                medianame[dev->if_port],
+                                (csr12 & 2) ? "failed" : "good");
+               if ((csr12 & 2)  &&  ! tp->medialock) {
+                       del_timer_sync(&tp->timer);
+                       t21142_start_nway(dev);
+                       tp->timer.expires = RUN_AT(3*HZ);
+                       add_timer(&tp->timer);
+               } else if (dev->if_port == 5)
+                       iowrite32(csr14 & ~0x080, ioaddr + CSR14);
+       } else if (dev->if_port == 0  ||  dev->if_port == 4) {
+               if ((csr12 & 4) == 0)
+                       dev_info(&dev->dev, "21143 10baseT link beat good\n");
+       } else if (!(csr12 & 4)) {              /* 10mbps link beat good. */
+               if (tulip_debug)
+                       dev_info(&dev->dev, "21143 10mbps sensed media\n");
+               dev->if_port = 0;
+       } else if (tp->nwayset) {
+               if (tulip_debug)
+                       dev_info(&dev->dev, "21143 using NWay-set %s, csr6 %08x\n",
+                                medianame[dev->if_port], tp->csr6);
+       } else {                /* 100mbps link beat good. */
+               if (tulip_debug)
+                       dev_info(&dev->dev, "21143 100baseTx sensed media\n");
+               dev->if_port = 3;
+               tp->csr6 = 0x838E0000 | (tp->csr6 & 0x20ff);
+               iowrite32(0x0003FF7F, ioaddr + CSR14);
+               iowrite32(0x0301, ioaddr + CSR12);
+               tulip_restart_rxtx(tp);
+       }
+ }
index 0000000,fa5eee9..14d5b61
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,385 +1,383 @@@
+ /*
+       drivers/net/tulip/eeprom.c
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
+       Please submit bug reports to http://bugzilla.kernel.org/.
+ */
+ #include <linux/pci.h>
+ #include <linux/slab.h>
+ #include "tulip.h"
+ #include <linux/init.h>
+ #include <asm/unaligned.h>
+ /* Serial EEPROM section. */
+ /* The main routine to parse the very complicated SROM structure.
+    Search www.digital.com for "21X4 SROM" to get details.
+    This code is very complex, and will require changes to support
+    additional cards, so I'll be verbose about what is going on.
+    */
+ /* Known cards that have old-style EEPROMs. */
+ static struct eeprom_fixup eeprom_fixups[] __devinitdata = {
+   {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
+                         0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
+   {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
+                          0x0000, 0x009E, /* 10baseT */
+                          0x0004, 0x009E, /* 10baseT-FD */
+                          0x0903, 0x006D, /* 100baseTx */
+                          0x0905, 0x006D, /* 100baseTx-FD */ }},
+   {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
+                                0x0107, 0x8021, /* 100baseFx */
+                                0x0108, 0x8021, /* 100baseFx-FD */
+                                0x0100, 0x009E, /* 10baseT */
+                                0x0104, 0x009E, /* 10baseT-FD */
+                                0x0103, 0x006D, /* 100baseTx */
+                                0x0105, 0x006D, /* 100baseTx-FD */ }},
+   {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
+                                  0x1001, 0x009E, /* 10base2, CSR12 0x10*/
+                                  0x0000, 0x009E, /* 10baseT */
+                                  0x0004, 0x009E, /* 10baseT-FD */
+                                  0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
+                                  0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
+   {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
+                                 0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
+                                 0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
+                                 0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
+                                 0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
+                                 0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
+    }},
+   {"NetWinder", 0x00, 0x10, 0x57,
+       /* Default media = MII
+        * MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1
+        */
+       { 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
+   },
+   {"Cobalt Microserver", 0, 0x10, 0xE0, {0x1e00, /* 0 == controller #, 1e == offset   */
+                                        0x0000, /* 0 == high offset, 0 == gap          */
+                                        0x0800, /* Default Autoselect                  */
+                                        0x8001, /* 1 leaf, extended type, bogus len    */
+                                        0x0003, /* Type 3 (MII), PHY #0                */
+                                        0x0400, /* 0 init instr, 4 reset instr         */
+                                        0x0801, /* Set control mode, GP0 output        */
+                                        0x0000, /* Drive GP0 Low (RST is active low)   */
+                                        0x0800, /* control mode, GP0 input (undriven)  */
+                                        0x0000, /* clear control mode                  */
+                                        0x7800, /* 100TX FDX + HDX, 10bT FDX + HDX     */
+                                        0x01e0, /* Advertise all above                 */
+                                        0x5000, /* FDX all above                       */
+                                        0x1800, /* Set fast TTM in 100bt modes         */
+                                        0x0000, /* PHY cannot be unplugged             */
+   }},
+   {NULL}};
+ static const char *block_name[] __devinitdata = {
+       "21140 non-MII",
+       "21140 MII PHY",
+       "21142 Serial PHY",
+       "21142 MII PHY",
+       "21143 SYM PHY",
+       "21143 reset method"
+ };
+ /**
+  * tulip_build_fake_mediatable - Build a fake mediatable entry.
+  * @tp: Ptr to the tulip private data.
+  *
+  * Some cards like the 3x5 HSC cards (J3514A) do not have a standard
+  * srom and can not be handled under the fixup routine.  These cards
+  * still need a valid mediatable entry for correct csr12 setup and
+  * mii handling.
+  *
+  * Since this is currently a parisc-linux specific function, the
+  * #ifdef __hppa__ should completely optimize this function away for
+  * non-parisc hardware.
+  */
+ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
+ {
+ #ifdef CONFIG_GSC
+       if (tp->flags & NEEDS_FAKE_MEDIA_TABLE) {
+               static unsigned char leafdata[] =
+                       { 0x01,       /* phy number */
+                         0x02,       /* gpr setup sequence length */
+                         0x02, 0x00, /* gpr setup sequence */
+                         0x02,       /* phy reset sequence length */
+                         0x01, 0x00, /* phy reset sequence */
+                         0x00, 0x78, /* media capabilities */
+                         0x00, 0xe0, /* nway advertisement */
+                         0x00, 0x05, /* fdx bit map */
+                         0x00, 0x06  /* ttm bit map */
+                       };
+               tp->mtable = kmalloc(sizeof(struct mediatable) +
+                                    sizeof(struct medialeaf), GFP_KERNEL);
+               if (tp->mtable == NULL)
+                       return; /* Horrible, impossible failure. */
+               tp->mtable->defaultmedia = 0x800;
+               tp->mtable->leafcount = 1;
+               tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
+               tp->mtable->has_nonmii = 0;
+               tp->mtable->has_reset = 0;
+               tp->mtable->has_mii = 1;
+               tp->mtable->csr15dir = tp->mtable->csr15val = 0;
+               tp->mtable->mleaf[0].type = 1;
+               tp->mtable->mleaf[0].media = 11;
+               tp->mtable->mleaf[0].leafdata = &leafdata[0];
+               tp->flags |= HAS_PHY_IRQ;
+               tp->csr12_shadow = -1;
+       }
+ #endif
+ }
+ void __devinit tulip_parse_eeprom(struct net_device *dev)
+ {
+       /*
+         dev is not registered at this point, so logging messages can't
+         use dev_<level> or netdev_<level> but dev->name is good via a
+         hack in the caller
+       */
+       /* The last media info list parsed, for multiport boards.  */
+       static struct mediatable *last_mediatable;
+       static unsigned char *last_ee_data;
+       static int controller_index;
+       struct tulip_private *tp = netdev_priv(dev);
+       unsigned char *ee_data = tp->eeprom;
+       int i;
+       tp->mtable = NULL;
+       /* Detect an old-style (SA only) EEPROM layout:
+          memcmp(eedata, eedata+16, 8). */
+       for (i = 0; i < 8; i ++)
+               if (ee_data[i] != ee_data[16+i])
+                       break;
+       if (i >= 8) {
+               if (ee_data[0] == 0xff) {
+                       if (last_mediatable) {
+                               controller_index++;
+                               pr_info("%s: Controller %d of multiport board\n",
+                                       dev->name, controller_index);
+                               tp->mtable = last_mediatable;
+                               ee_data = last_ee_data;
+                               goto subsequent_board;
+                       } else
+                               pr_info("%s: Missing EEPROM, this interface may not work correctly!\n",
+                                       dev->name);
+                       return;
+               }
+         /* Do a fix-up based on the vendor half of the station address prefix. */
+         for (i = 0; eeprom_fixups[i].name; i++) {
+                 if (dev->dev_addr[0] == eeprom_fixups[i].addr0 &&
+                     dev->dev_addr[1] == eeprom_fixups[i].addr1 &&
+                     dev->dev_addr[2] == eeprom_fixups[i].addr2) {
+                 if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
+                         i++;                  /* An Accton EN1207, not an outlaw Maxtech. */
+                 memcpy(ee_data + 26, eeprom_fixups[i].newtable,
+                                sizeof(eeprom_fixups[i].newtable));
+                 pr_info("%s: Old format EEPROM on '%s' board.  Using substitute media control info\n",
+                         dev->name, eeprom_fixups[i].name);
+                 break;
+               }
+         }
+         if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
+                 pr_info("%s: Old style EEPROM with no media selection information\n",
+                         dev->name);
+               return;
+         }
+       }
+       controller_index = 0;
+       if (ee_data[19] > 1) {          /* Multiport board. */
+               last_ee_data = ee_data;
+       }
+ subsequent_board:
+       if (ee_data[27] == 0) {         /* No valid media table. */
+               tulip_build_fake_mediatable(tp);
+       } else {
+               unsigned char *p = (void *)ee_data + ee_data[27];
+               unsigned char csr12dir = 0;
+               int count, new_advertise = 0;
+               struct mediatable *mtable;
+               u16 media = get_u16(p);
+               p += 2;
+               if (tp->flags & CSR12_IN_SROM)
+                       csr12dir = *p++;
+               count = *p++;
+               /* there is no phy information, don't even try to build mtable */
+               if (count == 0) {
+                       if (tulip_debug > 0)
+                               pr_warn("%s: no phy info, aborting mtable build\n",
+                                       dev->name);
+                       return;
+               }
+               mtable = kmalloc(sizeof(struct mediatable) +
+                                count * sizeof(struct medialeaf),
+                                GFP_KERNEL);
+               if (mtable == NULL)
+                       return;                         /* Horrible, impossible failure. */
+               last_mediatable = tp->mtable = mtable;
+               mtable->defaultmedia = media;
+               mtable->leafcount = count;
+               mtable->csr12dir = csr12dir;
+               mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
+               mtable->csr15dir = mtable->csr15val = 0;
+               pr_info("%s: EEPROM default media type %s\n",
+                       dev->name,
+                       media & 0x0800 ? "Autosense"
+                                      : medianame[media & MEDIA_MASK]);
+               for (i = 0; i < count; i++) {
+                       struct medialeaf *leaf = &mtable->mleaf[i];
+                       if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
+                               leaf->type = 0;
+                               leaf->media = p[0] & 0x3f;
+                               leaf->leafdata = p;
+                               if ((p[2] & 0x61) == 0x01)      /* Bogus, but Znyx boards do it. */
+                                       mtable->has_mii = 1;
+                               p += 4;
+                       } else {
+                               leaf->type = p[1];
+                               if (p[1] == 0x05) {
+                                       mtable->has_reset = i;
+                                       leaf->media = p[2] & 0x0f;
+                               } else if (tp->chip_id == DM910X && p[1] == 0x80) {
+                                       /* Hack to ignore Davicom delay period block */
+                                       mtable->leafcount--;
+                                       count--;
+                                       i--;
+                                       leaf->leafdata = p + 2;
+                                       p += (p[0] & 0x3f) + 1;
+                                       continue;
+                               } else if (p[1] & 1) {
+                                       int gpr_len, reset_len;
+                                       mtable->has_mii = 1;
+                                       leaf->media = 11;
+                                       gpr_len=p[3]*2;
+                                       reset_len=p[4+gpr_len]*2;
+                                       new_advertise |= get_u16(&p[7+gpr_len+reset_len]);
+                               } else {
+                                       mtable->has_nonmii = 1;
+                                       leaf->media = p[2] & MEDIA_MASK;
+                                       /* Davicom's media number for 100BaseTX is strange */
+                                       if (tp->chip_id == DM910X && leaf->media == 1)
+                                               leaf->media = 3;
+                                       switch (leaf->media) {
+                                       case 0: new_advertise |= 0x0020; break;
+                                       case 4: new_advertise |= 0x0040; break;
+                                       case 3: new_advertise |= 0x0080; break;
+                                       case 5: new_advertise |= 0x0100; break;
+                                       case 6: new_advertise |= 0x0200; break;
+                                       }
+                                       if (p[1] == 2  &&  leaf->media == 0) {
+                                               if (p[2] & 0x40) {
+                                                       u32 base15 = get_unaligned((u16*)&p[7]);
+                                                       mtable->csr15dir =
+                                                               (get_unaligned((u16*)&p[9])<<16) + base15;
+                                                       mtable->csr15val =
+                                                               (get_unaligned((u16*)&p[11])<<16) + base15;
+                                               } else {
+                                                       mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
+                                                       mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
+                                               }
+                                       }
+                               }
+                               leaf->leafdata = p + 2;
+                               p += (p[0] & 0x3f) + 1;
+                       }
+                       if (tulip_debug > 1  &&  leaf->media == 11) {
+                               unsigned char *bp = leaf->leafdata;
+                               pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n",
+                                       dev->name,
+                                       bp[0], bp[1], bp[2 + bp[1]*2],
+                                       bp[5 + bp[2 + bp[1]*2]*2],
+                                       bp[4 + bp[2 + bp[1]*2]*2]);
+                       }
+                       pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n",
+                               dev->name,
+                               i, medianame[leaf->media & 15], leaf->media,
+                               leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
+                               leaf->type);
+               }
+               if (new_advertise)
+                       tp->sym_advertise = new_advertise;
+       }
+ }
+ /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
+ /*  EEPROM_Ctrl bits. */
+ #define EE_SHIFT_CLK  0x02    /* EEPROM shift clock. */
+ #define EE_CS         0x01    /* EEPROM chip select. */
+ #define EE_DATA_WRITE 0x04    /* Data from the Tulip to EEPROM. */
+ #define EE_WRITE_0    0x01
+ #define EE_WRITE_1    0x05
+ #define EE_DATA_READ  0x08    /* Data from the EEPROM chip. */
+ #define EE_ENB                (0x4800 | EE_CS)
+ /* Delay between EEPROM clock transitions.
+    Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
+    We add a bus turn-around to insure that this remains true. */
+ #define eeprom_delay()        ioread32(ee_addr)
+ /* The EEPROM commands include the alway-set leading bit. */
+ #define EE_READ_CMD           (6)
+ /* Note: this routine returns extra data bits for size detection. */
+ int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_len)
+ {
+       int i;
+       unsigned retval = 0;
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ee_addr = tp->base_addr + CSR9;
+       int read_cmd = location | (EE_READ_CMD << addr_len);
+       /* If location is past the end of what we can address, don't
+        * read some other location (ie truncate). Just return zero.
+        */
+       if (location > (1 << addr_len) - 1)
+               return 0;
+       iowrite32(EE_ENB & ~EE_CS, ee_addr);
+       iowrite32(EE_ENB, ee_addr);
+       /* Shift the read command bits out. */
+       for (i = 4 + addr_len; i >= 0; i--) {
+               short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+               iowrite32(EE_ENB | dataval, ee_addr);
+               eeprom_delay();
+               iowrite32(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+               eeprom_delay();
+               retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
+       }
+       iowrite32(EE_ENB, ee_addr);
+       eeprom_delay();
+       for (i = 16; i > 0; i--) {
+               iowrite32(EE_ENB | EE_SHIFT_CLK, ee_addr);
+               eeprom_delay();
+               retval = (retval << 1) | ((ioread32(ee_addr) & EE_DATA_READ) ? 1 : 0);
+               iowrite32(EE_ENB, ee_addr);
+               eeprom_delay();
+       }
+       /* Terminate the EEPROM access. */
+       iowrite32(EE_ENB & ~EE_CS, ee_addr);
+       return (tp->flags & HAS_SWAPPED_SEEPROM) ? swab16(retval) : retval;
+ }
index 0000000,5350d75..4fb8c8c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,811 +1,808 @@@
+ /*
+       drivers/net/tulip/interrupt.c
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
+         Please submit bugs to http://bugzilla.kernel.org/ .
 -
+ */
+ #include <linux/pci.h>
+ #include "tulip.h"
+ #include <linux/etherdevice.h>
+ int tulip_rx_copybreak;
+ unsigned int tulip_max_interrupt_work;
+ #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+ #define MIT_SIZE 15
+ #define MIT_TABLE 15 /* We use 0 or max */
+ static unsigned int mit_table[MIT_SIZE+1] =
+ {
+         /*  CRS11 21143 hardware Mitigation Control Interrupt
+             We use only RX mitigation we other techniques for
+             TX intr. mitigation.
+            31    Cycle Size (timer control)
+            30:27 TX timer in 16 * Cycle size
+            26:24 TX No pkts before Int.
+            23:20 RX timer in Cycle size
+            19:17 RX No pkts before Int.
+            16       Continues Mode (CM)
+         */
+         0x0,             /* IM disabled */
+         0x80150000,      /* RX time = 1, RX pkts = 2, CM = 1 */
+         0x80150000,
+         0x80270000,
+         0x80370000,
+         0x80490000,
+         0x80590000,
+         0x80690000,
+         0x807B0000,
+         0x808B0000,
+         0x809D0000,
+         0x80AD0000,
+         0x80BD0000,
+         0x80CF0000,
+         0x80DF0000,
+ //       0x80FF0000      /* RX time = 16, RX pkts = 7, CM = 1 */
+         0x80F10000      /* RX time = 16, RX pkts = 0, CM = 1 */
+ };
+ #endif
+ int tulip_refill_rx(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int entry;
+       int refilled = 0;
+       /* Refill the Rx ring buffers. */
+       for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
+               entry = tp->dirty_rx % RX_RING_SIZE;
+               if (tp->rx_buffers[entry].skb == NULL) {
+                       struct sk_buff *skb;
+                       dma_addr_t mapping;
+                       skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ);
+                       if (skb == NULL)
+                               break;
+                       mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ,
+                                                PCI_DMA_FROMDEVICE);
+                       tp->rx_buffers[entry].mapping = mapping;
+                       skb->dev = dev;                 /* Mark as being used by this device. */
+                       tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
+                       refilled++;
+               }
+               tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
+       }
+       if(tp->chip_id == LC82C168) {
+               if(((ioread32(tp->base_addr + CSR5)>>17)&0x07) == 4) {
+                       /* Rx stopped due to out of buffers,
+                        * restart it
+                        */
+                       iowrite32(0x01, tp->base_addr + CSR2);
+               }
+       }
+       return refilled;
+ }
+ #ifdef CONFIG_TULIP_NAPI
+ void oom_timer(unsigned long data)
+ {
+         struct net_device *dev = (struct net_device *)data;
+       struct tulip_private *tp = netdev_priv(dev);
+       napi_schedule(&tp->napi);
+ }
+ int tulip_poll(struct napi_struct *napi, int budget)
+ {
+       struct tulip_private *tp = container_of(napi, struct tulip_private, napi);
+       struct net_device *dev = tp->dev;
+       int entry = tp->cur_rx % RX_RING_SIZE;
+       int work_done = 0;
+ #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+       int received = 0;
+ #endif
+ #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+ /* that one buffer is needed for mit activation; or might be a
+    bug in the ring buffer code; check later -- JHS*/
+         if (budget >=RX_RING_SIZE) budget--;
+ #endif
+       if (tulip_debug > 4)
+               netdev_dbg(dev, " In tulip_rx(), entry %d %08x\n",
+                          entry, tp->rx_ring[entry].status);
+        do {
+               if (ioread32(tp->base_addr + CSR5) == 0xffffffff) {
+                       netdev_dbg(dev, " In tulip_poll(), hardware disappeared\n");
+                       break;
+               }
+                /* Acknowledge current RX interrupt sources. */
+                iowrite32((RxIntr | RxNoBuf), tp->base_addr + CSR5);
+                /* If we own the next entry, it is a new packet. Send it up. */
+                while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
+                        s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+                      short pkt_len;
+                        if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
+                                break;
+                      if (tulip_debug > 5)
+                               netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+                                          entry, status);
+                      if (++work_done >= budget)
+                                goto not_done;
+                      /*
+                       * Omit the four octet CRC from the length.
+                       * (May not be considered valid until we have
+                       * checked status for RxLengthOver2047 bits)
+                       */
+                      pkt_len = ((status >> 16) & 0x7ff) - 4;
+                      /*
+                       * Maximum pkt_len is 1518 (1514 + vlan header)
+                       * Anything higher than this is always invalid
+                       * regardless of RxLengthOver2047 bits
+                       */
+                      if ((status & (RxLengthOver2047 |
+                                     RxDescCRCError |
+                                     RxDescCollisionSeen |
+                                     RxDescRunt |
+                                     RxDescDescErr |
+                                     RxWholePkt)) != RxWholePkt ||
+                          pkt_len > 1518) {
+                              if ((status & (RxLengthOver2047 |
+                                             RxWholePkt)) != RxWholePkt) {
+                                 /* Ingore earlier buffers. */
+                                        if ((status & 0xffff) != 0x7fff) {
+                                                if (tulip_debug > 1)
+                                                        dev_warn(&dev->dev,
+                                                               "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+                                                               status);
+                                               dev->stats.rx_length_errors++;
+                                       }
+                              } else {
+                                 /* There was a fatal error. */
+                                      if (tulip_debug > 2)
+                                               netdev_dbg(dev, "Receive error, Rx status %08x\n",
+                                                          status);
+                                       dev->stats.rx_errors++; /* end of a packet.*/
+                                       if (pkt_len > 1518 ||
+                                           (status & RxDescRunt))
+                                               dev->stats.rx_length_errors++;
+                                       if (status & 0x0004)
+                                               dev->stats.rx_frame_errors++;
+                                       if (status & 0x0002)
+                                               dev->stats.rx_crc_errors++;
+                                       if (status & 0x0001)
+                                               dev->stats.rx_fifo_errors++;
+                                }
+                        } else {
+                                struct sk_buff *skb;
+                                /* Check if the packet is long enough to accept without copying
+                                   to a minimally-sized skbuff. */
+                                if (pkt_len < tulip_rx_copybreak &&
+                                    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+                                        skb_reserve(skb, 2);    /* 16 byte align the IP header */
+                                        pci_dma_sync_single_for_cpu(tp->pdev,
+                                                                  tp->rx_buffers[entry].mapping,
+                                                                  pkt_len, PCI_DMA_FROMDEVICE);
+ #if ! defined(__alpha__)
+                                        skb_copy_to_linear_data(skb, tp->rx_buffers[entry].skb->data,
+                                                         pkt_len);
+                                        skb_put(skb, pkt_len);
+ #else
+                                        memcpy(skb_put(skb, pkt_len),
+                                               tp->rx_buffers[entry].skb->data,
+                                               pkt_len);
+ #endif
+                                        pci_dma_sync_single_for_device(tp->pdev,
+                                                                     tp->rx_buffers[entry].mapping,
+                                                                     pkt_len, PCI_DMA_FROMDEVICE);
+                                } else {        /* Pass up the skb already on the Rx ring. */
+                                        char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
+                                                             pkt_len);
+ #ifndef final_version
+                                        if (tp->rx_buffers[entry].mapping !=
+                                            le32_to_cpu(tp->rx_ring[entry].buffer1)) {
+                                                dev_err(&dev->dev,
+                                                      "Internal fault: The skbuff addresses do not match in tulip_rx: %08x vs. %08llx %p / %p\n",
+                                                      le32_to_cpu(tp->rx_ring[entry].buffer1),
+                                                      (unsigned long long)tp->rx_buffers[entry].mapping,
+                                                      skb->head, temp);
+                                        }
+ #endif
+                                        pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
+                                                         PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+                                        tp->rx_buffers[entry].skb = NULL;
+                                        tp->rx_buffers[entry].mapping = 0;
+                                }
+                                skb->protocol = eth_type_trans(skb, dev);
+                                netif_receive_skb(skb);
+                               dev->stats.rx_packets++;
+                               dev->stats.rx_bytes += pkt_len;
+                        }
+ #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+                      received++;
+ #endif
+                        entry = (++tp->cur_rx) % RX_RING_SIZE;
+                        if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4)
+                                tulip_refill_rx(dev);
+                 }
+                /* New ack strategy... irq does not ack Rx any longer
+                   hopefully this helps */
+                /* Really bad things can happen here... If new packet arrives
+                 * and an irq arrives (tx or just due to occasionally unset
+                 * mask), it will be acked by irq handler, but new thread
+                 * is not scheduled. It is major hole in design.
+                 * No idea how to fix this if "playing with fire" will fail
+                 * tomorrow (night 011029). If it will not fail, we won
+                 * finally: amount of IO did not increase at all. */
+        } while ((ioread32(tp->base_addr + CSR5) & RxIntr));
+  #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+           /* We use this simplistic scheme for IM. It's proven by
+              real life installations. We can have IM enabled
+             continuesly but this would cause unnecessary latency.
+             Unfortunely we can't use all the NET_RX_* feedback here.
+             This would turn on IM for devices that is not contributing
+             to backlog congestion with unnecessary latency.
+              We monitor the device RX-ring and have:
+              HW Interrupt Mitigation either ON or OFF.
+             ON:  More then 1 pkt received (per intr.) OR we are dropping
+              OFF: Only 1 pkt received
+              Note. We only use min and max (0, 15) settings from mit_table */
+           if( tp->flags &  HAS_INTR_MITIGATION) {
+                  if( received > 1 ) {
+                          if( ! tp->mit_on ) {
+                                  tp->mit_on = 1;
+                                  iowrite32(mit_table[MIT_TABLE], tp->base_addr + CSR11);
+                          }
+                   }
+                  else {
+                          if( tp->mit_on ) {
+                                  tp->mit_on = 0;
+                                  iowrite32(0, tp->base_addr + CSR11);
+                          }
+                   }
+           }
+ #endif /* CONFIG_TULIP_NAPI_HW_MITIGATION */
+          tulip_refill_rx(dev);
+          /* If RX ring is not full we are out of memory. */
+          if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                goto oom;
+          /* Remove us from polling list and enable RX intr. */
+          napi_complete(napi);
+          iowrite32(tulip_tbl[tp->chip_id].valid_intrs, tp->base_addr+CSR7);
+          /* The last op happens after poll completion. Which means the following:
+           * 1. it can race with disabling irqs in irq handler
+           * 2. it can race with dise/enabling irqs in other poll threads
+           * 3. if an irq raised after beginning loop, it will be immediately
+           *    triggered here.
+           *
+           * Summarizing: the logic results in some redundant irqs both
+           * due to races in masking and due to too late acking of already
+           * processed irqs. But it must not result in losing events.
+           */
+          return work_done;
+  not_done:
+          if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+              tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                  tulip_refill_rx(dev);
+          if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                goto oom;
+          return work_done;
+  oom:    /* Executed with RX ints disabled */
+          /* Start timer, stop polling, but do not enable rx interrupts. */
+          mod_timer(&tp->oom_timer, jiffies+1);
+          /* Think: timer_pending() was an explicit signature of bug.
+           * Timer can be pending now but fired and completed
+           * before we did napi_complete(). See? We would lose it. */
+          /* remove ourselves from the polling list */
+          napi_complete(napi);
+          return work_done;
+ }
+ #else /* CONFIG_TULIP_NAPI */
+ static int tulip_rx(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int entry = tp->cur_rx % RX_RING_SIZE;
+       int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
+       int received = 0;
+       if (tulip_debug > 4)
+               netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+                          entry, tp->rx_ring[entry].status);
+       /* If we own the next entry, it is a new packet. Send it up. */
+       while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
+               s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+               short pkt_len;
+               if (tulip_debug > 5)
+                       netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+                                  entry, status);
+               if (--rx_work_limit < 0)
+                       break;
+               /*
+                 Omit the four octet CRC from the length.
+                 (May not be considered valid until we have
+                 checked status for RxLengthOver2047 bits)
+               */
+               pkt_len = ((status >> 16) & 0x7ff) - 4;
+               /*
+                 Maximum pkt_len is 1518 (1514 + vlan header)
+                 Anything higher than this is always invalid
+                 regardless of RxLengthOver2047 bits
+               */
+               if ((status & (RxLengthOver2047 |
+                              RxDescCRCError |
+                              RxDescCollisionSeen |
+                              RxDescRunt |
+                              RxDescDescErr |
+                              RxWholePkt))        != RxWholePkt ||
+                   pkt_len > 1518) {
+                       if ((status & (RxLengthOver2047 |
+                            RxWholePkt))         != RxWholePkt) {
+                               /* Ingore earlier buffers. */
+                               if ((status & 0xffff) != 0x7fff) {
+                                       if (tulip_debug > 1)
+                                               netdev_warn(dev,
+                                                           "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+                                                           status);
+                                       dev->stats.rx_length_errors++;
+                               }
+                       } else {
+                               /* There was a fatal error. */
+                               if (tulip_debug > 2)
+                                       netdev_dbg(dev, "Receive error, Rx status %08x\n",
+                                                  status);
+                               dev->stats.rx_errors++; /* end of a packet.*/
+                               if (pkt_len > 1518 ||
+                                   (status & RxDescRunt))
+                                       dev->stats.rx_length_errors++;
+                               if (status & 0x0004)
+                                       dev->stats.rx_frame_errors++;
+                               if (status & 0x0002)
+                                       dev->stats.rx_crc_errors++;
+                               if (status & 0x0001)
+                                       dev->stats.rx_fifo_errors++;
+                       }
+               } else {
+                       struct sk_buff *skb;
+                       /* Check if the packet is long enough to accept without copying
+                          to a minimally-sized skbuff. */
+                       if (pkt_len < tulip_rx_copybreak &&
+                           (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+                               skb_reserve(skb, 2);    /* 16 byte align the IP header */
+                               pci_dma_sync_single_for_cpu(tp->pdev,
+                                                           tp->rx_buffers[entry].mapping,
+                                                           pkt_len, PCI_DMA_FROMDEVICE);
+ #if ! defined(__alpha__)
+                               skb_copy_to_linear_data(skb, tp->rx_buffers[entry].skb->data,
+                                                pkt_len);
+                               skb_put(skb, pkt_len);
+ #else
+                               memcpy(skb_put(skb, pkt_len),
+                                      tp->rx_buffers[entry].skb->data,
+                                      pkt_len);
+ #endif
+                               pci_dma_sync_single_for_device(tp->pdev,
+                                                              tp->rx_buffers[entry].mapping,
+                                                              pkt_len, PCI_DMA_FROMDEVICE);
+                       } else {        /* Pass up the skb already on the Rx ring. */
+                               char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
+                                                    pkt_len);
+ #ifndef final_version
+                               if (tp->rx_buffers[entry].mapping !=
+                                   le32_to_cpu(tp->rx_ring[entry].buffer1)) {
+                                       dev_err(&dev->dev,
+                                               "Internal fault: The skbuff addresses do not match in tulip_rx: %08x vs. %Lx %p / %p\n",
+                                               le32_to_cpu(tp->rx_ring[entry].buffer1),
+                                               (long long)tp->rx_buffers[entry].mapping,
+                                               skb->head, temp);
+                               }
+ #endif
+                               pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
+                                                PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+                               tp->rx_buffers[entry].skb = NULL;
+                               tp->rx_buffers[entry].mapping = 0;
+                       }
+                       skb->protocol = eth_type_trans(skb, dev);
+                       netif_rx(skb);
+                       dev->stats.rx_packets++;
+                       dev->stats.rx_bytes += pkt_len;
+               }
+               received++;
+               entry = (++tp->cur_rx) % RX_RING_SIZE;
+       }
+       return received;
+ }
+ #endif  /* CONFIG_TULIP_NAPI */
+ static inline unsigned int phy_interrupt (struct net_device *dev)
+ {
+ #ifdef __hppa__
+       struct tulip_private *tp = netdev_priv(dev);
+       int csr12 = ioread32(tp->base_addr + CSR12) & 0xff;
+       if (csr12 != tp->csr12_shadow) {
+               /* ack interrupt */
+               iowrite32(csr12 | 0x02, tp->base_addr + CSR12);
+               tp->csr12_shadow = csr12;
+               /* do link change stuff */
+               spin_lock(&tp->lock);
+               tulip_check_duplex(dev);
+               spin_unlock(&tp->lock);
+               /* clear irq ack bit */
+               iowrite32(csr12 & ~0x02, tp->base_addr + CSR12);
+               return 1;
+       }
+ #endif
+       return 0;
+ }
+ /* The interrupt handler does all of the Rx thread work and cleans up
+    after the Tx thread. */
+ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
+ {
+       struct net_device *dev = (struct net_device *)dev_instance;
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int csr5;
+       int missed;
+       int rx = 0;
+       int tx = 0;
+       int oi = 0;
+       int maxrx = RX_RING_SIZE;
+       int maxtx = TX_RING_SIZE;
+       int maxoi = TX_RING_SIZE;
+ #ifdef CONFIG_TULIP_NAPI
+       int rxd = 0;
+ #else
+       int entry;
+ #endif
+       unsigned int work_count = tulip_max_interrupt_work;
+       unsigned int handled = 0;
+       /* Let's see whether the interrupt really is for us */
+       csr5 = ioread32(ioaddr + CSR5);
+         if (tp->flags & HAS_PHY_IRQ)
+               handled = phy_interrupt (dev);
+       if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
+               return IRQ_RETVAL(handled);
+       tp->nir++;
+       do {
+ #ifdef CONFIG_TULIP_NAPI
+               if (!rxd && (csr5 & (RxIntr | RxNoBuf))) {
+                       rxd++;
+                       /* Mask RX intrs and add the device to poll list. */
+                       iowrite32(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
+                       napi_schedule(&tp->napi);
+                       if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
+                                break;
+               }
+                /* Acknowledge the interrupt sources we handle here ASAP
+                   the poll function does Rx and RxNoBuf acking */
+               iowrite32(csr5 & 0x0001ff3f, ioaddr + CSR5);
+ #else
+               /* Acknowledge all of the current interrupt sources ASAP. */
+               iowrite32(csr5 & 0x0001ffff, ioaddr + CSR5);
+               if (csr5 & (RxIntr | RxNoBuf)) {
+                               rx += tulip_rx(dev);
+                       tulip_refill_rx(dev);
+               }
+ #endif /*  CONFIG_TULIP_NAPI */
+               if (tulip_debug > 4)
+                       netdev_dbg(dev, "interrupt  csr5=%#8.8x new csr5=%#8.8x\n",
+                                  csr5, ioread32(ioaddr + CSR5));
+               if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
+                       unsigned int dirty_tx;
+                       spin_lock(&tp->lock);
+                       for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0;
+                                dirty_tx++) {
+                               int entry = dirty_tx % TX_RING_SIZE;
+                               int status = le32_to_cpu(tp->tx_ring[entry].status);
+                               if (status < 0)
+                                       break;                  /* It still has not been Txed */
+                               /* Check for Rx filter setup frames. */
+                               if (tp->tx_buffers[entry].skb == NULL) {
+                                       /* test because dummy frames not mapped */
+                                       if (tp->tx_buffers[entry].mapping)
+                                               pci_unmap_single(tp->pdev,
+                                                        tp->tx_buffers[entry].mapping,
+                                                        sizeof(tp->setup_frame),
+                                                        PCI_DMA_TODEVICE);
+                                       continue;
+                               }
+                               if (status & 0x8000) {
+                                       /* There was an major error, log it. */
+ #ifndef final_version
+                                       if (tulip_debug > 1)
+                                               netdev_dbg(dev, "Transmit error, Tx status %08x\n",
+                                                          status);
+ #endif
+                                       dev->stats.tx_errors++;
+                                       if (status & 0x4104)
+                                               dev->stats.tx_aborted_errors++;
+                                       if (status & 0x0C00)
+                                               dev->stats.tx_carrier_errors++;
+                                       if (status & 0x0200)
+                                               dev->stats.tx_window_errors++;
+                                       if (status & 0x0002)
+                                               dev->stats.tx_fifo_errors++;
+                                       if ((status & 0x0080) && tp->full_duplex == 0)
+                                               dev->stats.tx_heartbeat_errors++;
+                               } else {
+                                       dev->stats.tx_bytes +=
+                                               tp->tx_buffers[entry].skb->len;
+                                       dev->stats.collisions += (status >> 3) & 15;
+                                       dev->stats.tx_packets++;
+                               }
+                               pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
+                                                tp->tx_buffers[entry].skb->len,
+                                                PCI_DMA_TODEVICE);
+                               /* Free the original skb. */
+                               dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
+                               tp->tx_buffers[entry].skb = NULL;
+                               tp->tx_buffers[entry].mapping = 0;
+                               tx++;
+                       }
+ #ifndef final_version
+                       if (tp->cur_tx - dirty_tx > TX_RING_SIZE) {
+                               dev_err(&dev->dev,
+                                       "Out-of-sync dirty pointer, %d vs. %d\n",
+                                       dirty_tx, tp->cur_tx);
+                               dirty_tx += TX_RING_SIZE;
+                       }
+ #endif
+                       if (tp->cur_tx - dirty_tx < TX_RING_SIZE - 2)
+                               netif_wake_queue(dev);
+                       tp->dirty_tx = dirty_tx;
+                       if (csr5 & TxDied) {
+                               if (tulip_debug > 2)
+                                       dev_warn(&dev->dev,
+                                                "The transmitter stopped.  CSR5 is %x, CSR6 %x, new CSR6 %x\n",
+                                                csr5, ioread32(ioaddr + CSR6),
+                                                tp->csr6);
+                               tulip_restart_rxtx(tp);
+                       }
+                       spin_unlock(&tp->lock);
+               }
+               /* Log errors. */
+               if (csr5 & AbnormalIntr) {      /* Abnormal error summary bit. */
+                       if (csr5 == 0xffffffff)
+                               break;
+                       if (csr5 & TxJabber)
+                               dev->stats.tx_errors++;
+                       if (csr5 & TxFIFOUnderflow) {
+                               if ((tp->csr6 & 0xC000) != 0xC000)
+                                       tp->csr6 += 0x4000;     /* Bump up the Tx threshold */
+                               else
+                                       tp->csr6 |= 0x00200000;  /* Store-n-forward. */
+                               /* Restart the transmit process. */
+                               tulip_restart_rxtx(tp);
+                               iowrite32(0, ioaddr + CSR1);
+                       }
+                       if (csr5 & (RxDied | RxNoBuf)) {
+                               if (tp->flags & COMET_MAC_ADDR) {
+                                       iowrite32(tp->mc_filter[0], ioaddr + 0xAC);
+                                       iowrite32(tp->mc_filter[1], ioaddr + 0xB0);
+                               }
+                       }
+                       if (csr5 & RxDied) {            /* Missed a Rx frame. */
+                               dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
+                               dev->stats.rx_errors++;
+                               tulip_start_rxtx(tp);
+                       }
+                       /*
+                        * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this
+                        * call is ever done under the spinlock
+                        */
+                       if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) {
+                               if (tp->link_change)
+                                       (tp->link_change)(dev, csr5);
+                       }
+                       if (csr5 & SystemError) {
+                               int error = (csr5 >> 23) & 7;
+                               /* oops, we hit a PCI error.  The code produced corresponds
+                                * to the reason:
+                                *  0 - parity error
+                                *  1 - master abort
+                                *  2 - target abort
+                                * Note that on parity error, we should do a software reset
+                                * of the chip to get it back into a sane state (according
+                                * to the 21142/3 docs that is).
+                                *   -- rmk
+                                */
+                               dev_err(&dev->dev,
+                                       "(%lu) System Error occurred (%d)\n",
+                                       tp->nir, error);
+                       }
+                       /* Clear all error sources, included undocumented ones! */
+                       iowrite32(0x0800f7ba, ioaddr + CSR5);
+                       oi++;
+               }
+               if (csr5 & TimerInt) {
+                       if (tulip_debug > 2)
+                               dev_err(&dev->dev,
+                                       "Re-enabling interrupts, %08x\n",
+                                       csr5);
+                       iowrite32(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+                       tp->ttimer = 0;
+                       oi++;
+               }
+               if (tx > maxtx || rx > maxrx || oi > maxoi) {
+                       if (tulip_debug > 1)
+                               dev_warn(&dev->dev, "Too much work during an interrupt, csr5=0x%08x. (%lu) (%d,%d,%d)\n",
+                                        csr5, tp->nir, tx, rx, oi);
+                        /* Acknowledge all interrupt sources. */
+                         iowrite32(0x8001ffff, ioaddr + CSR5);
+                         if (tp->flags & HAS_INTR_MITIGATION) {
+                      /* Josip Loncaric at ICASE did extensive experimentation
+                       to develop a good interrupt mitigation setting.*/
+                                 iowrite32(0x8b240000, ioaddr + CSR11);
+                         } else if (tp->chip_id == LC82C168) {
+                               /* the LC82C168 doesn't have a hw timer.*/
+                               iowrite32(0x00, ioaddr + CSR7);
+                               mod_timer(&tp->timer, RUN_AT(HZ/50));
+                       } else {
+                           /* Mask all interrupting sources, set timer to
+                               re-enable. */
+                                 iowrite32(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt, ioaddr + CSR7);
+                                 iowrite32(0x0012, ioaddr + CSR11);
+                         }
+                       break;
+               }
+               work_count--;
+               if (work_count == 0)
+                       break;
+               csr5 = ioread32(ioaddr + CSR5);
+ #ifdef CONFIG_TULIP_NAPI
+               if (rxd)
+                       csr5 &= ~RxPollInt;
+       } while ((csr5 & (TxNoBuf |
+                         TxDied |
+                         TxIntr |
+                         TimerInt |
+                         /* Abnormal intr. */
+                         RxDied |
+                         TxFIFOUnderflow |
+                         TxJabber |
+                         TPLnkFail |
+                         SystemError )) != 0);
+ #else
+       } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0);
+       tulip_refill_rx(dev);
+       /* check if the card is in suspend mode */
+       entry = tp->dirty_rx % RX_RING_SIZE;
+       if (tp->rx_buffers[entry].skb == NULL) {
+               if (tulip_debug > 1)
+                       dev_warn(&dev->dev,
+                                "in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n",
+                                tp->nir, tp->cur_rx, tp->ttimer, rx);
+               if (tp->chip_id == LC82C168) {
+                       iowrite32(0x00, ioaddr + CSR7);
+                       mod_timer(&tp->timer, RUN_AT(HZ/50));
+               } else {
+                       if (tp->ttimer == 0 || (ioread32(ioaddr + CSR11) & 0xffff) == 0) {
+                               if (tulip_debug > 1)
+                                       dev_warn(&dev->dev,
+                                                "in rx suspend mode: (%lu) set timer\n",
+                                                tp->nir);
+                               iowrite32(tulip_tbl[tp->chip_id].valid_intrs | TimerInt,
+                                       ioaddr + CSR7);
+                               iowrite32(TimerInt, ioaddr + CSR5);
+                               iowrite32(12, ioaddr + CSR11);
+                               tp->ttimer = 1;
+                       }
+               }
+       }
+ #endif /* CONFIG_TULIP_NAPI */
+       if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) {
+               dev->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+       }
+       if (tulip_debug > 4)
+               netdev_dbg(dev, "exiting interrupt, csr5=%#04x\n",
+                          ioread32(ioaddr + CSR5));
+       return IRQ_HANDLED;
+ }
index 0000000,4bd1392..beeb17b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,556 +1,553 @@@
+ /*
+       drivers/net/tulip/media.c
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
 -
+       Please submit bugs to http://bugzilla.kernel.org/ .
+ */
+ #include <linux/kernel.h>
+ #include <linux/mii.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/pci.h>
+ #include "tulip.h"
+ /* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
+    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+    "overclocking" issues or future 66Mhz PCI. */
+ #define mdio_delay() ioread32(mdio_addr)
+ /* Read and write the MII registers using software-generated serial
+    MDIO protocol.  It is just different enough from the EEPROM protocol
+    to not share code.  The maxium data clock rate is 2.5 Mhz. */
+ #define MDIO_SHIFT_CLK                0x10000
+ #define MDIO_DATA_WRITE0      0x00000
+ #define MDIO_DATA_WRITE1      0x20000
+ #define MDIO_ENB              0x00000 /* Ignore the 0x02000 databook setting. */
+ #define MDIO_ENB_IN           0x40000
+ #define MDIO_DATA_READ                0x80000
+ static const unsigned char comet_miireg2offset[32] = {
+       0xB4, 0xB8, 0xBC, 0xC0,  0xC4, 0xC8, 0xCC, 0,  0,0,0,0,  0,0,0,0,
+       0,0xD0,0,0,  0,0,0,0,  0,0,0,0, 0, 0xD4, 0xD8, 0xDC, };
+ /* MII transceiver control section.
+    Read and write the MII registers using software-generated serial
+    MDIO protocol.
+    See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
+    or DP83840A data sheet for more details.
+    */
+ int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int i;
+       int read_cmd = (0xf6 << 10) | ((phy_id & 0x1f) << 5) | location;
+       int retval = 0;
+       void __iomem *ioaddr = tp->base_addr;
+       void __iomem *mdio_addr = ioaddr + CSR9;
+       unsigned long flags;
+       if (location & ~0x1f)
+               return 0xffff;
+       if (tp->chip_id == COMET  &&  phy_id == 30) {
+               if (comet_miireg2offset[location])
+                       return ioread32(ioaddr + comet_miireg2offset[location]);
+               return 0xffff;
+       }
+       spin_lock_irqsave(&tp->mii_lock, flags);
+       if (tp->chip_id == LC82C168) {
+               iowrite32(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
+               ioread32(ioaddr + 0xA0);
+               ioread32(ioaddr + 0xA0);
+               for (i = 1000; i >= 0; --i) {
+                       barrier();
+                       if ( ! ((retval = ioread32(ioaddr + 0xA0)) & 0x80000000))
+                               break;
+               }
+               spin_unlock_irqrestore(&tp->mii_lock, flags);
+               return retval & 0xffff;
+       }
+       /* Establish sync by sending at least 32 logic ones. */
+       for (i = 32; i >= 0; i--) {
+               iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
+               mdio_delay();
+               iowrite32(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+               mdio_delay();
+       }
+       /* Shift the read command bits out. */
+       for (i = 15; i >= 0; i--) {
+               int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+               iowrite32(MDIO_ENB | dataval, mdio_addr);
+               mdio_delay();
+               iowrite32(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
+               mdio_delay();
+       }
+       /* Read the two transition, 16 data, and wire-idle bits. */
+       for (i = 19; i > 0; i--) {
+               iowrite32(MDIO_ENB_IN, mdio_addr);
+               mdio_delay();
+               retval = (retval << 1) | ((ioread32(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+               iowrite32(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+               mdio_delay();
+       }
+       spin_unlock_irqrestore(&tp->mii_lock, flags);
+       return (retval>>1) & 0xffff;
+ }
+ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int i;
+       int cmd = (0x5002 << 16) | ((phy_id & 0x1f) << 23) | (location<<18) | (val & 0xffff);
+       void __iomem *ioaddr = tp->base_addr;
+       void __iomem *mdio_addr = ioaddr + CSR9;
+       unsigned long flags;
+       if (location & ~0x1f)
+               return;
+       if (tp->chip_id == COMET && phy_id == 30) {
+               if (comet_miireg2offset[location])
+                       iowrite32(val, ioaddr + comet_miireg2offset[location]);
+               return;
+       }
+       spin_lock_irqsave(&tp->mii_lock, flags);
+       if (tp->chip_id == LC82C168) {
+               iowrite32(cmd, ioaddr + 0xA0);
+               for (i = 1000; i >= 0; --i) {
+                       barrier();
+                       if ( ! (ioread32(ioaddr + 0xA0) & 0x80000000))
+                               break;
+               }
+               spin_unlock_irqrestore(&tp->mii_lock, flags);
+               return;
+       }
+       /* Establish sync by sending 32 logic ones. */
+       for (i = 32; i >= 0; i--) {
+               iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
+               mdio_delay();
+               iowrite32(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+               mdio_delay();
+       }
+       /* Shift the command bits out. */
+       for (i = 31; i >= 0; i--) {
+               int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+               iowrite32(MDIO_ENB | dataval, mdio_addr);
+               mdio_delay();
+               iowrite32(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
+               mdio_delay();
+       }
+       /* Clear out extra bits. */
+       for (i = 2; i > 0; i--) {
+               iowrite32(MDIO_ENB_IN, mdio_addr);
+               mdio_delay();
+               iowrite32(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+               mdio_delay();
+       }
+       spin_unlock_irqrestore(&tp->mii_lock, flags);
+ }
+ /* Set up the transceiver control registers for the selected media type. */
+ void tulip_select_media(struct net_device *dev, int startup)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       struct mediatable *mtable = tp->mtable;
+       u32 new_csr6;
+       int i;
+       if (mtable) {
+               struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
+               unsigned char *p = mleaf->leafdata;
+               switch (mleaf->type) {
+               case 0:                                 /* 21140 non-MII xcvr. */
+                       if (tulip_debug > 1)
+                               netdev_dbg(dev, "Using a 21140 non-MII transceiver with control setting %02x\n",
+                                          p[1]);
+                       dev->if_port = p[0];
+                       if (startup)
+                               iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
+                       iowrite32(p[1], ioaddr + CSR12);
+                       new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
+                       break;
+               case 2: case 4: {
+                       u16 setup[5];
+                       u32 csr13val, csr14val, csr15dir, csr15val;
+                       for (i = 0; i < 5; i++)
+                               setup[i] = get_u16(&p[i*2 + 1]);
+                       dev->if_port = p[0] & MEDIA_MASK;
+                       if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
+                               tp->full_duplex = 1;
+                       if (startup && mtable->has_reset) {
+                               struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
+                               unsigned char *rst = rleaf->leafdata;
+                               if (tulip_debug > 1)
+                                       netdev_dbg(dev, "Resetting the transceiver\n");
+                               for (i = 0; i < rst[0]; i++)
+                                       iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
+                       }
+                       if (tulip_debug > 1)
+                               netdev_dbg(dev, "21143 non-MII %s transceiver control %04x/%04x\n",
+                                          medianame[dev->if_port],
+                                          setup[0], setup[1]);
+                       if (p[0] & 0x40) {      /* SIA (CSR13-15) setup values are provided. */
+                               csr13val = setup[0];
+                               csr14val = setup[1];
+                               csr15dir = (setup[3]<<16) | setup[2];
+                               csr15val = (setup[4]<<16) | setup[2];
+                               iowrite32(0, ioaddr + CSR13);
+                               iowrite32(csr14val, ioaddr + CSR14);
+                               iowrite32(csr15dir, ioaddr + CSR15);    /* Direction */
+                               iowrite32(csr15val, ioaddr + CSR15);    /* Data */
+                               iowrite32(csr13val, ioaddr + CSR13);
+                       } else {
+                               csr13val = 1;
+                               csr14val = 0;
+                               csr15dir = (setup[0]<<16) | 0x0008;
+                               csr15val = (setup[1]<<16) | 0x0008;
+                               if (dev->if_port <= 4)
+                                       csr14val = t21142_csr14[dev->if_port];
+                               if (startup) {
+                                       iowrite32(0, ioaddr + CSR13);
+                                       iowrite32(csr14val, ioaddr + CSR14);
+                               }
+                               iowrite32(csr15dir, ioaddr + CSR15);    /* Direction */
+                               iowrite32(csr15val, ioaddr + CSR15);    /* Data */
+                               if (startup) iowrite32(csr13val, ioaddr + CSR13);
+                       }
+                       if (tulip_debug > 1)
+                               netdev_dbg(dev, "Setting CSR15 to %08x/%08x\n",
+                                          csr15dir, csr15val);
+                       if (mleaf->type == 4)
+                               new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
+                       else
+                               new_csr6 = 0x82420000;
+                       break;
+               }
+               case 1: case 3: {
+                       int phy_num = p[0];
+                       int init_length = p[1];
+                       u16 *misc_info, tmp_info;
+                       dev->if_port = 11;
+                       new_csr6 = 0x020E0000;
+                       if (mleaf->type == 3) { /* 21142 */
+                               u16 *init_sequence = (u16*)(p+2);
+                               u16 *reset_sequence = &((u16*)(p+3))[init_length];
+                               int reset_length = p[2 + init_length*2];
+                               misc_info = reset_sequence + reset_length;
+                               if (startup) {
+                                       int timeout = 10;       /* max 1 ms */
+                                       for (i = 0; i < reset_length; i++)
+                                               iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
+                                       /* flush posted writes */
+                                       ioread32(ioaddr + CSR15);
+                                       /* Sect 3.10.3 in DP83840A.pdf (p39) */
+                                       udelay(500);
+                                       /* Section 4.2 in DP83840A.pdf (p43) */
+                                       /* and IEEE 802.3 "22.2.4.1.1 Reset" */
+                                       while (timeout-- &&
+                                               (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
+                                               udelay(100);
+                               }
+                               for (i = 0; i < init_length; i++)
+                                       iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
+                               ioread32(ioaddr + CSR15);       /* flush posted writes */
+                       } else {
+                               u8 *init_sequence = p + 2;
+                               u8 *reset_sequence = p + 3 + init_length;
+                               int reset_length = p[2 + init_length];
+                               misc_info = (u16*)(reset_sequence + reset_length);
+                               if (startup) {
+                                       int timeout = 10;       /* max 1 ms */
+                                       iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
+                                       for (i = 0; i < reset_length; i++)
+                                               iowrite32(reset_sequence[i], ioaddr + CSR12);
+                                       /* flush posted writes */
+                                       ioread32(ioaddr + CSR12);
+                                       /* Sect 3.10.3 in DP83840A.pdf (p39) */
+                                       udelay(500);
+                                       /* Section 4.2 in DP83840A.pdf (p43) */
+                                       /* and IEEE 802.3 "22.2.4.1.1 Reset" */
+                                       while (timeout-- &&
+                                               (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
+                                               udelay(100);
+                               }
+                               for (i = 0; i < init_length; i++)
+                                       iowrite32(init_sequence[i], ioaddr + CSR12);
+                               ioread32(ioaddr + CSR12);       /* flush posted writes */
+                       }
+                       tmp_info = get_u16(&misc_info[1]);
+                       if (tmp_info)
+                               tp->advertising[phy_num] = tmp_info | 1;
+                       if (tmp_info && startup < 2) {
+                               if (tp->mii_advertise == 0)
+                                       tp->mii_advertise = tp->advertising[phy_num];
+                               if (tulip_debug > 1)
+                                       netdev_dbg(dev, " Advertising %04x on MII %d\n",
+                                                  tp->mii_advertise,
+                                                  tp->phys[phy_num]);
+                               tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise);
+                       }
+                       break;
+               }
+               case 5: case 6: {
+                       u16 setup[5];
+                       new_csr6 = 0; /* FIXME */
+                       for (i = 0; i < 5; i++)
+                               setup[i] = get_u16(&p[i*2 + 1]);
+                       if (startup && mtable->has_reset) {
+                               struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
+                               unsigned char *rst = rleaf->leafdata;
+                               if (tulip_debug > 1)
+                                       netdev_dbg(dev, "Resetting the transceiver\n");
+                               for (i = 0; i < rst[0]; i++)
+                                       iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
+                       }
+                       break;
+               }
+               default:
+                       netdev_dbg(dev, " Invalid media table selection %d\n",
+                                  mleaf->type);
+                       new_csr6 = 0x020E0000;
+               }
+               if (tulip_debug > 1)
+                       netdev_dbg(dev, "Using media type %s, CSR12 is %02x\n",
+                                  medianame[dev->if_port],
+                                  ioread32(ioaddr + CSR12) & 0xff);
+       } else if (tp->chip_id == LC82C168) {
+               if (startup && ! tp->medialock)
+                       dev->if_port = tp->mii_cnt ? 11 : 0;
+               if (tulip_debug > 1)
+                       netdev_dbg(dev, "PNIC PHY status is %3.3x, media %s\n",
+                                  ioread32(ioaddr + 0xB8),
+                                  medianame[dev->if_port]);
+               if (tp->mii_cnt) {
+                       new_csr6 = 0x810C0000;
+                       iowrite32(0x0001, ioaddr + CSR15);
+                       iowrite32(0x0201B07A, ioaddr + 0xB8);
+               } else if (startup) {
+                       /* Start with 10mbps to do autonegotiation. */
+                       iowrite32(0x32, ioaddr + CSR12);
+                       new_csr6 = 0x00420000;
+                       iowrite32(0x0001B078, ioaddr + 0xB8);
+                       iowrite32(0x0201B078, ioaddr + 0xB8);
+               } else if (dev->if_port == 3  ||  dev->if_port == 5) {
+                       iowrite32(0x33, ioaddr + CSR12);
+                       new_csr6 = 0x01860000;
+                       /* Trigger autonegotiation. */
+                       iowrite32(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
+               } else {
+                       iowrite32(0x32, ioaddr + CSR12);
+                       new_csr6 = 0x00420000;
+                       iowrite32(0x1F078, ioaddr + 0xB8);
+               }
+       } else {                                        /* Unknown chip type with no media table. */
+               if (tp->default_port == 0)
+                       dev->if_port = tp->mii_cnt ? 11 : 3;
+               if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+                       new_csr6 = 0x020E0000;
+               } else if (tulip_media_cap[dev->if_port] & MediaIsFx) {
+                       new_csr6 = 0x02860000;
+               } else
+                       new_csr6 = 0x03860000;
+               if (tulip_debug > 1)
+                       netdev_dbg(dev, "No media description table, assuming %s transceiver, CSR12 %02x\n",
+                                  medianame[dev->if_port],
+                                  ioread32(ioaddr + CSR12));
+       }
+       tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
+       mdelay(1);
+ }
+ /*
+   Check the MII negotiated duplex and change the CSR6 setting if
+   required.
+   Return 0 if everything is OK.
+   Return < 0 if the transceiver is missing or has no link beat.
+   */
+ int tulip_check_duplex(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       unsigned int bmsr, lpa, negotiated, new_csr6;
+       bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
+       lpa = tulip_mdio_read(dev, tp->phys[0], MII_LPA);
+       if (tulip_debug > 1)
+               dev_info(&dev->dev, "MII status %04x, Link partner report %04x\n",
+                        bmsr, lpa);
+       if (bmsr == 0xffff)
+               return -2;
+       if ((bmsr & BMSR_LSTATUS) == 0) {
+               int new_bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
+               if ((new_bmsr & BMSR_LSTATUS) == 0) {
+                       if (tulip_debug  > 1)
+                               dev_info(&dev->dev,
+                                        "No link beat on the MII interface, status %04x\n",
+                                        new_bmsr);
+                       return -1;
+               }
+       }
+       negotiated = lpa & tp->advertising[0];
+       tp->full_duplex = mii_duplex(tp->full_duplex_lock, negotiated);
+       new_csr6 = tp->csr6;
+       if (negotiated & LPA_100) new_csr6 &= ~TxThreshold;
+       else                      new_csr6 |= TxThreshold;
+       if (tp->full_duplex) new_csr6 |= FullDuplex;
+       else                 new_csr6 &= ~FullDuplex;
+       if (new_csr6 != tp->csr6) {
+               tp->csr6 = new_csr6;
+               tulip_restart_rxtx(tp);
+               if (tulip_debug > 0)
+                       dev_info(&dev->dev,
+                                "Setting %s-duplex based on MII#%d link partner capability of %04x\n",
+                                tp->full_duplex ? "full" : "half",
+                                tp->phys[0], lpa);
+               return 1;
+       }
+       return 0;
+ }
+ void __devinit tulip_find_mii (struct net_device *dev, int board_idx)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int phyn, phy_idx = 0;
+       int mii_reg0;
+       int mii_advert;
+       unsigned int to_advert, new_bmcr, ane_switch;
+       /* Find the connected MII xcvrs.
+          Doing this in open() would allow detecting external xcvrs later,
+          but takes much time. */
+       for (phyn = 1; phyn <= 32 && phy_idx < sizeof (tp->phys); phyn++) {
+               int phy = phyn & 0x1f;
+               int mii_status = tulip_mdio_read (dev, phy, MII_BMSR);
+               if ((mii_status & 0x8301) == 0x8001 ||
+                   ((mii_status & BMSR_100BASE4) == 0 &&
+                    (mii_status & 0x7800) != 0)) {
+                       /* preserve Becker logic, gain indentation level */
+               } else {
+                       continue;
+               }
+               mii_reg0 = tulip_mdio_read (dev, phy, MII_BMCR);
+               mii_advert = tulip_mdio_read (dev, phy, MII_ADVERTISE);
+               ane_switch = 0;
+               /* if not advertising at all, gen an
+                * advertising value from the capability
+                * bits in BMSR
+                */
+               if ((mii_advert & ADVERTISE_ALL) == 0) {
+                       unsigned int tmpadv = tulip_mdio_read (dev, phy, MII_BMSR);
+                       mii_advert = ((tmpadv >> 6) & 0x3e0) | 1;
+               }
+               if (tp->mii_advertise) {
+                       tp->advertising[phy_idx] =
+                       to_advert = tp->mii_advertise;
+               } else if (tp->advertising[phy_idx]) {
+                       to_advert = tp->advertising[phy_idx];
+               } else {
+                       tp->advertising[phy_idx] =
+                       tp->mii_advertise =
+                       to_advert = mii_advert;
+               }
+               tp->phys[phy_idx++] = phy;
+               pr_info("tulip%d:  MII transceiver #%d config %04x status %04x advertising %04x\n",
+                       board_idx, phy, mii_reg0, mii_status, mii_advert);
+               /* Fixup for DLink with miswired PHY. */
+               if (mii_advert != to_advert) {
+                       pr_debug("tulip%d:  Advertising %04x on PHY %d, previously advertising %04x\n",
+                                board_idx, to_advert, phy, mii_advert);
+                       tulip_mdio_write (dev, phy, 4, to_advert);
+               }
+               /* Enable autonegotiation: some boards default to off. */
+               if (tp->default_port == 0) {
+                       new_bmcr = mii_reg0 | BMCR_ANENABLE;
+                       if (new_bmcr != mii_reg0) {
+                               new_bmcr |= BMCR_ANRESTART;
+                               ane_switch = 1;
+                       }
+               }
+               /* ...or disable nway, if forcing media */
+               else {
+                       new_bmcr = mii_reg0 & ~BMCR_ANENABLE;
+                       if (new_bmcr != mii_reg0)
+                               ane_switch = 1;
+               }
+               /* clear out bits we never want at this point */
+               new_bmcr &= ~(BMCR_CTST | BMCR_FULLDPLX | BMCR_ISOLATE |
+                             BMCR_PDOWN | BMCR_SPEED100 | BMCR_LOOPBACK |
+                             BMCR_RESET);
+               if (tp->full_duplex)
+                       new_bmcr |= BMCR_FULLDPLX;
+               if (tulip_media_cap[tp->default_port] & MediaIs100)
+                       new_bmcr |= BMCR_SPEED100;
+               if (new_bmcr != mii_reg0) {
+                       /* some phys need the ANE switch to
+                        * happen before forced media settings
+                        * will "take."  However, we write the
+                        * same value twice in order not to
+                        * confuse the sane phys.
+                        */
+                       if (ane_switch) {
+                               tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr);
+                               udelay (10);
+                       }
+                       tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr);
+               }
+       }
+       tp->mii_cnt = phy_idx;
+       if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) {
+               pr_info("tulip%d: ***WARNING***: No MII transceiver found!\n",
+                       board_idx);
+               tp->phys[0] = 1;
+       }
+ }
index 0000000,52d898b..9c16e4a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,173 +1,170 @@@
+ /*
+       drivers/net/tulip/pnic.c
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
 -
+       Please submit bugs to http://bugzilla.kernel.org/ .
+ */
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/jiffies.h>
+ #include "tulip.h"
+ void pnic_do_nway(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       u32 phy_reg = ioread32(ioaddr + 0xB8);
+       u32 new_csr6 = tp->csr6 & ~0x40C40200;
+       if (phy_reg & 0x78000000) { /* Ignore baseT4 */
+               if (phy_reg & 0x20000000)               dev->if_port = 5;
+               else if (phy_reg & 0x40000000)  dev->if_port = 3;
+               else if (phy_reg & 0x10000000)  dev->if_port = 4;
+               else if (phy_reg & 0x08000000)  dev->if_port = 0;
+               tp->nwayset = 1;
+               new_csr6 = (dev->if_port & 1) ? 0x01860000 : 0x00420000;
+               iowrite32(0x32 | (dev->if_port & 1), ioaddr + CSR12);
+               if (dev->if_port & 1)
+                       iowrite32(0x1F868, ioaddr + 0xB8);
+               if (phy_reg & 0x30000000) {
+                       tp->full_duplex = 1;
+                       new_csr6 |= 0x00000200;
+               }
+               if (tulip_debug > 1)
+                       netdev_dbg(dev, "PNIC autonegotiated status %08x, %s\n",
+                                  phy_reg, medianame[dev->if_port]);
+               if (tp->csr6 != new_csr6) {
+                       tp->csr6 = new_csr6;
+                       /* Restart Tx */
+                       tulip_restart_rxtx(tp);
+                       dev->trans_start = jiffies;
+               }
+       }
+ }
+ void pnic_lnk_change(struct net_device *dev, int csr5)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int phy_reg = ioread32(ioaddr + 0xB8);
+       if (tulip_debug > 1)
+               netdev_dbg(dev, "PNIC link changed state %08x, CSR5 %08x\n",
+                          phy_reg, csr5);
+       if (ioread32(ioaddr + CSR5) & TPLnkFail) {
+               iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
+               /* If we use an external MII, then we mustn't use the
+                * internal negotiation.
+                */
+               if (tulip_media_cap[dev->if_port] & MediaIsMII)
+                       return;
+               if (! tp->nwayset || time_after(jiffies, dev_trans_start(dev) + 1*HZ)) {
+                       tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
+                       iowrite32(tp->csr6, ioaddr + CSR6);
+                       iowrite32(0x30, ioaddr + CSR12);
+                       iowrite32(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
+                       dev->trans_start = jiffies;
+               }
+       } else if (ioread32(ioaddr + CSR5) & TPLnkPass) {
+               if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+                       spin_lock(&tp->lock);
+                       tulip_check_duplex(dev);
+                       spin_unlock(&tp->lock);
+               } else {
+                       pnic_do_nway(dev);
+               }
+               iowrite32((ioread32(ioaddr + CSR7) & ~TPLnkPass) | TPLnkFail, ioaddr + CSR7);
+       }
+ }
+ void pnic_timer(unsigned long data)
+ {
+       struct net_device *dev = (struct net_device *)data;
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int next_tick = 60*HZ;
+       if(!ioread32(ioaddr + CSR7)) {
+               /* the timer was called due to a work overflow
+                * in the interrupt handler. Skip the connection
+                * checks, the nic is definitively speaking with
+                * his link partner.
+                */
+               goto too_good_connection;
+       }
+       if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+               spin_lock_irq(&tp->lock);
+               if (tulip_check_duplex(dev) > 0)
+                       next_tick = 3*HZ;
+               spin_unlock_irq(&tp->lock);
+       } else {
+               int csr12 = ioread32(ioaddr + CSR12);
+               int new_csr6 = tp->csr6 & ~0x40C40200;
+               int phy_reg = ioread32(ioaddr + 0xB8);
+               int csr5 = ioread32(ioaddr + CSR5);
+               if (tulip_debug > 1)
+                       netdev_dbg(dev, "PNIC timer PHY status %08x, %s CSR5 %08x\n",
+                                  phy_reg, medianame[dev->if_port], csr5);
+               if (phy_reg & 0x04000000) {     /* Remote link fault */
+                       iowrite32(0x0201F078, ioaddr + 0xB8);
+                       next_tick = 1*HZ;
+                       tp->nwayset = 0;
+               } else if (phy_reg & 0x78000000) { /* Ignore baseT4 */
+                       pnic_do_nway(dev);
+                       next_tick = 60*HZ;
+               } else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
+                       if (tulip_debug > 1)
+                               netdev_dbg(dev, "%s link beat failed, CSR12 %04x, CSR5 %08x, PHY %03x\n",
+                                          medianame[dev->if_port],
+                                          csr12,
+                                          ioread32(ioaddr + CSR5),
+                                          ioread32(ioaddr + 0xB8));
+                       next_tick = 3*HZ;
+                       if (tp->medialock) {
+                       } else if (tp->nwayset  &&  (dev->if_port & 1)) {
+                               next_tick = 1*HZ;
+                       } else if (dev->if_port == 0) {
+                               dev->if_port = 3;
+                               iowrite32(0x33, ioaddr + CSR12);
+                               new_csr6 = 0x01860000;
+                               iowrite32(0x1F868, ioaddr + 0xB8);
+                       } else {
+                               dev->if_port = 0;
+                               iowrite32(0x32, ioaddr + CSR12);
+                               new_csr6 = 0x00420000;
+                               iowrite32(0x1F078, ioaddr + 0xB8);
+                       }
+                       if (tp->csr6 != new_csr6) {
+                               tp->csr6 = new_csr6;
+                               /* Restart Tx */
+                               tulip_restart_rxtx(tp);
+                               dev->trans_start = jiffies;
+                               if (tulip_debug > 1)
+                                       dev_info(&dev->dev,
+                                                "Changing PNIC configuration to %s %s-duplex, CSR6 %08x\n",
+                                                medianame[dev->if_port],
+                                                tp->full_duplex ? "full" : "half",
+                                                new_csr6);
+                       }
+               }
+       }
+ too_good_connection:
+       mod_timer(&tp->timer, RUN_AT(next_tick));
+       if(!ioread32(ioaddr + CSR7)) {
+               if (tulip_debug > 1)
+                       dev_info(&dev->dev, "sw timer wakeup\n");
+               disable_irq(dev->irq);
+               tulip_refill_rx(dev);
+               enable_irq(dev->irq);
+               iowrite32(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+       }
+ }
index 0000000,93358ee..04a7e47
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,406 +1,403 @@@
+ /*
+       drivers/net/tulip/pnic2.c
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+         Modified to hep support PNIC_II by Kevin B. Hendricks
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
 -
+         Please submit bugs to http://bugzilla.kernel.org/ .
+ */
+ /* Understanding the PNIC_II - everything is this file is based
+  * on the PNIC_II_PDF datasheet which is sorely lacking in detail
+  *
+  * As I understand things, here are the registers and bits that
+  * explain the masks and constants used in this file that are
+  * either different from the 21142/3 or important for basic operation.
+  *
+  *
+  * CSR 6  (mask = 0xfe3bd1fd of bits not to change)
+  * -----
+  * Bit 24    - SCR
+  * Bit 23    - PCS
+  * Bit 22    - TTM (Trasmit Threshold Mode)
+  * Bit 18    - Port Select
+  * Bit 13    - Start - 1, Stop - 0 Transmissions
+  * Bit 11:10 - Loop Back Operation Mode
+  * Bit 9     - Full Duplex mode (Advertise 10BaseT-FD is CSR14<7> is set)
+  * Bit 1     - Start - 1, Stop - 0 Receive
+  *
+  *
+  * CSR 14  (mask = 0xfff0ee39 of bits not to change)
+  * ------
+  * Bit 19    - PAUSE-Pause
+  * Bit 18    - Advertise T4
+  * Bit 17    - Advertise 100baseTx-FD
+  * Bit 16    - Advertise 100baseTx-HD
+  * Bit 12    - LTE - Link Test Enable
+  * Bit 7     - ANE - Auto Negotiate Enable
+  * Bit 6     - HDE - Advertise 10baseT-HD
+  * Bit 2     - Reset to Power down - kept as 1 for normal operation
+  * Bit 1     -  Loop Back enable for 10baseT MCC
+  *
+  *
+  * CSR 12
+  * ------
+  * Bit 25    - Partner can do T4
+  * Bit 24    - Partner can do 100baseTx-FD
+  * Bit 23    - Partner can do 100baseTx-HD
+  * Bit 22    - Partner can do 10baseT-FD
+  * Bit 21    - Partner can do 10baseT-HD
+  * Bit 15    - LPN is 1 if all above bits are valid other wise 0
+  * Bit 14:12 - autonegotiation state (write 001 to start autonegotiate)
+  * Bit 3     - Autopolarity state
+  * Bit 2     - LS10B - link state of 10baseT 0 - good, 1 - failed
+  * Bit 1     - LS100B - link state of 100baseT 0 - good, 1 - failed
+  *
+  *
+  * Data Port Selection Info
+  *-------------------------
+  *
+  * CSR14<7>   CSR6<18>    CSR6<22>    CSR6<23>    CSR6<24>   MODE/PORT
+  *   1           0           0 (X)       0 (X)       1        NWAY
+  *   0           0           1           0 (X)       0        10baseT
+  *   0           1           0           1           1 (X)    100baseT
+  *
+  *
+  */
+ #include "tulip.h"
+ #include <linux/delay.h>
+ void pnic2_timer(unsigned long data)
+ {
+       struct net_device *dev = (struct net_device *)data;
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int next_tick = 60*HZ;
+       if (tulip_debug > 3)
+               dev_info(&dev->dev, "PNIC2 negotiation status %08x\n",
+                        ioread32(ioaddr + CSR12));
+       if (next_tick) {
+               mod_timer(&tp->timer, RUN_AT(next_tick));
+       }
+ }
+ void pnic2_start_nway(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+         int csr14;
+         int csr12;
+         /* set up what to advertise during the negotiation */
+         /* load in csr14  and mask off bits not to touch
+          * comment at top of file explains mask value
+          */
+       csr14 = (ioread32(ioaddr + CSR14) & 0xfff0ee39);
+         /* bit 17 - advetise 100baseTx-FD */
+         if (tp->sym_advertise & 0x0100) csr14 |= 0x00020000;
+         /* bit 16 - advertise 100baseTx-HD */
+         if (tp->sym_advertise & 0x0080) csr14 |= 0x00010000;
+         /* bit 6 - advertise 10baseT-HD */
+         if (tp->sym_advertise & 0x0020) csr14 |= 0x00000040;
+         /* Now set bit 12 Link Test Enable, Bit 7 Autonegotiation Enable
+          * and bit 0 Don't PowerDown 10baseT
+          */
+         csr14 |= 0x00001184;
+       if (tulip_debug > 1)
+               netdev_dbg(dev, "Restarting PNIC2 autonegotiation, csr14=%08x\n",
+                          csr14);
+         /* tell pnic2_lnk_change we are doing an nway negotiation */
+       dev->if_port = 0;
+       tp->nway = tp->mediasense = 1;
+       tp->nwayset = tp->lpar = 0;
+         /* now we have to set up csr6 for NWAY state */
+       tp->csr6 = ioread32(ioaddr + CSR6);
+       if (tulip_debug > 1)
+               netdev_dbg(dev, "On Entry to Nway, csr6=%08x\n", tp->csr6);
+         /* mask off any bits not to touch
+          * comment at top of file explains mask value
+          */
+       tp->csr6 = tp->csr6 & 0xfe3bd1fd;
+         /* don't forget that bit 9 is also used for advertising */
+         /* advertise 10baseT-FD for the negotiation (bit 9) */
+         if (tp->sym_advertise & 0x0040) tp->csr6 |= 0x00000200;
+         /* set bit 24 for nway negotiation mode ...
+          * see Data Port Selection comment at top of file
+          * and "Stop" - reset both Transmit (bit 13) and Receive (bit 1)
+          */
+         tp->csr6 |= 0x01000000;
+       iowrite32(csr14, ioaddr + CSR14);
+       iowrite32(tp->csr6, ioaddr + CSR6);
+         udelay(100);
+         /* all set up so now force the negotiation to begin */
+         /* read in current values and mask off all but the
+        * Autonegotiation bits 14:12.  Writing a 001 to those bits
+          * should start the autonegotiation
+          */
+         csr12 = (ioread32(ioaddr + CSR12) & 0xffff8fff);
+         csr12 |= 0x1000;
+       iowrite32(csr12, ioaddr + CSR12);
+ }
+ void pnic2_lnk_change(struct net_device *dev, int csr5)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+         int csr14;
+         /* read the staus register to find out what is up */
+       int csr12 = ioread32(ioaddr + CSR12);
+       if (tulip_debug > 1)
+               dev_info(&dev->dev,
+                        "PNIC2 link status interrupt %08x,  CSR5 %x, %08x\n",
+                        csr12, csr5, ioread32(ioaddr + CSR14));
+       /* If NWay finished and we have a negotiated partner capability.
+          * check bits 14:12 for bit pattern 101 - all is good
+          */
+       if (tp->nway  &&  !tp->nwayset) {
+               /* we did an auto negotiation */
+                 if ((csr12 & 0x7000) == 0x5000) {
+                      /* negotiation ended successfully */
+                      /* get the link partners reply and mask out all but
+                         * bits 24-21 which show the partners capabilities
+                         * and match those to what we advertised
+                         *
+                         * then begin to interpret the results of the negotiation.
+                         * Always go in this order : (we are ignoring T4 for now)
+                         *     100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD
+                         */
+                       int negotiated = ((csr12 >> 16) & 0x01E0) & tp->sym_advertise;
+                       tp->lpar = (csr12 >> 16);
+                       tp->nwayset = 1;
+                         if (negotiated & 0x0100)        dev->if_port = 5;
+                       else if (negotiated & 0x0080)   dev->if_port = 3;
+                       else if (negotiated & 0x0040)   dev->if_port = 4;
+                       else if (negotiated & 0x0020)   dev->if_port = 0;
+                       else {
+                            if (tulip_debug > 1)
+                                    dev_info(&dev->dev,
+                                             "funny autonegotiate result csr12 %08x advertising %04x\n",
+                                             csr12, tp->sym_advertise);
+                            tp->nwayset = 0;
+                            /* so check  if 100baseTx link state is okay */
+                            if ((csr12 & 2) == 0  &&  (tp->sym_advertise & 0x0180))
+                              dev->if_port = 3;
+                       }
+                       /* now record the duplex that was negotiated */
+                       tp->full_duplex = 0;
+                       if ((dev->if_port == 4) || (dev->if_port == 5))
+                              tp->full_duplex = 1;
+                       if (tulip_debug > 1) {
+                              if (tp->nwayset)
+                                      dev_info(&dev->dev,
+                                               "Switching to %s based on link negotiation %04x & %04x = %04x\n",
+                                               medianame[dev->if_port],
+                                               tp->sym_advertise, tp->lpar,
+                                               negotiated);
+                       }
+                         /* remember to turn off bit 7 - autonegotiate
+                          * enable so we can properly end nway mode and
+                          * set duplex (ie. use csr6<9> again)
+                          */
+                       csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
+                         iowrite32(csr14,ioaddr + CSR14);
+                         /* now set the data port and operating mode
+                        * (see the Data Port Selection comments at
+                        * the top of the file
+                        */
+                       /* get current csr6 and mask off bits not to touch */
+                       /* see comment at top of file */
+                       tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
+                       /* so if using if_port 3 or 5 then select the 100baseT
+                        * port else select the 10baseT port.
+                        * See the Data Port Selection table at the top
+                        * of the file which was taken from the PNIC_II.PDF
+                        * datasheet
+                        */
+                       if (dev->if_port & 1) tp->csr6 |= 0x01840000;
+                       else tp->csr6 |= 0x00400000;
+                       /* now set the full duplex bit appropriately */
+                       if (tp->full_duplex) tp->csr6 |= 0x00000200;
+                       iowrite32(1, ioaddr + CSR13);
+                       if (tulip_debug > 2)
+                               netdev_dbg(dev, "Setting CSR6 %08x/%x CSR12 %08x\n",
+                                          tp->csr6,
+                                          ioread32(ioaddr + CSR6),
+                                          ioread32(ioaddr + CSR12));
+                       /* now the following actually writes out the
+                        * new csr6 values
+                        */
+                       tulip_start_rxtx(tp);
+                         return;
+               } else {
+                       dev_info(&dev->dev,
+                                "Autonegotiation failed, using %s, link beat status %04x\n",
+                                medianame[dev->if_port], csr12);
+                         /* remember to turn off bit 7 - autonegotiate
+                          * enable so we don't forget
+                          */
+                       csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
+                         iowrite32(csr14,ioaddr + CSR14);
+                         /* what should we do when autonegotiate fails?
+                          * should we try again or default to baseline
+                          * case.  I just don't know.
+                          *
+                          * for now default to some baseline case
+                          */
+                        dev->if_port = 0;
+                          tp->nway = 0;
+                          tp->nwayset = 1;
+                          /* set to 10baseTx-HD - see Data Port Selection
+                           * comment given at the top of the file
+                           */
+                        tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
+                          tp->csr6 |= 0x00400000;
+                        tulip_restart_rxtx(tp);
+                          return;
+               }
+       }
+       if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
+            (dev->if_port == 3  ||  dev->if_port == 5) &&
+            (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) {
+               /* Link blew? Maybe restart NWay. */
+               if (tulip_debug > 2)
+                       netdev_dbg(dev, "Ugh! Link blew?\n");
+               del_timer_sync(&tp->timer);
+               pnic2_start_nway(dev);
+               tp->timer.expires = RUN_AT(3*HZ);
+               add_timer(&tp->timer);
+                 return;
+       }
+         if (dev->if_port == 3  ||  dev->if_port == 5) {
+               /* we are at 100mb and a potential link change occurred */
+               if (tulip_debug > 1)
+                       dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
+                                medianame[dev->if_port],
+                                (csr12 & 2) ? "failed" : "good");
+                 /* check 100 link beat */
+                 tp->nway = 0;
+                 tp->nwayset = 1;
+                 /* if failed then try doing an nway to get in sync */
+               if ((csr12 & 2)  &&  ! tp->medialock) {
+                       del_timer_sync(&tp->timer);
+                       pnic2_start_nway(dev);
+                       tp->timer.expires = RUN_AT(3*HZ);
+                               add_timer(&tp->timer);
+                 }
+                 return;
+         }
+       if (dev->if_port == 0  ||  dev->if_port == 4) {
+               /* we are at 10mb and a potential link change occurred */
+               if (tulip_debug > 1)
+                       dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
+                                medianame[dev->if_port],
+                                (csr12 & 4) ? "failed" : "good");
+                 tp->nway = 0;
+                 tp->nwayset = 1;
+                 /* if failed, try doing an nway to get in sync */
+               if ((csr12 & 4)  &&  ! tp->medialock) {
+                       del_timer_sync(&tp->timer);
+                       pnic2_start_nway(dev);
+                       tp->timer.expires = RUN_AT(3*HZ);
+                               add_timer(&tp->timer);
+                 }
+                 return;
+         }
+       if (tulip_debug > 1)
+               dev_info(&dev->dev, "PNIC2 Link Change Default?\n");
+         /* if all else fails default to trying 10baseT-HD */
+       dev->if_port = 0;
+         /* make sure autonegotiate enable is off */
+       csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
+         iowrite32(csr14,ioaddr + CSR14);
+         /* set to 10baseTx-HD - see Data Port Selection
+          * comment given at the top of the file
+          */
+       tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
+         tp->csr6 |= 0x00400000;
+       tulip_restart_rxtx(tp);
+ }
index 0000000,2017faf..19078d2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,179 +1,176 @@@
+ /*
+       drivers/net/tulip/timer.c
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
 -
+       Please submit bugs to http://bugzilla.kernel.org/ .
+ */
+ #include "tulip.h"
+ void tulip_media_task(struct work_struct *work)
+ {
+       struct tulip_private *tp =
+               container_of(work, struct tulip_private, media_work);
+       struct net_device *dev = tp->dev;
+       void __iomem *ioaddr = tp->base_addr;
+       u32 csr12 = ioread32(ioaddr + CSR12);
+       int next_tick = 2*HZ;
+       unsigned long flags;
+       if (tulip_debug > 2) {
+               netdev_dbg(dev, "Media selection tick, %s, status %08x mode %08x SIA %08x %08x %08x %08x\n",
+                          medianame[dev->if_port],
+                          ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR6),
+                          csr12, ioread32(ioaddr + CSR13),
+                          ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
+       }
+       switch (tp->chip_id) {
+       case DC21140:
+       case DC21142:
+       case MX98713:
+       case COMPEX9881:
+       case DM910X:
+       default: {
+               struct medialeaf *mleaf;
+               unsigned char *p;
+               if (tp->mtable == NULL) {       /* No EEPROM info, use generic code. */
+                       /* Not much that can be done.
+                          Assume this a generic MII or SYM transceiver. */
+                       next_tick = 60*HZ;
+                       if (tulip_debug > 2)
+                               netdev_dbg(dev, "network media monitor CSR6 %08x CSR12 0x%02x\n",
+                                          ioread32(ioaddr + CSR6),
+                                          csr12 & 0xff);
+                       break;
+               }
+               mleaf = &tp->mtable->mleaf[tp->cur_index];
+               p = mleaf->leafdata;
+               switch (mleaf->type) {
+               case 0: case 4: {
+                       /* Type 0 serial or 4 SYM transceiver.  Check the link beat bit. */
+                       int offset = mleaf->type == 4 ? 5 : 2;
+                       s8 bitnum = p[offset];
+                       if (p[offset+1] & 0x80) {
+                               if (tulip_debug > 1)
+                                       netdev_dbg(dev, "Transceiver monitor tick CSR12=%#02x, no media sense\n",
+                                                  csr12);
+                               if (mleaf->type == 4) {
+                                       if (mleaf->media == 3 && (csr12 & 0x02))
+                                               goto select_next_media;
+                               }
+                               break;
+                       }
+                       if (tulip_debug > 2)
+                               netdev_dbg(dev, "Transceiver monitor tick: CSR12=%#02x bit %d is %d, expecting %d\n",
+                                          csr12, (bitnum >> 1) & 7,
+                                          (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
+                                          (bitnum >= 0));
+                       /* Check that the specified bit has the proper value. */
+                       if ((bitnum < 0) !=
+                               ((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
+                               if (tulip_debug > 2)
+                                       netdev_dbg(dev, "Link beat detected for %s\n",
+                                                  medianame[mleaf->media & MEDIA_MASK]);
+                               if ((p[2] & 0x61) == 0x01)      /* Bogus Znyx board. */
+                                       goto actually_mii;
+                               netif_carrier_on(dev);
+                               break;
+                       }
+                       netif_carrier_off(dev);
+                       if (tp->medialock)
+                               break;
+         select_next_media:
+                       if (--tp->cur_index < 0) {
+                               /* We start again, but should instead look for default. */
+                               tp->cur_index = tp->mtable->leafcount - 1;
+                       }
+                       dev->if_port = tp->mtable->mleaf[tp->cur_index].media;
+                       if (tulip_media_cap[dev->if_port] & MediaIsFD)
+                               goto select_next_media; /* Skip FD entries. */
+                       if (tulip_debug > 1)
+                               netdev_dbg(dev, "No link beat on media %s, trying transceiver type %s\n",
+                                          medianame[mleaf->media & MEDIA_MASK],
+                                          medianame[tp->mtable->mleaf[tp->cur_index].media]);
+                       tulip_select_media(dev, 0);
+                       /* Restart the transmit process. */
+                       tulip_restart_rxtx(tp);
+                       next_tick = (24*HZ)/10;
+                       break;
+               }
+               case 1:  case 3:                /* 21140, 21142 MII */
+               actually_mii:
+                       if (tulip_check_duplex(dev) < 0) {
+                               netif_carrier_off(dev);
+                               next_tick = 3*HZ;
+                       } else {
+                               netif_carrier_on(dev);
+                               next_tick = 60*HZ;
+                       }
+                       break;
+               case 2:                                 /* 21142 serial block has no link beat. */
+               default:
+                       break;
+               }
+       }
+       break;
+       }
+       spin_lock_irqsave(&tp->lock, flags);
+       if (tp->timeout_recovery) {
+               tulip_tx_timeout_complete(tp, ioaddr);
+               tp->timeout_recovery = 0;
+       }
+       spin_unlock_irqrestore(&tp->lock, flags);
+       /* mod_timer synchronizes us with potential add_timer calls
+        * from interrupts.
+        */
+       mod_timer(&tp->timer, RUN_AT(next_tick));
+ }
+ void mxic_timer(unsigned long data)
+ {
+       struct net_device *dev = (struct net_device *)data;
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int next_tick = 60*HZ;
+       if (tulip_debug > 3) {
+               dev_info(&dev->dev, "MXIC negotiation status %08x\n",
+                        ioread32(ioaddr + CSR12));
+       }
+       if (next_tick) {
+               mod_timer(&tp->timer, RUN_AT(next_tick));
+       }
+ }
+ void comet_timer(unsigned long data)
+ {
+       struct net_device *dev = (struct net_device *)data;
+       struct tulip_private *tp = netdev_priv(dev);
+       int next_tick = 60*HZ;
+       if (tulip_debug > 1)
+               netdev_dbg(dev, "Comet link status %04x partner capability %04x\n",
+                          tulip_mdio_read(dev, tp->phys[0], 1),
+                          tulip_mdio_read(dev, tp->phys[0], 5));
+       /* mod_timer synchronizes us with potential add_timer calls
+        * from interrupts.
+        */
+       if (tulip_check_duplex(dev) < 0)
+               { netif_carrier_off(dev); }
+       else
+               { netif_carrier_on(dev); }
+       mod_timer(&tp->timer, RUN_AT(next_tick));
+ }
index 0000000,9db5289..fb3887c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,573 +1,570 @@@
+ /*
+       drivers/net/tulip/tulip.h
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
 -
+       Please submit bugs to http://bugzilla.kernel.org/ .
+ */
+ #ifndef __NET_TULIP_H__
+ #define __NET_TULIP_H__
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/spinlock.h>
+ #include <linux/netdevice.h>
+ #include <linux/ethtool.h>
+ #include <linux/timer.h>
+ #include <linux/delay.h>
+ #include <linux/pci.h>
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/unaligned.h>
+ /* undefine, or define to various debugging levels (>4 == obscene levels) */
+ #define TULIP_DEBUG 1
+ #ifdef CONFIG_TULIP_MMIO
+ #define TULIP_BAR     1       /* CBMA */
+ #else
+ #define TULIP_BAR     0       /* CBIO */
+ #endif
+ struct tulip_chip_table {
+       char *chip_name;
+       int io_size;
+       int valid_intrs;        /* CSR7 interrupt enable settings */
+       int flags;
+       void (*media_timer) (unsigned long);
+       work_func_t media_task;
+ };
+ enum tbl_flag {
+       HAS_MII                 = 0x00001,
+       HAS_MEDIA_TABLE         = 0x00002,
+       CSR12_IN_SROM           = 0x00004,
+       ALWAYS_CHECK_MII        = 0x00008,
+       HAS_ACPI                = 0x00010,
+       MC_HASH_ONLY            = 0x00020, /* Hash-only multicast filter. */
+       HAS_PNICNWAY            = 0x00080,
+       HAS_NWAY                = 0x00040, /* Uses internal NWay xcvr. */
+       HAS_INTR_MITIGATION     = 0x00100,
+       IS_ASIX                 = 0x00200,
+       HAS_8023X               = 0x00400,
+       COMET_MAC_ADDR          = 0x00800,
+       HAS_PCI_MWI             = 0x01000,
+       HAS_PHY_IRQ             = 0x02000,
+       HAS_SWAPPED_SEEPROM     = 0x04000,
+       NEEDS_FAKE_MEDIA_TABLE  = 0x08000,
+       COMET_PM                = 0x10000,
+ };
+ /* chip types.  careful!  order is VERY IMPORTANT here, as these
+  * are used throughout the driver as indices into arrays */
+ /* Note 21142 == 21143. */
+ enum chips {
+       DC21040 = 0,
+       DC21041 = 1,
+       DC21140 = 2,
+       DC21142 = 3, DC21143 = 3,
+       LC82C168,
+       MX98713,
+       MX98715,
+       MX98725,
+       AX88140,
+       PNIC2,
+       COMET,
+       COMPEX9881,
+       I21145,
+       DM910X,
+       CONEXANT,
+ };
+ enum MediaIs {
+       MediaIsFD = 1,
+       MediaAlwaysFD = 2,
+       MediaIsMII = 4,
+       MediaIsFx = 8,
+       MediaIs100 = 16
+ };
+ /* Offsets to the Command and Status Registers, "CSRs".  All accesses
+    must be longword instructions and quadword aligned. */
+ enum tulip_offsets {
+       CSR0 = 0,
+       CSR1 = 0x08,
+       CSR2 = 0x10,
+       CSR3 = 0x18,
+       CSR4 = 0x20,
+       CSR5 = 0x28,
+       CSR6 = 0x30,
+       CSR7 = 0x38,
+       CSR8 = 0x40,
+       CSR9 = 0x48,
+       CSR10 = 0x50,
+       CSR11 = 0x58,
+       CSR12 = 0x60,
+       CSR13 = 0x68,
+       CSR14 = 0x70,
+       CSR15 = 0x78,
+       CSR18 = 0x88,
+       CSR19 = 0x8c,
+       CSR20 = 0x90,
+       CSR27 = 0xAC,
+       CSR28 = 0xB0,
+ };
+ /* register offset and bits for CFDD PCI config reg */
+ enum pci_cfg_driver_reg {
+       CFDD = 0x40,
+       CFDD_Sleep = (1 << 31),
+       CFDD_Snooze = (1 << 30),
+ };
+ #define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber)
+ /* The bits in the CSR5 status registers, mostly interrupt sources. */
+ enum status_bits {
+       TimerInt = 0x800,
+       SystemError = 0x2000,
+       TPLnkFail = 0x1000,
+       TPLnkPass = 0x10,
+       NormalIntr = 0x10000,
+       AbnormalIntr = 0x8000,
+       RxJabber = 0x200,
+       RxDied = 0x100,
+       RxNoBuf = 0x80,
+       RxIntr = 0x40,
+       TxFIFOUnderflow = 0x20,
+       RxErrIntr = 0x10,
+       TxJabber = 0x08,
+       TxNoBuf = 0x04,
+       TxDied = 0x02,
+       TxIntr = 0x01,
+ };
+ /* bit mask for CSR5 TX/RX process state */
+ #define CSR5_TS       0x00700000
+ #define CSR5_RS       0x000e0000
+ enum tulip_mode_bits {
+       TxThreshold             = (1 << 22),
+       FullDuplex              = (1 << 9),
+       TxOn                    = 0x2000,
+       AcceptBroadcast         = 0x0100,
+       AcceptAllMulticast      = 0x0080,
+       AcceptAllPhys           = 0x0040,
+       AcceptRunt              = 0x0008,
+       RxOn                    = 0x0002,
+       RxTx                    = (TxOn | RxOn),
+ };
+ enum tulip_busconfig_bits {
+       MWI                     = (1 << 24),
+       MRL                     = (1 << 23),
+       MRM                     = (1 << 21),
+       CALShift                = 14,
+       BurstLenShift           = 8,
+ };
+ /* The Tulip Rx and Tx buffer descriptors. */
+ struct tulip_rx_desc {
+       __le32 status;
+       __le32 length;
+       __le32 buffer1;
+       __le32 buffer2;
+ };
+ struct tulip_tx_desc {
+       __le32 status;
+       __le32 length;
+       __le32 buffer1;
+       __le32 buffer2;         /* We use only buffer 1.  */
+ };
+ enum desc_status_bits {
+       DescOwned    = 0x80000000,
+       DescWholePkt = 0x60000000,
+       DescEndPkt   = 0x40000000,
+       DescStartPkt = 0x20000000,
+       DescEndRing  = 0x02000000,
+       DescUseLink  = 0x01000000,
+       /*
+        * Error summary flag is logical or of 'CRC Error', 'Collision Seen',
+        * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated
+        * within tulip chip.
+        */
+       RxDescErrorSummary = 0x8000,
+       RxDescCRCError = 0x0002,
+       RxDescCollisionSeen = 0x0040,
+       /*
+        * 'Frame Too Long' flag is set if packet length including CRC exceeds
+        * 1518.  However, a full sized VLAN tagged frame is 1522 bytes
+        * including CRC.
+        *
+        * The tulip chip does not block oversized frames, and if this flag is
+        * set on a receive descriptor it does not indicate the frame has been
+        * truncated.  The receive descriptor also includes the actual length.
+        * Therefore we can safety ignore this flag and check the length
+        * ourselves.
+        */
+       RxDescFrameTooLong = 0x0080,
+       RxDescRunt = 0x0800,
+       RxDescDescErr = 0x4000,
+       RxWholePkt   = 0x00000300,
+       /*
+        * Top three bits of 14 bit frame length (status bits 27-29) should
+        * never be set as that would make frame over 2047 bytes. The Receive
+        * Watchdog flag (bit 4) may indicate the length is over 2048 and the
+        * length field is invalid.
+        */
+       RxLengthOver2047 = 0x38000010
+ };
+ enum t21143_csr6_bits {
+       csr6_sc = (1<<31),
+       csr6_ra = (1<<30),
+       csr6_ign_dest_msb = (1<<26),
+       csr6_mbo = (1<<25),
+       csr6_scr = (1<<24),  /* scramble mode flag: can't be set */
+       csr6_pcs = (1<<23),  /* Enables PCS functions (symbol mode requires csr6_ps be set) default is set */
+       csr6_ttm = (1<<22),  /* Transmit Threshold Mode, set for 10baseT, 0 for 100BaseTX */
+       csr6_sf = (1<<21),   /* Store and forward. If set ignores TR bits */
+       csr6_hbd = (1<<19),  /* Heart beat disable. Disables SQE function in 10baseT */
+       csr6_ps = (1<<18),   /* Port Select. 0 (defualt) = 10baseT, 1 = 100baseTX: can't be set */
+       csr6_ca = (1<<17),   /* Collision Offset Enable. If set uses special algorithm in low collision situations */
+       csr6_trh = (1<<15),  /* Transmit Threshold high bit */
+       csr6_trl = (1<<14),  /* Transmit Threshold low bit */
+       /***************************************************************
+        * This table shows transmit threshold values based on media   *
+        * and these two registers (from PNIC1 & 2 docs) Note: this is *
+        * all meaningless if sf is set.                               *
+        ***************************************************************/
+       /***********************************
+        * (trh,trl) * 100BaseTX * 10BaseT *
+        ***********************************
+        *   (0,0)   *     128   *    72   *
+        *   (0,1)   *     256   *    96   *
+        *   (1,0)   *     512   *   128   *
+        *   (1,1)   *    1024   *   160   *
+        ***********************************/
+       csr6_fc = (1<<12),   /* Forces a collision in next transmission (for testing in loopback mode) */
+       csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */
+       csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */
+       /* set both and you get (PHY) loopback */
+       csr6_fd = (1<<9),    /* Full duplex mode, disables hearbeat, no loopback */
+       csr6_pm = (1<<7),    /* Pass All Multicast */
+       csr6_pr = (1<<6),    /* Promiscuous mode */
+       csr6_sb = (1<<5),    /* Start(1)/Stop(0) backoff counter */
+       csr6_if = (1<<4),    /* Inverse Filtering, rejects only addresses in address table: can't be set */
+       csr6_pb = (1<<3),    /* Pass Bad Frames, (1) causes even bad frames to be passed on */
+       csr6_ho = (1<<2),    /* Hash-only filtering mode: can't be set */
+       csr6_hp = (1<<0),    /* Hash/Perfect Receive Filtering Mode: can't be set */
+       csr6_mask_capture = (csr6_sc | csr6_ca),
+       csr6_mask_defstate = (csr6_mask_capture | csr6_mbo),
+       csr6_mask_hdcap = (csr6_mask_defstate | csr6_hbd | csr6_ps),
+       csr6_mask_hdcaptt = (csr6_mask_hdcap  | csr6_trh | csr6_trl),
+       csr6_mask_fullcap = (csr6_mask_hdcaptt | csr6_fd),
+       csr6_mask_fullpromisc = (csr6_pr | csr6_pm),
+       csr6_mask_filters = (csr6_hp | csr6_ho | csr6_if),
+       csr6_mask_100bt = (csr6_scr | csr6_pcs | csr6_hbd),
+ };
+ enum tulip_comet_csr13_bits {
+ /* The LINKOFFE and LINKONE work in conjunction with LSCE, i.e. they
+  * determine which link status transition wakes up if LSCE is
+  * enabled */
+         comet_csr13_linkoffe = (1 << 17),
+         comet_csr13_linkone = (1 << 16),
+         comet_csr13_wfre = (1 << 10),
+         comet_csr13_mpre = (1 << 9),
+         comet_csr13_lsce = (1 << 8),
+         comet_csr13_wfr = (1 << 2),
+         comet_csr13_mpr = (1 << 1),
+         comet_csr13_lsc = (1 << 0),
+ };
+ enum tulip_comet_csr18_bits {
+         comet_csr18_pmes_sticky = (1 << 24),
+         comet_csr18_pm_mode = (1 << 19),
+         comet_csr18_apm_mode = (1 << 18),
+         comet_csr18_d3a = (1 << 7)
+ };
+ enum tulip_comet_csr20_bits {
+         comet_csr20_pmes = (1 << 15),
+ };
+ /* Keep the ring sizes a power of two for efficiency.
+    Making the Tx ring too large decreases the effectiveness of channel
+    bonding and packet priority.
+    There are no ill effects from too-large receive rings. */
+ #define TX_RING_SIZE  32
+ #define RX_RING_SIZE  128
+ #define MEDIA_MASK     31
+ /* The receiver on the DC21143 rev 65 can fail to close the last
+  * receive descriptor in certain circumstances (see errata) when
+  * using MWI. This can only occur if the receive buffer ends on
+  * a cache line boundary, so the "+ 4" below ensures it doesn't.
+  */
+ #define PKT_BUF_SZ    (1536 + 4)      /* Size of each temporary Rx buffer. */
+ #define TULIP_MIN_CACHE_LINE  8       /* in units of 32-bit words */
+ #if defined(__sparc__) || defined(__hppa__)
+ /* The UltraSparc PCI controllers will disconnect at every 64-byte
+  * crossing anyways so it makes no sense to tell Tulip to burst
+  * any more than that.
+  */
+ #define TULIP_MAX_CACHE_LINE  16      /* in units of 32-bit words */
+ #else
+ #define TULIP_MAX_CACHE_LINE  32      /* in units of 32-bit words */
+ #endif
+ /* Ring-wrap flag in length field, use for last ring entry.
+       0x01000000 means chain on buffer2 address,
+       0x02000000 means use the ring start address in CSR2/3.
+    Note: Some work-alike chips do not function correctly in chained mode.
+    The ASIX chip works only in chained mode.
+    Thus we indicates ring mode, but always write the 'next' field for
+    chained mode as well.
+ */
+ #define DESC_RING_WRAP 0x02000000
+ #define EEPROM_SIZE 512       /* 2 << EEPROM_ADDRLEN */
+ #define RUN_AT(x) (jiffies + (x))
+ #define get_u16(ptr) get_unaligned_le16((ptr))
+ struct medialeaf {
+       u8 type;
+       u8 media;
+       unsigned char *leafdata;
+ };
+ struct mediatable {
+       u16 defaultmedia;
+       u8 leafcount;
+       u8 csr12dir;            /* General purpose pin directions. */
+       unsigned has_mii:1;
+       unsigned has_nonmii:1;
+       unsigned has_reset:6;
+       u32 csr15dir;
+       u32 csr15val;           /* 21143 NWay setting. */
+       struct medialeaf mleaf[0];
+ };
+ struct mediainfo {
+       struct mediainfo *next;
+       int info_type;
+       int index;
+       unsigned char *info;
+ };
+ struct ring_info {
+       struct sk_buff  *skb;
+       dma_addr_t      mapping;
+ };
+ struct tulip_private {
+       const char *product_name;
+       struct net_device *next_module;
+       struct tulip_rx_desc *rx_ring;
+       struct tulip_tx_desc *tx_ring;
+       dma_addr_t rx_ring_dma;
+       dma_addr_t tx_ring_dma;
+       /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+       struct ring_info tx_buffers[TX_RING_SIZE];
+       /* The addresses of receive-in-place skbuffs. */
+       struct ring_info rx_buffers[RX_RING_SIZE];
+       u16 setup_frame[96];    /* Pseudo-Tx frame to init address table. */
+       int chip_id;
+       int revision;
+       int flags;
+       struct napi_struct napi;
+       struct timer_list timer;        /* Media selection timer. */
+       struct timer_list oom_timer;    /* Out of memory timer. */
+       u32 mc_filter[2];
+       spinlock_t lock;
+       spinlock_t mii_lock;
+       unsigned int cur_rx, cur_tx;    /* The next free ring entry */
+       unsigned int dirty_rx, dirty_tx;        /* The ring entries to be free()ed. */
+ #ifdef        CONFIG_TULIP_NAPI_HW_MITIGATION
+         int mit_on;
+ #endif
+       unsigned int full_duplex:1;     /* Full-duplex operation requested. */
+       unsigned int full_duplex_lock:1;
+       unsigned int fake_addr:1;       /* Multiport board faked address. */
+       unsigned int default_port:4;    /* Last dev->if_port value. */
+       unsigned int media2:4;  /* Secondary monitored media port. */
+       unsigned int medialock:1;       /* Don't sense media type. */
+       unsigned int mediasense:1;      /* Media sensing in progress. */
+       unsigned int nway:1, nwayset:1;         /* 21143 internal NWay. */
+       unsigned int timeout_recovery:1;
+       unsigned int csr0;      /* CSR0 setting. */
+       unsigned int csr6;      /* Current CSR6 control settings. */
+       unsigned char eeprom[EEPROM_SIZE];      /* Serial EEPROM contents. */
+       void (*link_change) (struct net_device * dev, int csr5);
+         struct ethtool_wolinfo wolinfo;        /* WOL settings */
+       u16 sym_advertise, mii_advertise; /* NWay capabilities advertised.  */
+       u16 lpar;               /* 21143 Link partner ability. */
+       u16 advertising[4];
+       signed char phys[4], mii_cnt;   /* MII device addresses. */
+       struct mediatable *mtable;
+       int cur_index;          /* Current media index. */
+       int saved_if_port;
+       struct pci_dev *pdev;
+       int ttimer;
+       int susp_rx;
+       unsigned long nir;
+       void __iomem *base_addr;
+       int csr12_shadow;
+       int pad0;               /* Used for 8-byte alignment */
+       struct work_struct media_work;
+       struct net_device *dev;
+ };
+ struct eeprom_fixup {
+       char *name;
+       unsigned char addr0;
+       unsigned char addr1;
+       unsigned char addr2;
+       u16 newtable[32];       /* Max length below. */
+ };
+ /* 21142.c */
+ extern u16 t21142_csr14[];
+ void t21142_media_task(struct work_struct *work);
+ void t21142_start_nway(struct net_device *dev);
+ void t21142_lnk_change(struct net_device *dev, int csr5);
+ /* PNIC2.c */
+ void pnic2_lnk_change(struct net_device *dev, int csr5);
+ void pnic2_timer(unsigned long data);
+ void pnic2_start_nway(struct net_device *dev);
+ void pnic2_lnk_change(struct net_device *dev, int csr5);
+ /* eeprom.c */
+ void tulip_parse_eeprom(struct net_device *dev);
+ int tulip_read_eeprom(struct net_device *dev, int location, int addr_len);
+ /* interrupt.c */
+ extern unsigned int tulip_max_interrupt_work;
+ extern int tulip_rx_copybreak;
+ irqreturn_t tulip_interrupt(int irq, void *dev_instance);
+ int tulip_refill_rx(struct net_device *dev);
+ #ifdef CONFIG_TULIP_NAPI
+ int tulip_poll(struct napi_struct *napi, int budget);
+ #endif
+ /* media.c */
+ int tulip_mdio_read(struct net_device *dev, int phy_id, int location);
+ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value);
+ void tulip_select_media(struct net_device *dev, int startup);
+ int tulip_check_duplex(struct net_device *dev);
+ void tulip_find_mii (struct net_device *dev, int board_idx);
+ /* pnic.c */
+ void pnic_do_nway(struct net_device *dev);
+ void pnic_lnk_change(struct net_device *dev, int csr5);
+ void pnic_timer(unsigned long data);
+ /* timer.c */
+ void tulip_media_task(struct work_struct *work);
+ void mxic_timer(unsigned long data);
+ void comet_timer(unsigned long data);
+ /* tulip_core.c */
+ extern int tulip_debug;
+ extern const char * const medianame[];
+ extern const char tulip_media_cap[];
+ extern struct tulip_chip_table tulip_tbl[];
+ void oom_timer(unsigned long data);
+ extern u8 t21040_csr13[];
+ static inline void tulip_start_rxtx(struct tulip_private *tp)
+ {
+       void __iomem *ioaddr = tp->base_addr;
+       iowrite32(tp->csr6 | RxTx, ioaddr + CSR6);
+       barrier();
+       (void) ioread32(ioaddr + CSR6); /* mmio sync */
+ }
+ static inline void tulip_stop_rxtx(struct tulip_private *tp)
+ {
+       void __iomem *ioaddr = tp->base_addr;
+       u32 csr6 = ioread32(ioaddr + CSR6);
+       if (csr6 & RxTx) {
+               unsigned i=1300/10;
+               iowrite32(csr6 & ~RxTx, ioaddr + CSR6);
+               barrier();
+               /* wait until in-flight frame completes.
+                * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin)
+                * Typically expect this loop to end in < 50 us on 100BT.
+                */
+               while (--i && (ioread32(ioaddr + CSR5) & (CSR5_TS|CSR5_RS)))
+                       udelay(10);
+               if (!i)
+                       netdev_dbg(tp->dev, "tulip_stop_rxtx() failed (CSR5 0x%x CSR6 0x%x)\n",
+                                  ioread32(ioaddr + CSR5),
+                                  ioread32(ioaddr + CSR6));
+       }
+ }
+ static inline void tulip_restart_rxtx(struct tulip_private *tp)
+ {
+       tulip_stop_rxtx(tp);
+       udelay(5);
+       tulip_start_rxtx(tp);
+ }
+ static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr)
+ {
+       /* Stop and restart the chip's Tx processes. */
+       tulip_restart_rxtx(tp);
+       /* Trigger an immediate transmit demand. */
+       iowrite32(0, ioaddr + CSR1);
+       tp->dev->stats.tx_errors++;
+ }
+ #endif /* __NET_TULIP_H__ */
index 0000000,011f67c..9656dd0
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2011 +1,2008 @@@
+ /*    tulip_core.c: A DEC 21x4x-family ethernet driver for Linux.
+       Copyright 2000,2001  The Linux Kernel Team
+       Written/copyright 1994-2001 by Donald Becker.
+       This software may be used and distributed according to the terms
+       of the GNU General Public License, incorporated herein by reference.
 -      Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
 -      for more information on this driver.
 -
+       Please submit bugs to http://bugzilla.kernel.org/ .
+ */
+ #define pr_fmt(fmt) "tulip: " fmt
+ #define DRV_NAME      "tulip"
+ #ifdef CONFIG_TULIP_NAPI
+ #define DRV_VERSION    "1.1.15-NAPI" /* Keep at least for test */
+ #else
+ #define DRV_VERSION   "1.1.15"
+ #endif
+ #define DRV_RELDATE   "Feb 27, 2007"
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/slab.h>
+ #include "tulip.h"
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/etherdevice.h>
+ #include <linux/delay.h>
+ #include <linux/mii.h>
+ #include <linux/crc32.h>
+ #include <asm/unaligned.h>
+ #include <asm/uaccess.h>
+ #ifdef CONFIG_SPARC
+ #include <asm/prom.h>
+ #endif
+ static char version[] __devinitdata =
+       "Linux Tulip driver version " DRV_VERSION " (" DRV_RELDATE ")\n";
+ /* A few user-configurable values. */
+ /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+ static unsigned int max_interrupt_work = 25;
+ #define MAX_UNITS 8
+ /* Used to pass the full-duplex flag, etc. */
+ static int full_duplex[MAX_UNITS];
+ static int options[MAX_UNITS];
+ static int mtu[MAX_UNITS];                    /* Jumbo MTU for interfaces. */
+ /*  The possible media types that can be set in options[] are: */
+ const char * const medianame[32] = {
+       "10baseT", "10base2", "AUI", "100baseTx",
+       "10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx",
+       "100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII",
+       "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4",
+       "MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19",
+       "","","","", "","","","",  "","","","Transceiver reset",
+ };
+ /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
+ #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) || \
+       defined(CONFIG_SPARC) || defined(__ia64__) || \
+       defined(__sh__) || defined(__mips__)
+ static int rx_copybreak = 1518;
+ #else
+ static int rx_copybreak = 100;
+ #endif
+ /*
+   Set the bus performance register.
+       Typical: Set 16 longword cache alignment, no burst limit.
+       Cache alignment bits 15:14           Burst length 13:8
+               0000    No alignment  0x00000000 unlimited              0800 8 longwords
+               4000    8  longwords            0100 1 longword         1000 16 longwords
+               8000    16 longwords            0200 2 longwords        2000 32 longwords
+               C000    32  longwords           0400 4 longwords
+       Warning: many older 486 systems are broken and require setting 0x00A04800
+          8 longword cache alignment, 8 longword burst.
+       ToDo: Non-Intel setting could be better.
+ */
+ #if defined(__alpha__) || defined(__ia64__)
+ static int csr0 = 0x01A00000 | 0xE000;
+ #elif defined(__i386__) || defined(__powerpc__) || defined(__x86_64__)
+ static int csr0 = 0x01A00000 | 0x8000;
+ #elif defined(CONFIG_SPARC) || defined(__hppa__)
+ /* The UltraSparc PCI controllers will disconnect at every 64-byte
+  * crossing anyways so it makes no sense to tell Tulip to burst
+  * any more than that.
+  */
+ static int csr0 = 0x01A00000 | 0x9000;
+ #elif defined(__arm__) || defined(__sh__)
+ static int csr0 = 0x01A00000 | 0x4800;
+ #elif defined(__mips__)
+ static int csr0 = 0x00200000 | 0x4000;
+ #else
+ #warning Processor architecture undefined!
+ static int csr0 = 0x00A00000 | 0x4800;
+ #endif
+ /* Operational parameters that usually are not changed. */
+ /* Time in jiffies before concluding the transmitter is hung. */
+ #define TX_TIMEOUT  (4*HZ)
+ MODULE_AUTHOR("The Linux Kernel Team");
+ MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION(DRV_VERSION);
+ module_param(tulip_debug, int, 0);
+ module_param(max_interrupt_work, int, 0);
+ module_param(rx_copybreak, int, 0);
+ module_param(csr0, int, 0);
+ module_param_array(options, int, NULL, 0);
+ module_param_array(full_duplex, int, NULL, 0);
+ #ifdef TULIP_DEBUG
+ int tulip_debug = TULIP_DEBUG;
+ #else
+ int tulip_debug = 1;
+ #endif
+ static void tulip_timer(unsigned long data)
+ {
+       struct net_device *dev = (struct net_device *)data;
+       struct tulip_private *tp = netdev_priv(dev);
+       if (netif_running(dev))
+               schedule_work(&tp->media_work);
+ }
+ /*
+  * This table use during operation for capabilities and media timer.
+  *
+  * It is indexed via the values in 'enum chips'
+  */
+ struct tulip_chip_table tulip_tbl[] = {
+   { }, /* placeholder for array, slot unused currently */
+   { }, /* placeholder for array, slot unused currently */
+   /* DC21140 */
+   { "Digital DS21140 Tulip", 128, 0x0001ebef,
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer,
+       tulip_media_task },
+   /* DC21142, DC21143 */
+   { "Digital DS21142/43 Tulip", 128, 0x0801fbff,
+       HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY
+       | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task },
+   /* LC82C168 */
+   { "Lite-On 82c168 PNIC", 256, 0x0001fbef,
+       HAS_MII | HAS_PNICNWAY, pnic_timer, },
+   /* MX98713 */
+   { "Macronix 98713 PMAC", 128, 0x0001ebef,
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
+   /* MX98715 */
+   { "Macronix 98715 PMAC", 256, 0x0001ebef,
+       HAS_MEDIA_TABLE, mxic_timer, },
+   /* MX98725 */
+   { "Macronix 98725 PMAC", 256, 0x0001ebef,
+       HAS_MEDIA_TABLE, mxic_timer, },
+   /* AX88140 */
+   { "ASIX AX88140", 128, 0x0001fbff,
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY
+       | IS_ASIX, tulip_timer, tulip_media_task },
+   /* PNIC2 */
+   { "Lite-On PNIC-II", 256, 0x0801fbff,
+       HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer, },
+   /* COMET */
+   { "ADMtek Comet", 256, 0x0001abef,
+       HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer, },
+   /* COMPEX9881 */
+   { "Compex 9881 PMAC", 128, 0x0001ebef,
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
+   /* I21145 */
+   { "Intel DS21145 Tulip", 128, 0x0801fbff,
+       HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI
+       | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
+   /* DM910X */
+ #ifdef CONFIG_TULIP_DM910X
+   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
+       tulip_timer, tulip_media_task },
+ #else
+   { NULL },
+ #endif
+   /* RS7112 */
+   { "Conexant LANfinity", 256, 0x0001ebef,
+       HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task },
+ };
+ static DEFINE_PCI_DEVICE_TABLE(tulip_pci_tbl) = {
+       { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 },
+       { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 },
+       { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 },
+       { 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 },
+       { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
+ /*    { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 },*/
+       { 0x125B, 0x1400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AX88140 },
+       { 0x11AD, 0xc115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PNIC2 },
+       { 0x1317, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1317, 0x0985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1317, 0x1985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1317, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x13D1, 0xAB02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x13D1, 0xAB03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x13D1, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x104A, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x104A, 0x2774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
+       { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
+ #ifdef CONFIG_TULIP_DM910X
+       { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
+       { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
+ #endif
+       { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
+       { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1186, 0x1541, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1186, 0x1561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1186, 0x1591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
+       { 0x1626, 0x8410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */
+       { 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */
+       { 0x1414, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Microsoft MN-120 */
+       { 0x1414, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { } /* terminate list */
+ };
+ MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
+ /* A full-duplex map for media types. */
+ const char tulip_media_cap[32] =
+ {0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20,  28,31,0,0, };
+ static void tulip_tx_timeout(struct net_device *dev);
+ static void tulip_init_ring(struct net_device *dev);
+ static void tulip_free_ring(struct net_device *dev);
+ static netdev_tx_t tulip_start_xmit(struct sk_buff *skb,
+                                         struct net_device *dev);
+ static int tulip_open(struct net_device *dev);
+ static int tulip_close(struct net_device *dev);
+ static void tulip_up(struct net_device *dev);
+ static void tulip_down(struct net_device *dev);
+ static struct net_device_stats *tulip_get_stats(struct net_device *dev);
+ static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+ static void set_rx_mode(struct net_device *dev);
+ static void tulip_set_wolopts(struct pci_dev *pdev, u32 wolopts);
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ static void poll_tulip(struct net_device *dev);
+ #endif
+ static void tulip_set_power_state (struct tulip_private *tp,
+                                  int sleep, int snooze)
+ {
+       if (tp->flags & HAS_ACPI) {
+               u32 tmp, newtmp;
+               pci_read_config_dword (tp->pdev, CFDD, &tmp);
+               newtmp = tmp & ~(CFDD_Sleep | CFDD_Snooze);
+               if (sleep)
+                       newtmp |= CFDD_Sleep;
+               else if (snooze)
+                       newtmp |= CFDD_Snooze;
+               if (tmp != newtmp)
+                       pci_write_config_dword (tp->pdev, CFDD, newtmp);
+       }
+ }
+ static void tulip_up(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int next_tick = 3*HZ;
+       u32 reg;
+       int i;
+ #ifdef CONFIG_TULIP_NAPI
+       napi_enable(&tp->napi);
+ #endif
+       /* Wake the chip from sleep/snooze mode. */
+       tulip_set_power_state (tp, 0, 0);
+       /* Disable all WOL events */
+       pci_enable_wake(tp->pdev, PCI_D3hot, 0);
+       pci_enable_wake(tp->pdev, PCI_D3cold, 0);
+       tulip_set_wolopts(tp->pdev, 0);
+       /* On some chip revs we must set the MII/SYM port before the reset!? */
+       if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii))
+               iowrite32(0x00040000, ioaddr + CSR6);
+       /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
+       iowrite32(0x00000001, ioaddr + CSR0);
+       pci_read_config_dword(tp->pdev, PCI_COMMAND, &reg);  /* flush write */
+       udelay(100);
+       /* Deassert reset.
+          Wait the specified 50 PCI cycles after a reset by initializing
+          Tx and Rx queues and the address filter list. */
+       iowrite32(tp->csr0, ioaddr + CSR0);
+       pci_read_config_dword(tp->pdev, PCI_COMMAND, &reg);  /* flush write */
+       udelay(100);
+       if (tulip_debug > 1)
+               netdev_dbg(dev, "tulip_up(), irq==%d\n", dev->irq);
+       iowrite32(tp->rx_ring_dma, ioaddr + CSR3);
+       iowrite32(tp->tx_ring_dma, ioaddr + CSR4);
+       tp->cur_rx = tp->cur_tx = 0;
+       tp->dirty_rx = tp->dirty_tx = 0;
+       if (tp->flags & MC_HASH_ONLY) {
+               u32 addr_low = get_unaligned_le32(dev->dev_addr);
+               u32 addr_high = get_unaligned_le16(dev->dev_addr + 4);
+               if (tp->chip_id == AX88140) {
+                       iowrite32(0, ioaddr + CSR13);
+                       iowrite32(addr_low,  ioaddr + CSR14);
+                       iowrite32(1, ioaddr + CSR13);
+                       iowrite32(addr_high, ioaddr + CSR14);
+               } else if (tp->flags & COMET_MAC_ADDR) {
+                       iowrite32(addr_low,  ioaddr + 0xA4);
+                       iowrite32(addr_high, ioaddr + 0xA8);
+                       iowrite32(0, ioaddr + CSR27);
+                       iowrite32(0, ioaddr + CSR28);
+               }
+       } else {
+               /* This is set_rx_mode(), but without starting the transmitter. */
+               u16 *eaddrs = (u16 *)dev->dev_addr;
+               u16 *setup_frm = &tp->setup_frame[15*6];
+               dma_addr_t mapping;
+               /* 21140 bug: you must add the broadcast address. */
+               memset(tp->setup_frame, 0xff, sizeof(tp->setup_frame));
+               /* Fill the final entry of the table with our physical address. */
+               *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
+               *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
+               *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
+               mapping = pci_map_single(tp->pdev, tp->setup_frame,
+                                        sizeof(tp->setup_frame),
+                                        PCI_DMA_TODEVICE);
+               tp->tx_buffers[tp->cur_tx].skb = NULL;
+               tp->tx_buffers[tp->cur_tx].mapping = mapping;
+               /* Put the setup frame on the Tx list. */
+               tp->tx_ring[tp->cur_tx].length = cpu_to_le32(0x08000000 | 192);
+               tp->tx_ring[tp->cur_tx].buffer1 = cpu_to_le32(mapping);
+               tp->tx_ring[tp->cur_tx].status = cpu_to_le32(DescOwned);
+               tp->cur_tx++;
+       }
+       tp->saved_if_port = dev->if_port;
+       if (dev->if_port == 0)
+               dev->if_port = tp->default_port;
+       /* Allow selecting a default media. */
+       i = 0;
+       if (tp->mtable == NULL)
+               goto media_picked;
+       if (dev->if_port) {
+               int looking_for = tulip_media_cap[dev->if_port] & MediaIsMII ? 11 :
+                       (dev->if_port == 12 ? 0 : dev->if_port);
+               for (i = 0; i < tp->mtable->leafcount; i++)
+                       if (tp->mtable->mleaf[i].media == looking_for) {
+                               dev_info(&dev->dev,
+                                        "Using user-specified media %s\n",
+                                        medianame[dev->if_port]);
+                               goto media_picked;
+                       }
+       }
+       if ((tp->mtable->defaultmedia & 0x0800) == 0) {
+               int looking_for = tp->mtable->defaultmedia & MEDIA_MASK;
+               for (i = 0; i < tp->mtable->leafcount; i++)
+                       if (tp->mtable->mleaf[i].media == looking_for) {
+                               dev_info(&dev->dev,
+                                        "Using EEPROM-set media %s\n",
+                                        medianame[looking_for]);
+                               goto media_picked;
+                       }
+       }
+       /* Start sensing first non-full-duplex media. */
+       for (i = tp->mtable->leafcount - 1;
+                (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
+               ;
+ media_picked:
+       tp->csr6 = 0;
+       tp->cur_index = i;
+       tp->nwayset = 0;
+       if (dev->if_port) {
+               if (tp->chip_id == DC21143  &&
+                   (tulip_media_cap[dev->if_port] & MediaIsMII)) {
+                       /* We must reset the media CSRs when we force-select MII mode. */
+                       iowrite32(0x0000, ioaddr + CSR13);
+                       iowrite32(0x0000, ioaddr + CSR14);
+                       iowrite32(0x0008, ioaddr + CSR15);
+               }
+               tulip_select_media(dev, 1);
+       } else if (tp->chip_id == DC21142) {
+               if (tp->mii_cnt) {
+                       tulip_select_media(dev, 1);
+                       if (tulip_debug > 1)
+                               dev_info(&dev->dev,
+                                        "Using MII transceiver %d, status %04x\n",
+                                        tp->phys[0],
+                                        tulip_mdio_read(dev, tp->phys[0], 1));
+                       iowrite32(csr6_mask_defstate, ioaddr + CSR6);
+                       tp->csr6 = csr6_mask_hdcap;
+                       dev->if_port = 11;
+                       iowrite32(0x0000, ioaddr + CSR13);
+                       iowrite32(0x0000, ioaddr + CSR14);
+               } else
+                       t21142_start_nway(dev);
+       } else if (tp->chip_id == PNIC2) {
+               /* for initial startup advertise 10/100 Full and Half */
+               tp->sym_advertise = 0x01E0;
+                 /* enable autonegotiate end interrupt */
+               iowrite32(ioread32(ioaddr+CSR5)| 0x00008010, ioaddr + CSR5);
+               iowrite32(ioread32(ioaddr+CSR7)| 0x00008010, ioaddr + CSR7);
+               pnic2_start_nway(dev);
+       } else if (tp->chip_id == LC82C168  &&  ! tp->medialock) {
+               if (tp->mii_cnt) {
+                       dev->if_port = 11;
+                       tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
+                       iowrite32(0x0001, ioaddr + CSR15);
+               } else if (ioread32(ioaddr + CSR5) & TPLnkPass)
+                       pnic_do_nway(dev);
+               else {
+                       /* Start with 10mbps to do autonegotiation. */
+                       iowrite32(0x32, ioaddr + CSR12);
+                       tp->csr6 = 0x00420000;
+                       iowrite32(0x0001B078, ioaddr + 0xB8);
+                       iowrite32(0x0201B078, ioaddr + 0xB8);
+                       next_tick = 1*HZ;
+               }
+       } else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) &&
+                  ! tp->medialock) {
+               dev->if_port = 0;
+               tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
+               iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
+       } else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) {
+               /* Provided by BOLO, Macronix - 12/10/1998. */
+               dev->if_port = 0;
+               tp->csr6 = 0x01a80200;
+               iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
+               iowrite32(0x11000 | ioread16(ioaddr + 0xa0), ioaddr + 0xa0);
+       } else if (tp->chip_id == COMET || tp->chip_id == CONEXANT) {
+               /* Enable automatic Tx underrun recovery. */
+               iowrite32(ioread32(ioaddr + 0x88) | 1, ioaddr + 0x88);
+               dev->if_port = tp->mii_cnt ? 11 : 0;
+               tp->csr6 = 0x00040000;
+       } else if (tp->chip_id == AX88140) {
+               tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
+       } else
+               tulip_select_media(dev, 1);
+       /* Start the chip's Tx to process setup frame. */
+       tulip_stop_rxtx(tp);
+       barrier();
+       udelay(5);
+       iowrite32(tp->csr6 | TxOn, ioaddr + CSR6);
+       /* Enable interrupts by setting the interrupt mask. */
+       iowrite32(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
+       iowrite32(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+       tulip_start_rxtx(tp);
+       iowrite32(0, ioaddr + CSR2);            /* Rx poll demand */
+       if (tulip_debug > 2) {
+               netdev_dbg(dev, "Done tulip_up(), CSR0 %08x, CSR5 %08x CSR6 %08x\n",
+                          ioread32(ioaddr + CSR0),
+                          ioread32(ioaddr + CSR5),
+                          ioread32(ioaddr + CSR6));
+       }
+       /* Set the timer to switch to check for link beat and perhaps switch
+          to an alternate media type. */
+       tp->timer.expires = RUN_AT(next_tick);
+       add_timer(&tp->timer);
+ #ifdef CONFIG_TULIP_NAPI
+       init_timer(&tp->oom_timer);
+         tp->oom_timer.data = (unsigned long)dev;
+         tp->oom_timer.function = oom_timer;
+ #endif
+ }
+ static int
+ tulip_open(struct net_device *dev)
+ {
+       int retval;
+       tulip_init_ring (dev);
+       retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev);
+       if (retval)
+               goto free_ring;
+       tulip_up (dev);
+       netif_start_queue (dev);
+       return 0;
+ free_ring:
+       tulip_free_ring (dev);
+       return retval;
+ }
+ static void tulip_tx_timeout(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       unsigned long flags;
+       spin_lock_irqsave (&tp->lock, flags);
+       if (tulip_media_cap[dev->if_port] & MediaIsMII) {
+               /* Do nothing -- the media monitor should handle this. */
+               if (tulip_debug > 1)
+                       dev_warn(&dev->dev,
+                                "Transmit timeout using MII device\n");
+       } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 ||
+                  tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 ||
+                  tp->chip_id == DM910X) {
+               dev_warn(&dev->dev,
+                        "21140 transmit timed out, status %08x, SIA %08x %08x %08x %08x, resetting...\n",
+                        ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
+                        ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14),
+                        ioread32(ioaddr + CSR15));
+               tp->timeout_recovery = 1;
+               schedule_work(&tp->media_work);
+               goto out_unlock;
+       } else if (tp->chip_id == PNIC2) {
+               dev_warn(&dev->dev,
+                        "PNIC2 transmit timed out, status %08x, CSR6/7 %08x / %08x CSR12 %08x, resetting...\n",
+                        (int)ioread32(ioaddr + CSR5),
+                        (int)ioread32(ioaddr + CSR6),
+                        (int)ioread32(ioaddr + CSR7),
+                        (int)ioread32(ioaddr + CSR12));
+       } else {
+               dev_warn(&dev->dev,
+                        "Transmit timed out, status %08x, CSR12 %08x, resetting...\n",
+                        ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12));
+               dev->if_port = 0;
+       }
+ #if defined(way_too_many_messages)
+       if (tulip_debug > 3) {
+               int i;
+               for (i = 0; i < RX_RING_SIZE; i++) {
+                       u8 *buf = (u8 *)(tp->rx_ring[i].buffer1);
+                       int j;
+                       printk(KERN_DEBUG
+                              "%2d: %08x %08x %08x %08x  %02x %02x %02x\n",
+                              i,
+                              (unsigned int)tp->rx_ring[i].status,
+                              (unsigned int)tp->rx_ring[i].length,
+                              (unsigned int)tp->rx_ring[i].buffer1,
+                              (unsigned int)tp->rx_ring[i].buffer2,
+                              buf[0], buf[1], buf[2]);
+                       for (j = 0; buf[j] != 0xee && j < 1600; j++)
+                               if (j < 100)
+                                       pr_cont(" %02x", buf[j]);
+                       pr_cont(" j=%d\n", j);
+               }
+               printk(KERN_DEBUG "  Rx ring %p: ", tp->rx_ring);
+               for (i = 0; i < RX_RING_SIZE; i++)
+                       pr_cont(" %08x", (unsigned int)tp->rx_ring[i].status);
+               printk(KERN_DEBUG "  Tx ring %p: ", tp->tx_ring);
+               for (i = 0; i < TX_RING_SIZE; i++)
+                       pr_cont(" %08x", (unsigned int)tp->tx_ring[i].status);
+               pr_cont("\n");
+       }
+ #endif
+       tulip_tx_timeout_complete(tp, ioaddr);
+ out_unlock:
+       spin_unlock_irqrestore (&tp->lock, flags);
+       dev->trans_start = jiffies; /* prevent tx timeout */
+       netif_wake_queue (dev);
+ }
+ /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+ static void tulip_init_ring(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int i;
+       tp->susp_rx = 0;
+       tp->ttimer = 0;
+       tp->nir = 0;
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               tp->rx_ring[i].status = 0x00000000;
+               tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ);
+               tp->rx_ring[i].buffer2 = cpu_to_le32(tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * (i + 1));
+               tp->rx_buffers[i].skb = NULL;
+               tp->rx_buffers[i].mapping = 0;
+       }
+       /* Mark the last entry as wrapping the ring. */
+       tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP);
+       tp->rx_ring[i-1].buffer2 = cpu_to_le32(tp->rx_ring_dma);
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               dma_addr_t mapping;
+               /* Note the receive buffer must be longword aligned.
+                  dev_alloc_skb() provides 16 byte alignment.  But do *not*
+                  use skb_reserve() to align the IP header! */
+               struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
+               tp->rx_buffers[i].skb = skb;
+               if (skb == NULL)
+                       break;
+               mapping = pci_map_single(tp->pdev, skb->data,
+                                        PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+               tp->rx_buffers[i].mapping = mapping;
+               skb->dev = dev;                 /* Mark as being used by this device. */
+               tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */
+               tp->rx_ring[i].buffer1 = cpu_to_le32(mapping);
+       }
+       tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+       /* The Tx buffer descriptor is filled in as needed, but we
+          do need to clear the ownership bit. */
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               tp->tx_buffers[i].skb = NULL;
+               tp->tx_buffers[i].mapping = 0;
+               tp->tx_ring[i].status = 0x00000000;
+               tp->tx_ring[i].buffer2 = cpu_to_le32(tp->tx_ring_dma + sizeof(struct tulip_tx_desc) * (i + 1));
+       }
+       tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma);
+ }
+ static netdev_tx_t
+ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int entry;
+       u32 flag;
+       dma_addr_t mapping;
+       unsigned long flags;
+       spin_lock_irqsave(&tp->lock, flags);
+       /* Calculate the next Tx descriptor entry. */
+       entry = tp->cur_tx % TX_RING_SIZE;
+       tp->tx_buffers[entry].skb = skb;
+       mapping = pci_map_single(tp->pdev, skb->data,
+                                skb->len, PCI_DMA_TODEVICE);
+       tp->tx_buffers[entry].mapping = mapping;
+       tp->tx_ring[entry].buffer1 = cpu_to_le32(mapping);
+       if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
+               flag = 0x60000000; /* No interrupt */
+       } else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) {
+               flag = 0xe0000000; /* Tx-done intr. */
+       } else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) {
+               flag = 0x60000000; /* No Tx-done intr. */
+       } else {                /* Leave room for set_rx_mode() to fill entries. */
+               flag = 0xe0000000; /* Tx-done intr. */
+               netif_stop_queue(dev);
+       }
+       if (entry == TX_RING_SIZE-1)
+               flag = 0xe0000000 | DESC_RING_WRAP;
+       tp->tx_ring[entry].length = cpu_to_le32(skb->len | flag);
+       /* if we were using Transmit Automatic Polling, we would need a
+        * wmb() here. */
+       tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
+       wmb();
+       tp->cur_tx++;
+       /* Trigger an immediate transmit demand. */
+       iowrite32(0, tp->base_addr + CSR1);
+       spin_unlock_irqrestore(&tp->lock, flags);
+       return NETDEV_TX_OK;
+ }
+ static void tulip_clean_tx_ring(struct tulip_private *tp)
+ {
+       unsigned int dirty_tx;
+       for (dirty_tx = tp->dirty_tx ; tp->cur_tx - dirty_tx > 0;
+               dirty_tx++) {
+               int entry = dirty_tx % TX_RING_SIZE;
+               int status = le32_to_cpu(tp->tx_ring[entry].status);
+               if (status < 0) {
+                       tp->dev->stats.tx_errors++;     /* It wasn't Txed */
+                       tp->tx_ring[entry].status = 0;
+               }
+               /* Check for Tx filter setup frames. */
+               if (tp->tx_buffers[entry].skb == NULL) {
+                       /* test because dummy frames not mapped */
+                       if (tp->tx_buffers[entry].mapping)
+                               pci_unmap_single(tp->pdev,
+                                       tp->tx_buffers[entry].mapping,
+                                       sizeof(tp->setup_frame),
+                                       PCI_DMA_TODEVICE);
+                       continue;
+               }
+               pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
+                               tp->tx_buffers[entry].skb->len,
+                               PCI_DMA_TODEVICE);
+               /* Free the original skb. */
+               dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
+               tp->tx_buffers[entry].skb = NULL;
+               tp->tx_buffers[entry].mapping = 0;
+       }
+ }
+ static void tulip_down (struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       unsigned long flags;
+       cancel_work_sync(&tp->media_work);
+ #ifdef CONFIG_TULIP_NAPI
+       napi_disable(&tp->napi);
+ #endif
+       del_timer_sync (&tp->timer);
+ #ifdef CONFIG_TULIP_NAPI
+       del_timer_sync (&tp->oom_timer);
+ #endif
+       spin_lock_irqsave (&tp->lock, flags);
+       /* Disable interrupts by clearing the interrupt mask. */
+       iowrite32 (0x00000000, ioaddr + CSR7);
+       /* Stop the Tx and Rx processes. */
+       tulip_stop_rxtx(tp);
+       /* prepare receive buffers */
+       tulip_refill_rx(dev);
+       /* release any unconsumed transmit buffers */
+       tulip_clean_tx_ring(tp);
+       if (ioread32(ioaddr + CSR6) != 0xffffffff)
+               dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
+       spin_unlock_irqrestore (&tp->lock, flags);
+       init_timer(&tp->timer);
+       tp->timer.data = (unsigned long)dev;
+       tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
+       dev->if_port = tp->saved_if_port;
+       /* Leave the driver in snooze, not sleep, mode. */
+       tulip_set_power_state (tp, 0, 1);
+ }
+ static void tulip_free_ring (struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       int i;
+       /* Free all the skbuffs in the Rx queue. */
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               struct sk_buff *skb = tp->rx_buffers[i].skb;
+               dma_addr_t mapping = tp->rx_buffers[i].mapping;
+               tp->rx_buffers[i].skb = NULL;
+               tp->rx_buffers[i].mapping = 0;
+               tp->rx_ring[i].status = 0;      /* Not owned by Tulip chip. */
+               tp->rx_ring[i].length = 0;
+               /* An invalid address. */
+               tp->rx_ring[i].buffer1 = cpu_to_le32(0xBADF00D0);
+               if (skb) {
+                       pci_unmap_single(tp->pdev, mapping, PKT_BUF_SZ,
+                                        PCI_DMA_FROMDEVICE);
+                       dev_kfree_skb (skb);
+               }
+       }
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               struct sk_buff *skb = tp->tx_buffers[i].skb;
+               if (skb != NULL) {
+                       pci_unmap_single(tp->pdev, tp->tx_buffers[i].mapping,
+                                        skb->len, PCI_DMA_TODEVICE);
+                       dev_kfree_skb (skb);
+               }
+               tp->tx_buffers[i].skb = NULL;
+               tp->tx_buffers[i].mapping = 0;
+       }
+ }
+ static int tulip_close (struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       netif_stop_queue (dev);
+       tulip_down (dev);
+       if (tulip_debug > 1)
+               netdev_dbg(dev, "Shutting down ethercard, status was %02x\n",
+                          ioread32 (ioaddr + CSR5));
+       free_irq (dev->irq, dev);
+       tulip_free_ring (dev);
+       return 0;
+ }
+ static struct net_device_stats *tulip_get_stats(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       if (netif_running(dev)) {
+               unsigned long flags;
+               spin_lock_irqsave (&tp->lock, flags);
+               dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
+               spin_unlock_irqrestore(&tp->lock, flags);
+       }
+       return &dev->stats;
+ }
+ static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+ {
+       struct tulip_private *np = netdev_priv(dev);
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, pci_name(np->pdev));
+ }
+ static int tulip_ethtool_set_wol(struct net_device *dev,
+                                struct ethtool_wolinfo *wolinfo)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       if (wolinfo->wolopts & (~tp->wolinfo.supported))
+                  return -EOPNOTSUPP;
+       tp->wolinfo.wolopts = wolinfo->wolopts;
+       device_set_wakeup_enable(&tp->pdev->dev, tp->wolinfo.wolopts);
+       return 0;
+ }
+ static void tulip_ethtool_get_wol(struct net_device *dev,
+                                 struct ethtool_wolinfo *wolinfo)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       wolinfo->supported = tp->wolinfo.supported;
+       wolinfo->wolopts = tp->wolinfo.wolopts;
+       return;
+ }
+ static const struct ethtool_ops ops = {
+       .get_drvinfo = tulip_get_drvinfo,
+       .set_wol     = tulip_ethtool_set_wol,
+       .get_wol     = tulip_ethtool_get_wol,
+ };
+ /* Provide ioctl() calls to examine the MII xcvr state. */
+ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       struct mii_ioctl_data *data = if_mii(rq);
+       const unsigned int phy_idx = 0;
+       int phy = tp->phys[phy_idx] & 0x1f;
+       unsigned int regnum = data->reg_num;
+       switch (cmd) {
+       case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
+               if (tp->mii_cnt)
+                       data->phy_id = phy;
+               else if (tp->flags & HAS_NWAY)
+                       data->phy_id = 32;
+               else if (tp->chip_id == COMET)
+                       data->phy_id = 1;
+               else
+                       return -ENODEV;
+       case SIOCGMIIREG:               /* Read MII PHY register. */
+               if (data->phy_id == 32 && (tp->flags & HAS_NWAY)) {
+                       int csr12 = ioread32 (ioaddr + CSR12);
+                       int csr14 = ioread32 (ioaddr + CSR14);
+                       switch (regnum) {
+                       case 0:
+                                 if (((csr14<<5) & 0x1000) ||
+                                         (dev->if_port == 5 && tp->nwayset))
+                                         data->val_out = 0x1000;
+                                 else
+                                         data->val_out = (tulip_media_cap[dev->if_port]&MediaIs100 ? 0x2000 : 0)
+                                                 | (tulip_media_cap[dev->if_port]&MediaIsFD ? 0x0100 : 0);
+                               break;
+                       case 1:
+                                 data->val_out =
+                                       0x1848 +
+                                       ((csr12&0x7000) == 0x5000 ? 0x20 : 0) +
+                                       ((csr12&0x06) == 6 ? 0 : 4);
+                                 data->val_out |= 0x6048;
+                               break;
+                       case 4:
+                                 /* Advertised value, bogus 10baseTx-FD value from CSR6. */
+                                 data->val_out =
+                                       ((ioread32(ioaddr + CSR6) >> 3) & 0x0040) +
+                                       ((csr14 >> 1) & 0x20) + 1;
+                                 data->val_out |= ((csr14 >> 9) & 0x03C0);
+                               break;
+                       case 5: data->val_out = tp->lpar; break;
+                       default: data->val_out = 0; break;
+                       }
+               } else {
+                       data->val_out = tulip_mdio_read (dev, data->phy_id & 0x1f, regnum);
+               }
+               return 0;
+       case SIOCSMIIREG:               /* Write MII PHY register. */
+               if (regnum & ~0x1f)
+                       return -EINVAL;
+               if (data->phy_id == phy) {
+                       u16 value = data->val_in;
+                       switch (regnum) {
+                       case 0: /* Check for autonegotiation on or reset. */
+                               tp->full_duplex_lock = (value & 0x9000) ? 0 : 1;
+                               if (tp->full_duplex_lock)
+                                       tp->full_duplex = (value & 0x0100) ? 1 : 0;
+                               break;
+                       case 4:
+                               tp->advertising[phy_idx] =
+                               tp->mii_advertise = data->val_in;
+                               break;
+                       }
+               }
+               if (data->phy_id == 32 && (tp->flags & HAS_NWAY)) {
+                       u16 value = data->val_in;
+                       if (regnum == 0) {
+                         if ((value & 0x1200) == 0x1200) {
+                           if (tp->chip_id == PNIC2) {
+                                    pnic2_start_nway (dev);
+                             } else {
+                                  t21142_start_nway (dev);
+                             }
+                         }
+                       } else if (regnum == 4)
+                               tp->sym_advertise = value;
+               } else {
+                       tulip_mdio_write (dev, data->phy_id & 0x1f, regnum, data->val_in);
+               }
+               return 0;
+       default:
+               return -EOPNOTSUPP;
+       }
+       return -EOPNOTSUPP;
+ }
+ /* Set or clear the multicast filter for this adaptor.
+    Note that we only use exclusion around actually queueing the
+    new frame, not around filling tp->setup_frame.  This is non-deterministic
+    when re-entered but still correct. */
+ #undef set_bit_le
+ #define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0)
+ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       u16 hash_table[32];
+       struct netdev_hw_addr *ha;
+       int i;
+       u16 *eaddrs;
+       memset(hash_table, 0, sizeof(hash_table));
+       set_bit_le(255, hash_table);                    /* Broadcast entry */
+       /* This should work on big-endian machines as well. */
+       netdev_for_each_mc_addr(ha, dev) {
+               int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff;
+               set_bit_le(index, hash_table);
+       }
+       for (i = 0; i < 32; i++) {
+               *setup_frm++ = hash_table[i];
+               *setup_frm++ = hash_table[i];
+       }
+       setup_frm = &tp->setup_frame[13*6];
+       /* Fill the final entry with our physical address. */
+       eaddrs = (u16 *)dev->dev_addr;
+       *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
+       *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
+       *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
+ }
+ static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       struct netdev_hw_addr *ha;
+       u16 *eaddrs;
+       /* We have <= 14 addresses so we can use the wonderful
+          16 address perfect filtering of the Tulip. */
+       netdev_for_each_mc_addr(ha, dev) {
+               eaddrs = (u16 *) ha->addr;
+               *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
+               *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
+               *setup_frm++ = *eaddrs; *setup_frm++ = *eaddrs++;
+       }
+       /* Fill the unused entries with the broadcast address. */
+       memset(setup_frm, 0xff, (15 - netdev_mc_count(dev)) * 12);
+       setup_frm = &tp->setup_frame[15*6];
+       /* Fill the final entry with our physical address. */
+       eaddrs = (u16 *)dev->dev_addr;
+       *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0];
+       *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1];
+       *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2];
+ }
+ static void set_rx_mode(struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int csr6;
+       csr6 = ioread32(ioaddr + CSR6) & ~0x00D5;
+       tp->csr6 &= ~0x00D5;
+       if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous. */
+               tp->csr6 |= AcceptAllMulticast | AcceptAllPhys;
+               csr6 |= AcceptAllMulticast | AcceptAllPhys;
+       } else if ((netdev_mc_count(dev) > 1000) ||
+                  (dev->flags & IFF_ALLMULTI)) {
+               /* Too many to filter well -- accept all multicasts. */
+               tp->csr6 |= AcceptAllMulticast;
+               csr6 |= AcceptAllMulticast;
+       } else  if (tp->flags & MC_HASH_ONLY) {
+               /* Some work-alikes have only a 64-entry hash filter table. */
+               /* Should verify correctness on big-endian/__powerpc__ */
+               struct netdev_hw_addr *ha;
+               if (netdev_mc_count(dev) > 64) {
+                       /* Arbitrary non-effective limit. */
+                       tp->csr6 |= AcceptAllMulticast;
+                       csr6 |= AcceptAllMulticast;
+               } else {
+                       u32 mc_filter[2] = {0, 0};               /* Multicast hash filter */
+                       int filterbit;
+                       netdev_for_each_mc_addr(ha, dev) {
+                               if (tp->flags & COMET_MAC_ADDR)
+                                       filterbit = ether_crc_le(ETH_ALEN,
+                                                                ha->addr);
+                               else
+                                       filterbit = ether_crc(ETH_ALEN,
+                                                             ha->addr) >> 26;
+                               filterbit &= 0x3f;
+                               mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
+                               if (tulip_debug > 2)
+                                       dev_info(&dev->dev,
+                                                "Added filter for %pM  %08x bit %d\n",
+                                                ha->addr,
+                                                ether_crc(ETH_ALEN, ha->addr),
+                                                filterbit);
+                       }
+                       if (mc_filter[0] == tp->mc_filter[0]  &&
+                               mc_filter[1] == tp->mc_filter[1])
+                               ;                               /* No change. */
+                       else if (tp->flags & IS_ASIX) {
+                               iowrite32(2, ioaddr + CSR13);
+                               iowrite32(mc_filter[0], ioaddr + CSR14);
+                               iowrite32(3, ioaddr + CSR13);
+                               iowrite32(mc_filter[1], ioaddr + CSR14);
+                       } else if (tp->flags & COMET_MAC_ADDR) {
+                               iowrite32(mc_filter[0], ioaddr + CSR27);
+                               iowrite32(mc_filter[1], ioaddr + CSR28);
+                       }
+                       tp->mc_filter[0] = mc_filter[0];
+                       tp->mc_filter[1] = mc_filter[1];
+               }
+       } else {
+               unsigned long flags;
+               u32 tx_flags = 0x08000000 | 192;
+               /* Note that only the low-address shortword of setup_frame is valid!
+                  The values are doubled for big-endian architectures. */
+               if (netdev_mc_count(dev) > 14) {
+                       /* Must use a multicast hash table. */
+                       build_setup_frame_hash(tp->setup_frame, dev);
+                       tx_flags = 0x08400000 | 192;
+               } else {
+                       build_setup_frame_perfect(tp->setup_frame, dev);
+               }
+               spin_lock_irqsave(&tp->lock, flags);
+               if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
+                       /* Same setup recently queued, we need not add it. */
+               } else {
+                       unsigned int entry;
+                       int dummy = -1;
+                       /* Now add this frame to the Tx list. */
+                       entry = tp->cur_tx++ % TX_RING_SIZE;
+                       if (entry != 0) {
+                               /* Avoid a chip errata by prefixing a dummy entry. */
+                               tp->tx_buffers[entry].skb = NULL;
+                               tp->tx_buffers[entry].mapping = 0;
+                               tp->tx_ring[entry].length =
+                                       (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0;
+                               tp->tx_ring[entry].buffer1 = 0;
+                               /* Must set DescOwned later to avoid race with chip */
+                               dummy = entry;
+                               entry = tp->cur_tx++ % TX_RING_SIZE;
+                       }
+                       tp->tx_buffers[entry].skb = NULL;
+                       tp->tx_buffers[entry].mapping =
+                               pci_map_single(tp->pdev, tp->setup_frame,
+                                              sizeof(tp->setup_frame),
+                                              PCI_DMA_TODEVICE);
+                       /* Put the setup frame on the Tx list. */
+                       if (entry == TX_RING_SIZE-1)
+                               tx_flags |= DESC_RING_WRAP;             /* Wrap ring. */
+                       tp->tx_ring[entry].length = cpu_to_le32(tx_flags);
+                       tp->tx_ring[entry].buffer1 =
+                               cpu_to_le32(tp->tx_buffers[entry].mapping);
+                       tp->tx_ring[entry].status = cpu_to_le32(DescOwned);
+                       if (dummy >= 0)
+                               tp->tx_ring[dummy].status = cpu_to_le32(DescOwned);
+                       if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2)
+                               netif_stop_queue(dev);
+                       /* Trigger an immediate transmit demand. */
+                       iowrite32(0, ioaddr + CSR1);
+               }
+               spin_unlock_irqrestore(&tp->lock, flags);
+       }
+       iowrite32(csr6, ioaddr + CSR6);
+ }
+ #ifdef CONFIG_TULIP_MWI
+ static void __devinit tulip_mwi_config (struct pci_dev *pdev,
+                                       struct net_device *dev)
+ {
+       struct tulip_private *tp = netdev_priv(dev);
+       u8 cache;
+       u16 pci_command;
+       u32 csr0;
+       if (tulip_debug > 3)
+               netdev_dbg(dev, "tulip_mwi_config()\n");
+       tp->csr0 = csr0 = 0;
+       /* if we have any cache line size at all, we can do MRM and MWI */
+       csr0 |= MRM | MWI;
+       /* Enable MWI in the standard PCI command bit.
+        * Check for the case where MWI is desired but not available
+        */
+       pci_try_set_mwi(pdev);
+       /* read result from hardware (in case bit refused to enable) */
+       pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+       if ((csr0 & MWI) && (!(pci_command & PCI_COMMAND_INVALIDATE)))
+               csr0 &= ~MWI;
+       /* if cache line size hardwired to zero, no MWI */
+       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
+       if ((csr0 & MWI) && (cache == 0)) {
+               csr0 &= ~MWI;
+               pci_clear_mwi(pdev);
+       }
+       /* assign per-cacheline-size cache alignment and
+        * burst length values
+        */
+       switch (cache) {
+       case 8:
+               csr0 |= MRL | (1 << CALShift) | (16 << BurstLenShift);
+               break;
+       case 16:
+               csr0 |= MRL | (2 << CALShift) | (16 << BurstLenShift);
+               break;
+       case 32:
+               csr0 |= MRL | (3 << CALShift) | (32 << BurstLenShift);
+               break;
+       default:
+               cache = 0;
+               break;
+       }
+       /* if we have a good cache line size, we by now have a good
+        * csr0, so save it and exit
+        */
+       if (cache)
+               goto out;
+       /* we don't have a good csr0 or cache line size, disable MWI */
+       if (csr0 & MWI) {
+               pci_clear_mwi(pdev);
+               csr0 &= ~MWI;
+       }
+       /* sane defaults for burst length and cache alignment
+        * originally from de4x5 driver
+        */
+       csr0 |= (8 << BurstLenShift) | (1 << CALShift);
+ out:
+       tp->csr0 = csr0;
+       if (tulip_debug > 2)
+               netdev_dbg(dev, "MWI config cacheline=%d, csr0=%08x\n",
+                          cache, csr0);
+ }
+ #endif
+ /*
+  *    Chips that have the MRM/reserved bit quirk and the burst quirk. That
+  *    is the DM910X and the on chip ULi devices
+  */
+ static int tulip_uli_dm_quirk(struct pci_dev *pdev)
+ {
+       if (pdev->vendor == 0x1282 && pdev->device == 0x9102)
+               return 1;
+       return 0;
+ }
+ static const struct net_device_ops tulip_netdev_ops = {
+       .ndo_open               = tulip_open,
+       .ndo_start_xmit         = tulip_start_xmit,
+       .ndo_tx_timeout         = tulip_tx_timeout,
+       .ndo_stop               = tulip_close,
+       .ndo_get_stats          = tulip_get_stats,
+       .ndo_do_ioctl           = private_ioctl,
+       .ndo_set_rx_mode        = set_rx_mode,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller     = poll_tulip,
+ #endif
+ };
+ DEFINE_PCI_DEVICE_TABLE(early_486_chipsets) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) },
+       { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) },
+       { },
+ };
+ static int __devinit tulip_init_one (struct pci_dev *pdev,
+                                    const struct pci_device_id *ent)
+ {
+       struct tulip_private *tp;
+       /* See note below on the multiport cards. */
+       static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
+       static int last_irq;
+       static int multiport_cnt;       /* For four-port boards w/one EEPROM */
+       int i, irq;
+       unsigned short sum;
+       unsigned char *ee_data;
+       struct net_device *dev;
+       void __iomem *ioaddr;
+       static int board_idx = -1;
+       int chip_idx = ent->driver_data;
+       const char *chip_name = tulip_tbl[chip_idx].chip_name;
+       unsigned int eeprom_missing = 0;
+       unsigned int force_csr0 = 0;
+ #ifndef MODULE
+       if (tulip_debug > 0)
+               printk_once(KERN_INFO "%s", version);
+ #endif
+       board_idx++;
+       /*
+        *      Lan media wire a tulip chip to a wan interface. Needs a very
+        *      different driver (lmc driver)
+        */
+         if (pdev->subsystem_vendor == PCI_VENDOR_ID_LMC) {
+               pr_err("skipping LMC card\n");
+               return -ENODEV;
+       } else if (pdev->subsystem_vendor == PCI_VENDOR_ID_SBE &&
+                  (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_T3E3 ||
+                   pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P0 ||
+                   pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)) {
+               pr_err("skipping SBE T3E3 port\n");
+               return -ENODEV;
+       }
+       /*
+        *      DM910x chips should be handled by the dmfe driver, except
+        *      on-board chips on SPARC systems.  Also, early DM9100s need
+        *      software CRC which only the dmfe driver supports.
+        */
+ #ifdef CONFIG_TULIP_DM910X
+       if (chip_idx == DM910X) {
+               struct device_node *dp;
+               if (pdev->vendor == 0x1282 && pdev->device == 0x9100 &&
+                   pdev->revision < 0x30) {
+                       pr_info("skipping early DM9100 with Crc bug (use dmfe)\n");
+                       return -ENODEV;
+               }
+               dp = pci_device_to_OF_node(pdev);
+               if (!(dp && of_get_property(dp, "local-mac-address", NULL))) {
+                       pr_info("skipping DM910x expansion card (use dmfe)\n");
+                       return -ENODEV;
+               }
+       }
+ #endif
+       /*
+        *      Looks for early PCI chipsets where people report hangs
+        *      without the workarounds being on.
+        */
+       /* 1. Intel Saturn. Switch to 8 long words burst, 8 long word cache
+             aligned.  Aries might need this too. The Saturn errata are not
+             pretty reading but thankfully it's an old 486 chipset.
+          2. The dreaded SiS496 486 chipset. Same workaround as Intel
+             Saturn.
+       */
+       if (pci_dev_present(early_486_chipsets)) {
+               csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift);
+               force_csr0 = 1;
+       }
+       /* bugfix: the ASIX must have a burst limit or horrible things happen. */
+       if (chip_idx == AX88140) {
+               if ((csr0 & 0x3f00) == 0)
+                       csr0 |= 0x2000;
+       }
+       /* PNIC doesn't have MWI/MRL/MRM... */
+       if (chip_idx == LC82C168)
+               csr0 &= ~0xfff10000; /* zero reserved bits 31:20, 16 */
+       /* DM9102A has troubles with MRM & clear reserved bits 24:22, 20, 16, 7:1 */
+       if (tulip_uli_dm_quirk(pdev)) {
+               csr0 &= ~0x01f100ff;
+ #if defined(CONFIG_SPARC)
+                 csr0 = (csr0 & ~0xff00) | 0xe000;
+ #endif
+       }
+       /*
+        *      And back to business
+        */
+       i = pci_enable_device(pdev);
+       if (i) {
+               pr_err("Cannot enable tulip board #%d, aborting\n", board_idx);
+               return i;
+       }
+       /* The chip will fail to enter a low-power state later unless
+        * first explicitly commanded into D0 */
+       if (pci_set_power_state(pdev, PCI_D0)) {
+               pr_notice("Failed to set power state to D0\n");
+       }
+       irq = pdev->irq;
+       /* alloc_etherdev ensures aligned and zeroed private structures */
+       dev = alloc_etherdev (sizeof (*tp));
+       if (!dev) {
+               pr_err("ether device alloc failed, aborting\n");
+               return -ENOMEM;
+       }
+       SET_NETDEV_DEV(dev, &pdev->dev);
+       if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) {
+               pr_err("%s: I/O region (0x%llx@0x%llx) too small, aborting\n",
+                      pci_name(pdev),
+                      (unsigned long long)pci_resource_len (pdev, 0),
+                      (unsigned long long)pci_resource_start (pdev, 0));
+               goto err_out_free_netdev;
+       }
+       /* grab all resources from both PIO and MMIO regions, as we
+        * don't want anyone else messing around with our hardware */
+       if (pci_request_regions (pdev, DRV_NAME))
+               goto err_out_free_netdev;
+       ioaddr =  pci_iomap(pdev, TULIP_BAR, tulip_tbl[chip_idx].io_size);
+       if (!ioaddr)
+               goto err_out_free_res;
+       /*
+        * initialize private data structure 'tp'
+        * it is zeroed and aligned in alloc_etherdev
+        */
+       tp = netdev_priv(dev);
+       tp->dev = dev;
+       tp->rx_ring = pci_alloc_consistent(pdev,
+                                          sizeof(struct tulip_rx_desc) * RX_RING_SIZE +
+                                          sizeof(struct tulip_tx_desc) * TX_RING_SIZE,
+                                          &tp->rx_ring_dma);
+       if (!tp->rx_ring)
+               goto err_out_mtable;
+       tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE);
+       tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE;
+       tp->chip_id = chip_idx;
+       tp->flags = tulip_tbl[chip_idx].flags;
+       tp->wolinfo.supported = 0;
+       tp->wolinfo.wolopts = 0;
+       /* COMET: Enable power management only for AN983B */
+       if (chip_idx == COMET ) {
+               u32 sig;
+               pci_read_config_dword (pdev, 0x80, &sig);
+               if (sig == 0x09811317) {
+                       tp->flags |= COMET_PM;
+                       tp->wolinfo.supported = WAKE_PHY | WAKE_MAGIC;
+                       pr_info("%s: Enabled WOL support for AN983B\n",
+                               __func__);
+               }
+       }
+       tp->pdev = pdev;
+       tp->base_addr = ioaddr;
+       tp->revision = pdev->revision;
+       tp->csr0 = csr0;
+       spin_lock_init(&tp->lock);
+       spin_lock_init(&tp->mii_lock);
+       init_timer(&tp->timer);
+       tp->timer.data = (unsigned long)dev;
+       tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
+       INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task);
+       dev->base_addr = (unsigned long)ioaddr;
+ #ifdef CONFIG_TULIP_MWI
+       if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
+               tulip_mwi_config (pdev, dev);
+ #endif
+       /* Stop the chip's Tx and Rx processes. */
+       tulip_stop_rxtx(tp);
+       pci_set_master(pdev);
+ #ifdef CONFIG_GSC
+       if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP) {
+               switch (pdev->subsystem_device) {
+               default:
+                       break;
+               case 0x1061:
+               case 0x1062:
+               case 0x1063:
+               case 0x1098:
+               case 0x1099:
+               case 0x10EE:
+                       tp->flags |= HAS_SWAPPED_SEEPROM | NEEDS_FAKE_MEDIA_TABLE;
+                       chip_name = "GSC DS21140 Tulip";
+               }
+       }
+ #endif
+       /* Clear the missed-packet counter. */
+       ioread32(ioaddr + CSR8);
+       /* The station address ROM is read byte serially.  The register must
+          be polled, waiting for the value to be read bit serially from the
+          EEPROM.
+          */
+       ee_data = tp->eeprom;
+       memset(ee_data, 0, sizeof(tp->eeprom));
+       sum = 0;
+       if (chip_idx == LC82C168) {
+               for (i = 0; i < 3; i++) {
+                       int value, boguscnt = 100000;
+                       iowrite32(0x600 | i, ioaddr + 0x98);
+                       do {
+                               value = ioread32(ioaddr + CSR9);
+                       } while (value < 0  && --boguscnt > 0);
+                       put_unaligned_le16(value, ((__le16 *)dev->dev_addr) + i);
+                       sum += value & 0xffff;
+               }
+       } else if (chip_idx == COMET) {
+               /* No need to read the EEPROM. */
+               put_unaligned_le32(ioread32(ioaddr + 0xA4), dev->dev_addr);
+               put_unaligned_le16(ioread32(ioaddr + 0xA8), dev->dev_addr + 4);
+               for (i = 0; i < 6; i ++)
+                       sum += dev->dev_addr[i];
+       } else {
+               /* A serial EEPROM interface, we read now and sort it out later. */
+               int sa_offset = 0;
+               int ee_addr_size = tulip_read_eeprom(dev, 0xff, 8) & 0x40000 ? 8 : 6;
+               int ee_max_addr = ((1 << ee_addr_size) - 1) * sizeof(u16);
+               if (ee_max_addr > sizeof(tp->eeprom))
+                       ee_max_addr = sizeof(tp->eeprom);
+               for (i = 0; i < ee_max_addr ; i += sizeof(u16)) {
+                       u16 data = tulip_read_eeprom(dev, i/2, ee_addr_size);
+                       ee_data[i] = data & 0xff;
+                       ee_data[i + 1] = data >> 8;
+               }
+               /* DEC now has a specification (see Notes) but early board makers
+                  just put the address in the first EEPROM locations. */
+               /* This does  memcmp(ee_data, ee_data+16, 8) */
+               for (i = 0; i < 8; i ++)
+                       if (ee_data[i] != ee_data[16+i])
+                               sa_offset = 20;
+               if (chip_idx == CONEXANT) {
+                       /* Check that the tuple type and length is correct. */
+                       if (ee_data[0x198] == 0x04  &&  ee_data[0x199] == 6)
+                               sa_offset = 0x19A;
+               } else if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&
+                                  ee_data[2] == 0) {
+                       sa_offset = 2;          /* Grrr, damn Matrox boards. */
+                       multiport_cnt = 4;
+               }
+ #ifdef CONFIG_MIPS_COBALT
+                if ((pdev->bus->number == 0) &&
+                    ((PCI_SLOT(pdev->devfn) == 7) ||
+                     (PCI_SLOT(pdev->devfn) == 12))) {
+                        /* Cobalt MAC address in first EEPROM locations. */
+                        sa_offset = 0;
+                      /* Ensure our media table fixup get's applied */
+                      memcpy(ee_data + 16, ee_data, 8);
+                }
+ #endif
+ #ifdef CONFIG_GSC
+               /* Check to see if we have a broken srom */
+               if (ee_data[0] == 0x61 && ee_data[1] == 0x10) {
+                       /* pci_vendor_id and subsystem_id are swapped */
+                       ee_data[0] = ee_data[2];
+                       ee_data[1] = ee_data[3];
+                       ee_data[2] = 0x61;
+                       ee_data[3] = 0x10;
+                       /* HSC-PCI boards need to be byte-swaped and shifted
+                        * up 1 word.  This shift needs to happen at the end
+                        * of the MAC first because of the 2 byte overlap.
+                        */
+                       for (i = 4; i >= 0; i -= 2) {
+                               ee_data[17 + i + 3] = ee_data[17 + i];
+                               ee_data[16 + i + 5] = ee_data[16 + i];
+                       }
+               }
+ #endif
+               for (i = 0; i < 6; i ++) {
+                       dev->dev_addr[i] = ee_data[i + sa_offset];
+                       sum += ee_data[i + sa_offset];
+               }
+       }
+       /* Lite-On boards have the address byte-swapped. */
+       if ((dev->dev_addr[0] == 0xA0 ||
+            dev->dev_addr[0] == 0xC0 ||
+            dev->dev_addr[0] == 0x02) &&
+           dev->dev_addr[1] == 0x00)
+               for (i = 0; i < 6; i+=2) {
+                       char tmp = dev->dev_addr[i];
+                       dev->dev_addr[i] = dev->dev_addr[i+1];
+                       dev->dev_addr[i+1] = tmp;
+               }
+       /* On the Zynx 315 Etherarray and other multiport boards only the
+          first Tulip has an EEPROM.
+          On Sparc systems the mac address is held in the OBP property
+          "local-mac-address".
+          The addresses of the subsequent ports are derived from the first.
+          Many PCI BIOSes also incorrectly report the IRQ line, so we correct
+          that here as well. */
+       if (sum == 0  || sum == 6*0xff) {
+ #if defined(CONFIG_SPARC)
+               struct device_node *dp = pci_device_to_OF_node(pdev);
+               const unsigned char *addr;
+               int len;
+ #endif
+               eeprom_missing = 1;
+               for (i = 0; i < 5; i++)
+                       dev->dev_addr[i] = last_phys_addr[i];
+               dev->dev_addr[i] = last_phys_addr[i] + 1;
+ #if defined(CONFIG_SPARC)
+               addr = of_get_property(dp, "local-mac-address", &len);
+               if (addr && len == 6)
+                       memcpy(dev->dev_addr, addr, 6);
+ #endif
+ #if defined(__i386__) || defined(__x86_64__)  /* Patch up x86 BIOS bug. */
+               if (last_irq)
+                       irq = last_irq;
+ #endif
+       }
+       for (i = 0; i < 6; i++)
+               last_phys_addr[i] = dev->dev_addr[i];
+       last_irq = irq;
+       dev->irq = irq;
+       /* The lower four bits are the media type. */
+       if (board_idx >= 0  &&  board_idx < MAX_UNITS) {
+               if (options[board_idx] & MEDIA_MASK)
+                       tp->default_port = options[board_idx] & MEDIA_MASK;
+               if ((options[board_idx] & FullDuplex) || full_duplex[board_idx] > 0)
+                       tp->full_duplex = 1;
+               if (mtu[board_idx] > 0)
+                       dev->mtu = mtu[board_idx];
+       }
+       if (dev->mem_start & MEDIA_MASK)
+               tp->default_port = dev->mem_start & MEDIA_MASK;
+       if (tp->default_port) {
+               pr_info(DRV_NAME "%d: Transceiver selection forced to %s\n",
+                       board_idx, medianame[tp->default_port & MEDIA_MASK]);
+               tp->medialock = 1;
+               if (tulip_media_cap[tp->default_port] & MediaAlwaysFD)
+                       tp->full_duplex = 1;
+       }
+       if (tp->full_duplex)
+               tp->full_duplex_lock = 1;
+       if (tulip_media_cap[tp->default_port] & MediaIsMII) {
+               static const u16 media2advert[] = {
+                       0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200
+               };
+               tp->mii_advertise = media2advert[tp->default_port - 9];
+               tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */
+       }
+       if (tp->flags & HAS_MEDIA_TABLE) {
+               sprintf(dev->name, DRV_NAME "%d", board_idx);   /* hack */
+               tulip_parse_eeprom(dev);
+               strcpy(dev->name, "eth%d");                     /* un-hack */
+       }
+       if ((tp->flags & ALWAYS_CHECK_MII) ||
+               (tp->mtable  &&  tp->mtable->has_mii) ||
+               ( ! tp->mtable  &&  (tp->flags & HAS_MII))) {
+               if (tp->mtable  &&  tp->mtable->has_mii) {
+                       for (i = 0; i < tp->mtable->leafcount; i++)
+                               if (tp->mtable->mleaf[i].media == 11) {
+                                       tp->cur_index = i;
+                                       tp->saved_if_port = dev->if_port;
+                                       tulip_select_media(dev, 2);
+                                       dev->if_port = tp->saved_if_port;
+                                       break;
+                               }
+               }
+               /* Find the connected MII xcvrs.
+                  Doing this in open() would allow detecting external xcvrs
+                  later, but takes much time. */
+               tulip_find_mii (dev, board_idx);
+       }
+       /* The Tulip-specific entries in the device structure. */
+       dev->netdev_ops = &tulip_netdev_ops;
+       dev->watchdog_timeo = TX_TIMEOUT;
+ #ifdef CONFIG_TULIP_NAPI
+       netif_napi_add(dev, &tp->napi, tulip_poll, 16);
+ #endif
+       SET_ETHTOOL_OPS(dev, &ops);
+       if (register_netdev(dev))
+               goto err_out_free_ring;
+       pci_set_drvdata(pdev, dev);
+       dev_info(&dev->dev,
+ #ifdef CONFIG_TULIP_MMIO
+                "%s rev %d at MMIO %#llx,%s %pM, IRQ %d\n",
+ #else
+                "%s rev %d at Port %#llx,%s %pM, IRQ %d\n",
+ #endif
+                chip_name, pdev->revision,
+                (unsigned long long)pci_resource_start(pdev, TULIP_BAR),
+                eeprom_missing ? " EEPROM not present," : "",
+                dev->dev_addr, irq);
+         if (tp->chip_id == PNIC2)
+               tp->link_change = pnic2_lnk_change;
+       else if (tp->flags & HAS_NWAY)
+               tp->link_change = t21142_lnk_change;
+       else if (tp->flags & HAS_PNICNWAY)
+               tp->link_change = pnic_lnk_change;
+       /* Reset the xcvr interface and turn on heartbeat. */
+       switch (chip_idx) {
+       case DC21140:
+       case DM910X:
+       default:
+               if (tp->mtable)
+                       iowrite32(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
+               break;
+       case DC21142:
+               if (tp->mii_cnt  ||  tulip_media_cap[dev->if_port] & MediaIsMII) {
+                       iowrite32(csr6_mask_defstate, ioaddr + CSR6);
+                       iowrite32(0x0000, ioaddr + CSR13);
+                       iowrite32(0x0000, ioaddr + CSR14);
+                       iowrite32(csr6_mask_hdcap, ioaddr + CSR6);
+               } else
+                       t21142_start_nway(dev);
+               break;
+       case PNIC2:
+               /* just do a reset for sanity sake */
+               iowrite32(0x0000, ioaddr + CSR13);
+               iowrite32(0x0000, ioaddr + CSR14);
+               break;
+       case LC82C168:
+               if ( ! tp->mii_cnt) {
+                       tp->nway = 1;
+                       tp->nwayset = 0;
+                       iowrite32(csr6_ttm | csr6_ca, ioaddr + CSR6);
+                       iowrite32(0x30, ioaddr + CSR12);
+                       iowrite32(0x0001F078, ioaddr + CSR6);
+                       iowrite32(0x0201F078, ioaddr + CSR6); /* Turn on autonegotiation. */
+               }
+               break;
+       case MX98713:
+       case COMPEX9881:
+               iowrite32(0x00000000, ioaddr + CSR6);
+               iowrite32(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
+               iowrite32(0x00000001, ioaddr + CSR13);
+               break;
+       case MX98715:
+       case MX98725:
+               iowrite32(0x01a80000, ioaddr + CSR6);
+               iowrite32(0xFFFFFFFF, ioaddr + CSR14);
+               iowrite32(0x00001000, ioaddr + CSR12);
+               break;
+       case COMET:
+               /* No initialization necessary. */
+               break;
+       }
+       /* put the chip in snooze mode until opened */
+       tulip_set_power_state (tp, 0, 1);
+       return 0;
+ err_out_free_ring:
+       pci_free_consistent (pdev,
+                            sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
+                            sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
+                            tp->rx_ring, tp->rx_ring_dma);
+ err_out_mtable:
+       kfree (tp->mtable);
+       pci_iounmap(pdev, ioaddr);
+ err_out_free_res:
+       pci_release_regions (pdev);
+ err_out_free_netdev:
+       free_netdev (dev);
+       return -ENODEV;
+ }
+ /* set the registers according to the given wolopts */
+ static void tulip_set_wolopts (struct pci_dev *pdev, u32 wolopts)
+ {
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       if (tp->flags & COMET_PM) {
+         
+               unsigned int tmp;
+                       
+               tmp = ioread32(ioaddr + CSR18);
+               tmp &= ~(comet_csr18_pmes_sticky | comet_csr18_apm_mode | comet_csr18_d3a);
+               tmp |= comet_csr18_pm_mode;
+               iowrite32(tmp, ioaddr + CSR18);
+                       
+               /* Set the Wake-up Control/Status Register to the given WOL options*/
+               tmp = ioread32(ioaddr + CSR13);
+               tmp &= ~(comet_csr13_linkoffe | comet_csr13_linkone | comet_csr13_wfre | comet_csr13_lsce | comet_csr13_mpre);
+               if (wolopts & WAKE_MAGIC)
+                       tmp |= comet_csr13_mpre;
+               if (wolopts & WAKE_PHY)
+                       tmp |= comet_csr13_linkoffe | comet_csr13_linkone | comet_csr13_lsce;
+               /* Clear the event flags */
+               tmp |= comet_csr13_wfr | comet_csr13_mpr | comet_csr13_lsc;
+               iowrite32(tmp, ioaddr + CSR13);
+       }
+ }
+ #ifdef CONFIG_PM
+ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
+ {
+       pci_power_t pstate;
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct tulip_private *tp = netdev_priv(dev);
+       if (!dev)
+               return -EINVAL;
+       if (!netif_running(dev))
+               goto save_state;
+       tulip_down(dev);
+       netif_device_detach(dev);
+       free_irq(dev->irq, dev);
+ save_state:
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pstate = pci_choose_state(pdev, state);
+       if (state.event == PM_EVENT_SUSPEND && pstate != PCI_D0) {
+               int rc;
+               tulip_set_wolopts(pdev, tp->wolinfo.wolopts);
+               rc = pci_enable_wake(pdev, pstate, tp->wolinfo.wolopts);
+               if (rc)
+                       pr_err("pci_enable_wake failed (%d)\n", rc);
+       }
+       pci_set_power_state(pdev, pstate);
+       return 0;
+ }
+ static int tulip_resume(struct pci_dev *pdev)
+ {
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+       int retval;
+       unsigned int tmp;
+       if (!dev)
+               return -EINVAL;
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       if (!netif_running(dev))
+               return 0;
+       if ((retval = pci_enable_device(pdev))) {
+               pr_err("pci_enable_device failed in resume\n");
+               return retval;
+       }
+       if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
+               pr_err("request_irq failed in resume\n");
+               return retval;
+       }
+       if (tp->flags & COMET_PM) {
+               pci_enable_wake(pdev, PCI_D3hot, 0);
+               pci_enable_wake(pdev, PCI_D3cold, 0);
+               /* Clear the PMES flag */
+               tmp = ioread32(ioaddr + CSR20);
+               tmp |= comet_csr20_pmes;
+               iowrite32(tmp, ioaddr + CSR20);
+               /* Disable all wake-up events */
+               tulip_set_wolopts(pdev, 0);
+       }
+       netif_device_attach(dev);
+       if (netif_running(dev))
+               tulip_up(dev);
+       return 0;
+ }
+ #endif /* CONFIG_PM */
+ static void __devexit tulip_remove_one (struct pci_dev *pdev)
+ {
+       struct net_device *dev = pci_get_drvdata (pdev);
+       struct tulip_private *tp;
+       if (!dev)
+               return;
+       tp = netdev_priv(dev);
+       unregister_netdev(dev);
+       pci_free_consistent (pdev,
+                            sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
+                            sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
+                            tp->rx_ring, tp->rx_ring_dma);
+       kfree (tp->mtable);
+       pci_iounmap(pdev, tp->base_addr);
+       free_netdev (dev);
+       pci_release_regions (pdev);
+       pci_set_drvdata (pdev, NULL);
+       /* pci_power_off (pdev, -1); */
+ }
+ #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 poll_tulip (struct net_device *dev)
+ {
+       /* disable_irq here is not very nice, but with the lockless
+          interrupt handler we have no other choice. */
+       disable_irq(dev->irq);
+       tulip_interrupt (dev->irq, dev);
+       enable_irq(dev->irq);
+ }
+ #endif
+ static struct pci_driver tulip_driver = {
+       .name           = DRV_NAME,
+       .id_table       = tulip_pci_tbl,
+       .probe          = tulip_init_one,
+       .remove         = __devexit_p(tulip_remove_one),
+ #ifdef CONFIG_PM
+       .suspend        = tulip_suspend,
+       .resume         = tulip_resume,
+ #endif /* CONFIG_PM */
+ };
+ static int __init tulip_init (void)
+ {
+ #ifdef MODULE
+       pr_info("%s", version);
+ #endif
+       /* copy module parms into globals */
+       tulip_rx_copybreak = rx_copybreak;
+       tulip_max_interrupt_work = max_interrupt_work;
+       /* probe for and init boards */
+       return pci_register_driver(&tulip_driver);
+ }
+ static void __exit tulip_cleanup (void)
+ {
+       pci_unregister_driver (&tulip_driver);
+ }
+ module_init(tulip_init);
+ module_exit(tulip_cleanup);
index 0000000,74f2f11..469d95e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,446 +1,446 @@@
+ /*******************************************************************************
+   Intel(R) Gigabit Ethernet Linux driver
+   Copyright(c) 2007-2011 Intel Corporation.
+   This program is free software; you can redistribute it and/or modify it
+   under the terms and conditions of the GNU General Public License,
+   version 2, as published by the Free Software Foundation.
+   This program is distributed in the hope 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.,
+   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+   The full GNU General Public License is included in this distribution in
+   the file called "COPYING".
+   Contact Information:
+   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *******************************************************************************/
+ #include "e1000_mbx.h"
+ /**
+  *  igb_read_mbx - Reads a message from the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to read
+  *
 - *  returns SUCCESS if it successfuly read message from buffer
++ *  returns SUCCESS if it successfully read message from buffer
+  **/
+ s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       /* limit read to size of mailbox */
+       if (size > mbx->size)
+               size = mbx->size;
+       if (mbx->ops.read)
+               ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  igb_write_mbx - Write a message to the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer
+  **/
+ s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = 0;
+       if (size > mbx->size)
+               ret_val = -E1000_ERR_MBX;
+       else if (mbx->ops.write)
+               ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  igb_check_for_msg - checks to see if someone sent us mail
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to check
+  *
+  *  returns SUCCESS if the Status bit was found or else ERR_MBX
+  **/
+ s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       if (mbx->ops.check_for_msg)
+               ret_val = mbx->ops.check_for_msg(hw, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  igb_check_for_ack - checks to see if someone sent us ACK
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to check
+  *
+  *  returns SUCCESS if the Status bit was found or else ERR_MBX
+  **/
+ s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       if (mbx->ops.check_for_ack)
+               ret_val = mbx->ops.check_for_ack(hw, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  igb_check_for_rst - checks to see if other side has reset
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to check
+  *
+  *  returns SUCCESS if the Status bit was found or else ERR_MBX
+  **/
+ s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       if (mbx->ops.check_for_rst)
+               ret_val = mbx->ops.check_for_rst(hw, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  igb_poll_for_msg - Wait for message notification
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully received a message notification
+  **/
+ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       if (!countdown || !mbx->ops.check_for_msg)
+               goto out;
+       while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
+               countdown--;
+               if (!countdown)
+                       break;
+               udelay(mbx->usec_delay);
+       }
+       /* if we failed, all future posted messages fail until reset */
+       if (!countdown)
+               mbx->timeout = 0;
+ out:
+       return countdown ? 0 : -E1000_ERR_MBX;
+ }
+ /**
+  *  igb_poll_for_ack - Wait for message acknowledgement
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully received a message acknowledgement
+  **/
+ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       if (!countdown || !mbx->ops.check_for_ack)
+               goto out;
+       while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
+               countdown--;
+               if (!countdown)
+                       break;
+               udelay(mbx->usec_delay);
+       }
+       /* if we failed, all future posted messages fail until reset */
+       if (!countdown)
+               mbx->timeout = 0;
+ out:
+       return countdown ? 0 : -E1000_ERR_MBX;
+ }
+ /**
+  *  igb_read_posted_mbx - Wait for message notification and receive message
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully received a message notification and
+  *  copied it into the receive buffer.
+  **/
+ static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       if (!mbx->ops.read)
+               goto out;
+       ret_val = igb_poll_for_msg(hw, mbx_id);
+       if (!ret_val)
+               ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+ out:
+       return ret_val;
+ }
+ /**
+  *  igb_write_posted_mbx - Write a message to the mailbox, wait for ack
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer and
+  *  received an ack to that message within delay * timeout period
+  **/
+ static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       /* exit if either we can't write or there isn't a defined timeout */
+       if (!mbx->ops.write || !mbx->timeout)
+               goto out;
+       /* send msg */
+       ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+       /* if msg sent wait until we receive an ack */
+       if (!ret_val)
+               ret_val = igb_poll_for_ack(hw, mbx_id);
+ out:
+       return ret_val;
+ }
+ static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
+ {
+       u32 mbvficr = rd32(E1000_MBVFICR);
+       s32 ret_val = -E1000_ERR_MBX;
+       if (mbvficr & mask) {
+               ret_val = 0;
+               wr32(E1000_MBVFICR, mask);
+       }
+       return ret_val;
+ }
+ /**
+  *  igb_check_for_msg_pf - checks to see if the VF has sent mail
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+  **/
+ static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
+ {
+       s32 ret_val = -E1000_ERR_MBX;
+       if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
+               ret_val = 0;
+               hw->mbx.stats.reqs++;
+       }
+       return ret_val;
+ }
+ /**
+  *  igb_check_for_ack_pf - checks to see if the VF has ACKed
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+  **/
+ static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
+ {
+       s32 ret_val = -E1000_ERR_MBX;
+       if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
+               ret_val = 0;
+               hw->mbx.stats.acks++;
+       }
+       return ret_val;
+ }
+ /**
+  *  igb_check_for_rst_pf - checks to see if the VF has reset
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+  **/
+ static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
+ {
+       u32 vflre = rd32(E1000_VFLRE);
+       s32 ret_val = -E1000_ERR_MBX;
+       if (vflre & (1 << vf_number)) {
+               ret_val = 0;
+               wr32(E1000_VFLRE, (1 << vf_number));
+               hw->mbx.stats.rsts++;
+       }
+       return ret_val;
+ }
+ /**
+  *  igb_obtain_mbx_lock_pf - obtain mailbox lock
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  return SUCCESS if we obtained the mailbox lock
+  **/
+ static s32 igb_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
+ {
+       s32 ret_val = -E1000_ERR_MBX;
+       u32 p2v_mailbox;
+       /* Take ownership of the buffer */
+       wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+       /* reserve mailbox for vf use */
+       p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+       if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
+               ret_val = 0;
+       return ret_val;
+ }
+ /**
+  *  igb_write_mbx_pf - Places a message in the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer
+  **/
+ static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+                               u16 vf_number)
+ {
+       s32 ret_val;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+       if (ret_val)
+               goto out_no_write;
+       /* flush msg and acks as we are overwriting the message buffer */
+       igb_check_for_msg_pf(hw, vf_number);
+       igb_check_for_ack_pf(hw, vf_number);
+       /* copy the caller specified message to the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
+       /* Interrupt VF to tell it a message has been sent and release buffer*/
+       wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
+       /* update stats */
+       hw->mbx.stats.msgs_tx++;
+ out_no_write:
+       return ret_val;
+ }
+ /**
+  *  igb_read_mbx_pf - Read a message from the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @vf_number: the VF index
+  *
+  *  This function copies a message from the mailbox buffer to the caller's
+  *  memory buffer.  The presumption is that the caller knows that there was
+  *  a message due to a VF request so no polling for message is needed.
+  **/
+ static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+                              u16 vf_number)
+ {
+       s32 ret_val;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       ret_val = igb_obtain_mbx_lock_pf(hw, vf_number);
+       if (ret_val)
+               goto out_no_read;
+       /* copy the message to the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
+       /* Acknowledge the message and release buffer */
+       wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
+       /* update stats */
+       hw->mbx.stats.msgs_rx++;
+ out_no_read:
+       return ret_val;
+ }
+ /**
+  *  e1000_init_mbx_params_pf - set initial values for pf mailbox
+  *  @hw: pointer to the HW structure
+  *
+  *  Initializes the hw->mbx struct to correct values for pf mailbox
+  */
+ s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       mbx->timeout = 0;
+       mbx->usec_delay = 0;
+       mbx->size = E1000_VFMAILBOX_SIZE;
+       mbx->ops.read = igb_read_mbx_pf;
+       mbx->ops.write = igb_write_mbx_pf;
+       mbx->ops.read_posted = igb_read_posted_mbx;
+       mbx->ops.write_posted = igb_write_posted_mbx;
+       mbx->ops.check_for_msg = igb_check_for_msg_pf;
+       mbx->ops.check_for_ack = igb_check_for_ack_pf;
+       mbx->ops.check_for_rst = igb_check_for_rst_pf;
+       mbx->stats.msgs_tx = 0;
+       mbx->stats.msgs_rx = 0;
+       mbx->stats.reqs = 0;
+       mbx->stats.acks = 0;
+       mbx->stats.rsts = 0;
+       return 0;
+ }
index 0000000,3d6f4cc..048aae2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,350 +1,350 @@@
+ /*******************************************************************************
+   Intel(R) 82576 Virtual Function Linux driver
+   Copyright(c) 2009 - 2010 Intel Corporation.
+   This program is free software; you can redistribute it and/or modify it
+   under the terms and conditions of the GNU General Public License,
+   version 2, as published by the Free Software Foundation.
+   This program is distributed in the hope 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.,
+   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+   The full GNU General Public License is included in this distribution in
+   the file called "COPYING".
+   Contact Information:
+   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *******************************************************************************/
+ #include "mbx.h"
+ /**
+  *  e1000_poll_for_msg - Wait for message notification
+  *  @hw: pointer to the HW structure
+  *
+  *  returns SUCCESS if it successfully received a message notification
+  **/
+ static s32 e1000_poll_for_msg(struct e1000_hw *hw)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       if (!mbx->ops.check_for_msg)
+               goto out;
+       while (countdown && mbx->ops.check_for_msg(hw)) {
+               countdown--;
+               udelay(mbx->usec_delay);
+       }
+       /* if we failed, all future posted messages fail until reset */
+       if (!countdown)
+               mbx->timeout = 0;
+ out:
+       return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+ }
+ /**
+  *  e1000_poll_for_ack - Wait for message acknowledgement
+  *  @hw: pointer to the HW structure
+  *
+  *  returns SUCCESS if it successfully received a message acknowledgement
+  **/
+ static s32 e1000_poll_for_ack(struct e1000_hw *hw)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       if (!mbx->ops.check_for_ack)
+               goto out;
+       while (countdown && mbx->ops.check_for_ack(hw)) {
+               countdown--;
+               udelay(mbx->usec_delay);
+       }
+       /* if we failed, all future posted messages fail until reset */
+       if (!countdown)
+               mbx->timeout = 0;
+ out:
+       return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;
+ }
+ /**
+  *  e1000_read_posted_mbx - Wait for message notification and receive message
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
+  *  returns SUCCESS if it successfully received a message notification and
+  *  copied it into the receive buffer.
+  **/
+ static s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       if (!mbx->ops.read)
+               goto out;
+       ret_val = e1000_poll_for_msg(hw);
+       /* if ack received read message, otherwise we timed out */
+       if (!ret_val)
+               ret_val = mbx->ops.read(hw, msg, size);
+ out:
+       return ret_val;
+ }
+ /**
+  *  e1000_write_posted_mbx - Write a message to the mailbox, wait for ack
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer and
+  *  received an ack to that message within delay * timeout period
+  **/
+ static s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = -E1000_ERR_MBX;
+       /* exit if we either can't write or there isn't a defined timeout */
+       if (!mbx->ops.write || !mbx->timeout)
+               goto out;
+       /* send msg*/
+       ret_val = mbx->ops.write(hw, msg, size);
+       /* if msg sent wait until we receive an ack */
+       if (!ret_val)
+               ret_val = e1000_poll_for_ack(hw);
+ out:
+       return ret_val;
+ }
+ /**
+  *  e1000_read_v2p_mailbox - read v2p mailbox
+  *  @hw: pointer to the HW structure
+  *
+  *  This function is used to read the v2p mailbox without losing the read to
+  *  clear status bits.
+  **/
+ static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)
+ {
+       u32 v2p_mailbox = er32(V2PMAILBOX(0));
+       v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;
+       hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;
+       return v2p_mailbox;
+ }
+ /**
+  *  e1000_check_for_bit_vf - Determine if a status bit was set
+  *  @hw: pointer to the HW structure
+  *  @mask: bitmask for bits to be tested and cleared
+  *
+  *  This function is used to check for the read to clear bits within
+  *  the V2P mailbox.
+  **/
+ static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)
+ {
+       u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);
+       s32 ret_val = -E1000_ERR_MBX;
+       if (v2p_mailbox & mask)
+               ret_val = E1000_SUCCESS;
+       hw->dev_spec.vf.v2p_mailbox &= ~mask;
+       return ret_val;
+ }
+ /**
+  *  e1000_check_for_msg_vf - checks to see if the PF has sent mail
+  *  @hw: pointer to the HW structure
+  *
+  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
+  **/
+ static s32 e1000_check_for_msg_vf(struct e1000_hw *hw)
+ {
+       s32 ret_val = -E1000_ERR_MBX;
+       if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {
+               ret_val = E1000_SUCCESS;
+               hw->mbx.stats.reqs++;
+       }
+       return ret_val;
+ }
+ /**
+  *  e1000_check_for_ack_vf - checks to see if the PF has ACK'd
+  *  @hw: pointer to the HW structure
+  *
+  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
+  **/
+ static s32 e1000_check_for_ack_vf(struct e1000_hw *hw)
+ {
+       s32 ret_val = -E1000_ERR_MBX;
+       if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {
+               ret_val = E1000_SUCCESS;
+               hw->mbx.stats.acks++;
+       }
+       return ret_val;
+ }
+ /**
+  *  e1000_check_for_rst_vf - checks to see if the PF has reset
+  *  @hw: pointer to the HW structure
+  *
+  *  returns true if the PF has set the reset done bit or else false
+  **/
+ static s32 e1000_check_for_rst_vf(struct e1000_hw *hw)
+ {
+       s32 ret_val = -E1000_ERR_MBX;
+       if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |
+                                        E1000_V2PMAILBOX_RSTI))) {
+               ret_val = E1000_SUCCESS;
+               hw->mbx.stats.rsts++;
+       }
+       return ret_val;
+ }
+ /**
+  *  e1000_obtain_mbx_lock_vf - obtain mailbox lock
+  *  @hw: pointer to the HW structure
+  *
+  *  return SUCCESS if we obtained the mailbox lock
+  **/
+ static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
+ {
+       s32 ret_val = -E1000_ERR_MBX;
+       /* Take ownership of the buffer */
+       ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
+       /* reserve mailbox for vf use */
+       if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
+               ret_val = E1000_SUCCESS;
+       return ret_val;
+ }
+ /**
+  *  e1000_write_mbx_vf - Write a message to the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer
+  **/
+ static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+ {
+       s32 err;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       err = e1000_obtain_mbx_lock_vf(hw);
+       if (err)
+               goto out_no_write;
+       /* flush any ack or msg as we are going to overwrite mailbox */
+       e1000_check_for_ack_vf(hw);
+       e1000_check_for_msg_vf(hw);
+       /* copy the caller specified message to the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               array_ew32(VMBMEM(0), i, msg[i]);
+       /* update stats */
+       hw->mbx.stats.msgs_tx++;
+       /* Drop VFU and interrupt the PF to tell it a message has been sent */
+       ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);
+ out_no_write:
+       return err;
+ }
+ /**
+  *  e1000_read_mbx_vf - Reads a message from the inbox intended for vf
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
 - *  returns SUCCESS if it successfuly read message from buffer
++ *  returns SUCCESS if it successfully read message from buffer
+  **/
+ static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)
+ {
+       s32 err;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       err = e1000_obtain_mbx_lock_vf(hw);
+       if (err)
+               goto out_no_read;
+       /* copy the message from the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               msg[i] = array_er32(VMBMEM(0), i);
+       /* Acknowledge receipt and release mailbox, then we're done */
+       ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);
+       /* update stats */
+       hw->mbx.stats.msgs_rx++;
+ out_no_read:
+       return err;
+ }
+ /**
+  *  e1000_init_mbx_params_vf - set initial values for vf mailbox
+  *  @hw: pointer to the HW structure
+  *
+  *  Initializes the hw->mbx struct to correct values for vf mailbox
+  */
+ s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)
+ {
+       struct e1000_mbx_info *mbx = &hw->mbx;
+       /* start mailbox as timed out and let the reset_hw call set the timeout
+        * value to being communications */
+       mbx->timeout = 0;
+       mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;
+       mbx->size = E1000_VFMAILBOX_SIZE;
+       mbx->ops.read = e1000_read_mbx_vf;
+       mbx->ops.write = e1000_write_mbx_vf;
+       mbx->ops.read_posted = e1000_read_posted_mbx;
+       mbx->ops.write_posted = e1000_write_posted_mbx;
+       mbx->ops.check_for_msg = e1000_check_for_msg_vf;
+       mbx->ops.check_for_ack = e1000_check_for_ack_vf;
+       mbx->ops.check_for_rst = e1000_check_for_rst_vf;
+       mbx->stats.msgs_tx = 0;
+       mbx->stats.msgs_rx = 0;
+       mbx->stats.reqs = 0;
+       mbx->stats.acks = 0;
+       mbx->stats.rsts = 0;
+       return E1000_SUCCESS;
+ }
index 0000000,1ff0eef..3f725d4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,471 +1,471 @@@
+ /*******************************************************************************
+   Intel 10 Gigabit PCI Express Linux driver
+   Copyright(c) 1999 - 2011 Intel Corporation.
+   This program is free software; you can redistribute it and/or modify it
+   under the terms and conditions of the GNU General Public License,
+   version 2, as published by the Free Software Foundation.
+   This program is distributed in the hope 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.,
+   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+   The full GNU General Public License is included in this distribution in
+   the file called "COPYING".
+   Contact Information:
+   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *******************************************************************************/
+ #include <linux/pci.h>
+ #include <linux/delay.h>
+ #include "ixgbe_type.h"
+ #include "ixgbe_common.h"
+ #include "ixgbe_mbx.h"
+ /**
+  *  ixgbe_read_mbx - Reads a message from the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to read
+  *
 - *  returns SUCCESS if it successfuly read message from buffer
++ *  returns SUCCESS if it successfully read message from buffer
+  **/
+ s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = IXGBE_ERR_MBX;
+       /* limit read to size of mailbox */
+       if (size > mbx->size)
+               size = mbx->size;
+       if (mbx->ops.read)
+               ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  ixgbe_write_mbx - Write a message to the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer
+  **/
+ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = 0;
+       if (size > mbx->size)
+               ret_val = IXGBE_ERR_MBX;
+       else if (mbx->ops.write)
+               ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  ixgbe_check_for_msg - checks to see if someone sent us mail
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to check
+  *
+  *  returns SUCCESS if the Status bit was found or else ERR_MBX
+  **/
+ s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (mbx->ops.check_for_msg)
+               ret_val = mbx->ops.check_for_msg(hw, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  ixgbe_check_for_ack - checks to see if someone sent us ACK
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to check
+  *
+  *  returns SUCCESS if the Status bit was found or else ERR_MBX
+  **/
+ s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (mbx->ops.check_for_ack)
+               ret_val = mbx->ops.check_for_ack(hw, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  ixgbe_check_for_rst - checks to see if other side has reset
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to check
+  *
+  *  returns SUCCESS if the Status bit was found or else ERR_MBX
+  **/
+ s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (mbx->ops.check_for_rst)
+               ret_val = mbx->ops.check_for_rst(hw, mbx_id);
+       return ret_val;
+ }
+ /**
+  *  ixgbe_poll_for_msg - Wait for message notification
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully received a message notification
+  **/
+ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       if (!countdown || !mbx->ops.check_for_msg)
+               goto out;
+       while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
+               countdown--;
+               if (!countdown)
+                       break;
+               udelay(mbx->usec_delay);
+       }
+ out:
+       return countdown ? 0 : IXGBE_ERR_MBX;
+ }
+ /**
+  *  ixgbe_poll_for_ack - Wait for message acknowledgement
+  *  @hw: pointer to the HW structure
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully received a message acknowledgement
+  **/
+ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       if (!countdown || !mbx->ops.check_for_ack)
+               goto out;
+       while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
+               countdown--;
+               if (!countdown)
+                       break;
+               udelay(mbx->usec_delay);
+       }
+ out:
+       return countdown ? 0 : IXGBE_ERR_MBX;
+ }
+ /**
+  *  ixgbe_read_posted_mbx - Wait for message notification and receive message
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully received a message notification and
+  *  copied it into the receive buffer.
+  **/
+ static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
+                                u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (!mbx->ops.read)
+               goto out;
+       ret_val = ixgbe_poll_for_msg(hw, mbx_id);
+       /* if ack received read message, otherwise we timed out */
+       if (!ret_val)
+               ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+ out:
+       return ret_val;
+ }
+ /**
+  *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @mbx_id: id of mailbox to write
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer and
+  *  received an ack to that message within delay * timeout period
+  **/
+ static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
+                            u16 mbx_id)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = IXGBE_ERR_MBX;
+       /* exit if either we can't write or there isn't a defined timeout */
+       if (!mbx->ops.write || !mbx->timeout)
+               goto out;
+       /* send msg */
+       ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+       /* if msg sent wait until we receive an ack */
+       if (!ret_val)
+               ret_val = ixgbe_poll_for_ack(hw, mbx_id);
+ out:
+       return ret_val;
+ }
+ static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
+ {
+       u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (mbvficr & mask) {
+               ret_val = 0;
+               IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
+       }
+       return ret_val;
+ }
+ /**
+  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+  **/
+ static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
+ {
+       s32 ret_val = IXGBE_ERR_MBX;
+       s32 index = IXGBE_MBVFICR_INDEX(vf_number);
+       u32 vf_bit = vf_number % 16;
+       if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
+                                   index)) {
+               ret_val = 0;
+               hw->mbx.stats.reqs++;
+       }
+       return ret_val;
+ }
+ /**
+  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+  **/
+ static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
+ {
+       s32 ret_val = IXGBE_ERR_MBX;
+       s32 index = IXGBE_MBVFICR_INDEX(vf_number);
+       u32 vf_bit = vf_number % 16;
+       if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
+                                   index)) {
+               ret_val = 0;
+               hw->mbx.stats.acks++;
+       }
+       return ret_val;
+ }
+ /**
+  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+  **/
+ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
+ {
+       u32 reg_offset = (vf_number < 32) ? 0 : 1;
+       u32 vf_shift = vf_number % 32;
+       u32 vflre = 0;
+       s32 ret_val = IXGBE_ERR_MBX;
+       switch (hw->mac.type) {
+       case ixgbe_mac_82599EB:
+               vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
+               break;
+       case ixgbe_mac_X540:
+               vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
+               break;
+       default:
+               break;
+       }
+       if (vflre & (1 << vf_shift)) {
+               ret_val = 0;
+               IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
+               hw->mbx.stats.rsts++;
+       }
+       return ret_val;
+ }
+ /**
+  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
+  *  @hw: pointer to the HW structure
+  *  @vf_number: the VF index
+  *
+  *  return SUCCESS if we obtained the mailbox lock
+  **/
+ static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
+ {
+       s32 ret_val = IXGBE_ERR_MBX;
+       u32 p2v_mailbox;
+       /* Take ownership of the buffer */
+       IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
+       /* reserve mailbox for vf use */
+       p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
+       if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
+               ret_val = 0;
+       return ret_val;
+ }
+ /**
+  *  ixgbe_write_mbx_pf - Places a message in the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @vf_number: the VF index
+  *
+  *  returns SUCCESS if it successfully copied message into the buffer
+  **/
+ static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
+                               u16 vf_number)
+ {
+       s32 ret_val;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
+       if (ret_val)
+               goto out_no_write;
+       /* flush msg and acks as we are overwriting the message buffer */
+       ixgbe_check_for_msg_pf(hw, vf_number);
+       ixgbe_check_for_ack_pf(hw, vf_number);
+       /* copy the caller specified message to the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
+       /* Interrupt VF to tell it a message has been sent and release buffer*/
+       IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
+       /* update stats */
+       hw->mbx.stats.msgs_tx++;
+ out_no_write:
+       return ret_val;
+ }
+ /**
+  *  ixgbe_read_mbx_pf - Read a message from the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *  @vf_number: the VF index
+  *
+  *  This function copies a message from the mailbox buffer to the caller's
+  *  memory buffer.  The presumption is that the caller knows that there was
+  *  a message due to a VF request so no polling for message is needed.
+  **/
+ static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
+                              u16 vf_number)
+ {
+       s32 ret_val;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
+       if (ret_val)
+               goto out_no_read;
+       /* copy the message to the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
+       /* Acknowledge the message and release buffer */
+       IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
+       /* update stats */
+       hw->mbx.stats.msgs_rx++;
+ out_no_read:
+       return ret_val;
+ }
+ #ifdef CONFIG_PCI_IOV
+ /**
+  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
+  *  @hw: pointer to the HW structure
+  *
+  *  Initializes the hw->mbx struct to correct values for pf mailbox
+  */
+ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       if (hw->mac.type != ixgbe_mac_82599EB &&
+           hw->mac.type != ixgbe_mac_X540)
+               return;
+       mbx->timeout = 0;
+       mbx->usec_delay = 0;
+       mbx->stats.msgs_tx = 0;
+       mbx->stats.msgs_rx = 0;
+       mbx->stats.reqs = 0;
+       mbx->stats.acks = 0;
+       mbx->stats.rsts = 0;
+       mbx->size = IXGBE_VFMAILBOX_SIZE;
+ }
+ #endif /* CONFIG_PCI_IOV */
+ struct ixgbe_mbx_operations mbx_ops_generic = {
+       .read                   = ixgbe_read_mbx_pf,
+       .write                  = ixgbe_write_mbx_pf,
+       .read_posted            = ixgbe_read_posted_mbx,
+       .write_posted           = ixgbe_write_posted_mbx,
+       .check_for_msg          = ixgbe_check_for_msg_pf,
+       .check_for_ack          = ixgbe_check_for_ack_pf,
+       .check_for_rst          = ixgbe_check_for_rst_pf,
+ };
index 0000000,7a88331..930fa83
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,341 +1,341 @@@
+ /*******************************************************************************
+   Intel 82599 Virtual Function driver
+   Copyright(c) 1999 - 2010 Intel Corporation.
+   This program is free software; you can redistribute it and/or modify it
+   under the terms and conditions of the GNU General Public License,
+   version 2, as published by the Free Software Foundation.
+   This program is distributed in the hope 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.,
+   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+   The full GNU General Public License is included in this distribution in
+   the file called "COPYING".
+   Contact Information:
+   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *******************************************************************************/
+ #include "mbx.h"
+ /**
+  *  ixgbevf_poll_for_msg - Wait for message notification
+  *  @hw: pointer to the HW structure
+  *
+  *  returns 0 if it successfully received a message notification
+  **/
+ static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       while (countdown && mbx->ops.check_for_msg(hw)) {
+               countdown--;
+               udelay(mbx->udelay);
+       }
+       /* if we failed, all future posted messages fail until reset */
+       if (!countdown)
+               mbx->timeout = 0;
+       return countdown ? 0 : IXGBE_ERR_MBX;
+ }
+ /**
+  *  ixgbevf_poll_for_ack - Wait for message acknowledgement
+  *  @hw: pointer to the HW structure
+  *
+  *  returns 0 if it successfully received a message acknowledgement
+  **/
+ static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       int countdown = mbx->timeout;
+       while (countdown && mbx->ops.check_for_ack(hw)) {
+               countdown--;
+               udelay(mbx->udelay);
+       }
+       /* if we failed, all future posted messages fail until reset */
+       if (!countdown)
+               mbx->timeout = 0;
+       return countdown ? 0 : IXGBE_ERR_MBX;
+ }
+ /**
+  *  ixgbevf_read_posted_mbx - Wait for message notification and receive message
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
+  *  returns 0 if it successfully received a message notification and
+  *  copied it into the receive buffer.
+  **/
+ static s32 ixgbevf_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val = IXGBE_ERR_MBX;
+       ret_val = ixgbevf_poll_for_msg(hw);
+       /* if ack received read message, otherwise we timed out */
+       if (!ret_val)
+               ret_val = mbx->ops.read(hw, msg, size);
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_write_posted_mbx - Write a message to the mailbox, wait for ack
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
+  *  returns 0 if it successfully copied message into the buffer and
+  *  received an ack to that message within delay * timeout period
+  **/
+ static s32 ixgbevf_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       s32 ret_val;
+       /* send msg */
+       ret_val = mbx->ops.write(hw, msg, size);
+       /* if msg sent wait until we receive an ack */
+       if (!ret_val)
+               ret_val = ixgbevf_poll_for_ack(hw);
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_read_v2p_mailbox - read v2p mailbox
+  *  @hw: pointer to the HW structure
+  *
+  *  This function is used to read the v2p mailbox without losing the read to
+  *  clear status bits.
+  **/
+ static u32 ixgbevf_read_v2p_mailbox(struct ixgbe_hw *hw)
+ {
+       u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
+       v2p_mailbox |= hw->mbx.v2p_mailbox;
+       hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
+       return v2p_mailbox;
+ }
+ /**
+  *  ixgbevf_check_for_bit_vf - Determine if a status bit was set
+  *  @hw: pointer to the HW structure
+  *  @mask: bitmask for bits to be tested and cleared
+  *
+  *  This function is used to check for the read to clear bits within
+  *  the V2P mailbox.
+  **/
+ static s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
+ {
+       u32 v2p_mailbox = ixgbevf_read_v2p_mailbox(hw);
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (v2p_mailbox & mask)
+               ret_val = 0;
+       hw->mbx.v2p_mailbox &= ~mask;
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
+  *  @hw: pointer to the HW structure
+  *
+  *  returns 0 if the PF has set the Status bit or else ERR_MBX
+  **/
+ static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)
+ {
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
+               ret_val = 0;
+               hw->mbx.stats.reqs++;
+       }
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
+  *  @hw: pointer to the HW structure
+  *
+  *  returns 0 if the PF has set the ACK bit or else ERR_MBX
+  **/
+ static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)
+ {
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
+               ret_val = 0;
+               hw->mbx.stats.acks++;
+       }
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_check_for_rst_vf - checks to see if the PF has reset
+  *  @hw: pointer to the HW structure
+  *
+  *  returns true if the PF has set the reset done bit or else false
+  **/
+ static s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)
+ {
+       s32 ret_val = IXGBE_ERR_MBX;
+       if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
+                                        IXGBE_VFMAILBOX_RSTI))) {
+               ret_val = 0;
+               hw->mbx.stats.rsts++;
+       }
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
+  *  @hw: pointer to the HW structure
+  *
+  *  return 0 if we obtained the mailbox lock
+  **/
+ static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
+ {
+       s32 ret_val = IXGBE_ERR_MBX;
+       /* Take ownership of the buffer */
+       IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
+       /* reserve mailbox for vf use */
+       if (ixgbevf_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
+               ret_val = 0;
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_write_mbx_vf - Write a message to the mailbox
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
+  *  returns 0 if it successfully copied message into the buffer
+  **/
+ static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
+ {
+       s32 ret_val;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
+       if (ret_val)
+               goto out_no_write;
+       /* flush msg and acks as we are overwriting the message buffer */
+       ixgbevf_check_for_msg_vf(hw);
+       ixgbevf_check_for_ack_vf(hw);
+       /* copy the caller specified message to the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
+       /* update stats */
+       hw->mbx.stats.msgs_tx++;
+       /* Drop VFU and interrupt the PF to tell it a message has been sent */
+       IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
+ out_no_write:
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_read_mbx_vf - Reads a message from the inbox intended for vf
+  *  @hw: pointer to the HW structure
+  *  @msg: The message buffer
+  *  @size: Length of buffer
+  *
 - *  returns 0 if it successfuly read message from buffer
++ *  returns 0 if it successfully read message from buffer
+  **/
+ static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
+ {
+       s32 ret_val = 0;
+       u16 i;
+       /* lock the mailbox to prevent pf/vf race condition */
+       ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
+       if (ret_val)
+               goto out_no_read;
+       /* copy the message from the mailbox memory buffer */
+       for (i = 0; i < size; i++)
+               msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
+       /* Acknowledge receipt and release mailbox, then we're done */
+       IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
+       /* update stats */
+       hw->mbx.stats.msgs_rx++;
+ out_no_read:
+       return ret_val;
+ }
+ /**
+  *  ixgbevf_init_mbx_params_vf - set initial values for vf mailbox
+  *  @hw: pointer to the HW structure
+  *
+  *  Initializes the hw->mbx struct to correct values for vf mailbox
+  */
+ static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
+ {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       /* start mailbox as timed out and let the reset_hw call set the timeout
+        * value to begin communications */
+       mbx->timeout = 0;
+       mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;
+       mbx->size = IXGBE_VFMAILBOX_SIZE;
+       mbx->stats.msgs_tx = 0;
+       mbx->stats.msgs_rx = 0;
+       mbx->stats.reqs = 0;
+       mbx->stats.acks = 0;
+       mbx->stats.rsts = 0;
+       return 0;
+ }
+ struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
+       .init_params   = ixgbevf_init_mbx_params_vf,
+       .read          = ixgbevf_read_mbx_vf,
+       .write         = ixgbevf_write_mbx_vf,
+       .read_posted   = ixgbevf_read_posted_mbx,
+       .write_posted  = ixgbevf_write_posted_mbx,
+       .check_for_msg = ixgbevf_check_for_msg_vf,
+       .check_for_ack = ixgbevf_check_for_ack_vf,
+       .check_for_rst = ixgbevf_check_for_rst_vf,
+ };
index 0000000,7b083c4..cbd026f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,5158 +1,5158 @@@
+ /*
+  * New driver for Marvell Yukon 2 chipset.
+  * Based on earlier sk98lin, and skge driver.
+  *
+  * This driver intentionally does not support all the features
+  * of the original driver such as link fail-over and link management because
+  * those should be done at higher levels.
+  *
+  * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
+  *
+  * 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.
+  *
+  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+ #include <linux/crc32.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/netdevice.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/etherdevice.h>
+ #include <linux/ethtool.h>
+ #include <linux/pci.h>
+ #include <linux/interrupt.h>
+ #include <linux/ip.h>
+ #include <linux/slab.h>
+ #include <net/ip.h>
+ #include <linux/tcp.h>
+ #include <linux/in.h>
+ #include <linux/delay.h>
+ #include <linux/workqueue.h>
+ #include <linux/if_vlan.h>
+ #include <linux/prefetch.h>
+ #include <linux/debugfs.h>
+ #include <linux/mii.h>
+ #include <asm/irq.h>
+ #include "sky2.h"
+ #define DRV_NAME              "sky2"
+ #define DRV_VERSION           "1.29"
+ /*
+  * The Yukon II chipset takes 64 bit command blocks (called list elements)
+  * that are organized into three (receive, transmit, status) different rings
+  * similar to Tigon3.
+  */
+ #define RX_LE_SIZE            1024
+ #define RX_LE_BYTES           (RX_LE_SIZE*sizeof(struct sky2_rx_le))
+ #define RX_MAX_PENDING                (RX_LE_SIZE/6 - 2)
+ #define RX_DEF_PENDING                RX_MAX_PENDING
+ /* This is the worst case number of transmit list elements for a single skb:
+    VLAN:GSO + CKSUM + Data + skb_frags * DMA */
+ #define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
+ #define TX_MIN_PENDING                (MAX_SKB_TX_LE+1)
+ #define TX_MAX_PENDING                1024
+ #define TX_DEF_PENDING                127
+ #define TX_WATCHDOG           (5 * HZ)
+ #define NAPI_WEIGHT           64
+ #define PHY_RETRIES           1000
+ #define SKY2_EEPROM_MAGIC     0x9955aabb
+ #define RING_NEXT(x, s)       (((x)+1) & ((s)-1))
+ static const u32 default_msg =
+     NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
+     | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
+     | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
+ static int debug = -1;                /* defaults above */
+ module_param(debug, int, 0);
+ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+ static int copybreak __read_mostly = 128;
+ module_param(copybreak, int, 0);
+ MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+ static int disable_msi = 0;
+ module_param(disable_msi, int, 0);
+ MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
+ static DEFINE_PCI_DEVICE_TABLE(sky2_id_table) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
+       { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
+       { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E01) }, /* SK-9E21M */
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },    /* DGE-560T */
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) },    /* DGE-550SX */
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B02) },    /* DGE-560SX */
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B03) },    /* DGE-550T */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, /* 88E8021 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, /* 88E8022 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, /* 88E8061 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) }, /* 88E8062 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) }, /* 88E8021 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) }, /* 88E8022 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) }, /* 88E8061 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) }, /* 88E8062 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) }, /* 88E8035 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4355) }, /* 88E8040T */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, /* 88E8070 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4381) }, /* 88E8059 */
+       { 0 }
+ };
+ MODULE_DEVICE_TABLE(pci, sky2_id_table);
+ /* Avoid conditionals by using array */
+ static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
+ static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
+ static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 };
+ static void sky2_set_multicast(struct net_device *dev);
+ static irqreturn_t sky2_intr(int irq, void *dev_id);
+ /* Access to PHY via serial interconnect */
+ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
+ {
+       int i;
+       gma_write16(hw, port, GM_SMI_DATA, val);
+       gma_write16(hw, port, GM_SMI_CTRL,
+                   GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
+       for (i = 0; i < PHY_RETRIES; i++) {
+               u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
+               if (ctrl == 0xffff)
+                       goto io_error;
+               if (!(ctrl & GM_SMI_CT_BUSY))
+                       return 0;
+               udelay(10);
+       }
+       dev_warn(&hw->pdev->dev, "%s: phy write timeout\n", hw->dev[port]->name);
+       return -ETIMEDOUT;
+ io_error:
+       dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
+       return -EIO;
+ }
+ static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
+ {
+       int i;
+       gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
+                   | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
+       for (i = 0; i < PHY_RETRIES; i++) {
+               u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
+               if (ctrl == 0xffff)
+                       goto io_error;
+               if (ctrl & GM_SMI_CT_RD_VAL) {
+                       *val = gma_read16(hw, port, GM_SMI_DATA);
+                       return 0;
+               }
+               udelay(10);
+       }
+       dev_warn(&hw->pdev->dev, "%s: phy read timeout\n", hw->dev[port]->name);
+       return -ETIMEDOUT;
+ io_error:
+       dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
+       return -EIO;
+ }
+ static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
+ {
+       u16 v;
+       __gm_phy_read(hw, port, reg, &v);
+       return v;
+ }
+ static void sky2_power_on(struct sky2_hw *hw)
+ {
+       /* switch power to VCC (WA for VAUX problem) */
+       sky2_write8(hw, B0_POWER_CTRL,
+                   PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
+       /* disable Core Clock Division, */
+       sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
+       if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1)
+               /* enable bits are inverted */
+               sky2_write8(hw, B2_Y2_CLK_GATE,
+                           Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+                           Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+                           Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+       else
+               sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+       if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
+               u32 reg;
+               sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+               reg = sky2_pci_read32(hw, PCI_DEV_REG4);
+               /* set all bits to 0 except bits 15..12 and 8 */
+               reg &= P_ASPM_CONTROL_MSK;
+               sky2_pci_write32(hw, PCI_DEV_REG4, reg);
+               reg = sky2_pci_read32(hw, PCI_DEV_REG5);
+               /* set all bits to 0 except bits 28 & 27 */
+               reg &= P_CTL_TIM_VMAIN_AV_MSK;
+               sky2_pci_write32(hw, PCI_DEV_REG5, reg);
+               sky2_pci_write32(hw, PCI_CFG_REG_1, 0);
+               sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
+               /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */
+               reg = sky2_read32(hw, B2_GP_IO);
+               reg |= GLB_GPIO_STAT_RACE_DIS;
+               sky2_write32(hw, B2_GP_IO, reg);
+               sky2_read32(hw, B2_GP_IO);
+       }
+       /* Turn on "driver loaded" LED */
+       sky2_write16(hw, B0_CTST, Y2_LED_STAT_ON);
+ }
+ static void sky2_power_aux(struct sky2_hw *hw)
+ {
+       if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1)
+               sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+       else
+               /* enable bits are inverted */
+               sky2_write8(hw, B2_Y2_CLK_GATE,
+                           Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+                           Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+                           Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+       /* switch power to VAUX if supported and PME from D3cold */
+       if ( (sky2_read32(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+            pci_pme_capable(hw->pdev, PCI_D3cold))
+               sky2_write8(hw, B0_POWER_CTRL,
+                           (PC_VAUX_ENA | PC_VCC_ENA |
+                            PC_VAUX_ON | PC_VCC_OFF));
+       /* turn off "driver loaded LED" */
+       sky2_write16(hw, B0_CTST, Y2_LED_STAT_OFF);
+ }
+ static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
+ {
+       u16 reg;
+       /* disable all GMAC IRQ's */
+       sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+       gma_write16(hw, port, GM_MC_ADDR_H1, 0);        /* clear MC hash */
+       gma_write16(hw, port, GM_MC_ADDR_H2, 0);
+       gma_write16(hw, port, GM_MC_ADDR_H3, 0);
+       gma_write16(hw, port, GM_MC_ADDR_H4, 0);
+       reg = gma_read16(hw, port, GM_RX_CTRL);
+       reg |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
+       gma_write16(hw, port, GM_RX_CTRL, reg);
+ }
+ /* flow control to advertise bits */
+ static const u16 copper_fc_adv[] = {
+       [FC_NONE]       = 0,
+       [FC_TX]         = PHY_M_AN_ASP,
+       [FC_RX]         = PHY_M_AN_PC,
+       [FC_BOTH]       = PHY_M_AN_PC | PHY_M_AN_ASP,
+ };
+ /* flow control to advertise bits when using 1000BaseX */
+ static const u16 fiber_fc_adv[] = {
+       [FC_NONE] = PHY_M_P_NO_PAUSE_X,
+       [FC_TX]   = PHY_M_P_ASYM_MD_X,
+       [FC_RX]   = PHY_M_P_SYM_MD_X,
+       [FC_BOTH] = PHY_M_P_BOTH_MD_X,
+ };
+ /* flow control to GMA disable bits */
+ static const u16 gm_fc_disable[] = {
+       [FC_NONE] = GM_GPCR_FC_RX_DIS | GM_GPCR_FC_TX_DIS,
+       [FC_TX]   = GM_GPCR_FC_RX_DIS,
+       [FC_RX]   = GM_GPCR_FC_TX_DIS,
+       [FC_BOTH] = 0,
+ };
+ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
+ {
+       struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+       u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg;
+       if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
+           !(hw->flags & SKY2_HW_NEWER_PHY)) {
+               u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+               ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+                          PHY_M_EC_MAC_S_MSK);
+               ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
+               /* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */
+               if (hw->chip_id == CHIP_ID_YUKON_EC)
+                       /* set downshift counter to 3x and enable downshift */
+                       ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
+               else
+                       /* set master & slave downshift counter to 1x */
+                       ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
+               gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
+       }
+       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+       if (sky2_is_copper(hw)) {
+               if (!(hw->flags & SKY2_HW_GIGABIT)) {
+                       /* enable automatic crossover */
+                       ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
+                       if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+                           hw->chip_rev == CHIP_REV_YU_FE2_A0) {
+                               u16 spec;
+                               /* Enable Class A driver for FE+ A0 */
+                               spec = gm_phy_read(hw, port, PHY_MARV_FE_SPEC_2);
+                               spec |= PHY_M_FESC_SEL_CL_A;
+                               gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
+                       }
+               } else {
+                       if (hw->chip_id >= CHIP_ID_YUKON_OPT) {
+                               u16 ctrl2 = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL_2);
+                               /* enable PHY Reverse Auto-Negotiation */
+                               ctrl2 |= 1u << 13;
+                               /* Write PHY changes (SW-reset must follow) */
+                               gm_phy_write(hw, port, PHY_MARV_EXT_CTRL_2, ctrl2);
+                       }
+                       /* disable energy detect */
+                       ctrl &= ~PHY_M_PC_EN_DET_MSK;
+                       /* enable automatic crossover */
+                       ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
+                       /* downshift on PHY 88E1112 and 88E1149 is changed */
+                       if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
+                            (hw->flags & SKY2_HW_NEWER_PHY)) {
+                               /* set downshift counter to 3x and enable downshift */
+                               ctrl &= ~PHY_M_PC_DSC_MSK;
+                               ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
+                       }
+               }
+       } else {
+               /* workaround for deviation #4.88 (CRC errors) */
+               /* disable Automatic Crossover */
+               ctrl &= ~PHY_M_PC_MDIX_MSK;
+       }
+       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+       /* special setup for PHY 88E1112 Fiber */
+       if (hw->chip_id == CHIP_ID_YUKON_XL && (hw->flags & SKY2_HW_FIBRE_PHY)) {
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+               ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+               ctrl &= ~PHY_M_MAC_MD_MSK;
+               ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+               if (hw->pmd_type  == 'P') {
+                       /* select page 1 to access Fiber registers */
+                       gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
+                       /* for SFP-module set SIGDET polarity to low */
+                       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+                       ctrl |= PHY_M_FIB_SIGD_POL;
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+               }
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+       }
+       ctrl = PHY_CT_RESET;
+       ct1000 = 0;
+       adv = PHY_AN_CSMA;
+       reg = 0;
+       if (sky2->flags & SKY2_FLAG_AUTO_SPEED) {
+               if (sky2_is_copper(hw)) {
+                       if (sky2->advertising & ADVERTISED_1000baseT_Full)
+                               ct1000 |= PHY_M_1000C_AFD;
+                       if (sky2->advertising & ADVERTISED_1000baseT_Half)
+                               ct1000 |= PHY_M_1000C_AHD;
+                       if (sky2->advertising & ADVERTISED_100baseT_Full)
+                               adv |= PHY_M_AN_100_FD;
+                       if (sky2->advertising & ADVERTISED_100baseT_Half)
+                               adv |= PHY_M_AN_100_HD;
+                       if (sky2->advertising & ADVERTISED_10baseT_Full)
+                               adv |= PHY_M_AN_10_FD;
+                       if (sky2->advertising & ADVERTISED_10baseT_Half)
+                               adv |= PHY_M_AN_10_HD;
+               } else {        /* special defines for FIBER (88E1040S only) */
+                       if (sky2->advertising & ADVERTISED_1000baseT_Full)
+                               adv |= PHY_M_AN_1000X_AFD;
+                       if (sky2->advertising & ADVERTISED_1000baseT_Half)
+                               adv |= PHY_M_AN_1000X_AHD;
+               }
+               /* Restart Auto-negotiation */
+               ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+       } else {
+               /* forced speed/duplex settings */
+               ct1000 = PHY_M_1000C_MSE;
+               /* Disable auto update for duplex flow control and duplex */
+               reg |= GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_SPD_DIS;
+               switch (sky2->speed) {
+               case SPEED_1000:
+                       ctrl |= PHY_CT_SP1000;
+                       reg |= GM_GPCR_SPEED_1000;
+                       break;
+               case SPEED_100:
+                       ctrl |= PHY_CT_SP100;
+                       reg |= GM_GPCR_SPEED_100;
+                       break;
+               }
+               if (sky2->duplex == DUPLEX_FULL) {
+                       reg |= GM_GPCR_DUP_FULL;
+                       ctrl |= PHY_CT_DUP_MD;
+               } else if (sky2->speed < SPEED_1000)
+                       sky2->flow_mode = FC_NONE;
+       }
+       if (sky2->flags & SKY2_FLAG_AUTO_PAUSE) {
+               if (sky2_is_copper(hw))
+                       adv |= copper_fc_adv[sky2->flow_mode];
+               else
+                       adv |= fiber_fc_adv[sky2->flow_mode];
+       } else {
+               reg |= GM_GPCR_AU_FCT_DIS;
+               reg |= gm_fc_disable[sky2->flow_mode];
+               /* Forward pause packets to GMAC? */
+               if (sky2->flow_mode & FC_RX)
+                       sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+               else
+                       sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+       }
+       gma_write16(hw, port, GM_GP_CTRL, reg);
+       if (hw->flags & SKY2_HW_GIGABIT)
+               gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+       gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
+       gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+       /* Setup Phy LED's */
+       ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
+       ledover = 0;
+       switch (hw->chip_id) {
+       case CHIP_ID_YUKON_FE:
+               /* on 88E3082 these bits are at 11..9 (shifted left) */
+               ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
+               ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);
+               /* delete ACT LED control bits */
+               ctrl &= ~PHY_M_FELP_LED1_MSK;
+               /* change ACT LED control to blink mode */
+               ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
+               gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
+               break;
+       case CHIP_ID_YUKON_FE_P:
+               /* Enable Link Partner Next Page */
+               ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+               ctrl |= PHY_M_PC_ENA_LIP_NP;
+               /* disable Energy Detect and enable scrambler */
+               ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB);
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+               /* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */
+               ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) |
+                       PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) |
+                       PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED);
+               gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
+               break;
+       case CHIP_ID_YUKON_XL:
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               /* select page 3 to access LED control register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+               /* set LED Function Control register */
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                            (PHY_M_LEDC_LOS_CTRL(1) |  /* LINK/ACT */
+                             PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */
+                             PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
+                             PHY_M_LEDC_STA0_CTRL(7)));        /* 1000 Mbps */
+               /* set Polarity Control register */
+               gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
+                            (PHY_M_POLC_LS1_P_MIX(4) |
+                             PHY_M_POLC_IS0_P_MIX(4) |
+                             PHY_M_POLC_LOS_CTRL(2) |
+                             PHY_M_POLC_INIT_CTRL(2) |
+                             PHY_M_POLC_STA1_CTRL(2) |
+                             PHY_M_POLC_STA0_CTRL(2)));
+               /* restore page register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+               break;
+       case CHIP_ID_YUKON_EC_U:
+       case CHIP_ID_YUKON_EX:
+       case CHIP_ID_YUKON_SUPR:
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               /* select page 3 to access LED control register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+               /* set LED Function Control register */
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                            (PHY_M_LEDC_LOS_CTRL(1) |  /* LINK/ACT */
+                             PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */
+                             PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */
+                             PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */
+               /* set Blink Rate in LED Timer Control Register */
+               gm_phy_write(hw, port, PHY_MARV_INT_MASK,
+                            ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS));
+               /* restore page register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+               break;
+       default:
+               /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
+               ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+               /* turn off the Rx LED (LED_RX) */
+               ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
+       }
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_UL_2) {
+               /* apply fixes in PHY AFE */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
+               /* increase differential signal amplitude in 10BASE-T */
+               gm_phy_write(hw, port, 0x18, 0xaa99);
+               gm_phy_write(hw, port, 0x17, 0x2011);
+               if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+                       /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
+                       gm_phy_write(hw, port, 0x18, 0xa204);
+                       gm_phy_write(hw, port, 0x17, 0x2002);
+               }
+               /* set page register to 0 */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
+       } else if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+                  hw->chip_rev == CHIP_REV_YU_FE2_A0) {
+               /* apply workaround for integrated resistors calibration */
+               gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
+               gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
+       } else if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
+               /* apply fixes in PHY AFE */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff);
+               /* apply RDAC termination workaround */
+               gm_phy_write(hw, port, 24, 0x2800);
+               gm_phy_write(hw, port, 23, 0x2001);
+               /* set page register back to 0 */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
+       } else if (hw->chip_id != CHIP_ID_YUKON_EX &&
+                  hw->chip_id < CHIP_ID_YUKON_SUPR) {
+               /* no effect on Yukon-XL */
+               gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+               if (!(sky2->flags & SKY2_FLAG_AUTO_SPEED) ||
+                   sky2->speed == SPEED_100) {
+                       /* turn on 100 Mbps LED (LED_LINK100) */
+                       ledover |= PHY_M_LED_MO_100(MO_LED_ON);
+               }
+               if (ledover)
+                       gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+       } else if (hw->chip_id == CHIP_ID_YUKON_PRM &&
+                  (sky2_read8(hw, B2_MAC_CFG) & 0xf) == 0x7) {
+               int i;
+               /* This a phy register setup workaround copied from vendor driver. */
+               static const struct {
+                       u16 reg, val;
+               } eee_afe[] = {
+                       { 0x156, 0x58ce },
+                       { 0x153, 0x99eb },
+                       { 0x141, 0x8064 },
+                       /* { 0x155, 0x130b },*/
+                       { 0x000, 0x0000 },
+                       { 0x151, 0x8433 },
+                       { 0x14b, 0x8c44 },
+                       { 0x14c, 0x0f90 },
+                       { 0x14f, 0x39aa },
+                       /* { 0x154, 0x2f39 },*/
+                       { 0x14d, 0xba33 },
+                       { 0x144, 0x0048 },
+                       { 0x152, 0x2010 },
+                       /* { 0x158, 0x1223 },*/
+                       { 0x140, 0x4444 },
+                       { 0x154, 0x2f3b },
+                       { 0x158, 0xb203 },
+                       { 0x157, 0x2029 },
+               };
+               /* Start Workaround for OptimaEEE Rev.Z0 */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fb);
+               gm_phy_write(hw, port,  1, 0x4099);
+               gm_phy_write(hw, port,  3, 0x1120);
+               gm_phy_write(hw, port, 11, 0x113c);
+               gm_phy_write(hw, port, 14, 0x8100);
+               gm_phy_write(hw, port, 15, 0x112a);
+               gm_phy_write(hw, port, 17, 0x1008);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fc);
+               gm_phy_write(hw, port,  1, 0x20b0);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff);
+               for (i = 0; i < ARRAY_SIZE(eee_afe); i++) {
+                       /* apply AFE settings */
+                       gm_phy_write(hw, port, 17, eee_afe[i].val);
+                       gm_phy_write(hw, port, 16, eee_afe[i].reg | 1u<<13);
+               }
+               /* End Workaround for OptimaEEE */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
+               /* Enable 10Base-Te (EEE) */
+               if (hw->chip_id >= CHIP_ID_YUKON_PRM) {
+                       reg = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+                       gm_phy_write(hw, port, PHY_MARV_EXT_CTRL,
+                                    reg | PHY_M_10B_TE_ENABLE);
+               }
+       }
+       /* Enable phy interrupt on auto-negotiation complete (or link up) */
+       if (sky2->flags & SKY2_FLAG_AUTO_SPEED)
+               gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
+       else
+               gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+ }
+ static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
+ static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
+ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
+ {
+       u32 reg1;
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+       reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+       reg1 &= ~phy_power[port];
+       if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1)
+               reg1 |= coma_mode[port];
+       sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+       sky2_pci_read32(hw, PCI_DEV_REG1);
+       if (hw->chip_id == CHIP_ID_YUKON_FE)
+               gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_ANE);
+       else if (hw->flags & SKY2_HW_ADV_POWER_CTL)
+               sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
+ }
+ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
+ {
+       u32 reg1;
+       u16 ctrl;
+       /* release GPHY Control reset */
+       sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
+       /* release GMAC reset */
+       sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+       if (hw->flags & SKY2_HW_NEWER_PHY) {
+               /* select page 2 to access MAC control register */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+               ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+               /* allow GMII Power Down */
+               ctrl &= ~PHY_M_MAC_GMIF_PUP;
+               gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+               /* set page register back to 0 */
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
+       }
+       /* setup General Purpose Control Register */
+       gma_write16(hw, port, GM_GP_CTRL,
+                   GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 |
+                   GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |
+                   GM_GPCR_AU_SPD_DIS);
+       if (hw->chip_id != CHIP_ID_YUKON_EC) {
+               if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+                       /* select page 2 to access MAC control register */
+                       gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+                       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+                       /* enable Power Down */
+                       ctrl |= PHY_M_PC_POW_D_ENA;
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+                       /* set page register back to 0 */
+                       gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
+               }
+               /* set IEEE compatible Power Down Mode (dev. #4.99) */
+               gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN);
+       }
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+       reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+       reg1 |= phy_power[port];                /* set PHY to PowerDown/COMA Mode */
+       sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+ }
+ /* configure IPG according to used link speed */
+ static void sky2_set_ipg(struct sky2_port *sky2)
+ {
+       u16 reg;
+       reg = gma_read16(sky2->hw, sky2->port, GM_SERIAL_MODE);
+       reg &= ~GM_SMOD_IPG_MSK;
+       if (sky2->speed > SPEED_100)
+               reg |= IPG_DATA_VAL(IPG_DATA_DEF_1000);
+       else
+               reg |= IPG_DATA_VAL(IPG_DATA_DEF_10_100);
+       gma_write16(sky2->hw, sky2->port, GM_SERIAL_MODE, reg);
+ }
+ /* Enable Rx/Tx */
+ static void sky2_enable_rx_tx(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 reg;
+       reg = gma_read16(hw, port, GM_GP_CTRL);
+       reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+       gma_write16(hw, port, GM_GP_CTRL, reg);
+ }
+ /* Force a renegotiation */
+ static void sky2_phy_reinit(struct sky2_port *sky2)
+ {
+       spin_lock_bh(&sky2->phy_lock);
+       sky2_phy_init(sky2->hw, sky2->port);
+       sky2_enable_rx_tx(sky2);
+       spin_unlock_bh(&sky2->phy_lock);
+ }
+ /* Put device in state to listen for Wake On Lan */
+ static void sky2_wol_init(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       enum flow_control save_mode;
+       u16 ctrl;
+       /* Bring hardware out of reset */
+       sky2_write16(hw, B0_CTST, CS_RST_CLR);
+       sky2_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR);
+       sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
+       sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+       /* Force to 10/100
+        * sky2_reset will re-enable on resume
+        */
+       save_mode = sky2->flow_mode;
+       ctrl = sky2->advertising;
+       sky2->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
+       sky2->flow_mode = FC_NONE;
+       spin_lock_bh(&sky2->phy_lock);
+       sky2_phy_power_up(hw, port);
+       sky2_phy_init(hw, port);
+       spin_unlock_bh(&sky2->phy_lock);
+       sky2->flow_mode = save_mode;
+       sky2->advertising = ctrl;
+       /* Set GMAC to no flow control and auto update for speed/duplex */
+       gma_write16(hw, port, GM_GP_CTRL,
+                   GM_GPCR_FC_TX_DIS|GM_GPCR_TX_ENA|GM_GPCR_RX_ENA|
+                   GM_GPCR_DUP_FULL|GM_GPCR_FC_RX_DIS|GM_GPCR_AU_FCT_DIS);
+       /* Set WOL address */
+       memcpy_toio(hw->regs + WOL_REGS(port, WOL_MAC_ADDR),
+                   sky2->netdev->dev_addr, ETH_ALEN);
+       /* Turn on appropriate WOL control bits */
+       sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), WOL_CTL_CLEAR_RESULT);
+       ctrl = 0;
+       if (sky2->wol & WAKE_PHY)
+               ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG|WOL_CTL_ENA_LINK_CHG_UNIT;
+       else
+               ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG|WOL_CTL_DIS_LINK_CHG_UNIT;
+       if (sky2->wol & WAKE_MAGIC)
+               ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT;
+       else
+               ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;
+       ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
+       sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
+       /* Disable PiG firmware */
+       sky2_write16(hw, B0_CTST, Y2_HW_WOL_OFF);
+       /* block receiver */
+       sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+ }
+ static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
+ {
+       struct net_device *dev = hw->dev[port];
+       if ( (hw->chip_id == CHIP_ID_YUKON_EX &&
+             hw->chip_rev != CHIP_REV_YU_EX_A0) ||
+            hw->chip_id >= CHIP_ID_YUKON_FE_P) {
+               /* Yukon-Extreme B0 and further Extreme devices */
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
+       } else if (dev->mtu > ETH_DATA_LEN) {
+               /* set Tx GMAC FIFO Almost Empty Threshold */
+               sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
+                            (ECU_JUMBO_WM << 16) | ECU_AE_THR);
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
+       } else
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
+ }
+ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
+ {
+       struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+       u16 reg;
+       u32 rx_reg;
+       int i;
+       const u8 *addr = hw->dev[port]->dev_addr;
+       sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+       sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
+       sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+       if (hw->chip_id == CHIP_ID_YUKON_XL &&
+           hw->chip_rev == CHIP_REV_YU_XL_A0 &&
+           port == 1) {
+               /* WA DEV_472 -- looks like crossed wires on port 2 */
+               /* clear GMAC 1 Control reset */
+               sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
+               do {
+                       sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
+                       sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
+               } while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
+                        gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
+                        gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
+       }
+       sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
+       /* Enable Transmit FIFO Underrun */
+       sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
+       spin_lock_bh(&sky2->phy_lock);
+       sky2_phy_power_up(hw, port);
+       sky2_phy_init(hw, port);
+       spin_unlock_bh(&sky2->phy_lock);
+       /* MIB clear */
+       reg = gma_read16(hw, port, GM_PHY_ADDR);
+       gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+       for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
+               gma_read16(hw, port, i);
+       gma_write16(hw, port, GM_PHY_ADDR, reg);
+       /* transmit control */
+       gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
+       /* receive control reg: unicast + multicast + no FCS  */
+       gma_write16(hw, port, GM_RX_CTRL,
+                   GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
+       /* transmit flow control */
+       gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
+       /* transmit parameter */
+       gma_write16(hw, port, GM_TX_PARAM,
+                   TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
+                   TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
+                   TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
+                   TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));
+       /* serial mode register */
+       reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
+               GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF_1000);
+       if (hw->dev[port]->mtu > ETH_DATA_LEN)
+               reg |= GM_SMOD_JUMBO_ENA;
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+           hw->chip_rev == CHIP_REV_YU_EC_U_B1)
+               reg |= GM_NEW_FLOW_CTRL;
+       gma_write16(hw, port, GM_SERIAL_MODE, reg);
+       /* virtual address for data */
+       gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
+       /* physical address: used for pause frames */
+       gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
+       /* ignore counter overflows */
+       gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
+       gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
+       gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
+       /* Configure Rx MAC FIFO */
+       sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
+       rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
+       if (hw->chip_id == CHIP_ID_YUKON_EX ||
+           hw->chip_id == CHIP_ID_YUKON_FE_P)
+               rx_reg |= GMF_RX_OVER_ON;
+       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg);
+       if (hw->chip_id == CHIP_ID_YUKON_XL) {
+               /* Hardware errata - clear flush mask */
+               sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), 0);
+       } else {
+               /* Flush Rx MAC FIFO on any flow control or error */
+               sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
+       }
+       /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug  */
+       reg = RX_GMF_FL_THR_DEF + 1;
+       /* Another magic mystery workaround from sk98lin */
+       if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+           hw->chip_rev == CHIP_REV_YU_FE2_A0)
+               reg = 0x178;
+       sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg);
+       /* Configure Tx MAC FIFO */
+       sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
+       sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+       /* On chips without ram buffer, pause is controlled by MAC level */
+       if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
+               /* Pause threshold is scaled by 8 in bytes */
+               if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+                   hw->chip_rev == CHIP_REV_YU_FE2_A0)
+                       reg = 1568 / 8;
+               else
+                       reg = 1024 / 8;
+               sky2_write16(hw, SK_REG(port, RX_GMF_UP_THR), reg);
+               sky2_write16(hw, SK_REG(port, RX_GMF_LP_THR), 768 / 8);
+               sky2_set_tx_stfwd(hw, port);
+       }
+       if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+           hw->chip_rev == CHIP_REV_YU_FE2_A0) {
+               /* disable dynamic watermark */
+               reg = sky2_read16(hw, SK_REG(port, TX_GMF_EA));
+               reg &= ~TX_DYN_WM_ENA;
+               sky2_write16(hw, SK_REG(port, TX_GMF_EA), reg);
+       }
+ }
+ /* Assign Ram Buffer allocation to queue */
+ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space)
+ {
+       u32 end;
+       /* convert from K bytes to qwords used for hw register */
+       start *= 1024/8;
+       space *= 1024/8;
+       end = start + space - 1;
+       sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
+       sky2_write32(hw, RB_ADDR(q, RB_START), start);
+       sky2_write32(hw, RB_ADDR(q, RB_END), end);
+       sky2_write32(hw, RB_ADDR(q, RB_WP), start);
+       sky2_write32(hw, RB_ADDR(q, RB_RP), start);
+       if (q == Q_R1 || q == Q_R2) {
+               u32 tp = space - space/4;
+               /* On receive queue's set the thresholds
+                * give receiver priority when > 3/4 full
+                * send pause when down to 2K
+                */
+               sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
+               sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
+               tp = space - 2048/8;
+               sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
+               sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
+       } else {
+               /* Enable store & forward on Tx queue's because
+                * Tx FIFO is only 1K on Yukon
+                */
+               sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
+       }
+       sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
+       sky2_read8(hw, RB_ADDR(q, RB_CTRL));
+ }
+ /* Setup Bus Memory Interface */
+ static void sky2_qset(struct sky2_hw *hw, u16 q)
+ {
+       sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
+       sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
+       sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
+       sky2_write32(hw, Q_ADDR(q, Q_WM),  BMU_WM_DEFAULT);
+ }
+ /* Setup prefetch unit registers. This is the interface between
+  * hardware and driver list elements
+  */
+ static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
+                              dma_addr_t addr, u32 last)
+ {
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), upper_32_bits(addr));
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), lower_32_bits(addr));
+       sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
+       sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
+       sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
+ }
+ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot)
+ {
+       struct sky2_tx_le *le = sky2->tx_le + *slot;
+       *slot = RING_NEXT(*slot, sky2->tx_ring_size);
+       le->ctrl = 0;
+       return le;
+ }
+ static void tx_init(struct sky2_port *sky2)
+ {
+       struct sky2_tx_le *le;
+       sky2->tx_prod = sky2->tx_cons = 0;
+       sky2->tx_tcpsum = 0;
+       sky2->tx_last_mss = 0;
+       le = get_tx_le(sky2, &sky2->tx_prod);
+       le->addr = 0;
+       le->opcode = OP_ADDR64 | HW_OWNER;
+       sky2->tx_last_upper = 0;
+ }
+ /* Update chip's next pointer */
+ static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
+ {
+       /* Make sure write' to descriptors are complete before we tell hardware */
+       wmb();
+       sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
+       /* Synchronize I/O on since next processor may write to tail */
+       mmiowb();
+ }
+ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
+ {
+       struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
+       sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE);
+       le->ctrl = 0;
+       return le;
+ }
+ static unsigned sky2_get_rx_threshold(struct sky2_port *sky2)
+ {
+       unsigned size;
+       /* Space needed for frame data + headers rounded up */
+       size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
+       /* Stopping point for hardware truncation */
+       return (size - 8) / sizeof(u32);
+ }
+ static unsigned sky2_get_rx_data_size(struct sky2_port *sky2)
+ {
+       struct rx_ring_info *re;
+       unsigned size;
+       /* Space needed for frame data + headers rounded up */
+       size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
+       sky2->rx_nfrags = size >> PAGE_SHIFT;
+       BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
+       /* Compute residue after pages */
+       size -= sky2->rx_nfrags << PAGE_SHIFT;
+       /* Optimize to handle small packets and headers */
+       if (size < copybreak)
+               size = copybreak;
+       if (size < ETH_HLEN)
+               size = ETH_HLEN;
+       return size;
+ }
+ /* Build description to hardware for one receive segment */
+ static void sky2_rx_add(struct sky2_port *sky2, u8 op,
+                       dma_addr_t map, unsigned len)
+ {
+       struct sky2_rx_le *le;
+       if (sizeof(dma_addr_t) > sizeof(u32)) {
+               le = sky2_next_rx(sky2);
+               le->addr = cpu_to_le32(upper_32_bits(map));
+               le->opcode = OP_ADDR64 | HW_OWNER;
+       }
+       le = sky2_next_rx(sky2);
+       le->addr = cpu_to_le32(lower_32_bits(map));
+       le->length = cpu_to_le16(len);
+       le->opcode = op | HW_OWNER;
+ }
+ /* Build description to hardware for one possibly fragmented skb */
+ static void sky2_rx_submit(struct sky2_port *sky2,
+                          const struct rx_ring_info *re)
+ {
+       int i;
+       sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size);
+       for (i = 0; i < skb_shinfo(re->skb)->nr_frags; i++)
+               sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE);
+ }
+ static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+                           unsigned size)
+ {
+       struct sk_buff *skb = re->skb;
+       int i;
+       re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+       if (pci_dma_mapping_error(pdev, re->data_addr))
+               goto mapping_error;
+       dma_unmap_len_set(re, data_size, size);
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               re->frag_addr[i] = skb_frag_dma_map(&pdev->dev, frag, 0,
+                                                   skb_frag_size(frag),
+                                                   DMA_FROM_DEVICE);
+               if (dma_mapping_error(&pdev->dev, re->frag_addr[i]))
+                       goto map_page_error;
+       }
+       return 0;
+ map_page_error:
+       while (--i >= 0) {
+               pci_unmap_page(pdev, re->frag_addr[i],
+                              skb_frag_size(&skb_shinfo(skb)->frags[i]),
+                              PCI_DMA_FROMDEVICE);
+       }
+       pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size),
+                        PCI_DMA_FROMDEVICE);
+ mapping_error:
+       if (net_ratelimit())
+               dev_warn(&pdev->dev, "%s: rx mapping error\n",
+                        skb->dev->name);
+       return -EIO;
+ }
+ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
+ {
+       struct sk_buff *skb = re->skb;
+       int i;
+       pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size),
+                        PCI_DMA_FROMDEVICE);
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+               pci_unmap_page(pdev, re->frag_addr[i],
+                              skb_frag_size(&skb_shinfo(skb)->frags[i]),
+                              PCI_DMA_FROMDEVICE);
+ }
+ /* Tell chip where to start receive checksum.
+  * Actually has two checksums, but set both same to avoid possible byte
+  * order problems.
+  */
+ static void rx_set_checksum(struct sky2_port *sky2)
+ {
+       struct sky2_rx_le *le = sky2_next_rx(sky2);
+       le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
+       le->ctrl = 0;
+       le->opcode = OP_TCPSTART | HW_OWNER;
+       sky2_write32(sky2->hw,
+                    Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                    (sky2->netdev->features & NETIF_F_RXCSUM)
+                    ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+ }
+ /* Enable/disable receive hash calculation (RSS) */
+ static void rx_set_rss(struct net_device *dev, u32 features)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       int i, nkeys = 4;
+       /* Supports IPv6 and other modes */
+       if (hw->flags & SKY2_HW_NEW_LE) {
+               nkeys = 10;
+               sky2_write32(hw, SK_REG(sky2->port, RSS_CFG), HASH_ALL);
+       }
+       /* Program RSS initial values */
+       if (features & NETIF_F_RXHASH) {
+               u32 key[nkeys];
+               get_random_bytes(key, nkeys * sizeof(u32));
+               for (i = 0; i < nkeys; i++)
+                       sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
+                                    key[i]);
+               /* Need to turn on (undocumented) flag to make hashing work  */
+               sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
+                            RX_STFW_ENA);
+               sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                            BMU_ENA_RX_RSS_HASH);
+       } else
+               sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                            BMU_DIS_RX_RSS_HASH);
+ }
+ /*
+  * The RX Stop command will not work for Yukon-2 if the BMU does not
+  * reach the end of packet and since we can't make sure that we have
+  * incoming data, we must reset the BMU while it is not doing a DMA
+  * transfer. Since it is possible that the RX path is still active,
+  * the RX RAM buffer will be stopped first, so any possible incoming
+  * data will not trigger a DMA. After the RAM buffer is stopped, the
+  * BMU is polled until any DMA in progress is ended and only then it
+  * will be reset.
+  */
+ static void sky2_rx_stop(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned rxq = rxqaddr[sky2->port];
+       int i;
+       /* disable the RAM Buffer receive queue */
+       sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);
+       for (i = 0; i < 0xffff; i++)
+               if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
+                   == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
+                       goto stopped;
+       netdev_warn(sky2->netdev, "receiver stop failed\n");
+ stopped:
+       sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
+       /* reset the Rx prefetch unit */
+       sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+       mmiowb();
+ }
+ /* Clean out receive buffer area, assumes receiver hardware stopped */
+ static void sky2_rx_clean(struct sky2_port *sky2)
+ {
+       unsigned i;
+       memset(sky2->rx_le, 0, RX_LE_BYTES);
+       for (i = 0; i < sky2->rx_pending; i++) {
+               struct rx_ring_info *re = sky2->rx_ring + i;
+               if (re->skb) {
+                       sky2_rx_unmap_skb(sky2->hw->pdev, re);
+                       kfree_skb(re->skb);
+                       re->skb = NULL;
+               }
+       }
+ }
+ /* Basic MII support */
+ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+       struct mii_ioctl_data *data = if_mii(ifr);
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       int err = -EOPNOTSUPP;
+       if (!netif_running(dev))
+               return -ENODEV; /* Phy still in reset */
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = PHY_ADDR_MARV;
+               /* fallthru */
+       case SIOCGMIIREG: {
+               u16 val = 0;
+               spin_lock_bh(&sky2->phy_lock);
+               err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
+               spin_unlock_bh(&sky2->phy_lock);
+               data->val_out = val;
+               break;
+       }
+       case SIOCSMIIREG:
+               spin_lock_bh(&sky2->phy_lock);
+               err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
+                                  data->val_in);
+               spin_unlock_bh(&sky2->phy_lock);
+               break;
+       }
+       return err;
+ }
+ #define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO)
+ static void sky2_vlan_mode(struct net_device *dev, u32 features)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       u16 port = sky2->port;
+       if (features & NETIF_F_HW_VLAN_RX)
+               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+                            RX_VLAN_STRIP_ON);
+       else
+               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+                            RX_VLAN_STRIP_OFF);
+       if (features & NETIF_F_HW_VLAN_TX) {
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                            TX_VLAN_TAG_ON);
+               dev->vlan_features |= SKY2_VLAN_OFFLOADS;
+       } else {
+               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                            TX_VLAN_TAG_OFF);
+               /* Can't do transmit offload of vlan without hw vlan */
+               dev->vlan_features &= ~SKY2_VLAN_OFFLOADS;
+       }
+ }
+ /* Amount of required worst case padding in rx buffer */
+ static inline unsigned sky2_rx_pad(const struct sky2_hw *hw)
+ {
+       return (hw->flags & SKY2_HW_RAM_BUFFER) ? 8 : 2;
+ }
+ /*
+  * Allocate an skb for receiving. If the MTU is large enough
+  * make the skb non-linear with a fragment list of pages.
+  */
+ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2, gfp_t gfp)
+ {
+       struct sk_buff *skb;
+       int i;
+       skb = __netdev_alloc_skb(sky2->netdev,
+                                sky2->rx_data_size + sky2_rx_pad(sky2->hw),
+                                gfp);
+       if (!skb)
+               goto nomem;
+       if (sky2->hw->flags & SKY2_HW_RAM_BUFFER) {
+               unsigned char *start;
+               /*
+                * Workaround for a bug in FIFO that cause hang
+                * if the FIFO if the receive buffer is not 64 byte aligned.
+                * The buffer returned from netdev_alloc_skb is
+                * aligned except if slab debugging is enabled.
+                */
+               start = PTR_ALIGN(skb->data, 8);
+               skb_reserve(skb, start - skb->data);
+       } else
+               skb_reserve(skb, NET_IP_ALIGN);
+       for (i = 0; i < sky2->rx_nfrags; i++) {
+               struct page *page = alloc_page(gfp);
+               if (!page)
+                       goto free_partial;
+               skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
+       }
+       return skb;
+ free_partial:
+       kfree_skb(skb);
+ nomem:
+       return NULL;
+ }
+ static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
+ {
+       sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
+ }
+ static int sky2_alloc_rx_skbs(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned i;
+       sky2->rx_data_size = sky2_get_rx_data_size(sky2);
+       /* Fill Rx ring */
+       for (i = 0; i < sky2->rx_pending; i++) {
+               struct rx_ring_info *re = sky2->rx_ring + i;
+               re->skb = sky2_rx_alloc(sky2, GFP_KERNEL);
+               if (!re->skb)
+                       return -ENOMEM;
+               if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
+                       dev_kfree_skb(re->skb);
+                       re->skb = NULL;
+                       return -ENOMEM;
+               }
+       }
+       return 0;
+ }
+ /*
+  * Setup receiver buffer pool.
+  * Normal case this ends up creating one list element for skb
+  * in the receive ring. Worst case if using large MTU and each
+  * allocation falls on a different 64 bit region, that results
+  * in 6 list elements per ring entry.
+  * One element is used for checksum enable/disable, and one
+  * extra to avoid wrap.
+  */
+ static void sky2_rx_start(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       struct rx_ring_info *re;
+       unsigned rxq = rxqaddr[sky2->port];
+       unsigned i, thresh;
+       sky2->rx_put = sky2->rx_next = 0;
+       sky2_qset(hw, rxq);
+       /* On PCI express lowering the watermark gives better performance */
+       if (pci_is_pcie(hw->pdev))
+               sky2_write32(hw, Q_ADDR(rxq, Q_WM), BMU_WM_PEX);
+       /* These chips have no ram buffer?
+        * MAC Rx RAM Read is controlled by hardware */
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+           hw->chip_rev > CHIP_REV_YU_EC_U_A0)
+               sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS);
+       sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
+       if (!(hw->flags & SKY2_HW_NEW_LE))
+               rx_set_checksum(sky2);
+       if (!(hw->flags & SKY2_HW_RSS_BROKEN))
+               rx_set_rss(sky2->netdev, sky2->netdev->features);
+       /* submit Rx ring */
+       for (i = 0; i < sky2->rx_pending; i++) {
+               re = sky2->rx_ring + i;
+               sky2_rx_submit(sky2, re);
+       }
+       /*
+        * The receiver hangs if it receives frames larger than the
+        * packet buffer. As a workaround, truncate oversize frames, but
+        * the register is limited to 9 bits, so if you do frames > 2052
+        * you better get the MTU right!
+        */
+       thresh = sky2_get_rx_threshold(sky2);
+       if (thresh > 0x1ff)
+               sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
+       else {
+               sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), thresh);
+               sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
+       }
+       /* Tell chip about available buffers */
+       sky2_rx_update(sky2, rxq);
+       if (hw->chip_id == CHIP_ID_YUKON_EX ||
+           hw->chip_id == CHIP_ID_YUKON_SUPR) {
+               /*
+                * Disable flushing of non ASF packets;
+                * must be done after initializing the BMUs;
+                * drivers without ASF support should do this too, otherwise
+                * it may happen that they cannot run on ASF devices;
+                * remember that the MAC FIFO isn't reset during initialization.
+                */
+               sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_MACSEC_FLUSH_OFF);
+       }
+       if (hw->chip_id >= CHIP_ID_YUKON_SUPR) {
+               /* Enable RX Home Address & Routing Header checksum fix */
+               sky2_write16(hw, SK_REG(sky2->port, RX_GMF_FL_CTRL),
+                            RX_IPV6_SA_MOB_ENA | RX_IPV6_DA_MOB_ENA);
+               /* Enable TX Home Address & Routing Header checksum fix */
+               sky2_write32(hw, Q_ADDR(txqaddr[sky2->port], Q_TEST),
+                            TBMU_TEST_HOME_ADD_FIX_EN | TBMU_TEST_ROUTING_ADD_FIX_EN);
+       }
+ }
+ static int sky2_alloc_buffers(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       /* must be power of 2 */
+       sky2->tx_le = pci_alloc_consistent(hw->pdev,
+                                          sky2->tx_ring_size *
+                                          sizeof(struct sky2_tx_le),
+                                          &sky2->tx_le_map);
+       if (!sky2->tx_le)
+               goto nomem;
+       sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
+                               GFP_KERNEL);
+       if (!sky2->tx_ring)
+               goto nomem;
+       sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+                                          &sky2->rx_le_map);
+       if (!sky2->rx_le)
+               goto nomem;
+       memset(sky2->rx_le, 0, RX_LE_BYTES);
+       sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
+                               GFP_KERNEL);
+       if (!sky2->rx_ring)
+               goto nomem;
+       return sky2_alloc_rx_skbs(sky2);
+ nomem:
+       return -ENOMEM;
+ }
+ static void sky2_free_buffers(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       sky2_rx_clean(sky2);
+       if (sky2->rx_le) {
+               pci_free_consistent(hw->pdev, RX_LE_BYTES,
+                                   sky2->rx_le, sky2->rx_le_map);
+               sky2->rx_le = NULL;
+       }
+       if (sky2->tx_le) {
+               pci_free_consistent(hw->pdev,
+                                   sky2->tx_ring_size * sizeof(struct sky2_tx_le),
+                                   sky2->tx_le, sky2->tx_le_map);
+               sky2->tx_le = NULL;
+       }
+       kfree(sky2->tx_ring);
+       kfree(sky2->rx_ring);
+       sky2->tx_ring = NULL;
+       sky2->rx_ring = NULL;
+ }
+ static void sky2_hw_up(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u32 ramsize;
+       int cap;
+       struct net_device *otherdev = hw->dev[sky2->port^1];
+       tx_init(sky2);
+       /*
+        * On dual port PCI-X card, there is an problem where status
+        * can be received out of order due to split transactions
+        */
+       if (otherdev && netif_running(otherdev) &&
+           (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
+               u16 cmd;
+               cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
+               cmd &= ~PCI_X_CMD_MAX_SPLIT;
+               sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
+       }
+       sky2_mac_init(hw, port);
+       /* Register is number of 4K blocks on internal RAM buffer. */
+       ramsize = sky2_read8(hw, B2_E_0) * 4;
+       if (ramsize > 0) {
+               u32 rxspace;
+               netdev_dbg(sky2->netdev, "ram buffer %dK\n", ramsize);
+               if (ramsize < 16)
+                       rxspace = ramsize / 2;
+               else
+                       rxspace = 8 + (2*(ramsize - 16))/3;
+               sky2_ramset(hw, rxqaddr[port], 0, rxspace);
+               sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
+               /* Make sure SyncQ is disabled */
+               sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
+                           RB_RST_SET);
+       }
+       sky2_qset(hw, txqaddr[port]);
+       /* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */
+       if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0)
+               sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
+       /* Set almost empty threshold */
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+           hw->chip_rev == CHIP_REV_YU_EC_U_A0)
+               sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
+       sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
+                          sky2->tx_ring_size - 1);
+       sky2_vlan_mode(sky2->netdev, sky2->netdev->features);
+       netdev_update_features(sky2->netdev);
+       sky2_rx_start(sky2);
+ }
+ /* Setup device IRQ and enable napi to process */
+ static int sky2_setup_irq(struct sky2_hw *hw, const char *name)
+ {
+       struct pci_dev *pdev = hw->pdev;
+       int err;
+       err = request_irq(pdev->irq, sky2_intr,
+                         (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
+                         name, hw);
+       if (err)
+               dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
+       else {
+               napi_enable(&hw->napi);
+               sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+               sky2_read32(hw, B0_IMSK);
+       }
+       return err;
+ }
+ /* Bring up network interface. */
+ static int sky2_up(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u32 imask;
+       int err;
+       netif_carrier_off(dev);
+       err = sky2_alloc_buffers(sky2);
+       if (err)
+               goto err_out;
+       /* With single port, IRQ is setup when device is brought up */
+       if (hw->ports == 1 && (err = sky2_setup_irq(hw, dev->name)))
+               goto err_out;
+       sky2_hw_up(sky2);
+       /* Enable interrupts from phy/mac for port */
+       imask = sky2_read32(hw, B0_IMSK);
+       imask |= portirq_msk[port];
+       sky2_write32(hw, B0_IMSK, imask);
+       sky2_read32(hw, B0_IMSK);
+       netif_info(sky2, ifup, dev, "enabling interface\n");
+       return 0;
+ err_out:
+       sky2_free_buffers(sky2);
+       return err;
+ }
+ /* Modular subtraction in ring */
+ static inline int tx_inuse(const struct sky2_port *sky2)
+ {
+       return (sky2->tx_prod - sky2->tx_cons) & (sky2->tx_ring_size - 1);
+ }
+ /* Number of list elements available for next tx */
+ static inline int tx_avail(const struct sky2_port *sky2)
+ {
+       return sky2->tx_pending - tx_inuse(sky2);
+ }
+ /* Estimate of number of transmit list elements required */
+ static unsigned tx_le_req(const struct sk_buff *skb)
+ {
+       unsigned count;
+       count = (skb_shinfo(skb)->nr_frags + 1)
+               * (sizeof(dma_addr_t) / sizeof(u32));
+       if (skb_is_gso(skb))
+               ++count;
+       else if (sizeof(dma_addr_t) == sizeof(u32))
+               ++count;        /* possible vlan */
+       if (skb->ip_summed == CHECKSUM_PARTIAL)
+               ++count;
+       return count;
+ }
+ static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re)
+ {
+       if (re->flags & TX_MAP_SINGLE)
+               pci_unmap_single(pdev, dma_unmap_addr(re, mapaddr),
+                                dma_unmap_len(re, maplen),
+                                PCI_DMA_TODEVICE);
+       else if (re->flags & TX_MAP_PAGE)
+               pci_unmap_page(pdev, dma_unmap_addr(re, mapaddr),
+                              dma_unmap_len(re, maplen),
+                              PCI_DMA_TODEVICE);
+       re->flags = 0;
+ }
+ /*
+  * Put one packet in ring for transmit.
+  * A single packet can generate multiple list elements, and
+  * the number of ring elements will probably be less than the number
+  * of list elements used.
+  */
+ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
+                                  struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       struct sky2_tx_le *le = NULL;
+       struct tx_ring_info *re;
+       unsigned i, len;
+       dma_addr_t mapping;
+       u32 upper;
+       u16 slot;
+       u16 mss;
+       u8 ctrl;
+       if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
+               return NETDEV_TX_BUSY;
+       len = skb_headlen(skb);
+       mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(hw->pdev, mapping))
+               goto mapping_error;
+       slot = sky2->tx_prod;
+       netif_printk(sky2, tx_queued, KERN_DEBUG, dev,
+                    "tx queued, slot %u, len %d\n", slot, skb->len);
+       /* Send high bits if needed */
+       upper = upper_32_bits(mapping);
+       if (upper != sky2->tx_last_upper) {
+               le = get_tx_le(sky2, &slot);
+               le->addr = cpu_to_le32(upper);
+               sky2->tx_last_upper = upper;
+               le->opcode = OP_ADDR64 | HW_OWNER;
+       }
+       /* Check for TCP Segmentation Offload */
+       mss = skb_shinfo(skb)->gso_size;
+       if (mss != 0) {
+               if (!(hw->flags & SKY2_HW_NEW_LE))
+                       mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
+               if (mss != sky2->tx_last_mss) {
+                       le = get_tx_le(sky2, &slot);
+                       le->addr = cpu_to_le32(mss);
+                       if (hw->flags & SKY2_HW_NEW_LE)
+                               le->opcode = OP_MSS | HW_OWNER;
+                       else
+                               le->opcode = OP_LRGLEN | HW_OWNER;
+                       sky2->tx_last_mss = mss;
+               }
+       }
+       ctrl = 0;
+       /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
+       if (vlan_tx_tag_present(skb)) {
+               if (!le) {
+                       le = get_tx_le(sky2, &slot);
+                       le->addr = 0;
+                       le->opcode = OP_VLAN|HW_OWNER;
+               } else
+                       le->opcode |= OP_VLAN;
+               le->length = cpu_to_be16(vlan_tx_tag_get(skb));
+               ctrl |= INS_VLAN;
+       }
+       /* Handle TCP checksum offload */
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               /* On Yukon EX (some versions) encoding change. */
+               if (hw->flags & SKY2_HW_AUTO_TX_SUM)
+                       ctrl |= CALSUM; /* auto checksum */
+               else {
+                       const unsigned offset = skb_transport_offset(skb);
+                       u32 tcpsum;
+                       tcpsum = offset << 16;                  /* sum start */
+                       tcpsum |= offset + skb->csum_offset;    /* sum write */
+                       ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+                       if (ip_hdr(skb)->protocol == IPPROTO_UDP)
+                               ctrl |= UDPTCP;
+                       if (tcpsum != sky2->tx_tcpsum) {
+                               sky2->tx_tcpsum = tcpsum;
+                               le = get_tx_le(sky2, &slot);
+                               le->addr = cpu_to_le32(tcpsum);
+                               le->length = 0; /* initial checksum value */
+                               le->ctrl = 1;   /* one packet */
+                               le->opcode = OP_TCPLISW | HW_OWNER;
+                       }
+               }
+       }
+       re = sky2->tx_ring + slot;
+       re->flags = TX_MAP_SINGLE;
+       dma_unmap_addr_set(re, mapaddr, mapping);
+       dma_unmap_len_set(re, maplen, len);
+       le = get_tx_le(sky2, &slot);
+       le->addr = cpu_to_le32(lower_32_bits(mapping));
+       le->length = cpu_to_le16(len);
+       le->ctrl = ctrl;
+       le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               mapping = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
+                                          skb_frag_size(frag), DMA_TO_DEVICE);
+               if (dma_mapping_error(&hw->pdev->dev, mapping))
+                       goto mapping_unwind;
+               upper = upper_32_bits(mapping);
+               if (upper != sky2->tx_last_upper) {
+                       le = get_tx_le(sky2, &slot);
+                       le->addr = cpu_to_le32(upper);
+                       sky2->tx_last_upper = upper;
+                       le->opcode = OP_ADDR64 | HW_OWNER;
+               }
+               re = sky2->tx_ring + slot;
+               re->flags = TX_MAP_PAGE;
+               dma_unmap_addr_set(re, mapaddr, mapping);
+               dma_unmap_len_set(re, maplen, skb_frag_size(frag));
+               le = get_tx_le(sky2, &slot);
+               le->addr = cpu_to_le32(lower_32_bits(mapping));
+               le->length = cpu_to_le16(skb_frag_size(frag));
+               le->ctrl = ctrl;
+               le->opcode = OP_BUFFER | HW_OWNER;
+       }
+       re->skb = skb;
+       le->ctrl |= EOP;
+       sky2->tx_prod = slot;
+       if (tx_avail(sky2) <= MAX_SKB_TX_LE)
+               netif_stop_queue(dev);
+       sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
+       return NETDEV_TX_OK;
+ mapping_unwind:
+       for (i = sky2->tx_prod; i != slot; i = RING_NEXT(i, sky2->tx_ring_size)) {
+               re = sky2->tx_ring + i;
+               sky2_tx_unmap(hw->pdev, re);
+       }
+ mapping_error:
+       if (net_ratelimit())
+               dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
+ }
+ /*
+  * Free ring elements from starting at tx_cons until "done"
+  *
+  * NB:
+  *  1. The hardware will tell us about partial completion of multi-part
+  *     buffers so make sure not to free skb to early.
+  *  2. This may run in parallel start_xmit because the it only
+  *     looks at the tail of the queue of FIFO (tx_cons), not
+  *     the head (tx_prod)
+  */
+ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+ {
+       struct net_device *dev = sky2->netdev;
+       unsigned idx;
+       BUG_ON(done >= sky2->tx_ring_size);
+       for (idx = sky2->tx_cons; idx != done;
+            idx = RING_NEXT(idx, sky2->tx_ring_size)) {
+               struct tx_ring_info *re = sky2->tx_ring + idx;
+               struct sk_buff *skb = re->skb;
+               sky2_tx_unmap(sky2->hw->pdev, re);
+               if (skb) {
+                       netif_printk(sky2, tx_done, KERN_DEBUG, dev,
+                                    "tx done %u\n", idx);
+                       u64_stats_update_begin(&sky2->tx_stats.syncp);
+                       ++sky2->tx_stats.packets;
+                       sky2->tx_stats.bytes += skb->len;
+                       u64_stats_update_end(&sky2->tx_stats.syncp);
+                       re->skb = NULL;
+                       dev_kfree_skb_any(skb);
+                       sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size);
+               }
+       }
+       sky2->tx_cons = idx;
+       smp_mb();
+ }
+ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
+ {
+       /* Disable Force Sync bit and Enable Alloc bit */
+       sky2_write8(hw, SK_REG(port, TXA_CTRL),
+                   TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+       /* Stop Interval Timer and Limit Counter of Tx Arbiter */
+       sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
+       sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
+       /* Reset the PCI FIFO of the async Tx queue */
+       sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
+                    BMU_RST_SET | BMU_FIFO_RST);
+       /* Reset the Tx prefetch units */
+       sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
+                    PREF_UNIT_RST_SET);
+       sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
+       sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+ }
+ static void sky2_hw_down(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 ctrl;
+       /* Force flow control off */
+       sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+       /* Stop transmitter */
+       sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
+       sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));
+       sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
+                    RB_RST_SET | RB_DIS_OP_MD);
+       ctrl = gma_read16(hw, port, GM_GP_CTRL);
+       ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
+       gma_write16(hw, port, GM_GP_CTRL, ctrl);
+       sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+       /* Workaround shared GMAC reset */
+       if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 &&
+             port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
+               sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+       sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
 -      /* Force any delayed status interrrupt and NAPI */
++      /* Force any delayed status interrupt and NAPI */
+       sky2_write32(hw, STAT_LEV_TIMER_CNT, 0);
+       sky2_write32(hw, STAT_TX_TIMER_CNT, 0);
+       sky2_write32(hw, STAT_ISR_TIMER_CNT, 0);
+       sky2_read8(hw, STAT_ISR_TIMER_CTRL);
+       sky2_rx_stop(sky2);
+       spin_lock_bh(&sky2->phy_lock);
+       sky2_phy_power_down(hw, port);
+       spin_unlock_bh(&sky2->phy_lock);
+       sky2_tx_reset(hw, port);
+       /* Free any pending frames stuck in HW queue */
+       sky2_tx_complete(sky2, sky2->tx_prod);
+ }
+ /* Network shutdown */
+ static int sky2_down(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       /* Never really got started! */
+       if (!sky2->tx_le)
+               return 0;
+       netif_info(sky2, ifdown, dev, "disabling interface\n");
+       /* Disable port IRQ */
+       sky2_write32(hw, B0_IMSK,
+                    sky2_read32(hw, B0_IMSK) & ~portirq_msk[sky2->port]);
+       sky2_read32(hw, B0_IMSK);
+       if (hw->ports == 1) {
+               napi_disable(&hw->napi);
+               free_irq(hw->pdev->irq, hw);
+       } else {
+               synchronize_irq(hw->pdev->irq);
+               napi_synchronize(&hw->napi);
+       }
+       sky2_hw_down(sky2);
+       sky2_free_buffers(sky2);
+       return 0;
+ }
+ static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
+ {
+       if (hw->flags & SKY2_HW_FIBRE_PHY)
+               return SPEED_1000;
+       if (!(hw->flags & SKY2_HW_GIGABIT)) {
+               if (aux & PHY_M_PS_SPEED_100)
+                       return SPEED_100;
+               else
+                       return SPEED_10;
+       }
+       switch (aux & PHY_M_PS_SPEED_MSK) {
+       case PHY_M_PS_SPEED_1000:
+               return SPEED_1000;
+       case PHY_M_PS_SPEED_100:
+               return SPEED_100;
+       default:
+               return SPEED_10;
+       }
+ }
+ static void sky2_link_up(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       static const char *fc_name[] = {
+               [FC_NONE]       = "none",
+               [FC_TX]         = "tx",
+               [FC_RX]         = "rx",
+               [FC_BOTH]       = "both",
+       };
+       sky2_set_ipg(sky2);
+       sky2_enable_rx_tx(sky2);
+       gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+       netif_carrier_on(sky2->netdev);
+       mod_timer(&hw->watchdog_timer, jiffies + 1);
+       /* Turn on link LED */
+       sky2_write8(hw, SK_REG(port, LNK_LED_REG),
+                   LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
+       netif_info(sky2, link, sky2->netdev,
+                  "Link is up at %d Mbps, %s duplex, flow control %s\n",
+                  sky2->speed,
+                  sky2->duplex == DUPLEX_FULL ? "full" : "half",
+                  fc_name[sky2->flow_status]);
+ }
+ static void sky2_link_down(struct sky2_port *sky2)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 reg;
+       gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+       reg = gma_read16(hw, port, GM_GP_CTRL);
+       reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+       gma_write16(hw, port, GM_GP_CTRL, reg);
+       netif_carrier_off(sky2->netdev);
+       /* Turn off link LED */
+       sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
+       netif_info(sky2, link, sky2->netdev, "Link is down\n");
+       sky2_phy_init(hw, port);
+ }
+ static enum flow_control sky2_flow(int rx, int tx)
+ {
+       if (rx)
+               return tx ? FC_BOTH : FC_RX;
+       else
+               return tx ? FC_TX : FC_NONE;
+ }
+ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       u16 advert, lpa;
+       advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
+       lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
+       if (lpa & PHY_M_AN_RF) {
+               netdev_err(sky2->netdev, "remote fault\n");
+               return -1;
+       }
+       if (!(aux & PHY_M_PS_SPDUP_RES)) {
+               netdev_err(sky2->netdev, "speed/duplex mismatch\n");
+               return -1;
+       }
+       sky2->speed = sky2_phy_speed(hw, aux);
+       sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+       /* Since the pause result bits seem to in different positions on
+        * different chips. look at registers.
+        */
+       if (hw->flags & SKY2_HW_FIBRE_PHY) {
+               /* Shift for bits in fiber PHY */
+               advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM);
+               lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM);
+               if (advert & ADVERTISE_1000XPAUSE)
+                       advert |= ADVERTISE_PAUSE_CAP;
+               if (advert & ADVERTISE_1000XPSE_ASYM)
+                       advert |= ADVERTISE_PAUSE_ASYM;
+               if (lpa & LPA_1000XPAUSE)
+                       lpa |= LPA_PAUSE_CAP;
+               if (lpa & LPA_1000XPAUSE_ASYM)
+                       lpa |= LPA_PAUSE_ASYM;
+       }
+       sky2->flow_status = FC_NONE;
+       if (advert & ADVERTISE_PAUSE_CAP) {
+               if (lpa & LPA_PAUSE_CAP)
+                       sky2->flow_status = FC_BOTH;
+               else if (advert & ADVERTISE_PAUSE_ASYM)
+                       sky2->flow_status = FC_RX;
+       } else if (advert & ADVERTISE_PAUSE_ASYM) {
+               if ((lpa & LPA_PAUSE_CAP) && (lpa & LPA_PAUSE_ASYM))
+                       sky2->flow_status = FC_TX;
+       }
+       if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 &&
+           !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
+               sky2->flow_status = FC_NONE;
+       if (sky2->flow_status & FC_TX)
+               sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+       else
+               sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+       return 0;
+ }
+ /* Interrupt from PHY */
+ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
+ {
+       struct net_device *dev = hw->dev[port];
+       struct sky2_port *sky2 = netdev_priv(dev);
+       u16 istatus, phystat;
+       if (!netif_running(dev))
+               return;
+       spin_lock(&sky2->phy_lock);
+       istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
+       phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
+       netif_info(sky2, intr, sky2->netdev, "phy interrupt status 0x%x 0x%x\n",
+                  istatus, phystat);
+       if (istatus & PHY_M_IS_AN_COMPL) {
+               if (sky2_autoneg_done(sky2, phystat) == 0 &&
+                   !netif_carrier_ok(dev))
+                       sky2_link_up(sky2);
+               goto out;
+       }
+       if (istatus & PHY_M_IS_LSP_CHANGE)
+               sky2->speed = sky2_phy_speed(hw, phystat);
+       if (istatus & PHY_M_IS_DUP_CHANGE)
+               sky2->duplex =
+                   (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+       if (istatus & PHY_M_IS_LST_CHANGE) {
+               if (phystat & PHY_M_PS_LINK_UP)
+                       sky2_link_up(sky2);
+               else
+                       sky2_link_down(sky2);
+       }
+ out:
+       spin_unlock(&sky2->phy_lock);
+ }
+ /* Special quick link interrupt (Yukon-2 Optima only) */
+ static void sky2_qlink_intr(struct sky2_hw *hw)
+ {
+       struct sky2_port *sky2 = netdev_priv(hw->dev[0]);
+       u32 imask;
+       u16 phy;
+       /* disable irq */
+       imask = sky2_read32(hw, B0_IMSK);
+       imask &= ~Y2_IS_PHY_QLNK;
+       sky2_write32(hw, B0_IMSK, imask);
+       /* reset PHY Link Detect */
+       phy = sky2_pci_read16(hw, PSM_CONFIG_REG4);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+       sky2_pci_write16(hw, PSM_CONFIG_REG4, phy | 1);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+       sky2_link_up(sky2);
+ }
+ /* Transmit timeout is only called if we are running, carrier is up
+  * and tx queue is full (stopped).
+  */
+ static void sky2_tx_timeout(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       netif_err(sky2, timer, dev, "tx timeout\n");
+       netdev_printk(KERN_DEBUG, dev, "transmit ring %u .. %u report=%u done=%u\n",
+                     sky2->tx_cons, sky2->tx_prod,
+                     sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
+                     sky2_read16(hw, Q_ADDR(txqaddr[sky2->port], Q_DONE)));
+       /* can't restart safely under softirq */
+       schedule_work(&hw->restart_work);
+ }
+ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       int err;
+       u16 ctl, mode;
+       u32 imask;
+       /* MTU size outside the spec */
+       if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
+               return -EINVAL;
+       /* MTU > 1500 on yukon FE and FE+ not allowed */
+       if (new_mtu > ETH_DATA_LEN &&
+           (hw->chip_id == CHIP_ID_YUKON_FE ||
+            hw->chip_id == CHIP_ID_YUKON_FE_P))
+               return -EINVAL;
+       if (!netif_running(dev)) {
+               dev->mtu = new_mtu;
+               netdev_update_features(dev);
+               return 0;
+       }
+       imask = sky2_read32(hw, B0_IMSK);
+       sky2_write32(hw, B0_IMSK, 0);
+       dev->trans_start = jiffies;     /* prevent tx timeout */
+       napi_disable(&hw->napi);
+       netif_tx_disable(dev);
+       synchronize_irq(hw->pdev->irq);
+       if (!(hw->flags & SKY2_HW_RAM_BUFFER))
+               sky2_set_tx_stfwd(hw, port);
+       ctl = gma_read16(hw, port, GM_GP_CTRL);
+       gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
+       sky2_rx_stop(sky2);
+       sky2_rx_clean(sky2);
+       dev->mtu = new_mtu;
+       netdev_update_features(dev);
+       mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | GM_SMOD_VLAN_ENA;
+       if (sky2->speed > SPEED_100)
+               mode |= IPG_DATA_VAL(IPG_DATA_DEF_1000);
+       else
+               mode |= IPG_DATA_VAL(IPG_DATA_DEF_10_100);
+       if (dev->mtu > ETH_DATA_LEN)
+               mode |= GM_SMOD_JUMBO_ENA;
+       gma_write16(hw, port, GM_SERIAL_MODE, mode);
+       sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
+       err = sky2_alloc_rx_skbs(sky2);
+       if (!err)
+               sky2_rx_start(sky2);
+       else
+               sky2_rx_clean(sky2);
+       sky2_write32(hw, B0_IMSK, imask);
+       sky2_read32(hw, B0_Y2_SP_LISR);
+       napi_enable(&hw->napi);
+       if (err)
+               dev_close(dev);
+       else {
+               gma_write16(hw, port, GM_GP_CTRL, ctl);
+               netif_wake_queue(dev);
+       }
+       return err;
+ }
+ /* For small just reuse existing skb for next receive */
+ static struct sk_buff *receive_copy(struct sky2_port *sky2,
+                                   const struct rx_ring_info *re,
+                                   unsigned length)
+ {
+       struct sk_buff *skb;
+       skb = netdev_alloc_skb_ip_align(sky2->netdev, length);
+       if (likely(skb)) {
+               pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr,
+                                           length, PCI_DMA_FROMDEVICE);
+               skb_copy_from_linear_data(re->skb, skb->data, length);
+               skb->ip_summed = re->skb->ip_summed;
+               skb->csum = re->skb->csum;
+               pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
+                                              length, PCI_DMA_FROMDEVICE);
+               re->skb->ip_summed = CHECKSUM_NONE;
+               skb_put(skb, length);
+       }
+       return skb;
+ }
+ /* Adjust length of skb with fragments to match received data */
+ static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
+                         unsigned int length)
+ {
+       int i, num_frags;
+       unsigned int size;
+       /* put header into skb */
+       size = min(length, hdr_space);
+       skb->tail += size;
+       skb->len += size;
+       length -= size;
+       num_frags = skb_shinfo(skb)->nr_frags;
+       for (i = 0; i < num_frags; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               if (length == 0) {
+                       /* don't need this page */
+                       __skb_frag_unref(frag);
+                       --skb_shinfo(skb)->nr_frags;
+               } else {
+                       size = min(length, (unsigned) PAGE_SIZE);
+                       skb_frag_size_set(frag, size);
+                       skb->data_len += size;
+                       skb->truesize += PAGE_SIZE;
+                       skb->len += size;
+                       length -= size;
+               }
+       }
+ }
+ /* Normal packet - take skb from ring element and put in a new one  */
+ static struct sk_buff *receive_new(struct sky2_port *sky2,
+                                  struct rx_ring_info *re,
+                                  unsigned int length)
+ {
+       struct sk_buff *skb;
+       struct rx_ring_info nre;
+       unsigned hdr_space = sky2->rx_data_size;
+       nre.skb = sky2_rx_alloc(sky2, GFP_ATOMIC);
+       if (unlikely(!nre.skb))
+               goto nobuf;
+       if (sky2_rx_map_skb(sky2->hw->pdev, &nre, hdr_space))
+               goto nomap;
+       skb = re->skb;
+       sky2_rx_unmap_skb(sky2->hw->pdev, re);
+       prefetch(skb->data);
+       *re = nre;
+       if (skb_shinfo(skb)->nr_frags)
+               skb_put_frags(skb, hdr_space, length);
+       else
+               skb_put(skb, length);
+       return skb;
+ nomap:
+       dev_kfree_skb(nre.skb);
+ nobuf:
+       return NULL;
+ }
+ /*
+  * Receive one packet.
+  * For larger packets, get new buffer.
+  */
+ static struct sk_buff *sky2_receive(struct net_device *dev,
+                                   u16 length, u32 status)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
+       struct sk_buff *skb = NULL;
+       u16 count = (status & GMR_FS_LEN) >> 16;
+       if (status & GMR_FS_VLAN)
+               count -= VLAN_HLEN;     /* Account for vlan tag */
+       netif_printk(sky2, rx_status, KERN_DEBUG, dev,
+                    "rx slot %u status 0x%x len %d\n",
+                    sky2->rx_next, status, length);
+       sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
+       prefetch(sky2->rx_ring + sky2->rx_next);
+       /* This chip has hardware problems that generates bogus status.
+        * So do only marginal checking and expect higher level protocols
+        * to handle crap frames.
+        */
+       if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
+           sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 &&
+           length != count)
+               goto okay;
+       if (status & GMR_FS_ANY_ERR)
+               goto error;
+       if (!(status & GMR_FS_RX_OK))
+               goto resubmit;
+       /* if length reported by DMA does not match PHY, packet was truncated */
+       if (length != count)
+               goto error;
+ okay:
+       if (length < copybreak)
+               skb = receive_copy(sky2, re, length);
+       else
+               skb = receive_new(sky2, re, length);
+       dev->stats.rx_dropped += (skb == NULL);
+ resubmit:
+       sky2_rx_submit(sky2, re);
+       return skb;
+ error:
+       ++dev->stats.rx_errors;
+       if (net_ratelimit())
+               netif_info(sky2, rx_err, dev,
+                          "rx error, status 0x%x length %d\n", status, length);
+       goto resubmit;
+ }
+ /* Transmit complete */
+ static inline void sky2_tx_done(struct net_device *dev, u16 last)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       if (netif_running(dev)) {
+               sky2_tx_complete(sky2, last);
+               /* Wake unless it's detached, and called e.g. from sky2_down() */
+               if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
+                       netif_wake_queue(dev);
+       }
+ }
+ static inline void sky2_skb_rx(const struct sky2_port *sky2,
+                              u32 status, struct sk_buff *skb)
+ {
+       if (status & GMR_FS_VLAN)
+               __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
+       if (skb->ip_summed == CHECKSUM_NONE)
+               netif_receive_skb(skb);
+       else
+               napi_gro_receive(&sky2->hw->napi, skb);
+ }
+ static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port,
+                               unsigned packets, unsigned bytes)
+ {
+       struct net_device *dev = hw->dev[port];
+       struct sky2_port *sky2 = netdev_priv(dev);
+       if (packets == 0)
+               return;
+       u64_stats_update_begin(&sky2->rx_stats.syncp);
+       sky2->rx_stats.packets += packets;
+       sky2->rx_stats.bytes += bytes;
+       u64_stats_update_end(&sky2->rx_stats.syncp);
+       dev->last_rx = jiffies;
+       sky2_rx_update(netdev_priv(dev), rxqaddr[port]);
+ }
+ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
+ {
+       /* If this happens then driver assuming wrong format for chip type */
+       BUG_ON(sky2->hw->flags & SKY2_HW_NEW_LE);
+       /* Both checksum counters are programmed to start at
+        * the same offset, so unless there is a problem they
+        * should match. This failure is an early indication that
+        * hardware receive checksumming won't work.
+        */
+       if (likely((u16)(status >> 16) == (u16)status)) {
+               struct sk_buff *skb = sky2->rx_ring[sky2->rx_next].skb;
+               skb->ip_summed = CHECKSUM_COMPLETE;
+               skb->csum = le16_to_cpu(status);
+       } else {
+               dev_notice(&sky2->hw->pdev->dev,
+                          "%s: receive checksum problem (status = %#x)\n",
+                          sky2->netdev->name, status);
+               /* Disable checksum offload
+                * It will be reenabled on next ndo_set_features, but if it's
+                * really broken, will get disabled again
+                */
+               sky2->netdev->features &= ~NETIF_F_RXCSUM;
+               sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                            BMU_DIS_RX_CHKSUM);
+       }
+ }
+ static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
+ {
+       struct sk_buff *skb;
+       skb = sky2->rx_ring[sky2->rx_next].skb;
+       skb->rxhash = le32_to_cpu(status);
+ }
+ /* Process status response ring */
+ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
+ {
+       int work_done = 0;
+       unsigned int total_bytes[2] = { 0 };
+       unsigned int total_packets[2] = { 0 };
+       rmb();
+       do {
+               struct sky2_port *sky2;
+               struct sky2_status_le *le  = hw->st_le + hw->st_idx;
+               unsigned port;
+               struct net_device *dev;
+               struct sk_buff *skb;
+               u32 status;
+               u16 length;
+               u8 opcode = le->opcode;
+               if (!(opcode & HW_OWNER))
+                       break;
+               hw->st_idx = RING_NEXT(hw->st_idx, hw->st_size);
+               port = le->css & CSS_LINK_BIT;
+               dev = hw->dev[port];
+               sky2 = netdev_priv(dev);
+               length = le16_to_cpu(le->length);
+               status = le32_to_cpu(le->status);
+               le->opcode = 0;
+               switch (opcode & ~HW_OWNER) {
+               case OP_RXSTAT:
+                       total_packets[port]++;
+                       total_bytes[port] += length;
+                       skb = sky2_receive(dev, length, status);
+                       if (!skb)
+                               break;
+                       /* This chip reports checksum status differently */
+                       if (hw->flags & SKY2_HW_NEW_LE) {
+                               if ((dev->features & NETIF_F_RXCSUM) &&
+                                   (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
+                                   (le->css & CSS_TCPUDPCSOK))
+                                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+                               else
+                                       skb->ip_summed = CHECKSUM_NONE;
+                       }
+                       skb->protocol = eth_type_trans(skb, dev);
+                       sky2_skb_rx(sky2, status, skb);
+                       /* Stop after net poll weight */
+                       if (++work_done >= to_do)
+                               goto exit_loop;
+                       break;
+               case OP_RXVLAN:
+                       sky2->rx_tag = length;
+                       break;
+               case OP_RXCHKSVLAN:
+                       sky2->rx_tag = length;
+                       /* fall through */
+               case OP_RXCHKS:
+                       if (likely(dev->features & NETIF_F_RXCSUM))
+                               sky2_rx_checksum(sky2, status);
+                       break;
+               case OP_RSS_HASH:
+                       sky2_rx_hash(sky2, status);
+                       break;
+               case OP_TXINDEXLE:
+                       /* TX index reports status for both ports */
+                       sky2_tx_done(hw->dev[0], status & 0xfff);
+                       if (hw->dev[1])
+                               sky2_tx_done(hw->dev[1],
+                                    ((status >> 24) & 0xff)
+                                            | (u16)(length & 0xf) << 8);
+                       break;
+               default:
+                       if (net_ratelimit())
+                               pr_warning("unknown status opcode 0x%x\n", opcode);
+               }
+       } while (hw->st_idx != idx);
+       /* Fully processed status ring so clear irq */
+       sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+ exit_loop:
+       sky2_rx_done(hw, 0, total_packets[0], total_bytes[0]);
+       sky2_rx_done(hw, 1, total_packets[1], total_bytes[1]);
+       return work_done;
+ }
+ static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
+ {
+       struct net_device *dev = hw->dev[port];
+       if (net_ratelimit())
+               netdev_info(dev, "hw error interrupt status 0x%x\n", status);
+       if (status & Y2_IS_PAR_RD1) {
+               if (net_ratelimit())
+                       netdev_err(dev, "ram data read parity error\n");
+               /* Clear IRQ */
+               sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
+       }
+       if (status & Y2_IS_PAR_WR1) {
+               if (net_ratelimit())
+                       netdev_err(dev, "ram data write parity error\n");
+               sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
+       }
+       if (status & Y2_IS_PAR_MAC1) {
+               if (net_ratelimit())
+                       netdev_err(dev, "MAC parity error\n");
+               sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
+       }
+       if (status & Y2_IS_PAR_RX1) {
+               if (net_ratelimit())
+                       netdev_err(dev, "RX parity error\n");
+               sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
+       }
+       if (status & Y2_IS_TCP_TXA1) {
+               if (net_ratelimit())
+                       netdev_err(dev, "TCP segmentation error\n");
+               sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
+       }
+ }
+ static void sky2_hw_intr(struct sky2_hw *hw)
+ {
+       struct pci_dev *pdev = hw->pdev;
+       u32 status = sky2_read32(hw, B0_HWE_ISRC);
+       u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
+       status &= hwmsk;
+       if (status & Y2_IS_TIST_OV)
+               sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+       if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
+               u16 pci_err;
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+               pci_err = sky2_pci_read16(hw, PCI_STATUS);
+               if (net_ratelimit())
+                       dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
+                               pci_err);
+               sky2_pci_write16(hw, PCI_STATUS,
+                                     pci_err | PCI_STATUS_ERROR_BITS);
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+       }
+       if (status & Y2_IS_PCI_EXP) {
+               /* PCI-Express uncorrectable Error occurred */
+               u32 err;
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+               err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
+               sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
+                            0xfffffffful);
+               if (net_ratelimit())
+                       dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
+               sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+       }
+       if (status & Y2_HWE_L1_MASK)
+               sky2_hw_error(hw, 0, status);
+       status >>= 8;
+       if (status & Y2_HWE_L1_MASK)
+               sky2_hw_error(hw, 1, status);
+ }
+ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
+ {
+       struct net_device *dev = hw->dev[port];
+       struct sky2_port *sky2 = netdev_priv(dev);
+       u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
+       netif_info(sky2, intr, dev, "mac interrupt status 0x%x\n", status);
+       if (status & GM_IS_RX_CO_OV)
+               gma_read16(hw, port, GM_RX_IRQ_SRC);
+       if (status & GM_IS_TX_CO_OV)
+               gma_read16(hw, port, GM_TX_IRQ_SRC);
+       if (status & GM_IS_RX_FF_OR) {
+               ++dev->stats.rx_fifo_errors;
+               sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
+       }
+       if (status & GM_IS_TX_FF_UR) {
+               ++dev->stats.tx_fifo_errors;
+               sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
+       }
+ }
+ /* This should never happen it is a bug. */
+ static void sky2_le_error(struct sky2_hw *hw, unsigned port, u16 q)
+ {
+       struct net_device *dev = hw->dev[port];
+       u16 idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
+       dev_err(&hw->pdev->dev, "%s: descriptor error q=%#x get=%u put=%u\n",
+               dev->name, (unsigned) q, (unsigned) idx,
+               (unsigned) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)));
+       sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
+ }
+ static int sky2_rx_hung(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       unsigned rxq = rxqaddr[port];
+       u32 mac_rp = sky2_read32(hw, SK_REG(port, RX_GMF_RP));
+       u8 mac_lev = sky2_read8(hw, SK_REG(port, RX_GMF_RLEV));
+       u8 fifo_rp = sky2_read8(hw, Q_ADDR(rxq, Q_RP));
+       u8 fifo_lev = sky2_read8(hw, Q_ADDR(rxq, Q_RL));
+       /* If idle and MAC or PCI is stuck */
+       if (sky2->check.last == dev->last_rx &&
+           ((mac_rp == sky2->check.mac_rp &&
+             mac_lev != 0 && mac_lev >= sky2->check.mac_lev) ||
+            /* Check if the PCI RX hang */
+            (fifo_rp == sky2->check.fifo_rp &&
+             fifo_lev != 0 && fifo_lev >= sky2->check.fifo_lev))) {
+               netdev_printk(KERN_DEBUG, dev,
+                             "hung mac %d:%d fifo %d (%d:%d)\n",
+                             mac_lev, mac_rp, fifo_lev,
+                             fifo_rp, sky2_read8(hw, Q_ADDR(rxq, Q_WP)));
+               return 1;
+       } else {
+               sky2->check.last = dev->last_rx;
+               sky2->check.mac_rp = mac_rp;
+               sky2->check.mac_lev = mac_lev;
+               sky2->check.fifo_rp = fifo_rp;
+               sky2->check.fifo_lev = fifo_lev;
+               return 0;
+       }
+ }
+ static void sky2_watchdog(unsigned long arg)
+ {
+       struct sky2_hw *hw = (struct sky2_hw *) arg;
+       /* Check for lost IRQ once a second */
+       if (sky2_read32(hw, B0_ISRC)) {
+               napi_schedule(&hw->napi);
+       } else {
+               int i, active = 0;
+               for (i = 0; i < hw->ports; i++) {
+                       struct net_device *dev = hw->dev[i];
+                       if (!netif_running(dev))
+                               continue;
+                       ++active;
+                       /* For chips with Rx FIFO, check if stuck */
+                       if ((hw->flags & SKY2_HW_RAM_BUFFER) &&
+                            sky2_rx_hung(dev)) {
+                               netdev_info(dev, "receiver hang detected\n");
+                               schedule_work(&hw->restart_work);
+                               return;
+                       }
+               }
+               if (active == 0)
+                       return;
+       }
+       mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ));
+ }
+ /* Hardware/software error handling */
+ static void sky2_err_intr(struct sky2_hw *hw, u32 status)
+ {
+       if (net_ratelimit())
+               dev_warn(&hw->pdev->dev, "error interrupt status=%#x\n", status);
+       if (status & Y2_IS_HW_ERR)
+               sky2_hw_intr(hw);
+       if (status & Y2_IS_IRQ_MAC1)
+               sky2_mac_intr(hw, 0);
+       if (status & Y2_IS_IRQ_MAC2)
+               sky2_mac_intr(hw, 1);
+       if (status & Y2_IS_CHK_RX1)
+               sky2_le_error(hw, 0, Q_R1);
+       if (status & Y2_IS_CHK_RX2)
+               sky2_le_error(hw, 1, Q_R2);
+       if (status & Y2_IS_CHK_TXA1)
+               sky2_le_error(hw, 0, Q_XA1);
+       if (status & Y2_IS_CHK_TXA2)
+               sky2_le_error(hw, 1, Q_XA2);
+ }
+ static int sky2_poll(struct napi_struct *napi, int work_limit)
+ {
+       struct sky2_hw *hw = container_of(napi, struct sky2_hw, napi);
+       u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
+       int work_done = 0;
+       u16 idx;
+       if (unlikely(status & Y2_IS_ERROR))
+               sky2_err_intr(hw, status);
+       if (status & Y2_IS_IRQ_PHY1)
+               sky2_phy_intr(hw, 0);
+       if (status & Y2_IS_IRQ_PHY2)
+               sky2_phy_intr(hw, 1);
+       if (status & Y2_IS_PHY_QLNK)
+               sky2_qlink_intr(hw);
+       while ((idx = sky2_read16(hw, STAT_PUT_IDX)) != hw->st_idx) {
+               work_done += sky2_status_intr(hw, work_limit - work_done, idx);
+               if (work_done >= work_limit)
+                       goto done;
+       }
+       napi_complete(napi);
+       sky2_read32(hw, B0_Y2_SP_LISR);
+ done:
+       return work_done;
+ }
+ static irqreturn_t sky2_intr(int irq, void *dev_id)
+ {
+       struct sky2_hw *hw = dev_id;
+       u32 status;
+       /* Reading this mask interrupts as side effect */
+       status = sky2_read32(hw, B0_Y2_SP_ISRC2);
+       if (status == 0 || status == ~0)
+               return IRQ_NONE;
+       prefetch(&hw->st_le[hw->st_idx]);
+       napi_schedule(&hw->napi);
+       return IRQ_HANDLED;
+ }
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ static void sky2_netpoll(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       napi_schedule(&sky2->hw->napi);
+ }
+ #endif
+ /* Chip internal frequency for clock calculations */
+ static u32 sky2_mhz(const struct sky2_hw *hw)
+ {
+       switch (hw->chip_id) {
+       case CHIP_ID_YUKON_EC:
+       case CHIP_ID_YUKON_EC_U:
+       case CHIP_ID_YUKON_EX:
+       case CHIP_ID_YUKON_SUPR:
+       case CHIP_ID_YUKON_UL_2:
+       case CHIP_ID_YUKON_OPT:
+       case CHIP_ID_YUKON_PRM:
+       case CHIP_ID_YUKON_OP_2:
+               return 125;
+       case CHIP_ID_YUKON_FE:
+               return 100;
+       case CHIP_ID_YUKON_FE_P:
+               return 50;
+       case CHIP_ID_YUKON_XL:
+               return 156;
+       default:
+               BUG();
+       }
+ }
+ static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
+ {
+       return sky2_mhz(hw) * us;
+ }
+ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
+ {
+       return clk / sky2_mhz(hw);
+ }
+ static int __devinit sky2_init(struct sky2_hw *hw)
+ {
+       u8 t8;
+       /* Enable all clocks and check for bad PCI access */
+       sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+       sky2_write8(hw, B0_CTST, CS_RST_CLR);
+       hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
+       hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
+       switch (hw->chip_id) {
+       case CHIP_ID_YUKON_XL:
+               hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY;
+               if (hw->chip_rev < CHIP_REV_YU_XL_A2)
+                       hw->flags |= SKY2_HW_RSS_BROKEN;
+               break;
+       case CHIP_ID_YUKON_EC_U:
+               hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_NEWER_PHY
+                       | SKY2_HW_ADV_POWER_CTL;
+               break;
+       case CHIP_ID_YUKON_EX:
+               hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_NEWER_PHY
+                       | SKY2_HW_NEW_LE
+                       | SKY2_HW_ADV_POWER_CTL
+                       | SKY2_HW_RSS_CHKSUM;
+               /* New transmit checksum */
+               if (hw->chip_rev != CHIP_REV_YU_EX_B0)
+                       hw->flags |= SKY2_HW_AUTO_TX_SUM;
+               break;
+       case CHIP_ID_YUKON_EC:
+               /* This rev is really old, and requires untested workarounds */
+               if (hw->chip_rev == CHIP_REV_YU_EC_A1) {
+                       dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n");
+                       return -EOPNOTSUPP;
+               }
+               hw->flags = SKY2_HW_GIGABIT | SKY2_HW_RSS_BROKEN;
+               break;
+       case CHIP_ID_YUKON_FE:
+               hw->flags = SKY2_HW_RSS_BROKEN;
+               break;
+       case CHIP_ID_YUKON_FE_P:
+               hw->flags = SKY2_HW_NEWER_PHY
+                       | SKY2_HW_NEW_LE
+                       | SKY2_HW_AUTO_TX_SUM
+                       | SKY2_HW_ADV_POWER_CTL;
+               /* The workaround for status conflicts VLAN tag detection. */
+               if (hw->chip_rev == CHIP_REV_YU_FE2_A0)
+                       hw->flags |= SKY2_HW_VLAN_BROKEN | SKY2_HW_RSS_CHKSUM;
+               break;
+       case CHIP_ID_YUKON_SUPR:
+               hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_NEWER_PHY
+                       | SKY2_HW_NEW_LE
+                       | SKY2_HW_AUTO_TX_SUM
+                       | SKY2_HW_ADV_POWER_CTL;
+               if (hw->chip_rev == CHIP_REV_YU_SU_A0)
+                       hw->flags |= SKY2_HW_RSS_CHKSUM;
+               break;
+       case CHIP_ID_YUKON_UL_2:
+               hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_ADV_POWER_CTL;
+               break;
+       case CHIP_ID_YUKON_OPT:
+       case CHIP_ID_YUKON_PRM:
+       case CHIP_ID_YUKON_OP_2:
+               hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_NEW_LE
+                       | SKY2_HW_ADV_POWER_CTL;
+               break;
+       default:
+               dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
+                       hw->chip_id);
+               return -EOPNOTSUPP;
+       }
+       hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
+       if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
+               hw->flags |= SKY2_HW_FIBRE_PHY;
+       hw->ports = 1;
+       t8 = sky2_read8(hw, B2_Y2_HW_RES);
+       if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
+               if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
+                       ++hw->ports;
+       }
+       if (sky2_read8(hw, B2_E_0))
+               hw->flags |= SKY2_HW_RAM_BUFFER;
+       return 0;
+ }
+ static void sky2_reset(struct sky2_hw *hw)
+ {
+       struct pci_dev *pdev = hw->pdev;
+       u16 status;
+       int i;
+       u32 hwe_mask = Y2_HWE_ALL_MASK;
+       /* disable ASF */
+       if (hw->chip_id == CHIP_ID_YUKON_EX
+           || hw->chip_id == CHIP_ID_YUKON_SUPR) {
+               sky2_write32(hw, CPU_WDOG, 0);
+               status = sky2_read16(hw, HCU_CCSR);
+               status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE |
+                           HCU_CCSR_UC_STATE_MSK);
+               /*
+                * CPU clock divider shouldn't be used because
+                * - ASF firmware may malfunction
+                * - Yukon-Supreme: Parallel FLASH doesn't support divided clocks
+                */
+               status &= ~HCU_CCSR_CPU_CLK_DIVIDE_MSK;
+               sky2_write16(hw, HCU_CCSR, status);
+               sky2_write32(hw, CPU_WDOG, 0);
+       } else
+               sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+       sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
+       /* do a SW reset */
+       sky2_write8(hw, B0_CTST, CS_RST_SET);
+       sky2_write8(hw, B0_CTST, CS_RST_CLR);
+       /* allow writes to PCI config */
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+       /* clear PCI errors, if any */
+       status = sky2_pci_read16(hw, PCI_STATUS);
+       status |= PCI_STATUS_ERROR_BITS;
+       sky2_pci_write16(hw, PCI_STATUS, status);
+       sky2_write8(hw, B0_CTST, CS_MRST_CLR);
+       if (pci_is_pcie(pdev)) {
+               sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
+                            0xfffffffful);
+               /* If error bit is stuck on ignore it */
+               if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
+                       dev_info(&pdev->dev, "ignoring stuck error report bit\n");
+               else
+                       hwe_mask |= Y2_IS_PCI_EXP;
+       }
+       sky2_power_on(hw);
+       sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+       for (i = 0; i < hw->ports; i++) {
+               sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+               sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+               if (hw->chip_id == CHIP_ID_YUKON_EX ||
+                   hw->chip_id == CHIP_ID_YUKON_SUPR)
+                       sky2_write16(hw, SK_REG(i, GMAC_CTRL),
+                                    GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
+                                    | GMC_BYP_RETR_ON);
+       }
+       if (hw->chip_id == CHIP_ID_YUKON_SUPR && hw->chip_rev > CHIP_REV_YU_SU_B0) {
+               /* enable MACSec clock gating */
+               sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS);
+       }
+       if (hw->chip_id == CHIP_ID_YUKON_OPT ||
+           hw->chip_id == CHIP_ID_YUKON_PRM ||
+           hw->chip_id == CHIP_ID_YUKON_OP_2) {
+               u16 reg;
+               u32 msk;
+               if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
+                       /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
+                       sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7));
+                       /* set PHY Link Detect Timer to 1.1 second (11x 100ms) */
+                       reg = 10;
+                       /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
+                       sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
+               } else {
+                       /* set PHY Link Detect Timer to 0.4 second (4x 100ms) */
+                       reg = 3;
+               }
+               reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE;
+               reg |= PSM_CONFIG_REG4_RST_PHY_LINK_DETECT;
+               /* reset PHY Link Detect */
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+               sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
+               /* enable PHY Quick Link */
+               msk = sky2_read32(hw, B0_IMSK);
+               msk |= Y2_IS_PHY_QLNK;
+               sky2_write32(hw, B0_IMSK, msk);
+               /* check if PSMv2 was running before */
+               reg = sky2_pci_read16(hw, PSM_CONFIG_REG3);
+               if (reg & PCI_EXP_LNKCTL_ASPMC)
+                       /* restore the PCIe Link Control register */
+                       sky2_pci_write16(hw, pdev->pcie_cap + PCI_EXP_LNKCTL,
+                                        reg);
+               sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+               /* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
+               sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
+       }
+       /* Clear I2C IRQ noise */
+       sky2_write32(hw, B2_I2C_IRQ, 1);
+       /* turn off hardware timer (unused) */
+       sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
+       sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
+       /* Turn off descriptor polling */
+       sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
+       /* Turn off receive timestamp */
+       sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
+       sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+       /* enable the Tx Arbiters */
+       for (i = 0; i < hw->ports; i++)
+               sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
+       /* Initialize ram interface */
+       for (i = 0; i < hw->ports; i++) {
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
+               sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
+       }
+       sky2_write32(hw, B0_HWE_IMSK, hwe_mask);
+       for (i = 0; i < hw->ports; i++)
+               sky2_gmac_reset(hw, i);
+       memset(hw->st_le, 0, hw->st_size * sizeof(struct sky2_status_le));
+       hw->st_idx = 0;
+       sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
+       sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);
+       sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
+       sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
+       /* Set the list last index */
+       sky2_write16(hw, STAT_LAST_IDX, hw->st_size - 1);
+       sky2_write16(hw, STAT_TX_IDX_TH, 10);
+       sky2_write8(hw, STAT_FIFO_WM, 16);
+       /* set Status-FIFO ISR watermark */
+       if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
+               sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
+       else
+               sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
+       sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
+       sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
+       sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
+       /* enable status unit */
+       sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
+       sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+       sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+       sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+ }
+ /* Take device down (offline).
+  * Equivalent to doing dev_stop() but this does not
+  * inform upper layers of the transition.
+  */
+ static void sky2_detach(struct net_device *dev)
+ {
+       if (netif_running(dev)) {
+               netif_tx_lock(dev);
+               netif_device_detach(dev);       /* stop txq */
+               netif_tx_unlock(dev);
+               sky2_down(dev);
+       }
+ }
+ /* Bring device back after doing sky2_detach */
+ static int sky2_reattach(struct net_device *dev)
+ {
+       int err = 0;
+       if (netif_running(dev)) {
+               err = sky2_up(dev);
+               if (err) {
+                       netdev_info(dev, "could not restart %d\n", err);
+                       dev_close(dev);
+               } else {
+                       netif_device_attach(dev);
+                       sky2_set_multicast(dev);
+               }
+       }
+       return err;
+ }
+ static void sky2_all_down(struct sky2_hw *hw)
+ {
+       int i;
+       sky2_read32(hw, B0_IMSK);
+       sky2_write32(hw, B0_IMSK, 0);
+       synchronize_irq(hw->pdev->irq);
+       napi_disable(&hw->napi);
+       for (i = 0; i < hw->ports; i++) {
+               struct net_device *dev = hw->dev[i];
+               struct sky2_port *sky2 = netdev_priv(dev);
+               if (!netif_running(dev))
+                       continue;
+               netif_carrier_off(dev);
+               netif_tx_disable(dev);
+               sky2_hw_down(sky2);
+       }
+ }
+ static void sky2_all_up(struct sky2_hw *hw)
+ {
+       u32 imask = Y2_IS_BASE;
+       int i;
+       for (i = 0; i < hw->ports; i++) {
+               struct net_device *dev = hw->dev[i];
+               struct sky2_port *sky2 = netdev_priv(dev);
+               if (!netif_running(dev))
+                       continue;
+               sky2_hw_up(sky2);
+               sky2_set_multicast(dev);
+               imask |= portirq_msk[i];
+               netif_wake_queue(dev);
+       }
+       sky2_write32(hw, B0_IMSK, imask);
+       sky2_read32(hw, B0_IMSK);
+       sky2_read32(hw, B0_Y2_SP_LISR);
+       napi_enable(&hw->napi);
+ }
+ static void sky2_restart(struct work_struct *work)
+ {
+       struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work);
+       rtnl_lock();
+       sky2_all_down(hw);
+       sky2_reset(hw);
+       sky2_all_up(hw);
+       rtnl_unlock();
+ }
+ static inline u8 sky2_wol_supported(const struct sky2_hw *hw)
+ {
+       return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
+ }
+ static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ {
+       const struct sky2_port *sky2 = netdev_priv(dev);
+       wol->supported = sky2_wol_supported(sky2->hw);
+       wol->wolopts = sky2->wol;
+ }
+ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       bool enable_wakeup = false;
+       int i;
+       if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
+           !device_can_wakeup(&hw->pdev->dev))
+               return -EOPNOTSUPP;
+       sky2->wol = wol->wolopts;
+       for (i = 0; i < hw->ports; i++) {
+               struct net_device *dev = hw->dev[i];
+               struct sky2_port *sky2 = netdev_priv(dev);
+               if (sky2->wol)
+                       enable_wakeup = true;
+       }
+       device_set_wakeup_enable(&hw->pdev->dev, enable_wakeup);
+       return 0;
+ }
+ static u32 sky2_supported_modes(const struct sky2_hw *hw)
+ {
+       if (sky2_is_copper(hw)) {
+               u32 modes = SUPPORTED_10baseT_Half
+                       | SUPPORTED_10baseT_Full
+                       | SUPPORTED_100baseT_Half
+                       | SUPPORTED_100baseT_Full;
+               if (hw->flags & SKY2_HW_GIGABIT)
+                       modes |= SUPPORTED_1000baseT_Half
+                               | SUPPORTED_1000baseT_Full;
+               return modes;
+       } else
+               return SUPPORTED_1000baseT_Half
+                       | SUPPORTED_1000baseT_Full;
+ }
+ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       ecmd->transceiver = XCVR_INTERNAL;
+       ecmd->supported = sky2_supported_modes(hw);
+       ecmd->phy_address = PHY_ADDR_MARV;
+       if (sky2_is_copper(hw)) {
+               ecmd->port = PORT_TP;
+               ethtool_cmd_speed_set(ecmd, sky2->speed);
+               ecmd->supported |=  SUPPORTED_Autoneg | SUPPORTED_TP;
+       } else {
+               ethtool_cmd_speed_set(ecmd, SPEED_1000);
+               ecmd->port = PORT_FIBRE;
+               ecmd->supported |=  SUPPORTED_Autoneg | SUPPORTED_FIBRE;
+       }
+       ecmd->advertising = sky2->advertising;
+       ecmd->autoneg = (sky2->flags & SKY2_FLAG_AUTO_SPEED)
+               ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+       ecmd->duplex = sky2->duplex;
+       return 0;
+ }
+ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       const struct sky2_hw *hw = sky2->hw;
+       u32 supported = sky2_supported_modes(hw);
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               if (ecmd->advertising & ~supported)
+                       return -EINVAL;
+               if (sky2_is_copper(hw))
+                       sky2->advertising = ecmd->advertising |
+                                           ADVERTISED_TP |
+                                           ADVERTISED_Autoneg;
+               else
+                       sky2->advertising = ecmd->advertising |
+                                           ADVERTISED_FIBRE |
+                                           ADVERTISED_Autoneg;
+               sky2->flags |= SKY2_FLAG_AUTO_SPEED;
+               sky2->duplex = -1;
+               sky2->speed = -1;
+       } else {
+               u32 setting;
+               u32 speed = ethtool_cmd_speed(ecmd);
+               switch (speed) {
+               case SPEED_1000:
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               setting = SUPPORTED_1000baseT_Full;
+                       else if (ecmd->duplex == DUPLEX_HALF)
+                               setting = SUPPORTED_1000baseT_Half;
+                       else
+                               return -EINVAL;
+                       break;
+               case SPEED_100:
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               setting = SUPPORTED_100baseT_Full;
+                       else if (ecmd->duplex == DUPLEX_HALF)
+                               setting = SUPPORTED_100baseT_Half;
+                       else
+                               return -EINVAL;
+                       break;
+               case SPEED_10:
+                       if (ecmd->duplex == DUPLEX_FULL)
+                               setting = SUPPORTED_10baseT_Full;
+                       else if (ecmd->duplex == DUPLEX_HALF)
+                               setting = SUPPORTED_10baseT_Half;
+                       else
+                               return -EINVAL;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               if ((setting & supported) == 0)
+                       return -EINVAL;
+               sky2->speed = speed;
+               sky2->duplex = ecmd->duplex;
+               sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
+       }
+       if (netif_running(dev)) {
+               sky2_phy_reinit(sky2);
+               sky2_set_multicast(dev);
+       }
+       return 0;
+ }
+ static void sky2_get_drvinfo(struct net_device *dev,
+                            struct ethtool_drvinfo *info)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->fw_version, "N/A");
+       strcpy(info->bus_info, pci_name(sky2->hw->pdev));
+ }
+ static const struct sky2_stat {
+       char name[ETH_GSTRING_LEN];
+       u16 offset;
+ } sky2_stats[] = {
+       { "tx_bytes",      GM_TXO_OK_HI },
+       { "rx_bytes",      GM_RXO_OK_HI },
+       { "tx_broadcast",  GM_TXF_BC_OK },
+       { "rx_broadcast",  GM_RXF_BC_OK },
+       { "tx_multicast",  GM_TXF_MC_OK },
+       { "rx_multicast",  GM_RXF_MC_OK },
+       { "tx_unicast",    GM_TXF_UC_OK },
+       { "rx_unicast",    GM_RXF_UC_OK },
+       { "tx_mac_pause",  GM_TXF_MPAUSE },
+       { "rx_mac_pause",  GM_RXF_MPAUSE },
+       { "collisions",    GM_TXF_COL },
+       { "late_collision",GM_TXF_LAT_COL },
+       { "aborted",       GM_TXF_ABO_COL },
+       { "single_collisions", GM_TXF_SNG_COL },
+       { "multi_collisions", GM_TXF_MUL_COL },
+       { "rx_short",      GM_RXF_SHT },
+       { "rx_runt",       GM_RXE_FRAG },
+       { "rx_64_byte_packets", GM_RXF_64B },
+       { "rx_65_to_127_byte_packets", GM_RXF_127B },
+       { "rx_128_to_255_byte_packets", GM_RXF_255B },
+       { "rx_256_to_511_byte_packets", GM_RXF_511B },
+       { "rx_512_to_1023_byte_packets", GM_RXF_1023B },
+       { "rx_1024_to_1518_byte_packets", GM_RXF_1518B },
+       { "rx_1518_to_max_byte_packets", GM_RXF_MAX_SZ },
+       { "rx_too_long",   GM_RXF_LNG_ERR },
+       { "rx_fifo_overflow", GM_RXE_FIFO_OV },
+       { "rx_jabber",     GM_RXF_JAB_PKT },
+       { "rx_fcs_error",   GM_RXF_FCS_ERR },
+       { "tx_64_byte_packets", GM_TXF_64B },
+       { "tx_65_to_127_byte_packets", GM_TXF_127B },
+       { "tx_128_to_255_byte_packets", GM_TXF_255B },
+       { "tx_256_to_511_byte_packets", GM_TXF_511B },
+       { "tx_512_to_1023_byte_packets", GM_TXF_1023B },
+       { "tx_1024_to_1518_byte_packets", GM_TXF_1518B },
+       { "tx_1519_to_max_byte_packets", GM_TXF_MAX_SZ },
+       { "tx_fifo_underrun", GM_TXE_FIFO_UR },
+ };
+ static u32 sky2_get_msglevel(struct net_device *netdev)
+ {
+       struct sky2_port *sky2 = netdev_priv(netdev);
+       return sky2->msg_enable;
+ }
+ static int sky2_nway_reset(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       if (!netif_running(dev) || !(sky2->flags & SKY2_FLAG_AUTO_SPEED))
+               return -EINVAL;
+       sky2_phy_reinit(sky2);
+       sky2_set_multicast(dev);
+       return 0;
+ }
+ static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       int i;
+       data[0] = get_stats64(hw, port, GM_TXO_OK_LO);
+       data[1] = get_stats64(hw, port, GM_RXO_OK_LO);
+       for (i = 2; i < count; i++)
+               data[i] = get_stats32(hw, port, sky2_stats[i].offset);
+ }
+ static void sky2_set_msglevel(struct net_device *netdev, u32 value)
+ {
+       struct sky2_port *sky2 = netdev_priv(netdev);
+       sky2->msg_enable = value;
+ }
+ static int sky2_get_sset_count(struct net_device *dev, int sset)
+ {
+       switch (sset) {
+       case ETH_SS_STATS:
+               return ARRAY_SIZE(sky2_stats);
+       default:
+               return -EOPNOTSUPP;
+       }
+ }
+ static void sky2_get_ethtool_stats(struct net_device *dev,
+                                  struct ethtool_stats *stats, u64 * data)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       sky2_phy_stats(sky2, data, ARRAY_SIZE(sky2_stats));
+ }
+ static void sky2_get_strings(struct net_device *dev, u32 stringset, u8 * data)
+ {
+       int i;
+       switch (stringset) {
+       case ETH_SS_STATS:
+               for (i = 0; i < ARRAY_SIZE(sky2_stats); i++)
+                       memcpy(data + i * ETH_GSTRING_LEN,
+                              sky2_stats[i].name, ETH_GSTRING_LEN);
+               break;
+       }
+ }
+ static int sky2_set_mac_address(struct net_device *dev, void *p)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       const struct sockaddr *addr = p;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+       memcpy_toio(hw->regs + B2_MAC_1 + port * 8,
+                   dev->dev_addr, ETH_ALEN);
+       memcpy_toio(hw->regs + B2_MAC_2 + port * 8,
+                   dev->dev_addr, ETH_ALEN);
+       /* virtual address for data */
+       gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+       /* physical address: used for pause frames */
+       gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
+       return 0;
+ }
+ static inline void sky2_add_filter(u8 filter[8], const u8 *addr)
+ {
+       u32 bit;
+       bit = ether_crc(ETH_ALEN, addr) & 63;
+       filter[bit >> 3] |= 1 << (bit & 7);
+ }
+ static void sky2_set_multicast(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       struct netdev_hw_addr *ha;
+       u16 reg;
+       u8 filter[8];
+       int rx_pause;
+       static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };
+       rx_pause = (sky2->flow_status == FC_RX || sky2->flow_status == FC_BOTH);
+       memset(filter, 0, sizeof(filter));
+       reg = gma_read16(hw, port, GM_RX_CTRL);
+       reg |= GM_RXCR_UCF_ENA;
+       if (dev->flags & IFF_PROMISC)   /* promiscuous */
+               reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+       else if (dev->flags & IFF_ALLMULTI)
+               memset(filter, 0xff, sizeof(filter));
+       else if (netdev_mc_empty(dev) && !rx_pause)
+               reg &= ~GM_RXCR_MCF_ENA;
+       else {
+               reg |= GM_RXCR_MCF_ENA;
+               if (rx_pause)
+                       sky2_add_filter(filter, pause_mc_addr);
+               netdev_for_each_mc_addr(ha, dev)
+                       sky2_add_filter(filter, ha->addr);
+       }
+       gma_write16(hw, port, GM_MC_ADDR_H1,
+                   (u16) filter[0] | ((u16) filter[1] << 8));
+       gma_write16(hw, port, GM_MC_ADDR_H2,
+                   (u16) filter[2] | ((u16) filter[3] << 8));
+       gma_write16(hw, port, GM_MC_ADDR_H3,
+                   (u16) filter[4] | ((u16) filter[5] << 8));
+       gma_write16(hw, port, GM_MC_ADDR_H4,
+                   (u16) filter[6] | ((u16) filter[7] << 8));
+       gma_write16(hw, port, GM_RX_CTRL, reg);
+ }
+ static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev,
+                                               struct rtnl_link_stats64 *stats)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       unsigned int start;
+       u64 _bytes, _packets;
+       do {
+               start = u64_stats_fetch_begin_bh(&sky2->rx_stats.syncp);
+               _bytes = sky2->rx_stats.bytes;
+               _packets = sky2->rx_stats.packets;
+       } while (u64_stats_fetch_retry_bh(&sky2->rx_stats.syncp, start));
+       stats->rx_packets = _packets;
+       stats->rx_bytes = _bytes;
+       do {
+               start = u64_stats_fetch_begin_bh(&sky2->tx_stats.syncp);
+               _bytes = sky2->tx_stats.bytes;
+               _packets = sky2->tx_stats.packets;
+       } while (u64_stats_fetch_retry_bh(&sky2->tx_stats.syncp, start));
+       stats->tx_packets = _packets;
+       stats->tx_bytes = _bytes;
+       stats->multicast = get_stats32(hw, port, GM_RXF_MC_OK)
+               + get_stats32(hw, port, GM_RXF_BC_OK);
+       stats->collisions = get_stats32(hw, port, GM_TXF_COL);
+       stats->rx_length_errors = get_stats32(hw, port, GM_RXF_LNG_ERR);
+       stats->rx_crc_errors = get_stats32(hw, port, GM_RXF_FCS_ERR);
+       stats->rx_frame_errors = get_stats32(hw, port, GM_RXF_SHT)
+               + get_stats32(hw, port, GM_RXE_FRAG);
+       stats->rx_over_errors = get_stats32(hw, port, GM_RXE_FIFO_OV);
+       stats->rx_dropped = dev->stats.rx_dropped;
+       stats->rx_fifo_errors = dev->stats.rx_fifo_errors;
+       stats->tx_fifo_errors = dev->stats.tx_fifo_errors;
+       return stats;
+ }
+ /* Can have one global because blinking is controlled by
+  * ethtool and that is always under RTNL mutex
+  */
+ static void sky2_led(struct sky2_port *sky2, enum led_mode mode)
+ {
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       spin_lock_bh(&sky2->phy_lock);
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
+           hw->chip_id == CHIP_ID_YUKON_EX ||
+           hw->chip_id == CHIP_ID_YUKON_SUPR) {
+               u16 pg;
+               pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+               switch (mode) {
+               case MO_LED_OFF:
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                                    PHY_M_LEDC_LOS_CTRL(8) |
+                                    PHY_M_LEDC_INIT_CTRL(8) |
+                                    PHY_M_LEDC_STA1_CTRL(8) |
+                                    PHY_M_LEDC_STA0_CTRL(8));
+                       break;
+               case MO_LED_ON:
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                                    PHY_M_LEDC_LOS_CTRL(9) |
+                                    PHY_M_LEDC_INIT_CTRL(9) |
+                                    PHY_M_LEDC_STA1_CTRL(9) |
+                                    PHY_M_LEDC_STA0_CTRL(9));
+                       break;
+               case MO_LED_BLINK:
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                                    PHY_M_LEDC_LOS_CTRL(0xa) |
+                                    PHY_M_LEDC_INIT_CTRL(0xa) |
+                                    PHY_M_LEDC_STA1_CTRL(0xa) |
+                                    PHY_M_LEDC_STA0_CTRL(0xa));
+                       break;
+               case MO_LED_NORM:
+                       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+                                    PHY_M_LEDC_LOS_CTRL(1) |
+                                    PHY_M_LEDC_INIT_CTRL(8) |
+                                    PHY_M_LEDC_STA1_CTRL(7) |
+                                    PHY_M_LEDC_STA0_CTRL(7));
+               }
+               gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+       } else
+               gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+                                    PHY_M_LED_MO_DUP(mode) |
+                                    PHY_M_LED_MO_10(mode) |
+                                    PHY_M_LED_MO_100(mode) |
+                                    PHY_M_LED_MO_1000(mode) |
+                                    PHY_M_LED_MO_RX(mode) |
+                                    PHY_M_LED_MO_TX(mode));
+       spin_unlock_bh(&sky2->phy_lock);
+ }
+ /* blink LED's for finding board */
+ static int sky2_set_phys_id(struct net_device *dev,
+                           enum ethtool_phys_id_state state)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       switch (state) {
+       case ETHTOOL_ID_ACTIVE:
+               return 1;       /* cycle on/off once per second */
+       case ETHTOOL_ID_INACTIVE:
+               sky2_led(sky2, MO_LED_NORM);
+               break;
+       case ETHTOOL_ID_ON:
+               sky2_led(sky2, MO_LED_ON);
+               break;
+       case ETHTOOL_ID_OFF:
+               sky2_led(sky2, MO_LED_OFF);
+               break;
+       }
+       return 0;
+ }
+ static void sky2_get_pauseparam(struct net_device *dev,
+                               struct ethtool_pauseparam *ecmd)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       switch (sky2->flow_mode) {
+       case FC_NONE:
+               ecmd->tx_pause = ecmd->rx_pause = 0;
+               break;
+       case FC_TX:
+               ecmd->tx_pause = 1, ecmd->rx_pause = 0;
+               break;
+       case FC_RX:
+               ecmd->tx_pause = 0, ecmd->rx_pause = 1;
+               break;
+       case FC_BOTH:
+               ecmd->tx_pause = ecmd->rx_pause = 1;
+       }
+       ecmd->autoneg = (sky2->flags & SKY2_FLAG_AUTO_PAUSE)
+               ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ }
+ static int sky2_set_pauseparam(struct net_device *dev,
+                              struct ethtool_pauseparam *ecmd)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       if (ecmd->autoneg == AUTONEG_ENABLE)
+               sky2->flags |= SKY2_FLAG_AUTO_PAUSE;
+       else
+               sky2->flags &= ~SKY2_FLAG_AUTO_PAUSE;
+       sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause);
+       if (netif_running(dev))
+               sky2_phy_reinit(sky2);
+       return 0;
+ }
+ static int sky2_get_coalesce(struct net_device *dev,
+                            struct ethtool_coalesce *ecmd)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_STOP)
+               ecmd->tx_coalesce_usecs = 0;
+       else {
+               u32 clks = sky2_read32(hw, STAT_TX_TIMER_INI);
+               ecmd->tx_coalesce_usecs = sky2_clk2us(hw, clks);
+       }
+       ecmd->tx_max_coalesced_frames = sky2_read16(hw, STAT_TX_IDX_TH);
+       if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_STOP)
+               ecmd->rx_coalesce_usecs = 0;
+       else {
+               u32 clks = sky2_read32(hw, STAT_LEV_TIMER_INI);
+               ecmd->rx_coalesce_usecs = sky2_clk2us(hw, clks);
+       }
+       ecmd->rx_max_coalesced_frames = sky2_read8(hw, STAT_FIFO_WM);
+       if (sky2_read8(hw, STAT_ISR_TIMER_CTRL) == TIM_STOP)
+               ecmd->rx_coalesce_usecs_irq = 0;
+       else {
+               u32 clks = sky2_read32(hw, STAT_ISR_TIMER_INI);
+               ecmd->rx_coalesce_usecs_irq = sky2_clk2us(hw, clks);
+       }
+       ecmd->rx_max_coalesced_frames_irq = sky2_read8(hw, STAT_FIFO_ISR_WM);
+       return 0;
+ }
+ /* Note: this affect both ports */
+ static int sky2_set_coalesce(struct net_device *dev,
+                            struct ethtool_coalesce *ecmd)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       const u32 tmax = sky2_clk2us(hw, 0x0ffffff);
+       if (ecmd->tx_coalesce_usecs > tmax ||
+           ecmd->rx_coalesce_usecs > tmax ||
+           ecmd->rx_coalesce_usecs_irq > tmax)
+               return -EINVAL;
+       if (ecmd->tx_max_coalesced_frames >= sky2->tx_ring_size-1)
+               return -EINVAL;
+       if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING)
+               return -EINVAL;
+       if (ecmd->rx_max_coalesced_frames_irq > RX_MAX_PENDING)
+               return -EINVAL;
+       if (ecmd->tx_coalesce_usecs == 0)
+               sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+       else {
+               sky2_write32(hw, STAT_TX_TIMER_INI,
+                            sky2_us2clk(hw, ecmd->tx_coalesce_usecs));
+               sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+       }
+       sky2_write16(hw, STAT_TX_IDX_TH, ecmd->tx_max_coalesced_frames);
+       if (ecmd->rx_coalesce_usecs == 0)
+               sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
+       else {
+               sky2_write32(hw, STAT_LEV_TIMER_INI,
+                            sky2_us2clk(hw, ecmd->rx_coalesce_usecs));
+               sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+       }
+       sky2_write8(hw, STAT_FIFO_WM, ecmd->rx_max_coalesced_frames);
+       if (ecmd->rx_coalesce_usecs_irq == 0)
+               sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
+       else {
+               sky2_write32(hw, STAT_ISR_TIMER_INI,
+                            sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
+               sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+       }
+       sky2_write8(hw, STAT_FIFO_ISR_WM, ecmd->rx_max_coalesced_frames_irq);
+       return 0;
+ }
+ static void sky2_get_ringparam(struct net_device *dev,
+                              struct ethtool_ringparam *ering)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       ering->rx_max_pending = RX_MAX_PENDING;
+       ering->tx_max_pending = TX_MAX_PENDING;
+       ering->rx_pending = sky2->rx_pending;
+       ering->tx_pending = sky2->tx_pending;
+ }
+ static int sky2_set_ringparam(struct net_device *dev,
+                             struct ethtool_ringparam *ering)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       if (ering->rx_pending > RX_MAX_PENDING ||
+           ering->rx_pending < 8 ||
+           ering->tx_pending < TX_MIN_PENDING ||
+           ering->tx_pending > TX_MAX_PENDING)
+               return -EINVAL;
+       sky2_detach(dev);
+       sky2->rx_pending = ering->rx_pending;
+       sky2->tx_pending = ering->tx_pending;
+       sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1);
+       return sky2_reattach(dev);
+ }
+ static int sky2_get_regs_len(struct net_device *dev)
+ {
+       return 0x4000;
+ }
+ static int sky2_reg_access_ok(struct sky2_hw *hw, unsigned int b)
+ {
+       /* This complicated switch statement is to make sure and
+        * only access regions that are unreserved.
+        * Some blocks are only valid on dual port cards.
+        */
+       switch (b) {
+       /* second port */
+       case 5:         /* Tx Arbiter 2 */
+       case 9:         /* RX2 */
+       case 14 ... 15: /* TX2 */
+       case 17: case 19: /* Ram Buffer 2 */
+       case 22 ... 23: /* Tx Ram Buffer 2 */
+       case 25:        /* Rx MAC Fifo 1 */
+       case 27:        /* Tx MAC Fifo 2 */
+       case 31:        /* GPHY 2 */
+       case 40 ... 47: /* Pattern Ram 2 */
+       case 52: case 54: /* TCP Segmentation 2 */
+       case 112 ... 116: /* GMAC 2 */
+               return hw->ports > 1;
+       case 0:         /* Control */
+       case 2:         /* Mac address */
+       case 4:         /* Tx Arbiter 1 */
+       case 7:         /* PCI express reg */
+       case 8:         /* RX1 */
+       case 12 ... 13: /* TX1 */
+       case 16: case 18:/* Rx Ram Buffer 1 */
+       case 20 ... 21: /* Tx Ram Buffer 1 */
+       case 24:        /* Rx MAC Fifo 1 */
+       case 26:        /* Tx MAC Fifo 1 */
+       case 28 ... 29: /* Descriptor and status unit */
+       case 30:        /* GPHY 1*/
+       case 32 ... 39: /* Pattern Ram 1 */
+       case 48: case 50: /* TCP Segmentation 1 */
+       case 56 ... 60: /* PCI space */
+       case 80 ... 84: /* GMAC 1 */
+               return 1;
+       default:
+               return 0;
+       }
+ }
+ /*
+  * Returns copy of control register region
+  * Note: ethtool_get_regs always provides full size (16k) buffer
+  */
+ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+                         void *p)
+ {
+       const struct sky2_port *sky2 = netdev_priv(dev);
+       const void __iomem *io = sky2->hw->regs;
+       unsigned int b;
+       regs->version = 1;
+       for (b = 0; b < 128; b++) {
+               /* skip poisonous diagnostic ram region in block 3 */
+               if (b == 3)
+                       memcpy_fromio(p + 0x10, io + 0x10, 128 - 0x10);
+               else if (sky2_reg_access_ok(sky2->hw, b))
+                       memcpy_fromio(p, io, 128);
+               else
+                       memset(p, 0, 128);
+               p += 128;
+               io += 128;
+       }
+ }
+ static int sky2_get_eeprom_len(struct net_device *dev)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       u16 reg2;
+       reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
+       return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+ }
+ static int sky2_vpd_wait(const struct sky2_hw *hw, int cap, u16 busy)
+ {
+       unsigned long start = jiffies;
+       while ( (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F) == busy) {
+               /* Can take up to 10.6 ms for write */
+               if (time_after(jiffies, start + HZ/4)) {
+                       dev_err(&hw->pdev->dev, "VPD cycle timed out\n");
+                       return -ETIMEDOUT;
+               }
+               mdelay(1);
+       }
+       return 0;
+ }
+ static int sky2_vpd_read(struct sky2_hw *hw, int cap, void *data,
+                        u16 offset, size_t length)
+ {
+       int rc = 0;
+       while (length > 0) {
+               u32 val;
+               sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
+               rc = sky2_vpd_wait(hw, cap, 0);
+               if (rc)
+                       break;
+               val = sky2_pci_read32(hw, cap + PCI_VPD_DATA);
+               memcpy(data, &val, min(sizeof(val), length));
+               offset += sizeof(u32);
+               data += sizeof(u32);
+               length -= sizeof(u32);
+       }
+       return rc;
+ }
+ static int sky2_vpd_write(struct sky2_hw *hw, int cap, const void *data,
+                         u16 offset, unsigned int length)
+ {
+       unsigned int i;
+       int rc = 0;
+       for (i = 0; i < length; i += sizeof(u32)) {
+               u32 val = *(u32 *)(data + i);
+               sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
+               sky2_pci_write32(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
+               rc = sky2_vpd_wait(hw, cap, PCI_VPD_ADDR_F);
+               if (rc)
+                       break;
+       }
+       return rc;
+ }
+ static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+                          u8 *data)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+       if (!cap)
+               return -EINVAL;
+       eeprom->magic = SKY2_EEPROM_MAGIC;
+       return sky2_vpd_read(sky2->hw, cap, data, eeprom->offset, eeprom->len);
+ }
+ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+                          u8 *data)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+       if (!cap)
+               return -EINVAL;
+       if (eeprom->magic != SKY2_EEPROM_MAGIC)
+               return -EINVAL;
+       /* Partial writes not supported */
+       if ((eeprom->offset & 3) || (eeprom->len & 3))
+               return -EINVAL;
+       return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
+ }
+ static u32 sky2_fix_features(struct net_device *dev, u32 features)
+ {
+       const struct sky2_port *sky2 = netdev_priv(dev);
+       const struct sky2_hw *hw = sky2->hw;
+       /* In order to do Jumbo packets on these chips, need to turn off the
+        * transmit store/forward. Therefore checksum offload won't work.
+        */
+       if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U) {
+               netdev_info(dev, "checksum offload not possible with jumbo frames\n");
+               features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
+       }
+       /* Some hardware requires receive checksum for RSS to work. */
+       if ( (features & NETIF_F_RXHASH) &&
+            !(features & NETIF_F_RXCSUM) &&
+            (sky2->hw->flags & SKY2_HW_RSS_CHKSUM)) {
+               netdev_info(dev, "receive hashing forces receive checksum\n");
+               features |= NETIF_F_RXCSUM;
+       }
+       return features;
+ }
+ static int sky2_set_features(struct net_device *dev, u32 features)
+ {
+       struct sky2_port *sky2 = netdev_priv(dev);
+       u32 changed = dev->features ^ features;
+       if (changed & NETIF_F_RXCSUM) {
+               u32 on = features & NETIF_F_RXCSUM;
+               sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+                            on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+       }
+       if (changed & NETIF_F_RXHASH)
+               rx_set_rss(dev, features);
+       if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX))
+               sky2_vlan_mode(dev, features);
+       return 0;
+ }
+ static const struct ethtool_ops sky2_ethtool_ops = {
+       .get_settings   = sky2_get_settings,
+       .set_settings   = sky2_set_settings,
+       .get_drvinfo    = sky2_get_drvinfo,
+       .get_wol        = sky2_get_wol,
+       .set_wol        = sky2_set_wol,
+       .get_msglevel   = sky2_get_msglevel,
+       .set_msglevel   = sky2_set_msglevel,
+       .nway_reset     = sky2_nway_reset,
+       .get_regs_len   = sky2_get_regs_len,
+       .get_regs       = sky2_get_regs,
+       .get_link       = ethtool_op_get_link,
+       .get_eeprom_len = sky2_get_eeprom_len,
+       .get_eeprom     = sky2_get_eeprom,
+       .set_eeprom     = sky2_set_eeprom,
+       .get_strings    = sky2_get_strings,
+       .get_coalesce   = sky2_get_coalesce,
+       .set_coalesce   = sky2_set_coalesce,
+       .get_ringparam  = sky2_get_ringparam,
+       .set_ringparam  = sky2_set_ringparam,
+       .get_pauseparam = sky2_get_pauseparam,
+       .set_pauseparam = sky2_set_pauseparam,
+       .set_phys_id    = sky2_set_phys_id,
+       .get_sset_count = sky2_get_sset_count,
+       .get_ethtool_stats = sky2_get_ethtool_stats,
+ };
+ #ifdef CONFIG_SKY2_DEBUG
+ static struct dentry *sky2_debug;
+ /*
+  * Read and parse the first part of Vital Product Data
+  */
+ #define VPD_SIZE      128
+ #define VPD_MAGIC     0x82
+ static const struct vpd_tag {
+       char tag[2];
+       char *label;
+ } vpd_tags[] = {
+       { "PN", "Part Number" },
+       { "EC", "Engineering Level" },
+       { "MN", "Manufacturer" },
+       { "SN", "Serial Number" },
+       { "YA", "Asset Tag" },
+       { "VL", "First Error Log Message" },
+       { "VF", "Second Error Log Message" },
+       { "VB", "Boot Agent ROM Configuration" },
+       { "VE", "EFI UNDI Configuration" },
+ };
+ static void sky2_show_vpd(struct seq_file *seq, struct sky2_hw *hw)
+ {
+       size_t vpd_size;
+       loff_t offs;
+       u8 len;
+       unsigned char *buf;
+       u16 reg2;
+       reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
+       vpd_size = 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+       seq_printf(seq, "%s Product Data\n", pci_name(hw->pdev));
+       buf = kmalloc(vpd_size, GFP_KERNEL);
+       if (!buf) {
+               seq_puts(seq, "no memory!\n");
+               return;
+       }
+       if (pci_read_vpd(hw->pdev, 0, vpd_size, buf) < 0) {
+               seq_puts(seq, "VPD read failed\n");
+               goto out;
+       }
+       if (buf[0] != VPD_MAGIC) {
+               seq_printf(seq, "VPD tag mismatch: %#x\n", buf[0]);
+               goto out;
+       }
+       len = buf[1];
+       if (len == 0 || len > vpd_size - 4) {
+               seq_printf(seq, "Invalid id length: %d\n", len);
+               goto out;
+       }
+       seq_printf(seq, "%.*s\n", len, buf + 3);
+       offs = len + 3;
+       while (offs < vpd_size - 4) {
+               int i;
+               if (!memcmp("RW", buf + offs, 2))       /* end marker */
+                       break;
+               len = buf[offs + 2];
+               if (offs + len + 3 >= vpd_size)
+                       break;
+               for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
+                       if (!memcmp(vpd_tags[i].tag, buf + offs, 2)) {
+                               seq_printf(seq, " %s: %.*s\n",
+                                          vpd_tags[i].label, len, buf + offs + 3);
+                               break;
+                       }
+               }
+               offs += len + 3;
+       }
+ out:
+       kfree(buf);
+ }
+ static int sky2_debug_show(struct seq_file *seq, void *v)
+ {
+       struct net_device *dev = seq->private;
+       const struct sky2_port *sky2 = netdev_priv(dev);
+       struct sky2_hw *hw = sky2->hw;
+       unsigned port = sky2->port;
+       unsigned idx, last;
+       int sop;
+       sky2_show_vpd(seq, hw);
+       seq_printf(seq, "\nIRQ src=%x mask=%x control=%x\n",
+                  sky2_read32(hw, B0_ISRC),
+                  sky2_read32(hw, B0_IMSK),
+                  sky2_read32(hw, B0_Y2_SP_ICR));
+       if (!netif_running(dev)) {
+               seq_printf(seq, "network not running\n");
+               return 0;
+       }
+       napi_disable(&hw->napi);
+       last = sky2_read16(hw, STAT_PUT_IDX);
+       seq_printf(seq, "Status ring %u\n", hw->st_size);
+       if (hw->st_idx == last)
+               seq_puts(seq, "Status ring (empty)\n");
+       else {
+               seq_puts(seq, "Status ring\n");
+               for (idx = hw->st_idx; idx != last && idx < hw->st_size;
+                    idx = RING_NEXT(idx, hw->st_size)) {
+                       const struct sky2_status_le *le = hw->st_le + idx;
+                       seq_printf(seq, "[%d] %#x %d %#x\n",
+                                  idx, le->opcode, le->length, le->status);
+               }
+               seq_puts(seq, "\n");
+       }
+       seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n",
+                  sky2->tx_cons, sky2->tx_prod,
+                  sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
+                  sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE)));
+       /* Dump contents of tx ring */
+       sop = 1;
+       for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < sky2->tx_ring_size;
+            idx = RING_NEXT(idx, sky2->tx_ring_size)) {
+               const struct sky2_tx_le *le = sky2->tx_le + idx;
+               u32 a = le32_to_cpu(le->addr);
+               if (sop)
+                       seq_printf(seq, "%u:", idx);
+               sop = 0;
+               switch (le->opcode & ~HW_OWNER) {
+               case OP_ADDR64:
+                       seq_printf(seq, " %#x:", a);
+                       break;
+               case OP_LRGLEN:
+                       seq_printf(seq, " mtu=%d", a);
+                       break;
+               case OP_VLAN:
+                       seq_printf(seq, " vlan=%d", be16_to_cpu(le->length));
+                       break;
+               case OP_TCPLISW:
+                       seq_printf(seq, " csum=%#x", a);
+                       break;
+               case OP_LARGESEND:
+                       seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length));
+                       break;
+               case OP_PACKET:
+                       seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length));
+                       break;
+               case OP_BUFFER:
+                       seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length));
+                       break;
+               default:
+                       seq_printf(seq, " op=%#x,%#x(%d)", le->opcode,
+                                  a, le16_to_cpu(le->length));
+               }
+               if (le->ctrl & EOP) {
+                       seq_putc(seq, '\n');
+                       sop = 1;
+               }
+       }
+       seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n",
+                  sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)),
+                  sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
+                  sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
+       sky2_read32(hw, B0_Y2_SP_LISR);
+       napi_enable(&hw->napi);
+       return 0;
+ }
+ static int sky2_debug_open(struct inode *inode, struct file *file)
+ {
+       return single_open(file, sky2_debug_show, inode->i_private);
+ }
+ static const struct file_operations sky2_debug_fops = {
+       .owner          = THIS_MODULE,
+       .open           = sky2_debug_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+ };
+ /*
+  * Use network device events to create/remove/rename
+  * debugfs file entries
+  */
+ static int sky2_device_event(struct notifier_block *unused,
+                            unsigned long event, void *ptr)
+ {
+       struct net_device *dev = ptr;
+       struct sky2_port *sky2 = netdev_priv(dev);
+       if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug)
+               return NOTIFY_DONE;
+       switch (event) {
+       case NETDEV_CHANGENAME:
+               if (sky2->debugfs) {
+                       sky2->debugfs = debugfs_rename(sky2_debug, sky2->debugfs,
+                                                      sky2_debug, dev->name);
+               }
+               break;
+       case NETDEV_GOING_DOWN:
+               if (sky2->debugfs) {
+                       netdev_printk(KERN_DEBUG, dev, "remove debugfs\n");
+                       debugfs_remove(sky2->debugfs);
+                       sky2->debugfs = NULL;
+               }
+               break;
+       case NETDEV_UP:
+               sky2->debugfs = debugfs_create_file(dev->name, S_IRUGO,
+                                                   sky2_debug, dev,
+                                                   &sky2_debug_fops);
+               if (IS_ERR(sky2->debugfs))
+                       sky2->debugfs = NULL;
+       }
+       return NOTIFY_DONE;
+ }
+ static struct notifier_block sky2_notifier = {
+       .notifier_call = sky2_device_event,
+ };
+ static __init void sky2_debug_init(void)
+ {
+       struct dentry *ent;
+       ent = debugfs_create_dir("sky2", NULL);
+       if (!ent || IS_ERR(ent))
+               return;
+       sky2_debug = ent;
+       register_netdevice_notifier(&sky2_notifier);
+ }
+ static __exit void sky2_debug_cleanup(void)
+ {
+       if (sky2_debug) {
+               unregister_netdevice_notifier(&sky2_notifier);
+               debugfs_remove(sky2_debug);
+               sky2_debug = NULL;
+       }
+ }
+ #else
+ #define sky2_debug_init()
+ #define sky2_debug_cleanup()
+ #endif
+ /* Two copies of network device operations to handle special case of
+    not allowing netpoll on second port */
+ static const struct net_device_ops sky2_netdev_ops[2] = {
+   {
+       .ndo_open               = sky2_up,
+       .ndo_stop               = sky2_down,
+       .ndo_start_xmit         = sky2_xmit_frame,
+       .ndo_do_ioctl           = sky2_ioctl,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = sky2_set_mac_address,
+       .ndo_set_rx_mode        = sky2_set_multicast,
+       .ndo_change_mtu         = sky2_change_mtu,
+       .ndo_fix_features       = sky2_fix_features,
+       .ndo_set_features       = sky2_set_features,
+       .ndo_tx_timeout         = sky2_tx_timeout,
+       .ndo_get_stats64        = sky2_get_stats,
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = sky2_netpoll,
+ #endif
+   },
+   {
+       .ndo_open               = sky2_up,
+       .ndo_stop               = sky2_down,
+       .ndo_start_xmit         = sky2_xmit_frame,
+       .ndo_do_ioctl           = sky2_ioctl,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = sky2_set_mac_address,
+       .ndo_set_rx_mode        = sky2_set_multicast,
+       .ndo_change_mtu         = sky2_change_mtu,
+       .ndo_fix_features       = sky2_fix_features,
+       .ndo_set_features       = sky2_set_features,
+       .ndo_tx_timeout         = sky2_tx_timeout,
+       .ndo_get_stats64        = sky2_get_stats,
+   },
+ };
+ /* Initialize network device */
+ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
+                                                    unsigned port,
+                                                    int highmem, int wol)
+ {
+       struct sky2_port *sky2;
+       struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+       if (!dev) {
+               dev_err(&hw->pdev->dev, "etherdev alloc failed\n");
+               return NULL;
+       }
+       SET_NETDEV_DEV(dev, &hw->pdev->dev);
+       dev->irq = hw->pdev->irq;
+       SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
+       dev->watchdog_timeo = TX_WATCHDOG;
+       dev->netdev_ops = &sky2_netdev_ops[port];
+       sky2 = netdev_priv(dev);
+       sky2->netdev = dev;
+       sky2->hw = hw;
+       sky2->msg_enable = netif_msg_init(debug, default_msg);
+       /* Auto speed and flow control */
+       sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
+       if (hw->chip_id != CHIP_ID_YUKON_XL)
+               dev->hw_features |= NETIF_F_RXCSUM;
+       sky2->flow_mode = FC_BOTH;
+       sky2->duplex = -1;
+       sky2->speed = -1;
+       sky2->advertising = sky2_supported_modes(hw);
+       sky2->wol = wol;
+       spin_lock_init(&sky2->phy_lock);
+       sky2->tx_pending = TX_DEF_PENDING;
+       sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1);
+       sky2->rx_pending = RX_DEF_PENDING;
+       hw->dev[port] = dev;
+       sky2->port = port;
+       dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
+       if (highmem)
+               dev->features |= NETIF_F_HIGHDMA;
+       /* Enable receive hashing unless hardware is known broken */
+       if (!(hw->flags & SKY2_HW_RSS_BROKEN))
+               dev->hw_features |= NETIF_F_RXHASH;
+       if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) {
+               dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+               dev->vlan_features |= SKY2_VLAN_OFFLOADS;
+       }
+       dev->features |= dev->hw_features;
+       /* read the mac address */
+       memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+       return dev;
+ }
+ static void __devinit sky2_show_addr(struct net_device *dev)
+ {
+       const struct sky2_port *sky2 = netdev_priv(dev);
+       netif_info(sky2, probe, dev, "addr %pM\n", dev->dev_addr);
+ }
+ /* Handle software interrupt used during MSI test */
+ static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id)
+ {
+       struct sky2_hw *hw = dev_id;
+       u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
+       if (status == 0)
+               return IRQ_NONE;
+       if (status & Y2_IS_IRQ_SW) {
+               hw->flags |= SKY2_HW_USE_MSI;
+               wake_up(&hw->msi_wait);
+               sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
+       }
+       sky2_write32(hw, B0_Y2_SP_ICR, 2);
+       return IRQ_HANDLED;
+ }
+ /* Test interrupt path by forcing a a software IRQ */
+ static int __devinit sky2_test_msi(struct sky2_hw *hw)
+ {
+       struct pci_dev *pdev = hw->pdev;
+       int err;
+       init_waitqueue_head(&hw->msi_wait);
+       sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
+       err = request_irq(pdev->irq, sky2_test_intr, 0, DRV_NAME, hw);
+       if (err) {
+               dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
+               return err;
+       }
+       sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
+       sky2_read8(hw, B0_CTST);
+       wait_event_timeout(hw->msi_wait, (hw->flags & SKY2_HW_USE_MSI), HZ/10);
+       if (!(hw->flags & SKY2_HW_USE_MSI)) {
+               /* MSI test failed, go back to INTx mode */
+               dev_info(&pdev->dev, "No interrupt generated using MSI, "
+                        "switching to INTx mode.\n");
+               err = -EOPNOTSUPP;
+               sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
+       }
+       sky2_write32(hw, B0_IMSK, 0);
+       sky2_read32(hw, B0_IMSK);
+       free_irq(pdev->irq, hw);
+       return err;
+ }
+ /* This driver supports yukon2 chipset only */
+ static const char *sky2_name(u8 chipid, char *buf, int sz)
+ {
+       const char *name[] = {
+               "XL",           /* 0xb3 */
+               "EC Ultra",     /* 0xb4 */
+               "Extreme",      /* 0xb5 */
+               "EC",           /* 0xb6 */
+               "FE",           /* 0xb7 */
+               "FE+",          /* 0xb8 */
+               "Supreme",      /* 0xb9 */
+               "UL 2",         /* 0xba */
+               "Unknown",      /* 0xbb */
+               "Optima",       /* 0xbc */
+               "Optima Prime", /* 0xbd */
+               "Optima 2",     /* 0xbe */
+       };
+       if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OP_2)
+               strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
+       else
+               snprintf(buf, sz, "(chip %#x)", chipid);
+       return buf;
+ }
+ static int __devinit sky2_probe(struct pci_dev *pdev,
+                               const struct pci_device_id *ent)
+ {
+       struct net_device *dev, *dev1;
+       struct sky2_hw *hw;
+       int err, using_dac = 0, wol_default;
+       u32 reg;
+       char buf1[16];
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "cannot enable PCI device\n");
+               goto err_out;
+       }
+       /* Get configuration information
+        * Note: only regular PCI config access once to test for HW issues
+        *       other PCI access through shared memory for speed and to
+        *       avoid MMCONFIG problems.
+        */
+       err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+       if (err) {
+               dev_err(&pdev->dev, "PCI read config failed\n");
+               goto err_out;
+       }
+       if (~reg == 0) {
+               dev_err(&pdev->dev, "PCI configuration read error\n");
+               goto err_out;
+       }
+       err = pci_request_regions(pdev, DRV_NAME);
+       if (err) {
+               dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+               goto err_out_disable;
+       }
+       pci_set_master(pdev);
+       if (sizeof(dma_addr_t) > sizeof(u32) &&
+           !(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))) {
+               using_dac = 1;
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+               if (err < 0) {
+                       dev_err(&pdev->dev, "unable to obtain 64 bit DMA "
+                               "for consistent allocations\n");
+                       goto err_out_free_regions;
+               }
+       } else {
+               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+               if (err) {
+                       dev_err(&pdev->dev, "no usable DMA configuration\n");
+                       goto err_out_free_regions;
+               }
+       }
+ #ifdef __BIG_ENDIAN
+       /* The sk98lin vendor driver uses hardware byte swapping but
+        * this driver uses software swapping.
+        */
+       reg &= ~PCI_REV_DESC;
+       err = pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
+       if (err) {
+               dev_err(&pdev->dev, "PCI write config failed\n");
+               goto err_out_free_regions;
+       }
+ #endif
+       wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
+       err = -ENOMEM;
+       hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
+                    + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
+       if (!hw) {
+               dev_err(&pdev->dev, "cannot allocate hardware struct\n");
+               goto err_out_free_regions;
+       }
+       hw->pdev = pdev;
+       sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
+       hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
+       if (!hw->regs) {
+               dev_err(&pdev->dev, "cannot map device registers\n");
+               goto err_out_free_hw;
+       }
+       err = sky2_init(hw);
+       if (err)
+               goto err_out_iounmap;
+       /* ring for status responses */
+       hw->st_size = hw->ports * roundup_pow_of_two(3*RX_MAX_PENDING + TX_MAX_PENDING);
+       hw->st_le = pci_alloc_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
+                                        &hw->st_dma);
+       if (!hw->st_le)
+               goto err_out_reset;
+       dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n",
+                sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
+       sky2_reset(hw);
+       dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
+       if (!dev) {
+               err = -ENOMEM;
+               goto err_out_free_pci;
+       }
+       if (!disable_msi && pci_enable_msi(pdev) == 0) {
+               err = sky2_test_msi(hw);
+               if (err == -EOPNOTSUPP)
+                       pci_disable_msi(pdev);
+               else if (err)
+                       goto err_out_free_netdev;
+       }
+       err = register_netdev(dev);
+       if (err) {
+               dev_err(&pdev->dev, "cannot register net device\n");
+               goto err_out_free_netdev;
+       }
+       netif_carrier_off(dev);
+       netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
+       sky2_show_addr(dev);
+       if (hw->ports > 1) {
+               dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default);
+               if (!dev1) {
+                       err = -ENOMEM;
+                       goto err_out_unregister;
+               }
+               err = register_netdev(dev1);
+               if (err) {
+                       dev_err(&pdev->dev, "cannot register second net device\n");
+                       goto err_out_free_dev1;
+               }
+               err = sky2_setup_irq(hw, hw->irq_name);
+               if (err)
+                       goto err_out_unregister_dev1;
+               sky2_show_addr(dev1);
+       }
+       setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw);
+       INIT_WORK(&hw->restart_work, sky2_restart);
+       pci_set_drvdata(pdev, hw);
+       pdev->d3_delay = 150;
+       return 0;
+ err_out_unregister_dev1:
+       unregister_netdev(dev1);
+ err_out_free_dev1:
+       free_netdev(dev1);
+ err_out_unregister:
+       if (hw->flags & SKY2_HW_USE_MSI)
+               pci_disable_msi(pdev);
+       unregister_netdev(dev);
+ err_out_free_netdev:
+       free_netdev(dev);
+ err_out_free_pci:
+       pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
+                           hw->st_le, hw->st_dma);
+ err_out_reset:
+       sky2_write8(hw, B0_CTST, CS_RST_SET);
+ err_out_iounmap:
+       iounmap(hw->regs);
+ err_out_free_hw:
+       kfree(hw);
+ err_out_free_regions:
+       pci_release_regions(pdev);
+ err_out_disable:
+       pci_disable_device(pdev);
+ err_out:
+       pci_set_drvdata(pdev, NULL);
+       return err;
+ }
+ static void __devexit sky2_remove(struct pci_dev *pdev)
+ {
+       struct sky2_hw *hw = pci_get_drvdata(pdev);
+       int i;
+       if (!hw)
+               return;
+       del_timer_sync(&hw->watchdog_timer);
+       cancel_work_sync(&hw->restart_work);
+       for (i = hw->ports-1; i >= 0; --i)
+               unregister_netdev(hw->dev[i]);
+       sky2_write32(hw, B0_IMSK, 0);
+       sky2_read32(hw, B0_IMSK);
+       sky2_power_aux(hw);
+       sky2_write8(hw, B0_CTST, CS_RST_SET);
+       sky2_read8(hw, B0_CTST);
+       if (hw->ports > 1) {
+               napi_disable(&hw->napi);
+               free_irq(pdev->irq, hw);
+       }
+       if (hw->flags & SKY2_HW_USE_MSI)
+               pci_disable_msi(pdev);
+       pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
+                           hw->st_le, hw->st_dma);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       for (i = hw->ports-1; i >= 0; --i)
+               free_netdev(hw->dev[i]);
+       iounmap(hw->regs);
+       kfree(hw);
+       pci_set_drvdata(pdev, NULL);
+ }
+ static int sky2_suspend(struct device *dev)
+ {
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct sky2_hw *hw = pci_get_drvdata(pdev);
+       int i;
+       if (!hw)
+               return 0;
+       del_timer_sync(&hw->watchdog_timer);
+       cancel_work_sync(&hw->restart_work);
+       rtnl_lock();
+       sky2_all_down(hw);
+       for (i = 0; i < hw->ports; i++) {
+               struct net_device *dev = hw->dev[i];
+               struct sky2_port *sky2 = netdev_priv(dev);
+               if (sky2->wol)
+                       sky2_wol_init(sky2);
+       }
+       sky2_power_aux(hw);
+       rtnl_unlock();
+       return 0;
+ }
+ #ifdef CONFIG_PM_SLEEP
+ static int sky2_resume(struct device *dev)
+ {
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct sky2_hw *hw = pci_get_drvdata(pdev);
+       int err;
+       if (!hw)
+               return 0;
+       /* Re-enable all clocks */
+       err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
+       if (err) {
+               dev_err(&pdev->dev, "PCI write config failed\n");
+               goto out;
+       }
+       rtnl_lock();
+       sky2_reset(hw);
+       sky2_all_up(hw);
+       rtnl_unlock();
+       return 0;
+ out:
+       dev_err(&pdev->dev, "resume failed (%d)\n", err);
+       pci_disable_device(pdev);
+       return err;
+ }
+ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);
+ #define SKY2_PM_OPS (&sky2_pm_ops)
+ #else
+ #define SKY2_PM_OPS NULL
+ #endif
+ static void sky2_shutdown(struct pci_dev *pdev)
+ {
+       sky2_suspend(&pdev->dev);
+       pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
+       pci_set_power_state(pdev, PCI_D3hot);
+ }
+ static struct pci_driver sky2_driver = {
+       .name = DRV_NAME,
+       .id_table = sky2_id_table,
+       .probe = sky2_probe,
+       .remove = __devexit_p(sky2_remove),
+       .shutdown = sky2_shutdown,
+       .driver.pm = SKY2_PM_OPS,
+ };
+ static int __init sky2_init_module(void)
+ {
+       pr_info("driver version " DRV_VERSION "\n");
+       sky2_debug_init();
+       return pci_register_driver(&sky2_driver);
+ }
+ static void __exit sky2_cleanup_module(void)
+ {
+       pci_unregister_driver(&sky2_driver);
+       sky2_debug_cleanup();
+ }
+ module_init(sky2_init_module);
+ module_exit(sky2_cleanup_module);
+ MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver");
+ MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION(DRV_VERSION);
index 0000000,7078840..ab81c0d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1656 +1,1656 @@@
+ /*
+  * Micrel KS8695 (Centaur) Ethernet.
+  *
+  * 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.
+  *
+  * Copyright 2008 Simtec Electronics
+  *              Daniel Silverstone <dsilvers@simtec.co.uk>
+  *              Vincent Sanders <vince@simtec.co.uk>
+  */
+ #include <linux/dma-mapping.h>
+ #include <linux/module.h>
+ #include <linux/ioport.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/skbuff.h>
+ #include <linux/spinlock.h>
+ #include <linux/crc32.h>
+ #include <linux/mii.h>
+ #include <linux/ethtool.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+ #include <linux/irq.h>
+ #include <linux/io.h>
+ #include <linux/slab.h>
+ #include <asm/irq.h>
+ #include <mach/regs-switch.h>
+ #include <mach/regs-misc.h>
+ #include <asm/mach/irq.h>
+ #include <mach/regs-irq.h>
+ #include "ks8695net.h"
+ #define MODULENAME    "ks8695_ether"
+ #define MODULEVERSION "1.02"
+ /*
+  * Transmit and device reset timeout, default 5 seconds.
+  */
+ static int watchdog = 5000;
+ /* Hardware structures */
+ /**
+  *    struct rx_ring_desc - Receive descriptor ring element
+  *    @status: The status of the descriptor element (E.g. who owns it)
+  *    @length: The number of bytes in the block pointed to by data_ptr
+  *    @data_ptr: The physical address of the data block to receive into
+  *    @next_desc: The physical address of the next descriptor element.
+  */
+ struct rx_ring_desc {
+       __le32  status;
+       __le32  length;
+       __le32  data_ptr;
+       __le32  next_desc;
+ };
+ /**
+  *    struct tx_ring_desc - Transmit descriptor ring element
+  *    @owner: Who owns the descriptor
+  *    @status: The number of bytes in the block pointed to by data_ptr
+  *    @data_ptr: The physical address of the data block to receive into
+  *    @next_desc: The physical address of the next descriptor element.
+  */
+ struct tx_ring_desc {
+       __le32  owner;
+       __le32  status;
+       __le32  data_ptr;
+       __le32  next_desc;
+ };
+ /**
+  *    struct ks8695_skbuff - sk_buff wrapper for rx/tx rings.
+  *    @skb: The buffer in the ring
+  *    @dma_ptr: The mapped DMA pointer of the buffer
+  *    @length: The number of bytes mapped to dma_ptr
+  */
+ struct ks8695_skbuff {
+       struct sk_buff  *skb;
+       dma_addr_t      dma_ptr;
+       u32             length;
+ };
+ /* Private device structure */
+ #define MAX_TX_DESC 8
+ #define MAX_TX_DESC_MASK 0x7
+ #define MAX_RX_DESC 16
+ #define MAX_RX_DESC_MASK 0xf
+ /*napi_weight have better more than rx DMA buffers*/
+ #define NAPI_WEIGHT   64
+ #define MAX_RXBUF_SIZE 0x700
+ #define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC)
+ #define RX_RING_DMA_SIZE (sizeof(struct rx_ring_desc) * MAX_RX_DESC)
+ #define RING_DMA_SIZE (TX_RING_DMA_SIZE + RX_RING_DMA_SIZE)
+ /**
+  *    enum ks8695_dtype - Device type
+  *    @KS8695_DTYPE_WAN: This device is a WAN interface
+  *    @KS8695_DTYPE_LAN: This device is a LAN interface
+  *    @KS8695_DTYPE_HPNA: This device is an HPNA interface
+  */
+ enum ks8695_dtype {
+       KS8695_DTYPE_WAN,
+       KS8695_DTYPE_LAN,
+       KS8695_DTYPE_HPNA,
+ };
+ /**
+  *    struct ks8695_priv - Private data for the KS8695 Ethernet
+  *    @in_suspend: Flag to indicate if we're suspending/resuming
+  *    @ndev: The net_device for this interface
+  *    @dev: The platform device object for this interface
+  *    @dtype: The type of this device
+  *    @io_regs: The ioremapped registers for this interface
+  *      @napi : Add support NAPI for Rx
+  *    @rx_irq_name: The textual name of the RX IRQ from the platform data
+  *    @tx_irq_name: The textual name of the TX IRQ from the platform data
+  *    @link_irq_name: The textual name of the link IRQ from the
+  *                    platform data if available
+  *    @rx_irq: The IRQ number for the RX IRQ
+  *    @tx_irq: The IRQ number for the TX IRQ
+  *    @link_irq: The IRQ number for the link IRQ if available
+  *    @regs_req: The resource request for the registers region
+  *    @phyiface_req: The resource request for the phy/switch region
+  *                   if available
+  *    @phyiface_regs: The ioremapped registers for the phy/switch if available
+  *    @ring_base: The base pointer of the dma coherent memory for the rings
+  *    @ring_base_dma: The DMA mapped equivalent of ring_base
+  *    @tx_ring: The pointer in ring_base of the TX ring
+  *    @tx_ring_used: The number of slots in the TX ring which are occupied
+  *    @tx_ring_next_slot: The next slot to fill in the TX ring
+  *    @tx_ring_dma: The DMA mapped equivalent of tx_ring
+  *    @tx_buffers: The sk_buff mappings for the TX ring
+  *    @txq_lock: A lock to protect the tx_buffers tx_ring_used etc variables
+  *    @rx_ring: The pointer in ring_base of the RX ring
+  *    @rx_ring_dma: The DMA mapped equivalent of rx_ring
+  *    @rx_buffers: The sk_buff mappings for the RX ring
+  *    @next_rx_desc_read: The next RX descriptor to read from on IRQ
+  *      @rx_lock: A lock to protect Rx irq function
+  *    @msg_enable: The flags for which messages to emit
+  */
+ struct ks8695_priv {
+       int in_suspend;
+       struct net_device *ndev;
+       struct device *dev;
+       enum ks8695_dtype dtype;
+       void __iomem *io_regs;
+       struct napi_struct      napi;
+       const char *rx_irq_name, *tx_irq_name, *link_irq_name;
+       int rx_irq, tx_irq, link_irq;
+       struct resource *regs_req, *phyiface_req;
+       void __iomem *phyiface_regs;
+       void *ring_base;
+       dma_addr_t ring_base_dma;
+       struct tx_ring_desc *tx_ring;
+       int tx_ring_used;
+       int tx_ring_next_slot;
+       dma_addr_t tx_ring_dma;
+       struct ks8695_skbuff tx_buffers[MAX_TX_DESC];
+       spinlock_t txq_lock;
+       struct rx_ring_desc *rx_ring;
+       dma_addr_t rx_ring_dma;
+       struct ks8695_skbuff rx_buffers[MAX_RX_DESC];
+       int next_rx_desc_read;
+       spinlock_t rx_lock;
+       int msg_enable;
+ };
+ /* Register access */
+ /**
+  *    ks8695_readreg - Read from a KS8695 ethernet register
+  *    @ksp: The device to read from
+  *    @reg: The register to read
+  */
+ static inline u32
+ ks8695_readreg(struct ks8695_priv *ksp, int reg)
+ {
+       return readl(ksp->io_regs + reg);
+ }
+ /**
+  *    ks8695_writereg - Write to a KS8695 ethernet register
+  *    @ksp: The device to write to
+  *    @reg: The register to write
+  *    @value: The value to write to the register
+  */
+ static inline void
+ ks8695_writereg(struct ks8695_priv *ksp, int reg, u32 value)
+ {
+       writel(value, ksp->io_regs + reg);
+ }
+ /* Utility functions */
+ /**
+  *    ks8695_port_type - Retrieve port-type as user-friendly string
+  *    @ksp: The device to return the type for
+  *
+  *    Returns a string indicating which of the WAN, LAN or HPNA
+  *    ports this device is likely to represent.
+  */
+ static const char *
+ ks8695_port_type(struct ks8695_priv *ksp)
+ {
+       switch (ksp->dtype) {
+       case KS8695_DTYPE_LAN:
+               return "LAN";
+       case KS8695_DTYPE_WAN:
+               return "WAN";
+       case KS8695_DTYPE_HPNA:
+               return "HPNA";
+       }
+       return "UNKNOWN";
+ }
+ /**
+  *    ks8695_update_mac - Update the MAC registers in the device
+  *    @ksp: The device to update
+  *
+  *    Updates the MAC registers in the KS8695 device from the address in the
+  *    net_device structure associated with this interface.
+  */
+ static void
+ ks8695_update_mac(struct ks8695_priv *ksp)
+ {
+       /* Update the HW with the MAC from the net_device */
+       struct net_device *ndev = ksp->ndev;
+       u32 machigh, maclow;
+       maclow  = ((ndev->dev_addr[2] << 24) | (ndev->dev_addr[3] << 16) |
+                  (ndev->dev_addr[4] <<  8) | (ndev->dev_addr[5] <<  0));
+       machigh = ((ndev->dev_addr[0] <<  8) | (ndev->dev_addr[1] <<  0));
+       ks8695_writereg(ksp, KS8695_MAL, maclow);
+       ks8695_writereg(ksp, KS8695_MAH, machigh);
+ }
+ /**
+  *    ks8695_refill_rxbuffers - Re-fill the RX buffer ring
+  *    @ksp: The device to refill
+  *
+  *    Iterates the RX ring of the device looking for empty slots.
+  *    For each empty slot, we allocate and map a new SKB and give it
+  *    to the hardware.
+  *    This can be called from interrupt context safely.
+  */
+ static void
+ ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
+ {
+       /* Run around the RX ring, filling in any missing sk_buff's */
+       int buff_n;
+       for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
+               if (!ksp->rx_buffers[buff_n].skb) {
+                       struct sk_buff *skb = dev_alloc_skb(MAX_RXBUF_SIZE);
+                       dma_addr_t mapping;
+                       ksp->rx_buffers[buff_n].skb = skb;
+                       if (skb == NULL) {
+                               /* Failed to allocate one, perhaps
+                                * we'll try again later.
+                                */
+                               break;
+                       }
+                       mapping = dma_map_single(ksp->dev, skb->data,
+                                                MAX_RXBUF_SIZE,
+                                                DMA_FROM_DEVICE);
+                       if (unlikely(dma_mapping_error(ksp->dev, mapping))) {
+                               /* Failed to DMA map this SKB, try later */
+                               dev_kfree_skb_irq(skb);
+                               ksp->rx_buffers[buff_n].skb = NULL;
+                               break;
+                       }
+                       ksp->rx_buffers[buff_n].dma_ptr = mapping;
+                       skb->dev = ksp->ndev;
+                       ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE;
+                       /* Record this into the DMA ring */
+                       ksp->rx_ring[buff_n].data_ptr = cpu_to_le32(mapping);
+                       ksp->rx_ring[buff_n].length =
+                               cpu_to_le32(MAX_RXBUF_SIZE);
+                       wmb();
+                       /* And give ownership over to the hardware */
+                       ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
+               }
+       }
+ }
+ /* Maximum number of multicast addresses which the KS8695 HW supports */
+ #define KS8695_NR_ADDRESSES   16
+ /**
+  *    ks8695_init_partial_multicast - Init the mcast addr registers
+  *    @ksp: The device to initialise
+  *    @addr: The multicast address list to use
+  *    @nr_addr: The number of addresses in the list
+  *
+  *    This routine is a helper for ks8695_set_multicast - it writes
+  *    the additional-address registers in the KS8695 ethernet device
+  *    and cleans up any others left behind.
+  */
+ static void
+ ks8695_init_partial_multicast(struct ks8695_priv *ksp,
+                             struct net_device *ndev)
+ {
+       u32 low, high;
+       int i;
+       struct netdev_hw_addr *ha;
+       i = 0;
+       netdev_for_each_mc_addr(ha, ndev) {
+               /* Ran out of space in chip? */
+               BUG_ON(i == KS8695_NR_ADDRESSES);
+               low = (ha->addr[2] << 24) | (ha->addr[3] << 16) |
+                     (ha->addr[4] << 8) | (ha->addr[5]);
+               high = (ha->addr[0] << 8) | (ha->addr[1]);
+               ks8695_writereg(ksp, KS8695_AAL_(i), low);
+               ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high);
+               i++;
+       }
+       /* Clear the remaining Additional Station Addresses */
+       for (; i < KS8695_NR_ADDRESSES; i++) {
+               ks8695_writereg(ksp, KS8695_AAL_(i), 0);
+               ks8695_writereg(ksp, KS8695_AAH_(i), 0);
+       }
+ }
+ /* Interrupt handling */
+ /**
+  *    ks8695_tx_irq - Transmit IRQ handler
+  *    @irq: The IRQ which went off (ignored)
+  *    @dev_id: The net_device for the interrupt
+  *
+  *    Process the TX ring, clearing out any transmitted slots.
+  *    Allows the net_device to pass us new packets once slots are
+  *    freed.
+  */
+ static irqreturn_t
+ ks8695_tx_irq(int irq, void *dev_id)
+ {
+       struct net_device *ndev = (struct net_device *)dev_id;
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       int buff_n;
+       for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
+               if (ksp->tx_buffers[buff_n].skb &&
+                   !(ksp->tx_ring[buff_n].owner & cpu_to_le32(TDES_OWN))) {
+                       rmb();
+                       /* An SKB which is not owned by HW is present */
+                       /* Update the stats for the net_device */
+                       ndev->stats.tx_packets++;
+                       ndev->stats.tx_bytes += ksp->tx_buffers[buff_n].length;
+                       /* Free the packet from the ring */
+                       ksp->tx_ring[buff_n].data_ptr = 0;
+                       /* Free the sk_buff */
+                       dma_unmap_single(ksp->dev,
+                                        ksp->tx_buffers[buff_n].dma_ptr,
+                                        ksp->tx_buffers[buff_n].length,
+                                        DMA_TO_DEVICE);
+                       dev_kfree_skb_irq(ksp->tx_buffers[buff_n].skb);
+                       ksp->tx_buffers[buff_n].skb = NULL;
+                       ksp->tx_ring_used--;
+               }
+       }
+       netif_wake_queue(ndev);
+       return IRQ_HANDLED;
+ }
+ /**
+  *    ks8695_get_rx_enable_bit - Get rx interrupt enable/status bit
+  *    @ksp: Private data for the KS8695 Ethernet
+  *
+  *    For KS8695 document:
+  *    Interrupt Enable Register (offset 0xE204)
+  *        Bit29 : WAN MAC Receive Interrupt Enable
+  *        Bit16 : LAN MAC Receive Interrupt Enable
+  *    Interrupt Status Register (Offset 0xF208)
+  *        Bit29: WAN MAC Receive Status
+  *        Bit16: LAN MAC Receive Status
 - *    So, this Rx interrrupt enable/status bit number is equal
++ *    So, this Rx interrupt enable/status bit number is equal
+  *    as Rx IRQ number.
+  */
+ static inline u32 ks8695_get_rx_enable_bit(struct ks8695_priv *ksp)
+ {
+       return ksp->rx_irq;
+ }
+ /**
+  *    ks8695_rx_irq - Receive IRQ handler
+  *    @irq: The IRQ which went off (ignored)
+  *    @dev_id: The net_device for the interrupt
+  *
+  *    Inform NAPI that packet reception needs to be scheduled
+  */
+ static irqreturn_t
+ ks8695_rx_irq(int irq, void *dev_id)
+ {
+       struct net_device *ndev = (struct net_device *)dev_id;
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       spin_lock(&ksp->rx_lock);
+       if (napi_schedule_prep(&ksp->napi)) {
+               unsigned long status = readl(KS8695_IRQ_VA + KS8695_INTEN);
+               unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
+               /*disable rx interrupt*/
+               status &= ~mask_bit;
+               writel(status , KS8695_IRQ_VA + KS8695_INTEN);
+               __napi_schedule(&ksp->napi);
+       }
+       spin_unlock(&ksp->rx_lock);
+       return IRQ_HANDLED;
+ }
+ /**
+  *    ks8695_rx - Receive packets called by NAPI poll method
+  *    @ksp: Private data for the KS8695 Ethernet
+  *    @budget: Number of packets allowed to process
+  */
+ static int ks8695_rx(struct ks8695_priv *ksp, int budget)
+ {
+       struct net_device *ndev = ksp->ndev;
+       struct sk_buff *skb;
+       int buff_n;
+       u32 flags;
+       int pktlen;
+       int received = 0;
+       buff_n = ksp->next_rx_desc_read;
+       while (received < budget
+                       && ksp->rx_buffers[buff_n].skb
+                       && (!(ksp->rx_ring[buff_n].status &
+                                       cpu_to_le32(RDES_OWN)))) {
+                       rmb();
+                       flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
+                       /* Found an SKB which we own, this means we
+                        * received a packet
+                        */
+                       if ((flags & (RDES_FS | RDES_LS)) !=
+                           (RDES_FS | RDES_LS)) {
+                               /* This packet is not the first and
+                                * the last segment.  Therefore it is
+                                * a "spanning" packet and we can't
+                                * handle it
+                                */
+                               goto rx_failure;
+                       }
+                       if (flags & (RDES_ES | RDES_RE)) {
+                               /* It's an error packet */
+                               ndev->stats.rx_errors++;
+                               if (flags & RDES_TL)
+                                       ndev->stats.rx_length_errors++;
+                               if (flags & RDES_RF)
+                                       ndev->stats.rx_length_errors++;
+                               if (flags & RDES_CE)
+                                       ndev->stats.rx_crc_errors++;
+                               if (flags & RDES_RE)
+                                       ndev->stats.rx_missed_errors++;
+                               goto rx_failure;
+                       }
+                       pktlen = flags & RDES_FLEN;
+                       pktlen -= 4; /* Drop the CRC */
+                       /* Retrieve the sk_buff */
+                       skb = ksp->rx_buffers[buff_n].skb;
+                       /* Clear it from the ring */
+                       ksp->rx_buffers[buff_n].skb = NULL;
+                       ksp->rx_ring[buff_n].data_ptr = 0;
+                       /* Unmap the SKB */
+                       dma_unmap_single(ksp->dev,
+                                        ksp->rx_buffers[buff_n].dma_ptr,
+                                        ksp->rx_buffers[buff_n].length,
+                                        DMA_FROM_DEVICE);
+                       /* Relinquish the SKB to the network layer */
+                       skb_put(skb, pktlen);
+                       skb->protocol = eth_type_trans(skb, ndev);
+                       netif_receive_skb(skb);
+                       /* Record stats */
+                       ndev->stats.rx_packets++;
+                       ndev->stats.rx_bytes += pktlen;
+                       goto rx_finished;
+ rx_failure:
+                       /* This ring entry is an error, but we can
+                        * re-use the skb
+                        */
+                       /* Give the ring entry back to the hardware */
+                       ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
+ rx_finished:
+                       received++;
+                       buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
+       }
+       /* And note which RX descriptor we last did */
+       ksp->next_rx_desc_read = buff_n;
+       /* And refill the buffers */
+       ks8695_refill_rxbuffers(ksp);
+       /* Kick the RX DMA engine, in case it became suspended */
+       ks8695_writereg(ksp, KS8695_DRSC, 0);
+       return received;
+ }
+ /**
+  *    ks8695_poll - Receive packet by NAPI poll method
+  *    @ksp: Private data for the KS8695 Ethernet
+  *    @budget: The remaining number packets for network subsystem
+  *
+  *     Invoked by the network core when it requests for new
+  *     packets from the driver
+  */
+ static int ks8695_poll(struct napi_struct *napi, int budget)
+ {
+       struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi);
+       unsigned long  work_done;
+       unsigned long isr = readl(KS8695_IRQ_VA + KS8695_INTEN);
+       unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
+       work_done = ks8695_rx(ksp, budget);
+       if (work_done < budget) {
+               unsigned long flags;
+               spin_lock_irqsave(&ksp->rx_lock, flags);
+               __napi_complete(napi);
+               /*enable rx interrupt*/
+               writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
+               spin_unlock_irqrestore(&ksp->rx_lock, flags);
+       }
+       return work_done;
+ }
+ /**
+  *    ks8695_link_irq - Link change IRQ handler
+  *    @irq: The IRQ which went off (ignored)
+  *    @dev_id: The net_device for the interrupt
+  *
+  *    The WAN interface can generate an IRQ when the link changes,
+  *    report this to the net layer and the user.
+  */
+ static irqreturn_t
+ ks8695_link_irq(int irq, void *dev_id)
+ {
+       struct net_device *ndev = (struct net_device *)dev_id;
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       u32 ctrl;
+       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+       if (ctrl & WMC_WLS) {
+               netif_carrier_on(ndev);
+               if (netif_msg_link(ksp))
+                       dev_info(ksp->dev,
+                                "%s: Link is now up (10%sMbps/%s-duplex)\n",
+                                ndev->name,
+                                (ctrl & WMC_WSS) ? "0" : "",
+                                (ctrl & WMC_WDS) ? "Full" : "Half");
+       } else {
+               netif_carrier_off(ndev);
+               if (netif_msg_link(ksp))
+                       dev_info(ksp->dev, "%s: Link is now down.\n",
+                                ndev->name);
+       }
+       return IRQ_HANDLED;
+ }
+ /* KS8695 Device functions */
+ /**
+  *    ks8695_reset - Reset a KS8695 ethernet interface
+  *    @ksp: The interface to reset
+  *
+  *    Perform an engine reset of the interface and re-program it
+  *    with sensible defaults.
+  */
+ static void
+ ks8695_reset(struct ks8695_priv *ksp)
+ {
+       int reset_timeout = watchdog;
+       /* Issue the reset via the TX DMA control register */
+       ks8695_writereg(ksp, KS8695_DTXC, DTXC_TRST);
+       while (reset_timeout--) {
+               if (!(ks8695_readreg(ksp, KS8695_DTXC) & DTXC_TRST))
+                       break;
+               msleep(1);
+       }
+       if (reset_timeout < 0) {
+               dev_crit(ksp->dev,
+                        "Timeout waiting for DMA engines to reset\n");
+               /* And blithely carry on */
+       }
+       /* Definitely wait long enough before attempting to program
+        * the engines
+        */
+       msleep(10);
+       /* RX: unicast and broadcast */
+       ks8695_writereg(ksp, KS8695_DRXC, DRXC_RU | DRXC_RB);
+       /* TX: pad and add CRC */
+       ks8695_writereg(ksp, KS8695_DTXC, DTXC_TEP | DTXC_TAC);
+ }
+ /**
+  *    ks8695_shutdown - Shut down a KS8695 ethernet interface
+  *    @ksp: The interface to shut down
+  *
+  *    This disables packet RX/TX, cleans up IRQs, drains the rings,
+  *    and basically places the interface into a clean shutdown
+  *    state.
+  */
+ static void
+ ks8695_shutdown(struct ks8695_priv *ksp)
+ {
+       u32 ctrl;
+       int buff_n;
+       /* Disable packet transmission */
+       ctrl = ks8695_readreg(ksp, KS8695_DTXC);
+       ks8695_writereg(ksp, KS8695_DTXC, ctrl & ~DTXC_TE);
+       /* Disable packet reception */
+       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
+       ks8695_writereg(ksp, KS8695_DRXC, ctrl & ~DRXC_RE);
+       /* Release the IRQs */
+       free_irq(ksp->rx_irq, ksp->ndev);
+       free_irq(ksp->tx_irq, ksp->ndev);
+       if (ksp->link_irq != -1)
+               free_irq(ksp->link_irq, ksp->ndev);
+       /* Throw away any pending TX packets */
+       for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
+               if (ksp->tx_buffers[buff_n].skb) {
+                       /* Remove this SKB from the TX ring */
+                       ksp->tx_ring[buff_n].owner = 0;
+                       ksp->tx_ring[buff_n].status = 0;
+                       ksp->tx_ring[buff_n].data_ptr = 0;
+                       /* Unmap and bin this SKB */
+                       dma_unmap_single(ksp->dev,
+                                        ksp->tx_buffers[buff_n].dma_ptr,
+                                        ksp->tx_buffers[buff_n].length,
+                                        DMA_TO_DEVICE);
+                       dev_kfree_skb_irq(ksp->tx_buffers[buff_n].skb);
+                       ksp->tx_buffers[buff_n].skb = NULL;
+               }
+       }
+       /* Purge the RX buffers */
+       for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
+               if (ksp->rx_buffers[buff_n].skb) {
+                       /* Remove the SKB from the RX ring */
+                       ksp->rx_ring[buff_n].status = 0;
+                       ksp->rx_ring[buff_n].data_ptr = 0;
+                       /* Unmap and bin the SKB */
+                       dma_unmap_single(ksp->dev,
+                                        ksp->rx_buffers[buff_n].dma_ptr,
+                                        ksp->rx_buffers[buff_n].length,
+                                        DMA_FROM_DEVICE);
+                       dev_kfree_skb_irq(ksp->rx_buffers[buff_n].skb);
+                       ksp->rx_buffers[buff_n].skb = NULL;
+               }
+       }
+ }
+ /**
+  *    ks8695_setup_irq - IRQ setup helper function
+  *    @irq: The IRQ number to claim
+  *    @irq_name: The name to give the IRQ claimant
+  *    @handler: The function to call to handle the IRQ
+  *    @ndev: The net_device to pass in as the dev_id argument to the handler
+  *
+  *    Return 0 on success.
+  */
+ static int
+ ks8695_setup_irq(int irq, const char *irq_name,
+                irq_handler_t handler, struct net_device *ndev)
+ {
+       int ret;
+       ret = request_irq(irq, handler, IRQF_SHARED, irq_name, ndev);
+       if (ret) {
+               dev_err(&ndev->dev, "failure to request IRQ %d\n", irq);
+               return ret;
+       }
+       return 0;
+ }
+ /**
+  *    ks8695_init_net - Initialise a KS8695 ethernet interface
+  *    @ksp: The interface to initialise
+  *
+  *    This routine fills the RX ring, initialises the DMA engines,
+  *    allocates the IRQs and then starts the packet TX and RX
+  *    engines.
+  */
+ static int
+ ks8695_init_net(struct ks8695_priv *ksp)
+ {
+       int ret;
+       u32 ctrl;
+       ks8695_refill_rxbuffers(ksp);
+       /* Initialise the DMA engines */
+       ks8695_writereg(ksp, KS8695_RDLB, (u32) ksp->rx_ring_dma);
+       ks8695_writereg(ksp, KS8695_TDLB, (u32) ksp->tx_ring_dma);
+       /* Request the IRQs */
+       ret = ks8695_setup_irq(ksp->rx_irq, ksp->rx_irq_name,
+                              ks8695_rx_irq, ksp->ndev);
+       if (ret)
+               return ret;
+       ret = ks8695_setup_irq(ksp->tx_irq, ksp->tx_irq_name,
+                              ks8695_tx_irq, ksp->ndev);
+       if (ret)
+               return ret;
+       if (ksp->link_irq != -1) {
+               ret = ks8695_setup_irq(ksp->link_irq, ksp->link_irq_name,
+                                      ks8695_link_irq, ksp->ndev);
+               if (ret)
+                       return ret;
+       }
+       /* Set up the ring indices */
+       ksp->next_rx_desc_read = 0;
+       ksp->tx_ring_next_slot = 0;
+       ksp->tx_ring_used = 0;
+       /* Bring up transmission */
+       ctrl = ks8695_readreg(ksp, KS8695_DTXC);
+       /* Enable packet transmission */
+       ks8695_writereg(ksp, KS8695_DTXC, ctrl | DTXC_TE);
+       /* Bring up the reception */
+       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
+       /* Enable packet reception */
+       ks8695_writereg(ksp, KS8695_DRXC, ctrl | DRXC_RE);
+       /* And start the DMA engine */
+       ks8695_writereg(ksp, KS8695_DRSC, 0);
+       /* All done */
+       return 0;
+ }
+ /**
+  *    ks8695_release_device - HW resource release for KS8695 e-net
+  *    @ksp: The device to be freed
+  *
+  *    This unallocates io memory regions, dma-coherent regions etc
+  *    which were allocated in ks8695_probe.
+  */
+ static void
+ ks8695_release_device(struct ks8695_priv *ksp)
+ {
+       /* Unmap the registers */
+       iounmap(ksp->io_regs);
+       if (ksp->phyiface_regs)
+               iounmap(ksp->phyiface_regs);
+       /* And release the request */
+       release_resource(ksp->regs_req);
+       kfree(ksp->regs_req);
+       if (ksp->phyiface_req) {
+               release_resource(ksp->phyiface_req);
+               kfree(ksp->phyiface_req);
+       }
+       /* Free the ring buffers */
+       dma_free_coherent(ksp->dev, RING_DMA_SIZE,
+                         ksp->ring_base, ksp->ring_base_dma);
+ }
+ /* Ethtool support */
+ /**
+  *    ks8695_get_msglevel - Get the messages enabled for emission
+  *    @ndev: The network device to read from
+  */
+ static u32
+ ks8695_get_msglevel(struct net_device *ndev)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       return ksp->msg_enable;
+ }
+ /**
+  *    ks8695_set_msglevel - Set the messages enabled for emission
+  *    @ndev: The network device to configure
+  *    @value: The messages to set for emission
+  */
+ static void
+ ks8695_set_msglevel(struct net_device *ndev, u32 value)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       ksp->msg_enable = value;
+ }
+ /**
+  *    ks8695_wan_get_settings - Get device-specific settings.
+  *    @ndev: The network device to read settings from
+  *    @cmd: The ethtool structure to read into
+  */
+ static int
+ ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       u32 ctrl;
+       /* All ports on the KS8695 support these... */
+       cmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+                         SUPPORTED_TP | SUPPORTED_MII);
+       cmd->transceiver = XCVR_INTERNAL;
+       cmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
+       cmd->port = PORT_MII;
+       cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
+       cmd->phy_address = 0;
+       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+       if ((ctrl & WMC_WAND) == 0) {
+               /* auto-negotiation is enabled */
+               cmd->advertising |= ADVERTISED_Autoneg;
+               if (ctrl & WMC_WANA100F)
+                       cmd->advertising |= ADVERTISED_100baseT_Full;
+               if (ctrl & WMC_WANA100H)
+                       cmd->advertising |= ADVERTISED_100baseT_Half;
+               if (ctrl & WMC_WANA10F)
+                       cmd->advertising |= ADVERTISED_10baseT_Full;
+               if (ctrl & WMC_WANA10H)
+                       cmd->advertising |= ADVERTISED_10baseT_Half;
+               if (ctrl & WMC_WANAP)
+                       cmd->advertising |= ADVERTISED_Pause;
+               cmd->autoneg = AUTONEG_ENABLE;
+               ethtool_cmd_speed_set(cmd,
+                                     (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10);
+               cmd->duplex = (ctrl & WMC_WDS) ?
+                       DUPLEX_FULL : DUPLEX_HALF;
+       } else {
+               /* auto-negotiation is disabled */
+               cmd->autoneg = AUTONEG_DISABLE;
+               ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ?
+                                           SPEED_100 : SPEED_10));
+               cmd->duplex = (ctrl & WMC_WANFF) ?
+                       DUPLEX_FULL : DUPLEX_HALF;
+       }
+       return 0;
+ }
+ /**
+  *    ks8695_wan_set_settings - Set device-specific settings.
+  *    @ndev: The network device to configure
+  *    @cmd: The settings to configure
+  */
+ static int
+ ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       u32 ctrl;
+       if ((cmd->speed != SPEED_10) && (cmd->speed != SPEED_100))
+               return -EINVAL;
+       if ((cmd->duplex != DUPLEX_HALF) && (cmd->duplex != DUPLEX_FULL))
+               return -EINVAL;
+       if (cmd->port != PORT_MII)
+               return -EINVAL;
+       if (cmd->transceiver != XCVR_INTERNAL)
+               return -EINVAL;
+       if ((cmd->autoneg != AUTONEG_DISABLE) &&
+           (cmd->autoneg != AUTONEG_ENABLE))
+               return -EINVAL;
+       if (cmd->autoneg == AUTONEG_ENABLE) {
+               if ((cmd->advertising & (ADVERTISED_10baseT_Half |
+                               ADVERTISED_10baseT_Full |
+                               ADVERTISED_100baseT_Half |
+                               ADVERTISED_100baseT_Full)) == 0)
+                       return -EINVAL;
+               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+               ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
+                         WMC_WANA10F | WMC_WANA10H);
+               if (cmd->advertising & ADVERTISED_100baseT_Full)
+                       ctrl |= WMC_WANA100F;
+               if (cmd->advertising & ADVERTISED_100baseT_Half)
+                       ctrl |= WMC_WANA100H;
+               if (cmd->advertising & ADVERTISED_10baseT_Full)
+                       ctrl |= WMC_WANA10F;
+               if (cmd->advertising & ADVERTISED_10baseT_Half)
+                       ctrl |= WMC_WANA10H;
+               /* force a re-negotiation */
+               ctrl |= WMC_WANR;
+               writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
+       } else {
+               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+               /* disable auto-negotiation */
+               ctrl |= WMC_WAND;
+               ctrl &= ~(WMC_WANF100 | WMC_WANFF);
+               if (cmd->speed == SPEED_100)
+                       ctrl |= WMC_WANF100;
+               if (cmd->duplex == DUPLEX_FULL)
+                       ctrl |= WMC_WANFF;
+               writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
+       }
+       return 0;
+ }
+ /**
+  *    ks8695_wan_nwayreset - Restart the autonegotiation on the port.
+  *    @ndev: The network device to restart autoneotiation on
+  */
+ static int
+ ks8695_wan_nwayreset(struct net_device *ndev)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       u32 ctrl;
+       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+       if ((ctrl & WMC_WAND) == 0)
+               writel(ctrl | WMC_WANR,
+                      ksp->phyiface_regs + KS8695_WMC);
+       else
+               /* auto-negotiation not enabled */
+               return -EINVAL;
+       return 0;
+ }
+ /**
+  *    ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
+  *    @ndev: The device to retrieve settings from
+  *    @param: The structure to fill out with the information
+  */
+ static void
+ ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       u32 ctrl;
+       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+       /* advertise Pause */
+       param->autoneg = (ctrl & WMC_WANAP);
+       /* current Rx Flow-control */
+       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
+       param->rx_pause = (ctrl & DRXC_RFCE);
+       /* current Tx Flow-control */
+       ctrl = ks8695_readreg(ksp, KS8695_DTXC);
+       param->tx_pause = (ctrl & DTXC_TFCE);
+ }
+ /**
+  *    ks8695_get_drvinfo - Retrieve driver information
+  *    @ndev: The network device to retrieve info about
+  *    @info: The info structure to fill out.
+  */
+ static void
+ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
+ {
+       strlcpy(info->driver, MODULENAME, sizeof(info->driver));
+       strlcpy(info->version, MODULEVERSION, sizeof(info->version));
+       strlcpy(info->bus_info, dev_name(ndev->dev.parent),
+               sizeof(info->bus_info));
+ }
+ static const struct ethtool_ops ks8695_ethtool_ops = {
+       .get_msglevel   = ks8695_get_msglevel,
+       .set_msglevel   = ks8695_set_msglevel,
+       .get_drvinfo    = ks8695_get_drvinfo,
+ };
+ static const struct ethtool_ops ks8695_wan_ethtool_ops = {
+       .get_msglevel   = ks8695_get_msglevel,
+       .set_msglevel   = ks8695_set_msglevel,
+       .get_settings   = ks8695_wan_get_settings,
+       .set_settings   = ks8695_wan_set_settings,
+       .nway_reset     = ks8695_wan_nwayreset,
+       .get_link       = ethtool_op_get_link,
+       .get_pauseparam = ks8695_wan_get_pause,
+       .get_drvinfo    = ks8695_get_drvinfo,
+ };
+ /* Network device interface functions */
+ /**
+  *    ks8695_set_mac - Update MAC in net dev and HW
+  *    @ndev: The network device to update
+  *    @addr: The new MAC address to set
+  */
+ static int
+ ks8695_set_mac(struct net_device *ndev, void *addr)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       struct sockaddr *address = addr;
+       if (!is_valid_ether_addr(address->sa_data))
+               return -EADDRNOTAVAIL;
+       memcpy(ndev->dev_addr, address->sa_data, ndev->addr_len);
+       ks8695_update_mac(ksp);
+       dev_dbg(ksp->dev, "%s: Updated MAC address to %pM\n",
+               ndev->name, ndev->dev_addr);
+       return 0;
+ }
+ /**
+  *    ks8695_set_multicast - Set up the multicast behaviour of the interface
+  *    @ndev: The net_device to configure
+  *
+  *    This routine, called by the net layer, configures promiscuity
+  *    and multicast reception behaviour for the interface.
+  */
+ static void
+ ks8695_set_multicast(struct net_device *ndev)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       u32 ctrl;
+       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
+       if (ndev->flags & IFF_PROMISC) {
+               /* enable promiscuous mode */
+               ctrl |= DRXC_RA;
+       } else if (ndev->flags & ~IFF_PROMISC) {
+               /* disable promiscuous mode */
+               ctrl &= ~DRXC_RA;
+       }
+       if (ndev->flags & IFF_ALLMULTI) {
+               /* enable all multicast mode */
+               ctrl |= DRXC_RM;
+       } else if (netdev_mc_count(ndev) > KS8695_NR_ADDRESSES) {
+               /* more specific multicast addresses than can be
+                * handled in hardware
+                */
+               ctrl |= DRXC_RM;
+       } else {
+               /* enable specific multicasts */
+               ctrl &= ~DRXC_RM;
+               ks8695_init_partial_multicast(ksp, ndev);
+       }
+       ks8695_writereg(ksp, KS8695_DRXC, ctrl);
+ }
+ /**
+  *    ks8695_timeout - Handle a network tx/rx timeout.
+  *    @ndev: The net_device which timed out.
+  *
+  *    A network transaction timed out, reset the device.
+  */
+ static void
+ ks8695_timeout(struct net_device *ndev)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       netif_stop_queue(ndev);
+       ks8695_shutdown(ksp);
+       ks8695_reset(ksp);
+       ks8695_update_mac(ksp);
+       /* We ignore the return from this since it managed to init
+        * before it probably will be okay to init again.
+        */
+       ks8695_init_net(ksp);
+       /* Reconfigure promiscuity etc */
+       ks8695_set_multicast(ndev);
+       /* And start the TX queue once more */
+       netif_start_queue(ndev);
+ }
+ /**
+  *    ks8695_start_xmit - Start a packet transmission
+  *    @skb: The packet to transmit
+  *    @ndev: The network device to send the packet on
+  *
+  *    This routine, called by the net layer, takes ownership of the
+  *    sk_buff and adds it to the TX ring. It then kicks the TX DMA
+  *    engine to ensure transmission begins.
+  */
+ static int
+ ks8695_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       int buff_n;
+       dma_addr_t dmap;
+       spin_lock_irq(&ksp->txq_lock);
+       if (ksp->tx_ring_used == MAX_TX_DESC) {
+               /* Somehow we got entered when we have no room */
+               spin_unlock_irq(&ksp->txq_lock);
+               return NETDEV_TX_BUSY;
+       }
+       buff_n = ksp->tx_ring_next_slot;
+       BUG_ON(ksp->tx_buffers[buff_n].skb);
+       dmap = dma_map_single(ksp->dev, skb->data, skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(ksp->dev, dmap))) {
+               /* Failed to DMA map this SKB, give it back for now */
+               spin_unlock_irq(&ksp->txq_lock);
+               dev_dbg(ksp->dev, "%s: Could not map DMA memory for "\
+                       "transmission, trying later\n", ndev->name);
+               return NETDEV_TX_BUSY;
+       }
+       ksp->tx_buffers[buff_n].dma_ptr = dmap;
+       /* Mapped okay, store the buffer pointer and length for later */
+       ksp->tx_buffers[buff_n].skb = skb;
+       ksp->tx_buffers[buff_n].length = skb->len;
+       /* Fill out the TX descriptor */
+       ksp->tx_ring[buff_n].data_ptr =
+               cpu_to_le32(ksp->tx_buffers[buff_n].dma_ptr);
+       ksp->tx_ring[buff_n].status =
+               cpu_to_le32(TDES_IC | TDES_FS | TDES_LS |
+                           (skb->len & TDES_TBS));
+       wmb();
+       /* Hand it over to the hardware */
+       ksp->tx_ring[buff_n].owner = cpu_to_le32(TDES_OWN);
+       if (++ksp->tx_ring_used == MAX_TX_DESC)
+               netif_stop_queue(ndev);
+       /* Kick the TX DMA in case it decided to go IDLE */
+       ks8695_writereg(ksp, KS8695_DTSC, 0);
+       /* And update the next ring slot */
+       ksp->tx_ring_next_slot = (buff_n + 1) & MAX_TX_DESC_MASK;
+       spin_unlock_irq(&ksp->txq_lock);
+       return NETDEV_TX_OK;
+ }
+ /**
+  *    ks8695_stop - Stop (shutdown) a KS8695 ethernet interface
+  *    @ndev: The net_device to stop
+  *
+  *    This disables the TX queue and cleans up a KS8695 ethernet
+  *    device.
+  */
+ static int
+ ks8695_stop(struct net_device *ndev)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       netif_stop_queue(ndev);
+       napi_disable(&ksp->napi);
+       ks8695_shutdown(ksp);
+       return 0;
+ }
+ /**
+  *    ks8695_open - Open (bring up) a KS8695 ethernet interface
+  *    @ndev: The net_device to open
+  *
+  *    This resets, configures the MAC, initialises the RX ring and
+  *    DMA engines and starts the TX queue for a KS8695 ethernet
+  *    device.
+  */
+ static int
+ ks8695_open(struct net_device *ndev)
+ {
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       int ret;
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               return -EADDRNOTAVAIL;
+       ks8695_reset(ksp);
+       ks8695_update_mac(ksp);
+       ret = ks8695_init_net(ksp);
+       if (ret) {
+               ks8695_shutdown(ksp);
+               return ret;
+       }
+       napi_enable(&ksp->napi);
+       netif_start_queue(ndev);
+       return 0;
+ }
+ /* Platform device driver */
+ /**
+  *    ks8695_init_switch - Init LAN switch to known good defaults.
+  *    @ksp: The device to initialise
+  *
+  *    This initialises the LAN switch in the KS8695 to a known-good
+  *    set of defaults.
+  */
+ static void __devinit
+ ks8695_init_switch(struct ks8695_priv *ksp)
+ {
+       u32 ctrl;
+       /* Default value for SEC0 according to datasheet */
+       ctrl = 0x40819e00;
+       /* LED0 = Speed  LED1 = Link/Activity */
+       ctrl &= ~(SEC0_LLED1S | SEC0_LLED0S);
+       ctrl |= (LLED0S_LINK | LLED1S_LINK_ACTIVITY);
+       /* Enable Switch */
+       ctrl |= SEC0_ENABLE;
+       writel(ctrl, ksp->phyiface_regs + KS8695_SEC0);
+       /* Defaults for SEC1 */
+       writel(0x9400100, ksp->phyiface_regs + KS8695_SEC1);
+ }
+ /**
+  *    ks8695_init_wan_phy - Initialise the WAN PHY to sensible defaults
+  *    @ksp: The device to initialise
+  *
+  *    This initialises a KS8695's WAN phy to sensible values for
+  *    autonegotiation etc.
+  */
+ static void __devinit
+ ks8695_init_wan_phy(struct ks8695_priv *ksp)
+ {
+       u32 ctrl;
+       /* Support auto-negotiation */
+       ctrl = (WMC_WANAP | WMC_WANA100F | WMC_WANA100H |
+               WMC_WANA10F | WMC_WANA10H);
+       /* LED0 = Activity , LED1 = Link */
+       ctrl |= (WLED0S_ACTIVITY | WLED1S_LINK);
+       /* Restart Auto-negotiation */
+       ctrl |= WMC_WANR;
+       writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
+       writel(0, ksp->phyiface_regs + KS8695_WPPM);
+       writel(0, ksp->phyiface_regs + KS8695_PPS);
+ }
+ static const struct net_device_ops ks8695_netdev_ops = {
+       .ndo_open               = ks8695_open,
+       .ndo_stop               = ks8695_stop,
+       .ndo_start_xmit         = ks8695_start_xmit,
+       .ndo_tx_timeout         = ks8695_timeout,
+       .ndo_set_mac_address    = ks8695_set_mac,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_rx_mode        = ks8695_set_multicast,
+ };
+ /**
+  *    ks8695_probe - Probe and initialise a KS8695 ethernet interface
+  *    @pdev: The platform device to probe
+  *
+  *    Initialise a KS8695 ethernet device from platform data.
+  *
+  *    This driver requires at least one IORESOURCE_MEM for the
+  *    registers and two IORESOURCE_IRQ for the RX and TX IRQs
+  *    respectively. It can optionally take an additional
+  *    IORESOURCE_MEM for the switch or phy in the case of the lan or
+  *    wan ports, and an IORESOURCE_IRQ for the link IRQ for the wan
+  *    port.
+  */
+ static int __devinit
+ ks8695_probe(struct platform_device *pdev)
+ {
+       struct ks8695_priv *ksp;
+       struct net_device *ndev;
+       struct resource *regs_res, *phyiface_res;
+       struct resource *rxirq_res, *txirq_res, *linkirq_res;
+       int ret = 0;
+       int buff_n;
+       u32 machigh, maclow;
+       /* Initialise a net_device */
+       ndev = alloc_etherdev(sizeof(struct ks8695_priv));
+       if (!ndev) {
+               dev_err(&pdev->dev, "could not allocate device.\n");
+               return -ENOMEM;
+       }
+       SET_NETDEV_DEV(ndev, &pdev->dev);
+       dev_dbg(&pdev->dev, "ks8695_probe() called\n");
+       /* Configure our private structure a little */
+       ksp = netdev_priv(ndev);
+       ksp->dev = &pdev->dev;
+       ksp->ndev = ndev;
+       ksp->msg_enable = NETIF_MSG_LINK;
+       /* Retrieve resources */
+       regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       phyiface_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       rxirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       txirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+       linkirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
+       if (!(regs_res && rxirq_res && txirq_res)) {
+               dev_err(ksp->dev, "insufficient resources\n");
+               ret = -ENOENT;
+               goto failure;
+       }
+       ksp->regs_req = request_mem_region(regs_res->start,
+                                          resource_size(regs_res),
+                                          pdev->name);
+       if (!ksp->regs_req) {
+               dev_err(ksp->dev, "cannot claim register space\n");
+               ret = -EIO;
+               goto failure;
+       }
+       ksp->io_regs = ioremap(regs_res->start, resource_size(regs_res));
+       if (!ksp->io_regs) {
+               dev_err(ksp->dev, "failed to ioremap registers\n");
+               ret = -EINVAL;
+               goto failure;
+       }
+       if (phyiface_res) {
+               ksp->phyiface_req =
+                       request_mem_region(phyiface_res->start,
+                                          resource_size(phyiface_res),
+                                          phyiface_res->name);
+               if (!ksp->phyiface_req) {
+                       dev_err(ksp->dev,
+                               "cannot claim switch register space\n");
+                       ret = -EIO;
+                       goto failure;
+               }
+               ksp->phyiface_regs = ioremap(phyiface_res->start,
+                                            resource_size(phyiface_res));
+               if (!ksp->phyiface_regs) {
+                       dev_err(ksp->dev,
+                               "failed to ioremap switch registers\n");
+                       ret = -EINVAL;
+                       goto failure;
+               }
+       }
+       ksp->rx_irq = rxirq_res->start;
+       ksp->rx_irq_name = rxirq_res->name ? rxirq_res->name : "Ethernet RX";
+       ksp->tx_irq = txirq_res->start;
+       ksp->tx_irq_name = txirq_res->name ? txirq_res->name : "Ethernet TX";
+       ksp->link_irq = (linkirq_res ? linkirq_res->start : -1);
+       ksp->link_irq_name = (linkirq_res && linkirq_res->name) ?
+               linkirq_res->name : "Ethernet Link";
+       /* driver system setup */
+       ndev->netdev_ops = &ks8695_netdev_ops;
+       ndev->watchdog_timeo     = msecs_to_jiffies(watchdog);
+       netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
+       /* Retrieve the default MAC addr from the chip. */
+       /* The bootloader should have left it in there for us. */
+       machigh = ks8695_readreg(ksp, KS8695_MAH);
+       maclow = ks8695_readreg(ksp, KS8695_MAL);
+       ndev->dev_addr[0] = (machigh >> 8) & 0xFF;
+       ndev->dev_addr[1] = machigh & 0xFF;
+       ndev->dev_addr[2] = (maclow >> 24) & 0xFF;
+       ndev->dev_addr[3] = (maclow >> 16) & 0xFF;
+       ndev->dev_addr[4] = (maclow >> 8) & 0xFF;
+       ndev->dev_addr[5] = maclow & 0xFF;
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               dev_warn(ksp->dev, "%s: Invalid ethernet MAC address. Please "
+                        "set using ifconfig\n", ndev->name);
+       /* In order to be efficient memory-wise, we allocate both
+        * rings in one go.
+        */
+       ksp->ring_base = dma_alloc_coherent(&pdev->dev, RING_DMA_SIZE,
+                                           &ksp->ring_base_dma, GFP_KERNEL);
+       if (!ksp->ring_base) {
+               ret = -ENOMEM;
+               goto failure;
+       }
+       /* Specify the TX DMA ring buffer */
+       ksp->tx_ring = ksp->ring_base;
+       ksp->tx_ring_dma = ksp->ring_base_dma;
+       /* And initialise the queue's lock */
+       spin_lock_init(&ksp->txq_lock);
+       spin_lock_init(&ksp->rx_lock);
+       /* Specify the RX DMA ring buffer */
+       ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE;
+       ksp->rx_ring_dma = ksp->ring_base_dma + TX_RING_DMA_SIZE;
+       /* Zero the descriptor rings */
+       memset(ksp->tx_ring, 0, TX_RING_DMA_SIZE);
+       memset(ksp->rx_ring, 0, RX_RING_DMA_SIZE);
+       /* Build the rings */
+       for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
+               ksp->tx_ring[buff_n].next_desc =
+                       cpu_to_le32(ksp->tx_ring_dma +
+                                   (sizeof(struct tx_ring_desc) *
+                                    ((buff_n + 1) & MAX_TX_DESC_MASK)));
+       }
+       for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
+               ksp->rx_ring[buff_n].next_desc =
+                       cpu_to_le32(ksp->rx_ring_dma +
+                                   (sizeof(struct rx_ring_desc) *
+                                    ((buff_n + 1) & MAX_RX_DESC_MASK)));
+       }
+       /* Initialise the port (physically) */
+       if (ksp->phyiface_regs && ksp->link_irq == -1) {
+               ks8695_init_switch(ksp);
+               ksp->dtype = KS8695_DTYPE_LAN;
+               SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
+       } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
+               ks8695_init_wan_phy(ksp);
+               ksp->dtype = KS8695_DTYPE_WAN;
+               SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
+       } else {
+               /* No initialisation since HPNA does not have a PHY */
+               ksp->dtype = KS8695_DTYPE_HPNA;
+               SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
+       }
+       /* And bring up the net_device with the net core */
+       platform_set_drvdata(pdev, ndev);
+       ret = register_netdev(ndev);
+       if (ret == 0) {
+               dev_info(ksp->dev, "ks8695 ethernet (%s) MAC: %pM\n",
+                        ks8695_port_type(ksp), ndev->dev_addr);
+       } else {
+               /* Report the failure to register the net_device */
+               dev_err(ksp->dev, "ks8695net: failed to register netdev.\n");
+               goto failure;
+       }
+       /* All is well */
+       return 0;
+       /* Error exit path */
+ failure:
+       ks8695_release_device(ksp);
+       free_netdev(ndev);
+       return ret;
+ }
+ /**
+  *    ks8695_drv_suspend - Suspend a KS8695 ethernet platform device.
+  *    @pdev: The device to suspend
+  *    @state: The suspend state
+  *
+  *    This routine detaches and shuts down a KS8695 ethernet device.
+  */
+ static int
+ ks8695_drv_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       ksp->in_suspend = 1;
+       if (netif_running(ndev)) {
+               netif_device_detach(ndev);
+               ks8695_shutdown(ksp);
+       }
+       return 0;
+ }
+ /**
+  *    ks8695_drv_resume - Resume a KS8695 ethernet platform device.
+  *    @pdev: The device to resume
+  *
+  *    This routine re-initialises and re-attaches a KS8695 ethernet
+  *    device.
+  */
+ static int
+ ks8695_drv_resume(struct platform_device *pdev)
+ {
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       if (netif_running(ndev)) {
+               ks8695_reset(ksp);
+               ks8695_init_net(ksp);
+               ks8695_set_multicast(ndev);
+               netif_device_attach(ndev);
+       }
+       ksp->in_suspend = 0;
+       return 0;
+ }
+ /**
+  *    ks8695_drv_remove - Remove a KS8695 net device on driver unload.
+  *    @pdev: The platform device to remove
+  *
+  *    This unregisters and releases a KS8695 ethernet device.
+  */
+ static int __devexit
+ ks8695_drv_remove(struct platform_device *pdev)
+ {
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct ks8695_priv *ksp = netdev_priv(ndev);
+       platform_set_drvdata(pdev, NULL);
+       netif_napi_del(&ksp->napi);
+       unregister_netdev(ndev);
+       ks8695_release_device(ksp);
+       free_netdev(ndev);
+       dev_dbg(&pdev->dev, "released and freed device\n");
+       return 0;
+ }
+ static struct platform_driver ks8695_driver = {
+       .driver = {
+               .name   = MODULENAME,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = ks8695_probe,
+       .remove         = __devexit_p(ks8695_drv_remove),
+       .suspend        = ks8695_drv_suspend,
+       .resume         = ks8695_drv_resume,
+ };
+ /* Module interface */
+ static int __init
+ ks8695_init(void)
+ {
+       printk(KERN_INFO "%s Ethernet driver, V%s\n",
+              MODULENAME, MODULEVERSION);
+       return platform_driver_register(&ks8695_driver);
+ }
+ static void __exit
+ ks8695_cleanup(void)
+ {
+       platform_driver_unregister(&ks8695_driver);
+ }
+ module_init(ks8695_init);
+ module_exit(ks8695_cleanup);
+ MODULE_AUTHOR("Simtec Electronics");
+ MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver");
+ MODULE_LICENSE("GPL");
+ MODULE_ALIAS("platform:" MODULENAME);
+ module_param(watchdog, int, 0400);
+ MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
index 0000000,1854c88..5a689af
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,137 +1,136 @@@
+ #
+ # Western Digital/SMC network device configuration
+ #
+ config NET_VENDOR_SMSC
+       bool "SMC (SMSC)/Western Digital devices"
+       default y
+       depends on ARM || ISA || MAC || ARM || MIPS || M32R || SUPERH || \
+               BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA
+       ---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 SMC/Western Digital cards. If you say Y, you will
+         be asked for your specific card in the following questions.
+ if NET_VENDOR_SMSC
+ config SMC9194
+       tristate "SMC 9194 support"
+       depends on (ISA || MAC && BROKEN)
+       select CRC32
+       ---help---
+         This is support for the SMC9xxx based Ethernet cards. Choose this
+         option if you have a DELL laptop with the docking station, or
+         another SMC9192/9194 based chipset.  Say Y if you want it compiled
+         into the kernel, and read the file
+         <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
+         available from <http://www.tldp.org/docs.html#howto>.
+         To compile this driver as a module, choose M here. The module
+         will be called smc9194.
+ config SMC91X
+       tristate "SMC 91C9x/91C1xxx support"
+       select CRC32
+       select NET_CORE
+       select MII
+       depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \
+                   MN10300 || COLDFIRE)
+       ---help---
+         This is a driver for SMC's 91x series of Ethernet chipsets,
+         including the SMC91C94 and the SMC91C111. Say Y if you want it
+         compiled into the kernel, and read the file
+         <file:Documentation/networking/smc9.txt>  and the Ethernet-HOWTO,
+         available from  <http://www.tldp.org/docs.html#howto>.
+         This driver is also available as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want).
+         The module will be called smc91x.  If you want to compile it as a
+         module, say M here and read <file:Documentation/kbuild/modules.txt>.
+ config PCMCIA_SMC91C92
+       tristate "SMC 91Cxx PCMCIA support"
+       depends on PCMCIA
+       select CRC32
+       select NET_CORE
+       select MII
+       ---help---
+         Say Y here if you intend to attach an SMC 91Cxx compatible PCMCIA
+         (PC-card) Ethernet or Fast Ethernet card to your computer.
+         To compile this driver as a module, choose M here: the module will be
+         called smc91c92_cs.  If unsure, say N.
+ config EPIC100
+       tristate "SMC EtherPower II"
+       depends on PCI
+       select CRC32
+       select NET_CORE
+       select MII
+       ---help---
+         This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
+         which is based on the SMC83c17x (EPIC/100).
+         More specific information and updates are available from
+         <http://www.scyld.com/network/epic100.html>.
+ config SMC911X
+       tristate "SMSC LAN911[5678] support"
+       select CRC32
+       select NET_CORE
+       select MII
+       depends on (ARM || SUPERH || MN10300)
+       ---help---
+         This is a driver for SMSC's LAN911x series of Ethernet chipsets
+         including the new LAN9115, LAN9116, LAN9117, and LAN9118.
+         Say Y if you want it compiled into the kernel,
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+         This driver is also available as a module. The module will be
+         called smc911x.  If you want to compile it as a module, say M
+         here and read <file:Documentation/kbuild/modules.txt>
+ config SMSC911X
+       tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
+       depends on (ARM || SUPERH || BLACKFIN || MIPS || MN10300)
+       select CRC32
+       select NET_CORE
+       select MII
+       select PHYLIB
+       ---help---
+         Say Y here if you want support for SMSC LAN911x and LAN921x families
+         of ethernet controllers.
 -        To compile this driver as a module, choose M here and read
 -        <file:Documentation/networking/net-modules.txt>. The module
++        To compile this driver as a module, choose M here. The module
+         will be called smsc911x.
+ config SMSC911X_ARCH_HOOKS
+       def_bool n
+       depends on SMSC911X
+       ---help---
+         If the arch enables this, it allows the arch to implement various
+         hooks for more comprehensive interrupt control and also to override
+         the source of the MAC address.
+ config SMSC9420
+       tristate "SMSC LAN9420 PCI ethernet adapter support"
+       depends on PCI
+       select CRC32
+       select PHYLIB
+       select SMSC_PHY
+       ---help---
+         This is a driver for SMSC's LAN9420 PCI ethernet adapter.
+         Say Y if you want it compiled into the kernel,
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+         This driver is also available as a module. The module will be
+         called smsc9420.  If you want to compile it as a module, say M
+         here and read <file:Documentation/kbuild/modules.txt>
+ endif # NET_VENDOR_SMSC
index 0000000,78e3fb2..10826d8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2465 +1,2465 @@@
+ /*
+  * Copyright 2011 Tilera 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, version 2.
+  *
+  *   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, GOOD TITLE or
+  *   NON INFRINGEMENT.  See the GNU General Public License for
+  *   more details.
+  */
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/moduleparam.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>      /* printk() */
+ #include <linux/slab.h>        /* kmalloc() */
+ #include <linux/errno.h>       /* error codes */
+ #include <linux/types.h>       /* size_t */
+ #include <linux/interrupt.h>
+ #include <linux/in.h>
+ #include <linux/netdevice.h>   /* struct device, and other headers */
+ #include <linux/etherdevice.h> /* eth_type_trans */
+ #include <linux/skbuff.h>
+ #include <linux/ioctl.h>
+ #include <linux/cdev.h>
+ #include <linux/hugetlb.h>
+ #include <linux/in6.h>
+ #include <linux/timer.h>
+ #include <linux/io.h>
+ #include <asm/checksum.h>
+ #include <asm/homecache.h>
+ #include <hv/drv_xgbe_intf.h>
+ #include <hv/drv_xgbe_impl.h>
+ #include <hv/hypervisor.h>
+ #include <hv/netio_intf.h>
+ /* For TSO */
+ #include <linux/ip.h>
+ #include <linux/tcp.h>
+ /*
+  * First, "tile_net_init_module()" initializes all four "devices" which
+  * can be used by linux.
+  *
+  * Then, "ifconfig DEVICE up" calls "tile_net_open()", which analyzes
+  * the network cpus, then uses "tile_net_open_aux()" to initialize
+  * LIPP/LEPP, and then uses "tile_net_open_inner()" to register all
+  * the tiles, provide buffers to LIPP, allow ingress to start, and
+  * turn on hypervisor interrupt handling (and NAPI) on all tiles.
+  *
+  * If registration fails due to the link being down, then "retry_work"
+  * is used to keep calling "tile_net_open_inner()" until it succeeds.
+  *
+  * If "ifconfig DEVICE down" is called, it uses "tile_net_stop()" to
+  * stop egress, drain the LIPP buffers, unregister all the tiles, stop
+  * LIPP/LEPP, and wipe the LEPP queue.
+  *
+  * We start out with the ingress interrupt enabled on each CPU.  When
+  * this interrupt fires, we disable it, and call "napi_schedule()".
+  * This will cause "tile_net_poll()" to be called, which will pull
+  * packets from the netio queue, filtering them out, or passing them
+  * to "netif_receive_skb()".  If our budget is exhausted, we will
+  * return, knowing we will be called again later.  Otherwise, we
+  * reenable the ingress interrupt, and call "napi_complete()".
+  *
+  * HACK: Since disabling the ingress interrupt is not reliable, we
+  * ignore the interrupt if the global "active" flag is false.
+  *
+  *
+  * NOTE: The use of "native_driver" ensures that EPP exists, and that
+  * we are using "LIPP" and "LEPP".
+  *
+  * NOTE: Failing to free completions for an arbitrarily long time
+  * (which is defined to be illegal) does in fact cause bizarre
+  * problems.  The "egress_timer" helps prevent this from happening.
+  */
+ /* HACK: Allow use of "jumbo" packets. */
+ /* This should be 1500 if "jumbo" is not set in LIPP. */
+ /* This should be at most 10226 (10240 - 14) if "jumbo" is set in LIPP. */
+ /* ISSUE: This has not been thoroughly tested (except at 1500). */
+ #define TILE_NET_MTU 1500
+ /* HACK: Define to support GSO. */
+ /* ISSUE: This may actually hurt performance of the TCP blaster. */
+ /* #define TILE_NET_GSO */
+ /* Define this to collapse "duplicate" acks. */
+ /* #define IGNORE_DUP_ACKS */
+ /* HACK: Define this to verify incoming packets. */
+ /* #define TILE_NET_VERIFY_INGRESS */
+ /* Use 3000 to enable the Linux Traffic Control (QoS) layer, else 0. */
+ #define TILE_NET_TX_QUEUE_LEN 0
+ /* Define to dump packets (prints out the whole packet on tx and rx). */
+ /* #define TILE_NET_DUMP_PACKETS */
+ /* Define to enable debug spew (all PDEBUG's are enabled). */
+ /* #define TILE_NET_DEBUG */
+ /* Define to activate paranoia checks. */
+ /* #define TILE_NET_PARANOIA */
+ /* Default transmit lockup timeout period, in jiffies. */
+ #define TILE_NET_TIMEOUT (5 * HZ)
+ /* Default retry interval for bringing up the NetIO interface, in jiffies. */
+ #define TILE_NET_RETRY_INTERVAL (5 * HZ)
+ /* Number of ports (xgbe0, xgbe1, gbe0, gbe1). */
+ #define TILE_NET_DEVS 4
+ /* Paranoia. */
+ #if NET_IP_ALIGN != LIPP_PACKET_PADDING
+ #error "NET_IP_ALIGN must match LIPP_PACKET_PADDING."
+ #endif
+ /* Debug print. */
+ #ifdef TILE_NET_DEBUG
+ #define PDEBUG(fmt, args...) net_printk(fmt, ## args)
+ #else
+ #define PDEBUG(fmt, args...)
+ #endif
+ MODULE_AUTHOR("Tilera");
+ MODULE_LICENSE("GPL");
+ /*
+  * Queue of incoming packets for a specific cpu and device.
+  *
+  * Includes a pointer to the "system" data, and the actual "user" data.
+  */
+ struct tile_netio_queue {
+       netio_queue_impl_t *__system_part;
+       netio_queue_user_impl_t __user_part;
+ };
+ /*
+  * Statistics counters for a specific cpu and device.
+  */
+ struct tile_net_stats_t {
+       u32 rx_packets;
+       u32 rx_bytes;
+       u32 tx_packets;
+       u32 tx_bytes;
+ };
+ /*
+  * Info for a specific cpu and device.
+  *
+  * ISSUE: There is a "dev" pointer in "napi" as well.
+  */
+ struct tile_net_cpu {
+       /* The NAPI struct. */
+       struct napi_struct napi;
+       /* Packet queue. */
+       struct tile_netio_queue queue;
+       /* Statistics. */
+       struct tile_net_stats_t stats;
+       /* True iff NAPI is enabled. */
+       bool napi_enabled;
 -      /* True if this tile has succcessfully registered with the IPP. */
++      /* True if this tile has successfully registered with the IPP. */
+       bool registered;
+       /* True if the link was down last time we tried to register. */
+       bool link_down;
+       /* True if "egress_timer" is scheduled. */
+       bool egress_timer_scheduled;
+       /* Number of small sk_buffs which must still be provided. */
+       unsigned int num_needed_small_buffers;
+       /* Number of large sk_buffs which must still be provided. */
+       unsigned int num_needed_large_buffers;
+       /* A timer for handling egress completions. */
+       struct timer_list egress_timer;
+ };
+ /*
+  * Info for a specific device.
+  */
+ struct tile_net_priv {
+       /* Our network device. */
+       struct net_device *dev;
+       /* Pages making up the egress queue. */
+       struct page *eq_pages;
+       /* Address of the actual egress queue. */
+       lepp_queue_t *eq;
+       /* Protects "eq". */
+       spinlock_t eq_lock;
+       /* The hypervisor handle for this interface. */
+       int hv_devhdl;
+       /* The intr bit mask that IDs this device. */
+       u32 intr_id;
+       /* True iff "tile_net_open_aux()" has succeeded. */
+       bool partly_opened;
+       /* True iff the device is "active". */
+       bool active;
+       /* Effective network cpus. */
+       struct cpumask network_cpus_map;
+       /* Number of network cpus. */
+       int network_cpus_count;
+       /* Credits per network cpu. */
+       int network_cpus_credits;
+       /* Network stats. */
+       struct net_device_stats stats;
+       /* For NetIO bringup retries. */
+       struct delayed_work retry_work;
+       /* Quick access to per cpu data. */
+       struct tile_net_cpu *cpu[NR_CPUS];
+ };
+ /* Log2 of the number of small pages needed for the egress queue. */
+ #define EQ_ORDER  get_order(sizeof(lepp_queue_t))
+ /* Size of the egress queue's pages. */
+ #define EQ_SIZE   (1 << (PAGE_SHIFT + EQ_ORDER))
+ /*
+  * The actual devices (xgbe0, xgbe1, gbe0, gbe1).
+  */
+ static struct net_device *tile_net_devs[TILE_NET_DEVS];
+ /*
+  * The "tile_net_cpu" structures for each device.
+  */
+ static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe0);
+ static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe1);
+ static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe0);
+ static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe1);
+ /*
+  * True if "network_cpus" was specified.
+  */
+ static bool network_cpus_used;
+ /*
+  * The actual cpus in "network_cpus".
+  */
+ static struct cpumask network_cpus_map;
+ #ifdef TILE_NET_DEBUG
+ /*
+  * printk with extra stuff.
+  *
+  * We print the CPU we're running in brackets.
+  */
+ static void net_printk(char *fmt, ...)
+ {
+       int i;
+       int len;
+       va_list args;
+       static char buf[256];
+       len = sprintf(buf, "tile_net[%2.2d]: ", smp_processor_id());
+       va_start(args, fmt);
+       i = vscnprintf(buf + len, sizeof(buf) - len - 1, fmt, args);
+       va_end(args);
+       buf[255] = '\0';
+       pr_notice(buf);
+ }
+ #endif
+ #ifdef TILE_NET_DUMP_PACKETS
+ /*
+  * Dump a packet.
+  */
+ static void dump_packet(unsigned char *data, unsigned long length, char *s)
+ {
+       int my_cpu = smp_processor_id();
+       unsigned long i;
+       char buf[128];
+       static unsigned int count;
+       pr_info("dump_packet(data %p, length 0x%lx s %s count 0x%x)\n",
+              data, length, s, count++);
+       pr_info("\n");
+       for (i = 0; i < length; i++) {
+               if ((i & 0xf) == 0)
+                       sprintf(buf, "[%02d] %8.8lx:", my_cpu, i);
+               sprintf(buf + strlen(buf), " %2.2x", data[i]);
+               if ((i & 0xf) == 0xf || i == length - 1) {
+                       strcat(buf, "\n");
+                       pr_info("%s", buf);
+               }
+       }
+ }
+ #endif
+ /*
+  * Provide support for the __netio_fastio1() swint
+  * (see <hv/drv_xgbe_intf.h> for how it is used).
+  *
+  * The fastio swint2 call may clobber all the caller-saved registers.
+  * It rarely clobbers memory, but we allow for the possibility in
+  * the signature just to be on the safe side.
+  *
+  * Also, gcc doesn't seem to allow an input operand to be
+  * clobbered, so we fake it with dummy outputs.
+  *
+  * This function can't be static because of the way it is declared
+  * in the netio header.
+  */
+ inline int __netio_fastio1(u32 fastio_index, u32 arg0)
+ {
+       long result, clobber_r1, clobber_r10;
+       asm volatile("swint2"
+                    : "=R00" (result),
+                      "=R01" (clobber_r1), "=R10" (clobber_r10)
+                    : "R10" (fastio_index), "R01" (arg0)
+                    : "memory", "r2", "r3", "r4",
+                      "r5", "r6", "r7", "r8", "r9",
+                      "r11", "r12", "r13", "r14",
+                      "r15", "r16", "r17", "r18", "r19",
+                      "r20", "r21", "r22", "r23", "r24",
+                      "r25", "r26", "r27", "r28", "r29");
+       return result;
+ }
+ /*
+  * Provide a linux buffer to LIPP.
+  */
+ static void tile_net_provide_linux_buffer(struct tile_net_cpu *info,
+                                         void *va, bool small)
+ {
+       struct tile_netio_queue *queue = &info->queue;
+       /* Convert "va" and "small" to "linux_buffer_t". */
+       unsigned int buffer = ((unsigned int)(__pa(va) >> 7) << 1) + small;
+       __netio_fastio_free_buffer(queue->__user_part.__fastio_index, buffer);
+ }
+ /*
+  * Provide a linux buffer for LIPP.
+  *
+  * Note that the ACTUAL allocation for each buffer is a "struct sk_buff",
+  * plus a chunk of memory that includes not only the requested bytes, but
+  * also NET_SKB_PAD bytes of initial padding, and a "struct skb_shared_info".
+  *
+  * Note that "struct skb_shared_info" is 88 bytes with 64K pages and
+  * 268 bytes with 4K pages (since the frags[] array needs 18 entries).
+  *
+  * Without jumbo packets, the maximum packet size will be 1536 bytes,
+  * and we use 2 bytes (NET_IP_ALIGN) of padding.  ISSUE: If we told
+  * the hardware to clip at 1518 bytes instead of 1536 bytes, then we
+  * could save an entire cache line, but in practice, we don't need it.
+  *
+  * Since CPAs are 38 bits, and we can only encode the high 31 bits in
+  * a "linux_buffer_t", the low 7 bits must be zero, and thus, we must
+  * align the actual "va" mod 128.
+  *
+  * We assume that the underlying "head" will be aligned mod 64.  Note
+  * that in practice, we have seen "head" NOT aligned mod 128 even when
+  * using 2048 byte allocations, which is surprising.
+  *
+  * If "head" WAS always aligned mod 128, we could change LIPP to
+  * assume that the low SIX bits are zero, and the 7th bit is one, that
+  * is, align the actual "va" mod 128 plus 64, which would be "free".
+  *
+  * For now, the actual "head" pointer points at NET_SKB_PAD bytes of
+  * padding, plus 28 or 92 bytes of extra padding, plus the sk_buff
+  * pointer, plus the NET_IP_ALIGN padding, plus 126 or 1536 bytes for
+  * the actual packet, plus 62 bytes of empty padding, plus some
+  * padding and the "struct skb_shared_info".
+  *
+  * With 64K pages, a large buffer thus needs 32+92+4+2+1536+62+88
+  * bytes, or 1816 bytes, which fits comfortably into 2048 bytes.
+  *
+  * With 64K pages, a small buffer thus needs 32+92+4+2+126+88
+  * bytes, or 344 bytes, which means we are wasting 64+ bytes, and
+  * could presumably increase the size of small buffers.
+  *
+  * With 4K pages, a large buffer thus needs 32+92+4+2+1536+62+268
+  * bytes, or 1996 bytes, which fits comfortably into 2048 bytes.
+  *
+  * With 4K pages, a small buffer thus needs 32+92+4+2+126+268
+  * bytes, or 524 bytes, which is annoyingly wasteful.
+  *
+  * Maybe we should increase LIPP_SMALL_PACKET_SIZE to 192?
+  *
+  * ISSUE: Maybe we should increase "NET_SKB_PAD" to 64?
+  */
+ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info,
+                                          bool small)
+ {
+ #if TILE_NET_MTU <= 1536
+       /* Without "jumbo", 2 + 1536 should be sufficient. */
+       unsigned int large_size = NET_IP_ALIGN + 1536;
+ #else
+       /* ISSUE: This has not been tested. */
+       unsigned int large_size = NET_IP_ALIGN + TILE_NET_MTU + 100;
+ #endif
+       /* Avoid "false sharing" with last cache line. */
+       /* ISSUE: This is already done by "dev_alloc_skb()". */
+       unsigned int len =
+                (((small ? LIPP_SMALL_PACKET_SIZE : large_size) +
+                  CHIP_L2_LINE_SIZE() - 1) & -CHIP_L2_LINE_SIZE());
+       unsigned int padding = 128 - NET_SKB_PAD;
+       unsigned int align;
+       struct sk_buff *skb;
+       void *va;
+       struct sk_buff **skb_ptr;
+       /* Request 96 extra bytes for alignment purposes. */
+       skb = dev_alloc_skb(len + padding);
+       if (skb == NULL)
+               return false;
+       /* Skip 32 or 96 bytes to align "data" mod 128. */
+       align = -(long)skb->data & (128 - 1);
+       BUG_ON(align > padding);
+       skb_reserve(skb, align);
+       /* This address is given to IPP. */
+       va = skb->data;
+       /* Buffers must not span a huge page. */
+       BUG_ON(((((long)va & ~HPAGE_MASK) + len) & HPAGE_MASK) != 0);
+ #ifdef TILE_NET_PARANOIA
+ #if CHIP_HAS_CBOX_HOME_MAP()
+       if (hash_default) {
+               HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)va);
+               if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3)
+                       panic("Non-HFH ingress buffer! VA=%p Mode=%d PTE=%llx",
+                             va, hv_pte_get_mode(pte), hv_pte_val(pte));
+       }
+ #endif
+ #endif
+       /* Invalidate the packet buffer. */
+       if (!hash_default)
+               __inv_buffer(va, len);
+       /* Skip two bytes to satisfy LIPP assumptions. */
+       /* Note that this aligns IP on a 16 byte boundary. */
+       /* ISSUE: Do this when the packet arrives? */
+       skb_reserve(skb, NET_IP_ALIGN);
+       /* Save a back-pointer to 'skb'. */
+       skb_ptr = va - sizeof(*skb_ptr);
+       *skb_ptr = skb;
+       /* Make sure "skb_ptr" has been flushed. */
+       __insn_mf();
+       /* Provide the new buffer. */
+       tile_net_provide_linux_buffer(info, va, small);
+       return true;
+ }
+ /*
+  * Provide linux buffers for LIPP.
+  */
+ static void tile_net_provide_needed_buffers(struct tile_net_cpu *info)
+ {
+       while (info->num_needed_small_buffers != 0) {
+               if (!tile_net_provide_needed_buffer(info, true))
+                       goto oops;
+               info->num_needed_small_buffers--;
+       }
+       while (info->num_needed_large_buffers != 0) {
+               if (!tile_net_provide_needed_buffer(info, false))
+                       goto oops;
+               info->num_needed_large_buffers--;
+       }
+       return;
+ oops:
+       /* Add a description to the page allocation failure dump. */
+       pr_notice("Could not provide a linux buffer to LIPP.\n");
+ }
+ /*
+  * Grab some LEPP completions, and store them in "comps", of size
+  * "comps_size", and return the number of completions which were
+  * stored, so the caller can free them.
+  */
+ static unsigned int tile_net_lepp_grab_comps(lepp_queue_t *eq,
+                                            struct sk_buff *comps[],
+                                            unsigned int comps_size,
+                                            unsigned int min_size)
+ {
+       unsigned int n = 0;
+       unsigned int comp_head = eq->comp_head;
+       unsigned int comp_busy = eq->comp_busy;
+       while (comp_head != comp_busy && n < comps_size) {
+               comps[n++] = eq->comps[comp_head];
+               LEPP_QINC(comp_head);
+       }
+       if (n < min_size)
+               return 0;
+       eq->comp_head = comp_head;
+       return n;
+ }
+ /*
+  * Free some comps, and return true iff there are still some pending.
+  */
+ static bool tile_net_lepp_free_comps(struct net_device *dev, bool all)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       lepp_queue_t *eq = priv->eq;
+       struct sk_buff *olds[64];
+       unsigned int wanted = 64;
+       unsigned int i, n;
+       bool pending;
+       spin_lock(&priv->eq_lock);
+       if (all)
+               eq->comp_busy = eq->comp_tail;
+       n = tile_net_lepp_grab_comps(eq, olds, wanted, 0);
+       pending = (eq->comp_head != eq->comp_tail);
+       spin_unlock(&priv->eq_lock);
+       for (i = 0; i < n; i++)
+               kfree_skb(olds[i]);
+       return pending;
+ }
+ /*
+  * Make sure the egress timer is scheduled.
+  *
+  * Note that we use "schedule if not scheduled" logic instead of the more
+  * obvious "reschedule" logic, because "reschedule" is fairly expensive.
+  */
+ static void tile_net_schedule_egress_timer(struct tile_net_cpu *info)
+ {
+       if (!info->egress_timer_scheduled) {
+               mod_timer_pinned(&info->egress_timer, jiffies + 1);
+               info->egress_timer_scheduled = true;
+       }
+ }
+ /*
+  * The "function" for "info->egress_timer".
+  *
+  * This timer will reschedule itself as long as there are any pending
+  * completions expected (on behalf of any tile).
+  *
+  * ISSUE: Realistically, will the timer ever stop scheduling itself?
+  *
+  * ISSUE: This timer is almost never actually needed, so just use a global
+  * timer that can run on any tile.
+  *
+  * ISSUE: Maybe instead track number of expected completions, and free
+  * only that many, resetting to zero if "pending" is ever false.
+  */
+ static void tile_net_handle_egress_timer(unsigned long arg)
+ {
+       struct tile_net_cpu *info = (struct tile_net_cpu *)arg;
+       struct net_device *dev = info->napi.dev;
+       /* The timer is no longer scheduled. */
+       info->egress_timer_scheduled = false;
+       /* Free comps, and reschedule timer if more are pending. */
+       if (tile_net_lepp_free_comps(dev, false))
+               tile_net_schedule_egress_timer(info);
+ }
+ #ifdef IGNORE_DUP_ACKS
+ /*
+  * Help detect "duplicate" ACKs.  These are sequential packets (for a
+  * given flow) which are exactly 66 bytes long, sharing everything but
+  * ID=2@0x12, Hsum=2@0x18, Ack=4@0x2a, WinSize=2@0x30, Csum=2@0x32,
+  * Tstamps=10@0x38.  The ID's are +1, the Hsum's are -1, the Ack's are
+  * +N, and the Tstamps are usually identical.
+  *
+  * NOTE: Apparently truly duplicate acks (with identical "ack" values),
+  * should not be collapsed, as they are used for some kind of flow control.
+  */
+ static bool is_dup_ack(char *s1, char *s2, unsigned int len)
+ {
+       int i;
+       unsigned long long ignorable = 0;
+       /* Identification. */
+       ignorable |= (1ULL << 0x12);
+       ignorable |= (1ULL << 0x13);
+       /* Header checksum. */
+       ignorable |= (1ULL << 0x18);
+       ignorable |= (1ULL << 0x19);
+       /* ACK. */
+       ignorable |= (1ULL << 0x2a);
+       ignorable |= (1ULL << 0x2b);
+       ignorable |= (1ULL << 0x2c);
+       ignorable |= (1ULL << 0x2d);
+       /* WinSize. */
+       ignorable |= (1ULL << 0x30);
+       ignorable |= (1ULL << 0x31);
+       /* Checksum. */
+       ignorable |= (1ULL << 0x32);
+       ignorable |= (1ULL << 0x33);
+       for (i = 0; i < len; i++, ignorable >>= 1) {
+               if ((ignorable & 1) || (s1[i] == s2[i]))
+                       continue;
+ #ifdef TILE_NET_DEBUG
+               /* HACK: Mention non-timestamp diffs. */
+               if (i < 0x38 && i != 0x2f &&
+                   net_ratelimit())
+                       pr_info("Diff at 0x%x\n", i);
+ #endif
+               return false;
+       }
+ #ifdef TILE_NET_NO_SUPPRESS_DUP_ACKS
+       /* HACK: Do not suppress truly duplicate ACKs. */
+       /* ISSUE: Is this actually necessary or helpful? */
+       if (s1[0x2a] == s2[0x2a] &&
+           s1[0x2b] == s2[0x2b] &&
+           s1[0x2c] == s2[0x2c] &&
+           s1[0x2d] == s2[0x2d]) {
+               return false;
+       }
+ #endif
+       return true;
+ }
+ #endif
+ static void tile_net_discard_aux(struct tile_net_cpu *info, int index)
+ {
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_impl_t *qsp = queue->__system_part;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+       int index2_aux = index + sizeof(netio_pkt_t);
+       int index2 =
+               ((index2_aux ==
+                 qsp->__packet_receive_queue.__last_packet_plus_one) ?
+                0 : index2_aux);
+       netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long) &qsp[1] + index);
+       /* Extract the "linux_buffer_t". */
+       unsigned int buffer = pkt->__packet.word;
+       /* Convert "linux_buffer_t" to "va". */
+       void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+       /* Acquire the associated "skb". */
+       struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+       struct sk_buff *skb = *skb_ptr;
+       kfree_skb(skb);
+       /* Consume this packet. */
+       qup->__packet_receive_read = index2;
+ }
+ /*
+  * Like "tile_net_poll()", but just discard packets.
+  */
+ static void tile_net_discard_packets(struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_impl_t *qsp = queue->__system_part;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+       while (qup->__packet_receive_read !=
+              qsp->__packet_receive_queue.__packet_write) {
+               int index = qup->__packet_receive_read;
+               tile_net_discard_aux(info, index);
+       }
+ }
+ /*
+  * Handle the next packet.  Return true if "processed", false if "filtered".
+  */
+ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)
+ {
+       struct net_device *dev = info->napi.dev;
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_impl_t *qsp = queue->__system_part;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+       struct tile_net_stats_t *stats = &info->stats;
+       int filter;
+       int index2_aux = index + sizeof(netio_pkt_t);
+       int index2 =
+               ((index2_aux ==
+                 qsp->__packet_receive_queue.__last_packet_plus_one) ?
+                0 : index2_aux);
+       netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long) &qsp[1] + index);
+       netio_pkt_metadata_t *metadata = NETIO_PKT_METADATA(pkt);
+       /* Extract the packet size.  FIXME: Shouldn't the second line */
+       /* get subtracted?  Mostly moot, since it should be "zero". */
+       unsigned long len =
+               (NETIO_PKT_CUSTOM_LENGTH(pkt) +
+                NET_IP_ALIGN - NETIO_PACKET_PADDING);
+       /* Extract the "linux_buffer_t". */
+       unsigned int buffer = pkt->__packet.word;
+       /* Extract "small" (vs "large"). */
+       bool small = ((buffer & 1) != 0);
+       /* Convert "linux_buffer_t" to "va". */
+       void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+       /* Extract the packet data pointer. */
+       /* Compare to "NETIO_PKT_CUSTOM_DATA(pkt)". */
+       unsigned char *buf = va + NET_IP_ALIGN;
+       /* Invalidate the packet buffer. */
+       if (!hash_default)
+               __inv_buffer(buf, len);
+       /* ISSUE: Is this needed? */
+       dev->last_rx = jiffies;
+ #ifdef TILE_NET_DUMP_PACKETS
+       dump_packet(buf, len, "rx");
+ #endif /* TILE_NET_DUMP_PACKETS */
+ #ifdef TILE_NET_VERIFY_INGRESS
+       if (!NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt) &&
+           NETIO_PKT_L4_CSUM_CALCULATED_M(metadata, pkt)) {
+               /* Bug 6624: Includes UDP packets with a "zero" checksum. */
+               pr_warning("Bad L4 checksum on %d byte packet.\n", len);
+       }
+       if (!NETIO_PKT_L3_CSUM_CORRECT_M(metadata, pkt) &&
+           NETIO_PKT_L3_CSUM_CALCULATED_M(metadata, pkt)) {
+               dump_packet(buf, len, "rx");
+               panic("Bad L3 checksum.");
+       }
+       switch (NETIO_PKT_STATUS_M(metadata, pkt)) {
+       case NETIO_PKT_STATUS_OVERSIZE:
+               if (len >= 64) {
+                       dump_packet(buf, len, "rx");
+                       panic("Unexpected OVERSIZE.");
+               }
+               break;
+       case NETIO_PKT_STATUS_BAD:
+               pr_warning("Unexpected BAD %ld byte packet.\n", len);
+       }
+ #endif
+       filter = 0;
+       /* ISSUE: Filter TCP packets with "bad" checksums? */
+       if (!(dev->flags & IFF_UP)) {
+               /* Filter packets received before we're up. */
+               filter = 1;
+       } else if (NETIO_PKT_STATUS_M(metadata, pkt) == NETIO_PKT_STATUS_BAD) {
+               /* Filter "truncated" packets. */
+               filter = 1;
+       } else if (!(dev->flags & IFF_PROMISC)) {
+               /* FIXME: Implement HW multicast filter. */
+               if (!is_multicast_ether_addr(buf)) {
+                       /* Filter packets not for our address. */
+                       const u8 *mine = dev->dev_addr;
+                       filter = compare_ether_addr(mine, buf);
+               }
+       }
+       if (filter) {
+               /* ISSUE: Update "drop" statistics? */
+               tile_net_provide_linux_buffer(info, va, small);
+       } else {
+               /* Acquire the associated "skb". */
+               struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+               struct sk_buff *skb = *skb_ptr;
+               /* Paranoia. */
+               if (skb->data != buf)
+                       panic("Corrupt linux buffer from LIPP! "
+                             "VA=%p, skb=%p, skb->data=%p\n",
+                             va, skb, skb->data);
+               /* Encode the actual packet length. */
+               skb_put(skb, len);
+               /* NOTE: This call also sets "skb->dev = dev". */
+               skb->protocol = eth_type_trans(skb, dev);
+               /* Avoid recomputing "good" TCP/UDP checksums. */
+               if (NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt))
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+               netif_receive_skb(skb);
+               stats->rx_packets++;
+               stats->rx_bytes += len;
+               if (small)
+                       info->num_needed_small_buffers++;
+               else
+                       info->num_needed_large_buffers++;
+       }
+       /* Return four credits after every fourth packet. */
+       if (--qup->__receive_credit_remaining == 0) {
+               u32 interval = qup->__receive_credit_interval;
+               qup->__receive_credit_remaining = interval;
+               __netio_fastio_return_credits(qup->__fastio_index, interval);
+       }
+       /* Consume this packet. */
+       qup->__packet_receive_read = index2;
+       return !filter;
+ }
+ /*
+  * Handle some packets for the given device on the current CPU.
+  *
+  * If "tile_net_stop()" is called on some other tile while this
+  * function is running, we will return, hopefully before that
+  * other tile asks us to call "napi_disable()".
+  *
+  * The "rotting packet" race condition occurs if a packet arrives
+  * during the extremely narrow window between the queue appearing to
+  * be empty, and the ingress interrupt being re-enabled.  This happens
+  * a LOT under heavy network load.
+  */
+ static int tile_net_poll(struct napi_struct *napi, int budget)
+ {
+       struct net_device *dev = napi->dev;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_netio_queue *queue = &info->queue;
+       netio_queue_impl_t *qsp = queue->__system_part;
+       netio_queue_user_impl_t *qup = &queue->__user_part;
+       unsigned int work = 0;
+       while (priv->active) {
+               int index = qup->__packet_receive_read;
+               if (index == qsp->__packet_receive_queue.__packet_write)
+                       break;
+               if (tile_net_poll_aux(info, index)) {
+                       if (++work >= budget)
+                               goto done;
+               }
+       }
+       napi_complete(&info->napi);
+       if (!priv->active)
+               goto done;
+       /* Re-enable the ingress interrupt. */
+       enable_percpu_irq(priv->intr_id);
+       /* HACK: Avoid the "rotting packet" problem (see above). */
+       if (qup->__packet_receive_read !=
+           qsp->__packet_receive_queue.__packet_write) {
+               /* ISSUE: Sometimes this returns zero, presumably */
+               /* because an interrupt was handled for this tile. */
+               (void)napi_reschedule(&info->napi);
+       }
+ done:
+       if (priv->active)
+               tile_net_provide_needed_buffers(info);
+       return work;
+ }
+ /*
+  * Handle an ingress interrupt for the given device on the current cpu.
+  *
+  * ISSUE: Sometimes this gets called after "disable_percpu_irq()" has
+  * been called!  This is probably due to "pending hypervisor downcalls".
+  *
+  * ISSUE: Is there any race condition between the "napi_schedule()" here
+  * and the "napi_complete()" call above?
+  */
+ static irqreturn_t tile_net_handle_ingress_interrupt(int irq, void *dev_ptr)
+ {
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       /* Disable the ingress interrupt. */
+       disable_percpu_irq(priv->intr_id);
+       /* Ignore unwanted interrupts. */
+       if (!priv->active)
+               return IRQ_HANDLED;
+       /* ISSUE: Sometimes "info->napi_enabled" is false here. */
+       napi_schedule(&info->napi);
+       return IRQ_HANDLED;
+ }
+ /*
+  * One time initialization per interface.
+  */
+ static int tile_net_open_aux(struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int ret;
+       int dummy;
+       unsigned int epp_lotar;
+       /*
+        * Find out where EPP memory should be homed.
+        */
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)&epp_lotar, sizeof(epp_lotar),
+                          NETIO_EPP_SHM_OFF);
+       if (ret < 0) {
+               pr_err("could not read epp_shm_queue lotar.\n");
+               return -EIO;
+       }
+       /*
+        * Home the page on the EPP.
+        */
+       {
+               int epp_home = hv_lotar_to_cpu(epp_lotar);
+               homecache_change_page_home(priv->eq_pages, EQ_ORDER, epp_home);
+       }
+       /*
+        * Register the EPP shared memory queue.
+        */
+       {
+               netio_ipp_address_t ea = {
+                       .va = 0,
+                       .pa = __pa(priv->eq),
+                       .pte = hv_pte(0),
+                       .size = EQ_SIZE,
+               };
+               ea.pte = hv_pte_set_lotar(ea.pte, epp_lotar);
+               ea.pte = hv_pte_set_mode(ea.pte, HV_PTE_MODE_CACHE_TILE_L3);
+               ret = hv_dev_pwrite(priv->hv_devhdl, 0,
+                                   (HV_VirtAddr)&ea,
+                                   sizeof(ea),
+                                   NETIO_EPP_SHM_OFF);
+               if (ret < 0)
+                       return -EIO;
+       }
+       /*
+        * Start LIPP/LEPP.
+        */
+       if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                         sizeof(dummy), NETIO_IPP_START_SHIM_OFF) < 0) {
+               pr_warning("Failed to start LIPP/LEPP.\n");
+               return -EIO;
+       }
+       return 0;
+ }
+ /*
+  * Register with hypervisor on the current CPU.
+  *
+  * Strangely, this function does important things even if it "fails",
+  * which is especially common if the link is not up yet.  Hopefully
+  * these things are all "harmless" if done twice!
+  */
+ static void tile_net_register(void *dev_ptr)
+ {
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info;
+       struct tile_netio_queue *queue;
+       /* Only network cpus can receive packets. */
+       int queue_id =
+               cpumask_test_cpu(my_cpu, &priv->network_cpus_map) ? 0 : 255;
+       netio_input_config_t config = {
+               .flags = 0,
+               .num_receive_packets = priv->network_cpus_credits,
+               .queue_id = queue_id
+       };
+       int ret = 0;
+       netio_queue_impl_t *queuep;
+       PDEBUG("tile_net_register(queue_id %d)\n", queue_id);
+       if (!strcmp(dev->name, "xgbe0"))
+               info = &__get_cpu_var(hv_xgbe0);
+       else if (!strcmp(dev->name, "xgbe1"))
+               info = &__get_cpu_var(hv_xgbe1);
+       else if (!strcmp(dev->name, "gbe0"))
+               info = &__get_cpu_var(hv_gbe0);
+       else if (!strcmp(dev->name, "gbe1"))
+               info = &__get_cpu_var(hv_gbe1);
+       else
+               BUG();
+       /* Initialize the egress timer. */
+       init_timer(&info->egress_timer);
+       info->egress_timer.data = (long)info;
+       info->egress_timer.function = tile_net_handle_egress_timer;
+       priv->cpu[my_cpu] = info;
+       /*
+        * Register ourselves with LIPP.  This does a lot of stuff,
+        * including invoking the LIPP registration code.
+        */
+       ret = hv_dev_pwrite(priv->hv_devhdl, 0,
+                           (HV_VirtAddr)&config,
+                           sizeof(netio_input_config_t),
+                           NETIO_IPP_INPUT_REGISTER_OFF);
+       PDEBUG("hv_dev_pwrite(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n",
+              ret);
+       if (ret < 0) {
+               if (ret != NETIO_LINK_DOWN) {
+                       printk(KERN_DEBUG "hv_dev_pwrite "
+                              "NETIO_IPP_INPUT_REGISTER_OFF failure %d\n",
+                              ret);
+               }
+               info->link_down = (ret == NETIO_LINK_DOWN);
+               return;
+       }
+       /*
+        * Get the pointer to our queue's system part.
+        */
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)&queuep,
+                          sizeof(netio_queue_impl_t *),
+                          NETIO_IPP_INPUT_REGISTER_OFF);
+       PDEBUG("hv_dev_pread(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n",
+              ret);
+       PDEBUG("queuep %p\n", queuep);
+       if (ret <= 0) {
+               /* ISSUE: Shouldn't this be a fatal error? */
+               pr_err("hv_dev_pread NETIO_IPP_INPUT_REGISTER_OFF failure\n");
+               return;
+       }
+       queue = &info->queue;
+       queue->__system_part = queuep;
+       memset(&queue->__user_part, 0, sizeof(netio_queue_user_impl_t));
+       /* This is traditionally "config.num_receive_packets / 2". */
+       queue->__user_part.__receive_credit_interval = 4;
+       queue->__user_part.__receive_credit_remaining =
+               queue->__user_part.__receive_credit_interval;
+       /*
+        * Get a fastio index from the hypervisor.
+        * ISSUE: Shouldn't this check the result?
+        */
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)&queue->__user_part.__fastio_index,
+                          sizeof(queue->__user_part.__fastio_index),
+                          NETIO_IPP_GET_FASTIO_OFF);
+       PDEBUG("hv_dev_pread(NETIO_IPP_GET_FASTIO_OFF) returned %d\n", ret);
+       /* Now we are registered. */
+       info->registered = true;
+ }
+ /*
+  * Deregister with hypervisor on the current CPU.
+  *
+  * This simply discards all our credits, so no more packets will be
+  * delivered to this tile.  There may still be packets in our queue.
+  *
+  * Also, disable the ingress interrupt.
+  */
+ static void tile_net_deregister(void *dev_ptr)
+ {
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       /* Disable the ingress interrupt. */
+       disable_percpu_irq(priv->intr_id);
+       /* Do nothing else if not registered. */
+       if (info == NULL || !info->registered)
+               return;
+       {
+               struct tile_netio_queue *queue = &info->queue;
+               netio_queue_user_impl_t *qup = &queue->__user_part;
+               /* Discard all our credits. */
+               __netio_fastio_return_credits(qup->__fastio_index, -1);
+       }
+ }
+ /*
+  * Unregister with hypervisor on the current CPU.
+  *
+  * Also, disable the ingress interrupt.
+  */
+ static void tile_net_unregister(void *dev_ptr)
+ {
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       int ret;
+       int dummy = 0;
+       /* Disable the ingress interrupt. */
+       disable_percpu_irq(priv->intr_id);
+       /* Do nothing else if not registered. */
+       if (info == NULL || !info->registered)
+               return;
+       /* Unregister ourselves with LIPP/LEPP. */
+       ret = hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                           sizeof(dummy), NETIO_IPP_INPUT_UNREGISTER_OFF);
+       if (ret < 0)
+               panic("Failed to unregister with LIPP/LEPP!\n");
+       /* Discard all packets still in our NetIO queue. */
+       tile_net_discard_packets(dev);
+       /* Reset state. */
+       info->num_needed_small_buffers = 0;
+       info->num_needed_large_buffers = 0;
+       /* Cancel egress timer. */
+       del_timer(&info->egress_timer);
+       info->egress_timer_scheduled = false;
+ }
+ /*
+  * Helper function for "tile_net_stop()".
+  *
+  * Also used to handle registration failure in "tile_net_open_inner()",
+  * when the various extra steps in "tile_net_stop()" are not necessary.
+  */
+ static void tile_net_stop_aux(struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int i;
+       int dummy = 0;
+       /*
+        * Unregister all tiles, so LIPP will stop delivering packets.
+        * Also, delete all the "napi" objects (sequentially, to protect
+        * "dev->napi_list").
+        */
+       on_each_cpu(tile_net_unregister, (void *)dev, 1);
+       for_each_online_cpu(i) {
+               struct tile_net_cpu *info = priv->cpu[i];
+               if (info != NULL && info->registered) {
+                       netif_napi_del(&info->napi);
+                       info->registered = false;
+               }
+       }
+       /* Stop LIPP/LEPP. */
+       if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                         sizeof(dummy), NETIO_IPP_STOP_SHIM_OFF) < 0)
+               panic("Failed to stop LIPP/LEPP!\n");
+       priv->partly_opened = 0;
+ }
+ /*
+  * Disable NAPI for the given device on the current cpu.
+  */
+ static void tile_net_stop_disable(void *dev_ptr)
+ {
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       /* Disable NAPI if needed. */
+       if (info != NULL && info->napi_enabled) {
+               napi_disable(&info->napi);
+               info->napi_enabled = false;
+       }
+ }
+ /*
+  * Enable NAPI and the ingress interrupt for the given device
+  * on the current cpu.
+  *
+  * ISSUE: Only do this for "network cpus"?
+  */
+ static void tile_net_open_enable(void *dev_ptr)
+ {
+       struct net_device *dev = (struct net_device *)dev_ptr;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       /* Enable NAPI. */
+       napi_enable(&info->napi);
+       info->napi_enabled = true;
+       /* Enable the ingress interrupt. */
+       enable_percpu_irq(priv->intr_id);
+ }
+ /*
+  * tile_net_open_inner does most of the work of bringing up the interface.
+  * It's called from tile_net_open(), and also from tile_net_retry_open().
+  * The return value is 0 if the interface was brought up, < 0 if
+  * tile_net_open() should return the return value as an error, and > 0 if
+  * tile_net_open() should return success and schedule a work item to
+  * periodically retry the bringup.
+  */
+ static int tile_net_open_inner(struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info;
+       struct tile_netio_queue *queue;
+       int result = 0;
+       int i;
+       int dummy = 0;
+       /*
+        * First try to register just on the local CPU, and handle any
+        * semi-expected "link down" failure specially.  Note that we
+        * do NOT call "tile_net_stop_aux()", unlike below.
+        */
+       tile_net_register(dev);
+       info = priv->cpu[my_cpu];
+       if (!info->registered) {
+               if (info->link_down)
+                       return 1;
+               return -EAGAIN;
+       }
+       /*
+        * Now register everywhere else.  If any registration fails,
+        * even for "link down" (which might not be possible), we
+        * clean up using "tile_net_stop_aux()".  Also, add all the
+        * "napi" objects (sequentially, to protect "dev->napi_list").
+        * ISSUE: Only use "netif_napi_add()" for "network cpus"?
+        */
+       smp_call_function(tile_net_register, (void *)dev, 1);
+       for_each_online_cpu(i) {
+               struct tile_net_cpu *info = priv->cpu[i];
+               if (info->registered)
+                       netif_napi_add(dev, &info->napi, tile_net_poll, 64);
+               else
+                       result = -EAGAIN;
+       }
+       if (result != 0) {
+               tile_net_stop_aux(dev);
+               return result;
+       }
+       queue = &info->queue;
+       if (priv->intr_id == 0) {
+               unsigned int irq;
+               /*
+                * Acquire the irq allocated by the hypervisor.  Every
+                * queue gets the same irq.  The "__intr_id" field is
+                * "1 << irq", so we use "__ffs()" to extract "irq".
+                */
+               priv->intr_id = queue->__system_part->__intr_id;
+               BUG_ON(priv->intr_id == 0);
+               irq = __ffs(priv->intr_id);
+               /*
+                * Register the ingress interrupt handler for this
+                * device, permanently.
+                *
+                * We used to call "free_irq()" in "tile_net_stop()",
+                * and then re-register the handler here every time,
+                * but that caused DNP errors in "handle_IRQ_event()"
+                * because "desc->action" was NULL.  See bug 9143.
+                */
+               tile_irq_activate(irq, TILE_IRQ_PERCPU);
+               BUG_ON(request_irq(irq, tile_net_handle_ingress_interrupt,
+                                  0, dev->name, (void *)dev) != 0);
+       }
+       {
+               /* Allocate initial buffers. */
+               int max_buffers =
+                       priv->network_cpus_count * priv->network_cpus_credits;
+               info->num_needed_small_buffers =
+                       min(LIPP_SMALL_BUFFERS, max_buffers);
+               info->num_needed_large_buffers =
+                       min(LIPP_LARGE_BUFFERS, max_buffers);
+               tile_net_provide_needed_buffers(info);
+               if (info->num_needed_small_buffers != 0 ||
+                   info->num_needed_large_buffers != 0)
+                       panic("Insufficient memory for buffer stack!");
+       }
+       /* We are about to be active. */
+       priv->active = true;
+       /* Make sure "active" is visible to all tiles. */
+       mb();
+       /* On each tile, enable NAPI and the ingress interrupt. */
+       on_each_cpu(tile_net_open_enable, (void *)dev, 1);
+       /* Start LIPP/LEPP and activate "ingress" at the shim. */
+       if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+                         sizeof(dummy), NETIO_IPP_INPUT_INIT_OFF) < 0)
+               panic("Failed to activate the LIPP Shim!\n");
+       /* Start our transmit queue. */
+       netif_start_queue(dev);
+       return 0;
+ }
+ /*
+  * Called periodically to retry bringing up the NetIO interface,
+  * if it doesn't come up cleanly during tile_net_open().
+  */
+ static void tile_net_open_retry(struct work_struct *w)
+ {
+       struct delayed_work *dw =
+               container_of(w, struct delayed_work, work);
+       struct tile_net_priv *priv =
+               container_of(dw, struct tile_net_priv, retry_work);
+       /*
+        * Try to bring the NetIO interface up.  If it fails, reschedule
+        * ourselves to try again later; otherwise, tell Linux we now have
+        * a working link.  ISSUE: What if the return value is negative?
+        */
+       if (tile_net_open_inner(priv->dev) != 0)
+               schedule_delayed_work(&priv->retry_work,
+                                     TILE_NET_RETRY_INTERVAL);
+       else
+               netif_carrier_on(priv->dev);
+ }
+ /*
+  * Called when a network interface is made active.
+  *
+  * 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 (if needed), the watchdog timer
+  * is started, and the stack is notified that the interface is ready.
+  *
+  * If the actual link is not available yet, then we tell Linux that
+  * we have no carrier, and we keep checking until the link comes up.
+  */
+ static int tile_net_open(struct net_device *dev)
+ {
+       int ret = 0;
+       struct tile_net_priv *priv = netdev_priv(dev);
+       /*
+        * We rely on priv->partly_opened to tell us if this is the
+        * first time this interface is being brought up. If it is
+        * set, the IPP was already initialized and should not be
+        * initialized again.
+        */
+       if (!priv->partly_opened) {
+               int count;
+               int credits;
+               /* Initialize LIPP/LEPP, and start the Shim. */
+               ret = tile_net_open_aux(dev);
+               if (ret < 0) {
+                       pr_err("tile_net_open_aux failed: %d\n", ret);
+                       return ret;
+               }
+               /* Analyze the network cpus. */
+               if (network_cpus_used)
+                       cpumask_copy(&priv->network_cpus_map,
+                                    &network_cpus_map);
+               else
+                       cpumask_copy(&priv->network_cpus_map, cpu_online_mask);
+               count = cpumask_weight(&priv->network_cpus_map);
+               /* Limit credits to available buffers, and apply min. */
+               credits = max(16, (LIPP_LARGE_BUFFERS / count) & ~1);
+               /* Apply "GBE" max limit. */
+               /* ISSUE: Use higher limit for XGBE? */
+               credits = min(NETIO_MAX_RECEIVE_PKTS, credits);
+               priv->network_cpus_count = count;
+               priv->network_cpus_credits = credits;
+ #ifdef TILE_NET_DEBUG
+               pr_info("Using %d network cpus, with %d credits each\n",
+                      priv->network_cpus_count, priv->network_cpus_credits);
+ #endif
+               priv->partly_opened = 1;
+       } else {
+               /* FIXME: Is this possible? */
+               /* printk("Already partly opened.\n"); */
+       }
+       /*
+        * Attempt to bring up the link.
+        */
+       ret = tile_net_open_inner(dev);
+       if (ret <= 0) {
+               if (ret == 0)
+                       netif_carrier_on(dev);
+               return ret;
+       }
+       /*
+        * We were unable to bring up the NetIO interface, but we want to
+        * try again in a little bit.  Tell Linux that we have no carrier
+        * so it doesn't try to use the interface before the link comes up
+        * and then remember to try again later.
+        */
+       netif_carrier_off(dev);
+       schedule_delayed_work(&priv->retry_work, TILE_NET_RETRY_INTERVAL);
+       return 0;
+ }
+ static int tile_net_drain_lipp_buffers(struct tile_net_priv *priv)
+ {
+       int n = 0;
+       /* Drain all the LIPP buffers. */
+       while (true) {
+               int buffer;
+               /* NOTE: This should never fail. */
+               if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&buffer,
+                                sizeof(buffer), NETIO_IPP_DRAIN_OFF) < 0)
+                       break;
+               /* Stop when done. */
+               if (buffer == 0)
+                       break;
+               {
+                       /* Convert "linux_buffer_t" to "va". */
+                       void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+                       /* Acquire the associated "skb". */
+                       struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+                       struct sk_buff *skb = *skb_ptr;
+                       kfree_skb(skb);
+               }
+               n++;
+       }
+       return n;
+ }
+ /*
+  * Disables a network interface.
+  *
+  * 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.
+  *
+  * ISSUE: How closely does "netif_running(dev)" mirror "priv->active"?
+  *
+  * Before we are called by "__dev_close()", "netif_running()" will
+  * have been cleared, so no NEW calls to "tile_net_poll()" will be
+  * made by "netpoll_poll_dev()".
+  *
+  * Often, this can cause some tiles to still have packets in their
+  * queues, so we must call "tile_net_discard_packets()" later.
+  *
+  * Note that some other tile may still be INSIDE "tile_net_poll()",
+  * and in fact, many will be, if there is heavy network load.
+  *
+  * Calling "on_each_cpu(tile_net_stop_disable, (void *)dev, 1)" when
+  * any tile is still "napi_schedule()"'d will induce a horrible crash
+  * when "msleep()" is called.  This includes tiles which are inside
+  * "tile_net_poll()" which have not yet called "napi_complete()".
+  *
+  * So, we must first try to wait long enough for other tiles to finish
+  * with any current "tile_net_poll()" call, and, hopefully, to clear
+  * the "scheduled" flag.  ISSUE: It is unclear what happens to tiles
+  * which have called "napi_schedule()" but which had not yet tried to
+  * call "tile_net_poll()", or which exhausted their budget inside
+  * "tile_net_poll()" just before this function was called.
+  */
+ static int tile_net_stop(struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       PDEBUG("tile_net_stop()\n");
+       /* Start discarding packets. */
+       priv->active = false;
+       /* Make sure "active" is visible to all tiles. */
+       mb();
+       /*
+        * On each tile, make sure no NEW packets get delivered, and
+        * disable the ingress interrupt.
+        *
+        * Note that the ingress interrupt can fire AFTER this,
+        * presumably due to packets which were recently delivered,
+        * but it will have no effect.
+        */
+       on_each_cpu(tile_net_deregister, (void *)dev, 1);
+       /* Optimistically drain LIPP buffers. */
+       (void)tile_net_drain_lipp_buffers(priv);
+       /* ISSUE: Only needed if not yet fully open. */
+       cancel_delayed_work_sync(&priv->retry_work);
+       /* Can't transmit any more. */
+       netif_stop_queue(dev);
+       /* Disable NAPI on each tile. */
+       on_each_cpu(tile_net_stop_disable, (void *)dev, 1);
+       /*
+        * Drain any remaining LIPP buffers.  NOTE: This "printk()"
+        * has never been observed, but in theory it could happen.
+        */
+       if (tile_net_drain_lipp_buffers(priv) != 0)
+               printk("Had to drain some extra LIPP buffers!\n");
+       /* Stop LIPP/LEPP. */
+       tile_net_stop_aux(dev);
+       /*
+        * ISSUE: It appears that, in practice anyway, by the time we
+        * get here, there are no pending completions, but just in case,
+        * we free (all of) them anyway.
+        */
+       while (tile_net_lepp_free_comps(dev, true))
+               /* loop */;
+       /* Wipe the EPP queue, and wait till the stores hit the EPP. */
+       memset(priv->eq, 0, sizeof(lepp_queue_t));
+       mb();
+       return 0;
+ }
+ /*
+  * Prepare the "frags" info for the resulting LEPP command.
+  *
+  * If needed, flush the memory used by the frags.
+  */
+ static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
+                                     struct sk_buff *skb,
+                                     void *b_data, unsigned int b_len)
+ {
+       unsigned int i, n = 0;
+       struct skb_shared_info *sh = skb_shinfo(skb);
+       phys_addr_t cpa;
+       if (b_len != 0) {
+               if (!hash_default)
+                       finv_buffer_remote(b_data, b_len, 0);
+               cpa = __pa(b_data);
+               frags[n].cpa_lo = cpa;
+               frags[n].cpa_hi = cpa >> 32;
+               frags[n].length = b_len;
+               frags[n].hash_for_home = hash_default;
+               n++;
+       }
+       for (i = 0; i < sh->nr_frags; i++) {
+               skb_frag_t *f = &sh->frags[i];
+               unsigned long pfn = page_to_pfn(f->page);
+               /* FIXME: Compute "hash_for_home" properly. */
+               /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */
+               int hash_for_home = hash_default;
+               /* FIXME: Hmmm. */
+               if (!hash_default) {
+                       void *va = pfn_to_kaddr(pfn) + f->page_offset;
+                       BUG_ON(PageHighMem(f->page));
+                       finv_buffer_remote(va, f->size, 0);
+               }
+               cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset;
+               frags[n].cpa_lo = cpa;
+               frags[n].cpa_hi = cpa >> 32;
+               frags[n].length = skb_frag_size(f);
+               frags[n].hash_for_home = hash_for_home;
+               n++;
+       }
+       return n;
+ }
+ /*
+  * This function takes "skb", consisting of a header template and a
+  * payload, and hands it to LEPP, to emit as one or more segments,
+  * each consisting of a possibly modified header, plus a piece of the
+  * payload, via a process known as "tcp segmentation offload".
+  *
+  * Usually, "data" will contain the header template, of size "sh_len",
+  * and "sh->frags" will contain "skb->data_len" bytes of payload, and
+  * there will be "sh->gso_segs" segments.
+  *
+  * Sometimes, if "sendfile()" requires copying, we will be called with
+  * "data" containing the header and payload, with "frags" being empty.
+  *
+  * In theory, "sh->nr_frags" could be 3, but in practice, it seems
+  * that this will never actually happen.
+  *
+  * See "emulate_large_send_offload()" for some reference code, which
+  * does not handle checksumming.
+  *
+  * ISSUE: How do we make sure that high memory DMA does not migrate?
+  */
+ static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_net_stats_t *stats = &info->stats;
+       struct skb_shared_info *sh = skb_shinfo(skb);
+       unsigned char *data = skb->data;
+       /* The ip header follows the ethernet header. */
+       struct iphdr *ih = ip_hdr(skb);
+       unsigned int ih_len = ih->ihl * 4;
+       /* Note that "nh == ih", by definition. */
+       unsigned char *nh = skb_network_header(skb);
+       unsigned int eh_len = nh - data;
+       /* The tcp header follows the ip header. */
+       struct tcphdr *th = (struct tcphdr *)(nh + ih_len);
+       unsigned int th_len = th->doff * 4;
+       /* The total number of header bytes. */
+       /* NOTE: This may be less than skb_headlen(skb). */
+       unsigned int sh_len = eh_len + ih_len + th_len;
+       /* The number of payload bytes at "skb->data + sh_len". */
+       /* This is non-zero for sendfile() without HIGHDMA. */
+       unsigned int b_len = skb_headlen(skb) - sh_len;
+       /* The total number of payload bytes. */
+       unsigned int d_len = b_len + skb->data_len;
+       /* The maximum payload size. */
+       unsigned int p_len = sh->gso_size;
+       /* The total number of segments. */
+       unsigned int num_segs = sh->gso_segs;
+       /* The temporary copy of the command. */
+       u32 cmd_body[(LEPP_MAX_CMD_SIZE + 3) / 4];
+       lepp_tso_cmd_t *cmd = (lepp_tso_cmd_t *)cmd_body;
+       /* Analyze the "frags". */
+       unsigned int num_frags =
+               tile_net_tx_frags(cmd->frags, skb, data + sh_len, b_len);
+       /* The size of the command, including frags and header. */
+       size_t cmd_size = LEPP_TSO_CMD_SIZE(num_frags, sh_len);
+       /* The command header. */
+       lepp_tso_cmd_t cmd_init = {
+               .tso = true,
+               .header_size = sh_len,
+               .ip_offset = eh_len,
+               .tcp_offset = eh_len + ih_len,
+               .payload_size = p_len,
+               .num_frags = num_frags,
+       };
+       unsigned long irqflags;
+       lepp_queue_t *eq = priv->eq;
+       struct sk_buff *olds[8];
+       unsigned int wanted = 8;
+       unsigned int i, nolds = 0;
+       unsigned int cmd_head, cmd_tail, cmd_next;
+       unsigned int comp_tail;
+       /* Paranoia. */
+       BUG_ON(skb->protocol != htons(ETH_P_IP));
+       BUG_ON(ih->protocol != IPPROTO_TCP);
+       BUG_ON(skb->ip_summed != CHECKSUM_PARTIAL);
+       BUG_ON(num_frags > LEPP_MAX_FRAGS);
+       /*--BUG_ON(num_segs != (d_len + (p_len - 1)) / p_len); */
+       BUG_ON(num_segs <= 1);
+       /* Finish preparing the command. */
+       /* Copy the command header. */
+       *cmd = cmd_init;
+       /* Copy the "header". */
+       memcpy(&cmd->frags[num_frags], data, sh_len);
+       /* Prefetch and wait, to minimize time spent holding the spinlock. */
+       prefetch_L1(&eq->comp_tail);
+       prefetch_L1(&eq->cmd_tail);
+       mb();
+       /* Enqueue the command. */
+       spin_lock_irqsave(&priv->eq_lock, irqflags);
+       /*
+        * Handle completions if needed to make room.
+        * HACK: Spin until there is sufficient room.
+        */
+       if (lepp_num_free_comp_slots(eq) == 0) {
+               nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0);
+               if (nolds == 0) {
+ busy:
+                       spin_unlock_irqrestore(&priv->eq_lock, irqflags);
+                       return NETDEV_TX_BUSY;
+               }
+       }
+       cmd_head = eq->cmd_head;
+       cmd_tail = eq->cmd_tail;
+       /* Prepare to advance, detecting full queue. */
+       cmd_next = cmd_tail + cmd_size;
+       if (cmd_tail < cmd_head && cmd_next >= cmd_head)
+               goto busy;
+       if (cmd_next > LEPP_CMD_LIMIT) {
+               cmd_next = 0;
+               if (cmd_next == cmd_head)
+                       goto busy;
+       }
+       /* Copy the command. */
+       memcpy(&eq->cmds[cmd_tail], cmd, cmd_size);
+       /* Advance. */
+       cmd_tail = cmd_next;
+       /* Record "skb" for eventual freeing. */
+       comp_tail = eq->comp_tail;
+       eq->comps[comp_tail] = skb;
+       LEPP_QINC(comp_tail);
+       eq->comp_tail = comp_tail;
+       /* Flush before allowing LEPP to handle the command. */
+       /* ISSUE: Is this the optimal location for the flush? */
+       __insn_mf();
+       eq->cmd_tail = cmd_tail;
+       /* NOTE: Using "4" here is more efficient than "0" or "2", */
+       /* and, strangely, more efficient than pre-checking the number */
+       /* of available completions, and comparing it to 4. */
+       if (nolds == 0)
+               nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 4);
+       spin_unlock_irqrestore(&priv->eq_lock, irqflags);
+       /* Handle completions. */
+       for (i = 0; i < nolds; i++)
+               kfree_skb(olds[i]);
+       /* Update stats. */
+       stats->tx_packets += num_segs;
+       stats->tx_bytes += (num_segs * sh_len) + d_len;
+       /* Make sure the egress timer is scheduled. */
+       tile_net_schedule_egress_timer(info);
+       return NETDEV_TX_OK;
+ }
+ /*
+  * Transmit a packet (called by the kernel via "hard_start_xmit" hook).
+  */
+ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       int my_cpu = smp_processor_id();
+       struct tile_net_cpu *info = priv->cpu[my_cpu];
+       struct tile_net_stats_t *stats = &info->stats;
+       unsigned long irqflags;
+       struct skb_shared_info *sh = skb_shinfo(skb);
+       unsigned int len = skb->len;
+       unsigned char *data = skb->data;
+       unsigned int csum_start = skb_checksum_start_offset(skb);
+       lepp_frag_t frags[LEPP_MAX_FRAGS];
+       unsigned int num_frags;
+       lepp_queue_t *eq = priv->eq;
+       struct sk_buff *olds[8];
+       unsigned int wanted = 8;
+       unsigned int i, nolds = 0;
+       unsigned int cmd_size = sizeof(lepp_cmd_t);
+       unsigned int cmd_head, cmd_tail, cmd_next;
+       unsigned int comp_tail;
+       lepp_cmd_t cmds[LEPP_MAX_FRAGS];
+       /*
+        * This is paranoia, since we think that if the link doesn't come
+        * up, telling Linux we have no carrier will keep it from trying
+        * to transmit.  If it does, though, we can't execute this routine,
+        * since data structures we depend on aren't set up yet.
+        */
+       if (!info->registered)
+               return NETDEV_TX_BUSY;
+       /* Save the timestamp. */
+       dev->trans_start = jiffies;
+ #ifdef TILE_NET_PARANOIA
+ #if CHIP_HAS_CBOX_HOME_MAP()
+       if (hash_default) {
+               HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)data);
+               if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3)
+                       panic("Non-HFH egress buffer! VA=%p Mode=%d PTE=%llx",
+                             data, hv_pte_get_mode(pte), hv_pte_val(pte));
+       }
+ #endif
+ #endif
+ #ifdef TILE_NET_DUMP_PACKETS
+       /* ISSUE: Does not dump the "frags". */
+       dump_packet(data, skb_headlen(skb), "tx");
+ #endif /* TILE_NET_DUMP_PACKETS */
+       if (sh->gso_size != 0)
+               return tile_net_tx_tso(skb, dev);
+       /* Prepare the commands. */
+       num_frags = tile_net_tx_frags(frags, skb, data, skb_headlen(skb));
+       for (i = 0; i < num_frags; i++) {
+               bool final = (i == num_frags - 1);
+               lepp_cmd_t cmd = {
+                       .cpa_lo = frags[i].cpa_lo,
+                       .cpa_hi = frags[i].cpa_hi,
+                       .length = frags[i].length,
+                       .hash_for_home = frags[i].hash_for_home,
+                       .send_completion = final,
+                       .end_of_packet = final
+               };
+               if (i == 0 && skb->ip_summed == CHECKSUM_PARTIAL) {
+                       cmd.compute_checksum = 1;
+                       cmd.checksum_data.bits.start_byte = csum_start;
+                       cmd.checksum_data.bits.count = len - csum_start;
+                       cmd.checksum_data.bits.destination_byte =
+                               csum_start + skb->csum_offset;
+               }
+               cmds[i] = cmd;
+       }
+       /* Prefetch and wait, to minimize time spent holding the spinlock. */
+       prefetch_L1(&eq->comp_tail);
+       prefetch_L1(&eq->cmd_tail);
+       mb();
+       /* Enqueue the commands. */
+       spin_lock_irqsave(&priv->eq_lock, irqflags);
+       /*
+        * Handle completions if needed to make room.
+        * HACK: Spin until there is sufficient room.
+        */
+       if (lepp_num_free_comp_slots(eq) == 0) {
+               nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0);
+               if (nolds == 0) {
+ busy:
+                       spin_unlock_irqrestore(&priv->eq_lock, irqflags);
+                       return NETDEV_TX_BUSY;
+               }
+       }
+       cmd_head = eq->cmd_head;
+       cmd_tail = eq->cmd_tail;
+       /* Copy the commands, or fail. */
+       for (i = 0; i < num_frags; i++) {
+               /* Prepare to advance, detecting full queue. */
+               cmd_next = cmd_tail + cmd_size;
+               if (cmd_tail < cmd_head && cmd_next >= cmd_head)
+                       goto busy;
+               if (cmd_next > LEPP_CMD_LIMIT) {
+                       cmd_next = 0;
+                       if (cmd_next == cmd_head)
+                               goto busy;
+               }
+               /* Copy the command. */
+               *(lepp_cmd_t *)&eq->cmds[cmd_tail] = cmds[i];
+               /* Advance. */
+               cmd_tail = cmd_next;
+       }
+       /* Record "skb" for eventual freeing. */
+       comp_tail = eq->comp_tail;
+       eq->comps[comp_tail] = skb;
+       LEPP_QINC(comp_tail);
+       eq->comp_tail = comp_tail;
+       /* Flush before allowing LEPP to handle the command. */
+       /* ISSUE: Is this the optimal location for the flush? */
+       __insn_mf();
+       eq->cmd_tail = cmd_tail;
+       /* NOTE: Using "4" here is more efficient than "0" or "2", */
+       /* and, strangely, more efficient than pre-checking the number */
+       /* of available completions, and comparing it to 4. */
+       if (nolds == 0)
+               nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 4);
+       spin_unlock_irqrestore(&priv->eq_lock, irqflags);
+       /* Handle completions. */
+       for (i = 0; i < nolds; i++)
+               kfree_skb(olds[i]);
+       /* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */
+       stats->tx_packets++;
+       stats->tx_bytes += ((len >= ETH_ZLEN) ? len : ETH_ZLEN);
+       /* Make sure the egress timer is scheduled. */
+       tile_net_schedule_egress_timer(info);
+       return NETDEV_TX_OK;
+ }
+ /*
+  * Deal with a transmit timeout.
+  */
+ static void tile_net_tx_timeout(struct net_device *dev)
+ {
+       PDEBUG("tile_net_tx_timeout()\n");
+       PDEBUG("Transmit timeout at %ld, latency %ld\n", jiffies,
+              jiffies - dev->trans_start);
+       /* XXX: ISSUE: This doesn't seem useful for us. */
+       netif_wake_queue(dev);
+ }
+ /*
+  * Ioctl commands.
+  */
+ static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+       return -EOPNOTSUPP;
+ }
+ /*
+  * Get System Network Statistics.
+  *
+  * Returns the address of the device statistics structure.
+  */
+ static struct net_device_stats *tile_net_get_stats(struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       u32 rx_packets = 0;
+       u32 tx_packets = 0;
+       u32 rx_bytes = 0;
+       u32 tx_bytes = 0;
+       int i;
+       for_each_online_cpu(i) {
+               if (priv->cpu[i]) {
+                       rx_packets += priv->cpu[i]->stats.rx_packets;
+                       rx_bytes += priv->cpu[i]->stats.rx_bytes;
+                       tx_packets += priv->cpu[i]->stats.tx_packets;
+                       tx_bytes += priv->cpu[i]->stats.tx_bytes;
+               }
+       }
+       priv->stats.rx_packets = rx_packets;
+       priv->stats.rx_bytes = rx_bytes;
+       priv->stats.tx_packets = tx_packets;
+       priv->stats.tx_bytes = tx_bytes;
+       return &priv->stats;
+ }
+ /*
+  * Change the "mtu".
+  *
+  * The "change_mtu" method is usually not needed.
+  * If you need it, it must be like this.
+  */
+ static int tile_net_change_mtu(struct net_device *dev, int new_mtu)
+ {
+       PDEBUG("tile_net_change_mtu()\n");
+       /* Check ranges. */
+       if ((new_mtu < 68) || (new_mtu > 1500))
+               return -EINVAL;
+       /* Accept the value. */
+       dev->mtu = new_mtu;
+       return 0;
+ }
+ /*
+  * Change the Ethernet Address of the NIC.
+  *
+  * The hypervisor driver does not support changing MAC address.  However,
+  * the IPP does not do anything with the MAC address, so the address which
+  * gets used on outgoing packets, and which is accepted on incoming packets,
+  * is completely up to the NetIO program or kernel driver which is actually
+  * handling them.
+  *
+  * Returns 0 on success, negative on failure.
+  */
+ static int tile_net_set_mac_address(struct net_device *dev, void *p)
+ {
+       struct sockaddr *addr = p;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EINVAL;
+       /* ISSUE: Note that "dev_addr" is now a pointer. */
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       return 0;
+ }
+ /*
+  * Obtain the MAC address from the hypervisor.
+  * This must be done before opening the device.
+  */
+ static int tile_net_get_mac(struct net_device *dev)
+ {
+       struct tile_net_priv *priv = netdev_priv(dev);
+       char hv_dev_name[32];
+       int len;
+       __netio_getset_offset_t offset = { .word = NETIO_IPP_PARAM_OFF };
+       int ret;
+       /* For example, "xgbe0". */
+       strcpy(hv_dev_name, dev->name);
+       len = strlen(hv_dev_name);
+       /* For example, "xgbe/0". */
+       hv_dev_name[len] = hv_dev_name[len - 1];
+       hv_dev_name[len - 1] = '/';
+       len++;
+       /* For example, "xgbe/0/native_hash". */
+       strcpy(hv_dev_name + len, hash_default ? "/native_hash" : "/native");
+       /* Get the hypervisor handle for this device. */
+       priv->hv_devhdl = hv_dev_open((HV_VirtAddr)hv_dev_name, 0);
+       PDEBUG("hv_dev_open(%s) returned %d %p\n",
+              hv_dev_name, priv->hv_devhdl, &priv->hv_devhdl);
+       if (priv->hv_devhdl < 0) {
+               if (priv->hv_devhdl == HV_ENODEV)
+                       printk(KERN_DEBUG "Ignoring unconfigured device %s\n",
+                                hv_dev_name);
+               else
+                       printk(KERN_DEBUG "hv_dev_open(%s) returned %d\n",
+                                hv_dev_name, priv->hv_devhdl);
+               return -1;
+       }
+       /*
+        * Read the hardware address from the hypervisor.
+        * ISSUE: Note that "dev_addr" is now a pointer.
+        */
+       offset.bits.class = NETIO_PARAM;
+       offset.bits.addr = NETIO_PARAM_MAC;
+       ret = hv_dev_pread(priv->hv_devhdl, 0,
+                          (HV_VirtAddr)dev->dev_addr, dev->addr_len,
+                          offset.word);
+       PDEBUG("hv_dev_pread(NETIO_PARAM_MAC) returned %d\n", ret);
+       if (ret <= 0) {
+               printk(KERN_DEBUG "hv_dev_pread(NETIO_PARAM_MAC) %s failed\n",
+                      dev->name);
+               /*
+                * Since the device is configured by the hypervisor but we
+                * can't get its MAC address, we are most likely running
+                * the simulator, so let's generate a random MAC address.
+                */
+               random_ether_addr(dev->dev_addr);
+       }
+       return 0;
+ }
+ static struct net_device_ops tile_net_ops = {
+       .ndo_open = tile_net_open,
+       .ndo_stop = tile_net_stop,
+       .ndo_start_xmit = tile_net_tx,
+       .ndo_do_ioctl = tile_net_ioctl,
+       .ndo_get_stats = tile_net_get_stats,
+       .ndo_change_mtu = tile_net_change_mtu,
+       .ndo_tx_timeout = tile_net_tx_timeout,
+       .ndo_set_mac_address = tile_net_set_mac_address
+ };
+ /*
+  * The setup function.
+  *
+  * This uses ether_setup() to assign various fields in dev, including
+  * setting IFF_BROADCAST and IFF_MULTICAST, then sets some extra fields.
+  */
+ static void tile_net_setup(struct net_device *dev)
+ {
+       PDEBUG("tile_net_setup()\n");
+       ether_setup(dev);
+       dev->netdev_ops = &tile_net_ops;
+       dev->watchdog_timeo = TILE_NET_TIMEOUT;
+       /* We want lockless xmit. */
+       dev->features |= NETIF_F_LLTX;
+       /* We support hardware tx checksums. */
+       dev->features |= NETIF_F_HW_CSUM;
+       /* We support scatter/gather. */
+       dev->features |= NETIF_F_SG;
+       /* We support TSO. */
+       dev->features |= NETIF_F_TSO;
+ #ifdef TILE_NET_GSO
+       /* We support GSO. */
+       dev->features |= NETIF_F_GSO;
+ #endif
+       if (hash_default)
+               dev->features |= NETIF_F_HIGHDMA;
+       /* ISSUE: We should support NETIF_F_UFO. */
+       dev->tx_queue_len = TILE_NET_TX_QUEUE_LEN;
+       dev->mtu = TILE_NET_MTU;
+ }
+ /*
+  * Allocate the device structure, register the device, and obtain the
+  * MAC address from the hypervisor.
+  */
+ static struct net_device *tile_net_dev_init(const char *name)
+ {
+       int ret;
+       struct net_device *dev;
+       struct tile_net_priv *priv;
+       /*
+        * Allocate the device structure.  This allocates "priv", calls
+        * tile_net_setup(), and saves "name".  Normally, "name" is a
+        * template, instantiated by register_netdev(), but not for us.
+        */
+       dev = alloc_netdev(sizeof(*priv), name, tile_net_setup);
+       if (!dev) {
+               pr_err("alloc_netdev(%s) failed\n", name);
+               return NULL;
+       }
+       priv = netdev_priv(dev);
+       /* Initialize "priv". */
+       memset(priv, 0, sizeof(*priv));
+       /* Save "dev" for "tile_net_open_retry()". */
+       priv->dev = dev;
+       INIT_DELAYED_WORK(&priv->retry_work, tile_net_open_retry);
+       spin_lock_init(&priv->eq_lock);
+       /* Allocate "eq". */
+       priv->eq_pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, EQ_ORDER);
+       if (!priv->eq_pages) {
+               free_netdev(dev);
+               return NULL;
+       }
+       priv->eq = page_address(priv->eq_pages);
+       /* Register the network device. */
+       ret = register_netdev(dev);
+       if (ret) {
+               pr_err("register_netdev %s failed %d\n", dev->name, ret);
+               __free_pages(priv->eq_pages, EQ_ORDER);
+               free_netdev(dev);
+               return NULL;
+       }
+       /* Get the MAC address. */
+       ret = tile_net_get_mac(dev);
+       if (ret < 0) {
+               unregister_netdev(dev);
+               __free_pages(priv->eq_pages, EQ_ORDER);
+               free_netdev(dev);
+               return NULL;
+       }
+       return dev;
+ }
+ /*
+  * Module cleanup.
+  *
+  * FIXME: If compiled as a module, this module cannot be "unloaded",
+  * because the "ingress interrupt handler" is registered permanently.
+  */
+ static void tile_net_cleanup(void)
+ {
+       int i;
+       for (i = 0; i < TILE_NET_DEVS; i++) {
+               if (tile_net_devs[i]) {
+                       struct net_device *dev = tile_net_devs[i];
+                       struct tile_net_priv *priv = netdev_priv(dev);
+                       unregister_netdev(dev);
+                       finv_buffer_remote(priv->eq, EQ_SIZE, 0);
+                       __free_pages(priv->eq_pages, EQ_ORDER);
+                       free_netdev(dev);
+               }
+       }
+ }
+ /*
+  * Module initialization.
+  */
+ static int tile_net_init_module(void)
+ {
+       pr_info("Tilera IPP Net Driver\n");
+       tile_net_devs[0] = tile_net_dev_init("xgbe0");
+       tile_net_devs[1] = tile_net_dev_init("xgbe1");
+       tile_net_devs[2] = tile_net_dev_init("gbe0");
+       tile_net_devs[3] = tile_net_dev_init("gbe1");
+       return 0;
+ }
+ module_init(tile_net_init_module);
+ module_exit(tile_net_cleanup);
+ #ifndef MODULE
+ /*
+  * The "network_cpus" boot argument specifies the cpus that are dedicated
+  * to handle ingress packets.
+  *
+  * The parameter should be in the form "network_cpus=m-n[,x-y]", where
+  * m, n, x, y are integer numbers that represent the cpus that can be
+  * neither a dedicated cpu nor a dataplane cpu.
+  */
+ static int __init network_cpus_setup(char *str)
+ {
+       int rc = cpulist_parse_crop(str, &network_cpus_map);
+       if (rc != 0) {
+               pr_warning("network_cpus=%s: malformed cpu list\n",
+                      str);
+       } else {
+               /* Remove dedicated cpus. */
+               cpumask_and(&network_cpus_map, &network_cpus_map,
+                           cpu_possible_mask);
+               if (cpumask_empty(&network_cpus_map)) {
+                       pr_warning("Ignoring network_cpus='%s'.\n",
+                              str);
+               } else {
+                       char buf[1024];
+                       cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map);
+                       pr_info("Linux network CPUs: %s\n", buf);
+                       network_cpus_used = true;
+               }
+       }
+       return 0;
+ }
+ __setup("network_cpus=", network_cpus_setup);
+ #endif
Simple merge
Simple merge
Simple merge
diff --cc fs/sysfs/dir.c
@@@ -558,36 -547,22 +565,43 @@@ struct sysfs_dirent *sysfs_find_dirent(
                                       const void *ns,
                                       const unsigned char *name)
  {
 -      struct sysfs_dirent *sd;
 +      struct rb_node *p = parent_sd->s_dir.name_tree.rb_node;
 +      struct sysfs_dirent *found = NULL;
  
+       if (!!sysfs_ns_type(parent_sd) != !!ns) {
+               WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
+                       sysfs_ns_type(parent_sd)? "required": "invalid",
+                       parent_sd->s_name, name);
+               return NULL;
+       }
 -      for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) {
 -              if (sd->s_ns != ns)
 -                      continue;
 -              if (!strcmp(sd->s_name, name))
 -                      return sd;
 +      while (p) {
 +              int c;
 +#define node  rb_entry(p, struct sysfs_dirent, name_node)
 +              c = strcmp(name, node->s_name);
 +              if (c < 0) {
 +                      p = node->name_node.rb_left;
 +              } else if (c > 0) {
 +                      p = node->name_node.rb_right;
 +              } else {
 +                      found = node;
 +                      p = node->name_node.rb_left;
 +              }
 +#undef node
        }
 -      return NULL;
 +
 +      if (found && ns) {
 +              while (found->s_ns && found->s_ns != ns) {
 +                      p = rb_next(&found->name_node);
 +                      if (!p)
 +                              return NULL;
 +                      found = rb_entry(p, struct sysfs_dirent, name_node);
 +                      if (strcmp(name, found->s_name))
 +                              return NULL;
 +              }
 +      }
 +
 +      return found;
  }
  
  /**
Simple merge
Simple merge
Simple merge
diff --cc net/core/dev.c
Simple merge