aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlge
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-10-30 00:28:59 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-30 00:28:59 -0400
commit0519d83d83ed485b5a1f9222ff69d7d6c9bb8a01 (patch)
tree2e336be8a4bd2e59bcd4b69b00feb77c6672a9cb /drivers/net/qlge
parent38bfd8f5bec496e8e0db8849e01c99a33479418a (diff)
parentb5dd884e682cae6b8c037f9d11f3b623b4cf2011 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'drivers/net/qlge')
-rw-r--r--drivers/net/qlge/qlge.h1
-rw-r--r--drivers/net/qlge/qlge_main.c78
-rw-r--r--drivers/net/qlge/qlge_mpi.c23
3 files changed, 65 insertions, 37 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 4b954e13c007..73c7fd2badcd 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -97,6 +97,7 @@ enum {
97 97
98 /* Misc. stuff */ 98 /* Misc. stuff */
99 MAILBOX_COUNT = 16, 99 MAILBOX_COUNT = 16,
100 MAILBOX_TIMEOUT = 5,
100 101
101 PROC_ADDR_RDY = (1 << 31), 102 PROC_ADDR_RDY = (1 << 31),
102 PROC_ADDR_R = (1 << 30), 103 PROC_ADDR_R = (1 << 30),
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index dd0ea0277550..42ad811ec313 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -4101,6 +4101,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
4101 goto err_out; 4101 goto err_out;
4102 } 4102 }
4103 4103
4104 pci_save_state(pdev);
4104 qdev->reg_base = 4105 qdev->reg_base =
4105 ioremap_nocache(pci_resource_start(pdev, 1), 4106 ioremap_nocache(pci_resource_start(pdev, 1),
4106 pci_resource_len(pdev, 1)); 4107 pci_resource_len(pdev, 1));
@@ -4255,6 +4256,33 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
4255 free_netdev(ndev); 4256 free_netdev(ndev);
4256} 4257}
4257 4258
4259/* Clean up resources without touching hardware. */
4260static void ql_eeh_close(struct net_device *ndev)
4261{
4262 int i;
4263 struct ql_adapter *qdev = netdev_priv(ndev);
4264
4265 if (netif_carrier_ok(ndev)) {
4266 netif_carrier_off(ndev);
4267 netif_stop_queue(ndev);
4268 }
4269
4270 if (test_bit(QL_ADAPTER_UP, &qdev->flags))
4271 cancel_delayed_work_sync(&qdev->asic_reset_work);
4272 cancel_delayed_work_sync(&qdev->mpi_reset_work);
4273 cancel_delayed_work_sync(&qdev->mpi_work);
4274 cancel_delayed_work_sync(&qdev->mpi_idc_work);
4275 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
4276
4277 for (i = 0; i < qdev->rss_ring_count; i++)
4278 netif_napi_del(&qdev->rx_ring[i].napi);
4279
4280 clear_bit(QL_ADAPTER_UP, &qdev->flags);
4281 ql_tx_ring_clean(qdev);
4282 ql_free_rx_buffers(qdev);
4283 ql_release_adapter_resources(qdev);
4284}
4285
4258/* 4286/*
4259 * This callback is called by the PCI subsystem whenever 4287 * This callback is called by the PCI subsystem whenever
4260 * a PCI bus error is detected. 4288 * a PCI bus error is detected.
@@ -4263,17 +4291,21 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
4263 enum pci_channel_state state) 4291 enum pci_channel_state state)
4264{ 4292{
4265 struct net_device *ndev = pci_get_drvdata(pdev); 4293 struct net_device *ndev = pci_get_drvdata(pdev);
4266 struct ql_adapter *qdev = netdev_priv(ndev);
4267
4268 netif_device_detach(ndev);
4269 4294
4270 if (state == pci_channel_io_perm_failure) 4295 switch (state) {
4296 case pci_channel_io_normal:
4297 return PCI_ERS_RESULT_CAN_RECOVER;
4298 case pci_channel_io_frozen:
4299 netif_device_detach(ndev);
4300 if (netif_running(ndev))
4301 ql_eeh_close(ndev);
4302 pci_disable_device(pdev);
4303 return PCI_ERS_RESULT_NEED_RESET;
4304 case pci_channel_io_perm_failure:
4305 dev_err(&pdev->dev,
4306 "%s: pci_channel_io_perm_failure.\n", __func__);
4271 return PCI_ERS_RESULT_DISCONNECT; 4307 return PCI_ERS_RESULT_DISCONNECT;
4272 4308 }
4273 if (netif_running(ndev))
4274 ql_adapter_down(qdev);
4275
4276 pci_disable_device(pdev);
4277 4309
4278 /* Request a slot reset. */ 4310 /* Request a slot reset. */
4279 return PCI_ERS_RESULT_NEED_RESET; 4311 return PCI_ERS_RESULT_NEED_RESET;
@@ -4290,25 +4322,15 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
4290 struct net_device *ndev = pci_get_drvdata(pdev); 4322 struct net_device *ndev = pci_get_drvdata(pdev);
4291 struct ql_adapter *qdev = netdev_priv(ndev); 4323 struct ql_adapter *qdev = netdev_priv(ndev);
4292 4324
4325 pdev->error_state = pci_channel_io_normal;
4326
4327 pci_restore_state(pdev);
4293 if (pci_enable_device(pdev)) { 4328 if (pci_enable_device(pdev)) {
4294 QPRINTK(qdev, IFUP, ERR, 4329 QPRINTK(qdev, IFUP, ERR,
4295 "Cannot re-enable PCI device after reset.\n"); 4330 "Cannot re-enable PCI device after reset.\n");
4296 return PCI_ERS_RESULT_DISCONNECT; 4331 return PCI_ERS_RESULT_DISCONNECT;
4297 } 4332 }
4298
4299 pci_set_master(pdev); 4333 pci_set_master(pdev);
4300
4301 netif_carrier_off(ndev);
4302 ql_adapter_reset(qdev);
4303
4304 /* Make sure the EEPROM is good */
4305 memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
4306
4307 if (!is_valid_ether_addr(ndev->perm_addr)) {
4308 QPRINTK(qdev, IFUP, ERR, "After reset, invalid MAC address.\n");
4309 return PCI_ERS_RESULT_DISCONNECT;
4310 }
4311
4312 return PCI_ERS_RESULT_RECOVERED; 4334 return PCI_ERS_RESULT_RECOVERED;
4313} 4335}
4314 4336
@@ -4316,17 +4338,21 @@ static void qlge_io_resume(struct pci_dev *pdev)
4316{ 4338{
4317 struct net_device *ndev = pci_get_drvdata(pdev); 4339 struct net_device *ndev = pci_get_drvdata(pdev);
4318 struct ql_adapter *qdev = netdev_priv(ndev); 4340 struct ql_adapter *qdev = netdev_priv(ndev);
4341 int err = 0;
4319 4342
4320 pci_set_master(pdev); 4343 if (ql_adapter_reset(qdev))
4321 4344 QPRINTK(qdev, DRV, ERR, "reset FAILED!\n");
4322 if (netif_running(ndev)) { 4345 if (netif_running(ndev)) {
4323 if (ql_adapter_up(qdev)) { 4346 err = qlge_open(ndev);
4347 if (err) {
4324 QPRINTK(qdev, IFUP, ERR, 4348 QPRINTK(qdev, IFUP, ERR,
4325 "Device initialization failed after reset.\n"); 4349 "Device initialization failed after reset.\n");
4326 return; 4350 return;
4327 } 4351 }
4352 } else {
4353 QPRINTK(qdev, IFUP, ERR,
4354 "Device was not running prior to EEH.\n");
4328 } 4355 }
4329
4330 netif_device_attach(ndev); 4356 netif_device_attach(ndev);
4331} 4357}
4332 4358
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 80b68539c5aa..bac7b86f2129 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -454,7 +454,8 @@ end:
454 */ 454 */
455static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) 455static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
456{ 456{
457 int status, count; 457 int status;
458 unsigned long count;
458 459
459 460
460 /* Begin polled mode for MPI */ 461 /* Begin polled mode for MPI */
@@ -475,9 +476,9 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
475 /* Wait for the command to complete. We loop 476 /* Wait for the command to complete. We loop
476 * here because some AEN might arrive while 477 * here because some AEN might arrive while
477 * we're waiting for the mailbox command to 478 * we're waiting for the mailbox command to
478 * complete. If more than 5 arrive then we can 479 * complete. If more than 5 seconds expire we can
479 * assume something is wrong. */ 480 * assume something is wrong. */
480 count = 5; 481 count = jiffies + HZ * MAILBOX_TIMEOUT;
481 do { 482 do {
482 /* Wait for the interrupt to come in. */ 483 /* Wait for the interrupt to come in. */
483 status = ql_wait_mbx_cmd_cmplt(qdev); 484 status = ql_wait_mbx_cmd_cmplt(qdev);
@@ -501,15 +502,15 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
501 MB_CMD_STS_GOOD) || 502 MB_CMD_STS_GOOD) ||
502 ((mbcp->mbox_out[0] & 0x0000f000) == 503 ((mbcp->mbox_out[0] & 0x0000f000) ==
503 MB_CMD_STS_INTRMDT)) 504 MB_CMD_STS_INTRMDT))
504 break; 505 goto done;
505 } while (--count); 506 } while (time_before(jiffies, count));
506 507
507 if (!count) { 508 QPRINTK(qdev, DRV, ERR,
508 QPRINTK(qdev, DRV, ERR, 509 "Timed out waiting for mailbox complete.\n");
509 "Timed out waiting for mailbox complete.\n"); 510 status = -ETIMEDOUT;
510 status = -ETIMEDOUT; 511 goto end;
511 goto end; 512
512 } 513done:
513 514
514 /* Now we can clear the interrupt condition 515 /* Now we can clear the interrupt condition
515 * and look at our status. 516 * and look at our status.