]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/net/s2io.c
net: wireless: bcmdhd: Enable wlan access on resume for all sdio functions
[linux-2.6.git] / drivers / net / s2io.c
index 80efc05d4d646d2bcacffffbbfbe106e88a776d2..277d48b0800a28781f392e7a6fde83030e37e809 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 #include <net/tcp.h>
 
 #include <asm/system.h>
@@ -355,56 +356,6 @@ static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr)
        sp->def_mac_addr[offset].mac_addr[0] = (u8) (mac_addr >> 40);
 }
 
-/* Add the vlan */
-static void s2io_vlan_rx_register(struct net_device *dev,
-                                 struct vlan_group *grp)
-{
-       int i;
-       struct s2io_nic *nic = netdev_priv(dev);
-       unsigned long flags[MAX_TX_FIFOS];
-       struct config_param *config = &nic->config;
-       struct mac_info *mac_control = &nic->mac_control;
-
-       for (i = 0; i < config->tx_fifo_num; i++) {
-               struct fifo_info *fifo = &mac_control->fifos[i];
-
-               spin_lock_irqsave(&fifo->tx_lock, flags[i]);
-       }
-
-       nic->vlgrp = grp;
-
-       for (i = config->tx_fifo_num - 1; i >= 0; i--) {
-               struct fifo_info *fifo = &mac_control->fifos[i];
-
-               spin_unlock_irqrestore(&fifo->tx_lock, flags[i]);
-       }
-}
-
-/* Unregister the vlan */
-static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       int i;
-       struct s2io_nic *nic = netdev_priv(dev);
-       unsigned long flags[MAX_TX_FIFOS];
-       struct config_param *config = &nic->config;
-       struct mac_info *mac_control = &nic->mac_control;
-
-       for (i = 0; i < config->tx_fifo_num; i++) {
-               struct fifo_info *fifo = &mac_control->fifos[i];
-
-               spin_lock_irqsave(&fifo->tx_lock, flags[i]);
-       }
-
-       if (nic->vlgrp)
-               vlan_group_set_device(nic->vlgrp, vid, NULL);
-
-       for (i = config->tx_fifo_num - 1; i >= 0; i--) {
-               struct fifo_info *fifo = &mac_control->fifos[i];
-
-               spin_unlock_irqrestore(&fifo->tx_lock, flags[i]);
-       }
-}
-
 /*
  * Constants to be programmed into the Xena's registers, to configure
  * the XAUI.
@@ -840,7 +791,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                        tmp_p_addr = ring->rx_blocks[j].block_dma_addr;
                        tmp_p_addr_next = ring->rx_blocks[next].block_dma_addr;
 
-                       pre_rxd_blk = (struct RxD_block *)tmp_v_addr;
+                       pre_rxd_blk = tmp_v_addr;
                        pre_rxd_blk->reserved_2_pNext_RxD_block =
                                (unsigned long)tmp_v_addr_next;
                        pre_rxd_blk->pNext_RxD_Blk_physical =
@@ -917,7 +868,7 @@ static int init_shared_mem(struct s2io_nic *nic)
        mac_control->stats_mem_sz = size;
 
        tmp_v_addr = mac_control->stats_mem;
-       mac_control->stats_info = (struct stat_block *)tmp_v_addr;
+       mac_control->stats_info = tmp_v_addr;
        memset(tmp_v_addr, 0, size);
        DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n",
                dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr);
@@ -2244,13 +2195,12 @@ static int verify_xena_quiescence(struct s2io_nic *sp)
 static void fix_mac_address(struct s2io_nic *sp)
 {
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
-       u64 val64;
        int i = 0;
 
        while (fix_mac[i] != END_SIGN) {
                writeq(fix_mac[i++], &bar0->gpio_control);
                udelay(10);
-               val64 = readq(&bar0->gpio_control);
+               (void) readq(&bar0->gpio_control);
        }
 }
 
@@ -2353,7 +2303,7 @@ static int start_nic(struct s2io_nic *nic)
 
        if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) {
                /*
-                * Dont see link state interrupts initally on some switches,
+                * Dont see link state interrupts initially on some switches,
                 * so directly scheduling the link state task here.
                 */
                schedule_work(&nic->set_link_task);
@@ -2439,7 +2389,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
 
                spin_lock_irqsave(&fifo->tx_lock, flags);
                for (j = 0; j < tx_cfg->fifo_len; j++) {
-                       txdp = (struct TxD *)fifo->list_info[j].list_virt_addr;
+                       txdp = fifo->list_info[j].list_virt_addr;
                        skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
                        if (skb) {
                                swstats->mem_freed += skb->truesize;
@@ -2727,7 +2677,6 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
        int j;
        struct sk_buff *skb;
        struct RxD_t *rxdp;
-       struct buffAdd *ba;
        struct RxD1 *rxdp1;
        struct RxD3 *rxdp3;
        struct mac_info *mac_control = &sp->mac_control;
@@ -2751,7 +2700,6 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
                        memset(rxdp, 0, sizeof(struct RxD1));
                } else if (sp->rxd_mode == RXD_MODE_3B) {
                        rxdp3 = (struct RxD3 *)rxdp;
-                       ba = &mac_control->rings[ring_no].ba[blk][j];
                        pci_unmap_single(sp->pdev,
                                         (dma_addr_t)rxdp3->Buffer0_ptr,
                                         BUF0_LEN,
@@ -3077,8 +3025,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 
        get_info = fifo_data->tx_curr_get_info;
        memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info));
-       txdlp = (struct TxD *)
-               fifo_data->list_info[get_info.offset].list_virt_addr;
+       txdlp = fifo_data->list_info[get_info.offset].list_virt_addr;
        while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) &&
               (get_info.offset != put_info.offset) &&
               (txdlp->Host_Control)) {
@@ -3131,8 +3078,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
                get_info.offset++;
                if (get_info.offset == get_info.fifo_len + 1)
                        get_info.offset = 0;
-               txdlp = (struct TxD *)
-                       fifo_data->list_info[get_info.offset].list_virt_addr;
+               txdlp = fifo_data->list_info[get_info.offset].list_virt_addr;
                fifo_data->tx_curr_get_info.offset = get_info.offset;
        }
 
@@ -3563,7 +3509,7 @@ static void s2io_reset(struct s2io_nic *sp)
        }
 
        /*
-        * Clear spurious ECC interrupts that would have occured on
+        * Clear spurious ECC interrupts that would have occurred on
         * XFRAME II cards after reset.
         */
        if (sp->device_type == XFRAME_II_DEVICE) {
@@ -3598,10 +3544,12 @@ static int s2io_set_swapper(struct s2io_nic *sp)
        val64 = readq(&bar0->pif_rd_swapper_fb);
        if (val64 != 0x0123456789ABCDEFULL) {
                int i = 0;
-               u64 value[] = { 0xC30000C3C30000C3ULL,   /* FE=1, SE=1 */
-                               0x8100008181000081ULL,  /* FE=1, SE=0 */
-                               0x4200004242000042ULL,  /* FE=0, SE=1 */
-                               0};                     /* FE=0, SE=0 */
+               static const u64 value[] = {
+                       0xC30000C3C30000C3ULL,  /* FE=1, SE=1 */
+                       0x8100008181000081ULL,  /* FE=1, SE=0 */
+                       0x4200004242000042ULL,  /* FE=0, SE=1 */
+                       0                       /* FE=0, SE=0 */
+               };
 
                while (i < 4) {
                        writeq(value[i], &bar0->swapper_ctrl);
@@ -3627,10 +3575,12 @@ static int s2io_set_swapper(struct s2io_nic *sp)
 
        if (val64 != valt) {
                int i = 0;
-               u64 value[] = { 0x00C3C30000C3C300ULL,  /* FE=1, SE=1 */
-                               0x0081810000818100ULL,  /* FE=1, SE=0 */
-                               0x0042420000424200ULL,  /* FE=0, SE=1 */
-                               0};                     /* FE=0, SE=0 */
+               static const u64 value[] = {
+                       0x00C3C30000C3C300ULL,  /* FE=1, SE=1 */
+                       0x0081810000818100ULL,  /* FE=1, SE=0 */
+                       0x0042420000424200ULL,  /* FE=0, SE=1 */
+                       0                       /* FE=0, SE=0 */
+               };
 
                while (i < 4) {
                        writeq((value[i] | valr), &bar0->swapper_ctrl);
@@ -4061,7 +4011,7 @@ static int s2io_close(struct net_device *dev)
  *  Description :
  *  This function is the Tx entry point of the driver. S2IO NIC supports
  *  certain protocol assist features on Tx side, namely  CSO, S/G, LSO.
- *  NOTE: when device cant queue the pkt,just the trans_start variable will
+ *  NOTE: when device can't queue the pkt,just the trans_start variable will
  *  not be upadted.
  *  Return value:
  *  0 on success & 1 on failure.
@@ -4109,7 +4059,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                        struct tcphdr *th;
                        ip = ip_hdr(skb);
 
-                       if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) {
+                       if (!ip_is_fragment(ip)) {
                                th = (struct tcphdr *)(((unsigned char *)ip) +
                                                       ip->ihl*4);
 
@@ -4161,7 +4111,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 
        put_off = (u16)fifo->tx_curr_put_info.offset;
        get_off = (u16)fifo->tx_curr_get_info.offset;
-       txdp = (struct TxD *)fifo->list_info[put_off].list_virt_addr;
+       txdp = fifo->list_info[put_off].list_virt_addr;
 
        queue_len = fifo->tx_curr_put_info.fifo_len + 1;
        /* Avoid "put" pointer going beyond "get" pointer */
@@ -5379,7 +5329,7 @@ static int s2io_ethtool_sset(struct net_device *dev,
 {
        struct s2io_nic *sp = netdev_priv(dev);
        if ((info->autoneg == AUTONEG_ENABLE) ||
-           (info->speed != SPEED_10000) ||
+           (ethtool_cmd_speed(info) != SPEED_10000) ||
            (info->duplex != DUPLEX_FULL))
                return -EINVAL;
        else {
@@ -5413,10 +5363,10 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
        info->transceiver = XCVR_EXTERNAL;
 
        if (netif_carrier_ok(sp->dev)) {
-               info->speed = 10000;
+               ethtool_cmd_speed_set(info, SPEED_10000);
                info->duplex = DUPLEX_FULL;
        } else {
-               info->speed = -1;
+               ethtool_cmd_speed_set(info, -1);
                info->duplex = -1;
        }
 
@@ -5480,83 +5430,79 @@ static void s2io_ethtool_gregs(struct net_device *dev,
        }
 }
 
-/**
- *  s2io_phy_id  - timer function that alternates adapter LED.
- *  @data : address of the private member of the device structure, which
- *  is a pointer to the s2io_nic structure, provided as an u32.
- * Description: This is actually the timer function that alternates the
- * adapter LED bit of the adapter control bit to set/reset every time on
- * invocation. The timer is set for 1/2 a second, hence tha NIC blinks
- *  once every second.
+/*
+ *  s2io_set_led - control NIC led
  */
-static void s2io_phy_id(unsigned long data)
+static void s2io_set_led(struct s2io_nic *sp, bool on)
 {
-       struct s2io_nic *sp = (struct s2io_nic *)data;
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
-       u64 val64 = 0;
-       u16 subid;
+       u16 subid = sp->pdev->subsystem_device;
+       u64 val64;
 
-       subid = sp->pdev->subsystem_device;
        if ((sp->device_type == XFRAME_II_DEVICE) ||
            ((subid & 0xFF) >= 0x07)) {
                val64 = readq(&bar0->gpio_control);
-               val64 ^= GPIO_CTRL_GPIO_0;
+               if (on)
+                       val64 |= GPIO_CTRL_GPIO_0;
+               else
+                       val64 &= ~GPIO_CTRL_GPIO_0;
+
                writeq(val64, &bar0->gpio_control);
        } else {
                val64 = readq(&bar0->adapter_control);
-               val64 ^= ADAPTER_LED_ON;
+               if (on)
+                       val64 |= ADAPTER_LED_ON;
+               else
+                       val64 &= ~ADAPTER_LED_ON;
+
                writeq(val64, &bar0->adapter_control);
        }
 
-       mod_timer(&sp->id_timer, jiffies + HZ / 2);
 }
 
 /**
- * s2io_ethtool_idnic - To physically identify the nic on the system.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @id : pointer to the structure with identification parameters given by
- * ethtool.
+ * s2io_ethtool_set_led - To physically identify the nic on the system.
+ * @dev : network device
+ * @state: led setting
+ *
  * Description: Used to physically identify the NIC on the system.
  * The Link LED will blink for a time specified by the user for
  * identification.
  * NOTE: The Link has to be Up to be able to blink the LED. Hence
  * identification is possible only if it's link is up.
- * Return value:
- * int , returns 0 on success
  */
 
-static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
+static int s2io_ethtool_set_led(struct net_device *dev,
+                               enum ethtool_phys_id_state state)
 {
-       u64 val64 = 0, last_gpio_ctrl_val;
        struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
-       u16 subid;
+       u16 subid = sp->pdev->subsystem_device;
 
-       subid = sp->pdev->subsystem_device;
-       last_gpio_ctrl_val = readq(&bar0->gpio_control);
        if ((sp->device_type == XFRAME_I_DEVICE) && ((subid & 0xFF) < 0x07)) {
-               val64 = readq(&bar0->adapter_control);
+               u64 val64 = readq(&bar0->adapter_control);
                if (!(val64 & ADAPTER_CNTL_EN)) {
                        pr_err("Adapter Link down, cannot blink LED\n");
-                       return -EFAULT;
+                       return -EAGAIN;
                }
        }
-       if (sp->id_timer.function == NULL) {
-               init_timer(&sp->id_timer);
-               sp->id_timer.function = s2io_phy_id;
-               sp->id_timer.data = (unsigned long)sp;
-       }
-       mod_timer(&sp->id_timer, jiffies);
-       if (data)
-               msleep_interruptible(data * HZ);
-       else
-               msleep_interruptible(MAX_FLICKER_TIME);
-       del_timer_sync(&sp->id_timer);
 
-       if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) {
-               writeq(last_gpio_ctrl_val, &bar0->gpio_control);
-               last_gpio_ctrl_val = readq(&bar0->gpio_control);
+       switch (state) {
+       case ETHTOOL_ID_ACTIVE:
+               sp->adapt_ctrl_org = readq(&bar0->gpio_control);
+               return 1;       /* cycle on/off once per second */
+
+       case ETHTOOL_ID_ON:
+               s2io_set_led(sp, true);
+               break;
+
+       case ETHTOOL_ID_OFF:
+               s2io_set_led(sp, false);
+               break;
+
+       case ETHTOOL_ID_INACTIVE:
+               if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid))
+                       writeq(sp->adapt_ctrl_org, &bar0->gpio_control);
        }
 
        return 0;
@@ -6621,25 +6567,6 @@ static int s2io_ethtool_get_regs_len(struct net_device *dev)
 }
 
 
-static u32 s2io_ethtool_get_rx_csum(struct net_device *dev)
-{
-       struct s2io_nic *sp = netdev_priv(dev);
-
-       return sp->rx_csum;
-}
-
-static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
-{
-       struct s2io_nic *sp = netdev_priv(dev);
-
-       if (data)
-               sp->rx_csum = 1;
-       else
-               sp->rx_csum = 0;
-
-       return 0;
-}
-
 static int s2io_get_eeprom_len(struct net_device *dev)
 {
        return XENA_EEPROM_SPACE;
@@ -6691,61 +6618,27 @@ static void s2io_ethtool_get_strings(struct net_device *dev,
        }
 }
 
-static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
-{
-       if (data)
-               dev->features |= NETIF_F_IP_CSUM;
-       else
-               dev->features &= ~NETIF_F_IP_CSUM;
-
-       return 0;
-}
-
-static u32 s2io_ethtool_op_get_tso(struct net_device *dev)
-{
-       return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
-       if (data)
-               dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
-       else
-               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
-       return 0;
-}
-
-static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+static int s2io_set_features(struct net_device *dev, u32 features)
 {
        struct s2io_nic *sp = netdev_priv(dev);
-       int rc = 0;
-       int changed = 0;
-
-       if (data & ~ETH_FLAG_LRO)
-               return -EINVAL;
-
-       if (data & ETH_FLAG_LRO) {
-               if (!(dev->features & NETIF_F_LRO)) {
-                       dev->features |= NETIF_F_LRO;
-                       changed = 1;
-               }
-       } else if (dev->features & NETIF_F_LRO) {
-               dev->features &= ~NETIF_F_LRO;
-               changed = 1;
-       }
+       u32 changed = (features ^ dev->features) & NETIF_F_LRO;
 
        if (changed && netif_running(dev)) {
+               int rc;
+
                s2io_stop_all_tx_queue(sp);
                s2io_card_down(sp);
+               dev->features = features;
                rc = s2io_card_up(sp);
                if (rc)
                        s2io_reset(sp);
                else
                        s2io_start_all_tx_queue(sp);
+
+               return rc ? rc : 1;
        }
 
-       return rc;
+       return 0;
 }
 
 static const struct ethtool_ops netdev_ethtool_ops = {
@@ -6761,18 +6654,9 @@ static const struct ethtool_ops netdev_ethtool_ops = {
        .get_ringparam = s2io_ethtool_gringparam,
        .get_pauseparam = s2io_ethtool_getpause_data,
        .set_pauseparam = s2io_ethtool_setpause_data,
-       .get_rx_csum = s2io_ethtool_get_rx_csum,
-       .set_rx_csum = s2io_ethtool_set_rx_csum,
-       .set_tx_csum = s2io_ethtool_op_set_tx_csum,
-       .set_flags = s2io_ethtool_set_flags,
-       .get_flags = ethtool_op_get_flags,
-       .set_sg = ethtool_op_set_sg,
-       .get_tso = s2io_ethtool_op_get_tso,
-       .set_tso = s2io_ethtool_op_set_tso,
-       .set_ufo = ethtool_op_set_ufo,
        .self_test = s2io_ethtool_test,
        .get_strings = s2io_ethtool_get_strings,
-       .phys_id = s2io_ethtool_idnic,
+       .set_phys_id = s2io_ethtool_set_led,
        .get_ethtool_stats = s2io_get_ethtool_stats,
        .get_sset_count = s2io_get_sset_count,
 };
@@ -7227,7 +7111,7 @@ static void do_s2io_card_down(struct s2io_nic *sp, int do_io)
                /* As per the HW requirement we need to replenish the
                 * receive buffer to avoid the ring bump. Since there is
                 * no intention of processing the Rx frame at this pointwe are
-                * just settting the ownership bit of rxd in Each Rx
+                * just setting the ownership bit of rxd in Each Rx
                 * ring to HW and set the appropriate buffer size
                 * based on the ring mode
                 */
@@ -7541,7 +7425,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
        if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
            ((!ring_data->lro) ||
             (ring_data->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) &&
-           (sp->rx_csum)) {
+           (dev->features & NETIF_F_RXCSUM)) {
                l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
                l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1);
                if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) {
@@ -7552,7 +7436,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                         */
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                        if (ring_data->lro) {
-                               u32 tcp_len;
+                               u32 tcp_len = 0;
                                u8 *tcp;
                                int ret = 0;
 
@@ -7802,8 +7686,7 @@ static const struct net_device_ops s2io_netdev_ops = {
        .ndo_do_ioctl           = s2io_ioctl,
        .ndo_set_mac_address    = s2io_set_mac_addr,
        .ndo_change_mtu         = s2io_change_mtu,
-       .ndo_vlan_rx_register   = s2io_vlan_rx_register,
-       .ndo_vlan_rx_kill_vid   = s2io_vlan_rx_kill_vid,
+       .ndo_set_features       = s2io_set_features,
        .ndo_tx_timeout         = s2io_tx_watchdog,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = s2io_netpoll,
@@ -8035,25 +7918,24 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
        /* Initializing the BAR1 address as the start of the FIFO pointer. */
        for (j = 0; j < MAX_TX_FIFOS; j++) {
-               mac_control->tx_FIFO_start[j] =
-                       (struct TxFIFO_element __iomem *)
-                       (sp->bar1 + (j * 0x00020000));
+               mac_control->tx_FIFO_start[j] = sp->bar1 + (j * 0x00020000);
        }
 
        /*  Driver entry points */
        dev->netdev_ops = &s2io_netdev_ops;
        SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-       dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-       dev->features |= NETIF_F_LRO;
-       dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+       dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+               NETIF_F_TSO | NETIF_F_TSO6 |
+               NETIF_F_RXCSUM | NETIF_F_LRO;
+       dev->features |= dev->hw_features |
+               NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+       if (sp->device_type & XFRAME_II_DEVICE) {
+               dev->hw_features |= NETIF_F_UFO;
+               if (ufo)
+                       dev->features |= NETIF_F_UFO;
+       }
        if (sp->high_dma_flag == true)
                dev->features |= NETIF_F_HIGHDMA;
-       dev->features |= NETIF_F_TSO;
-       dev->features |= NETIF_F_TSO6;
-       if ((sp->device_type & XFRAME_II_DEVICE) && (ufo))  {
-               dev->features |= NETIF_F_UFO;
-               dev->features |= NETIF_F_HW_CSUM;
-       }
        dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
        INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
        INIT_WORK(&sp->set_link_task, s2io_set_link);
@@ -8337,9 +8219,11 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
                return;
        }
 
-       flush_scheduled_work();
-
        sp = netdev_priv(dev);
+
+       cancel_work_sync(&sp->rst_timer_task);
+       cancel_work_sync(&sp->set_link_task);
+
        unregister_netdev(dev);
 
        free_shared_mem(sp);
@@ -8681,18 +8565,12 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
        struct s2io_nic *sp = netdev_priv(dev);
 
        skb->protocol = eth_type_trans(skb, dev);
-       if (sp->vlgrp && vlan_tag && (sp->vlan_strip_flag)) {
-               /* Queueing the vlan frame to the upper layer */
-               if (sp->config.napi)
-                       vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag);
-               else
-                       vlan_hwaccel_rx(skb, sp->vlgrp, vlan_tag);
-       } else {
-               if (sp->config.napi)
-                       netif_receive_skb(skb);
-               else
-                       netif_rx(skb);
-       }
+       if (vlan_tag && sp->vlan_strip_flag)
+               __vlan_hwaccel_put_tag(skb, vlan_tag);
+       if (sp->config.napi)
+               netif_receive_skb(skb);
+       else
+               netif_rx(skb);
 }
 
 static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,