aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlge
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qlge')
-rw-r--r--drivers/net/qlge/qlge.h1
-rw-r--r--drivers/net/qlge/qlge_main.c80
-rw-r--r--drivers/net/qlge/qlge_mpi.c25
3 files changed, 68 insertions, 38 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index e7285f01bd04..c2383adcd527 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -95,6 +95,7 @@ enum {
95 95
96 /* Misc. stuff */ 96 /* Misc. stuff */
97 MAILBOX_COUNT = 16, 97 MAILBOX_COUNT = 16,
98 MAILBOX_TIMEOUT = 5,
98 99
99 PROC_ADDR_RDY = (1 << 31), 100 PROC_ADDR_RDY = (1 << 31),
100 PROC_ADDR_R = (1 << 30), 101 PROC_ADDR_R = (1 << 30),
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 48b45df85ec9..a2fc70a0d0cc 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3916,6 +3916,9 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3916 goto err_out; 3916 goto err_out;
3917 } 3917 }
3918 3918
3919 /* Set PCIe reset type for EEH to fundamental. */
3920 pdev->needs_freset = 1;
3921 pci_save_state(pdev);
3919 qdev->reg_base = 3922 qdev->reg_base =
3920 ioremap_nocache(pci_resource_start(pdev, 1), 3923 ioremap_nocache(pci_resource_start(pdev, 1),
3921 pci_resource_len(pdev, 1)); 3924 pci_resource_len(pdev, 1));
@@ -4070,6 +4073,33 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
4070 free_netdev(ndev); 4073 free_netdev(ndev);
4071} 4074}
4072 4075
4076/* Clean up resources without touching hardware. */
4077static void ql_eeh_close(struct net_device *ndev)
4078{
4079 int i;
4080 struct ql_adapter *qdev = netdev_priv(ndev);
4081
4082 if (netif_carrier_ok(ndev)) {
4083 netif_carrier_off(ndev);
4084 netif_stop_queue(ndev);
4085 }
4086
4087 if (test_bit(QL_ADAPTER_UP, &qdev->flags))
4088 cancel_delayed_work_sync(&qdev->asic_reset_work);
4089 cancel_delayed_work_sync(&qdev->mpi_reset_work);
4090 cancel_delayed_work_sync(&qdev->mpi_work);
4091 cancel_delayed_work_sync(&qdev->mpi_idc_work);
4092 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
4093
4094 for (i = 0; i < qdev->rss_ring_count; i++)
4095 netif_napi_del(&qdev->rx_ring[i].napi);
4096
4097 clear_bit(QL_ADAPTER_UP, &qdev->flags);
4098 ql_tx_ring_clean(qdev);
4099 ql_free_rx_buffers(qdev);
4100 ql_release_adapter_resources(qdev);
4101}
4102
4073/* 4103/*
4074 * This callback is called by the PCI subsystem whenever 4104 * This callback is called by the PCI subsystem whenever
4075 * a PCI bus error is detected. 4105 * a PCI bus error is detected.
@@ -4078,17 +4108,21 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
4078 enum pci_channel_state state) 4108 enum pci_channel_state state)
4079{ 4109{
4080 struct net_device *ndev = pci_get_drvdata(pdev); 4110 struct net_device *ndev = pci_get_drvdata(pdev);
4081 struct ql_adapter *qdev = netdev_priv(ndev);
4082
4083 netif_device_detach(ndev);
4084 4111
4085 if (state == pci_channel_io_perm_failure) 4112 switch (state) {
4113 case pci_channel_io_normal:
4114 return PCI_ERS_RESULT_CAN_RECOVER;
4115 case pci_channel_io_frozen:
4116 netif_device_detach(ndev);
4117 if (netif_running(ndev))
4118 ql_eeh_close(ndev);
4119 pci_disable_device(pdev);
4120 return PCI_ERS_RESULT_NEED_RESET;
4121 case pci_channel_io_perm_failure:
4122 dev_err(&pdev->dev,
4123 "%s: pci_channel_io_perm_failure.\n", __func__);
4086 return PCI_ERS_RESULT_DISCONNECT; 4124 return PCI_ERS_RESULT_DISCONNECT;
4087 4125 }
4088 if (netif_running(ndev))
4089 ql_adapter_down(qdev);
4090
4091 pci_disable_device(pdev);
4092 4126
4093 /* Request a slot reset. */ 4127 /* Request a slot reset. */
4094 return PCI_ERS_RESULT_NEED_RESET; 4128 return PCI_ERS_RESULT_NEED_RESET;
@@ -4105,25 +4139,15 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
4105 struct net_device *ndev = pci_get_drvdata(pdev); 4139 struct net_device *ndev = pci_get_drvdata(pdev);
4106 struct ql_adapter *qdev = netdev_priv(ndev); 4140 struct ql_adapter *qdev = netdev_priv(ndev);
4107 4141
4142 pdev->error_state = pci_channel_io_normal;
4143
4144 pci_restore_state(pdev);
4108 if (pci_enable_device(pdev)) { 4145 if (pci_enable_device(pdev)) {
4109 QPRINTK(qdev, IFUP, ERR, 4146 QPRINTK(qdev, IFUP, ERR,
4110 "Cannot re-enable PCI device after reset.\n"); 4147 "Cannot re-enable PCI device after reset.\n");
4111 return PCI_ERS_RESULT_DISCONNECT; 4148 return PCI_ERS_RESULT_DISCONNECT;
4112 } 4149 }
4113
4114 pci_set_master(pdev); 4150 pci_set_master(pdev);
4115
4116 netif_carrier_off(ndev);
4117 ql_adapter_reset(qdev);
4118
4119 /* Make sure the EEPROM is good */
4120 memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
4121
4122 if (!is_valid_ether_addr(ndev->perm_addr)) {
4123 QPRINTK(qdev, IFUP, ERR, "After reset, invalid MAC address.\n");
4124 return PCI_ERS_RESULT_DISCONNECT;
4125 }
4126
4127 return PCI_ERS_RESULT_RECOVERED; 4151 return PCI_ERS_RESULT_RECOVERED;
4128} 4152}
4129 4153
@@ -4131,17 +4155,21 @@ static void qlge_io_resume(struct pci_dev *pdev)
4131{ 4155{
4132 struct net_device *ndev = pci_get_drvdata(pdev); 4156 struct net_device *ndev = pci_get_drvdata(pdev);
4133 struct ql_adapter *qdev = netdev_priv(ndev); 4157 struct ql_adapter *qdev = netdev_priv(ndev);
4158 int err = 0;
4134 4159
4135 pci_set_master(pdev); 4160 if (ql_adapter_reset(qdev))
4136 4161 QPRINTK(qdev, DRV, ERR, "reset FAILED!\n");
4137 if (netif_running(ndev)) { 4162 if (netif_running(ndev)) {
4138 if (ql_adapter_up(qdev)) { 4163 err = qlge_open(ndev);
4164 if (err) {
4139 QPRINTK(qdev, IFUP, ERR, 4165 QPRINTK(qdev, IFUP, ERR,
4140 "Device initialization failed after reset.\n"); 4166 "Device initialization failed after reset.\n");
4141 return; 4167 return;
4142 } 4168 }
4169 } else {
4170 QPRINTK(qdev, IFUP, ERR,
4171 "Device was not running prior to EEH.\n");
4143 } 4172 }
4144
4145 netif_device_attach(ndev); 4173 netif_device_attach(ndev);
4146} 4174}
4147 4175
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 99e58e3f8e22..aec05f266107 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -470,7 +470,8 @@ end:
470 */ 470 */
471static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) 471static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
472{ 472{
473 int status, count; 473 int status;
474 unsigned long count;
474 475
475 476
476 /* Begin polled mode for MPI */ 477 /* Begin polled mode for MPI */
@@ -491,14 +492,14 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
491 /* Wait for the command to complete. We loop 492 /* Wait for the command to complete. We loop
492 * here because some AEN might arrive while 493 * here because some AEN might arrive while
493 * we're waiting for the mailbox command to 494 * we're waiting for the mailbox command to
494 * complete. If more than 5 arrive then we can 495 * complete. If more than 5 seconds expire we can
495 * assume something is wrong. */ 496 * assume something is wrong. */
496 count = 5; 497 count = jiffies + HZ * MAILBOX_TIMEOUT;
497 do { 498 do {
498 /* Wait for the interrupt to come in. */ 499 /* Wait for the interrupt to come in. */
499 status = ql_wait_mbx_cmd_cmplt(qdev); 500 status = ql_wait_mbx_cmd_cmplt(qdev);
500 if (status) 501 if (status)
501 goto end; 502 continue;
502 503
503 /* Process the event. If it's an AEN, it 504 /* Process the event. If it's an AEN, it
504 * will be handled in-line or a worker 505 * will be handled in-line or a worker
@@ -517,15 +518,15 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
517 MB_CMD_STS_GOOD) || 518 MB_CMD_STS_GOOD) ||
518 ((mbcp->mbox_out[0] & 0x0000f000) == 519 ((mbcp->mbox_out[0] & 0x0000f000) ==
519 MB_CMD_STS_INTRMDT)) 520 MB_CMD_STS_INTRMDT))
520 break; 521 goto done;
521 } while (--count); 522 } while (time_before(jiffies, count));
522 523
523 if (!count) { 524 QPRINTK(qdev, DRV, ERR,
524 QPRINTK(qdev, DRV, ERR, 525 "Timed out waiting for mailbox complete.\n");
525 "Timed out waiting for mailbox complete.\n"); 526 status = -ETIMEDOUT;
526 status = -ETIMEDOUT; 527 goto end;
527 goto end; 528
528 } 529done:
529 530
530 /* Now we can clear the interrupt condition 531 /* Now we can clear the interrupt condition
531 * and look at our status. 532 * and look at our status.