diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 102 |
3 files changed, 75 insertions, 48 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 8c73d34b2ff1..06bbef742fa3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -1088,7 +1088,8 @@ enum bnx2x_recovery_state { | |||
1088 | BNX2X_RECOVERY_DONE, | 1088 | BNX2X_RECOVERY_DONE, |
1089 | BNX2X_RECOVERY_INIT, | 1089 | BNX2X_RECOVERY_INIT, |
1090 | BNX2X_RECOVERY_WAIT, | 1090 | BNX2X_RECOVERY_WAIT, |
1091 | BNX2X_RECOVERY_FAILED | 1091 | BNX2X_RECOVERY_FAILED, |
1092 | BNX2X_RECOVERY_NIC_LOADING | ||
1092 | }; | 1093 | }; |
1093 | 1094 | ||
1094 | /* | 1095 | /* |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 15db2d679a14..8fdd71b7bef0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -1776,6 +1776,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
1776 | * common blocks should be initialized, otherwise - not | 1776 | * common blocks should be initialized, otherwise - not |
1777 | */ | 1777 | */ |
1778 | if (!BP_NOMCP(bp)) { | 1778 | if (!BP_NOMCP(bp)) { |
1779 | /* init fw_seq */ | ||
1780 | bp->fw_seq = | ||
1781 | (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & | ||
1782 | DRV_MSG_SEQ_NUMBER_MASK); | ||
1783 | BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); | ||
1784 | |||
1785 | /* Get current FW pulse sequence */ | ||
1786 | bp->fw_drv_pulse_wr_seq = | ||
1787 | (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb) & | ||
1788 | DRV_PULSE_SEQ_MASK); | ||
1789 | BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); | ||
1790 | |||
1779 | load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); | 1791 | load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); |
1780 | if (!load_code) { | 1792 | if (!load_code) { |
1781 | BNX2X_ERR("MCP response failure, aborting\n"); | 1793 | BNX2X_ERR("MCP response failure, aborting\n"); |
@@ -3442,7 +3454,7 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) | |||
3442 | struct bnx2x *bp = netdev_priv(dev); | 3454 | struct bnx2x *bp = netdev_priv(dev); |
3443 | 3455 | ||
3444 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { | 3456 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { |
3445 | pr_err("Handling parity error recovery. Try again later\n"); | 3457 | netdev_err(dev, "Handling parity error recovery. Try again later\n"); |
3446 | return -EAGAIN; | 3458 | return -EAGAIN; |
3447 | } | 3459 | } |
3448 | 3460 | ||
@@ -3569,7 +3581,7 @@ int bnx2x_resume(struct pci_dev *pdev) | |||
3569 | bp = netdev_priv(dev); | 3581 | bp = netdev_priv(dev); |
3570 | 3582 | ||
3571 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { | 3583 | if (bp->recovery_state != BNX2X_RECOVERY_DONE) { |
3572 | pr_err("Handling parity error recovery. Try again later\n"); | 3584 | netdev_err(dev, "Handling parity error recovery. Try again later\n"); |
3573 | return -EAGAIN; | 3585 | return -EAGAIN; |
3574 | } | 3586 | } |
3575 | 3587 | ||
@@ -3585,8 +3597,6 @@ int bnx2x_resume(struct pci_dev *pdev) | |||
3585 | bnx2x_set_power_state(bp, PCI_D0); | 3597 | bnx2x_set_power_state(bp, PCI_D0); |
3586 | netif_device_attach(dev); | 3598 | netif_device_attach(dev); |
3587 | 3599 | ||
3588 | /* Since the chip was reset, clear the FW sequence number */ | ||
3589 | bp->fw_seq = 0; | ||
3590 | rc = bnx2x_nic_load(bp, LOAD_OPEN); | 3600 | rc = bnx2x_nic_load(bp, LOAD_OPEN); |
3591 | 3601 | ||
3592 | rtnl_unlock(); | 3602 | rtnl_unlock(); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f7f167a0f85a..c945df061618 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -468,7 +468,9 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, | |||
468 | while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) { | 468 | while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) { |
469 | DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); | 469 | DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); |
470 | 470 | ||
471 | if (!cnt) { | 471 | if (!cnt || |
472 | (bp->recovery_state != BNX2X_RECOVERY_DONE && | ||
473 | bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) { | ||
472 | BNX2X_ERR("DMAE timeout!\n"); | 474 | BNX2X_ERR("DMAE timeout!\n"); |
473 | rc = DMAE_TIMEOUT; | 475 | rc = DMAE_TIMEOUT; |
474 | goto unlock; | 476 | goto unlock; |
@@ -8477,13 +8479,38 @@ int bnx2x_leader_reset(struct bnx2x *bp) | |||
8477 | { | 8479 | { |
8478 | int rc = 0; | 8480 | int rc = 0; |
8479 | bool global = bnx2x_reset_is_global(bp); | 8481 | bool global = bnx2x_reset_is_global(bp); |
8482 | u32 load_code; | ||
8483 | |||
8484 | /* if not going to reset MCP - load "fake" driver to reset HW while | ||
8485 | * driver is owner of the HW | ||
8486 | */ | ||
8487 | if (!global && !BP_NOMCP(bp)) { | ||
8488 | load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); | ||
8489 | if (!load_code) { | ||
8490 | BNX2X_ERR("MCP response failure, aborting\n"); | ||
8491 | rc = -EAGAIN; | ||
8492 | goto exit_leader_reset; | ||
8493 | } | ||
8494 | if ((load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) && | ||
8495 | (load_code != FW_MSG_CODE_DRV_LOAD_COMMON)) { | ||
8496 | BNX2X_ERR("MCP unexpected resp, aborting\n"); | ||
8497 | rc = -EAGAIN; | ||
8498 | goto exit_leader_reset2; | ||
8499 | } | ||
8500 | load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); | ||
8501 | if (!load_code) { | ||
8502 | BNX2X_ERR("MCP response failure, aborting\n"); | ||
8503 | rc = -EAGAIN; | ||
8504 | goto exit_leader_reset2; | ||
8505 | } | ||
8506 | } | ||
8480 | 8507 | ||
8481 | /* Try to recover after the failure */ | 8508 | /* Try to recover after the failure */ |
8482 | if (bnx2x_process_kill(bp, global)) { | 8509 | if (bnx2x_process_kill(bp, global)) { |
8483 | netdev_err(bp->dev, "Something bad had happen on engine %d! " | 8510 | netdev_err(bp->dev, "Something bad had happen on engine %d! " |
8484 | "Aii!\n", BP_PATH(bp)); | 8511 | "Aii!\n", BP_PATH(bp)); |
8485 | rc = -EAGAIN; | 8512 | rc = -EAGAIN; |
8486 | goto exit_leader_reset; | 8513 | goto exit_leader_reset2; |
8487 | } | 8514 | } |
8488 | 8515 | ||
8489 | /* | 8516 | /* |
@@ -8494,6 +8521,12 @@ int bnx2x_leader_reset(struct bnx2x *bp) | |||
8494 | if (global) | 8521 | if (global) |
8495 | bnx2x_clear_reset_global(bp); | 8522 | bnx2x_clear_reset_global(bp); |
8496 | 8523 | ||
8524 | exit_leader_reset2: | ||
8525 | /* unload "fake driver" if it was loaded */ | ||
8526 | if (!global && !BP_NOMCP(bp)) { | ||
8527 | bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); | ||
8528 | bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); | ||
8529 | } | ||
8497 | exit_leader_reset: | 8530 | exit_leader_reset: |
8498 | bp->is_leader = 0; | 8531 | bp->is_leader = 0; |
8499 | bnx2x_release_leader_lock(bp); | 8532 | bnx2x_release_leader_lock(bp); |
@@ -8530,13 +8563,15 @@ static inline void bnx2x_recovery_failed(struct bnx2x *bp) | |||
8530 | static void bnx2x_parity_recover(struct bnx2x *bp) | 8563 | static void bnx2x_parity_recover(struct bnx2x *bp) |
8531 | { | 8564 | { |
8532 | bool global = false; | 8565 | bool global = false; |
8566 | bool is_parity; | ||
8533 | 8567 | ||
8534 | DP(NETIF_MSG_HW, "Handling parity\n"); | 8568 | DP(NETIF_MSG_HW, "Handling parity\n"); |
8535 | while (1) { | 8569 | while (1) { |
8536 | switch (bp->recovery_state) { | 8570 | switch (bp->recovery_state) { |
8537 | case BNX2X_RECOVERY_INIT: | 8571 | case BNX2X_RECOVERY_INIT: |
8538 | DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n"); | 8572 | DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n"); |
8539 | bnx2x_chk_parity_attn(bp, &global, false); | 8573 | is_parity = bnx2x_chk_parity_attn(bp, &global, false); |
8574 | WARN_ON(!is_parity); | ||
8540 | 8575 | ||
8541 | /* Try to get a LEADER_LOCK HW lock */ | 8576 | /* Try to get a LEADER_LOCK HW lock */ |
8542 | if (bnx2x_trylock_leader_lock(bp)) { | 8577 | if (bnx2x_trylock_leader_lock(bp)) { |
@@ -8560,15 +8595,6 @@ static void bnx2x_parity_recover(struct bnx2x *bp) | |||
8560 | 8595 | ||
8561 | bp->recovery_state = BNX2X_RECOVERY_WAIT; | 8596 | bp->recovery_state = BNX2X_RECOVERY_WAIT; |
8562 | 8597 | ||
8563 | /* | ||
8564 | * Reset MCP command sequence number and MCP mail box | ||
8565 | * sequence as we are going to reset the MCP. | ||
8566 | */ | ||
8567 | if (global) { | ||
8568 | bp->fw_seq = 0; | ||
8569 | bp->fw_drv_pulse_wr_seq = 0; | ||
8570 | } | ||
8571 | |||
8572 | /* Ensure "is_leader", MCP command sequence and | 8598 | /* Ensure "is_leader", MCP command sequence and |
8573 | * "recovery_state" update values are seen on other | 8599 | * "recovery_state" update values are seen on other |
8574 | * CPUs. | 8600 | * CPUs. |
@@ -8652,9 +8678,20 @@ static void bnx2x_parity_recover(struct bnx2x *bp) | |||
8652 | return; | 8678 | return; |
8653 | } | 8679 | } |
8654 | 8680 | ||
8655 | if (bnx2x_nic_load(bp, LOAD_NORMAL)) | 8681 | bp->recovery_state = |
8656 | bnx2x_recovery_failed(bp); | 8682 | BNX2X_RECOVERY_NIC_LOADING; |
8657 | else { | 8683 | if (bnx2x_nic_load(bp, LOAD_NORMAL)) { |
8684 | netdev_err(bp->dev, | ||
8685 | "Recovery failed. " | ||
8686 | "Power cycle " | ||
8687 | "needed\n"); | ||
8688 | /* Disconnect this device */ | ||
8689 | netif_device_detach(bp->dev); | ||
8690 | /* Shut down the power */ | ||
8691 | bnx2x_set_power_state( | ||
8692 | bp, PCI_D3hot); | ||
8693 | smp_mb(); | ||
8694 | } else { | ||
8658 | bp->recovery_state = | 8695 | bp->recovery_state = |
8659 | BNX2X_RECOVERY_DONE; | 8696 | BNX2X_RECOVERY_DONE; |
8660 | smp_mb(); | 8697 | smp_mb(); |
@@ -8908,9 +8945,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) | |||
8908 | 8945 | ||
8909 | /* restore our func and fw_seq */ | 8946 | /* restore our func and fw_seq */ |
8910 | bp->pf_num = orig_pf_num; | 8947 | bp->pf_num = orig_pf_num; |
8911 | bp->fw_seq = | ||
8912 | (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & | ||
8913 | DRV_MSG_SEQ_NUMBER_MASK); | ||
8914 | } | 8948 | } |
8915 | } | 8949 | } |
8916 | 8950 | ||
@@ -9936,16 +9970,6 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) | |||
9936 | 9970 | ||
9937 | bnx2x_get_cnic_info(bp); | 9971 | bnx2x_get_cnic_info(bp); |
9938 | 9972 | ||
9939 | /* Get current FW pulse sequence */ | ||
9940 | if (!BP_NOMCP(bp)) { | ||
9941 | int mb_idx = BP_FW_MB_IDX(bp); | ||
9942 | |||
9943 | bp->fw_drv_pulse_wr_seq = | ||
9944 | (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & | ||
9945 | DRV_PULSE_SEQ_MASK); | ||
9946 | BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); | ||
9947 | } | ||
9948 | |||
9949 | return rc; | 9973 | return rc; |
9950 | } | 9974 | } |
9951 | 9975 | ||
@@ -10115,14 +10139,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) | |||
10115 | if (!BP_NOMCP(bp)) | 10139 | if (!BP_NOMCP(bp)) |
10116 | bnx2x_undi_unload(bp); | 10140 | bnx2x_undi_unload(bp); |
10117 | 10141 | ||
10118 | /* init fw_seq after undi_unload! */ | ||
10119 | if (!BP_NOMCP(bp)) { | ||
10120 | bp->fw_seq = | ||
10121 | (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & | ||
10122 | DRV_MSG_SEQ_NUMBER_MASK); | ||
10123 | BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); | ||
10124 | } | ||
10125 | |||
10126 | if (CHIP_REV_IS_FPGA(bp)) | 10142 | if (CHIP_REV_IS_FPGA(bp)) |
10127 | dev_err(&bp->pdev->dev, "FPGA detected\n"); | 10143 | dev_err(&bp->pdev->dev, "FPGA detected\n"); |
10128 | 10144 | ||
@@ -11331,13 +11347,6 @@ static void bnx2x_eeh_recover(struct bnx2x *bp) | |||
11331 | if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) | 11347 | if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) |
11332 | != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) | 11348 | != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) |
11333 | BNX2X_ERR("BAD MCP validity signature\n"); | 11349 | BNX2X_ERR("BAD MCP validity signature\n"); |
11334 | |||
11335 | if (!BP_NOMCP(bp)) { | ||
11336 | bp->fw_seq = | ||
11337 | (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & | ||
11338 | DRV_MSG_SEQ_NUMBER_MASK); | ||
11339 | BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); | ||
11340 | } | ||
11341 | } | 11350 | } |
11342 | 11351 | ||
11343 | /** | 11352 | /** |
@@ -11593,6 +11602,13 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev, | |||
11593 | return -EIO; | 11602 | return -EIO; |
11594 | #endif | 11603 | #endif |
11595 | 11604 | ||
11605 | if ((bp->recovery_state != BNX2X_RECOVERY_DONE) && | ||
11606 | (bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) { | ||
11607 | netdev_err(dev, "Handling parity error recovery. Try again " | ||
11608 | "later\n"); | ||
11609 | return -EAGAIN; | ||
11610 | } | ||
11611 | |||
11596 | spin_lock_bh(&bp->spq_lock); | 11612 | spin_lock_bh(&bp->spq_lock); |
11597 | 11613 | ||
11598 | for (i = 0; i < count; i++) { | 11614 | for (i = 0; i < count; i++) { |