diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 57d3293c65b..4b2b57018a0 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.1.6" -#define DRV_MODULE_RELDATE "Mar 7, 2011" +#define DRV_MODULE_VERSION "2.1.11" +#define DRV_MODULE_RELDATE "July 20, 2011" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1a.fw" @@ -385,6 +385,9 @@ static int bnx2_register_cnic(struct net_device *dev, struct cnic_ops *ops, if (cp->drv_state & CNIC_DRV_STATE_REGD) return -EBUSY; + if (!bnx2_reg_rd_ind(bp, BNX2_FW_MAX_ISCSI_CONN)) + return -ENODEV; + bp->cnic_data = data; rcu_assign_pointer(bp->cnic_ops, ops); @@ -416,6 +419,9 @@ struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + if (!cp->max_iscsi_conn) + return NULL; + cp->drv_owner = THIS_MODULE; cp->chip_id = bp->chip_id; cp->pdev = bp->pdev; @@ -2440,6 +2446,48 @@ bnx2_set_phy_loopback(struct bnx2 *bp) return 0; } +static void +bnx2_dump_mcp_state(struct bnx2 *bp) +{ + struct net_device *dev = bp->dev; + u32 mcp_p0, mcp_p1; + + netdev_err(dev, "<--- start MCP states dump --->\n"); + if (CHIP_NUM(bp) == CHIP_NUM_5709) { + mcp_p0 = BNX2_MCP_STATE_P0; + mcp_p1 = BNX2_MCP_STATE_P1; + } else { + mcp_p0 = BNX2_MCP_STATE_P0_5708; + mcp_p1 = BNX2_MCP_STATE_P1_5708; + } + netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n", + bnx2_reg_rd_ind(bp, mcp_p0), bnx2_reg_rd_ind(bp, mcp_p1)); + netdev_err(dev, "DEBUG: MCP mode[%08x] state[%08x] evt_mask[%08x]\n", + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_MODE), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_STATE), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_EVENT_MASK)); + netdev_err(dev, "DEBUG: pc[%08x] pc[%08x] instr[%08x]\n", + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_PROGRAM_COUNTER), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_PROGRAM_COUNTER), + bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_INSTRUCTION)); + netdev_err(dev, "DEBUG: shmem states:\n"); + netdev_err(dev, "DEBUG: drv_mb[%08x] fw_mb[%08x] link_status[%08x]", + bnx2_shmem_rd(bp, BNX2_DRV_MB), + bnx2_shmem_rd(bp, BNX2_FW_MB), + bnx2_shmem_rd(bp, BNX2_LINK_STATUS)); + pr_cont(" drv_pulse_mb[%08x]\n", bnx2_shmem_rd(bp, BNX2_DRV_PULSE_MB)); + netdev_err(dev, "DEBUG: dev_info_signature[%08x] reset_type[%08x]", + bnx2_shmem_rd(bp, BNX2_DEV_INFO_SIGNATURE), + bnx2_shmem_rd(bp, BNX2_BC_STATE_RESET_TYPE)); + pr_cont(" condition[%08x]\n", + bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION)); + DP_SHMEM_LINE(bp, 0x3cc); + DP_SHMEM_LINE(bp, 0x3dc); + DP_SHMEM_LINE(bp, 0x3ec); + netdev_err(dev, "DEBUG: 0x3fc[%08x]\n", bnx2_shmem_rd(bp, 0x3fc)); + netdev_err(dev, "<--- end MCP states dump --->\n"); +} + static int bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent) { @@ -2468,13 +2516,14 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent) /* If we timed out, inform the firmware that this is the case. */ if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) { - if (!silent) - pr_err("fw sync timeout, reset code = %x\n", msg_data); - msg_data &= ~BNX2_DRV_MSG_CODE; msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data); + if (!silent) { + pr_err("fw sync timeout, reset code = %x\n", msg_data); + bnx2_dump_mcp_state(bp); + } return -EBUSY; } @@ -6293,6 +6342,7 @@ static void bnx2_reset_task(struct work_struct *work) { struct bnx2 *bp = container_of(work, struct bnx2, reset_task); + int rc; rtnl_lock(); if (!netif_running(bp->dev)) { @@ -6302,7 +6352,14 @@ bnx2_reset_task(struct work_struct *work) bnx2_netif_stop(bp, true); - bnx2_init_nic(bp, 1); + rc = bnx2_init_nic(bp, 1); + if (rc) { + netdev_err(bp->dev, "failed to reset NIC, closing\n"); + bnx2_napi_enable(bp); + dev_close(bp->dev); + rtnl_unlock(); + return; + } atomic_set(&bp->intr_sem, 1); bnx2_netif_start(bp, true); @@ -6313,7 +6370,7 @@ static void bnx2_dump_state(struct bnx2 *bp) { struct net_device *dev = bp->dev; - u32 mcp_p0, mcp_p1, val1, val2; + u32 val1, val2; pci_read_config_dword(bp->pdev, PCI_COMMAND, &val1); netdev_err(dev, "DEBUG: intr_sem[%x] PCI_CMD[%08x]\n", @@ -6326,15 +6383,6 @@ bnx2_dump_state(struct bnx2 *bp) REG_RD(bp, BNX2_EMAC_RX_STATUS)); netdev_err(dev, "DEBUG: RPM_MGMT_PKT_CTRL[%08x]\n", REG_RD(bp, BNX2_RPM_MGMT_PKT_CTRL)); - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - mcp_p0 = BNX2_MCP_STATE_P0; - mcp_p1 = BNX2_MCP_STATE_P1; - } else { - mcp_p0 = BNX2_MCP_STATE_P0_5708; - mcp_p1 = BNX2_MCP_STATE_P1_5708; - } - netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n", - bnx2_reg_rd_ind(bp, mcp_p0), bnx2_reg_rd_ind(bp, mcp_p1)); netdev_err(dev, "DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n", REG_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS)); if (bp->flags & BNX2_FLAG_USING_MSIX) @@ -6348,6 +6396,7 @@ bnx2_tx_timeout(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); bnx2_dump_state(bp); + bnx2_dump_mcp_state(bp); /* This allows the netif to be shutdown gracefully before resetting */ schedule_work(&bp->reset_task); @@ -6532,8 +6581,6 @@ bnx2_close(struct net_device *dev) { struct bnx2 *bp = netdev_priv(dev); - cancel_work_sync(&bp->reset_task); - bnx2_disable_int_sync(bp); bnx2_napi_disable(bp); del_timer_sync(&bp->timer); @@ -7908,9 +7955,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->chip_id = REG_RD(bp, BNX2_MISC_ID); if (CHIP_NUM(bp) == CHIP_NUM_5709) { - if (pci_find_capability(pdev, PCI_CAP_ID_EXP) == 0) { - dev_err(&pdev->dev, - "Cannot find PCIE capability, aborting\n"); + if (!pci_is_pcie(pdev)) { + dev_err(&pdev->dev, "Not PCIE, aborting\n"); rc = -EIO; goto err_out_unmap; } @@ -8051,7 +8097,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->fw_version[j++] = ' '; for (i = 0; i < 3 && j < 28; i++) { reg = bnx2_reg_rd_ind(bp, addr + i * 4); - reg = swab32(reg); + reg = be32_to_cpu(reg); memcpy(&bp->fw_version[j], ®, 4); j += 4; } @@ -8177,6 +8223,12 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2_timer; +#ifdef BCM_CNIC + if (bnx2_shmem_rd(bp, BNX2_ISCSI_INITIATOR) & BNX2_ISCSI_INITIATOR_EN) + bp->cnic_eth_dev.max_iscsi_conn = + (bnx2_shmem_rd(bp, BNX2_ISCSI_MAX_CONN) & + BNX2_ISCSI_MAX_CONN_MASK) >> BNX2_ISCSI_MAX_CONN_SHIFT; +#endif pci_save_state(pdev); return 0; @@ -8358,6 +8410,7 @@ bnx2_remove_one(struct pci_dev *pdev) unregister_netdev(dev); del_timer_sync(&bp->timer); + cancel_work_sync(&bp->reset_task); if (bp->mips_firmware) release_firmware(bp->mips_firmware); |