]> Pileus Git - ~andy/linux/blobdiff - drivers/net/s2io.c
[PATCH] S2io: Support for Xframe II NIC
[~andy/linux] / drivers / net / s2io.c
index 6668b99025c844b61e3b0580ce27ddf3b95838bf..15e2ee9f9703e1a8fe6f89b980b50634192ff938 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/ethtool.h>
 #include <linux/version.h>
 #include <linux/workqueue.h>
+#include <linux/if_vlan.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -83,9 +84,10 @@ static inline int RXD_IS_UP2DT(RxD_t *rxdp)
  * problem, 600B, 600C, 600D, 640B, 640C and 640D.
  * macro below identifies these cards given the subsystem_id.
  */
-#define CARDS_WITH_FAULTY_LINK_INDICATORS(subid) \
-               (((subid >= 0x600B) && (subid <= 0x600D)) || \
-                ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0
+#define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) \
+       (dev_type == XFRAME_I_DEVICE) ?                 \
+               ((((subid >= 0x600B) && (subid <= 0x600D)) || \
+                ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0
 
 #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \
                                      ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
@@ -100,8 +102,7 @@ static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring)
        mac_control = &sp->mac_control;
        if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) {
                level = LOW;
-               if ((mac_control->rings[ring].pkt_cnt - rxb_size) <
-                               MAX_RXDS_PER_BLOCK) {
+               if (rxb_size <= MAX_RXDS_PER_BLOCK) {
                        level = PANIC;
                }
        }
@@ -169,6 +170,36 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
 #define S2IO_TEST_LEN  sizeof(s2io_gstrings) / ETH_GSTRING_LEN
 #define S2IO_STRINGS_LEN       S2IO_TEST_LEN * ETH_GSTRING_LEN
 
+#define S2IO_TIMER_CONF(timer, handle, arg, exp)               \
+                       init_timer(&timer);                     \
+                       timer.function = handle;                \
+                       timer.data = (unsigned long) arg;       \
+                       mod_timer(&timer, (jiffies + exp))      \
+
+/* Add the vlan */
+static void s2io_vlan_rx_register(struct net_device *dev,
+                                       struct vlan_group *grp)
+{
+       nic_t *nic = dev->priv;
+       unsigned long flags;
+
+       spin_lock_irqsave(&nic->tx_lock, flags);
+       nic->vlgrp = grp;
+       spin_unlock_irqrestore(&nic->tx_lock, flags);
+}
+
+/* Unregister the vlan */
+static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
+{
+       nic_t *nic = dev->priv;
+       unsigned long flags;
+
+       spin_lock_irqsave(&nic->tx_lock, flags);
+       if (nic->vlgrp)
+               nic->vlgrp->vlan_devices[vid] = NULL;
+       spin_unlock_irqrestore(&nic->tx_lock, flags);
+}
+
 /*
  * Constants to be programmed into the Xena's registers, to configure
  * the XAUI.
@@ -177,7 +208,24 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
 #define SWITCH_SIGN    0xA5A5A5A5A5A5A5A5ULL
 #define        END_SIGN        0x0
 
-static u64 default_mdio_cfg[] = {
+static u64 herc_act_dtx_cfg[] = {
+       /* Set address */
+       0x80000515BA750000ULL, 0x80000515BA7500E0ULL,
+       /* Write data */
+       0x80000515BA750004ULL, 0x80000515BA7500E4ULL,
+       /* Set address */
+       0x80010515003F0000ULL, 0x80010515003F00E0ULL,
+       /* Write data */
+       0x80010515003F0004ULL, 0x80010515003F00E4ULL,
+       /* Set address */
+       0x80020515F2100000ULL, 0x80020515F21000E0ULL,
+       /* Write data */
+       0x80020515F2100004ULL, 0x80020515F21000E4ULL,
+       /* Done */
+       END_SIGN
+};
+
+static u64 xena_mdio_cfg[] = {
        /* Reset PMA PLL */
        0xC001010000000000ULL, 0xC0010100000000E0ULL,
        0xC0010100008000E4ULL,
@@ -187,7 +235,7 @@ static u64 default_mdio_cfg[] = {
        END_SIGN
 };
 
-static u64 default_dtx_cfg[] = {
+static u64 xena_dtx_cfg[] = {
        0x8000051500000000ULL, 0x80000515000000E0ULL,
        0x80000515D93500E4ULL, 0x8001051500000000ULL,
        0x80010515000000E0ULL, 0x80010515001E00E4ULL,
@@ -625,6 +673,87 @@ static void free_shared_mem(struct s2io_nic *nic)
        }
 }
 
+/**
+ * s2io_verify_pci_mode -
+ */
+
+static int s2io_verify_pci_mode(nic_t *nic)
+{
+       XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+       register u64 val64 = 0;
+       int     mode;
+
+       val64 = readq(&bar0->pci_mode);
+       mode = (u8)GET_PCI_MODE(val64);
+
+       if ( val64 & PCI_MODE_UNKNOWN_MODE)
+               return -1;      /* Unknown PCI mode */
+       return mode;
+}
+
+
+/**
+ * s2io_print_pci_mode -
+ */
+static int s2io_print_pci_mode(nic_t *nic)
+{
+       XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+       register u64 val64 = 0;
+       int     mode;
+       struct config_param *config = &nic->config;
+
+       val64 = readq(&bar0->pci_mode);
+       mode = (u8)GET_PCI_MODE(val64);
+
+       if ( val64 & PCI_MODE_UNKNOWN_MODE)
+               return -1;      /* Unknown PCI mode */
+
+       if (val64 & PCI_MODE_32_BITS) {
+               DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name);
+       } else {
+               DBG_PRINT(ERR_DBG, "%s: Device is on 64 bit ", nic->dev->name);
+       }
+
+       switch(mode) {
+               case PCI_MODE_PCI_33:
+                       DBG_PRINT(ERR_DBG, "33MHz PCI bus\n");
+                       config->bus_speed = 33;
+                       break;
+               case PCI_MODE_PCI_66:
+                       DBG_PRINT(ERR_DBG, "66MHz PCI bus\n");
+                       config->bus_speed = 133;
+                       break;
+               case PCI_MODE_PCIX_M1_66:
+                       DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n");
+                       config->bus_speed = 133; /* Herc doubles the clock rate */
+                       break;
+               case PCI_MODE_PCIX_M1_100:
+                       DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n");
+                       config->bus_speed = 200;
+                       break;
+               case PCI_MODE_PCIX_M1_133:
+                       DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n");
+                       config->bus_speed = 266;
+                       break;
+               case PCI_MODE_PCIX_M2_66:
+                       DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n");
+                       config->bus_speed = 133;
+                       break;
+               case PCI_MODE_PCIX_M2_100:
+                       DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n");
+                       config->bus_speed = 200;
+                       break;
+               case PCI_MODE_PCIX_M2_133:
+                       DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n");
+                       config->bus_speed = 266;
+                       break;
+               default:
+                       return -1;      /* Unsupported bus speed */
+       }
+
+       return mode;
+}
+
 /**
  *  init_nic - Initialization of hardware
  *  @nic: device peivate variable
@@ -657,6 +786,16 @@ static int init_nic(struct s2io_nic *nic)
                return -1;
        }
 
+       /*
+        * Herc requires EOI to be removed from reset before XGXS, so..
+        */
+       if (nic->device_type & XFRAME_II_DEVICE) {
+               val64 = 0xA500000000ULL;
+               writeq(val64, &bar0->sw_reset);
+               msleep(500);
+               val64 = readq(&bar0->sw_reset);
+       }
+
        /* Remove XGXS from reset state */
        val64 = 0;
        writeq(val64, &bar0->sw_reset);
@@ -688,41 +827,51 @@ static int init_nic(struct s2io_nic *nic)
         * of 64 bit values into two registers in a particular
         * sequence. Hence a macro 'SWITCH_SIGN' has been defined
         * which will be defined in the array of configuration values
-        * (default_dtx_cfg & default_mdio_cfg) at appropriate places
+        * (xena_dtx_cfg & xena_mdio_cfg) at appropriate places
         * to switch writing from one regsiter to another. We continue
         * writing these values until we encounter the 'END_SIGN' macro.
         * For example, After making a series of 21 writes into
         * dtx_control register the 'SWITCH_SIGN' appears and hence we
         * start writing into mdio_control until we encounter END_SIGN.
         */
-       while (1) {
-             dtx_cfg:
-               while (default_dtx_cfg[dtx_cnt] != END_SIGN) {
-                       if (default_dtx_cfg[dtx_cnt] == SWITCH_SIGN) {
-                               dtx_cnt++;
-                               goto mdio_cfg;
-                       }
-                       SPECIAL_REG_WRITE(default_dtx_cfg[dtx_cnt],
+       if (nic->device_type & XFRAME_II_DEVICE) {
+               while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) {
+                       SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt],
                                          &bar0->dtx_control, UF);
-                       val64 = readq(&bar0->dtx_control);
+                       if (dtx_cnt & 0x1)
+                               msleep(1); /* Necessary!! */
                        dtx_cnt++;
                }
-             mdio_cfg:
-               while (default_mdio_cfg[mdio_cnt] != END_SIGN) {
-                       if (default_mdio_cfg[mdio_cnt] == SWITCH_SIGN) {
+       } else {
+               while (1) {
+                     dtx_cfg:
+                       while (xena_dtx_cfg[dtx_cnt] != END_SIGN) {
+                               if (xena_dtx_cfg[dtx_cnt] == SWITCH_SIGN) {
+                                       dtx_cnt++;
+                                       goto mdio_cfg;
+                               }
+                               SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt],
+                                                 &bar0->dtx_control, UF);
+                               val64 = readq(&bar0->dtx_control);
+                               dtx_cnt++;
+                       }
+                     mdio_cfg:
+                       while (xena_mdio_cfg[mdio_cnt] != END_SIGN) {
+                               if (xena_mdio_cfg[mdio_cnt] == SWITCH_SIGN) {
+                                       mdio_cnt++;
+                                       goto dtx_cfg;
+                               }
+                               SPECIAL_REG_WRITE(xena_mdio_cfg[mdio_cnt],
+                                                 &bar0->mdio_control, UF);
+                               val64 = readq(&bar0->mdio_control);
                                mdio_cnt++;
+                       }
+                       if ((xena_dtx_cfg[dtx_cnt] == END_SIGN) &&
+                           (xena_mdio_cfg[mdio_cnt] == END_SIGN)) {
+                               break;
+                       } else {
                                goto dtx_cfg;
                        }
-                       SPECIAL_REG_WRITE(default_mdio_cfg[mdio_cnt],
-                                         &bar0->mdio_control, UF);
-                       val64 = readq(&bar0->mdio_control);
-                       mdio_cnt++;
-               }
-               if ((default_dtx_cfg[dtx_cnt] == END_SIGN) &&
-                   (default_mdio_cfg[mdio_cnt] == END_SIGN)) {
-                       break;
-               } else {
-                       goto dtx_cfg;
                }
        }
 
@@ -773,7 +922,8 @@ static int init_nic(struct s2io_nic *nic)
         * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug
         * SXE-008 TRANSMIT DMA ARBITRATION ISSUE.
         */
-       if (get_xena_rev_id(nic->pdev) < 4)
+       if ((nic->device_type == XFRAME_I_DEVICE) &&
+               (get_xena_rev_id(nic->pdev) < 4))
                writeq(PCC_ENABLE_FOUR, &bar0->pcc_enable);
 
        val64 = readq(&bar0->tx_fifo_partition_0);
@@ -803,7 +953,11 @@ static int init_nic(struct s2io_nic *nic)
         * configured Rings.
         */
        val64 = 0;
-       mem_size = 64;
+       if (nic->device_type & XFRAME_II_DEVICE)
+               mem_size = 32;
+       else
+               mem_size = 64;
+
        for (i = 0; i < config->rx_ring_num; i++) {
                switch (i) {
                case 0:
@@ -1086,6 +1240,11 @@ static int init_nic(struct s2io_nic *nic)
        /* Program statistics memory */
        writeq(mac_control->stats_mem_phy, &bar0->stat_addr);
 
+       if (nic->device_type == XFRAME_II_DEVICE) {
+               val64 = STAT_BC(0x320);
+               writeq(val64, &bar0->stat_byte_cnt);
+       }
+
        /*
         * Initializing the sampling rate for the device to calculate the
         * bandwidth utilization.
@@ -1104,12 +1263,18 @@ static int init_nic(struct s2io_nic *nic)
         * 250 interrupts per sec. Continuous interrupts are enabled
         * by default.
         */
-       val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078) |
-           TTI_DATA1_MEM_TX_URNG_A(0xA) |
+       if (nic->device_type == XFRAME_II_DEVICE) {
+               int count = (nic->config.bus_speed * 125)/2;
+               val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count);
+       } else {
+
+               val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078);
+       }
+       val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) |
            TTI_DATA1_MEM_TX_URNG_B(0x10) |
            TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN;
-       if (use_continuous_tx_intrs)
-               val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
+               if (use_continuous_tx_intrs)
+                       val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
        writeq(val64, &bar0->tti_data1_mem);
 
        val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
@@ -1141,9 +1306,19 @@ static int init_nic(struct s2io_nic *nic)
                time++;
        }
 
+
        /* RTI Initialization */
-       val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF) |
-           RTI_DATA1_MEM_RX_URNG_A(0xA) |
+       if (nic->device_type == XFRAME_II_DEVICE) {
+               /*
+                * Programmed to generate Apprx 500 Intrs per
+                * second
+                */
+               int count = (nic->config.bus_speed * 125)/4;
+               val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count);
+       } else {
+               val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF);
+       }
+       val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) |
            RTI_DATA1_MEM_RX_URNG_B(0x10) |
            RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN;
 
@@ -1237,6 +1412,15 @@ static int init_nic(struct s2io_nic *nic)
        val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits);
        writeq(val64, &bar0->pic_control);
 
+       /*
+        * Programming the Herc to split every write transaction
+        * that does not start on an ADB to reduce disconnects.
+        */
+       if (nic->device_type == XFRAME_II_DEVICE) {
+               val64 = WREQ_SPLIT_MASK_SET_MASK(255);
+               writeq(val64, &bar0->wreq_split_mask);
+       }
+
        return SUCCESS;
 }
 
@@ -1479,18 +1663,18 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
        }
 }
 
-static int check_prc_pcc_state(u64 val64, int flag, int rev_id)
+static int check_prc_pcc_state(u64 val64, int flag, int rev_id, int herc)
 {
        int ret = 0;
 
        if (flag == FALSE) {
-               if (rev_id >= 4) {
+               if ((!herc && (rev_id >= 4)) || herc) {
                        if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) &&
                            ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
                             ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
                                ret = 1;
                        }
-               } else {
+               }else {
                        if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) &&
                            ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
                             ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
@@ -1498,7 +1682,7 @@ static int check_prc_pcc_state(u64 val64, int flag, int rev_id)
                        }
                }
        } else {
-               if (rev_id >= 4) {
+               if ((!herc && (rev_id >= 4)) || herc) {
                        if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) ==
                             ADAPTER_STATUS_RMAC_PCC_IDLE) &&
                            (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ||
@@ -1534,10 +1718,11 @@ static int check_prc_pcc_state(u64 val64, int flag, int rev_id)
 
 static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
 {
-       int ret = 0;
+       int ret = 0, herc;
        u64 tmp64 = ~((u64) val64);
        int rev_id = get_xena_rev_id(sp->pdev);
 
+       herc = (sp->device_type == XFRAME_II_DEVICE);
        if (!
            (tmp64 &
             (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY |
@@ -1545,7 +1730,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
              ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY |
              ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK |
              ADAPTER_STATUS_P_PLL_LOCK))) {
-               ret = check_prc_pcc_state(val64, flag, rev_id);
+               ret = check_prc_pcc_state(val64, flag, rev_id, herc);
        }
 
        return ret;
@@ -1676,7 +1861,8 @@ static int start_nic(struct s2io_nic *nic)
 
        /* SXE-002: Initialize link and activity LED */
        subid = nic->pdev->subsystem_device;
-       if ((subid & 0xFF) >= 0x07) {
+       if (((subid & 0xFF) >= 0x07) &&
+           (nic->device_type == XFRAME_I_DEVICE)) {
                val64 = readq(&bar0->gpio_control);
                val64 |= 0x0000800000000000ULL;
                writeq(val64, &bar0->gpio_control);
@@ -2193,7 +2379,6 @@ static void rx_intr_handler(ring_info_t *ring_data)
 {
        nic_t *nic = ring_data->nic;
        struct net_device *dev = (struct net_device *) nic->dev;
-       XENA_dev_config_t __iomem *bar0 = nic->bar0;
        int get_block, get_offset, put_block, put_offset, ring_bufs;
        rx_curr_get_info_t get_info, put_info;
        RxD_t *rxdp;
@@ -2201,8 +2386,6 @@ static void rx_intr_handler(ring_info_t *ring_data)
 #ifndef CONFIG_S2IO_NAPI
        int pkt_cnt = 0;
 #endif
-       register u64 val64;
-
        spin_lock(&nic->rx_lock);
        if (atomic_read(&nic->card_state) == CARD_DOWN) {
                DBG_PRINT(ERR_DBG, "%s: %s going down for reset\n",
@@ -2210,13 +2393,6 @@ static void rx_intr_handler(ring_info_t *ring_data)
                spin_unlock(&nic->rx_lock);
        }
 
-       /*
-        * rx_traffic_int reg is an R1 register, hence we read and write
-        * back the same value in the register to clear it
-        */
-       val64 = readq(&bar0->tx_traffic_int);
-       writeq(val64, &bar0->tx_traffic_int);
-
        get_info = ring_data->rx_curr_get_info;
        get_block = get_info.block_index;
        put_info = ring_data->rx_curr_put_info;
@@ -2312,20 +2488,11 @@ static void rx_intr_handler(ring_info_t *ring_data)
 static void tx_intr_handler(fifo_info_t *fifo_data)
 {
        nic_t *nic = fifo_data->nic;
-       XENA_dev_config_t __iomem *bar0 = nic->bar0;
        struct net_device *dev = (struct net_device *) nic->dev;
        tx_curr_get_info_t get_info, put_info;
        struct sk_buff *skb;
        TxD_t *txdlp;
        u16 j, frg_cnt;
-       register u64 val64 = 0;
-
-       /*
-        * tx_traffic_int reg is an R1 register, hence we read and write
-        * back the same value in the register to clear it
-        */
-       val64 = readq(&bar0->tx_traffic_int);
-       writeq(val64, &bar0->tx_traffic_int);
 
        get_info = fifo_data->tx_curr_get_info;
        put_info = fifo_data->tx_curr_put_info;
@@ -2530,9 +2697,12 @@ void s2io_reset(nic_t * sp)
         */
        msleep(250);
 
+       if (!(sp->device_type & XFRAME_II_DEVICE)) {
        /* Restore the PCI state saved during initializarion. */
-       pci_restore_state(sp->pdev);
-
+               pci_restore_state(sp->pdev);
+       } else {
+               pci_set_master(sp->pdev);
+       }
        s2io_init_pci(sp);
 
        msleep(250);
@@ -2557,7 +2727,8 @@ void s2io_reset(nic_t * sp)
 
        /* SXE-002: Configure link and activity LED to turn it off */
        subid = sp->pdev->subsystem_device;
-       if ((subid & 0xFF) >= 0x07) {
+       if (((subid & 0xFF) >= 0x07) &&
+           (sp->device_type == XFRAME_I_DEVICE)) {
                val64 = readq(&bar0->gpio_control);
                val64 |= 0x0000800000000000ULL;
                writeq(val64, &bar0->gpio_control);
@@ -2565,6 +2736,15 @@ void s2io_reset(nic_t * sp)
                writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700));
        }
 
+       /*
+        * Clear spurious ECC interrupts that would have occured on
+        * XFRAME II cards after reset.
+        */
+       if (sp->device_type == XFRAME_II_DEVICE) {
+               val64 = readq(&bar0->pcc_err_reg);
+               writeq(val64, &bar0->pcc_err_reg);
+       }
+
        sp->device_enabled_once = FALSE;
 }
 
@@ -2761,6 +2941,7 @@ int s2io_open(struct net_device *dev)
 setting_mac_address_failed:
        free_irq(sp->pdev->irq, dev);
 isr_registration_failed:
+       del_timer_sync(&sp->alarm_timer);
        s2io_reset(sp);
 hw_init_failed:
        return err;
@@ -2816,9 +2997,10 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 #ifdef NETIF_F_TSO
        int mss;
 #endif
+       u16 vlan_tag = 0;
+       int vlan_priority = 0;
        mac_info_t *mac_control;
        struct config_param *config;
-       XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
        mac_control = &sp->mac_control;
        config = &sp->config;
@@ -2835,6 +3017,13 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 
        queue = 0;
 
+       /* Get Fifo number to Transmit based on vlan priority */
+       if (sp->vlgrp && vlan_tx_tag_present(skb)) {
+               vlan_tag = vlan_tx_tag_get(skb);
+               vlan_priority = vlan_tag >> 13;
+               queue = config->fifo_mapping[vlan_priority];
+       }
+
        put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset;
        get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset;
        txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off].
@@ -2871,6 +3060,11 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 
        txdp->Control_2 |= config->tx_intr_type;
 
+       if (sp->vlgrp && vlan_tx_tag_present(skb)) {
+               txdp->Control_2 |= TXD_VLAN_ENABLE;
+               txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
+       }
+
        txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
                            TXD_GATHER_CODE_FIRST);
        txdp->Control_1 |= TXD_LIST_OWN_XENA;
@@ -2890,6 +3084,8 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr;
        writeq(val64, &tx_fifo->TxDL_Pointer);
 
+       wmb();
+
        val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST |
                 TX_FIFO_LAST_LIST);
 
@@ -2899,9 +3095,6 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
        writeq(val64, &tx_fifo->List_Control);
 
-       /* Perform a PCI read to flush previous writes */
-       val64 = readq(&bar0->general_int_status);
-
        put_off++;
        put_off %= mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1;
        mac_control->fifos[queue].tx_curr_put_info.offset = put_off;
@@ -2920,6 +3113,15 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        return 0;
 }
 
+static void
+s2io_alarm_handle(unsigned long data)
+{
+       nic_t *sp = (nic_t *)data;
+
+       alarm_intr_handler(sp);
+       mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
+}
+
 /**
  *  s2io_isr - ISR handler of the device .
  *  @irq: the irq of the device.
@@ -2940,7 +3142,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
        nic_t *sp = dev->priv;
        XENA_dev_config_t __iomem *bar0 = sp->bar0;
        int i;
-       u64 reason = 0;
+       u64 reason = 0, val64;
        mac_info_t *mac_control;
        struct config_param *config;
 
@@ -2964,9 +3166,6 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
                return IRQ_NONE;
        }
 
-       if (reason & (GEN_ERROR_INTR))
-               alarm_intr_handler(sp);
-
 #ifdef CONFIG_S2IO_NAPI
        if (reason & GEN_INTR_RXTRAFFIC) {
                if (netif_rx_schedule_prep(dev)) {
@@ -2978,6 +3177,13 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
 #else
        /* If Intr is because of Rx Traffic */
        if (reason & GEN_INTR_RXTRAFFIC) {
+               /*
+                * rx_traffic_int reg is an R1 register, writing all 1's
+                * will ensure that the actual interrupt causing bit get's
+                * cleared and hence a read can be avoided.
+                */
+               val64 = 0xFFFFFFFFFFFFFFFFULL;
+               writeq(val64, &bar0->rx_traffic_int);
                for (i = 0; i < config->rx_ring_num; i++) {
                        rx_intr_handler(&mac_control->rings[i]);
                }
@@ -2986,6 +3192,14 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
 
        /* If Intr is because of Tx Traffic */
        if (reason & GEN_INTR_TXTRAFFIC) {
+               /*
+                * tx_traffic_int reg is an R1 register, writing all 1's
+                * will ensure that the actual interrupt causing bit get's
+                * cleared and hence a read can be avoided.
+                */
+               val64 = 0xFFFFFFFFFFFFFFFFULL;
+               writeq(val64, &bar0->tx_traffic_int);
+
                for (i = 0; i < config->tx_fifo_num; i++)
                        tx_intr_handler(&mac_control->fifos[i]);
        }
@@ -3418,7 +3632,8 @@ static void s2io_phy_id(unsigned long data)
        u16 subid;
 
        subid = sp->pdev->subsystem_device;
-       if ((subid & 0xFF) >= 0x07) {
+       if ((sp->device_type == XFRAME_II_DEVICE) ||
+                  ((subid & 0xFF) >= 0x07)) {
                val64 = readq(&bar0->gpio_control);
                val64 ^= GPIO_CTRL_GPIO_0;
                writeq(val64, &bar0->gpio_control);
@@ -3455,7 +3670,8 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 
        subid = sp->pdev->subsystem_device;
        last_gpio_ctrl_val = readq(&bar0->gpio_control);
-       if ((subid & 0xFF) < 0x07) {
+       if ((sp->device_type == XFRAME_I_DEVICE) &&
+               ((subid & 0xFF) < 0x07)) {
                val64 = readq(&bar0->adapter_control);
                if (!(val64 & ADAPTER_CNTL_EN)) {
                        printk(KERN_ERR
@@ -3475,7 +3691,7 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
                msleep_interruptible(MAX_FLICKER_TIME);
        del_timer_sync(&sp->id_timer);
 
-       if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+       if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) {
                writeq(last_gpio_ctrl_val, &bar0->gpio_control);
                last_gpio_ctrl_val = readq(&bar0->gpio_control);
        }
@@ -4089,44 +4305,91 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
        StatInfo_t *stat_info = sp->mac_control.stats_info;
 
        s2io_updt_stats(sp);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_data_octets);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_frms_oflow) << 32  |
+               le32_to_cpu(stat_info->tmac_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_data_octets_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_data_octets);
        tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_mcst_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_bcst_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_mcst_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_mcst_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_bcst_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_bcst_frms);
        tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_any_err_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_any_err_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_any_err_frms);
        tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_vld_ip);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_drop_ip);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_icmp);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_rst_tcp);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_vld_ip_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_vld_ip);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_drop_ip_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_drop_ip);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_icmp_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_icmp);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->tmac_rst_tcp_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_rst_tcp);
        tmp_stats[i++] = le64_to_cpu(stat_info->tmac_tcp);
-       tmp_stats[i++] = le32_to_cpu(stat_info->tmac_udp);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_data_octets);
+       tmp_stats[i++] = (u64)le32_to_cpu(stat_info->tmac_udp_oflow) << 32 |
+               le32_to_cpu(stat_info->tmac_udp);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_vld_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_vld_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_data_octets_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_data_octets);
        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_fcs_err_frms);
        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_drop_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_mcst_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_bcst_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_vld_mcst_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_vld_mcst_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_vld_bcst_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_vld_bcst_frms);
        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms);
        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms);
        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_discarded_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_usized_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_osized_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_frag_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_jabber_frms);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ip);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_discarded_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_discarded_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_usized_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_usized_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_osized_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_osized_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_frag_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_frag_frms);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_jabber_frms_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_jabber_frms);
+       tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_ip);
        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets);
        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_drop_ip);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_icmp);
+       tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_drop_ip);
+       tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_icmp);
        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_udp);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_drp_udp);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pause_cnt);
-       tmp_stats[i++] = le32_to_cpu(stat_info->rmac_accepted_ip);
+       tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_udp);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_err_drp_udp_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_err_drp_udp);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_pause_cnt_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_pause_cnt);
+       tmp_stats[i++] =
+               (u64)le32_to_cpu(stat_info->rmac_accepted_ip_oflow) << 32 |
+               le32_to_cpu(stat_info->rmac_accepted_ip);
        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp);
        tmp_stats[i++] = 0;
        tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs;
@@ -4254,14 +4517,6 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
        nic_t *sp = dev->priv;
-       XENA_dev_config_t __iomem *bar0 = sp->bar0;
-       register u64 val64;
-
-       if (netif_running(dev)) {
-               DBG_PRINT(ERR_DBG, "%s: Must be stopped to ", dev->name);
-               DBG_PRINT(ERR_DBG, "change its MTU\n");
-               return -EBUSY;
-       }
 
        if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) {
                DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n",
@@ -4269,11 +4524,22 @@ int s2io_change_mtu(struct net_device *dev, int new_mtu)
                return -EPERM;
        }
 
-       /* Set the new MTU into the PYLD register of the NIC */
-       val64 = new_mtu;
-       writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
-
        dev->mtu = new_mtu;
+       if (netif_running(dev)) {
+               s2io_card_down(sp);
+               netif_stop_queue(dev);
+               if (s2io_card_up(sp)) {
+                       DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
+                                 __FUNCTION__);
+               }
+               if (netif_queue_stopped(dev))
+                       netif_wake_queue(dev);
+       } else { /* Device is down */
+               XENA_dev_config_t __iomem *bar0 = sp->bar0;
+               u64 val64 = new_mtu;
+
+               writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
+       }
 
        return 0;
 }
@@ -4353,7 +4619,8 @@ static void s2io_set_link(unsigned long data)
                        val64 = readq(&bar0->adapter_control);
                        val64 |= ADAPTER_CNTL_EN;
                        writeq(val64, &bar0->adapter_control);
-                       if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+                       if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type,
+                                                            subid)) {
                                val64 = readq(&bar0->gpio_control);
                                val64 |= GPIO_CTRL_GPIO_0;
                                writeq(val64, &bar0->gpio_control);
@@ -4375,7 +4642,8 @@ static void s2io_set_link(unsigned long data)
                        }
                        s2io_link(nic, LINK_UP);
                } else {
-                       if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+                       if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type,
+                                                             subid)) {
                                val64 = readq(&bar0->gpio_control);
                                val64 &= ~GPIO_CTRL_GPIO_0;
                                writeq(val64, &bar0->gpio_control);
@@ -4398,6 +4666,7 @@ static void s2io_card_down(nic_t * sp)
        unsigned long flags;
        register u64 val64 = 0;
 
+       del_timer_sync(&sp->alarm_timer);
        /* If s2io_set_link task is executing, wait till it completes. */
        while (test_and_set_bit(0, &(sp->link_state))) {
                msleep(50);
@@ -4500,6 +4769,8 @@ static int s2io_card_up(nic_t * sp)
                return -ENODEV;
        }
 
+       S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2));
+
        atomic_set(&sp->card_state, CARD_UP);
        return 0;
 }
@@ -4641,9 +4912,21 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp)
 
        skb->protocol = eth_type_trans(skb, dev);
 #ifdef CONFIG_S2IO_NAPI
-       netif_receive_skb(skb);
+       if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) {
+               /* Queueing the vlan frame to the upper layer */
+               vlan_hwaccel_receive_skb(skb, sp->vlgrp,
+                       RXD_GET_VLAN_TAG(rxdp->Control_2));
+       } else {
+               netif_receive_skb(skb);
+       }
 #else
-       netif_rx(skb);
+       if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) {
+               /* Queueing the vlan frame to the upper layer */
+               vlan_hwaccel_rx(skb, sp->vlgrp,
+                       RXD_GET_VLAN_TAG(rxdp->Control_2));
+       } else {
+               netif_rx(skb);
+       }
 #endif
        dev->last_rx = jiffies;
        atomic_dec(&sp->rx_bufs_left[ring_no]);
@@ -4778,6 +5061,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        u16 subid;
        mac_info_t *mac_control;
        struct config_param *config;
+       int mode;
 
 #ifdef CONFIG_S2IO_NAPI
        DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
@@ -4834,6 +5118,12 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        sp->high_dma_flag = dma_flag;
        sp->device_enabled_once = FALSE;
 
+       if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
+               (pdev->device == PCI_DEVICE_ID_HERC_UNI))
+               sp->device_type = XFRAME_II_DEVICE;
+       else
+               sp->device_type = XFRAME_I_DEVICE;
+
        /* Initialize some PCI/PCI-X fields of the NIC. */
        s2io_init_pci(sp);
 
@@ -4942,6 +5232,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        dev->do_ioctl = &s2io_ioctl;
        dev->change_mtu = &s2io_change_mtu;
        SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+       dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+       dev->vlan_rx_register = s2io_vlan_rx_register;
+       dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid;
 
        /*
         * will use eth_mac_addr() for  dev->set_mac_address
@@ -4966,7 +5259,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        INIT_WORK(&sp->set_link_task,
                  (void (*)(void *)) s2io_set_link, sp);
 
-       pci_save_state(sp->pdev);
+       if (!(sp->device_type & XFRAME_II_DEVICE)) {
+               pci_save_state(sp->pdev);
+       }
 
        /* Setting swapper control on the NIC, for proper reset operation */
        if (s2io_set_swapper(sp)) {
@@ -4976,12 +5271,26 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                goto set_swap_failed;
        }
 
-       /*
-        * Fix for all "FFs" MAC address problems observed on
-        * Alpha platforms
-        */
-       fix_mac_address(sp);
-       s2io_reset(sp);
+       /* Verify if the Herc works on the slot its placed into */
+       if (sp->device_type & XFRAME_II_DEVICE) {
+               mode = s2io_verify_pci_mode(sp);
+               if (mode < 0) {
+                       DBG_PRINT(ERR_DBG, "%s: ", __FUNCTION__);
+                       DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n");
+                       ret = -EBADSLT;
+                       goto set_swap_failed;
+               }
+       }
+
+       /* Not needed for Herc */
+       if (sp->device_type & XFRAME_I_DEVICE) {
+               /*
+                * Fix for all "FFs" MAC address problems observed on
+                * Alpha platforms
+                */
+               fix_mac_address(sp);
+               s2io_reset(sp);
+       }
 
        /*
         * MAC address initialization.
@@ -5006,22 +5315,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_down >> 16);
        sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_down >> 24);
 
-       DBG_PRINT(INIT_DBG,
-                 "DEFAULT MAC ADDR:0x%02x-%02x-%02x-%02x-%02x-%02x\n",
-                 sp->def_mac_addr[0].mac_addr[0],
-                 sp->def_mac_addr[0].mac_addr[1],
-                 sp->def_mac_addr[0].mac_addr[2],
-                 sp->def_mac_addr[0].mac_addr[3],
-                 sp->def_mac_addr[0].mac_addr[4],
-                 sp->def_mac_addr[0].mac_addr[5]);
-
        /*  Set the factory defined MAC address initially   */
        dev->addr_len = ETH_ALEN;
        memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN);
 
        /*
         * Initialize the tasklet status and link state flags
-        * and the card statte parameter
+        * and the card state parameter
         */
        atomic_set(&(sp->card_state), 0);
        sp->tasklet_status = 0;
@@ -5056,9 +5356,46 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                goto register_failed;
        }
 
+       if (sp->device_type & XFRAME_II_DEVICE) {
+               DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ",
+                         dev->name);
+               DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n",
+                               get_xena_rev_id(sp->pdev),
+                               s2io_driver_version);
+               DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                         sp->def_mac_addr[0].mac_addr[0],
+                         sp->def_mac_addr[0].mac_addr[1],
+                         sp->def_mac_addr[0].mac_addr[2],
+                         sp->def_mac_addr[0].mac_addr[3],
+                         sp->def_mac_addr[0].mac_addr[4],
+                         sp->def_mac_addr[0].mac_addr[5]);
+               int mode = s2io_print_pci_mode(sp);
+               if (mode < 0) {
+                       DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode ");
+                       ret = -EBADSLT;
+                       goto set_swap_failed;
+               }
+       } else {
+               DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ",
+                         dev->name);
+               DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n",
+                                       get_xena_rev_id(sp->pdev),
+                                       s2io_driver_version);
+               DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                         sp->def_mac_addr[0].mac_addr[0],
+                         sp->def_mac_addr[0].mac_addr[1],
+                         sp->def_mac_addr[0].mac_addr[2],
+                         sp->def_mac_addr[0].mac_addr[3],
+                         sp->def_mac_addr[0].mac_addr[4],
+                         sp->def_mac_addr[0].mac_addr[5]);
+       }
+
        /* Initialize device name */
        strcpy(sp->name, dev->name);
-       strcat(sp->name, ": Neterion Xframe I 10GbE adapter");
+       if (sp->device_type & XFRAME_II_DEVICE)
+               strcat(sp->name, ": Neterion Xframe II 10GbE adapter");
+       else
+               strcat(sp->name, ": Neterion Xframe I 10GbE adapter");
 
        /*
         * Make Link state as off at this point, when the Link change