diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-01-21 22:37:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-22 16:45:06 -0500 |
commit | 2dfe0e1fecb582b4aae7f2490904864c05472f3a (patch) | |
tree | 40a3f46b11961fb9294f3df0a8a251c2d585449c /drivers/net/bnx2x_main.c | |
parent | e94d8af3da79f4bfbd22819d28ecf0602456f06f (diff) |
bnx2x: Handling load failures
Failures on load were not handled correctly - separate the flow to handle
different failures
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 154 |
1 files changed, 88 insertions, 66 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 860b9f8ddd30..707c4bbe46a4 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -6328,7 +6328,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev); | |||
6328 | static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | 6328 | static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) |
6329 | { | 6329 | { |
6330 | u32 load_code; | 6330 | u32 load_code; |
6331 | int i, rc; | 6331 | int i, rc = 0; |
6332 | #ifdef BNX2X_STOP_ON_ERROR | 6332 | #ifdef BNX2X_STOP_ON_ERROR |
6333 | if (unlikely(bp->panic)) | 6333 | if (unlikely(bp->panic)) |
6334 | return -EPERM; | 6334 | return -EPERM; |
@@ -6336,48 +6336,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6336 | 6336 | ||
6337 | bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; | 6337 | bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; |
6338 | 6338 | ||
6339 | /* Send LOAD_REQUEST command to MCP | ||
6340 | Returns the type of LOAD command: | ||
6341 | if it is the first port to be initialized | ||
6342 | common blocks should be initialized, otherwise - not | ||
6343 | */ | ||
6344 | if (!BP_NOMCP(bp)) { | ||
6345 | load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); | ||
6346 | if (!load_code) { | ||
6347 | BNX2X_ERR("MCP response failure, aborting\n"); | ||
6348 | return -EBUSY; | ||
6349 | } | ||
6350 | if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) | ||
6351 | return -EBUSY; /* other port in diagnostic mode */ | ||
6352 | |||
6353 | } else { | ||
6354 | int port = BP_PORT(bp); | ||
6355 | |||
6356 | DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n", | ||
6357 | load_count[0], load_count[1], load_count[2]); | ||
6358 | load_count[0]++; | ||
6359 | load_count[1 + port]++; | ||
6360 | DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n", | ||
6361 | load_count[0], load_count[1], load_count[2]); | ||
6362 | if (load_count[0] == 1) | ||
6363 | load_code = FW_MSG_CODE_DRV_LOAD_COMMON; | ||
6364 | else if (load_count[1 + port] == 1) | ||
6365 | load_code = FW_MSG_CODE_DRV_LOAD_PORT; | ||
6366 | else | ||
6367 | load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; | ||
6368 | } | ||
6369 | |||
6370 | if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || | ||
6371 | (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) | ||
6372 | bp->port.pmf = 1; | ||
6373 | else | ||
6374 | bp->port.pmf = 0; | ||
6375 | DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); | ||
6376 | |||
6377 | /* if we can't use MSI-X we only need one fp, | ||
6378 | * so try to enable MSI-X with the requested number of fp's | ||
6379 | * and fallback to inta with one fp | ||
6380 | */ | ||
6381 | if (use_inta) { | 6339 | if (use_inta) { |
6382 | bp->num_queues = 1; | 6340 | bp->num_queues = 1; |
6383 | 6341 | ||
@@ -6392,7 +6350,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6392 | else | 6350 | else |
6393 | bp->num_queues = 1; | 6351 | bp->num_queues = 1; |
6394 | 6352 | ||
6395 | if (bnx2x_enable_msix(bp)) { | 6353 | DP(NETIF_MSG_IFUP, |
6354 | "set number of queues to %d\n", bp->num_queues); | ||
6355 | |||
6356 | /* if we can't use MSI-X we only need one fp, | ||
6357 | * so try to enable MSI-X with the requested number of fp's | ||
6358 | * and fallback to MSI or legacy INTx with one fp | ||
6359 | */ | ||
6360 | rc = bnx2x_enable_msix(bp); | ||
6361 | if (rc) { | ||
6396 | /* failed to enable MSI-X */ | 6362 | /* failed to enable MSI-X */ |
6397 | bp->num_queues = 1; | 6363 | bp->num_queues = 1; |
6398 | if (use_multi) | 6364 | if (use_multi) |
@@ -6400,8 +6366,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6400 | " to enable MSI-X\n"); | 6366 | " to enable MSI-X\n"); |
6401 | } | 6367 | } |
6402 | } | 6368 | } |
6403 | DP(NETIF_MSG_IFUP, | ||
6404 | "set number of queues to %d\n", bp->num_queues); | ||
6405 | 6369 | ||
6406 | if (bnx2x_alloc_mem(bp)) | 6370 | if (bnx2x_alloc_mem(bp)) |
6407 | return -ENOMEM; | 6371 | return -ENOMEM; |
@@ -6410,30 +6374,85 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6410 | bnx2x_fp(bp, i, disable_tpa) = | 6374 | bnx2x_fp(bp, i, disable_tpa) = |
6411 | ((bp->flags & TPA_ENABLE_FLAG) == 0); | 6375 | ((bp->flags & TPA_ENABLE_FLAG) == 0); |
6412 | 6376 | ||
6377 | for_each_queue(bp, i) | ||
6378 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), | ||
6379 | bnx2x_poll, 128); | ||
6380 | |||
6381 | #ifdef BNX2X_STOP_ON_ERROR | ||
6382 | for_each_queue(bp, i) { | ||
6383 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
6384 | |||
6385 | fp->poll_no_work = 0; | ||
6386 | fp->poll_calls = 0; | ||
6387 | fp->poll_max_calls = 0; | ||
6388 | fp->poll_complete = 0; | ||
6389 | fp->poll_exit = 0; | ||
6390 | } | ||
6391 | #endif | ||
6392 | bnx2x_napi_enable(bp); | ||
6393 | |||
6413 | if (bp->flags & USING_MSIX_FLAG) { | 6394 | if (bp->flags & USING_MSIX_FLAG) { |
6414 | rc = bnx2x_req_msix_irqs(bp); | 6395 | rc = bnx2x_req_msix_irqs(bp); |
6415 | if (rc) { | 6396 | if (rc) { |
6416 | pci_disable_msix(bp->pdev); | 6397 | pci_disable_msix(bp->pdev); |
6417 | goto load_error; | 6398 | goto load_error1; |
6418 | } | 6399 | } |
6400 | printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name); | ||
6419 | } else { | 6401 | } else { |
6420 | bnx2x_ack_int(bp); | 6402 | bnx2x_ack_int(bp); |
6421 | rc = bnx2x_req_irq(bp); | 6403 | rc = bnx2x_req_irq(bp); |
6422 | if (rc) { | 6404 | if (rc) { |
6423 | BNX2X_ERR("IRQ request failed, aborting\n"); | 6405 | BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); |
6424 | goto load_error; | 6406 | goto load_error1; |
6425 | } | 6407 | } |
6426 | } | 6408 | } |
6427 | 6409 | ||
6428 | for_each_queue(bp, i) | 6410 | /* Send LOAD_REQUEST command to MCP |
6429 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), | 6411 | Returns the type of LOAD command: |
6430 | bnx2x_poll, 128); | 6412 | if it is the first port to be initialized |
6413 | common blocks should be initialized, otherwise - not | ||
6414 | */ | ||
6415 | if (!BP_NOMCP(bp)) { | ||
6416 | load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); | ||
6417 | if (!load_code) { | ||
6418 | BNX2X_ERR("MCP response failure, aborting\n"); | ||
6419 | rc = -EBUSY; | ||
6420 | goto load_error2; | ||
6421 | } | ||
6422 | if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { | ||
6423 | rc = -EBUSY; /* other port in diagnostic mode */ | ||
6424 | goto load_error2; | ||
6425 | } | ||
6426 | |||
6427 | } else { | ||
6428 | int port = BP_PORT(bp); | ||
6429 | |||
6430 | DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n", | ||
6431 | load_count[0], load_count[1], load_count[2]); | ||
6432 | load_count[0]++; | ||
6433 | load_count[1 + port]++; | ||
6434 | DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n", | ||
6435 | load_count[0], load_count[1], load_count[2]); | ||
6436 | if (load_count[0] == 1) | ||
6437 | load_code = FW_MSG_CODE_DRV_LOAD_COMMON; | ||
6438 | else if (load_count[1 + port] == 1) | ||
6439 | load_code = FW_MSG_CODE_DRV_LOAD_PORT; | ||
6440 | else | ||
6441 | load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; | ||
6442 | } | ||
6443 | |||
6444 | if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || | ||
6445 | (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) | ||
6446 | bp->port.pmf = 1; | ||
6447 | else | ||
6448 | bp->port.pmf = 0; | ||
6449 | DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf); | ||
6431 | 6450 | ||
6432 | /* Initialize HW */ | 6451 | /* Initialize HW */ |
6433 | rc = bnx2x_init_hw(bp, load_code); | 6452 | rc = bnx2x_init_hw(bp, load_code); |
6434 | if (rc) { | 6453 | if (rc) { |
6435 | BNX2X_ERR("HW init failed, aborting\n"); | 6454 | BNX2X_ERR("HW init failed, aborting\n"); |
6436 | goto load_int_disable; | 6455 | goto load_error2; |
6437 | } | 6456 | } |
6438 | 6457 | ||
6439 | /* Setup NIC internals and enable interrupts */ | 6458 | /* Setup NIC internals and enable interrupts */ |
@@ -6445,7 +6464,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6445 | if (!load_code) { | 6464 | if (!load_code) { |
6446 | BNX2X_ERR("MCP response failure, aborting\n"); | 6465 | BNX2X_ERR("MCP response failure, aborting\n"); |
6447 | rc = -EBUSY; | 6466 | rc = -EBUSY; |
6448 | goto load_rings_free; | 6467 | goto load_error3; |
6449 | } | 6468 | } |
6450 | } | 6469 | } |
6451 | 6470 | ||
@@ -6454,7 +6473,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6454 | rc = bnx2x_setup_leading(bp); | 6473 | rc = bnx2x_setup_leading(bp); |
6455 | if (rc) { | 6474 | if (rc) { |
6456 | BNX2X_ERR("Setup leading failed!\n"); | 6475 | BNX2X_ERR("Setup leading failed!\n"); |
6457 | goto load_netif_stop; | 6476 | goto load_error3; |
6458 | } | 6477 | } |
6459 | 6478 | ||
6460 | if (CHIP_IS_E1H(bp)) | 6479 | if (CHIP_IS_E1H(bp)) |
@@ -6467,7 +6486,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6467 | for_each_nondefault_queue(bp, i) { | 6486 | for_each_nondefault_queue(bp, i) { |
6468 | rc = bnx2x_setup_multi(bp, i); | 6487 | rc = bnx2x_setup_multi(bp, i); |
6469 | if (rc) | 6488 | if (rc) |
6470 | goto load_netif_stop; | 6489 | goto load_error3; |
6471 | } | 6490 | } |
6472 | 6491 | ||
6473 | if (CHIP_IS_E1(bp)) | 6492 | if (CHIP_IS_E1(bp)) |
@@ -6483,18 +6502,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6483 | case LOAD_NORMAL: | 6502 | case LOAD_NORMAL: |
6484 | /* Tx queue should be only reenabled */ | 6503 | /* Tx queue should be only reenabled */ |
6485 | netif_wake_queue(bp->dev); | 6504 | netif_wake_queue(bp->dev); |
6505 | /* Initialize the receive filter. */ | ||
6486 | bnx2x_set_rx_mode(bp->dev); | 6506 | bnx2x_set_rx_mode(bp->dev); |
6487 | break; | 6507 | break; |
6488 | 6508 | ||
6489 | case LOAD_OPEN: | 6509 | case LOAD_OPEN: |
6490 | netif_start_queue(bp->dev); | 6510 | netif_start_queue(bp->dev); |
6511 | /* Initialize the receive filter. */ | ||
6491 | bnx2x_set_rx_mode(bp->dev); | 6512 | bnx2x_set_rx_mode(bp->dev); |
6492 | if (bp->flags & USING_MSIX_FLAG) | ||
6493 | printk(KERN_INFO PFX "%s: using MSI-X\n", | ||
6494 | bp->dev->name); | ||
6495 | break; | 6513 | break; |
6496 | 6514 | ||
6497 | case LOAD_DIAG: | 6515 | case LOAD_DIAG: |
6516 | /* Initialize the receive filter. */ | ||
6498 | bnx2x_set_rx_mode(bp->dev); | 6517 | bnx2x_set_rx_mode(bp->dev); |
6499 | bp->state = BNX2X_STATE_DIAG; | 6518 | bp->state = BNX2X_STATE_DIAG; |
6500 | break; | 6519 | break; |
@@ -6512,20 +6531,23 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6512 | 6531 | ||
6513 | return 0; | 6532 | return 0; |
6514 | 6533 | ||
6515 | load_netif_stop: | 6534 | load_error3: |
6516 | bnx2x_napi_disable(bp); | 6535 | bnx2x_int_disable_sync(bp, 1); |
6517 | load_rings_free: | 6536 | if (!BP_NOMCP(bp)) { |
6537 | bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); | ||
6538 | bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); | ||
6539 | } | ||
6540 | bp->port.pmf = 0; | ||
6518 | /* Free SKBs, SGEs, TPA pool and driver internals */ | 6541 | /* Free SKBs, SGEs, TPA pool and driver internals */ |
6519 | bnx2x_free_skbs(bp); | 6542 | bnx2x_free_skbs(bp); |
6520 | for_each_queue(bp, i) | 6543 | for_each_queue(bp, i) |
6521 | bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); | 6544 | bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); |
6522 | load_int_disable: | 6545 | load_error2: |
6523 | bnx2x_int_disable_sync(bp, 1); | ||
6524 | /* Release IRQs */ | 6546 | /* Release IRQs */ |
6525 | bnx2x_free_irq(bp); | 6547 | bnx2x_free_irq(bp); |
6526 | load_error: | 6548 | load_error1: |
6549 | bnx2x_napi_disable(bp); | ||
6527 | bnx2x_free_mem(bp); | 6550 | bnx2x_free_mem(bp); |
6528 | bp->port.pmf = 0; | ||
6529 | 6551 | ||
6530 | /* TBD we really need to reset the chip | 6552 | /* TBD we really need to reset the chip |
6531 | if we want to recover from this */ | 6553 | if we want to recover from this */ |