qlcnic: Add support for 83xx suspend and resume.
o Implement shutdown and resume handlers for 83xx. o Refactor 82xx shutdown and resume handlers. Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com> Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8af3f33db0
commit
486a5bc77a
@ -1596,6 +1596,8 @@ struct qlcnic_nic_template {
|
|||||||
void (*napi_del)(struct qlcnic_adapter *);
|
void (*napi_del)(struct qlcnic_adapter *);
|
||||||
void (*config_ipaddr)(struct qlcnic_adapter *, __be32, int);
|
void (*config_ipaddr)(struct qlcnic_adapter *, __be32, int);
|
||||||
irqreturn_t (*clear_legacy_intr)(struct qlcnic_adapter *);
|
irqreturn_t (*clear_legacy_intr)(struct qlcnic_adapter *);
|
||||||
|
int (*shutdown)(struct pci_dev *);
|
||||||
|
int (*resume)(struct qlcnic_adapter *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Adapter hardware abstraction */
|
/* Adapter hardware abstraction */
|
||||||
@ -1800,6 +1802,18 @@ static inline void qlcnic_napi_enable(struct qlcnic_adapter *adapter)
|
|||||||
adapter->ahw->hw_ops->napi_enable(adapter);
|
adapter->ahw->hw_ops->napi_enable(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int __qlcnic_shutdown(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
|
return adapter->nic_ops->shutdown(pdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int __qlcnic_resume(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
return adapter->nic_ops->resume(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void qlcnic_napi_disable(struct qlcnic_adapter *adapter)
|
static inline void qlcnic_napi_disable(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
adapter->ahw->hw_ops->napi_disable(adapter);
|
adapter->ahw->hw_ops->napi_disable(adapter);
|
||||||
|
@ -186,6 +186,8 @@ static struct qlcnic_nic_template qlcnic_83xx_ops = {
|
|||||||
.napi_del = qlcnic_83xx_napi_del,
|
.napi_del = qlcnic_83xx_napi_del,
|
||||||
.config_ipaddr = qlcnic_83xx_config_ipaddr,
|
.config_ipaddr = qlcnic_83xx_config_ipaddr,
|
||||||
.clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
|
.clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
|
||||||
|
.shutdown = qlcnic_83xx_shutdown,
|
||||||
|
.resume = qlcnic_83xx_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
|
void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
|
||||||
@ -3393,3 +3395,54 @@ int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qlcnic_83xx_shutdown(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
|
||||||
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
netif_device_detach(netdev);
|
||||||
|
qlcnic_cancel_idc_work(adapter);
|
||||||
|
|
||||||
|
if (netif_running(netdev))
|
||||||
|
qlcnic_down(adapter, netdev);
|
||||||
|
|
||||||
|
qlcnic_83xx_disable_mbx_intr(adapter);
|
||||||
|
cancel_delayed_work_sync(&adapter->idc_aen_work);
|
||||||
|
|
||||||
|
retval = pci_save_state(pdev);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||||
|
struct qlc_83xx_idc *idc = &ahw->idc;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
err = qlcnic_83xx_idc_init(adapter);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE) {
|
||||||
|
if (ahw->op_mode == QLCNIC_MGMT_FUNC) {
|
||||||
|
qlcnic_83xx_set_vnic_opmode(adapter);
|
||||||
|
} else {
|
||||||
|
err = qlcnic_83xx_check_vnic_state(adapter);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = qlcnic_83xx_idc_reattach_driver(adapter);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
|
||||||
|
idc->delay);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@ -628,4 +628,10 @@ u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *);
|
|||||||
void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
|
void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
|
||||||
void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
|
void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
|
||||||
void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
|
void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
|
||||||
|
int qlcnic_83xx_shutdown(struct pci_dev *);
|
||||||
|
int qlcnic_83xx_resume(struct qlcnic_adapter *);
|
||||||
|
int qlcnic_83xx_idc_init(struct qlcnic_adapter *);
|
||||||
|
int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *);
|
||||||
|
int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *);
|
||||||
|
int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *);
|
||||||
#endif
|
#endif
|
||||||
|
@ -606,7 +606,7 @@ static int qlcnic_83xx_idc_check_fan_failure(struct qlcnic_adapter *adapter)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
|
int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -1135,7 +1135,7 @@ qlcnic_83xx_idc_first_to_load_function_handler(struct qlcnic_adapter *adapter)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qlcnic_83xx_idc_init(struct qlcnic_adapter *adapter)
|
int qlcnic_83xx_idc_init(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
@ -1554,9 +1554,18 @@ static int qlcnic_83xx_reset_template_checksum(struct qlcnic_adapter *p_dev)
|
|||||||
|
|
||||||
int qlcnic_83xx_get_reset_instruction_template(struct qlcnic_adapter *p_dev)
|
int qlcnic_83xx_get_reset_instruction_template(struct qlcnic_adapter *p_dev)
|
||||||
{
|
{
|
||||||
u8 *p_buff;
|
|
||||||
u32 addr, count;
|
|
||||||
struct qlcnic_hardware_context *ahw = p_dev->ahw;
|
struct qlcnic_hardware_context *ahw = p_dev->ahw;
|
||||||
|
u32 addr, count, prev_ver, curr_ver;
|
||||||
|
u8 *p_buff;
|
||||||
|
|
||||||
|
if (ahw->reset.buff != NULL) {
|
||||||
|
prev_ver = p_dev->fw_version;
|
||||||
|
curr_ver = qlcnic_83xx_get_fw_version(p_dev);
|
||||||
|
if (curr_ver > prev_ver)
|
||||||
|
kfree(ahw->reset.buff);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ahw->reset.seq_error = 0;
|
ahw->reset.seq_error = 0;
|
||||||
ahw->reset.buff = kzalloc(QLC_83XX_RESTART_TEMPLATE_SIZE, GFP_KERNEL);
|
ahw->reset.buff = kzalloc(QLC_83XX_RESTART_TEMPLATE_SIZE, GFP_KERNEL);
|
||||||
|
@ -39,7 +39,7 @@ int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
|
int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
u8 id;
|
u8 id;
|
||||||
int ret = -EBUSY;
|
int ret = -EBUSY;
|
||||||
@ -218,3 +218,24 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||||
|
struct qlc_83xx_idc *idc = &ahw->idc;
|
||||||
|
u32 state;
|
||||||
|
|
||||||
|
state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
|
||||||
|
while (state != QLCNIC_DEV_NPAR_OPER && idc->vnic_wait_limit--) {
|
||||||
|
msleep(1000);
|
||||||
|
state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!idc->vnic_wait_limit) {
|
||||||
|
dev_err(&adapter->pdev->dev,
|
||||||
|
"vNIC mode not operational, state check timed out.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -1577,3 +1577,54 @@ void qlcnic_82xx_api_unlock(struct qlcnic_adapter *adapter)
|
|||||||
{
|
{
|
||||||
qlcnic_pcie_sem_unlock(adapter, 5);
|
qlcnic_pcie_sem_unlock(adapter, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qlcnic_82xx_shutdown(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
|
||||||
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
netif_device_detach(netdev);
|
||||||
|
|
||||||
|
qlcnic_cancel_idc_work(adapter);
|
||||||
|
|
||||||
|
if (netif_running(netdev))
|
||||||
|
qlcnic_down(adapter, netdev);
|
||||||
|
|
||||||
|
qlcnic_clr_all_drv_state(adapter, 0);
|
||||||
|
|
||||||
|
clear_bit(__QLCNIC_RESETTING, &adapter->state);
|
||||||
|
|
||||||
|
retval = pci_save_state(pdev);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
if (qlcnic_wol_supported(adapter)) {
|
||||||
|
pci_enable_wake(pdev, PCI_D3cold, 1);
|
||||||
|
pci_enable_wake(pdev, PCI_D3hot, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qlcnic_82xx_resume(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = qlcnic_start_firmware(adapter);
|
||||||
|
if (err) {
|
||||||
|
dev_err(&adapter->pdev->dev, "failed to start firmware\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netif_running(netdev)) {
|
||||||
|
err = qlcnic_up(adapter, netdev);
|
||||||
|
if (!err)
|
||||||
|
qlcnic_restore_indev_addr(netdev, NETDEV_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
netif_device_attach(netdev);
|
||||||
|
qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@ -199,4 +199,8 @@ void qlcnic_82xx_api_unlock(struct qlcnic_adapter *);
|
|||||||
void qlcnic_82xx_napi_enable(struct qlcnic_adapter *);
|
void qlcnic_82xx_napi_enable(struct qlcnic_adapter *);
|
||||||
void qlcnic_82xx_napi_disable(struct qlcnic_adapter *);
|
void qlcnic_82xx_napi_disable(struct qlcnic_adapter *);
|
||||||
void qlcnic_82xx_napi_del(struct qlcnic_adapter *);
|
void qlcnic_82xx_napi_del(struct qlcnic_adapter *);
|
||||||
|
int qlcnic_82xx_shutdown(struct pci_dev *);
|
||||||
|
int qlcnic_82xx_resume(struct qlcnic_adapter *);
|
||||||
|
void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed);
|
||||||
|
void qlcnic_fw_poll_work(struct work_struct *work);
|
||||||
#endif /* __QLCNIC_HW_H_ */
|
#endif /* __QLCNIC_HW_H_ */
|
||||||
|
@ -59,13 +59,11 @@ static int qlcnic_close(struct net_device *netdev);
|
|||||||
static void qlcnic_tx_timeout(struct net_device *netdev);
|
static void qlcnic_tx_timeout(struct net_device *netdev);
|
||||||
static void qlcnic_attach_work(struct work_struct *work);
|
static void qlcnic_attach_work(struct work_struct *work);
|
||||||
static void qlcnic_fwinit_work(struct work_struct *work);
|
static void qlcnic_fwinit_work(struct work_struct *work);
|
||||||
static void qlcnic_fw_poll_work(struct work_struct *work);
|
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
static void qlcnic_poll_controller(struct net_device *netdev);
|
static void qlcnic_poll_controller(struct net_device *netdev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding);
|
static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding);
|
||||||
static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8);
|
|
||||||
static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter);
|
static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter);
|
||||||
|
|
||||||
static irqreturn_t qlcnic_tmp_intr(int irq, void *data);
|
static irqreturn_t qlcnic_tmp_intr(int irq, void *data);
|
||||||
@ -469,6 +467,8 @@ static struct qlcnic_nic_template qlcnic_ops = {
|
|||||||
.napi_add = qlcnic_82xx_napi_add,
|
.napi_add = qlcnic_82xx_napi_add,
|
||||||
.napi_del = qlcnic_82xx_napi_del,
|
.napi_del = qlcnic_82xx_napi_del,
|
||||||
.config_ipaddr = qlcnic_82xx_config_ipaddr,
|
.config_ipaddr = qlcnic_82xx_config_ipaddr,
|
||||||
|
.shutdown = qlcnic_82xx_shutdown,
|
||||||
|
.resume = qlcnic_82xx_resume,
|
||||||
.clear_legacy_intr = qlcnic_82xx_clear_legacy_intr,
|
.clear_legacy_intr = qlcnic_82xx_clear_legacy_intr,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2277,37 +2277,6 @@ static void qlcnic_remove(struct pci_dev *pdev)
|
|||||||
kfree(ahw);
|
kfree(ahw);
|
||||||
free_netdev(netdev);
|
free_netdev(netdev);
|
||||||
}
|
}
|
||||||
static int __qlcnic_shutdown(struct pci_dev *pdev)
|
|
||||||
{
|
|
||||||
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
|
|
||||||
struct net_device *netdev = adapter->netdev;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
netif_device_detach(netdev);
|
|
||||||
|
|
||||||
qlcnic_cancel_idc_work(adapter);
|
|
||||||
|
|
||||||
if (netif_running(netdev))
|
|
||||||
qlcnic_down(adapter, netdev);
|
|
||||||
|
|
||||||
qlcnic_sriov_cleanup(adapter);
|
|
||||||
if (qlcnic_82xx_check(adapter))
|
|
||||||
qlcnic_clr_all_drv_state(adapter, 0);
|
|
||||||
|
|
||||||
clear_bit(__QLCNIC_RESETTING, &adapter->state);
|
|
||||||
|
|
||||||
retval = pci_save_state(pdev);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
if (qlcnic_82xx_check(adapter)) {
|
|
||||||
if (qlcnic_wol_supported(adapter)) {
|
|
||||||
pci_enable_wake(pdev, PCI_D3cold, 1);
|
|
||||||
pci_enable_wake(pdev, PCI_D3hot, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qlcnic_shutdown(struct pci_dev *pdev)
|
static void qlcnic_shutdown(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
@ -2318,8 +2287,7 @@ static void qlcnic_shutdown(struct pci_dev *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
static int
|
static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||||
qlcnic_suspend(struct pci_dev *pdev, pm_message_t state)
|
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
@ -2331,11 +2299,9 @@ qlcnic_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int qlcnic_resume(struct pci_dev *pdev)
|
||||||
qlcnic_resume(struct pci_dev *pdev)
|
|
||||||
{
|
{
|
||||||
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
|
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
|
||||||
struct net_device *netdev = adapter->netdev;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = pci_enable_device(pdev);
|
err = pci_enable_device(pdev);
|
||||||
@ -2346,23 +2312,7 @@ qlcnic_resume(struct pci_dev *pdev)
|
|||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
pci_restore_state(pdev);
|
pci_restore_state(pdev);
|
||||||
|
|
||||||
err = qlcnic_start_firmware(adapter);
|
return __qlcnic_resume(adapter);
|
||||||
if (err) {
|
|
||||||
dev_err(&pdev->dev, "failed to start firmware\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (netif_running(netdev)) {
|
|
||||||
err = qlcnic_up(adapter, netdev);
|
|
||||||
if (err)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
qlcnic_restore_indev_addr(netdev, NETDEV_UP);
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
netif_device_attach(netdev);
|
|
||||||
qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2701,8 +2651,7 @@ qlcnic_clr_drv_state(struct qlcnic_adapter *adapter)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
|
||||||
qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
|
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
@ -3213,8 +3162,7 @@ detach:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void qlcnic_fw_poll_work(struct work_struct *work)
|
||||||
qlcnic_fw_poll_work(struct work_struct *work)
|
|
||||||
{
|
{
|
||||||
struct qlcnic_adapter *adapter = container_of(work,
|
struct qlcnic_adapter *adapter = container_of(work,
|
||||||
struct qlcnic_adapter, fw_work.work);
|
struct qlcnic_adapter, fw_work.work);
|
||||||
|
@ -195,6 +195,8 @@ int __qlcnic_sriov_add_act_list(struct qlcnic_sriov *, struct qlcnic_vf_info *,
|
|||||||
int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
|
int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
|
||||||
struct qlcnic_info *, u16);
|
struct qlcnic_info *, u16);
|
||||||
int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
|
int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
|
||||||
|
int qlcnic_sriov_vf_shutdown(struct pci_dev *);
|
||||||
|
int qlcnic_sriov_vf_resume(struct qlcnic_adapter *);
|
||||||
|
|
||||||
static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
|
static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
|
@ -76,6 +76,8 @@ static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {
|
|||||||
.cancel_idc_work = qlcnic_sriov_vf_cancel_fw_work,
|
.cancel_idc_work = qlcnic_sriov_vf_cancel_fw_work,
|
||||||
.napi_add = qlcnic_83xx_napi_add,
|
.napi_add = qlcnic_83xx_napi_add,
|
||||||
.napi_del = qlcnic_83xx_napi_del,
|
.napi_del = qlcnic_83xx_napi_del,
|
||||||
|
.shutdown = qlcnic_sriov_vf_shutdown,
|
||||||
|
.resume = qlcnic_sriov_vf_resume,
|
||||||
.config_ipaddr = qlcnic_83xx_config_ipaddr,
|
.config_ipaddr = qlcnic_83xx_config_ipaddr,
|
||||||
.clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
|
.clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
|
||||||
};
|
};
|
||||||
@ -1954,3 +1956,54 @@ static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *adapter)
|
|||||||
kfree(cur);
|
kfree(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qlcnic_sriov_vf_shutdown(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
|
||||||
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
netif_device_detach(netdev);
|
||||||
|
qlcnic_cancel_idc_work(adapter);
|
||||||
|
|
||||||
|
if (netif_running(netdev))
|
||||||
|
qlcnic_down(adapter, netdev);
|
||||||
|
|
||||||
|
qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);
|
||||||
|
qlcnic_sriov_cfg_bc_intr(adapter, 0);
|
||||||
|
qlcnic_83xx_disable_mbx_intr(adapter);
|
||||||
|
cancel_delayed_work_sync(&adapter->idc_aen_work);
|
||||||
|
|
||||||
|
retval = pci_save_state(pdev);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qlcnic_sriov_vf_resume(struct qlcnic_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct qlc_83xx_idc *idc = &adapter->ahw->idc;
|
||||||
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
set_bit(QLC_83XX_MODULE_LOADED, &idc->status);
|
||||||
|
qlcnic_83xx_enable_mbx_intrpt(adapter);
|
||||||
|
err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);
|
||||||
|
if (!err) {
|
||||||
|
if (netif_running(netdev)) {
|
||||||
|
err = qlcnic_up(adapter, netdev);
|
||||||
|
if (!err)
|
||||||
|
qlcnic_restore_indev_addr(netdev, NETDEV_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
netif_device_attach(netdev);
|
||||||
|
qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,
|
||||||
|
idc->delay);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user