fbdev: save the activate field before calling fb_check_var()
[powerpc.git] / drivers / net / s2io.c
index 89881aa..290e1c1 100644 (file)
@@ -1,6 +1,6 @@
 /************************************************************************
  * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2005 Neterion Inc.
+ * Copyright(c) 2002-2007 Neterion Inc.
 
  * This software may be used and distributed according to the terms of
  * the GNU General Public License (GPL), incorporated herein by reference.
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.16.1"
+#define DRV_VERSION "2.0.22.1"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -139,7 +139,7 @@ static char s2io_gstrings[][ETH_GSTRING_LEN] = {
        "BIST Test\t(offline)"
 };
 
-static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
+static char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = {
        {"tmac_frms"},
        {"tmac_data_octets"},
        {"tmac_drop_frms"},
@@ -233,7 +233,10 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
        {"rxd_rd_cnt"},
        {"rxd_wr_cnt"},
        {"txf_rd_cnt"},
-       {"rxf_wr_cnt"},
+       {"rxf_wr_cnt"}
+};
+
+static char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = {
        {"rmac_ttl_1519_4095_frms"},
        {"rmac_ttl_4096_8191_frms"},
        {"rmac_ttl_8192_max_frms"},
@@ -249,7 +252,10 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
        {"rmac_red_discard"},
        {"rmac_rts_discard"},
        {"rmac_ingm_full_discard"},
-       {"link_fault_cnt"},
+       {"link_fault_cnt"}
+};
+
+static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
        {"\n DRIVER STATISTICS"},
        {"single_bit_ecc_errs"},
        {"double_bit_ecc_errs"},
@@ -277,8 +283,16 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
        ("lro_avg_aggr_pkts"),
 };
 
-#define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN
-#define S2IO_STAT_STRINGS_LEN S2IO_STAT_LEN * ETH_GSTRING_LEN
+#define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN
+#define S2IO_ENHANCED_STAT_LEN sizeof(ethtool_enhanced_stats_keys)/ \
+                                       ETH_GSTRING_LEN
+#define S2IO_DRIVER_STAT_LEN sizeof(ethtool_driver_stats_keys)/ ETH_GSTRING_LEN
+
+#define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN )
+#define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN )
+
+#define XFRAME_I_STAT_STRINGS_LEN ( XFRAME_I_STAT_LEN * ETH_GSTRING_LEN )
+#define XFRAME_II_STAT_STRINGS_LEN ( XFRAME_II_STAT_LEN * ETH_GSTRING_LEN )
 
 #define S2IO_TEST_LEN  sizeof(s2io_gstrings) / ETH_GSTRING_LEN
 #define S2IO_STRINGS_LEN       S2IO_TEST_LEN * ETH_GSTRING_LEN
@@ -302,7 +316,7 @@ static void s2io_vlan_rx_register(struct net_device *dev,
 }
 
 /* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
-int vlan_strip_flag;
+static int vlan_strip_flag;
 
 /* Unregister the vlan */
 static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
@@ -311,8 +325,7 @@ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
        unsigned long flags;
 
        spin_lock_irqsave(&nic->tx_lock, flags);
-       if (nic->vlgrp)
-               nic->vlgrp->vlan_devices[vid] = NULL;
+       vlan_group_set_device(nic->vlgrp, vid, NULL);
        spin_unlock_irqrestore(&nic->tx_lock, flags);
 }
 
@@ -381,7 +394,6 @@ static const u64 fix_mac[] = {
        END_SIGN
 };
 
-MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
@@ -503,7 +515,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                mac_control->fifos[i].list_info = kmalloc(list_holder_size,
                                                          GFP_KERNEL);
                if (!mac_control->fifos[i].list_info) {
-                       DBG_PRINT(ERR_DBG,
+                       DBG_PRINT(INFO_DBG,
                                  "Malloc failed for list_info\n");
                        return -ENOMEM;
                }
@@ -529,9 +541,9 @@ static int init_shared_mem(struct s2io_nic *nic)
                        tmp_v = pci_alloc_consistent(nic->pdev,
                                                     PAGE_SIZE, &tmp_p);
                        if (!tmp_v) {
-                               DBG_PRINT(ERR_DBG,
+                               DBG_PRINT(INFO_DBG,
                                          "pci_alloc_consistent ");
-                               DBG_PRINT(ERR_DBG, "failed for TxDL\n");
+                               DBG_PRINT(INFO_DBG, "failed for TxDL\n");
                                return -ENOMEM;
                        }
                        /* If we got a zero DMA address(can happen on
@@ -548,9 +560,9 @@ static int init_shared_mem(struct s2io_nic *nic)
                                tmp_v = pci_alloc_consistent(nic->pdev,
                                                     PAGE_SIZE, &tmp_p);
                                if (!tmp_v) {
-                                       DBG_PRINT(ERR_DBG,
+                                       DBG_PRINT(INFO_DBG,
                                          "pci_alloc_consistent ");
-                                       DBG_PRINT(ERR_DBG, "failed for TxDL\n");
+                                       DBG_PRINT(INFO_DBG, "failed for TxDL\n");
                                        return -ENOMEM;
                                }
                        }
@@ -2174,7 +2186,7 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
        /* skb_shinfo(skb)->frag_list will have L4 data payload */
        skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
        if (skb_shinfo(skb)->frag_list == NULL) {
-               DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
+               DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
                return -ENOMEM ;
        }
        frag_list = skb_shinfo(skb)->frag_list;
@@ -2182,7 +2194,7 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
        frag_list->next = NULL;
        tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
        frag_list->data = tmp;
-       frag_list->tail = tmp;
+       skb_reset_tail_pointer(frag_list);
 
        /* Buffer-2 receives L4 data payload */
        ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
@@ -2229,6 +2241,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
        struct buffAdd *ba;
        unsigned long flags;
        struct RxD_t *first_rxdp = NULL;
+       u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
 
        mac_control = &nic->mac_control;
        config = &nic->config;
@@ -2300,8 +2313,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                /* allocate skb */
                skb = dev_alloc_skb(size);
                if(!skb) {
-                       DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
-                       DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n");
+                       DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+                       DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
                        if (first_rxdp) {
                                wmb();
                                first_rxdp->Control_1 |= RXD_OWN_XENA;
@@ -2329,14 +2342,21 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                         * payload
                         */
 
+                       /* save the buffer pointers to avoid frequent dma mapping */
+                       Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
+                       Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
                        memset(rxdp, 0, sizeof(struct RxD3));
+                       /* restore the buffer pointers for dma sync*/
+                       ((struct RxD3*)rxdp)->Buffer0_ptr = Buffer0_ptr;
+                       ((struct RxD3*)rxdp)->Buffer1_ptr = Buffer1_ptr;
+
                        ba = &mac_control->rings[ring_no].ba[block_no][off];
                        skb_reserve(skb, BUF0_LEN);
                        tmp = (u64)(unsigned long) skb->data;
                        tmp += ALIGN_SIZE;
                        tmp &= ~ALIGN_SIZE;
                        skb->data = (void *) (unsigned long)tmp;
-                       skb->tail = (void *) (unsigned long)tmp;
+                       skb_reset_tail_pointer(skb);
 
                        if (!(((struct RxD3*)rxdp)->Buffer0_ptr))
                                ((struct RxD3*)rxdp)->Buffer0_ptr =
@@ -2560,8 +2580,8 @@ static int s2io_poll(struct net_device *dev, int *budget)
 
        for (i = 0; i < config->rx_ring_num; i++) {
                if (fill_rx_buffers(nic, i) == -ENOMEM) {
-                       DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name);
-                       DBG_PRINT(ERR_DBG, " in Rx Poll!!\n");
+                       DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
+                       DBG_PRINT(INFO_DBG, " in Rx Poll!!\n");
                        break;
                }
        }
@@ -2577,8 +2597,8 @@ no_rx:
 
        for (i = 0; i < config->rx_ring_num; i++) {
                if (fill_rx_buffers(nic, i) == -ENOMEM) {
-                       DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name);
-                       DBG_PRINT(ERR_DBG, " in Rx Poll!!\n");
+                       DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
+                       DBG_PRINT(INFO_DBG, " in Rx Poll!!\n");
                        break;
                }
        }
@@ -2627,8 +2647,8 @@ static void s2io_netpoll(struct net_device *dev)
 
        for (i = 0; i < config->rx_ring_num; i++) {
                if (fill_rx_buffers(nic, i) == -ENOMEM) {
-                       DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name);
-                       DBG_PRINT(ERR_DBG, " in Rx Netpoll!!\n");
+                       DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
+                       DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n");
                        break;
                }
        }
@@ -3294,6 +3314,7 @@ static void s2io_reset(struct s2io_nic * sp)
        u16 subid, pci_cmd;
        int i;
        u16 val16;
+       unsigned long long reset_cnt = 0;
        DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
                        __FUNCTION__, sp->dev->name);
 
@@ -3359,6 +3380,11 @@ new_way:
 
        /* Reset device statistics maintained by OS */
        memset(&sp->stats, 0, sizeof (struct net_device_stats));
+       /* save reset count */
+       reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt;
+       memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
+       /* restore reset count */
+       sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt;
 
        /* SXE-002: Configure link and activity LED to turn it off */
        subid = sp->pdev->subsystem_device;
@@ -3380,6 +3406,9 @@ new_way:
                writeq(val64, &bar0->pcc_err_reg);
        }
 
+       /* restore the previously assigned mac address */
+       s2io_set_mac_addr(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr);
+
        sp->device_enabled_once = FALSE;
 }
 
@@ -3643,7 +3672,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
        nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
                               GFP_KERNEL);
        if (nic->entries == NULL) {
-               DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
                return -ENOMEM;
        }
        memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
@@ -3652,7 +3681,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
                kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
                                   GFP_KERNEL);
        if (nic->s2io_entries == NULL) {
-               DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
                kfree(nic->entries);
                return -ENOMEM;
        }
@@ -4003,7 +4032,7 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n)
                        DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
                        DBG_PRINT(INTR_DBG, "PANIC levels\n");
                        if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
-                               DBG_PRINT(ERR_DBG, "Out of memory in %s",
+                               DBG_PRINT(INFO_DBG, "Out of memory in %s",
                                          __FUNCTION__);
                                clear_bit(0, (&sp->tasklet_status));
                                return -1;
@@ -4013,8 +4042,8 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n)
                        tasklet_schedule(&sp->task);
 
        } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) {
-                       DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name);
-                       DBG_PRINT(ERR_DBG, " in Rx Intr!!\n");
+                       DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name);
+                       DBG_PRINT(INFO_DBG, " in Rx Intr!!\n");
        }
        return 0;
 }
@@ -4127,6 +4156,11 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
                        val64 &= ~GPIO_INT_MASK_LINK_UP;
                        val64 |= GPIO_INT_MASK_LINK_DOWN;
                        writeq(val64, &bar0->gpio_int_mask);
+
+                       /* turn off LED */
+                       val64 = readq(&bar0->adapter_control);
+                       val64 = val64 &(~ADAPTER_LED_ON);
+                       writeq(val64, &bar0->adapter_control);
                }
        }
        val64 = readq(&bar0->gpio_int_mask);
@@ -4258,9 +4292,7 @@ static void s2io_updt_stats(struct s2io_nic *sp)
                        if (cnt == 5)
                                break; /* Updt failed */
                } while(1);
-       } else {
-               memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
-       }
+       } 
 }
 
 /**
@@ -4493,6 +4525,7 @@ static int s2io_set_mac_addr(struct net_device *dev, u8 * addr)
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        register u64 val64, mac_addr = 0;
        int i;
+       u64 old_mac_addr = 0;
 
        /*
         * Set the new MAC address as the new unicast filter and reflect this
@@ -4502,6 +4535,22 @@ static int s2io_set_mac_addr(struct net_device *dev, u8 * addr)
        for (i = 0; i < ETH_ALEN; i++) {
                mac_addr <<= 8;
                mac_addr |= addr[i];
+               old_mac_addr <<= 8;
+               old_mac_addr |= sp->def_mac_addr[0].mac_addr[i];
+       }
+
+       if(0 == mac_addr)
+               return SUCCESS;
+
+       /* Update the internal structure with this new mac address */
+       if(mac_addr != old_mac_addr) {
+               memset(sp->def_mac_addr[0].mac_addr, 0, sizeof(ETH_ALEN));
+               sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_addr);
+               sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_addr >> 8);
+               sp->def_mac_addr[0].mac_addr[3] = (u8) (mac_addr >> 16);
+               sp->def_mac_addr[0].mac_addr[2] = (u8) (mac_addr >> 24);
+               sp->def_mac_addr[0].mac_addr[1] = (u8) (mac_addr >> 32);
+               sp->def_mac_addr[0].mac_addr[0] = (u8) (mac_addr >> 40);
        }
 
        writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr),
@@ -4604,7 +4653,11 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev,
        info->regdump_len = XENA_REG_SPACE;
        info->eedump_len = XENA_EEPROM_SPACE;
        info->testinfo_len = S2IO_TEST_LEN;
-       info->n_stats = S2IO_STAT_LEN;
+
+       if (sp->device_type == XFRAME_I_DEVICE)
+               info->n_stats = XFRAME_I_STAT_LEN;
+       else
+               info->n_stats = XFRAME_II_STAT_LEN;
 }
 
 /**
@@ -5626,22 +5679,30 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
        tmp_stats[i++] = le32_to_cpu(stat_info->rxd_wr_cnt);
        tmp_stats[i++] = le32_to_cpu(stat_info->txf_rd_cnt);
        tmp_stats[i++] = le32_to_cpu(stat_info->rxf_wr_cnt);
-       tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_1519_4095_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_4096_8191_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_8192_max_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_gt_max_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_osized_alt_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_jabber_alt_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_gt_max_alt_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_vlan_frms);
-        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_len_discard);
-        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_fcs_discard);
-        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pf_discard);
-        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_da_discard);
-        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_red_discard);
-        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_rts_discard);
-        tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ingm_full_discard);
-        tmp_stats[i++] = le32_to_cpu(stat_info->link_fault_cnt);
+
+       /* Enhanced statistics exist only for Hercules */
+       if(sp->device_type == XFRAME_II_DEVICE) {
+               tmp_stats[i++] =
+                               le64_to_cpu(stat_info->rmac_ttl_1519_4095_frms);
+               tmp_stats[i++] =
+                               le64_to_cpu(stat_info->rmac_ttl_4096_8191_frms);
+               tmp_stats[i++] =
+                               le64_to_cpu(stat_info->rmac_ttl_8192_max_frms);
+               tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_gt_max_frms);
+               tmp_stats[i++] = le64_to_cpu(stat_info->rmac_osized_alt_frms);
+               tmp_stats[i++] = le64_to_cpu(stat_info->rmac_jabber_alt_frms);
+               tmp_stats[i++] = le64_to_cpu(stat_info->rmac_gt_max_alt_frms);
+               tmp_stats[i++] = le64_to_cpu(stat_info->rmac_vlan_frms);
+               tmp_stats[i++] = le32_to_cpu(stat_info->rmac_len_discard);
+               tmp_stats[i++] = le32_to_cpu(stat_info->rmac_fcs_discard);
+               tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pf_discard);
+               tmp_stats[i++] = le32_to_cpu(stat_info->rmac_da_discard);
+               tmp_stats[i++] = le32_to_cpu(stat_info->rmac_red_discard);
+               tmp_stats[i++] = le32_to_cpu(stat_info->rmac_rts_discard);
+               tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ingm_full_discard);
+               tmp_stats[i++] = le32_to_cpu(stat_info->link_fault_cnt);
+       }
+
        tmp_stats[i++] = 0;
        tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs;
        tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
@@ -5721,18 +5782,42 @@ static int s2io_ethtool_self_test_count(struct net_device *dev)
 static void s2io_ethtool_get_strings(struct net_device *dev,
                                     u32 stringset, u8 * data)
 {
+       int stat_size = 0;
+       struct s2io_nic *sp = dev->priv;
+
        switch (stringset) {
        case ETH_SS_TEST:
                memcpy(data, s2io_gstrings, S2IO_STRINGS_LEN);
                break;
        case ETH_SS_STATS:
-               memcpy(data, &ethtool_stats_keys,
-                      sizeof(ethtool_stats_keys));
+               stat_size = sizeof(ethtool_xena_stats_keys);
+               memcpy(data, &ethtool_xena_stats_keys,stat_size);
+               if(sp->device_type == XFRAME_II_DEVICE) {
+                       memcpy(data + stat_size,
+                               &ethtool_enhanced_stats_keys,
+                               sizeof(ethtool_enhanced_stats_keys));
+                       stat_size += sizeof(ethtool_enhanced_stats_keys);
+               }
+
+               memcpy(data + stat_size, &ethtool_driver_stats_keys,
+                       sizeof(ethtool_driver_stats_keys));
        }
 }
 static int s2io_ethtool_get_stats_count(struct net_device *dev)
 {
-       return (S2IO_STAT_LEN);
+       struct s2io_nic *sp = dev->priv;
+       int stat_count = 0;
+       switch(sp->device_type) {
+       case XFRAME_I_DEVICE:
+               stat_count = XFRAME_I_STAT_LEN;
+       break;
+
+       case XFRAME_II_DEVICE:
+               stat_count = XFRAME_II_STAT_LEN;
+       break;
+       }
+
+       return stat_count;
 }
 
 static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
@@ -5875,12 +5960,12 @@ static void s2io_tasklet(unsigned long dev_addr)
                for (i = 0; i < config->rx_ring_num; i++) {
                        ret = fill_rx_buffers(sp, i);
                        if (ret == -ENOMEM) {
-                               DBG_PRINT(ERR_DBG, "%s: Out of ",
+                               DBG_PRINT(INFO_DBG, "%s: Out of ",
                                          dev->name);
                                DBG_PRINT(ERR_DBG, "memory in tasklet\n");
                                break;
                        } else if (ret == -EFILL) {
-                               DBG_PRINT(ERR_DBG,
+                               DBG_PRINT(INFO_DBG,
                                          "%s: Rx Ring %d is full\n",
                                          dev->name, i);
                                break;
@@ -5967,7 +6052,7 @@ static void s2io_set_link(struct work_struct *work)
        clear_bit(0, &(nic->link_state));
 
 out_unlock:
-       rtnl_lock();
+       rtnl_unlock();
 }
 
 static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
@@ -5991,8 +6076,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                } else {
                        *skb = dev_alloc_skb(size);
                        if (!(*skb)) {
-                               DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
-                               DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n");
+                               DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+                               DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
                                return -ENOMEM ;
                        }
                        /* storing the mapped addr in a temp variable
@@ -6014,7 +6099,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                } else {
                        *skb = dev_alloc_skb(size);
                        if (!(*skb)) {
-                               DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n",
+                               DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
                                        dev->name);
                                return -ENOMEM;
                        }
@@ -6041,7 +6126,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                } else {
                        *skb = dev_alloc_skb(size);
                        if (!(*skb)) {
-                               DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n",
+                               DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
                                          dev->name);
                                return -ENOMEM;
                        }
@@ -6124,10 +6209,13 @@ static  int rxd_owner_bit_reset(struct s2io_nic *sp)
                                        rx_blocks[j].rxds[k].virt_addr;
                                if(sp->rxd_mode >= RXD_MODE_3A)
                                        ba = &mac_control->rings[i].ba[j][k];
-                               set_rxd_buffer_pointer(sp, rxdp, ba,
+                               if (set_rxd_buffer_pointer(sp, rxdp, ba,
                                                       &skb,(u64 *)&temp0_64,
                                                       (u64 *)&temp1_64,
-                                                      (u64 *)&temp2_64, size);
+                                                      (u64 *)&temp2_64,
+                                                       size) == ENOMEM) {
+                                       return 0;
+                               }
 
                                set_rxd_buffer_size(sp, rxdp, size);
                                wmb();
@@ -6539,7 +6627,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 
        /* Updating statistics */
        rxdp->Host_Control = 0;
-       sp->rx_pkt_count++;
        sp->stats.rx_packets++;
        if (sp->rxd_mode == RXD_MODE_1) {
                int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
@@ -7124,8 +7211,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        mac_down = (u32) tmp64;
        mac_up = (u32) (tmp64 >> 32);
 
-       memset(sp->def_mac_addr[0].mac_addr, 0, sizeof(ETH_ALEN));
-
        sp->def_mac_addr[0].mac_addr[3] = (u8) (mac_up);
        sp->def_mac_addr[0].mac_addr[2] = (u8) (mac_up >> 8);
        sp->def_mac_addr[0].mac_addr[1] = (u8) (mac_up >> 16);
@@ -7177,7 +7262,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                goto register_failed;
        }
        s2io_vpd_read(sp);
-       DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n");
+       DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2007 Neterion Inc.\n");
        DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name,
                  sp->product_name, get_xena_rev_id(sp->pdev));
        DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,