sky2: fix sky2_link_down copy/paste comment error
[safe/jmp/linux-2.6] / drivers / net / bnx2x_main.c
index 0ebbc77..20f0ed9 100644 (file)
 #include "bnx2x_init_ops.h"
 #include "bnx2x_dump.h"
 
-#define DRV_MODULE_VERSION     "1.48.114-1"
-#define DRV_MODULE_RELDATE     "2009/07/29"
+#define DRV_MODULE_VERSION     "1.52.1"
+#define DRV_MODULE_RELDATE     "2009/08/12"
 #define BNX2X_BC_VER           0x040200
 
 #include <linux/firmware.h>
 #include "bnx2x_fw_file_hdr.h"
 /* FW files */
-#define FW_FILE_PREFIX_E1              "bnx2x-e1-"
-#define FW_FILE_PREFIX_E1H             "bnx2x-e1h-"
+#define FW_FILE_PREFIX_E1      "bnx2x-e1-"
+#define FW_FILE_PREFIX_E1H     "bnx2x-e1h-"
 
 /* Time in jiffies before concluding the transmitter is hung */
 #define TX_TIMEOUT             (5*HZ)
@@ -138,12 +138,9 @@ static struct {
 
 
 static const struct pci_device_id bnx2x_pci_tbl[] = {
-       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 },
-       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711 },
-       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711E,
-               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711E },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 },
+       { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E },
        { 0 }
 };
 
@@ -156,7 +153,7 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
 /* used only at init
  * locking is done by mcp
  */
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
+void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
 {
        pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
        pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val);
@@ -203,7 +200,7 @@ static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
 void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
                      u32 len32)
 {
-       struct dmae_command *dmae = &bp->init_dmae;
+       struct dmae_command dmae;
        u32 *wb_comp = bnx2x_sp(bp, wb_comp);
        int cnt = 200;
 
@@ -216,43 +213,43 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
                return;
        }
 
-       mutex_lock(&bp->dmae_mutex);
-
-       memset(dmae, 0, sizeof(struct dmae_command));
+       memset(&dmae, 0, sizeof(struct dmae_command));
 
-       dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
-                       DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
-                       DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+       dmae.opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+                      DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+                      DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
 #ifdef __BIG_ENDIAN
-                       DMAE_CMD_ENDIANITY_B_DW_SWAP |
+                      DMAE_CMD_ENDIANITY_B_DW_SWAP |
 #else
-                       DMAE_CMD_ENDIANITY_DW_SWAP |
+                      DMAE_CMD_ENDIANITY_DW_SWAP |
 #endif
-                       (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
-                       (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
-       dmae->src_addr_lo = U64_LO(dma_addr);
-       dmae->src_addr_hi = U64_HI(dma_addr);
-       dmae->dst_addr_lo = dst_addr >> 2;
-       dmae->dst_addr_hi = 0;
-       dmae->len = len32;
-       dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
-       dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
-       dmae->comp_val = DMAE_COMP_VAL;
+                      (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+                      (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+       dmae.src_addr_lo = U64_LO(dma_addr);
+       dmae.src_addr_hi = U64_HI(dma_addr);
+       dmae.dst_addr_lo = dst_addr >> 2;
+       dmae.dst_addr_hi = 0;
+       dmae.len = len32;
+       dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+       dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+       dmae.comp_val = DMAE_COMP_VAL;
 
        DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
           DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
                    "dst_addr [%x:%08x (%08x)]\n"
           DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
-          dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
-          dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
-          dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+          dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo,
+          dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, dst_addr,
+          dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val);
        DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
           bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
           bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
 
+       mutex_lock(&bp->dmae_mutex);
+
        *wb_comp = 0;
 
-       bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+       bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp));
 
        udelay(5);
 
@@ -276,7 +273,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 
 void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 {
-       struct dmae_command *dmae = &bp->init_dmae;
+       struct dmae_command dmae;
        u32 *wb_comp = bnx2x_sp(bp, wb_comp);
        int cnt = 200;
 
@@ -291,41 +288,41 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
                return;
        }
 
-       mutex_lock(&bp->dmae_mutex);
-
-       memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
-       memset(dmae, 0, sizeof(struct dmae_command));
+       memset(&dmae, 0, sizeof(struct dmae_command));
 
-       dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
-                       DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
-                       DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+       dmae.opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+                      DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+                      DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
 #ifdef __BIG_ENDIAN
-                       DMAE_CMD_ENDIANITY_B_DW_SWAP |
+                      DMAE_CMD_ENDIANITY_B_DW_SWAP |
 #else
-                       DMAE_CMD_ENDIANITY_DW_SWAP |
+                      DMAE_CMD_ENDIANITY_DW_SWAP |
 #endif
-                       (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
-                       (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
-       dmae->src_addr_lo = src_addr >> 2;
-       dmae->src_addr_hi = 0;
-       dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
-       dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
-       dmae->len = len32;
-       dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
-       dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
-       dmae->comp_val = DMAE_COMP_VAL;
+                      (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+                      (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+       dmae.src_addr_lo = src_addr >> 2;
+       dmae.src_addr_hi = 0;
+       dmae.dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
+       dmae.dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
+       dmae.len = len32;
+       dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+       dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+       dmae.comp_val = DMAE_COMP_VAL;
 
        DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
           DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
                    "dst_addr [%x:%08x (%08x)]\n"
           DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
-          dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
-          dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
-          dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+          dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo,
+          dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, src_addr,
+          dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val);
 
+       mutex_lock(&bp->dmae_mutex);
+
+       memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
        *wb_comp = 0;
 
-       bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+       bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp));
 
        udelay(5);
 
@@ -349,6 +346,21 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
        mutex_unlock(&bp->dmae_mutex);
 }
 
+void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
+                              u32 addr, u32 len)
+{
+       int offset = 0;
+
+       while (len > DMAE_LEN32_WR_MAX) {
+               bnx2x_write_dmae(bp, phys_addr + offset,
+                                addr + offset, DMAE_LEN32_WR_MAX);
+               offset += DMAE_LEN32_WR_MAX * 4;
+               len -= DMAE_LEN32_WR_MAX;
+       }
+
+       bnx2x_write_dmae(bp, phys_addr + offset, addr + offset, len);
+}
+
 /* used only for slowpath so not inlined */
 static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
 {
@@ -711,7 +723,6 @@ static void bnx2x_int_disable(struct bnx2x *bp)
        REG_WR(bp, addr, val);
        if (REG_RD(bp, addr) != val)
                BNX2X_ERR("BUG! proper val not read from IGU!\n");
-
 }
 
 static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
@@ -1648,6 +1659,7 @@ reuse_rx:
                }
 
                skb_record_rx_queue(skb, fp->index);
+
 #ifdef BCM_VLAN
                if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
                    (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
@@ -2406,14 +2418,12 @@ static void bnx2x_link_attn(struct bnx2x *bp)
                int func;
                int vn;
 
+               /* Set the attention towards other drivers on the same port */
                for (vn = VN_0; vn < E1HVN_MAX; vn++) {
                        if (vn == BP_E1HVN(bp))
                                continue;
 
                        func = ((vn << 1) | port);
-
-                       /* Set the attention towards other drivers
-                          on the same port */
                        REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
                               (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
                }
@@ -2868,6 +2878,7 @@ static inline void bnx2x_fan_failure(struct bnx2x *bp)
               " damage.  Please contact Dell Support for assistance\n",
               bp->dev->name);
 }
+
 static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
 {
        int port = BP_PORT(bp);
@@ -2927,7 +2938,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
                REG_WR(bp, reg_offset, val);
 
                BNX2X_ERR("FATAL HW block attention set0 0x%x\n",
-                         (attn & HW_INTERRUT_ASSERT_SET_0));
+                         (u32)(attn & HW_INTERRUT_ASSERT_SET_0));
                bnx2x_panic();
        }
 }
@@ -2958,7 +2969,7 @@ static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
                REG_WR(bp, reg_offset, val);
 
                BNX2X_ERR("FATAL HW block attention set1 0x%x\n",
-                         (attn & HW_INTERRUT_ASSERT_SET_1));
+                         (u32)(attn & HW_INTERRUT_ASSERT_SET_1));
                bnx2x_panic();
        }
 }
@@ -2998,7 +3009,7 @@ static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
                REG_WR(bp, reg_offset, val);
 
                BNX2X_ERR("FATAL HW block attention set2 0x%x\n",
-                         (attn & HW_INTERRUT_ASSERT_SET_2));
+                         (u32)(attn & HW_INTERRUT_ASSERT_SET_2));
                bnx2x_panic();
        }
 }
@@ -4412,6 +4423,9 @@ static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
        bnx2x_stats_stm[state][event].action(bp);
        bp->stats_state = bnx2x_stats_stm[state][event].next_state;
 
+       /* Make sure the state has been "changed" */
+       smp_wmb();
+
        if ((event != STATS_EVENT_UPDATE) || (bp->msglevel & NETIF_MSG_TIMER))
                DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
                   state, event, bp->stats_state);
@@ -5917,6 +5931,24 @@ static void bnx2x_reset_common(struct bnx2x *bp)
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
 }
 
+static void bnx2x_init_pxp(struct bnx2x *bp)
+{
+       u16 devctl;
+       int r_order, w_order;
+
+       pci_read_config_word(bp->pdev,
+                            bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
+       DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
+       w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+       if (bp->mrrs == -1)
+               r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+       else {
+               DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
+               r_order = bp->mrrs;
+       }
+
+       bnx2x_init_pxp_arb(bp, r_order, w_order);
+}
 
 static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
 {
@@ -6479,9 +6511,15 @@ static int bnx2x_init_func(struct bnx2x *bp)
 
 
        if (CHIP_IS_E1H(bp)) {
-               for (i = 0; i < 9; i++)
-                       bnx2x_init_block(bp,
-                                        cm_blocks[i], FUNC0_STAGE + func);
+               bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func);
+               bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func);
 
                REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
                REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
@@ -6512,7 +6550,9 @@ static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
 
        bp->dmae_ready = 0;
        mutex_init(&bp->dmae_mutex);
-       bnx2x_gunzip_init(bp);
+       rc = bnx2x_gunzip_init(bp);
+       if (rc)
+               return rc;
 
        switch (load_code) {
        case FW_MSG_CODE_DRV_LOAD_COMMON:
@@ -7109,6 +7149,9 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
                }
 
                msleep(1);
+
+               if (bp->panic)
+                       return -EIO;
        }
 
        /* timeout! */
@@ -7373,7 +7416,12 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
        rc = bnx2x_setup_leading(bp);
        if (rc) {
                BNX2X_ERR("Setup leading failed!\n");
+#ifndef BNX2X_STOP_ON_ERROR
                goto load_error3;
+#else
+               bp->panic = 1;
+               return -EBUSY;
+#endif
        }
 
        if (CHIP_IS_E1H(bp))
@@ -7611,9 +7659,11 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 
        bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
 
+       /* Set "drop all" */
        bp->rx_mode = BNX2X_RX_MODE_NONE;
        bnx2x_set_storm_rx_mode(bp);
 
+       /* Disable HW interrupts, NAPI and Tx */
        bnx2x_netif_stop(bp, 1);
 
        del_timer_sync(&bp->timer);
@@ -8533,9 +8583,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
        else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
                 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
                bp->mdio.prtad =
-                       (bp->link_params.ext_phy_config &
-                        PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT;
+                       XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
 
        val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
        val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
@@ -8939,50 +8987,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        return 0;
 }
 
-#define PHY_FW_VER_LEN                 10
-
-static void bnx2x_get_drvinfo(struct net_device *dev,
-                             struct ethtool_drvinfo *info)
-{
-       struct bnx2x *bp = netdev_priv(dev);
-       u8 phy_fw_ver[PHY_FW_VER_LEN];
-
-       strcpy(info->driver, DRV_MODULE_NAME);
-       strcpy(info->version, DRV_MODULE_VERSION);
-
-       phy_fw_ver[0] = '\0';
-       if (bp->port.pmf) {
-               bnx2x_acquire_phy_lock(bp);
-               bnx2x_get_ext_phy_fw_version(&bp->link_params,
-                                            (bp->state != BNX2X_STATE_CLOSED),
-                                            phy_fw_ver, PHY_FW_VER_LEN);
-               bnx2x_release_phy_lock(bp);
-       }
-
-       snprintf(info->fw_version, 32, "BC:%d.%d.%d%s%s",
-                (bp->common.bc_ver & 0xff0000) >> 16,
-                (bp->common.bc_ver & 0xff00) >> 8,
-                (bp->common.bc_ver & 0xff),
-                ((phy_fw_ver[0] != '\0') ? " PHY:" : ""), phy_fw_ver);
-       strcpy(info->bus_info, pci_name(bp->pdev));
-       info->n_stats = BNX2X_NUM_STATS;
-       info->testinfo_len = BNX2X_NUM_TESTS;
-       info->eedump_len = bp->common.flash_size;
-       info->regdump_len = 0;
-}
-
 #define IS_E1_ONLINE(info)     (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
 #define IS_E1H_ONLINE(info)    (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
 
 static int bnx2x_get_regs_len(struct net_device *dev)
 {
-       static u32 regdump_len;
        struct bnx2x *bp = netdev_priv(dev);
+       int regdump_len = 0;
        int i;
 
-       if (regdump_len)
-               return regdump_len;
-
        if (CHIP_IS_E1(bp)) {
                for (i = 0; i < REGS_COUNT; i++)
                        if (IS_E1_ONLINE(reg_addrs[i].info))
@@ -9049,6 +9062,38 @@ static void bnx2x_get_regs(struct net_device *dev,
        }
 }
 
+#define PHY_FW_VER_LEN                 10
+
+static void bnx2x_get_drvinfo(struct net_device *dev,
+                             struct ethtool_drvinfo *info)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       u8 phy_fw_ver[PHY_FW_VER_LEN];
+
+       strcpy(info->driver, DRV_MODULE_NAME);
+       strcpy(info->version, DRV_MODULE_VERSION);
+
+       phy_fw_ver[0] = '\0';
+       if (bp->port.pmf) {
+               bnx2x_acquire_phy_lock(bp);
+               bnx2x_get_ext_phy_fw_version(&bp->link_params,
+                                            (bp->state != BNX2X_STATE_CLOSED),
+                                            phy_fw_ver, PHY_FW_VER_LEN);
+               bnx2x_release_phy_lock(bp);
+       }
+
+       snprintf(info->fw_version, 32, "BC:%d.%d.%d%s%s",
+                (bp->common.bc_ver & 0xff0000) >> 16,
+                (bp->common.bc_ver & 0xff00) >> 8,
+                (bp->common.bc_ver & 0xff),
+                ((phy_fw_ver[0] != '\0') ? " PHY:" : ""), phy_fw_ver);
+       strcpy(info->bus_info, pci_name(bp->pdev));
+       info->n_stats = BNX2X_NUM_STATS;
+       info->testinfo_len = BNX2X_NUM_TESTS;
+       info->eedump_len = bp->common.flash_size;
+       info->regdump_len = bnx2x_get_regs_len(dev);
+}
+
 static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct bnx2x *bp = netdev_priv(dev);
@@ -9114,8 +9159,7 @@ static int bnx2x_nway_reset(struct net_device *dev)
        return 0;
 }
 
-static u32
-bnx2x_get_link(struct net_device *dev)
+static u32 bnx2x_get_link(struct net_device *dev)
 {
        struct bnx2x *bp = netdev_priv(dev);
 
@@ -9539,9 +9583,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
                if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
                                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) {
                        u8 ext_phy_addr =
-                               (bp->link_params.ext_phy_config &
-                                PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-                                       PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT;
+                            XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
 
                        /* DSP Remove Download Mode */
                        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
@@ -10127,7 +10169,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
        __be32 buf[0x350 / 4];
        u8 *data = (u8 *)buf;
        int i, rc;
-       u32 magic, csum;
+       u32 magic, crc;
 
        rc = bnx2x_nvram_read(bp, 0, data, 4);
        if (rc) {
@@ -10152,10 +10194,10 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
                        goto test_nvram_exit;
                }
 
-               csum = ether_crc_le(nvram_tbl[i].size, data);
-               if (csum != CRC32_RESIDUAL) {
+               crc = ether_crc_le(nvram_tbl[i].size, data);
+               if (crc != CRC32_RESIDUAL) {
                        DP(NETIF_MSG_PROBE,
-                          "nvram_tbl[%d] csum value (0x%08x)\n", i, csum);
+                          "nvram_tbl[%d] crc value (0x%08x)\n", i, crc);
                        rc = -ENODEV;
                        goto test_nvram_exit;
                }
@@ -10564,7 +10606,7 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
        return 0;
 }
 
-static struct ethtool_ops bnx2x_ethtool_ops = {
+static const struct ethtool_ops bnx2x_ethtool_ops = {
        .get_settings           = bnx2x_get_settings,
        .set_settings           = bnx2x_set_settings,
        .get_drvinfo            = bnx2x_get_drvinfo,
@@ -10894,7 +10936,7 @@ exit_lbl:
  * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
  * netif_wake_queue()
  */
-static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct bnx2x *bp = netdev_priv(dev);
        struct bnx2x_fastpath *fp, *fp_stat;
@@ -11663,31 +11705,26 @@ err_out:
        return rc;
 }
 
-static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp)
+static void __devinit bnx2x_get_pcie_width_speed(struct bnx2x *bp,
+                                                int *width, int *speed)
 {
        u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
 
-       val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
-       return val;
-}
+       *width = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
 
-/* return value of 1=2.5GHz 2=5GHz */
-static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
-{
-       u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
-
-       val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
-       return val;
+       /* return value of 1=2.5GHz 2=5GHz */
+       *speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
 }
+
 static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
 {
+       const struct firmware *firmware = bp->firmware;
        struct bnx2x_fw_file_hdr *fw_hdr;
        struct bnx2x_fw_file_section *sections;
-       u16 *ops_offsets;
        u32 offset, len, num_ops;
+       u16 *ops_offsets;
        int i;
-       const struct firmware *firmware = bp->firmware;
-       const u8 * fw_ver;
+       const u8 *fw_ver;
 
        if (firmware->size < sizeof(struct bnx2x_fw_file_hdr))
                return -EINVAL;
@@ -11701,7 +11738,8 @@ static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
                offset = be32_to_cpu(sections[i].offset);
                len = be32_to_cpu(sections[i].len);
                if (offset + len > firmware->size) {
-                       printk(KERN_ERR PFX "Section %d length is out of bounds\n", i);
+                       printk(KERN_ERR PFX "Section %d length is out of "
+                                           "bounds\n", i);
                        return -EINVAL;
                }
        }
@@ -11713,7 +11751,8 @@ static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
 
        for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) {
                if (be16_to_cpu(ops_offsets[i]) > num_ops) {
-                       printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i);
+                       printk(KERN_ERR PFX "Section offset %d is out of "
+                                           "bounds\n", i);
                        return -EINVAL;
                }
        }
@@ -11732,17 +11771,17 @@ static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
                       BCM_5710_FW_MINOR_VERSION,
                       BCM_5710_FW_REVISION_VERSION,
                       BCM_5710_FW_ENGINEERING_VERSION);
-                return -EINVAL;
+               return -EINVAL;
        }
 
        return 0;
 }
 
-static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+static inline void be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
 {
+       const __be32 *source = (const __be32 *)_source;
+       u32 *target = (u32 *)_target;
        u32 i;
-       const __be32 *source = (const __be32*)_source;
-       u32 *target = (u32*)_target;
 
        for (i = 0; i < n/4; i++)
                target[i] = be32_to_cpu(source[i]);
@@ -11752,66 +11791,67 @@ static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
    Ops array is stored in the following format:
    {op(8bit), offset(24bit, big endian), data(32bit, big endian)}
  */
-static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
+static inline void bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
 {
+       const __be32 *source = (const __be32 *)_source;
+       struct raw_op *target = (struct raw_op *)_target;
        u32 i, j, tmp;
-       const __be32 *source = (const __be32*)_source;
-       struct raw_op *target = (struct raw_op*)_target;
 
-       for (i = 0, j = 0; i < n/8; i++, j+=2) {
+       for (i = 0, j = 0; i < n/8; i++, j += 2) {
                tmp = be32_to_cpu(source[j]);
                target[i].op = (tmp >> 24) & 0xff;
                target[i].offset =  tmp & 0xffffff;
                target[i].raw_data = be32_to_cpu(source[j+1]);
        }
 }
-static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+
+static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
 {
+       const __be16 *source = (const __be16 *)_source;
+       u16 *target = (u16 *)_target;
        u32 i;
-       u16 *target = (u16*)_target;
-       const __be16 *source = (const __be16*)_source;
 
        for (i = 0; i < n/2; i++)
                target[i] = be16_to_cpu(source[i]);
 }
 
 #define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
-       do {   \
-               u32 len = be32_to_cpu(fw_hdr->arr.len);   \
-               bp->arr = kmalloc(len, GFP_KERNEL);  \
+       do { \
+               u32 len = be32_to_cpu(fw_hdr->arr.len); \
+               bp->arr = kmalloc(len, GFP_KERNEL); \
                if (!bp->arr) { \
-                       printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \
+                       printk(KERN_ERR PFX "Failed to allocate %d bytes " \
+                                           "for "#arr"\n", len); \
                        goto lbl; \
                } \
-               func(bp->firmware->data + \
-                       be32_to_cpu(fw_hdr->arr.offset), \
-                       (u8*)bp->arr, len); \
+               func(bp->firmware->data + be32_to_cpu(fw_hdr->arr.offset), \
+                    (u8 *)bp->arr, len); \
        } while (0)
 
-
 static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
 {
        char fw_file_name[40] = {0};
-        int rc, offset;
        struct bnx2x_fw_file_hdr *fw_hdr;
+       int rc, offset;
 
        /* Create a FW file name */
        if (CHIP_IS_E1(bp))
-                offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
+               offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
        else
                offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
 
        sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw",
                BCM_5710_FW_MAJOR_VERSION,
-                BCM_5710_FW_MINOR_VERSION,
-                BCM_5710_FW_REVISION_VERSION,
-                BCM_5710_FW_ENGINEERING_VERSION);
+               BCM_5710_FW_MINOR_VERSION,
+               BCM_5710_FW_REVISION_VERSION,
+               BCM_5710_FW_ENGINEERING_VERSION);
 
        printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
 
        rc = request_firmware(&bp->firmware, fw_file_name, dev);
        if (rc) {
-               printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name);
+               printk(KERN_ERR PFX "Can't load firmware file %s\n",
+                      fw_file_name);
                goto request_firmware_exit;
        }
 
@@ -11831,27 +11871,29 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
        BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops);
 
        /* Offsets */
-       BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
+       BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err,
+                           be16_to_cpu_n);
 
        /* STORMs firmware */
-       bp->tsem_int_table_data = bp->firmware->data +
-               be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
-       bp->tsem_pram_data      = bp->firmware->data +
-               be32_to_cpu(fw_hdr->tsem_pram_data.offset);
-       bp->usem_int_table_data = bp->firmware->data +
-               be32_to_cpu(fw_hdr->usem_int_table_data.offset);
-       bp->usem_pram_data      = bp->firmware->data +
-               be32_to_cpu(fw_hdr->usem_pram_data.offset);
-       bp->xsem_int_table_data = bp->firmware->data +
-               be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
-       bp->xsem_pram_data      = bp->firmware->data +
-               be32_to_cpu(fw_hdr->xsem_pram_data.offset);
-       bp->csem_int_table_data = bp->firmware->data +
-               be32_to_cpu(fw_hdr->csem_int_table_data.offset);
-       bp->csem_pram_data      = bp->firmware->data +
-               be32_to_cpu(fw_hdr->csem_pram_data.offset);
+       INIT_TSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
+       INIT_TSEM_PRAM_DATA(bp)      = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->tsem_pram_data.offset);
+       INIT_USEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->usem_int_table_data.offset);
+       INIT_USEM_PRAM_DATA(bp)      = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->usem_pram_data.offset);
+       INIT_XSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
+       INIT_XSEM_PRAM_DATA(bp)      = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->xsem_pram_data.offset);
+       INIT_CSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->csem_int_table_data.offset);
+       INIT_CSEM_PRAM_DATA(bp)      = bp->firmware->data +
+                       be32_to_cpu(fw_hdr->csem_pram_data.offset);
 
        return 0;
+
 init_offsets_alloc_err:
        kfree(bp->init_ops);
 init_ops_alloc_err:
@@ -11863,18 +11905,14 @@ request_firmware_exit:
 }
 
 
-
 static int __devinit bnx2x_init_one(struct pci_dev *pdev,
                                    const struct pci_device_id *ent)
 {
-       static int version_printed;
        struct net_device *dev = NULL;
        struct bnx2x *bp;
+       int pcie_width, pcie_speed;
        int rc;
 
-       if (version_printed++ == 0)
-               printk(KERN_INFO "%s", version);
-
        /* dev zeroed in init_etherdev */
        dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT);
        if (!dev) {
@@ -11885,14 +11923,14 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
        bp = netdev_priv(dev);
        bp->msglevel = debug;
 
+       pci_set_drvdata(pdev, dev);
+
        rc = bnx2x_init_dev(pdev, dev);
        if (rc < 0) {
                free_netdev(dev);
                return rc;
        }
 
-       pci_set_drvdata(pdev, dev);
-
        rc = bnx2x_init_bp(bp);
        if (rc)
                goto init_one_exit;
@@ -11910,11 +11948,11 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
                goto init_one_exit;
        }
 
+       bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed);
        printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
               " IRQ %d, ", dev->name, board_info[ent->driver_data].name,
               (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
-              bnx2x_get_pcie_width(bp),
-              (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
+              pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz",
               dev->base_addr, bp->pdev->irq);
        printk(KERN_CONT "node addr %pM\n", dev->dev_addr);
 
@@ -12212,6 +12250,8 @@ static int __init bnx2x_init(void)
 {
        int ret;
 
+       printk(KERN_INFO "%s", version);
+
        bnx2x_wq = create_singlethread_workqueue("bnx2x");
        if (bnx2x_wq == NULL) {
                printk(KERN_ERR PFX "Cannot create workqueue\n");