aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPratik Pujar <pratik.pujar@qlogic.com>2013-08-30 13:51:20 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-31 22:34:44 -0400
commit4460f2e83c61e21c2e78a28a327b716252b13069 (patch)
tree1e60eaf7d75572d9bca6a43155f3ae5abb66365d
parent890b6e023bd7ff9b5fc89750d9ab2cd414fa302e (diff)
qlcnic: Add AER callback handlers.
o Generic AER callback handlers will make use of qlcnic_hardware_ops structure to call adapter specific handlers. Signed-off-by: Pratik Pujar <pratik.pujar@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h8
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c71
2 files changed, 55 insertions, 24 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index f9cd2744b2a0..318663f91b5e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1479,6 +1479,10 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter);
1479int qlcnic_dump_fw(struct qlcnic_adapter *); 1479int qlcnic_dump_fw(struct qlcnic_adapter *);
1480int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *); 1480int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *);
1481bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *); 1481bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *);
1482pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *,
1483 pci_channel_state_t);
1484pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *);
1485void qlcnic_82xx_io_resume(struct pci_dev *);
1482 1486
1483/* Functions from qlcnic_init.c */ 1487/* Functions from qlcnic_init.c */
1484void qlcnic_schedule_work(struct qlcnic_adapter *, work_func_t, int); 1488void qlcnic_schedule_work(struct qlcnic_adapter *, work_func_t, int);
@@ -1724,6 +1728,10 @@ struct qlcnic_hardware_ops {
1724 void (*set_mac_filter_count) (struct qlcnic_adapter *); 1728 void (*set_mac_filter_count) (struct qlcnic_adapter *);
1725 void (*free_mac_list) (struct qlcnic_adapter *); 1729 void (*free_mac_list) (struct qlcnic_adapter *);
1726 int (*read_phys_port_id) (struct qlcnic_adapter *); 1730 int (*read_phys_port_id) (struct qlcnic_adapter *);
1731 pci_ers_result_t (*io_error_detected) (struct pci_dev *,
1732 pci_channel_state_t);
1733 pci_ers_result_t (*io_slot_reset) (struct pci_dev *);
1734 void (*io_resume) (struct pci_dev *);
1727}; 1735};
1728 1736
1729extern struct qlcnic_nic_template qlcnic_vf_ops; 1737extern struct qlcnic_nic_template qlcnic_vf_ops;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index e380f0398165..b1046c3b68d2 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -540,6 +540,9 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
540 .set_mac_filter_count = qlcnic_82xx_set_mac_filter_count, 540 .set_mac_filter_count = qlcnic_82xx_set_mac_filter_count,
541 .free_mac_list = qlcnic_82xx_free_mac_list, 541 .free_mac_list = qlcnic_82xx_free_mac_list,
542 .read_phys_port_id = qlcnic_82xx_read_phys_port_id, 542 .read_phys_port_id = qlcnic_82xx_read_phys_port_id,
543 .io_error_detected = qlcnic_82xx_io_error_detected,
544 .io_slot_reset = qlcnic_82xx_io_slot_reset,
545 .io_resume = qlcnic_82xx_io_resume,
543}; 546};
544 547
545static void qlcnic_get_multiq_capability(struct qlcnic_adapter *adapter) 548static void qlcnic_get_multiq_capability(struct qlcnic_adapter *adapter)
@@ -3431,19 +3434,6 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
3431 return err; 3434 return err;
3432 } 3435 }
3433 3436
3434 if (qlcnic_83xx_check(adapter)) {
3435 /* register for NIC IDC AEN Events */
3436 qlcnic_83xx_register_nic_idc_func(adapter, 1);
3437 err = qlcnic_83xx_setup_mbx_intr(adapter);
3438 if (err) {
3439 dev_err(&adapter->pdev->dev,
3440 "failed to setup mbx interrupt\n");
3441 qlcnic_clr_all_drv_state(adapter, 1);
3442 clear_bit(__QLCNIC_AER, &adapter->state);
3443 goto done;
3444 }
3445 }
3446
3447 if (netif_running(netdev)) { 3437 if (netif_running(netdev)) {
3448 err = qlcnic_attach(adapter); 3438 err = qlcnic_attach(adapter);
3449 if (err) { 3439 if (err) {
@@ -3464,8 +3454,8 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
3464 return err; 3454 return err;
3465} 3455}
3466 3456
3467static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, 3457pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *pdev,
3468 pci_channel_state_t state) 3458 pci_channel_state_t state)
3469{ 3459{
3470 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3460 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3471 struct net_device *netdev = adapter->netdev; 3461 struct net_device *netdev = adapter->netdev;
@@ -3484,12 +3474,6 @@ static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev,
3484 if (netif_running(netdev)) 3474 if (netif_running(netdev))
3485 qlcnic_down(adapter, netdev); 3475 qlcnic_down(adapter, netdev);
3486 3476
3487 if (qlcnic_83xx_check(adapter)) {
3488 qlcnic_83xx_free_mbx_intr(adapter);
3489 qlcnic_83xx_register_nic_idc_func(adapter, 0);
3490 cancel_delayed_work_sync(&adapter->idc_aen_work);
3491 }
3492
3493 qlcnic_detach(adapter); 3477 qlcnic_detach(adapter);
3494 qlcnic_teardown_intr(adapter); 3478 qlcnic_teardown_intr(adapter);
3495 3479
@@ -3501,13 +3485,13 @@ static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev,
3501 return PCI_ERS_RESULT_NEED_RESET; 3485 return PCI_ERS_RESULT_NEED_RESET;
3502} 3486}
3503 3487
3504static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) 3488pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *pdev)
3505{ 3489{
3506 return qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT : 3490 return qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT :
3507 PCI_ERS_RESULT_RECOVERED; 3491 PCI_ERS_RESULT_RECOVERED;
3508} 3492}
3509 3493
3510static void qlcnic_io_resume(struct pci_dev *pdev) 3494void qlcnic_82xx_io_resume(struct pci_dev *pdev)
3511{ 3495{
3512 u32 state; 3496 u32 state;
3513 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); 3497 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
@@ -3517,9 +3501,48 @@ static void qlcnic_io_resume(struct pci_dev *pdev)
3517 if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER, 3501 if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER,
3518 &adapter->state)) 3502 &adapter->state))
3519 qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, 3503 qlcnic_schedule_work(adapter, qlcnic_fw_poll_work,
3520 FW_POLL_DELAY); 3504 FW_POLL_DELAY);
3521} 3505}
3522 3506
3507static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev,
3508 pci_channel_state_t state)
3509{
3510 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3511 struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops;
3512
3513 if (hw_ops->io_error_detected) {
3514 return hw_ops->io_error_detected(pdev, state);
3515 } else {
3516 dev_err(&pdev->dev, "AER error_detected handler not registered.\n");
3517 return PCI_ERS_RESULT_DISCONNECT;
3518 }
3519}
3520
3521static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev)
3522{
3523 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3524 struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops;
3525
3526 if (hw_ops->io_slot_reset) {
3527 return hw_ops->io_slot_reset(pdev);
3528 } else {
3529 dev_err(&pdev->dev, "AER slot_reset handler not registered.\n");
3530 return PCI_ERS_RESULT_DISCONNECT;
3531 }
3532}
3533
3534static void qlcnic_io_resume(struct pci_dev *pdev)
3535{
3536 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3537 struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops;
3538
3539 if (hw_ops->io_resume)
3540 hw_ops->io_resume(pdev);
3541 else
3542 dev_err(&pdev->dev, "AER resume handler not registered.\n");
3543}
3544
3545
3523static int 3546static int
3524qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) 3547qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
3525{ 3548{