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

Commit 0b72e659 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller
Browse files

netxen: add suspend resume support



Detach network interface on PCI suspend and recreate hardware
context after resumes.

Signed-off-by: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fbb52f22
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1389,6 +1389,7 @@ void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);

int netxen_nic_get_board_info(struct netxen_adapter *adapter);
void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
int netxen_nic_wol_supported(struct netxen_adapter *adapter);

int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
		ulong off, void *data, int len);
+17 −0
Original line number Diff line number Diff line
@@ -2320,3 +2320,20 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
	}
}

int
netxen_nic_wol_supported(struct netxen_adapter *adapter)
{
	u32 wol_cfg;

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
		return 0;

	wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
	if (wol_cfg & (1UL << adapter->portnum)) {
		wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
		if (wol_cfg & (1 << adapter->portnum))
			return 1;
	}

	return 0;
}
+84 −18
Original line number Diff line number Diff line
@@ -643,6 +643,18 @@ netxen_start_firmware(struct netxen_adapter *adapter)
	int val, err, first_boot;
	struct pci_dev *pdev = adapter->pdev;

	int first_driver = 0;
	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		if (adapter->ahw.pci_func == 0)
			first_driver = 1;
	} else {
		if (adapter->portnum == 0)
			first_driver = 1;
	}

	if (!first_driver)
		return 0;

	first_boot = adapter->pci_read_normalize(adapter,
			NETXEN_CAM_RAM(0x1fc));

@@ -859,7 +871,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	struct net_device *netdev = NULL;
	struct netxen_adapter *adapter = NULL;
	int i = 0, err;
	int first_driver;
	int pci_func_id = PCI_FUNC(pdev->devfn);
	uint8_t revision_id;

@@ -978,20 +989,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	 */
	netxen_check_options(adapter);

	first_driver = 0;
	if (NX_IS_REVISION_P3(revision_id)) {
		if (adapter->ahw.pci_func == 0)
			first_driver = 1;
	} else {
		if (adapter->portnum == 0)
			first_driver = 1;
	}

	if (first_driver) {
	err = netxen_start_firmware(adapter);
	if (err)
		goto err_out_iounmap;
	}

	nx_update_dma_mask(adapter);

@@ -1062,7 +1062,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_disable_msi:
	netxen_teardown_intr(adapter);

	if (first_driver)
	netxen_free_adapter_offload(adapter);

err_out_iounmap:
@@ -1114,6 +1113,71 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
	free_netdev(netdev);
}

static int
netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
{

	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
	struct net_device *netdev = adapter->netdev;

	netif_device_detach(netdev);

	if (netif_running(netdev))
		netxen_nic_down(adapter, netdev);

	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
		netxen_nic_detach(adapter);

	pci_save_state(pdev);

	if (netxen_nic_wol_supported(adapter)) {
		pci_enable_wake(pdev, PCI_D3cold, 1);
		pci_enable_wake(pdev, PCI_D3hot, 1);
	}

	pci_disable_device(pdev);
	pci_set_power_state(pdev, pci_choose_state(pdev, state));

	return 0;
}

static int
netxen_nic_resume(struct pci_dev *pdev)
{
	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
	struct net_device *netdev = adapter->netdev;
	int err;

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);

	err = pci_enable_device(pdev);
	if (err)
		return err;

	adapter->curr_window = 255;

	err = netxen_start_firmware(adapter);
	if (err) {
		dev_err(&pdev->dev, "failed to start firmware\n");
		return err;
	}

	if (netif_running(netdev)) {
		err = netxen_nic_attach(adapter);
		if (err)
			return err;

		err = netxen_nic_up(adapter, netdev);
		if (err)
			return err;

		netif_device_attach(netdev);
	}

	return 0;
}

static int netxen_nic_open(struct net_device *netdev)
{
	struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1649,7 +1713,9 @@ static struct pci_driver netxen_driver = {
	.name = netxen_nic_driver_name,
	.id_table = netxen_pci_tbl,
	.probe = netxen_nic_probe,
	.remove = __devexit_p(netxen_nic_remove)
	.remove = __devexit_p(netxen_nic_remove),
	.suspend = netxen_nic_suspend,
	.resume = netxen_nic_resume
};

/* Driver Registration on NetXen card    */