Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 486a5bc7 authored by Rajesh Borundia's avatar Rajesh Borundia Committed by David S. Miller
Browse files

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: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarJitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8af3f33d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1596,6 +1596,8 @@ struct qlcnic_nic_template {
	void (*napi_del)(struct qlcnic_adapter *);
	void (*config_ipaddr)(struct qlcnic_adapter *, __be32, int);
	irqreturn_t (*clear_legacy_intr)(struct qlcnic_adapter *);
	int (*shutdown)(struct pci_dev *);
	int (*resume)(struct qlcnic_adapter *);
};

/* Adapter hardware abstraction */
@@ -1800,6 +1802,18 @@ static inline void qlcnic_napi_enable(struct qlcnic_adapter *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)
{
	adapter->ahw->hw_ops->napi_disable(adapter);
+53 −0
Original line number Diff line number Diff line
@@ -186,6 +186,8 @@ static struct qlcnic_nic_template qlcnic_83xx_ops = {
	.napi_del		= qlcnic_83xx_napi_del,
	.config_ipaddr		= qlcnic_83xx_config_ipaddr,
	.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)
@@ -3393,3 +3395,54 @@ int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
	}
	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;
}
+6 −0
Original line number Diff line number Diff line
@@ -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_disable_mbx_poll(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
+13 −4
Original line number Diff line number Diff line
@@ -606,7 +606,7 @@ static int qlcnic_83xx_idc_check_fan_failure(struct qlcnic_adapter *adapter)
	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;

@@ -1135,7 +1135,7 @@ qlcnic_83xx_idc_first_to_load_function_handler(struct qlcnic_adapter *adapter)
	return 0;
}

static int qlcnic_83xx_idc_init(struct qlcnic_adapter *adapter)
int qlcnic_83xx_idc_init(struct qlcnic_adapter *adapter)
{
	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)
{
	u8 *p_buff;
	u32 addr, count;
	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.buff = kzalloc(QLC_83XX_RESTART_TEMPLATE_SIZE, GFP_KERNEL);
+22 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
	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;
	int ret = -EBUSY;
@@ -218,3 +218,24 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)

	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;
}
Loading