diff options
author | Pratik Pujar <pratik.pujar@qlogic.com> | 2013-08-30 13:51:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-31 22:34:44 -0400 |
commit | 4460f2e83c61e21c2e78a28a327b716252b13069 (patch) | |
tree | 1e60eaf7d75572d9bca6a43155f3ae5abb66365d | |
parent | 890b6e023bd7ff9b5fc89750d9ab2cd414fa302e (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.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 71 |
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); | |||
1479 | int qlcnic_dump_fw(struct qlcnic_adapter *); | 1479 | int qlcnic_dump_fw(struct qlcnic_adapter *); |
1480 | int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *); | 1480 | int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *); |
1481 | bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *); | 1481 | bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *); |
1482 | pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *, | ||
1483 | pci_channel_state_t); | ||
1484 | pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *); | ||
1485 | void qlcnic_82xx_io_resume(struct pci_dev *); | ||
1482 | 1486 | ||
1483 | /* Functions from qlcnic_init.c */ | 1487 | /* Functions from qlcnic_init.c */ |
1484 | void qlcnic_schedule_work(struct qlcnic_adapter *, work_func_t, int); | 1488 | void 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 | ||
1729 | extern struct qlcnic_nic_template qlcnic_vf_ops; | 1737 | extern 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 | ||
545 | static void qlcnic_get_multiq_capability(struct qlcnic_adapter *adapter) | 548 | static 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 | ||
3467 | static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, | 3457 | pci_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 | ||
3504 | static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) | 3488 | pci_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 | ||
3510 | static void qlcnic_io_resume(struct pci_dev *pdev) | 3494 | void 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 | ||
3507 | static 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 | |||
3521 | static 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 | |||
3534 | static 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 | |||
3523 | static int | 3546 | static int |
3524 | qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) | 3547 | qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) |
3525 | { | 3548 | { |