aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/s2io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r--drivers/net/s2io.c116
1 files changed, 110 insertions, 6 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 09078ff84cd2..2d826fff7e2e 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -469,11 +469,18 @@ static struct pci_device_id s2io_tbl[] __devinitdata = {
469 469
470MODULE_DEVICE_TABLE(pci, s2io_tbl); 470MODULE_DEVICE_TABLE(pci, s2io_tbl);
471 471
472static struct pci_error_handlers s2io_err_handler = {
473 .error_detected = s2io_io_error_detected,
474 .slot_reset = s2io_io_slot_reset,
475 .resume = s2io_io_resume,
476};
477
472static struct pci_driver s2io_driver = { 478static struct pci_driver s2io_driver = {
473 .name = "S2IO", 479 .name = "S2IO",
474 .id_table = s2io_tbl, 480 .id_table = s2io_tbl,
475 .probe = s2io_init_nic, 481 .probe = s2io_init_nic,
476 .remove = __devexit_p(s2io_rem_nic), 482 .remove = __devexit_p(s2io_rem_nic),
483 .err_handler = &s2io_err_handler,
477}; 484};
478 485
479/* A simplifier macro used both by init and free shared_mem Fns(). */ 486/* A simplifier macro used both by init and free shared_mem Fns(). */
@@ -2689,6 +2696,9 @@ static void s2io_netpoll(struct net_device *dev)
2689 u64 val64 = 0xFFFFFFFFFFFFFFFFULL; 2696 u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
2690 int i; 2697 int i;
2691 2698
2699 if (pci_channel_offline(nic->pdev))
2700 return;
2701
2692 disable_irq(dev->irq); 2702 disable_irq(dev->irq);
2693 2703
2694 atomic_inc(&nic->isr_cnt); 2704 atomic_inc(&nic->isr_cnt);
@@ -3215,6 +3225,8 @@ static void alarm_intr_handler(struct s2io_nic *nic)
3215 int i; 3225 int i;
3216 if (atomic_read(&nic->card_state) == CARD_DOWN) 3226 if (atomic_read(&nic->card_state) == CARD_DOWN)
3217 return; 3227 return;
3228 if (pci_channel_offline(nic->pdev))
3229 return;
3218 nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0; 3230 nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0;
3219 /* Handling the XPAK counters update */ 3231 /* Handling the XPAK counters update */
3220 if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) { 3232 if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) {
@@ -3958,7 +3970,6 @@ static int s2io_close(struct net_device *dev)
3958 /* Reset card, kill tasklet and free Tx and Rx buffers. */ 3970 /* Reset card, kill tasklet and free Tx and Rx buffers. */
3959 s2io_card_down(sp); 3971 s2io_card_down(sp);
3960 3972
3961 sp->device_close_flag = TRUE; /* Device is shut down. */
3962 return 0; 3973 return 0;
3963} 3974}
3964 3975
@@ -4314,6 +4325,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
4314 struct mac_info *mac_control; 4325 struct mac_info *mac_control;
4315 struct config_param *config; 4326 struct config_param *config;
4316 4327
4328 /* Pretend we handled any irq's from a disconnected card */
4329 if (pci_channel_offline(sp->pdev))
4330 return IRQ_NONE;
4331
4317 atomic_inc(&sp->isr_cnt); 4332 atomic_inc(&sp->isr_cnt);
4318 mac_control = &sp->mac_control; 4333 mac_control = &sp->mac_control;
4319 config = &sp->config; 4334 config = &sp->config;
@@ -6569,7 +6584,7 @@ static void s2io_rem_isr(struct s2io_nic * sp)
6569 } while(cnt < 5); 6584 } while(cnt < 5);
6570} 6585}
6571 6586
6572static void s2io_card_down(struct s2io_nic * sp) 6587static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
6573{ 6588{
6574 int cnt = 0; 6589 int cnt = 0;
6575 struct XENA_dev_config __iomem *bar0 = sp->bar0; 6590 struct XENA_dev_config __iomem *bar0 = sp->bar0;
@@ -6584,7 +6599,8 @@ static void s2io_card_down(struct s2io_nic * sp)
6584 atomic_set(&sp->card_state, CARD_DOWN); 6599 atomic_set(&sp->card_state, CARD_DOWN);
6585 6600
6586 /* disable Tx and Rx traffic on the NIC */ 6601 /* disable Tx and Rx traffic on the NIC */
6587 stop_nic(sp); 6602 if (do_io)
6603 stop_nic(sp);
6588 6604
6589 s2io_rem_isr(sp); 6605 s2io_rem_isr(sp);
6590 6606
@@ -6592,7 +6608,7 @@ static void s2io_card_down(struct s2io_nic * sp)
6592 tasklet_kill(&sp->task); 6608 tasklet_kill(&sp->task);
6593 6609
6594 /* Check if the device is Quiescent and then Reset the NIC */ 6610 /* Check if the device is Quiescent and then Reset the NIC */
6595 do { 6611 while(do_io) {
6596 /* As per the HW requirement we need to replenish the 6612 /* As per the HW requirement we need to replenish the
6597 * receive buffer to avoid the ring bump. Since there is 6613 * receive buffer to avoid the ring bump. Since there is
6598 * no intention of processing the Rx frame at this pointwe are 6614 * no intention of processing the Rx frame at this pointwe are
@@ -6617,8 +6633,9 @@ static void s2io_card_down(struct s2io_nic * sp)
6617 (unsigned long long) val64); 6633 (unsigned long long) val64);
6618 break; 6634 break;
6619 } 6635 }
6620 } while (1); 6636 }
6621 s2io_reset(sp); 6637 if (do_io)
6638 s2io_reset(sp);
6622 6639
6623 spin_lock_irqsave(&sp->tx_lock, flags); 6640 spin_lock_irqsave(&sp->tx_lock, flags);
6624 /* Free all Tx buffers */ 6641 /* Free all Tx buffers */
@@ -6633,6 +6650,11 @@ static void s2io_card_down(struct s2io_nic * sp)
6633 clear_bit(0, &(sp->link_state)); 6650 clear_bit(0, &(sp->link_state));
6634} 6651}
6635 6652
6653static void s2io_card_down(struct s2io_nic * sp)
6654{
6655 do_s2io_card_down(sp, 1);
6656}
6657
6636static int s2io_card_up(struct s2io_nic * sp) 6658static int s2io_card_up(struct s2io_nic * sp)
6637{ 6659{
6638 int i, ret = 0; 6660 int i, ret = 0;
@@ -8010,3 +8032,85 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
8010 sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; 8032 sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++;
8011 return; 8033 return;
8012} 8034}
8035
8036/**
8037 * s2io_io_error_detected - called when PCI error is detected
8038 * @pdev: Pointer to PCI device
8039 * @state: The current pci conneection state
8040 *
8041 * This function is called after a PCI bus error affecting
8042 * this device has been detected.
8043 */
8044static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
8045 pci_channel_state_t state)
8046{
8047 struct net_device *netdev = pci_get_drvdata(pdev);
8048 struct s2io_nic *sp = netdev->priv;
8049
8050 netif_device_detach(netdev);
8051
8052 if (netif_running(netdev)) {
8053 /* Bring down the card, while avoiding PCI I/O */
8054 do_s2io_card_down(sp, 0);
8055 }
8056 pci_disable_device(pdev);
8057
8058 return PCI_ERS_RESULT_NEED_RESET;
8059}
8060
8061/**
8062 * s2io_io_slot_reset - called after the pci bus has been reset.
8063 * @pdev: Pointer to PCI device
8064 *
8065 * Restart the card from scratch, as if from a cold-boot.
8066 * At this point, the card has exprienced a hard reset,
8067 * followed by fixups by BIOS, and has its config space
8068 * set up identically to what it was at cold boot.
8069 */
8070static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev)
8071{
8072 struct net_device *netdev = pci_get_drvdata(pdev);
8073 struct s2io_nic *sp = netdev->priv;
8074
8075 if (pci_enable_device(pdev)) {
8076 printk(KERN_ERR "s2io: "
8077 "Cannot re-enable PCI device after reset.\n");
8078 return PCI_ERS_RESULT_DISCONNECT;
8079 }
8080
8081 pci_set_master(pdev);
8082 s2io_reset(sp);
8083
8084 return PCI_ERS_RESULT_RECOVERED;
8085}
8086
8087/**
8088 * s2io_io_resume - called when traffic can start flowing again.
8089 * @pdev: Pointer to PCI device
8090 *
8091 * This callback is called when the error recovery driver tells
8092 * us that its OK to resume normal operation.
8093 */
8094static void s2io_io_resume(struct pci_dev *pdev)
8095{
8096 struct net_device *netdev = pci_get_drvdata(pdev);
8097 struct s2io_nic *sp = netdev->priv;
8098
8099 if (netif_running(netdev)) {
8100 if (s2io_card_up(sp)) {
8101 printk(KERN_ERR "s2io: "
8102 "Can't bring device back up after reset.\n");
8103 return;
8104 }
8105
8106 if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) {
8107 s2io_card_down(sp);
8108 printk(KERN_ERR "s2io: "
8109 "Can't resetore mac addr after reset.\n");
8110 return;
8111 }
8112 }
8113
8114 netif_device_attach(netdev);
8115 netif_wake_queue(netdev);
8116}