Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
[sfrench/cifs-2.6.git] / drivers / net / s2io.c
index 7f6b0e611e3ba203e1c3f5c36f48125c3d9dafee..b8c0e7b4ca1cdd0e0d4d3a9251af47cff784a326 100644 (file)
@@ -38,7 +38,7 @@
  * Tx descriptors that can be associated with each corresponding FIFO.
  * intr_type: This defines the type of interrupt. The values can be 0(INTA),
  *     2(MSI_X). Default value is '2(MSI_X)'
- * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
+ * lro_enable: Specifies whether to enable Large Receive Offload (LRO) or not.
  *     Possible values '1' for enable '0' for disable. Default is '0'
  * lro_max_pkts: This parameter defines maximum number of packets can be
  *     aggregated as a single large packet
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.2"
+#define DRV_VERSION "2.0.26.5"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -276,46 +276,46 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
        {"ring_5_full_cnt"},
        {"ring_6_full_cnt"},
        {"ring_7_full_cnt"},
-       ("alarm_transceiver_temp_high"),
-       ("alarm_transceiver_temp_low"),
-       ("alarm_laser_bias_current_high"),
-       ("alarm_laser_bias_current_low"),
-       ("alarm_laser_output_power_high"),
-       ("alarm_laser_output_power_low"),
-       ("warn_transceiver_temp_high"),
-       ("warn_transceiver_temp_low"),
-       ("warn_laser_bias_current_high"),
-       ("warn_laser_bias_current_low"),
-       ("warn_laser_output_power_high"),
-       ("warn_laser_output_power_low"),
-       ("lro_aggregated_pkts"),
-       ("lro_flush_both_count"),
-       ("lro_out_of_sequence_pkts"),
-       ("lro_flush_due_to_max_pkts"),
-       ("lro_avg_aggr_pkts"),
-       ("mem_alloc_fail_cnt"),
-       ("pci_map_fail_cnt"),
-       ("watchdog_timer_cnt"),
-       ("mem_allocated"),
-       ("mem_freed"),
-       ("link_up_cnt"),
-       ("link_down_cnt"),
-       ("link_up_time"),
-       ("link_down_time"),
-       ("tx_tcode_buf_abort_cnt"),
-       ("tx_tcode_desc_abort_cnt"),
-       ("tx_tcode_parity_err_cnt"),
-       ("tx_tcode_link_loss_cnt"),
-       ("tx_tcode_list_proc_err_cnt"),
-       ("rx_tcode_parity_err_cnt"),
-       ("rx_tcode_abort_cnt"),
-       ("rx_tcode_parity_abort_cnt"),
-       ("rx_tcode_rda_fail_cnt"),
-       ("rx_tcode_unkn_prot_cnt"),
-       ("rx_tcode_fcs_err_cnt"),
-       ("rx_tcode_buf_size_err_cnt"),
-       ("rx_tcode_rxd_corrupt_cnt"),
-       ("rx_tcode_unkn_err_cnt"),
+       {"alarm_transceiver_temp_high"},
+       {"alarm_transceiver_temp_low"},
+       {"alarm_laser_bias_current_high"},
+       {"alarm_laser_bias_current_low"},
+       {"alarm_laser_output_power_high"},
+       {"alarm_laser_output_power_low"},
+       {"warn_transceiver_temp_high"},
+       {"warn_transceiver_temp_low"},
+       {"warn_laser_bias_current_high"},
+       {"warn_laser_bias_current_low"},
+       {"warn_laser_output_power_high"},
+       {"warn_laser_output_power_low"},
+       {"lro_aggregated_pkts"},
+       {"lro_flush_both_count"},
+       {"lro_out_of_sequence_pkts"},
+       {"lro_flush_due_to_max_pkts"},
+       {"lro_avg_aggr_pkts"},
+       {"mem_alloc_fail_cnt"},
+       {"pci_map_fail_cnt"},
+       {"watchdog_timer_cnt"},
+       {"mem_allocated"},
+       {"mem_freed"},
+       {"link_up_cnt"},
+       {"link_down_cnt"},
+       {"link_up_time"},
+       {"link_down_time"},
+       {"tx_tcode_buf_abort_cnt"},
+       {"tx_tcode_desc_abort_cnt"},
+       {"tx_tcode_parity_err_cnt"},
+       {"tx_tcode_link_loss_cnt"},
+       {"tx_tcode_list_proc_err_cnt"},
+       {"rx_tcode_parity_err_cnt"},
+       {"rx_tcode_abort_cnt"},
+       {"rx_tcode_parity_abort_cnt"},
+       {"rx_tcode_rda_fail_cnt"},
+       {"rx_tcode_unkn_prot_cnt"},
+       {"rx_tcode_fcs_err_cnt"},
+       {"rx_tcode_buf_size_err_cnt"},
+       {"rx_tcode_rxd_corrupt_cnt"},
+       {"rx_tcode_unkn_err_cnt"},
        {"tda_err_cnt"},
        {"pfc_err_cnt"},
        {"pcc_err_cnt"},
@@ -355,6 +355,16 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
                        timer.data = (unsigned long) arg;       \
                        mod_timer(&timer, (jiffies + exp))      \
 
+/* copy mac addr to def_mac_addr array */
+static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr)
+{
+       sp->def_mac_addr[offset].mac_addr[5] = (u8) (mac_addr);
+       sp->def_mac_addr[offset].mac_addr[4] = (u8) (mac_addr >> 8);
+       sp->def_mac_addr[offset].mac_addr[3] = (u8) (mac_addr >> 16);
+       sp->def_mac_addr[offset].mac_addr[2] = (u8) (mac_addr >> 24);
+       sp->def_mac_addr[offset].mac_addr[1] = (u8) (mac_addr >> 32);
+       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)
@@ -452,14 +462,15 @@ S2IO_PARM_INT(mc_pause_threshold_q4q7, 187);
 S2IO_PARM_INT(shared_splits, 0);
 S2IO_PARM_INT(tmac_util_period, 5);
 S2IO_PARM_INT(rmac_util_period, 5);
-S2IO_PARM_INT(bimodal, 0);
 S2IO_PARM_INT(l3l4hdr_size, 128);
 /* Frequency of Rx desc syncs expressed as power of 2 */
 S2IO_PARM_INT(rxsync_frequency, 3);
 /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
 S2IO_PARM_INT(intr_type, 2);
 /* Large receive offload feature */
-S2IO_PARM_INT(lro, 0);
+static unsigned int lro_enable;
+module_param_named(lro, lro_enable, uint, 0);
+
 /* Max pkts to be aggregated by LRO at one time. If not specified,
  * aggregation happens until we hit max IP pkt size(64K)
  */
@@ -561,7 +572,7 @@ static int init_shared_mem(struct s2io_nic *nic)
        for (i = 0; i < config->tx_fifo_num; i++) {
                int fifo_len = config->tx_cfg[i].fifo_len;
                int list_holder_size = fifo_len * sizeof(struct list_info_hold);
-               mac_control->fifos[i].list_info = kmalloc(list_holder_size,
+               mac_control->fifos[i].list_info = kzalloc(list_holder_size,
                                                          GFP_KERNEL);
                if (!mac_control->fifos[i].list_info) {
                        DBG_PRINT(INFO_DBG,
@@ -569,7 +580,6 @@ static int init_shared_mem(struct s2io_nic *nic)
                        return -ENOMEM;
                }
                mem_allocated += list_holder_size;
-               memset(mac_control->fifos[i].list_info, 0, list_holder_size);
        }
        for (i = 0; i < config->tx_fifo_num; i++) {
                int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
@@ -700,7 +710,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                                                  GFP_KERNEL);
                        if (!rx_blocks->rxds)
                                return -ENOMEM;
-                       mem_allocated += 
+                       mem_allocated +=
                        (sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
                        for (l=0; l<rxd_count[nic->rxd_mode];l++) {
                                rx_blocks->rxds[l].virt_addr =
@@ -762,7 +772,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                                            (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
                                        if (!ba->ba_0_org)
                                                return -ENOMEM;
-                                       mem_allocated += 
+                                       mem_allocated +=
                                                (BUF0_LEN + ALIGN_SIZE);
                                        tmp = (unsigned long)ba->ba_0_org;
                                        tmp += ALIGN_SIZE;
@@ -773,7 +783,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                                            (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
                                        if (!ba->ba_1_org)
                                                return -ENOMEM;
-                                       mem_allocated 
+                                       mem_allocated
                                                += (BUF1_LEN + ALIGN_SIZE);
                                        tmp = (unsigned long) ba->ba_1_org;
                                        tmp += ALIGN_SIZE;
@@ -858,7 +868,7 @@ static void free_shared_mem(struct s2io_nic *nic)
                                            mac_control->fifos[i].
                                            list_info[mem_blks].
                                            list_phy_addr);
-                       nic->mac_control.stats_info->sw_stat.mem_freed 
+                       nic->mac_control.stats_info->sw_stat.mem_freed
                                                += PAGE_SIZE;
                }
                /* If we got a zero DMA address during allocation,
@@ -873,11 +883,11 @@ static void free_shared_mem(struct s2io_nic *nic)
                                dev->name);
                        DBG_PRINT(INIT_DBG, "Virtual address %p\n",
                                mac_control->zerodma_virt_addr);
-                       nic->mac_control.stats_info->sw_stat.mem_freed 
+                       nic->mac_control.stats_info->sw_stat.mem_freed
                                                += PAGE_SIZE;
                }
                kfree(mac_control->fifos[i].list_info);
-               nic->mac_control.stats_info->sw_stat.mem_freed += 
+               nic->mac_control.stats_info->sw_stat.mem_freed +=
                (nic->config.tx_cfg[i].fifo_len *sizeof(struct list_info_hold));
        }
 
@@ -895,7 +905,7 @@ static void free_shared_mem(struct s2io_nic *nic)
                                            tmp_v_addr, tmp_p_addr);
                        nic->mac_control.stats_info->sw_stat.mem_freed += size;
                        kfree(mac_control->rings[i].rx_blocks[j].rxds);
-                       nic->mac_control.stats_info->sw_stat.mem_freed += 
+                       nic->mac_control.stats_info->sw_stat.mem_freed +=
                        ( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
                }
        }
@@ -926,7 +936,7 @@ static void free_shared_mem(struct s2io_nic *nic)
                                        (rxd_count[nic->rxd_mode] + 1));
                        }
                        kfree(mac_control->rings[i].ba);
-                       nic->mac_control.stats_info->sw_stat.mem_freed += 
+                       nic->mac_control.stats_info->sw_stat.mem_freed +=
                        (sizeof(struct buffAdd *) * blk_cnt);
                }
        }
@@ -936,12 +946,12 @@ static void free_shared_mem(struct s2io_nic *nic)
                                    mac_control->stats_mem_sz,
                                    mac_control->stats_mem,
                                    mac_control->stats_mem_phy);
-               nic->mac_control.stats_info->sw_stat.mem_freed += 
+               nic->mac_control.stats_info->sw_stat.mem_freed +=
                        mac_control->stats_mem_sz;
        }
        if (nic->ufo_in_band_v) {
                kfree(nic->ufo_in_band_v);
-               nic->mac_control.stats_info->sw_stat.mem_freed 
+               nic->mac_control.stats_info->sw_stat.mem_freed
                        += (ufo_size * sizeof(u64));
        }
 }
@@ -1486,7 +1496,7 @@ static int init_nic(struct s2io_nic *nic)
                                &bar0->rts_frm_len_n[i]);
                }
        }
-       
+
        /* Disable differentiated services steering logic */
        for (i = 0; i < 64; i++) {
                if (rts_ds_steer(nic, i, 0) == FAILURE) {
@@ -1566,90 +1576,57 @@ static int init_nic(struct s2io_nic *nic)
                time++;
        }
 
-       if (nic->config.bimodal) {
-               int k = 0;
-               for (k = 0; k < config->rx_ring_num; k++) {
-                       val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD;
-                       val64 |= TTI_CMD_MEM_OFFSET(0x38+k);
-                       writeq(val64, &bar0->tti_command_mem);
-
+       /* RTI Initialization */
+       if (nic->device_type == XFRAME_II_DEVICE) {
                /*
-                * Once the operation completes, the Strobe bit of the command
-                * register will be reset. We poll for this particular condition
-                * We wait for a maximum of 500ms for the operation to complete,
-                * if it's not complete by then we return error.
-               */
-                       time = 0;
-                       while (TRUE) {
-                               val64 = readq(&bar0->tti_command_mem);
-                               if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) {
-                                       break;
-                               }
-                               if (time > 10) {
-                                       DBG_PRINT(ERR_DBG,
-                                               "%s: TTI init Failed\n",
-                                       dev->name);
-                                       return -1;
-                               }
-                               time++;
-                               msleep(50);
-                       }
-               }
-       } else {
-
-               /* RTI Initialization */
-               if (nic->device_type == XFRAME_II_DEVICE) {
-                       /*
-                        * Programmed to generate Apprx 500 Intrs per
-                        * second
-                        */
-                       int count = (nic->config.bus_speed * 125)/4;
-                       val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count);
-               } else {
-                       val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF);
-               }
-               val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) |
-                   RTI_DATA1_MEM_RX_URNG_B(0x10) |
-                   RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN;
-
-               writeq(val64, &bar0->rti_data1_mem);
+                * Programmed to generate Apprx 500 Intrs per
+                * second
+                */
+               int count = (nic->config.bus_speed * 125)/4;
+               val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count);
+       } else
+               val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF);
+       val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) |
+                RTI_DATA1_MEM_RX_URNG_B(0x10) |
+                RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN;
+
+       writeq(val64, &bar0->rti_data1_mem);
+
+       val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
+               RTI_DATA2_MEM_RX_UFC_B(0x2) ;
+       if (nic->config.intr_type == MSI_X)
+           val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
+                       RTI_DATA2_MEM_RX_UFC_D(0x40));
+       else
+           val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \
+                       RTI_DATA2_MEM_RX_UFC_D(0x80));
+       writeq(val64, &bar0->rti_data2_mem);
 
-               val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
-                   RTI_DATA2_MEM_RX_UFC_B(0x2) ;
-               if (nic->config.intr_type == MSI_X)
-                   val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
-                               RTI_DATA2_MEM_RX_UFC_D(0x40));
-               else
-                   val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \
-                               RTI_DATA2_MEM_RX_UFC_D(0x80));
-               writeq(val64, &bar0->rti_data2_mem);
+       for (i = 0; i < config->rx_ring_num; i++) {
+               val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD
+                               | RTI_CMD_MEM_OFFSET(i);
+               writeq(val64, &bar0->rti_command_mem);
 
-               for (i = 0; i < config->rx_ring_num; i++) {
-                       val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD
-                                       | RTI_CMD_MEM_OFFSET(i);
-                       writeq(val64, &bar0->rti_command_mem);
+               /*
+                * Once the operation completes, the Strobe bit of the
+                * command register will be reset. We poll for this
+                * particular condition. We wait for a maximum of 500ms
+                * for the operation to complete, if it's not complete
+                * by then we return error.
+                */
+               time = 0;
+               while (TRUE) {
+                       val64 = readq(&bar0->rti_command_mem);
+                       if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD))
+                               break;
 
-                       /*
-                        * Once the operation completes, the Strobe bit of the
-                        * command register will be reset. We poll for this
-                        * particular condition. We wait for a maximum of 500ms
-                        * for the operation to complete, if it's not complete
-                        * by then we return error.
-                        */
-                       time = 0;
-                       while (TRUE) {
-                               val64 = readq(&bar0->rti_command_mem);
-                               if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) {
-                                       break;
-                               }
-                               if (time > 10) {
-                                       DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n",
-                                                 dev->name);
-                                       return -1;
-                               }
-                               time++;
-                               msleep(50);
+                       if (time > 10) {
+                               DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n",
+                                         dev->name);
+                               return -1;
                        }
+                       time++;
+                       msleep(50);
                }
        }
 
@@ -1739,7 +1716,7 @@ static int init_nic(struct s2io_nic *nic)
                        MISC_LINK_STABILITY_PRD(3);
                writeq(val64, &bar0->misc_control);
                val64 = readq(&bar0->pic_control2);
-               val64 &= ~(BIT(13)|BIT(14)|BIT(15));
+               val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15));
                writeq(val64, &bar0->pic_control2);
        }
        if (strstr(nic->product_name, "CX4")) {
@@ -1784,7 +1761,7 @@ static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr)
        writeq(temp64, addr);
 }
 
-void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
+static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
 {
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
        register u64 gen_int_mask = 0;
@@ -2006,7 +1983,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag)
        int ret = 0, herc;
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        u64 val64 = readq(&bar0->adapter_status);
-       
+
        herc = (sp->device_type == XFRAME_II_DEVICE);
 
        if (flag == FALSE) {
@@ -2152,8 +2129,6 @@ static int start_nic(struct s2io_nic *nic)
                       &bar0->prc_rxd0_n[i]);
 
                val64 = readq(&bar0->prc_ctrl_n[i]);
-               if (nic->config.bimodal)
-                       val64 |= PRC_CTRL_BIMODAL_INTERRUPT;
                if (nic->rxd_mode == RXD_MODE_1)
                        val64 |= PRC_CTRL_RC_ENABLED;
                else
@@ -2313,7 +2288,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
                        mac_control->fifos[i].list_info[j].list_virt_addr;
                        skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
                        if (skb) {
-                               nic->mac_control.stats_info->sw_stat.mem_freed 
+                               nic->mac_control.stats_info->sw_stat.mem_freed
                                        += skb->truesize;
                                dev_kfree_skb(skb);
                                cnt++;
@@ -2452,7 +2427,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                }
                if ((rxdp->Control_1 & RXD_OWN_XENA) &&
                        ((nic->rxd_mode == RXD_MODE_3B) &&
-                               (rxdp->Control_2 & BIT(0)))) {
+                               (rxdp->Control_2 & s2BIT(0)))) {
                        mac_control->rings[ring_no].rx_curr_put_info.
                                        offset = off;
                        goto end;
@@ -2478,7 +2453,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                                mem_alloc_fail_cnt++;
                        return -ENOMEM ;
                }
-               nic->mac_control.stats_info->sw_stat.mem_allocated 
+               nic->mac_control.stats_info->sw_stat.mem_allocated
                        += skb->truesize;
                if (nic->rxd_mode == RXD_MODE_1) {
                        /* 1 buffer mode - normal operation mode */
@@ -2493,7 +2468,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                                DMA_ERROR_CODE))
                                goto pci_map_failed;
 
-                       rxdp->Control_2 = 
+                       rxdp->Control_2 =
                                SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
 
                } else if (nic->rxd_mode == RXD_MODE_3B) {
@@ -2565,7 +2540,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                                rxdp->Control_2 |= SET_BUFFER2_SIZE_3
                                                                (dev->mtu + 4);
                        }
-                       rxdp->Control_2 |= BIT(0);
+                       rxdp->Control_2 |= s2BIT(0);
                }
                rxdp->Host_Control = (unsigned long) (skb);
                if (alloc_tab & ((1 << rxsync_frequency) - 1))
@@ -3402,12 +3377,12 @@ static void s2io_reset(struct s2io_nic * sp)
                pci_write_config_dword(sp->pdev, 0x68, 0x7C);
 
                /* Clearing PCI_STATUS error reflected here */
-               writeq(BIT(62), &bar0->txpic_int_reg);
+               writeq(s2BIT(62), &bar0->txpic_int_reg);
        }
 
        /* Reset device statistics maintained by OS */
        memset(&sp->stats, 0, sizeof (struct net_device_stats));
-       
+
        up_cnt = sp->mac_control.stats_info->sw_stat.link_up_cnt;
        down_cnt = sp->mac_control.stats_info->sw_stat.link_down_cnt;
        up_time = sp->mac_control.stats_info->sw_stat.link_up_time;
@@ -3449,7 +3424,7 @@ static void s2io_reset(struct s2io_nic * sp)
        }
 
        /* restore the previously assigned mac address */
-       s2io_set_mac_addr(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr);
+       do_s2io_prog_unicast(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr);
 
        sp->device_enabled_once = FALSE;
 }
@@ -3600,7 +3575,7 @@ static int wait_for_msix_trans(struct s2io_nic *nic, int i)
 
        do {
                val64 = readq(&bar0->xmsi_access);
-               if (!(val64 & BIT(15)))
+               if (!(val64 & s2BIT(15)))
                        break;
                mdelay(1);
                cnt++;
@@ -3622,7 +3597,7 @@ static void restore_xmsi_data(struct s2io_nic *nic)
        for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
                writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
                writeq(nic->msix_info[i].data, &bar0->xmsi_data);
-               val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+               val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6));
                writeq(val64, &bar0->xmsi_access);
                if (wait_for_msix_trans(nic, i)) {
                        DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -3639,7 +3614,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
 
        /* Store and display */
        for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
-               val64 = (BIT(15) | vBIT(i, 26, 6));
+               val64 = (s2BIT(15) | vBIT(i, 26, 6));
                writeq(val64, &bar0->xmsi_access);
                if (wait_for_msix_trans(nic, i)) {
                        DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -3661,34 +3636,31 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
        u16 msi_control; /* Temp variable */
        int ret, i, j, msix_indx = 1;
 
-       nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
+       nic->entries = kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct msix_entry),
                               GFP_KERNEL);
-       if (nic->entries == NULL) {
+       if (!nic->entries) {
                DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
                        __FUNCTION__);
                nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                return -ENOMEM;
        }
-       nic->mac_control.stats_info->sw_stat.mem_allocated 
+       nic->mac_control.stats_info->sw_stat.mem_allocated
                += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
-       memset(nic->entries, 0,MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
 
        nic->s2io_entries =
-               kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
+               kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct s2io_msix_entry),
                                   GFP_KERNEL);
-       if (nic->s2io_entries == NULL) {
-               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", 
+       if (!nic->s2io_entries) {
+               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
                        __FUNCTION__);
                nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                kfree(nic->entries);
-               nic->mac_control.stats_info->sw_stat.mem_freed 
+               nic->mac_control.stats_info->sw_stat.mem_freed
                        += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
                return -ENOMEM;
        }
-        nic->mac_control.stats_info->sw_stat.mem_allocated 
+        nic->mac_control.stats_info->sw_stat.mem_allocated
                += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
-       memset(nic->s2io_entries, 0,
-              MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
 
        for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
                nic->entries[i].entry = i;
@@ -3706,27 +3678,15 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
        }
        writeq(tx_mat, &bar0->tx_mat0_n[0]);
 
-       if (!nic->config.bimodal) {
-               rx_mat = readq(&bar0->rx_mat);
-               for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
-                       rx_mat |= RX_MAT_SET(j, msix_indx);
-                       nic->s2io_entries[msix_indx].arg 
-                               = &nic->mac_control.rings[j];
-                       nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
-                       nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
-               }
-               writeq(rx_mat, &bar0->rx_mat);
-       } else {
-               tx_mat = readq(&bar0->tx_mat0_n[7]);
-               for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
-                       tx_mat |= TX_MAT_SET(i, msix_indx);
-                       nic->s2io_entries[msix_indx].arg 
-                               = &nic->mac_control.rings[j];
-                       nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
-                       nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
-               }
-               writeq(tx_mat, &bar0->tx_mat0_n[7]);
+       rx_mat = readq(&bar0->rx_mat);
+       for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) {
+               rx_mat |= RX_MAT_SET(j, msix_indx);
+               nic->s2io_entries[msix_indx].arg
+                       = &nic->mac_control.rings[j];
+               nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
+               nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
        }
+       writeq(rx_mat, &bar0->rx_mat);
 
        nic->avail_msix_vectors = 0;
        ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X);
@@ -3738,10 +3698,10 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
        if (ret) {
                DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
                kfree(nic->entries);
-               nic->mac_control.stats_info->sw_stat.mem_freed 
+               nic->mac_control.stats_info->sw_stat.mem_freed
                        += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
                kfree(nic->s2io_entries);
-               nic->mac_control.stats_info->sw_stat.mem_freed 
+               nic->mac_control.stats_info->sw_stat.mem_freed
                += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
                nic->entries = NULL;
                nic->s2io_entries = NULL;
@@ -3895,7 +3855,7 @@ static int s2io_open(struct net_device *dev)
                goto hw_init_failed;
        }
 
-       if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) {
+       if (do_s2io_prog_unicast(dev, dev->dev_addr) == FAILURE) {
                DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n");
                s2io_card_down(sp);
                err = -ENODEV;
@@ -3910,12 +3870,12 @@ hw_init_failed:
        if (sp->config.intr_type == MSI_X) {
                if (sp->entries) {
                        kfree(sp->entries);
-                       sp->mac_control.stats_info->sw_stat.mem_freed 
+                       sp->mac_control.stats_info->sw_stat.mem_freed
                        += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
                }
                if (sp->s2io_entries) {
                        kfree(sp->s2io_entries);
-                       sp->mac_control.stats_info->sw_stat.mem_freed 
+                       sp->mac_control.stats_info->sw_stat.mem_freed
                        += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
                }
        }
@@ -4270,7 +4230,7 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
  *  1 - if alarm bit set
  *  0 - if alarm bit is not set
  */
-int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
+static int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
                          unsigned long long *cnt)
 {
        u64 val64;
@@ -4674,13 +4634,13 @@ static void s2io_updt_stats(struct s2io_nic *sp)
                do {
                        udelay(100);
                        val64 = readq(&bar0->stat_cfg);
-                       if (!(val64 & BIT(0)))
+                       if (!(val64 & s2BIT(0)))
                                break;
                        cnt++;
                        if (cnt == 5)
                                break; /* Updt failed */
                } while(1);
-       } 
+       }
 }
 
 /**
@@ -4897,8 +4857,48 @@ static void s2io_set_multicast(struct net_device *dev)
        }
 }
 
+/* add unicast MAC address to CAM */
+static int do_s2io_add_unicast(struct s2io_nic *sp, u64 addr, int off)
+{
+       u64 val64;
+       struct XENA_dev_config __iomem *bar0 = sp->bar0;
+
+       writeq(RMAC_ADDR_DATA0_MEM_ADDR(addr),
+               &bar0->rmac_addr_data0_mem);
+
+       val64 =
+               RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+               RMAC_ADDR_CMD_MEM_OFFSET(off);
+       writeq(val64, &bar0->rmac_addr_cmd_mem);
+
+       /* Wait till command completes */
+       if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
+               RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+               S2IO_BIT_RESET)) {
+               DBG_PRINT(INFO_DBG, "add_mac_addr failed\n");
+               return FAILURE;
+       }
+       return SUCCESS;
+}
+
+/**
+ * s2io_set_mac_addr driver entry point
+ */
+static int s2io_set_mac_addr(struct net_device *dev, void *p)
+{
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EINVAL;
+
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+       /* store the MAC address in CAM */
+       return (do_s2io_prog_unicast(dev, dev->dev_addr));
+}
+
 /**
- *  s2io_set_mac_addr - Programs the Xframe mac address
+ *  do_s2io_prog_unicast - Programs the Xframe mac address
  *  @dev : pointer to the device structure.
  *  @addr: a uchar pointer to the new mac address which is to be set.
  *  Description : This procedure will program the Xframe to receive
@@ -4906,56 +4906,31 @@ static void s2io_set_multicast(struct net_device *dev)
  *  Return value: SUCCESS on success and an appropriate (-)ve integer
  *  as defined in errno.h file on failure.
  */
-
-static int s2io_set_mac_addr(struct net_device *dev, u8 * addr)
+static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
 {
        struct s2io_nic *sp = dev->priv;
-       struct XENA_dev_config __iomem *bar0 = sp->bar0;
-       register u64 val64, mac_addr = 0;
+       register u64 mac_addr = 0, perm_addr = 0;
        int i;
-       u64 old_mac_addr = 0;
 
        /*
-        * Set the new MAC address as the new unicast filter and reflect this
-        * change on the device address registered with the OS. It will be
-        * at offset 0.
-        */
+       * Set the new MAC address as the new unicast filter and reflect this
+       * change on the device address registered with the OS. It will be
+       * at offset 0.
+       */
        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];
+               perm_addr <<= 8;
+               perm_addr |= sp->def_mac_addr[0].mac_addr[i];
        }
 
-       if(0 == mac_addr)
+       /* check if the dev_addr is different than perm_addr */
+       if (mac_addr == perm_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),
-              &bar0->rmac_addr_data0_mem);
-
-       val64 =
-           RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-           RMAC_ADDR_CMD_MEM_OFFSET(0);
-       writeq(val64, &bar0->rmac_addr_cmd_mem);
-       /* Wait till command completes */
-       if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-                     RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET)) {
-               DBG_PRINT(ERR_DBG, "%s: set_mac_addr failed\n", dev->name);
-               return FAILURE;
-       }
-
-       return SUCCESS;
+       do_s2io_copy_mac_addr(sp, 0, mac_addr);
+       return (do_s2io_add_unicast(sp, mac_addr, 0));
 }
 
 /**
@@ -5003,7 +4978,9 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
        info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
        info->advertising = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
        info->port = PORT_FIBRE;
-       /* info->transceiver?? TODO */
+
+       /* info->transceiver */
+       info->transceiver = XCVR_EXTERNAL;
 
        if (netif_carrier_ok(sp->dev)) {
                info->speed = 10000;
@@ -5169,13 +5146,13 @@ static void s2io_ethtool_gringparam(struct net_device *dev,
                ering->rx_max_pending = MAX_RX_DESC_2;
 
        ering->tx_max_pending = MAX_TX_DESC;
-       for (i = 0 ; i < sp->config.tx_fifo_num ; i++) 
+       for (i = 0 ; i < sp->config.tx_fifo_num ; i++)
                tx_desc_count += sp->config.tx_cfg[i].fifo_len;
-       
+
        DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
        ering->tx_pending = tx_desc_count;
        rx_desc_count = 0;
-       for (i = 0 ; i < sp->config.rx_ring_num ; i++) 
+       for (i = 0 ; i < sp->config.rx_ring_num ; i++)
                rx_desc_count += sp->config.rx_cfg[i].num_rxd;
 
        ering->rx_pending = rx_desc_count;
@@ -6543,7 +6520,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                                        mem_alloc_fail_cnt++;
                                return -ENOMEM ;
                        }
-                       sp->mac_control.stats_info->sw_stat.mem_allocated 
+                       sp->mac_control.stats_info->sw_stat.mem_allocated
                                += (*skb)->truesize;
                        /* storing the mapped addr in a temp variable
                         * such it will be used for next rxd whose
@@ -6576,7 +6553,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                                        mem_alloc_fail_cnt++;
                                return -ENOMEM;
                        }
-                       sp->mac_control.stats_info->sw_stat.mem_allocated 
+                       sp->mac_control.stats_info->sw_stat.mem_allocated
                                += (*skb)->truesize;
                        rxdp3->Buffer2_ptr = *temp2 =
                                pci_map_single(sp->pdev, (*skb)->data,
@@ -7111,7 +7088,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                        DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%x\n",
                                dev->name, err_mask);
                        sp->stats.rx_crc_errors++;
-                       sp->mac_control.stats_info->sw_stat.mem_freed 
+                       sp->mac_control.stats_info->sw_stat.mem_freed
                                += skb->truesize;
                        dev_kfree_skb(skb);
                        atomic_dec(&sp->rx_bufs_left[ring_no]);
@@ -7160,7 +7137,8 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                                int ret = 0;
 
                                ret = s2io_club_tcp_session(skb->data, &tcp,
-                                               &tcp_len, &lro, rxdp, sp);
+                                                           &tcp_len, &lro,
+                                                           rxdp, sp);
                                switch (ret) {
                                        case 3: /* Begin anew */
                                                lro->parent = skb;
@@ -7265,13 +7243,13 @@ static void s2io_link(struct s2io_nic * sp, int link)
                        DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
                        netif_carrier_off(dev);
                        if(sp->mac_control.stats_info->sw_stat.link_up_cnt)
-                       sp->mac_control.stats_info->sw_stat.link_up_time = 
+                       sp->mac_control.stats_info->sw_stat.link_up_time =
                                jiffies - sp->start_time;
                        sp->mac_control.stats_info->sw_stat.link_down_cnt++;
                } else {
                        DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
                        if (sp->mac_control.stats_info->sw_stat.link_down_cnt)
-                       sp->mac_control.stats_info->sw_stat.link_down_time = 
+                       sp->mac_control.stats_info->sw_stat.link_down_time =
                                jiffies - sp->start_time;
                        sp->mac_control.stats_info->sw_stat.link_up_cnt++;
                        netif_carrier_on(dev);
@@ -7476,7 +7454,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        else
                sp->device_type = XFRAME_I_DEVICE;
 
-       sp->lro = lro;
+       sp->lro = lro_enable;
 
        /* Initialize some PCI/PCI-X fields of the NIC. */
        s2io_init_pci(sp);
@@ -7582,6 +7560,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        dev->get_stats = &s2io_get_stats;
        dev->set_multicast_list = &s2io_set_multicast;
        dev->do_ioctl = &s2io_ioctl;
+       dev->set_mac_address = &s2io_set_mac_addr;
        dev->change_mtu = &s2io_change_mtu;
        SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
@@ -7667,6 +7646,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        /*  Set the factory defined MAC address initially   */
        dev->addr_len = ETH_ALEN;
        memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN);
+       memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
 
         /* Store the values of the MSIX table in the s2io_nic structure */
        store_xmsi_data(sp);
@@ -7756,14 +7736,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        /* Initialize device name */
        sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name);
 
-       /* Initialize bimodal Interrupts */
-       sp->config.bimodal = bimodal;
-       if (!(sp->device_type & XFRAME_II_DEVICE) && bimodal) {
-               sp->config.bimodal = 0;
-               DBG_PRINT(ERR_DBG,"%s:Bimodal intr not supported by Xframe I\n",
-                       dev->name);
-       }
-
        /*
         * Make Link state as off at this point, when the Link change
         * interrupt comes the state will be automatically changed to
@@ -7829,7 +7801,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
  * the module loadable parameters and initializes PCI configuration space.
  */
 
-int __init s2io_starter(void)
+static int __init s2io_starter(void)
 {
        return pci_register_driver(&s2io_driver);
 }