aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bnx2x_main.c154
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);
6328static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) 6328static 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
6515load_netif_stop: 6534load_error3:
6516 bnx2x_napi_disable(bp); 6535 bnx2x_int_disable_sync(bp, 1);
6517load_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);
6522load_int_disable: 6545load_error2:
6523 bnx2x_int_disable_sync(bp, 1);
6524 /* Release IRQs */ 6546 /* Release IRQs */
6525 bnx2x_free_irq(bp); 6547 bnx2x_free_irq(bp);
6526load_error: 6548load_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 */