From: Pratik Pujar Date: Fri, 30 Aug 2013 17:51:20 +0000 (-0400) Subject: qlcnic: Add AER callback handlers. X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=4460f2e83c61e21c2e78a28a327b716252b13069;p=linux-beck.git 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 Signed-off-by: David S. Miller --- 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); int qlcnic_dump_fw(struct qlcnic_adapter *); int qlcnic_enable_fw_dump_state(struct qlcnic_adapter *); bool qlcnic_check_fw_dump_state(struct qlcnic_adapter *); +pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *, + pci_channel_state_t); +pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *); +void qlcnic_82xx_io_resume(struct pci_dev *); /* Functions from qlcnic_init.c */ void qlcnic_schedule_work(struct qlcnic_adapter *, work_func_t, int); @@ -1724,6 +1728,10 @@ struct qlcnic_hardware_ops { void (*set_mac_filter_count) (struct qlcnic_adapter *); void (*free_mac_list) (struct qlcnic_adapter *); int (*read_phys_port_id) (struct qlcnic_adapter *); + pci_ers_result_t (*io_error_detected) (struct pci_dev *, + pci_channel_state_t); + pci_ers_result_t (*io_slot_reset) (struct pci_dev *); + void (*io_resume) (struct pci_dev *); }; 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 = { .set_mac_filter_count = qlcnic_82xx_set_mac_filter_count, .free_mac_list = qlcnic_82xx_free_mac_list, .read_phys_port_id = qlcnic_82xx_read_phys_port_id, + .io_error_detected = qlcnic_82xx_io_error_detected, + .io_slot_reset = qlcnic_82xx_io_slot_reset, + .io_resume = qlcnic_82xx_io_resume, }; static void qlcnic_get_multiq_capability(struct qlcnic_adapter *adapter) @@ -3431,19 +3434,6 @@ static int qlcnic_attach_func(struct pci_dev *pdev) return err; } - if (qlcnic_83xx_check(adapter)) { - /* register for NIC IDC AEN Events */ - qlcnic_83xx_register_nic_idc_func(adapter, 1); - err = qlcnic_83xx_setup_mbx_intr(adapter); - if (err) { - dev_err(&adapter->pdev->dev, - "failed to setup mbx interrupt\n"); - qlcnic_clr_all_drv_state(adapter, 1); - clear_bit(__QLCNIC_AER, &adapter->state); - goto done; - } - } - if (netif_running(netdev)) { err = qlcnic_attach(adapter); if (err) { @@ -3464,8 +3454,8 @@ static int qlcnic_attach_func(struct pci_dev *pdev) return err; } -static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) +pci_ers_result_t qlcnic_82xx_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) { struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); struct net_device *netdev = adapter->netdev; @@ -3484,12 +3474,6 @@ static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, if (netif_running(netdev)) qlcnic_down(adapter, netdev); - if (qlcnic_83xx_check(adapter)) { - qlcnic_83xx_free_mbx_intr(adapter); - qlcnic_83xx_register_nic_idc_func(adapter, 0); - cancel_delayed_work_sync(&adapter->idc_aen_work); - } - qlcnic_detach(adapter); qlcnic_teardown_intr(adapter); @@ -3501,13 +3485,13 @@ static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, return PCI_ERS_RESULT_NEED_RESET; } -static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) +pci_ers_result_t qlcnic_82xx_io_slot_reset(struct pci_dev *pdev) { return qlcnic_attach_func(pdev) ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; } -static void qlcnic_io_resume(struct pci_dev *pdev) +void qlcnic_82xx_io_resume(struct pci_dev *pdev) { u32 state; struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); @@ -3517,9 +3501,48 @@ static void qlcnic_io_resume(struct pci_dev *pdev) if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER, &adapter->state)) qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, - FW_POLL_DELAY); + FW_POLL_DELAY); } +static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); + struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; + + if (hw_ops->io_error_detected) { + return hw_ops->io_error_detected(pdev, state); + } else { + dev_err(&pdev->dev, "AER error_detected handler not registered.\n"); + return PCI_ERS_RESULT_DISCONNECT; + } +} + +static pci_ers_result_t qlcnic_io_slot_reset(struct pci_dev *pdev) +{ + struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); + struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; + + if (hw_ops->io_slot_reset) { + return hw_ops->io_slot_reset(pdev); + } else { + dev_err(&pdev->dev, "AER slot_reset handler not registered.\n"); + return PCI_ERS_RESULT_DISCONNECT; + } +} + +static void qlcnic_io_resume(struct pci_dev *pdev) +{ + struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); + struct qlcnic_hardware_ops *hw_ops = adapter->ahw->hw_ops; + + if (hw_ops->io_resume) + hw_ops->io_resume(pdev); + else + dev_err(&pdev->dev, "AER resume handler not registered.\n"); +} + + static int qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) {