]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - drivers/net/s2io.c
s2io: Removed enabling of some of the unused interrupts.
[linux-3.10.git] / drivers / net / s2io.c
index 250cdbeefdfde0da0641c999e6af0f0272351aa0..b4c4cf467dc638934e88c9feb03e22420fef05e6 100644 (file)
@@ -401,9 +401,10 @@ S2IO_PARM_INT(lro, 0);
  * aggregation happens until we hit max IP pkt size(64K)
  */
 S2IO_PARM_INT(lro_max_pkts, 0xFFFF);
-#ifndef CONFIG_S2IO_NAPI
 S2IO_PARM_INT(indicate_max_pkts, 0);
-#endif
+
+S2IO_PARM_INT(napi, 1);
+S2IO_PARM_INT(ufo, 0);
 
 static unsigned int tx_fifo_len[MAX_TX_FIFOS] =
     {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN};
@@ -458,7 +459,7 @@ static int init_shared_mem(struct s2io_nic *nic)
        void *tmp_v_addr, *tmp_v_addr_next;
        dma_addr_t tmp_p_addr, tmp_p_addr_next;
        RxD_block_t *pre_rxd_blk = NULL;
-       int i, j, blk_cnt, rx_sz, tx_sz;
+       int i, j, blk_cnt;
        int lst_size, lst_per_page;
        struct net_device *dev = nic->dev;
        unsigned long tmp;
@@ -483,7 +484,6 @@ static int init_shared_mem(struct s2io_nic *nic)
        }
 
        lst_size = (sizeof(TxD_t) * config->max_txds);
-       tx_sz = lst_size * size;
        lst_per_page = PAGE_SIZE / lst_size;
 
        for (i = 0; i < config->tx_fifo_num; i++) {
@@ -556,10 +556,9 @@ static int init_shared_mem(struct s2io_nic *nic)
                }
        }
 
-       nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL);
+       nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL);
        if (!nic->ufo_in_band_v)
                return -ENOMEM;
-       memset(nic->ufo_in_band_v, 0, size);
 
        /* Allocation and initialization of RXDs in Rings */
        size = 0;
@@ -583,7 +582,6 @@ static int init_shared_mem(struct s2io_nic *nic)
                size = (size * (sizeof(RxD1_t)));
        else
                size = (size * (sizeof(RxD3_t)));
-       rx_sz = size;
 
        for (i = 0; i < config->rx_ring_num; i++) {
                mac_control->rings[i].rx_curr_get_info.block_index = 0;
@@ -624,6 +622,8 @@ static int init_shared_mem(struct s2io_nic *nic)
                        rx_blocks->rxds = kmalloc(sizeof(rxd_info_t)*
                                                  rxd_count[nic->rxd_mode],
                                                  GFP_KERNEL);
+                       if (!rx_blocks->rxds)
+                               return -ENOMEM;
                        for (l=0; l<rxd_count[nic->rxd_mode];l++) {
                                rx_blocks->rxds[l].virt_addr =
                                        rx_blocks->block_virt_addr +
@@ -1415,7 +1415,7 @@ static int init_nic(struct s2io_nic *nic)
 
        val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
            TTI_DATA2_MEM_TX_UFC_B(0x20) |
-           TTI_DATA2_MEM_TX_UFC_C(0x70) | TTI_DATA2_MEM_TX_UFC_D(0x80);
+           TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80);
        writeq(val64, &bar0->tti_data2_mem);
 
        val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD;
@@ -1611,7 +1611,8 @@ static int init_nic(struct s2io_nic *nic)
         * that does not start on an ADB to reduce disconnects.
         */
        if (nic->device_type == XFRAME_II_DEVICE) {
-               val64 = EXT_REQ_EN | MISC_LINK_STABILITY_PRD(3);
+               val64 = FAULT_BEHAVIOUR | EXT_REQ_EN |
+                       MISC_LINK_STABILITY_PRD(3);
                writeq(val64, &bar0->misc_control);
                val64 = readq(&bar0->pic_control2);
                val64 &= ~(BIT(13)|BIT(14)|BIT(15));
@@ -1657,7 +1658,7 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
        /*  PIC Interrupts */
        if ((mask & (TX_PIC_INTR | RX_PIC_INTR))) {
                /*  Enable PIC Intrs in the general intr mask register */
-               val64 = TXPIC_INT_M | PIC_RX_INT_M;
+               val64 = TXPIC_INT_M;
                if (flag == ENABLE_INTRS) {
                        temp64 = readq(&bar0->general_int_mask);
                        temp64 &= ~((u64) val64);
@@ -1695,70 +1696,6 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
                }
        }
 
-       /*  DMA Interrupts */
-       /*  Enabling/Disabling Tx DMA interrupts */
-       if (mask & TX_DMA_INTR) {
-               /* Enable TxDMA Intrs in the general intr mask register */
-               val64 = TXDMA_INT_M;
-               if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
-                       /*
-                        * Keep all interrupts other than PFC interrupt
-                        * and PCC interrupt disabled in DMA level.
-                        */
-                       val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M |
-                                                     TXDMA_PCC_INT_M);
-                       writeq(val64, &bar0->txdma_int_mask);
-                       /*
-                        * Enable only the MISC error 1 interrupt in PFC block
-                        */
-                       val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1);
-                       writeq(val64, &bar0->pfc_err_mask);
-                       /*
-                        * Enable only the FB_ECC error interrupt in PCC block
-                        */
-                       val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR);
-                       writeq(val64, &bar0->pcc_err_mask);
-               } else if (flag == DISABLE_INTRS) {
-                       /*
-                        * Disable TxDMA Intrs in the general intr mask
-                        * register
-                        */
-                       writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask);
-                       writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask);
-                       temp64 = readq(&bar0->general_int_mask);
-                       val64 |= temp64;
-                       writeq(val64, &bar0->general_int_mask);
-               }
-       }
-
-       /*  Enabling/Disabling Rx DMA interrupts */
-       if (mask & RX_DMA_INTR) {
-               /*  Enable RxDMA Intrs in the general intr mask register */
-               val64 = RXDMA_INT_M;
-               if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
-                       /*
-                        * All RxDMA block interrupts are disabled for now
-                        * TODO
-                        */
-                       writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask);
-               } else if (flag == DISABLE_INTRS) {
-                       /*
-                        * Disable RxDMA Intrs in the general intr mask
-                        * register
-                        */
-                       writeq(DISABLE_ALL_INTRS, &bar0->rxdma_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)) {
@@ -1785,53 +1722,6 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
                }
        }
 
-       /*  XGXS Interrupts */
-       if (mask & (TX_XGXS_INTR | RX_XGXS_INTR)) {
-               val64 = TXXGXS_INT_M | RXXGXS_INT_M;
-               if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
-                       /*
-                        * All XGXS block error interrupts are disabled for now
-                        * TODO
-                        */
-                       writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask);
-               } else if (flag == DISABLE_INTRS) {
-                       /*
-                        * Disable MC Intrs in the general intr mask register
-                        */
-                       writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask);
-                       temp64 = readq(&bar0->general_int_mask);
-                       val64 |= temp64;
-                       writeq(val64, &bar0->general_int_mask);
-               }
-       }
-
-       /*  Memory Controller(MC) interrupts */
-       if (mask & MC_INTR) {
-               val64 = MC_INT_M;
-               if (flag == ENABLE_INTRS) {
-                       temp64 = readq(&bar0->general_int_mask);
-                       temp64 &= ~((u64) val64);
-                       writeq(temp64, &bar0->general_int_mask);
-                       /*
-                        * Enable all MC Intrs.
-                        */
-                       writeq(0x0, &bar0->mc_int_mask);
-                       writeq(0x0, &bar0->mc_err_mask);
-               } else if (flag == DISABLE_INTRS) {
-                       /*
-                        * Disable MC Intrs in the general intr mask register
-                        */
-                       writeq(DISABLE_ALL_INTRS, &bar0->mc_int_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;
@@ -1878,41 +1768,36 @@ 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, int herc)
+/**
+ *  verify_pcc_quiescent- Checks for PCC quiescent state
+ *  Return: 1 If PCC is quiescence
+ *          0 If PCC is not quiescence
+ */
+static int verify_pcc_quiescent(nic_t *sp, int flag)
 {
-       int ret = 0;
+       int ret = 0, herc;
+       XENA_dev_config_t __iomem *bar0 = sp->bar0;
+       u64 val64 = readq(&bar0->adapter_status);
+       
+       herc = (sp->device_type == XFRAME_II_DEVICE);
 
        if (flag == FALSE) {
-               if ((!herc && (rev_id >= 4)) || herc) {
-                       if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) &&
-                           ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
-                            ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
+               if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) {
+                       if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE))
                                ret = 1;
-                       }
-               }else {
-                       if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) &&
-                           ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
-                            ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
+               } else {
+                       if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE))
                                ret = 1;
-                       }
                }
        } else {
-               if ((!herc && (rev_id >= 4)) || herc) {
+               if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) {
                        if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) ==
-                            ADAPTER_STATUS_RMAC_PCC_IDLE) &&
-                           (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ||
-                            ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
-                             ADAPTER_STATUS_RC_PRC_QUIESCENT))) {
+                            ADAPTER_STATUS_RMAC_PCC_IDLE))
                                ret = 1;
-                       }
                } else {
                        if (((val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) ==
-                            ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) &&
-                           (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ||
-                            ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
-                             ADAPTER_STATUS_RC_PRC_QUIESCENT))) {
+                            ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE))
                                ret = 1;
-                       }
                }
        }
 
@@ -1920,9 +1805,6 @@ static int check_prc_pcc_state(u64 val64, int flag, int rev_id, int herc)
 }
 /**
  *  verify_xena_quiescence - Checks whether the H/W is ready
- *  @val64 :  Value read from adapter status register.
- *  @flag : indicates if the adapter enable bit was ever written once
- *  before.
  *  Description: Returns whether the H/W is ready to go or not. Depending
  *  on whether adapter enable bit was written or not the comparison
  *  differs and the calling function passes the input argument flag to
@@ -1931,24 +1813,63 @@ static int check_prc_pcc_state(u64 val64, int flag, int rev_id, int herc)
  *          0 If Xena is not quiescence
  */
 
-static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
+static int verify_xena_quiescence(nic_t *sp)
 {
-       int ret = 0, herc;
-       u64 tmp64 = ~((u64) val64);
-       int rev_id = get_xena_rev_id(sp->pdev);
+       int  mode;
+       XENA_dev_config_t __iomem *bar0 = sp->bar0;
+       u64 val64 = readq(&bar0->adapter_status);
+       mode = s2io_verify_pci_mode(sp);
 
-       herc = (sp->device_type == XFRAME_II_DEVICE);
-       if (!
-           (tmp64 &
-            (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY |
-             ADAPTER_STATUS_PFC_READY | ADAPTER_STATUS_TMAC_BUF_EMPTY |
-             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, herc);
+       if (!(val64 & ADAPTER_STATUS_TDMA_READY)) {
+               DBG_PRINT(ERR_DBG, "%s", "TDMA is not ready!");
+               return 0;
+       }
+       if (!(val64 & ADAPTER_STATUS_RDMA_READY)) {
+       DBG_PRINT(ERR_DBG, "%s", "RDMA is not ready!");
+               return 0;
+       }
+       if (!(val64 & ADAPTER_STATUS_PFC_READY)) {
+               DBG_PRINT(ERR_DBG, "%s", "PFC is not ready!");
+               return 0;
+       }
+       if (!(val64 & ADAPTER_STATUS_TMAC_BUF_EMPTY)) {
+               DBG_PRINT(ERR_DBG, "%s", "TMAC BUF is not empty!");
+               return 0;
+       }
+       if (!(val64 & ADAPTER_STATUS_PIC_QUIESCENT)) {
+               DBG_PRINT(ERR_DBG, "%s", "PIC is not QUIESCENT!");
+               return 0;
+       }
+       if (!(val64 & ADAPTER_STATUS_MC_DRAM_READY)) {
+               DBG_PRINT(ERR_DBG, "%s", "MC_DRAM is not ready!");
+               return 0;
+       }
+       if (!(val64 & ADAPTER_STATUS_MC_QUEUES_READY)) {
+               DBG_PRINT(ERR_DBG, "%s", "MC_QUEUES is not ready!");
+               return 0;
+       }
+       if (!(val64 & ADAPTER_STATUS_M_PLL_LOCK)) {
+               DBG_PRINT(ERR_DBG, "%s", "M_PLL is not locked!");
+               return 0;
        }
 
-       return ret;
+       /*
+        * In PCI 33 mode, the P_PLL is not used, and therefore,
+        * the the P_PLL_LOCK bit in the adapter_status register will
+        * not be asserted.
+        */
+       if (!(val64 & ADAPTER_STATUS_P_PLL_LOCK) &&
+               sp->device_type == XFRAME_II_DEVICE && mode !=
+               PCI_MODE_PCI_33) {
+               DBG_PRINT(ERR_DBG, "%s", "P_PLL is not locked!");
+               return 0;
+       }
+       if (!((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
+                       ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
+               DBG_PRINT(ERR_DBG, "%s", "RC_PRC is not QUIESCENT!");
+               return 0;
+       }
+       return 1;
 }
 
 /**
@@ -2053,7 +1974,7 @@ static int start_nic(struct s2io_nic *nic)
         * it.
         */
        val64 = readq(&bar0->adapter_status);
-       if (!verify_xena_quiescence(nic, val64, nic->device_enabled_once)) {
+       if (!verify_xena_quiescence(nic)) {
                DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name);
                DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n",
                          (unsigned long long) val64);
@@ -2227,6 +2148,7 @@ static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
                return -ENOMEM ;
        }
        frag_list = skb_shinfo(skb)->frag_list;
+       skb->truesize += frag_list->truesize;
        frag_list->next = NULL;
        tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
        frag_list->data = tmp;
@@ -2275,9 +2197,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
        struct config_param *config;
        u64 tmp;
        buffAdd_t *ba;
-#ifndef CONFIG_S2IO_NAPI
        unsigned long flags;
-#endif
        RxD_t *first_rxdp = NULL;
 
        mac_control = &nic->mac_control;
@@ -2321,12 +2241,15 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                        DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n",
                                  dev->name, rxdp);
                }
-#ifndef CONFIG_S2IO_NAPI
-               spin_lock_irqsave(&nic->put_lock, flags);
-               mac_control->rings[ring_no].put_pos =
-                   (block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
-               spin_unlock_irqrestore(&nic->put_lock, flags);
-#endif
+               if(!napi) {
+                       spin_lock_irqsave(&nic->put_lock, flags);
+                       mac_control->rings[ring_no].put_pos =
+                       (block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
+                       spin_unlock_irqrestore(&nic->put_lock, flags);
+               } else {
+                       mac_control->rings[ring_no].put_pos =
+                       (block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
+               }
                if ((rxdp->Control_1 & RXD_OWN_XENA) &&
                        ((nic->rxd_mode >= RXD_MODE_3A) &&
                                (rxdp->Control_2 & BIT(0)))) {
@@ -2569,7 +2492,6 @@ static void free_rx_buffers(struct s2io_nic *sp)
  * 0 on success and 1 if there are No Rx packets to be processed.
  */
 
-#if defined(CONFIG_S2IO_NAPI)
 static int s2io_poll(struct net_device *dev, int *budget)
 {
        nic_t *nic = dev->priv;
@@ -2577,7 +2499,6 @@ static int s2io_poll(struct net_device *dev, int *budget)
        mac_info_t *mac_control;
        struct config_param *config;
        XENA_dev_config_t __iomem *bar0 = nic->bar0;
-       u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
        int i;
 
        atomic_inc(&nic->isr_cnt);
@@ -2589,8 +2510,8 @@ static int s2io_poll(struct net_device *dev, int *budget)
                nic->pkts_to_process = dev->quota;
        org_pkts_to_process = nic->pkts_to_process;
 
-       writeq(val64, &bar0->rx_traffic_int);
-       val64 = readl(&bar0->rx_traffic_int);
+       writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+       readl(&bar0->rx_traffic_int);
 
        for (i = 0; i < config->rx_ring_num; i++) {
                rx_intr_handler(&mac_control->rings[i]);
@@ -2616,7 +2537,7 @@ static int s2io_poll(struct net_device *dev, int *budget)
        }
        /* Re enable the Rx interrupts. */
        writeq(0x0, &bar0->rx_traffic_mask);
-       val64 = readl(&bar0->rx_traffic_mask);
+       readl(&bar0->rx_traffic_mask);
        atomic_dec(&nic->isr_cnt);
        return 0;
 
@@ -2634,7 +2555,6 @@ no_rx:
        atomic_dec(&nic->isr_cnt);
        return 1;
 }
-#endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /**
@@ -2708,9 +2628,7 @@ static void rx_intr_handler(ring_info_t *ring_data)
        rx_curr_get_info_t get_info, put_info;
        RxD_t *rxdp;
        struct sk_buff *skb;
-#ifndef CONFIG_S2IO_NAPI
        int pkt_cnt = 0;
-#endif
        int i;
 
        spin_lock(&nic->rx_lock);
@@ -2726,16 +2644,18 @@ static void rx_intr_handler(ring_info_t *ring_data)
        put_info = ring_data->rx_curr_put_info;
        put_block = put_info.block_index;
        rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr;
-#ifndef CONFIG_S2IO_NAPI
-       spin_lock(&nic->put_lock);
-       put_offset = ring_data->put_pos;
-       spin_unlock(&nic->put_lock);
-#else
-       put_offset = (put_block * (rxd_count[nic->rxd_mode] + 1)) +
-               put_info.offset;
-#endif
+       if (!napi) {
+               spin_lock(&nic->put_lock);
+               put_offset = ring_data->put_pos;
+               spin_unlock(&nic->put_lock);
+       } else
+               put_offset = ring_data->put_pos;
+
        while (RXD_IS_UP2DT(rxdp)) {
-               /* If your are next to put index then it's FIFO full condition */
+               /*
+                * If your are next to put index then it's
+                * FIFO full condition
+                */
                if ((get_block == put_block) &&
                    (get_info.offset + 1) == put_info.offset) {
                        DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name);
@@ -2793,15 +2713,12 @@ static void rx_intr_handler(ring_info_t *ring_data)
                        rxdp = ring_data->rx_blocks[get_block].block_virt_addr;
                }
 
-#ifdef CONFIG_S2IO_NAPI
                nic->pkts_to_process -= 1;
-               if (!nic->pkts_to_process)
+               if ((napi) && (!nic->pkts_to_process))
                        break;
-#else
                pkt_cnt++;
                if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts))
                        break;
-#endif
        }
        if (nic->lro) {
                /* Clear all LRO sessions before exiting */
@@ -2855,11 +2772,10 @@ static void tx_intr_handler(fifo_info_t *fifo_data)
                        }
                        if ((err >> 48) == 0xA) {
                                DBG_PRINT(TX_DBG, "TxD returned due \
-to loss of link\n");
+                                               to loss of link\n");
                        }
                        else {
-                               DBG_PRINT(ERR_DBG, "***TxD error \
-%llx\n", err);
+                               DBG_PRINT(ERR_DBG, "***TxD error %llx\n", err);
                        }
                }
 
@@ -3159,6 +3075,8 @@ static void alarm_intr_handler(struct s2io_nic *nic)
        register u64 val64 = 0, err_reg = 0;
        u64 cnt;
        int i;
+       if (atomic_read(&nic->card_state) == CARD_DOWN)
+               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) {
@@ -3298,6 +3216,25 @@ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit)
        }
        return ret;
 }
+/*
+ * check_pci_device_id - Checks if the device id is supported
+ * @id : device id
+ * Description: Function to check if the pci device id is supported by driver.
+ * Return value: Actual device id if supported else PCI_ANY_ID
+ */
+static u16 check_pci_device_id(u16 id)
+{
+       switch (id) {
+       case PCI_DEVICE_ID_HERC_WIN:
+       case PCI_DEVICE_ID_HERC_UNI:
+               return XFRAME_II_DEVICE;
+       case PCI_DEVICE_ID_S2IO_UNI:
+       case PCI_DEVICE_ID_S2IO_WIN:
+               return XFRAME_I_DEVICE;
+       default:
+               return PCI_ANY_ID;
+       }
+}
 
 /**
  *  s2io_reset - Resets the card.
@@ -3314,37 +3251,52 @@ static void s2io_reset(nic_t * sp)
        XENA_dev_config_t __iomem *bar0 = sp->bar0;
        u64 val64;
        u16 subid, pci_cmd;
+       int i;
+       u16 val16;
+       DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
+                       __FUNCTION__, sp->dev->name);
 
        /* Back up  the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
        pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
 
+       if (sp->device_type == XFRAME_II_DEVICE) {
+               int ret;
+               ret = pci_set_power_state(sp->pdev, 3);
+               if (!ret)
+                       ret = pci_set_power_state(sp->pdev, 0);
+               else {
+                       DBG_PRINT(ERR_DBG,"%s PME based SW_Reset failed!\n",
+                                       __FUNCTION__);
+                       goto old_way;
+               }
+               msleep(20);
+               goto new_way;
+       }
+old_way:
        val64 = SW_RESET_ALL;
        writeq(val64, &bar0->sw_reset);
-
-       /*
-        * At this stage, if the PCI write is indeed completed, the
-        * card is reset and so is the PCI Config space of the device.
-        * So a read cannot be issued at this stage on any of the
-        * registers to ensure the write into "sw_reset" register
-        * has gone through.
-        * Question: Is there any system call that will explicitly force
-        * all the write commands still pending on the bus to be pushed
-        * through?
-        * As of now I'am just giving a 250ms delay and hoping that the
-        * PCI write to sw_reset register is done by this time.
-        */
-       msleep(250);
+new_way:
        if (strstr(sp->product_name, "CX4")) {
                msleep(750);
        }
+       msleep(250);
+       for (i = 0; i < S2IO_MAX_PCI_CONFIG_SPACE_REINIT; i++) {
 
-       /* Restore the PCI state saved during initialization. */
-       pci_restore_state(sp->pdev);
-       pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
-                                    pci_cmd);
-       s2io_init_pci(sp);
+               /* Restore the PCI state saved during initialization. */
+               pci_restore_state(sp->pdev);
+               pci_read_config_word(sp->pdev, 0x2, &val16);
+               if (check_pci_device_id(val16) != (u16)PCI_ANY_ID)
+                       break;
+               msleep(200);
+       }
 
-       msleep(250);
+       if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) {
+               DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __FUNCTION__);
+       }
+
+       pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd);
+
+       s2io_init_pci(sp);
 
        /* Set swapper to enable I/O register access */
        s2io_set_swapper(sp);
@@ -3888,12 +3840,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        offload_type = s2io_offload_type(skb);
-#ifdef NETIF_F_TSO
        if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
                txdp->Control_1 |= TXD_TCP_LSO_EN;
                txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb));
        }
-#endif
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                txdp->Control_2 |=
                    (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN |
@@ -4110,39 +4060,33 @@ static void s2io_txpic_intr_handle(nic_t *sp)
                }
                else if (val64 & GPIO_INT_REG_LINK_UP) {
                        val64 = readq(&bar0->adapter_status);
-                       if (verify_xena_quiescence(sp, val64,
-                                                  sp->device_enabled_once)) {
                                /* Enable Adapter */
-                               val64 = readq(&bar0->adapter_control);
-                               val64 |= ADAPTER_CNTL_EN;
-                               writeq(val64, &bar0->adapter_control);
-                               val64 |= ADAPTER_LED_ON;
-                               writeq(val64, &bar0->adapter_control);
-                               if (!sp->device_enabled_once)
-                                       sp->device_enabled_once = 1;
+                       val64 = readq(&bar0->adapter_control);
+                       val64 |= ADAPTER_CNTL_EN;
+                       writeq(val64, &bar0->adapter_control);
+                       val64 |= ADAPTER_LED_ON;
+                       writeq(val64, &bar0->adapter_control);
+                       if (!sp->device_enabled_once)
+                               sp->device_enabled_once = 1;
 
-                               s2io_link(sp, LINK_UP);
-                               /*
-                                * unmask link down interrupt and mask link-up
-                                * intr
-                                */
-                               val64 = readq(&bar0->gpio_int_mask);
-                               val64 &= ~GPIO_INT_MASK_LINK_DOWN;
-                               val64 |= GPIO_INT_MASK_LINK_UP;
-                               writeq(val64, &bar0->gpio_int_mask);
+                       s2io_link(sp, LINK_UP);
+                       /*
+                        * unmask link down interrupt and mask link-up
+                        * intr
+                        */
+                       val64 = readq(&bar0->gpio_int_mask);
+                       val64 &= ~GPIO_INT_MASK_LINK_DOWN;
+                       val64 |= GPIO_INT_MASK_LINK_UP;
+                       writeq(val64, &bar0->gpio_int_mask);
 
-                       }
                }else if (val64 & GPIO_INT_REG_LINK_DOWN) {
                        val64 = readq(&bar0->adapter_status);
-                       if (verify_xena_quiescence(sp, val64,
-                                                  sp->device_enabled_once)) {
-                               s2io_link(sp, LINK_DOWN);
-                               /* Link is down so unmaks link up interrupt */
-                               val64 = readq(&bar0->gpio_int_mask);
-                               val64 &= ~GPIO_INT_MASK_LINK_UP;
-                               val64 |= GPIO_INT_MASK_LINK_DOWN;
-                               writeq(val64, &bar0->gpio_int_mask);
-                       }
+                       s2io_link(sp, LINK_DOWN);
+                       /* Link is down so unmaks link up interrupt */
+                       val64 = readq(&bar0->gpio_int_mask);
+                       val64 &= ~GPIO_INT_MASK_LINK_UP;
+                       val64 |= GPIO_INT_MASK_LINK_DOWN;
+                       writeq(val64, &bar0->gpio_int_mask);
                }
        }
        val64 = readq(&bar0->gpio_int_mask);
@@ -4167,7 +4111,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
        nic_t *sp = dev->priv;
        XENA_dev_config_t __iomem *bar0 = sp->bar0;
        int i;
-       u64 reason = 0, val64, org_mask;
+       u64 reason = 0;
        mac_info_t *mac_control;
        struct config_param *config;
 
@@ -4186,43 +4130,48 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
        reason = readq(&bar0->general_int_status);
 
        if (!reason) {
-               /* The interrupt was not raised by Xena. */
+               /* 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;
        }
 
-       val64 = 0xFFFFFFFFFFFFFFFFULL;
-       /* Store current mask before masking all interrupts */
-       org_mask = readq(&bar0->general_int_mask);
-       writeq(val64, &bar0->general_int_mask);
+       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);
+                       }
+                       else
+                               writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
+               }
+       } 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
+                * 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);
 
-#ifdef CONFIG_S2IO_NAPI
-       if (reason & GEN_INTR_RXTRAFFIC) {
-               if (netif_rx_schedule_prep(dev)) {
-                       writeq(val64, &bar0->rx_traffic_mask);
-                       __netif_rx_schedule(dev);
+               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
-        * will ensure that the actual interrupt causing bit get's
-        * cleared and hence a read can be avoided.
-        */
-       writeq(val64, &bar0->rx_traffic_int);
-       for (i = 0; i < config->rx_ring_num; i++) {
-               rx_intr_handler(&mac_control->rings[i]);
-       }
-#endif
 
        /*
         * 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.
         */
-       writeq(val64, &bar0->tx_traffic_int);
+       if (reason & GEN_INTR_TXTRAFFIC)
+               writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
 
        for (i = 0; i < config->tx_fifo_num; i++)
                tx_intr_handler(&mac_control->fifos[i]);
@@ -4234,11 +4183,14 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
         * reallocate the buffers from the interrupt handler itself,
         * else schedule a tasklet to reallocate the buffers.
         */
-#ifndef CONFIG_S2IO_NAPI
-       for (i = 0; i < config->rx_ring_num; i++)
-               s2io_chk_rx_buffers(sp, i);
-#endif
-       writeq(org_mask, &bar0->general_int_mask);
+       if (!napi) {
+               for (i = 0; i < config->rx_ring_num; i++)
+                       s2io_chk_rx_buffers(sp, i);
+       }
+
+       writeq(0, &bar0->general_int_mask);
+       readl(&bar0->general_int_status);
+
        atomic_dec(&sp->isr_cnt);
        return IRQ_HANDLED;
 }
@@ -4915,6 +4867,7 @@ static void s2io_vpd_read(nic_t *nic)
                strcpy(nic->product_name, "Xframe I 10GbE network adapter");
                vpd_addr = 0x50;
        }
+       strcpy(nic->serial_num, "NOT AVAILABLE");
 
        vpd_data = kmalloc(256, GFP_KERNEL);
        if (!vpd_data)
@@ -4938,7 +4891,22 @@ static void s2io_vpd_read(nic_t *nic)
                pci_read_config_dword(nic->pdev,  (vpd_addr + 4),
                                      (u32 *)&vpd_data[i]);
        }
-       if ((!fail) && (vpd_data[1] < VPD_PRODUCT_NAME_LEN)) {
+
+       if(!fail) {
+               /* read serial number of adapter */
+               for (cnt = 0; cnt < 256; cnt++) {
+               if ((vpd_data[cnt] == 'S') &&
+                       (vpd_data[cnt+1] == 'N') &&
+                       (vpd_data[cnt+2] < VPD_STRING_LEN)) {
+                               memset(nic->serial_num, 0, VPD_STRING_LEN);
+                               memcpy(nic->serial_num, &vpd_data[cnt + 3],
+                                       vpd_data[cnt+2]);
+                               break;
+                       }
+               }
+       }
+
+       if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) {
                memset(nic->product_name, 0, vpd_data[1]);
                memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
        }
@@ -5751,10 +5719,8 @@ static const struct ethtool_ops netdev_ethtool_ops = {
        .set_tx_csum = s2io_ethtool_op_set_tx_csum,
        .get_sg = ethtool_op_get_sg,
        .set_sg = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
        .get_tso = s2io_ethtool_op_get_tso,
        .set_tso = s2io_ethtool_op_set_tso,
-#endif
        .get_ufo = ethtool_op_get_ufo,
        .set_ufo = ethtool_op_set_ufo,
        .self_test_count = s2io_ethtool_self_test_count,
@@ -5895,50 +5861,45 @@ static void s2io_set_link(struct work_struct *work)
        }
 
        val64 = readq(&bar0->adapter_status);
-       if (verify_xena_quiescence(nic, val64, nic->device_enabled_once)) {
-               if (LINK_IS_UP(val64)) {
-                       val64 = readq(&bar0->adapter_control);
-                       val64 |= ADAPTER_CNTL_EN;
-                       writeq(val64, &bar0->adapter_control);
-                       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);
-                               val64 = readq(&bar0->gpio_control);
-                       } else {
-                               val64 |= ADAPTER_LED_ON;
+       if (LINK_IS_UP(val64)) {
+               if (!(readq(&bar0->adapter_control) & ADAPTER_CNTL_EN)) {
+                       if (verify_xena_quiescence(nic)) {
+                               val64 = readq(&bar0->adapter_control);
+                               val64 |= ADAPTER_CNTL_EN;
                                writeq(val64, &bar0->adapter_control);
-                       }
-                       if (s2io_link_fault_indication(nic) ==
-                                               MAC_RMAC_ERR_TIMER) {
-                               val64 = readq(&bar0->adapter_status);
-                               if (!LINK_IS_UP(val64)) {
-                                       DBG_PRINT(ERR_DBG, "%s:", dev->name);
-                                       DBG_PRINT(ERR_DBG, " Link down");
-                                       DBG_PRINT(ERR_DBG, "after ");
-                                       DBG_PRINT(ERR_DBG, "enabling ");
-                                       DBG_PRINT(ERR_DBG, "device \n");
+                               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);
+                                       val64 = readq(&bar0->gpio_control);
+                               } else {
+                                       val64 |= ADAPTER_LED_ON;
+                                       writeq(val64, &bar0->adapter_control);
                                }
-                       }
-                       if (nic->device_enabled_once == FALSE) {
                                nic->device_enabled_once = TRUE;
+                       } else {
+                               DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name);
+                               DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
+                               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);
-               } else {
-                       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);
-                               val64 = readq(&bar0->gpio_control);
-                       }
-                       s2io_link(nic, LINK_DOWN);
+       } else {
+               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);
+                       val64 = readq(&bar0->gpio_control);
                }
-       } else {                /* NIC is not Quiescent. */
-               DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name);
-               DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
-               netif_stop_queue(dev);
+               s2io_link(nic, LINK_DOWN);
        }
        clear_bit(0, &(nic->link_state));
 }
@@ -5987,7 +5948,7 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba,
                        *skb = dev_alloc_skb(size);
                        if (!(*skb)) {
                                DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n",
-                                         dev->name);
+                                       dev->name);
                                return -ENOMEM;
                        }
                        ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 =
@@ -6257,7 +6218,8 @@ static void s2io_card_down(nic_t * sp)
                rxd_owner_bit_reset(sp);
 
                val64 = readq(&bar0->adapter_status);
-               if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) {
+               if (verify_xena_quiescence(sp)) {
+                       if(verify_pcc_quiescent(sp, sp->device_enabled_once))
                        break;
                }
 
@@ -6320,6 +6282,13 @@ static int s2io_card_up(nic_t * sp)
                DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
                          atomic_read(&sp->rx_bufs_left[i]));
        }
+       /* Maintain the state prior to the open */
+       if (sp->promisc_flg)
+               sp->promisc_flg = 0;
+       if (sp->m_cast_flg) {
+               sp->m_cast_flg = 0;
+               sp->all_multi_pos= 0;
+       }
 
        /* Setting its receive mode */
        s2io_set_multicast(dev);
@@ -6499,7 +6468,6 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp)
                        skb_put(skb, buf1_len);
                        skb->len += buf2_len;
                        skb->data_len += buf2_len;
-                       skb->truesize += buf2_len;
                        skb_put(skb_shinfo(skb)->frag_list, buf2_len);
                        sp->stats.rx_bytes += buf1_len;
 
@@ -6583,23 +6551,20 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp)
 
        if (!sp->lro) {
                skb->protocol = eth_type_trans(skb, dev);
-#ifdef CONFIG_S2IO_NAPI
-               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
                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));
+                       if (napi)
+                               vlan_hwaccel_receive_skb(skb, sp->vlgrp,
+                                       RXD_GET_VLAN_TAG(rxdp->Control_2));
+                       else
+                               vlan_hwaccel_rx(skb, sp->vlgrp,
+                                       RXD_GET_VLAN_TAG(rxdp->Control_2));
                } else {
-                       netif_rx(skb);
+                       if (napi)
+                               netif_receive_skb(skb);
+                       else
+                               netif_rx(skb);
                }
-#endif
        } else {
 send_up:
                queue_rx_frame(skb);
@@ -6700,13 +6665,9 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
                DBG_PRINT(ERR_DBG, "s2io: Default to 8 Rx rings\n");
                rx_ring_num = 8;
        }
-#ifdef CONFIG_S2IO_NAPI
-       if (*dev_intr_type != INTA) {
-               DBG_PRINT(ERR_DBG, "s2io: NAPI cannot be enabled when "
-                         "MSI/MSI-X is enabled. Defaulting to INTA\n");
-               *dev_intr_type = INTA;
-       }
-#endif
+       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"
@@ -6727,6 +6688,8 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
                                        "Defaulting to INTA\n");
                *dev_intr_type = INTA;
        }
+       if ( (rx_ring_num > 1) && (*dev_intr_type != INTA) )
+               napi = 0;
        if (rx_ring_mode > 3) {
                DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n");
                DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n");
@@ -6926,7 +6889,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        sp->bar0 = ioremap(pci_resource_start(pdev, 0),
                                     pci_resource_len(pdev, 0));
        if (!sp->bar0) {
-               DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem1\n",
+               DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem1\n",
                          dev->name);
                ret = -ENOMEM;
                goto bar0_remap_failed;
@@ -6935,7 +6898,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        sp->bar1 = ioremap(pci_resource_start(pdev, 2),
                                     pci_resource_len(pdev, 2));
        if (!sp->bar1) {
-               DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem2\n",
+               DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem2\n",
                          dev->name);
                ret = -ENOMEM;
                goto bar1_remap_failed;
@@ -6967,10 +6930,8 @@ 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
         */
-#if defined(CONFIG_S2IO_NAPI)
        dev->poll = s2io_poll;
        dev->weight = 32;
-#endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = s2io_netpoll;
@@ -6979,13 +6940,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
        if (sp->high_dma_flag == TRUE)
                dev->features |= NETIF_F_HIGHDMA;
-#ifdef NETIF_F_TSO
        dev->features |= NETIF_F_TSO;
-#endif
-#ifdef NETIF_F_TSO6
        dev->features |= NETIF_F_TSO6;
-#endif
-       if (sp->device_type & XFRAME_II_DEVICE) {
+       if ((sp->device_type & XFRAME_II_DEVICE) && (ufo))  {
                dev->features |= NETIF_F_UFO;
                dev->features |= NETIF_F_HW_CSUM;
        }
@@ -7066,9 +7023,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
        /* Initialize spinlocks */
        spin_lock_init(&sp->tx_lock);
-#ifndef CONFIG_S2IO_NAPI
-       spin_lock_init(&sp->put_lock);
-#endif
+
+       if (!napi)
+               spin_lock_init(&sp->put_lock);
        spin_lock_init(&sp->rx_lock);
 
        /*
@@ -7099,13 +7056,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        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\n", dev->name,
+                         "%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, "SERIAL NUMBER: %s\n", sp->serial_num);
        if (sp->device_type & XFRAME_II_DEVICE) {
                mode = s2io_print_pci_mode(sp);
                if (mode < 0) {
@@ -7129,9 +7087,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                                                dev->name);
                    break;
        }
-#ifdef CONFIG_S2IO_NAPI
-       DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name);
-#endif
+
+       if (napi)
+               DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name);
        switch(sp->intr_type) {
                case INTA:
                    DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
@@ -7146,7 +7104,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        if (sp->lro)
                DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
                          dev->name);
-
+       if (ufo)
+               DBG_PRINT(ERR_DBG, "%s: UDP Fragmentation Offload(UFO)"
+                                       " enabled\n", dev->name);
        /* Initialize device name */
        sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name);
 
@@ -7216,7 +7176,6 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
        free_shared_mem(sp);
        iounmap(sp->bar0);
        iounmap(sp->bar1);
-       pci_disable_device(pdev);
        if (sp->intr_type != MSI_X)
                pci_release_regions(pdev);
        else {
@@ -7227,6 +7186,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
        }
        pci_set_drvdata(pdev, NULL);
        free_netdev(dev);
+       pci_disable_device(pdev);
 }
 
 /**
@@ -7245,7 +7205,7 @@ int __init s2io_starter(void)
  * Description: This function is the cleanup routine for the driver. It unregist * ers the driver.
  */
 
-static void s2io_closer(void)
+static __exit void s2io_closer(void)
 {
        pci_unregister_driver(&s2io_driver);
        DBG_PRINT(INIT_DBG, "cleanup done\n");
@@ -7548,11 +7508,10 @@ static void queue_rx_frame(struct sk_buff *skb)
        struct net_device *dev = skb->dev;
 
        skb->protocol = eth_type_trans(skb, dev);
-#ifdef CONFIG_S2IO_NAPI
-       netif_receive_skb(skb);
-#else
-       netif_rx(skb);
-#endif
+       if (napi)
+               netif_receive_skb(skb);
+       else
+               netif_rx(skb);
 }
 
 static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb,
@@ -7567,6 +7526,7 @@ static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb,
                lro->last_frag->next = skb;
        else
                skb_shinfo(first)->frag_list = skb;
+       first->truesize += skb->truesize;
        lro->last_frag = skb;
        sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++;
        return;