]> err.no Git - linux-2.6/blobdiff - drivers/net/s2io.c
[NET]: Introduce and use print_mac() and DECLARE_MAC_BUF()
[linux-2.6] / drivers / net / s2io.c
index 9fd465b9f8534f500b035eba2f4a6b9548e4c5a2..26895de3e264414c21c7732988f5d3f7eed8dbf5 100644 (file)
@@ -37,7 +37,7 @@
  * tx_fifo_len: This too is an array of 8. Each element defines the number of
  * Tx descriptors that can be associated with each corresponding FIFO.
  * intr_type: This defines the type of interrupt. The values can be 0(INTA),
- *     2(MSI_X). Default value is '0(INTA)'
+ *     2(MSI_X). Default value is '2(MSI_X)'
  * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
  *     Possible values '1' for enable '0' for disable. Default is '0'
  * lro_max_pkts: This parameter defines maximum number of packets can be
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.24.1"
+#define DRV_VERSION "2.0.26.2"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -130,6 +130,11 @@ static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring)
        return 0;
 }
 
+static inline int is_s2io_card_up(const struct s2io_nic * sp)
+{
+       return test_bit(__S2IO_STATE_CARD_UP, &sp->state);
+}
+
 /* Ethtool related variables and Macros. */
 static char s2io_gstrings[][ETH_GSTRING_LEN] = {
        "Register test\t(offline)",
@@ -263,7 +268,14 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
        {"serious_err_cnt"},
        {"soft_reset_cnt"},
        {"fifo_full_cnt"},
-       {"ring_full_cnt"},
+       {"ring_0_full_cnt"},
+       {"ring_1_full_cnt"},
+       {"ring_2_full_cnt"},
+       {"ring_3_full_cnt"},
+       {"ring_4_full_cnt"},
+       {"ring_5_full_cnt"},
+       {"ring_6_full_cnt"},
+       {"ring_7_full_cnt"},
        ("alarm_transceiver_temp_high"),
        ("alarm_transceiver_temp_low"),
        ("alarm_laser_bias_current_high"),
@@ -303,7 +315,24 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
        ("rx_tcode_fcs_err_cnt"),
        ("rx_tcode_buf_size_err_cnt"),
        ("rx_tcode_rxd_corrupt_cnt"),
-       ("rx_tcode_unkn_err_cnt")
+       ("rx_tcode_unkn_err_cnt"),
+       {"tda_err_cnt"},
+       {"pfc_err_cnt"},
+       {"pcc_err_cnt"},
+       {"tti_err_cnt"},
+       {"tpa_err_cnt"},
+       {"sm_err_cnt"},
+       {"lso_err_cnt"},
+       {"mac_tmac_err_cnt"},
+       {"mac_rmac_err_cnt"},
+       {"xgxs_txgxs_err_cnt"},
+       {"xgxs_rxgxs_err_cnt"},
+       {"rc_err_cnt"},
+       {"prc_pcix_err_cnt"},
+       {"rpa_err_cnt"},
+       {"rda_err_cnt"},
+       {"rti_err_cnt"},
+       {"mc_err_cnt"}
 };
 
 #define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN
@@ -428,7 +457,7 @@ S2IO_PARM_INT(l3l4hdr_size, 128);
 /* Frequency of Rx desc syncs expressed as power of 2 */
 S2IO_PARM_INT(rxsync_frequency, 3);
 /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
-S2IO_PARM_INT(intr_type, 0);
+S2IO_PARM_INT(intr_type, 2);
 /* Large receive offload feature */
 S2IO_PARM_INT(lro, 0);
 /* Max pkts to be aggregated by LRO at one time. If not specified,
@@ -892,8 +921,9 @@ static void free_shared_mem(struct s2io_nic *nic)
                                        k++;
                                }
                                kfree(mac_control->rings[i].ba[j]);
-                               nic->mac_control.stats_info->sw_stat.mem_freed                          += (sizeof(struct buffAdd) * 
-                               (rxd_count[nic->rxd_mode] + 1));
+                               nic->mac_control.stats_info->sw_stat.mem_freed +=
+                                       (sizeof(struct buffAdd) *
+                                       (rxd_count[nic->rxd_mode] + 1));
                        }
                        kfree(mac_control->rings[i].ba);
                        nic->mac_control.stats_info->sw_stat.mem_freed += 
@@ -1586,7 +1616,7 @@ static int init_nic(struct s2io_nic *nic)
 
                val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
                    RTI_DATA2_MEM_RX_UFC_B(0x2) ;
-               if (nic->intr_type == MSI_X)
+               if (nic->config.intr_type == MSI_X)
                    val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
                                RTI_DATA2_MEM_RX_UFC_D(0x40));
                else
@@ -1724,7 +1754,7 @@ static int init_nic(struct s2io_nic *nic)
 
 static int s2io_link_fault_indication(struct s2io_nic *nic)
 {
-       if (nic->intr_type != INTA)
+       if (nic->config.intr_type != INTA)
                return MAC_RMAC_ERR_TIMER;
        if (nic->device_type == XFRAME_II_DEVICE)
                return LINK_UP_DOWN_INTERRUPT;
@@ -1732,6 +1762,150 @@ static int s2io_link_fault_indication(struct s2io_nic *nic)
                return MAC_RMAC_ERR_TIMER;
 }
 
+/**
+ *  do_s2io_write_bits -  update alarm bits in alarm register
+ *  @value: alarm bits
+ *  @flag: interrupt status
+ *  @addr: address value
+ *  Description: update alarm bits in alarm register
+ *  Return Value:
+ *  NONE.
+ */
+static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr)
+{
+       u64 temp64;
+
+       temp64 = readq(addr);
+
+       if(flag == ENABLE_INTRS)
+               temp64 &= ~((u64) value);
+       else
+               temp64 |= ((u64) value);
+       writeq(temp64, addr);
+}
+
+void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
+{
+       struct XENA_dev_config __iomem *bar0 = nic->bar0;
+       register u64 gen_int_mask = 0;
+
+       if (mask & TX_DMA_INTR) {
+
+               gen_int_mask |= TXDMA_INT_M;
+
+               do_s2io_write_bits(TXDMA_TDA_INT | TXDMA_PFC_INT |
+                               TXDMA_PCC_INT | TXDMA_TTI_INT |
+                               TXDMA_LSO_INT | TXDMA_TPA_INT |
+                               TXDMA_SM_INT, flag, &bar0->txdma_int_mask);
+
+               do_s2io_write_bits(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM |
+                               PFC_MISC_0_ERR | PFC_MISC_1_ERR |
+                               PFC_PCIX_ERR | PFC_ECC_SG_ERR, flag,
+                               &bar0->pfc_err_mask);
+
+               do_s2io_write_bits(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM |
+                               TDA_SM1_ERR_ALARM | TDA_Fn_ECC_SG_ERR |
+                               TDA_PCIX_ERR, flag, &bar0->tda_err_mask);
+
+               do_s2io_write_bits(PCC_FB_ECC_DB_ERR | PCC_TXB_ECC_DB_ERR |
+                               PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM |
+                               PCC_N_SERR | PCC_6_COF_OV_ERR |
+                               PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR |
+                               PCC_7_LSO_OV_ERR | PCC_FB_ECC_SG_ERR |
+                               PCC_TXB_ECC_SG_ERR, flag, &bar0->pcc_err_mask);
+
+               do_s2io_write_bits(TTI_SM_ERR_ALARM | TTI_ECC_SG_ERR |
+                               TTI_ECC_DB_ERR, flag, &bar0->tti_err_mask);
+
+               do_s2io_write_bits(LSO6_ABORT | LSO7_ABORT |
+                               LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM |
+                               LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
+                               flag, &bar0->lso_err_mask);
+
+               do_s2io_write_bits(TPA_SM_ERR_ALARM | TPA_TX_FRM_DROP,
+                               flag, &bar0->tpa_err_mask);
+
+               do_s2io_write_bits(SM_SM_ERR_ALARM, flag, &bar0->sm_err_mask);
+
+       }
+
+       if (mask & TX_MAC_INTR) {
+               gen_int_mask |= TXMAC_INT_M;
+               do_s2io_write_bits(MAC_INT_STATUS_TMAC_INT, flag,
+                               &bar0->mac_int_mask);
+               do_s2io_write_bits(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR |
+                               TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR |
+                               TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
+                               flag, &bar0->mac_tmac_err_mask);
+       }
+
+       if (mask & TX_XGXS_INTR) {
+               gen_int_mask |= TXXGXS_INT_M;
+               do_s2io_write_bits(XGXS_INT_STATUS_TXGXS, flag,
+                               &bar0->xgxs_int_mask);
+               do_s2io_write_bits(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR |
+                               TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
+                               flag, &bar0->xgxs_txgxs_err_mask);
+       }
+
+       if (mask & RX_DMA_INTR) {
+               gen_int_mask |= RXDMA_INT_M;
+               do_s2io_write_bits(RXDMA_INT_RC_INT_M | RXDMA_INT_RPA_INT_M |
+                               RXDMA_INT_RDA_INT_M | RXDMA_INT_RTI_INT_M,
+                               flag, &bar0->rxdma_int_mask);
+               do_s2io_write_bits(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR |
+                               RC_PRCn_SM_ERR_ALARM | RC_FTC_SM_ERR_ALARM |
+                               RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR |
+                               RC_RDA_FAIL_WR_Rn, flag, &bar0->rc_err_mask);
+               do_s2io_write_bits(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn |
+                               PRC_PCI_AB_F_WR_Rn | PRC_PCI_DP_RD_Rn |
+                               PRC_PCI_DP_WR_Rn | PRC_PCI_DP_F_WR_Rn, flag,
+                               &bar0->prc_pcix_err_mask);
+               do_s2io_write_bits(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR |
+                               RPA_ECC_SG_ERR | RPA_ECC_DB_ERR, flag,
+                               &bar0->rpa_err_mask);
+               do_s2io_write_bits(RDA_RXDn_ECC_DB_ERR | RDA_FRM_ECC_DB_N_AERR |
+                               RDA_SM1_ERR_ALARM | RDA_SM0_ERR_ALARM |
+                               RDA_RXD_ECC_DB_SERR | RDA_RXDn_ECC_SG_ERR |
+                               RDA_FRM_ECC_SG_ERR | RDA_MISC_ERR|RDA_PCIX_ERR,
+                               flag, &bar0->rda_err_mask);
+               do_s2io_write_bits(RTI_SM_ERR_ALARM |
+                               RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
+                               flag, &bar0->rti_err_mask);
+       }
+
+       if (mask & RX_MAC_INTR) {
+               gen_int_mask |= RXMAC_INT_M;
+               do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
+                               &bar0->mac_int_mask);
+               do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
+                               RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
+                               RMAC_DOUBLE_ECC_ERR |
+                               RMAC_LINK_STATE_CHANGE_INT,
+                               flag, &bar0->mac_rmac_err_mask);
+       }
+
+       if (mask & RX_XGXS_INTR)
+       {
+               gen_int_mask |= RXXGXS_INT_M;
+               do_s2io_write_bits(XGXS_INT_STATUS_RXGXS, flag,
+                               &bar0->xgxs_int_mask);
+               do_s2io_write_bits(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR, flag,
+                               &bar0->xgxs_rxgxs_err_mask);
+       }
+
+       if (mask & MC_INTR) {
+               gen_int_mask |= MC_INT_M;
+               do_s2io_write_bits(MC_INT_MASK_MC_INT, flag, &bar0->mc_int_mask);
+               do_s2io_write_bits(MC_ERR_REG_SM_ERR | MC_ERR_REG_ECC_ALL_SNG |
+                               MC_ERR_REG_ECC_ALL_DBL | PLL_LOCK_N, flag,
+                               &bar0->mc_err_mask);
+       }
+       nic->general_int_mask = gen_int_mask;
+
+       /* Remove this line when alarm interrupts are enabled */
+       nic->general_int_mask = 0;
+}
 /**
  *  en_dis_able_nic_intrs - Enable or Disable the interrupts
  *  @nic: device private variable,
@@ -1746,17 +1920,16 @@ static int s2io_link_fault_indication(struct s2io_nic *nic)
 static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
 {
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
-       register u64 val64 = 0, temp64 = 0;
+       register u64 temp64 = 0, intr_mask = 0;
+
+       intr_mask = nic->general_int_mask;
 
        /*  Top level interrupt classification */
        /*  PIC Interrupts */
-       if ((mask & (TX_PIC_INTR | RX_PIC_INTR))) {
+       if (mask & TX_PIC_INTR) {
                /*  Enable PIC Intrs in the general intr mask register */
-               val64 = TXPIC_INT_M;
+               intr_mask |= TXPIC_INT_M;
                if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
                        /*
                         * If Hercules adapter enable GPIO otherwise
                         * disable all PCIX, Flash, MDIO, IIC and GPIO
@@ -1765,64 +1938,25 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
                         */
                        if (s2io_link_fault_indication(nic) ==
                                        LINK_UP_DOWN_INTERRUPT ) {
-                               temp64 = readq(&bar0->pic_int_mask);
-                               temp64 &= ~((u64) PIC_INT_GPIO);
-                               writeq(temp64, &bar0->pic_int_mask);
-                               temp64 = readq(&bar0->gpio_int_mask);
-                               temp64 &= ~((u64) GPIO_INT_MASK_LINK_UP);
-                               writeq(temp64, &bar0->gpio_int_mask);
-                       } else {
+                               do_s2io_write_bits(PIC_INT_GPIO, flag,
+                                               &bar0->pic_int_mask);
+                               do_s2io_write_bits(GPIO_INT_MASK_LINK_UP, flag,
+                                               &bar0->gpio_int_mask);
+                       } else
                                writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
-                       }
-                       /*
-                        * No MSI Support is available presently, so TTI and
-                        * RTI interrupts are also disabled.
-                        */
                } else if (flag == DISABLE_INTRS) {
                        /*
                         * Disable PIC Intrs in the general
                         * intr mask register
                         */
                        writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
-                       temp64 = readq(&bar0->general_int_mask);
-                       val64 |= temp64;
-                       writeq(val64, &bar0->general_int_mask);
-               }
-       }
-
-       /*  MAC Interrupts */
-       /*  Enabling/Disabling MAC interrupts */
-       if (mask & (TX_MAC_INTR | RX_MAC_INTR)) {
-               val64 = TXMAC_INT_M | RXMAC_INT_M;
-               if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
-                       /*
-                        * All MAC block error interrupts are disabled for now
-                        * TODO
-                        */
-               } else if (flag == DISABLE_INTRS) {
-                       /*
-                        * Disable MAC Intrs in the general intr mask register
-                        */
-                       writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask);
-                       writeq(DISABLE_ALL_INTRS,
-                              &bar0->mac_rmac_err_mask);
-
-                       temp64 = readq(&bar0->general_int_mask);
-                       val64 |= temp64;
-                       writeq(val64, &bar0->general_int_mask);
                }
        }
 
        /*  Tx traffic interrupts */
        if (mask & TX_TRAFFIC_INTR) {
-               val64 = TXTRAFFIC_INT_M;
+               intr_mask |= TXTRAFFIC_INT_M;
                if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
                        /*
                         * Enable all the Tx side interrupts
                         * writing 0 Enables all 64 TX interrupt levels
@@ -1834,19 +1968,13 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
                         * register.
                         */
                        writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask);
-                       temp64 = readq(&bar0->general_int_mask);
-                       val64 |= temp64;
-                       writeq(val64, &bar0->general_int_mask);
                }
        }
 
        /*  Rx traffic interrupts */
        if (mask & RX_TRAFFIC_INTR) {
-               val64 = RXTRAFFIC_INT_M;
+               intr_mask |= RXTRAFFIC_INT_M;
                if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
                        /* writing 0 Enables all 8 RX interrupt levels */
                        writeq(0x0, &bar0->rx_traffic_mask);
                } else if (flag == DISABLE_INTRS) {
@@ -1855,11 +1983,17 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
                         * register.
                         */
                        writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask);
-                       temp64 = readq(&bar0->general_int_mask);
-                       val64 |= temp64;
-                       writeq(val64, &bar0->general_int_mask);
                }
        }
+
+       temp64 = readq(&bar0->general_int_mask);
+       if (flag == ENABLE_INTRS)
+               temp64 &= ~((u64) intr_mask);
+       else
+               temp64 = DISABLE_ALL_INTRS;
+       writeq(temp64, &bar0->general_int_mask);
+
+       nic->general_int_mask = readq(&bar0->general_int_mask);
 }
 
 /**
@@ -2062,14 +2196,6 @@ static int start_nic(struct s2io_nic *nic)
        val64 &= ~ADAPTER_ECC_EN;
        writeq(val64, &bar0->adapter_control);
 
-       /*
-        * Clearing any possible Link state change interrupts that
-        * could have popped up just before Enabling the card.
-        */
-       val64 = readq(&bar0->mac_rmac_err_reg);
-       if (val64)
-               writeq(val64, &bar0->mac_rmac_err_reg);
-
        /*
         * Verify if the device is ready to be enabled, if so enable
         * it.
@@ -2223,9 +2349,9 @@ static void stop_nic(struct s2io_nic *nic)
        config = &nic->config;
 
        /*  Disable all interrupts */
+       en_dis_err_alarms(nic, ENA_ALL_INTRS, DISABLE_INTRS);
        interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
-       interruptible |= TX_PIC_INTR | RX_PIC_INTR;
-       interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+       interruptible |= TX_PIC_INTR;
        en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS);
 
        /* Clearing Adapter_En bit of ADAPTER_CONTROL Register */
@@ -2430,7 +2556,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                                        (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
                                        pci_unmap_single
                                                (nic->pdev,
-                                               (dma_addr_t)skb->data,
+                                               (dma_addr_t)rxdp3->Buffer2_ptr,
                                                dev->mtu + 4,
                                                PCI_DMA_FROMDEVICE);
                                        goto pci_map_failed;
@@ -2568,7 +2694,7 @@ static void free_rx_buffers(struct s2io_nic *sp)
 
 /**
  * s2io_poll - Rx interrupt handler for NAPI support
- * @dev : pointer to the device structure.
+ * @napi : pointer to the napi structure.
  * @budget : The number of packets that were budgeted to be processed
  * during  one pass through the 'Poll" function.
  * Description:
@@ -2579,22 +2705,23 @@ static void free_rx_buffers(struct s2io_nic *sp)
  * 0 on success and 1 if there are No Rx packets to be processed.
  */
 
-static int s2io_poll(struct net_device *dev, int *budget)
+static int s2io_poll(struct napi_struct *napi, int budget)
 {
-       struct s2io_nic *nic = dev->priv;
+       struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi);
+       struct net_device *dev = nic->dev;
        int pkt_cnt = 0, org_pkts_to_process;
        struct mac_info *mac_control;
        struct config_param *config;
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
        int i;
 
-       atomic_inc(&nic->isr_cnt);
+       if (!is_s2io_card_up(nic))
+               return 0;
+
        mac_control = &nic->mac_control;
        config = &nic->config;
 
-       nic->pkts_to_process = *budget;
-       if (nic->pkts_to_process > dev->quota)
-               nic->pkts_to_process = dev->quota;
+       nic->pkts_to_process = budget;
        org_pkts_to_process = nic->pkts_to_process;
 
        writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
@@ -2608,12 +2735,8 @@ static int s2io_poll(struct net_device *dev, int *budget)
                        goto no_rx;
                }
        }
-       if (!pkt_cnt)
-               pkt_cnt = 1;
 
-       dev->quota -= pkt_cnt;
-       *budget -= pkt_cnt;
-       netif_rx_complete(dev);
+       netif_rx_complete(dev, napi);
 
        for (i = 0; i < config->rx_ring_num; i++) {
                if (fill_rx_buffers(nic, i) == -ENOMEM) {
@@ -2625,13 +2748,9 @@ static int s2io_poll(struct net_device *dev, int *budget)
        /* Re enable the Rx interrupts. */
        writeq(0x0, &bar0->rx_traffic_mask);
        readl(&bar0->rx_traffic_mask);
-       atomic_dec(&nic->isr_cnt);
-       return 0;
+       return pkt_cnt;
 
 no_rx:
-       dev->quota -= pkt_cnt;
-       *budget -= pkt_cnt;
-
        for (i = 0; i < config->rx_ring_num; i++) {
                if (fill_rx_buffers(nic, i) == -ENOMEM) {
                        DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
@@ -2639,8 +2758,7 @@ no_rx:
                        break;
                }
        }
-       atomic_dec(&nic->isr_cnt);
-       return 1;
+       return pkt_cnt;
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2667,7 +2785,6 @@ static void s2io_netpoll(struct net_device *dev)
 
        disable_irq(dev->irq);
 
-       atomic_inc(&nic->isr_cnt);
        mac_control = &nic->mac_control;
        config = &nic->config;
 
@@ -2692,7 +2809,6 @@ static void s2io_netpoll(struct net_device *dev)
                        break;
                }
        }
-       atomic_dec(&nic->isr_cnt);
        enable_irq(dev->irq);
        return;
 }
@@ -2724,12 +2840,6 @@ static void rx_intr_handler(struct ring_info *ring_data)
        struct RxD3* rxdp3;
 
        spin_lock(&nic->rx_lock);
-       if (atomic_read(&nic->card_state) == CARD_DOWN) {
-               DBG_PRINT(INTR_DBG, "%s: %s going down for reset\n",
-                         __FUNCTION__, dev->name);
-               spin_unlock(&nic->rx_lock);
-               return;
-       }
 
        get_info = ring_data->rx_curr_get_info;
        get_block = get_info.block_index;
@@ -3163,135 +3273,6 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
                stat_info->xpak_stat.warn_laser_output_power_low++;
 }
 
-/**
- *  alarm_intr_handler - Alarm Interrrupt handler
- *  @nic: device private variable
- *  Description: If the interrupt was neither because of Rx packet or Tx
- *  complete, this function is called. If the interrupt was to indicate
- *  a loss of link, the OSM link status handler is invoked for any other
- *  alarm interrupt the block that raised the interrupt is displayed
- *  and a H/W reset is issued.
- *  Return Value:
- *  NONE
-*/
-
-static void alarm_intr_handler(struct s2io_nic *nic)
-{
-       struct net_device *dev = (struct net_device *) nic->dev;
-       struct XENA_dev_config __iomem *bar0 = nic->bar0;
-       register u64 val64 = 0, err_reg = 0;
-       u64 cnt;
-       int i;
-       if (atomic_read(&nic->card_state) == CARD_DOWN)
-               return;
-       if (pci_channel_offline(nic->pdev))
-               return;
-       nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0;
-       /* Handling the XPAK counters update */
-       if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) {
-               /* waiting for an hour */
-               nic->mac_control.stats_info->xpak_stat.xpak_timer_count++;
-       } else {
-               s2io_updt_xpak_counter(dev);
-               /* reset the count to zero */
-               nic->mac_control.stats_info->xpak_stat.xpak_timer_count = 0;
-       }
-
-       /* Handling link status change error Intr */
-       if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) {
-               err_reg = readq(&bar0->mac_rmac_err_reg);
-               writeq(err_reg, &bar0->mac_rmac_err_reg);
-               if (err_reg & RMAC_LINK_STATE_CHANGE_INT) {
-                       schedule_work(&nic->set_link_task);
-               }
-       }
-
-       /* Handling Ecc errors */
-       val64 = readq(&bar0->mc_err_reg);
-       writeq(val64, &bar0->mc_err_reg);
-       if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) {
-               if (val64 & MC_ERR_REG_ECC_ALL_DBL) {
-                       nic->mac_control.stats_info->sw_stat.
-                               double_ecc_errs++;
-                       DBG_PRINT(INIT_DBG, "%s: Device indicates ",
-                                 dev->name);
-                       DBG_PRINT(INIT_DBG, "double ECC error!!\n");
-                       if (nic->device_type != XFRAME_II_DEVICE) {
-                               /* Reset XframeI only if critical error */
-                               if (val64 & (MC_ERR_REG_MIRI_ECC_DB_ERR_0 |
-                                            MC_ERR_REG_MIRI_ECC_DB_ERR_1)) {
-                                       netif_stop_queue(dev);
-                                       schedule_work(&nic->rst_timer_task);
-                                       nic->mac_control.stats_info->sw_stat.
-                                                       soft_reset_cnt++;
-                               }
-                       }
-               } else {
-                       nic->mac_control.stats_info->sw_stat.
-                               single_ecc_errs++;
-               }
-       }
-
-       /* In case of a serious error, the device will be Reset. */
-       val64 = readq(&bar0->serr_source);
-       if (val64 & SERR_SOURCE_ANY) {
-               nic->mac_control.stats_info->sw_stat.serious_err_cnt++;
-               DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name);
-               DBG_PRINT(ERR_DBG, "serious error %llx!!\n",
-                         (unsigned long long)val64);
-               netif_stop_queue(dev);
-               schedule_work(&nic->rst_timer_task);
-               nic->mac_control.stats_info->sw_stat.soft_reset_cnt++;
-       }
-
-       /*
-        * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC
-        * Error occurs, the adapter will be recycled by disabling the
-        * adapter enable bit and enabling it again after the device
-        * becomes Quiescent.
-        */
-       val64 = readq(&bar0->pcc_err_reg);
-       writeq(val64, &bar0->pcc_err_reg);
-       if (val64 & PCC_FB_ECC_DB_ERR) {
-               u64 ac = readq(&bar0->adapter_control);
-               ac &= ~(ADAPTER_CNTL_EN);
-               writeq(ac, &bar0->adapter_control);
-               ac = readq(&bar0->adapter_control);
-               schedule_work(&nic->set_link_task);
-       }
-       /* Check for data parity error */
-       val64 = readq(&bar0->pic_int_status);
-       if (val64 & PIC_INT_GPIO) {
-               val64 = readq(&bar0->gpio_int_reg);
-               if (val64 & GPIO_INT_REG_DP_ERR_INT) {
-                       nic->mac_control.stats_info->sw_stat.parity_err_cnt++;
-                       schedule_work(&nic->rst_timer_task);
-                       nic->mac_control.stats_info->sw_stat.soft_reset_cnt++;
-               }
-       }
-
-       /* Check for ring full counter */
-       if (nic->device_type & XFRAME_II_DEVICE) {
-               val64 = readq(&bar0->ring_bump_counter1);
-               for (i=0; i<4; i++) {
-                       cnt = ( val64 & vBIT(0xFFFF,(i*16),16));
-                       cnt >>= 64 - ((i+1)*16);
-                       nic->mac_control.stats_info->sw_stat.ring_full_cnt
-                               += cnt;
-               }
-
-               val64 = readq(&bar0->ring_bump_counter2);
-               for (i=0; i<4; i++) {
-                       cnt = ( val64 & vBIT(0xFFFF,(i*16),16));
-                       cnt >>= 64 - ((i+1)*16);
-                       nic->mac_control.stats_info->sw_stat.ring_full_cnt
-                               += cnt;
-               }
-       }
-
-       /* Other type of interrupts are not being handled now,  TODO */
-}
-
 /**
  *  wait_for_cmd_complete - waits for a command to complete.
  *  @sp : private member of the device structure, which is a pointer to the
@@ -3565,7 +3546,7 @@ static int s2io_set_swapper(struct s2io_nic * sp)
                 SWAPPER_CTRL_RXF_W_FE |
                 SWAPPER_CTRL_XMSI_FE |
                 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
-       if (sp->intr_type == INTA)
+       if (sp->config.intr_type == INTA)
                val64 |= SWAPPER_CTRL_XMSI_SE;
        writeq(val64, &bar0->swapper_ctrl);
 #else
@@ -3588,7 +3569,7 @@ static int s2io_set_swapper(struct s2io_nic * sp)
                 SWAPPER_CTRL_RXF_W_FE |
                 SWAPPER_CTRL_XMSI_FE |
                 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
-       if (sp->intr_type == INTA)
+       if (sp->config.intr_type == INTA)
                val64 |= SWAPPER_CTRL_XMSI_SE;
        writeq(val64, &bar0->swapper_ctrl);
 #endif
@@ -3781,6 +3762,59 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
        return 0;
 }
 
+/* Handle software interrupt used during MSI(X) test */
+static irqreturn_t __devinit s2io_test_intr(int irq, void *dev_id)
+{
+       struct s2io_nic *sp = dev_id;
+
+       sp->msi_detected = 1;
+       wake_up(&sp->msi_wait);
+
+       return IRQ_HANDLED;
+}
+
+/* Test interrupt path by forcing a a software IRQ */
+static int __devinit s2io_test_msi(struct s2io_nic *sp)
+{
+       struct pci_dev *pdev = sp->pdev;
+       struct XENA_dev_config __iomem *bar0 = sp->bar0;
+       int err;
+       u64 val64, saved64;
+
+       err = request_irq(sp->entries[1].vector, s2io_test_intr, 0,
+                       sp->name, sp);
+       if (err) {
+               DBG_PRINT(ERR_DBG, "%s: PCI %s: cannot assign irq %d\n",
+                      sp->dev->name, pci_name(pdev), pdev->irq);
+               return err;
+       }
+
+       init_waitqueue_head (&sp->msi_wait);
+       sp->msi_detected = 0;
+
+       saved64 = val64 = readq(&bar0->scheduled_int_ctrl);
+       val64 |= SCHED_INT_CTRL_ONE_SHOT;
+       val64 |= SCHED_INT_CTRL_TIMER_EN;
+       val64 |= SCHED_INT_CTRL_INT2MSI(1);
+       writeq(val64, &bar0->scheduled_int_ctrl);
+
+       wait_event_timeout(sp->msi_wait, sp->msi_detected, HZ/10);
+
+       if (!sp->msi_detected) {
+               /* MSI(X) test failed, go back to INTx mode */
+               DBG_PRINT(ERR_DBG, "%s: PCI %s: No interrupt was generated"
+                       "using MSI(X) during test\n", sp->dev->name,
+                       pci_name(pdev));
+
+               err = -EOPNOTSUPP;
+       }
+
+       free_irq(sp->entries[1].vector, sp);
+
+       writeq(saved64, &bar0->scheduled_int_ctrl);
+
+       return err;
+}
 /* ********************************************************* *
  * Functions defined below concern the OS part of the driver *
  * ********************************************************* */
@@ -3809,6 +3843,50 @@ static int s2io_open(struct net_device *dev)
        netif_carrier_off(dev);
        sp->last_link_state = 0;
 
+       napi_enable(&sp->napi);
+
+       if (sp->config.intr_type == MSI_X) {
+               int ret = s2io_enable_msi_x(sp);
+
+               if (!ret) {
+                       u16 msi_control;
+
+                       ret = s2io_test_msi(sp);
+
+                       /* rollback MSI-X, will re-enable during add_isr() */
+                       kfree(sp->entries);
+                       sp->mac_control.stats_info->sw_stat.mem_freed +=
+                               (MAX_REQUESTED_MSI_X *
+                               sizeof(struct msix_entry));
+                       kfree(sp->s2io_entries);
+                       sp->mac_control.stats_info->sw_stat.mem_freed +=
+                               (MAX_REQUESTED_MSI_X *
+                               sizeof(struct s2io_msix_entry));
+                       sp->entries = NULL;
+                       sp->s2io_entries = NULL;
+
+                       pci_read_config_word(sp->pdev, 0x42, &msi_control);
+                       msi_control &= 0xFFFE; /* Disable MSI */
+                       pci_write_config_word(sp->pdev, 0x42, msi_control);
+
+                       pci_disable_msix(sp->pdev);
+
+               }
+               if (ret) {
+
+                       DBG_PRINT(ERR_DBG,
+                         "%s: MSI-X requested but failed to enable\n",
+                         dev->name);
+                       sp->config.intr_type = INTA;
+               }
+       }
+
+       /* NAPI doesn't work well with MSI(X) */
+        if (sp->config.intr_type != INTA) {
+               if(sp->config.napi)
+                       sp->config.napi = 0;
+       }
+
        /* Initialize H/W and enable interrupts */
        err = s2io_card_up(sp);
        if (err) {
@@ -3828,7 +3906,8 @@ static int s2io_open(struct net_device *dev)
        return 0;
 
 hw_init_failed:
-       if (sp->intr_type == MSI_X) {
+       napi_disable(&sp->napi);
+       if (sp->config.intr_type == MSI_X) {
                if (sp->entries) {
                        kfree(sp->entries);
                        sp->mac_control.stats_info->sw_stat.mem_freed 
@@ -3861,6 +3940,7 @@ static int s2io_close(struct net_device *dev)
        struct s2io_nic *sp = dev->priv;
 
        netif_stop_queue(dev);
+       napi_disable(&sp->napi);
        /* Reset card, kill tasklet and free Tx and Rx buffers. */
        s2io_card_down(sp);
 
@@ -3907,7 +3987,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
        spin_lock_irqsave(&sp->tx_lock, flags);
-       if (atomic_read(&sp->card_state) == CARD_DOWN) {
+       if (!is_s2io_card_up(sp)) {
                DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
                          dev->name);
                spin_unlock_irqrestore(&sp->tx_lock, flags);
@@ -4059,8 +4139,9 @@ static void
 s2io_alarm_handle(unsigned long data)
 {
        struct s2io_nic *sp = (struct s2io_nic *)data;
+       struct net_device *dev = sp->dev;
 
-       alarm_intr_handler(sp);
+       s2io_handle_errors(dev);
        mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
 }
 
@@ -4098,12 +4179,12 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
        struct ring_info *ring = (struct ring_info *)dev_id;
        struct s2io_nic *sp = ring->nic;
 
-       atomic_inc(&sp->isr_cnt);
+       if (!is_s2io_card_up(sp))
+               return IRQ_HANDLED;
 
        rx_intr_handler(ring);
        s2io_chk_rx_buffers(sp, ring->ring_no);
 
-       atomic_dec(&sp->isr_cnt);
        return IRQ_HANDLED;
 }
 
@@ -4112,9 +4193,10 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
        struct fifo_info *fifo = (struct fifo_info *)dev_id;
        struct s2io_nic *sp = fifo->nic;
 
-       atomic_inc(&sp->isr_cnt);
+       if (!is_s2io_card_up(sp))
+               return IRQ_HANDLED;
+
        tx_intr_handler(fifo);
-       atomic_dec(&sp->isr_cnt);
        return IRQ_HANDLED;
 }
 static void s2io_txpic_intr_handle(struct s2io_nic *sp)
@@ -4178,6 +4260,292 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
        val64 = readq(&bar0->gpio_int_mask);
 }
 
+/**
+ *  do_s2io_chk_alarm_bit - Check for alarm and incrment the counter
+ *  @value: alarm bits
+ *  @addr: address value
+ *  @cnt: counter variable
+ *  Description: Check for alarm and increment the counter
+ *  Return Value:
+ *  1 - if alarm bit set
+ *  0 - if alarm bit is not set
+ */
+int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
+                         unsigned long long *cnt)
+{
+       u64 val64;
+       val64 = readq(addr);
+       if ( val64 & value ) {
+               writeq(val64, addr);
+               (*cnt)++;
+               return 1;
+       }
+       return 0;
+
+}
+
+/**
+ *  s2io_handle_errors - Xframe error indication handler
+ *  @nic: device private variable
+ *  Description: Handle alarms such as loss of link, single or
+ *  double ECC errors, critical and serious errors.
+ *  Return Value:
+ *  NONE
+ */
+static void s2io_handle_errors(void * dev_id)
+{
+       struct net_device *dev = (struct net_device *) dev_id;
+       struct s2io_nic *sp = dev->priv;
+       struct XENA_dev_config __iomem *bar0 = sp->bar0;
+       u64 temp64 = 0,val64=0;
+       int i = 0;
+
+       struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat;
+       struct xpakStat *stats = &sp->mac_control.stats_info->xpak_stat;
+
+       if (!is_s2io_card_up(sp))
+               return;
+
+       if (pci_channel_offline(sp->pdev))
+               return;
+
+       memset(&sw_stat->ring_full_cnt, 0,
+               sizeof(sw_stat->ring_full_cnt));
+
+       /* Handling the XPAK counters update */
+       if(stats->xpak_timer_count < 72000) {
+               /* waiting for an hour */
+               stats->xpak_timer_count++;
+       } else {
+               s2io_updt_xpak_counter(dev);
+               /* reset the count to zero */
+               stats->xpak_timer_count = 0;
+       }
+
+       /* Handling link status change error Intr */
+       if (s2io_link_fault_indication(sp) == MAC_RMAC_ERR_TIMER) {
+               val64 = readq(&bar0->mac_rmac_err_reg);
+               writeq(val64, &bar0->mac_rmac_err_reg);
+               if (val64 & RMAC_LINK_STATE_CHANGE_INT)
+                       schedule_work(&sp->set_link_task);
+       }
+
+       /* In case of a serious error, the device will be Reset. */
+       if (do_s2io_chk_alarm_bit(SERR_SOURCE_ANY, &bar0->serr_source,
+                               &sw_stat->serious_err_cnt))
+               goto reset;
+
+       /* Check for data parity error */
+       if (do_s2io_chk_alarm_bit(GPIO_INT_REG_DP_ERR_INT, &bar0->gpio_int_reg,
+                               &sw_stat->parity_err_cnt))
+               goto reset;
+
+       /* Check for ring full counter */
+       if (sp->device_type == XFRAME_II_DEVICE) {
+               val64 = readq(&bar0->ring_bump_counter1);
+               for (i=0; i<4; i++) {
+                       temp64 = ( val64 & vBIT(0xFFFF,(i*16),16));
+                       temp64 >>= 64 - ((i+1)*16);
+                       sw_stat->ring_full_cnt[i] += temp64;
+               }
+
+               val64 = readq(&bar0->ring_bump_counter2);
+               for (i=0; i<4; i++) {
+                       temp64 = ( val64 & vBIT(0xFFFF,(i*16),16));
+                       temp64 >>= 64 - ((i+1)*16);
+                        sw_stat->ring_full_cnt[i+4] += temp64;
+               }
+       }
+
+       val64 = readq(&bar0->txdma_int_status);
+       /*check for pfc_err*/
+       if (val64 & TXDMA_PFC_INT) {
+               if (do_s2io_chk_alarm_bit(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM|
+                               PFC_MISC_0_ERR | PFC_MISC_1_ERR|
+                               PFC_PCIX_ERR, &bar0->pfc_err_reg,
+                               &sw_stat->pfc_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(PFC_ECC_SG_ERR, &bar0->pfc_err_reg,
+                               &sw_stat->pfc_err_cnt);
+       }
+
+       /*check for tda_err*/
+       if (val64 & TXDMA_TDA_INT) {
+               if(do_s2io_chk_alarm_bit(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM |
+                               TDA_SM1_ERR_ALARM, &bar0->tda_err_reg,
+                               &sw_stat->tda_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(TDA_Fn_ECC_SG_ERR | TDA_PCIX_ERR,
+                               &bar0->tda_err_reg, &sw_stat->tda_err_cnt);
+       }
+       /*check for pcc_err*/
+       if (val64 & TXDMA_PCC_INT) {
+               if (do_s2io_chk_alarm_bit(PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM
+                               | PCC_N_SERR | PCC_6_COF_OV_ERR
+                               | PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR
+                               | PCC_7_LSO_OV_ERR | PCC_FB_ECC_DB_ERR
+                               | PCC_TXB_ECC_DB_ERR, &bar0->pcc_err_reg,
+                               &sw_stat->pcc_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(PCC_FB_ECC_SG_ERR | PCC_TXB_ECC_SG_ERR,
+                               &bar0->pcc_err_reg, &sw_stat->pcc_err_cnt);
+       }
+
+       /*check for tti_err*/
+       if (val64 & TXDMA_TTI_INT) {
+               if (do_s2io_chk_alarm_bit(TTI_SM_ERR_ALARM, &bar0->tti_err_reg,
+                               &sw_stat->tti_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(TTI_ECC_SG_ERR | TTI_ECC_DB_ERR,
+                               &bar0->tti_err_reg, &sw_stat->tti_err_cnt);
+       }
+
+       /*check for lso_err*/
+       if (val64 & TXDMA_LSO_INT) {
+               if (do_s2io_chk_alarm_bit(LSO6_ABORT | LSO7_ABORT
+                               | LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM,
+                               &bar0->lso_err_reg, &sw_stat->lso_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
+                               &bar0->lso_err_reg, &sw_stat->lso_err_cnt);
+       }
+
+       /*check for tpa_err*/
+       if (val64 & TXDMA_TPA_INT) {
+               if (do_s2io_chk_alarm_bit(TPA_SM_ERR_ALARM, &bar0->tpa_err_reg,
+                       &sw_stat->tpa_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(TPA_TX_FRM_DROP, &bar0->tpa_err_reg,
+                       &sw_stat->tpa_err_cnt);
+       }
+
+       /*check for sm_err*/
+       if (val64 & TXDMA_SM_INT) {
+               if (do_s2io_chk_alarm_bit(SM_SM_ERR_ALARM, &bar0->sm_err_reg,
+                       &sw_stat->sm_err_cnt))
+                       goto reset;
+       }
+
+       val64 = readq(&bar0->mac_int_status);
+       if (val64 & MAC_INT_STATUS_TMAC_INT) {
+               if (do_s2io_chk_alarm_bit(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR,
+                               &bar0->mac_tmac_err_reg,
+                               &sw_stat->mac_tmac_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR
+                               | TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
+                               &bar0->mac_tmac_err_reg,
+                               &sw_stat->mac_tmac_err_cnt);
+       }
+
+       val64 = readq(&bar0->xgxs_int_status);
+       if (val64 & XGXS_INT_STATUS_TXGXS) {
+               if (do_s2io_chk_alarm_bit(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR,
+                               &bar0->xgxs_txgxs_err_reg,
+                               &sw_stat->xgxs_txgxs_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
+                               &bar0->xgxs_txgxs_err_reg,
+                               &sw_stat->xgxs_txgxs_err_cnt);
+       }
+
+       val64 = readq(&bar0->rxdma_int_status);
+       if (val64 & RXDMA_INT_RC_INT_M) {
+               if (do_s2io_chk_alarm_bit(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR
+                               | RC_PRCn_SM_ERR_ALARM |RC_FTC_SM_ERR_ALARM,
+                               &bar0->rc_err_reg, &sw_stat->rc_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR
+                               | RC_RDA_FAIL_WR_Rn, &bar0->rc_err_reg,
+                               &sw_stat->rc_err_cnt);
+               if (do_s2io_chk_alarm_bit(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn
+                               | PRC_PCI_AB_F_WR_Rn, &bar0->prc_pcix_err_reg,
+                               &sw_stat->prc_pcix_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(PRC_PCI_DP_RD_Rn | PRC_PCI_DP_WR_Rn
+                               | PRC_PCI_DP_F_WR_Rn, &bar0->prc_pcix_err_reg,
+                               &sw_stat->prc_pcix_err_cnt);
+       }
+
+       if (val64 & RXDMA_INT_RPA_INT_M) {
+               if (do_s2io_chk_alarm_bit(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR,
+                               &bar0->rpa_err_reg, &sw_stat->rpa_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(RPA_ECC_SG_ERR | RPA_ECC_DB_ERR,
+                               &bar0->rpa_err_reg, &sw_stat->rpa_err_cnt);
+       }
+
+       if (val64 & RXDMA_INT_RDA_INT_M) {
+               if (do_s2io_chk_alarm_bit(RDA_RXDn_ECC_DB_ERR
+                               | RDA_FRM_ECC_DB_N_AERR | RDA_SM1_ERR_ALARM
+                               | RDA_SM0_ERR_ALARM | RDA_RXD_ECC_DB_SERR,
+                               &bar0->rda_err_reg, &sw_stat->rda_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(RDA_RXDn_ECC_SG_ERR | RDA_FRM_ECC_SG_ERR
+                               | RDA_MISC_ERR | RDA_PCIX_ERR,
+                               &bar0->rda_err_reg, &sw_stat->rda_err_cnt);
+       }
+
+       if (val64 & RXDMA_INT_RTI_INT_M) {
+               if (do_s2io_chk_alarm_bit(RTI_SM_ERR_ALARM, &bar0->rti_err_reg,
+                               &sw_stat->rti_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
+                               &bar0->rti_err_reg, &sw_stat->rti_err_cnt);
+       }
+
+       val64 = readq(&bar0->mac_int_status);
+       if (val64 & MAC_INT_STATUS_RMAC_INT) {
+               if (do_s2io_chk_alarm_bit(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR,
+                               &bar0->mac_rmac_err_reg,
+                               &sw_stat->mac_rmac_err_cnt))
+                       goto reset;
+               do_s2io_chk_alarm_bit(RMAC_UNUSED_INT|RMAC_SINGLE_ECC_ERR|
+                               RMAC_DOUBLE_ECC_ERR, &bar0->mac_rmac_err_reg,
+                               &sw_stat->mac_rmac_err_cnt);
+       }
+
+       val64 = readq(&bar0->xgxs_int_status);
+       if (val64 & XGXS_INT_STATUS_RXGXS) {
+               if (do_s2io_chk_alarm_bit(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR,
+                               &bar0->xgxs_rxgxs_err_reg,
+                               &sw_stat->xgxs_rxgxs_err_cnt))
+                       goto reset;
+       }
+
+       val64 = readq(&bar0->mc_int_status);
+       if(val64 & MC_INT_STATUS_MC_INT) {
+               if (do_s2io_chk_alarm_bit(MC_ERR_REG_SM_ERR, &bar0->mc_err_reg,
+                               &sw_stat->mc_err_cnt))
+                       goto reset;
+
+               /* Handling Ecc errors */
+               if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) {
+                       writeq(val64, &bar0->mc_err_reg);
+                       if (val64 & MC_ERR_REG_ECC_ALL_DBL) {
+                               sw_stat->double_ecc_errs++;
+                               if (sp->device_type != XFRAME_II_DEVICE) {
+                                       /*
+                                        * Reset XframeI only if critical error
+                                        */
+                                       if (val64 &
+                                               (MC_ERR_REG_MIRI_ECC_DB_ERR_0 |
+                                               MC_ERR_REG_MIRI_ECC_DB_ERR_1))
+                                                               goto reset;
+                                       }
+                       } else
+                               sw_stat->single_ecc_errs++;
+               }
+       }
+       return;
+
+reset:
+       netif_stop_queue(dev);
+       schedule_work(&sp->rst_timer_task);
+       sw_stat->soft_reset_cnt++;
+       return;
+}
+
 /**
  *  s2io_isr - ISR handler of the device .
  *  @irq: the irq of the device.
@@ -4205,7 +4573,9 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
        if (pci_channel_offline(sp->pdev))
                return IRQ_NONE;
 
-       atomic_inc(&sp->isr_cnt);
+       if (!is_s2io_card_up(sp))
+               return IRQ_NONE;
+
        mac_control = &sp->mac_control;
        config = &sp->config;
 
@@ -4215,73 +4585,75 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
         * 1. Rx of packet.
         * 2. Tx complete.
         * 3. Link down.
-        * 4. Error in any functional blocks of the NIC.
         */
        reason = readq(&bar0->general_int_status);
 
-       if (!reason) {
-               /* The interrupt was not raised by us. */
-               atomic_dec(&sp->isr_cnt);
-               return IRQ_NONE;
-       }
-       else if (unlikely(reason == S2IO_MINUS_ONE) ) {
-               /* Disable device and get out */
-               atomic_dec(&sp->isr_cnt);
-               return IRQ_NONE;
+       if (unlikely(reason == S2IO_MINUS_ONE) ) {
+               /* Nothing much can be done. Get out */
+               return IRQ_HANDLED;
        }
 
-       if (napi) {
-               if (reason & GEN_INTR_RXTRAFFIC) {
-                       if ( likely ( netif_rx_schedule_prep(dev)) ) {
-                               __netif_rx_schedule(dev);
-                               writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
+       if (reason & (GEN_INTR_RXTRAFFIC |
+               GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC))
+       {
+               writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
+
+               if (config->napi) {
+                       if (reason & GEN_INTR_RXTRAFFIC) {
+                               if (likely(netif_rx_schedule_prep(dev,
+                                                       &sp->napi))) {
+                                       __netif_rx_schedule(dev, &sp->napi);
+                                       writeq(S2IO_MINUS_ONE,
+                                              &bar0->rx_traffic_mask);
+                               } else
+                                       writeq(S2IO_MINUS_ONE,
+                                              &bar0->rx_traffic_int);
                        }
-                       else
+               } else {
+                       /*
+                        * 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.
+                        */
+                       if (reason & GEN_INTR_RXTRAFFIC)
                                writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+
+                       for (i = 0; i < config->rx_ring_num; i++)
+                               rx_intr_handler(&mac_control->rings[i]);
                }
-       } else {
+
                /*
-                * Rx handler is called by default, without checking for the
-                * cause of interrupt.
-                * rx_traffic_int reg is an R1 register, writing all 1's
+                * 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.
                 */
-               if (reason & GEN_INTR_RXTRAFFIC)
-                       writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+               if (reason & GEN_INTR_TXTRAFFIC)
+                       writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
 
-               for (i = 0; i < config->rx_ring_num; i++) {
-                       rx_intr_handler(&mac_control->rings[i]);
-               }
-       }
+               for (i = 0; i < config->tx_fifo_num; i++)
+                       tx_intr_handler(&mac_control->fifos[i]);
 
-       /*
-        * 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.
-        */
-       if (reason & GEN_INTR_TXTRAFFIC)
-               writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
+               if (reason & GEN_INTR_TXPIC)
+                       s2io_txpic_intr_handle(sp);
 
-       for (i = 0; i < config->tx_fifo_num; i++)
-               tx_intr_handler(&mac_control->fifos[i]);
+               /*
+                * Reallocate the buffers from the interrupt handler itself.
+                */
+               if (!config->napi) {
+                       for (i = 0; i < config->rx_ring_num; i++)
+                               s2io_chk_rx_buffers(sp, i);
+               }
+               writeq(sp->general_int_mask, &bar0->general_int_mask);
+               readl(&bar0->general_int_status);
 
-       if (reason & GEN_INTR_TXPIC)
-               s2io_txpic_intr_handle(sp);
-       /*
-        * If the Rx buffer count is below the panic threshold then
-        * reallocate the buffers from the interrupt handler itself,
-        * else schedule a tasklet to reallocate the buffers.
-        */
-       if (!napi) {
-               for (i = 0; i < config->rx_ring_num; i++)
-                       s2io_chk_rx_buffers(sp, i);
-       }
+               return IRQ_HANDLED;
 
-       writeq(0, &bar0->general_int_mask);
-       readl(&bar0->general_int_status);
+       }
+       else if (!reason) {
+               /* The interrupt was not raised by us */
+               return IRQ_NONE;
+       }
 
-       atomic_dec(&sp->isr_cnt);
        return IRQ_HANDLED;
 }
 
@@ -4294,7 +4666,7 @@ static void s2io_updt_stats(struct s2io_nic *sp)
        u64 val64;
        int cnt = 0;
 
-       if (atomic_read(&sp->card_state) == CARD_UP) {
+       if (is_s2io_card_up(sp)) {
                /* Apprx 30us on a 133 MHz bus */
                val64 = SET_UPDT_CLICKS(10) |
                        STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN;
@@ -5567,7 +5939,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
                                   struct ethtool_stats *estats,
                                   u64 * tmp_stats)
 {
-       int i = 0;
+       int i = 0, k;
        struct s2io_nic *sp = dev->priv;
        struct stat_block *stat_info = sp->mac_control.stats_info;
 
@@ -5762,7 +6134,8 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
        tmp_stats[i++] = stat_info->sw_stat.serious_err_cnt;
        tmp_stats[i++] = stat_info->sw_stat.soft_reset_cnt;
        tmp_stats[i++] = stat_info->sw_stat.fifo_full_cnt;
-       tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt;
+       for (k = 0; k < MAX_RX_RINGS; k++)
+               tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt[k];
        tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_high;
        tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_low;
        tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_high;
@@ -5819,6 +6192,23 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
        tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt;
        tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt;
        tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.tda_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.pfc_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.pcc_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.tti_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.tpa_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.sm_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.lso_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.mac_tmac_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.mac_rmac_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.xgxs_txgxs_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.xgxs_rxgxs_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rc_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.prc_pcix_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rpa_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rda_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rti_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.mc_err_cnt;
 }
 
 static int s2io_ethtool_get_regs_len(struct net_device *dev)
@@ -5936,13 +6326,10 @@ static const struct ethtool_ops netdev_ethtool_ops = {
        .set_pauseparam = s2io_ethtool_setpause_data,
        .get_rx_csum = s2io_ethtool_get_rx_csum,
        .set_rx_csum = s2io_ethtool_set_rx_csum,
-       .get_tx_csum = ethtool_op_get_tx_csum,
        .set_tx_csum = s2io_ethtool_op_set_tx_csum,
-       .get_sg = ethtool_op_get_sg,
        .set_sg = ethtool_op_set_sg,
        .get_tso = s2io_ethtool_op_get_tso,
        .set_tso = s2io_ethtool_op_set_tso,
-       .get_ufo = ethtool_op_get_ufo,
        .set_ufo = ethtool_op_set_ufo,
        .self_test_count = s2io_ethtool_self_test_count,
        .self_test = s2io_ethtool_test,
@@ -6072,7 +6459,7 @@ static void s2io_set_link(struct work_struct *work)
        if (!netif_running(dev))
                goto out_unlock;
 
-       if (test_and_set_bit(0, &(nic->link_state))) {
+       if (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(nic->state))) {
                /* The card is being reset, no point doing anything */
                goto out_unlock;
        }
@@ -6110,13 +6497,10 @@ static void s2io_set_link(struct work_struct *work)
                                netif_stop_queue(dev);
                        }
                }
-               val64 = readq(&bar0->adapter_status);
-               if (!LINK_IS_UP(val64)) {
-                       DBG_PRINT(ERR_DBG, "%s:", dev->name);
-                       DBG_PRINT(ERR_DBG, " Link down after enabling ");
-                       DBG_PRINT(ERR_DBG, "device \n");
-               } else
-                       s2io_link(nic, LINK_UP);
+               val64 = readq(&bar0->adapter_control);
+               val64 |= ADAPTER_LED_ON;
+               writeq(val64, &bar0->adapter_control);
+               s2io_link(nic, LINK_UP);
        } else {
                if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type,
                                                      subid)) {
@@ -6125,9 +6509,13 @@ static void s2io_set_link(struct work_struct *work)
                        writeq(val64, &bar0->gpio_control);
                        val64 = readq(&bar0->gpio_control);
                }
+               /* turn off LED */
+               val64 = readq(&bar0->adapter_control);
+               val64 = val64 &(~ADAPTER_LED_ON);
+               writeq(val64, &bar0->adapter_control);
                s2io_link(nic, LINK_DOWN);
        }
-       clear_bit(0, &(nic->link_state));
+       clear_bit(__S2IO_STATE_LINK_TASK, &(nic->state));
 
 out_unlock:
        rtnl_unlock();
@@ -6211,7 +6599,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                        if( (rxdp3->Buffer0_ptr == 0) ||
                                (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) {
                                pci_unmap_single (sp->pdev,
-                                       (dma_addr_t)(*skb)->data,
+                                       (dma_addr_t)rxdp3->Buffer2_ptr,
                                        dev->mtu + 4, PCI_DMA_FROMDEVICE);
                                goto memalloc_failed;
                        }
@@ -6224,7 +6612,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                        if( (rxdp3->Buffer1_ptr == 0) ||
                                (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
                                pci_unmap_single (sp->pdev,
-                                       (dma_addr_t)(*skb)->data,
+                                       (dma_addr_t)rxdp3->Buffer0_ptr,
+                                       BUF0_LEN, PCI_DMA_FROMDEVICE);
+                               pci_unmap_single (sp->pdev,
+                                       (dma_addr_t)rxdp3->Buffer2_ptr,
                                        dev->mtu + 4, PCI_DMA_FROMDEVICE);
                                goto memalloc_failed;
                        }
@@ -6305,18 +6696,18 @@ static int s2io_add_isr(struct s2io_nic * sp)
        struct net_device *dev = sp->dev;
        int err = 0;
 
-       if (sp->intr_type == MSI_X)
+       if (sp->config.intr_type == MSI_X)
                ret = s2io_enable_msi_x(sp);
        if (ret) {
                DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
-               sp->intr_type = INTA;
+               sp->config.intr_type = INTA;
        }
 
        /* Store the values of the MSIX table in the struct s2io_nic structure */
        store_xmsi_data(sp);
 
        /* After proper initialization of H/W, register ISR */
-       if (sp->intr_type == MSI_X) {
+       if (sp->config.intr_type == MSI_X) {
                int i, msix_tx_cnt=0,msix_rx_cnt=0;
 
                for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
@@ -6368,7 +6759,7 @@ static int s2io_add_isr(struct s2io_nic * sp)
                printk("MSI-X-TX %d entries enabled\n",msix_tx_cnt);
                printk("MSI-X-RX %d entries enabled\n",msix_rx_cnt);
        }
-       if (sp->intr_type == INTA) {
+       if (sp->config.intr_type == INTA) {
                err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED,
                                sp->name, dev);
                if (err) {
@@ -6381,10 +6772,10 @@ static int s2io_add_isr(struct s2io_nic * sp)
 }
 static void s2io_rem_isr(struct s2io_nic * sp)
 {
-       int cnt = 0;
        struct net_device *dev = sp->dev;
+       struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
 
-       if (sp->intr_type == MSI_X) {
+       if (sp->config.intr_type == MSI_X) {
                int i;
                u16 msi_control;
 
@@ -6393,24 +6784,28 @@ static void s2io_rem_isr(struct s2io_nic * sp)
                        int vector = sp->entries[i].vector;
                        void *arg = sp->s2io_entries[i].arg;
 
+                       synchronize_irq(vector);
                        free_irq(vector, arg);
                }
+
+               kfree(sp->entries);
+               stats->mem_freed +=
+                       (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+               kfree(sp->s2io_entries);
+               stats->mem_freed +=
+                       (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
+               sp->entries = NULL;
+               sp->s2io_entries = NULL;
+
                pci_read_config_word(sp->pdev, 0x42, &msi_control);
                msi_control &= 0xFFFE; /* Disable MSI */
                pci_write_config_word(sp->pdev, 0x42, msi_control);
 
                pci_disable_msix(sp->pdev);
        } else {
+               synchronize_irq(sp->pdev->irq);
                free_irq(sp->pdev->irq, dev);
        }
-       /* Waiting till all Interrupt handlers are complete */
-       cnt = 0;
-       do {
-               msleep(10);
-               if (!atomic_read(&sp->isr_cnt))
-                       break;
-               cnt++;
-       } while(cnt < 5);
 }
 
 static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
@@ -6422,10 +6817,10 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 
        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))) {
+       while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state))) {
                msleep(50);
        }
-       atomic_set(&sp->card_state, CARD_DOWN);
+       clear_bit(__S2IO_STATE_CARD_UP, &sp->state);
 
        /* disable Tx and Rx traffic on the NIC */
        if (do_io)
@@ -6476,7 +6871,7 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
        free_rx_buffers(sp);
        spin_unlock_irqrestore(&sp->rx_lock, flags);
 
-       clear_bit(0, &(sp->link_state));
+       clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state));
 }
 
 static void s2io_card_down(struct s2io_nic * sp)
@@ -6547,7 +6942,7 @@ static int s2io_card_up(struct s2io_nic * sp)
 
        /* Add interrupt service routine */
        if (s2io_add_isr(sp) != 0) {
-               if (sp->intr_type == MSI_X)
+               if (sp->config.intr_type == MSI_X)
                        s2io_rem_isr(sp);
                s2io_reset(sp);
                free_rx_buffers(sp);
@@ -6560,17 +6955,16 @@ static int s2io_card_up(struct s2io_nic * sp)
        tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev);
 
        /*  Enable select interrupts */
-       if (sp->intr_type != INTA)
+       en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
+       if (sp->config.intr_type != INTA)
                en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS);
        else {
                interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
-               interruptible |= TX_PIC_INTR | RX_PIC_INTR;
-               interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+               interruptible |= TX_PIC_INTR;
                en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
        }
 
-
-       atomic_set(&sp->card_state, CARD_UP);
+       set_bit(__S2IO_STATE_CARD_UP, &sp->state);
        return 0;
 }
 
@@ -6734,6 +7128,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
        }
 
        /* Updating statistics */
+       sp->stats.rx_packets++;
        rxdp->Host_Control = 0;
        if (sp->rxd_mode == RXD_MODE_1) {
                int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
@@ -6940,19 +7335,12 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
        if (*dev_intr_type != INTA)
                napi = 0;
 
-#ifndef CONFIG_PCI_MSI
-       if (*dev_intr_type != INTA) {
-               DBG_PRINT(ERR_DBG, "s2io: This kernel does not support"
-                         "MSI/MSI-X. Defaulting to INTA\n");
-               *dev_intr_type = INTA;
-       }
-#else
        if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
                DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
                          "Defaulting to INTA\n");
                *dev_intr_type = INTA;
        }
-#endif
+
        if ((*dev_intr_type == MSI_X) &&
                        ((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
                        (pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
@@ -7029,6 +7417,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        struct config_param *config;
        int mode;
        u8 dev_intr_type = intr_type;
+       DECLARE_MAC_BUF(mac);
 
        if ((ret = s2io_verify_parm(pdev, &dev_intr_type)))
                return ret;
@@ -7072,7 +7461,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
        pci_set_master(pdev);
        pci_set_drvdata(pdev, dev);
-       SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        /*  Private member variable initialized to s2io NIC structure */
@@ -7087,7 +7475,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        if (rx_ring_mode == 2)
                sp->rxd_mode = RXD_MODE_3B;
 
-       sp->intr_type = dev_intr_type;
+       sp->config.intr_type = dev_intr_type;
 
        if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
                (pdev->device == PCI_DEVICE_ID_HERC_UNI))
@@ -7110,6 +7498,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        mac_control = &sp->mac_control;
        config = &sp->config;
 
+       config->napi = napi;
+
        /* Tx side parameters. */
        config->tx_fifo_num = tx_fifo_num;
        for (i = 0; i < MAX_TX_FIFOS; i++) {
@@ -7157,9 +7547,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        for (i = 0; i < config->rx_ring_num; i++)
                atomic_set(&sp->rx_bufs_left[i], 0);
 
-       /* Initialize the number of ISRs currently running */
-       atomic_set(&sp->isr_cnt, 0);
-
        /*  initialize the shared memory used by the NIC and the host */
        if (init_shared_mem(sp)) {
                DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n",
@@ -7211,8 +7598,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
         * will use eth_mac_addr() for  dev->set_mac_address
         * mac address will be set every time dev->open() is called
         */
-       dev->poll = s2io_poll;
-       dev->weight = 32;
+       netif_napi_add(dev, &sp->napi, s2io_poll, 32);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = s2io_netpoll;
@@ -7289,6 +7675,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        dev->addr_len = ETH_ALEN;
        memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN);
 
+        /* Store the values of the MSIX table in the s2io_nic structure */
+       store_xmsi_data(sp);
        /* reset Nic and bring it to known state */
        s2io_reset(sp);
 
@@ -7296,9 +7684,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
         * Initialize the tasklet status and link state flags
         * and the card state parameter
         */
-       atomic_set(&(sp->card_state), 0);
        sp->tasklet_status = 0;
-       sp->link_state = 0;
+       sp->state = 0;
 
        /* Initialize spinlocks */
        spin_lock_init(&sp->tx_lock);
@@ -7334,14 +7721,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                  sp->product_name, pdev->revision);
        DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
                  s2io_driver_version);
-       DBG_PRINT(ERR_DBG, "%s: MAC ADDR: "
-                         "%02x:%02x:%02x:%02x:%02x:%02x", dev->name,
-                         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]);
+       DBG_PRINT(ERR_DBG, "%s: MAC ADDR: %s\n",
+                 dev->name, print_mac(mac, dev->dev_addr));
        DBG_PRINT(ERR_DBG, "SERIAL NUMBER: %s\n", sp->serial_num);
        if (sp->device_type & XFRAME_II_DEVICE) {
                mode = s2io_print_pci_mode(sp);
@@ -7365,7 +7746,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
        if (napi)
                DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name);
-       switch(sp->intr_type) {
+       switch(sp->config.intr_type) {
                case INTA:
                    DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
                    break;