aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_main.c
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2011-07-18 21:42:04 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-19 12:57:48 -0400
commit6debea870a66be4aac2e28be0e3952dad6c7fcdb (patch)
tree60bf7bed2d6350ada4f0802f6d59d73c2ca6b372 /drivers/net/bnx2x/bnx2x_main.c
parentf13ac41f5165c0ac0441f9d42f7d6f6f9ee7c075 (diff)
bnx2x: DCB rework
create DCB related states in function state-machine allow handling of DCB errors from FW allow disablement of DCB in FW, when peer disappears or error clean up unused functions/variables as pointed by David Binderman <dcb314@hotmail.com> Reported-by: David Binderman <dcb314@hotmail.com> Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c98
1 files changed, 91 insertions, 7 deletions
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 8a374a77cdc9..a86517cffd4a 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -4403,11 +4403,17 @@ static void bnx2x_eq_int(struct bnx2x *bp)
4403 4403
4404 case EVENT_RING_OPCODE_STOP_TRAFFIC: 4404 case EVENT_RING_OPCODE_STOP_TRAFFIC:
4405 DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n"); 4405 DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n");
4406 if (f_obj->complete_cmd(bp, f_obj,
4407 BNX2X_F_CMD_TX_STOP))
4408 break;
4406 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); 4409 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED);
4407 goto next_spqe; 4410 goto next_spqe;
4408 4411
4409 case EVENT_RING_OPCODE_START_TRAFFIC: 4412 case EVENT_RING_OPCODE_START_TRAFFIC:
4410 DP(NETIF_MSG_IFUP, "got START TRAFFIC\n"); 4413 DP(NETIF_MSG_IFUP, "got START TRAFFIC\n");
4414 if (f_obj->complete_cmd(bp, f_obj,
4415 BNX2X_F_CMD_TX_START))
4416 break;
4411 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); 4417 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED);
4412 goto next_spqe; 4418 goto next_spqe;
4413 case EVENT_RING_OPCODE_FUNCTION_START: 4419 case EVENT_RING_OPCODE_FUNCTION_START:
@@ -7536,6 +7542,71 @@ void bnx2x_send_unload_done(struct bnx2x *bp)
7536 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); 7542 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
7537} 7543}
7538 7544
7545static inline int bnx2x_func_wait_started(struct bnx2x *bp)
7546{
7547 int tout = 50;
7548 int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
7549
7550 if (!bp->port.pmf)
7551 return 0;
7552
7553 /*
7554 * (assumption: No Attention from MCP at this stage)
7555 * PMF probably in the middle of TXdisable/enable transaction
7556 * 1. Sync IRS for default SB
7557 * 2. Sync SP queue - this guarantes us that attention handling started
7558 * 3. Wait, that TXdisable/enable transaction completes
7559 *
7560 * 1+2 guranty that if DCBx attention was scheduled it already changed
7561 * pending bit of transaction from STARTED-->TX_STOPPED, if we alredy
7562 * received complettion for the transaction the state is TX_STOPPED.
7563 * State will return to STARTED after completion of TX_STOPPED-->STARTED
7564 * transaction.
7565 */
7566
7567 /* make sure default SB ISR is done */
7568 if (msix)
7569 synchronize_irq(bp->msix_table[0].vector);
7570 else
7571 synchronize_irq(bp->pdev->irq);
7572
7573 flush_workqueue(bnx2x_wq);
7574
7575 while (bnx2x_func_get_state(bp, &bp->func_obj) !=
7576 BNX2X_F_STATE_STARTED && tout--)
7577 msleep(20);
7578
7579 if (bnx2x_func_get_state(bp, &bp->func_obj) !=
7580 BNX2X_F_STATE_STARTED) {
7581#ifdef BNX2X_STOP_ON_ERROR
7582 return -EBUSY;
7583#else
7584 /*
7585 * Failed to complete the transaction in a "good way"
7586 * Force both transactions with CLR bit
7587 */
7588 struct bnx2x_func_state_params func_params = {0};
7589
7590 DP(BNX2X_MSG_SP, "Hmmm... unexpected function state! "
7591 "Forcing STARTED-->TX_ST0PPED-->STARTED\n");
7592
7593 func_params.f_obj = &bp->func_obj;
7594 __set_bit(RAMROD_DRV_CLR_ONLY,
7595 &func_params.ramrod_flags);
7596
7597 /* STARTED-->TX_ST0PPED */
7598 func_params.cmd = BNX2X_F_CMD_TX_STOP;
7599 bnx2x_func_state_change(bp, &func_params);
7600
7601 /* TX_ST0PPED-->STARTED */
7602 func_params.cmd = BNX2X_F_CMD_TX_START;
7603 return bnx2x_func_state_change(bp, &func_params);
7604#endif
7605 }
7606
7607 return 0;
7608}
7609
7539void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) 7610void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
7540{ 7611{
7541 int port = BP_PORT(bp); 7612 int port = BP_PORT(bp);
@@ -7595,6 +7666,26 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
7595 netif_addr_unlock_bh(bp->dev); 7666 netif_addr_unlock_bh(bp->dev);
7596 7667
7597 7668
7669
7670 /*
7671 * Send the UNLOAD_REQUEST to the MCP. This will return if
7672 * this function should perform FUNC, PORT or COMMON HW
7673 * reset.
7674 */
7675 reset_code = bnx2x_send_unload_req(bp, unload_mode);
7676
7677 /*
7678 * (assumption: No Attention from MCP at this stage)
7679 * PMF probably in the middle of TXdisable/enable transaction
7680 */
7681 rc = bnx2x_func_wait_started(bp);
7682 if (rc) {
7683 BNX2X_ERR("bnx2x_func_wait_started failed\n");
7684#ifdef BNX2X_STOP_ON_ERROR
7685 return;
7686#endif
7687 }
7688
7598 /* Close multi and leading connections 7689 /* Close multi and leading connections
7599 * Completions for ramrods are collected in a synchronous way 7690 * Completions for ramrods are collected in a synchronous way
7600 */ 7691 */
@@ -7622,13 +7713,6 @@ unload_error:
7622#endif 7713#endif
7623 } 7714 }
7624 7715
7625 /*
7626 * Send the UNLOAD_REQUEST to the MCP. This will return if
7627 * this function should perform FUNC, PORT or COMMON HW
7628 * reset.
7629 */
7630 reset_code = bnx2x_send_unload_req(bp, unload_mode);
7631
7632 /* Disable HW interrupts, NAPI */ 7716 /* Disable HW interrupts, NAPI */
7633 bnx2x_netif_stop(bp, 1); 7717 bnx2x_netif_stop(bp, 1);
7634 7718