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

Commit d2de064b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wil6210: run-time PM when interface down"

parents 97ce7fae 8cb135bf
Loading
Loading
Loading
Loading
+89 −7
Original line number Diff line number Diff line
@@ -242,12 +242,19 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
{
	struct wil6210_priv *wil = s->private;
	int ret;

	ret = wil_pm_runtime_get(wil);
	if (ret < 0)
		return ret;

	wil_print_ring(s, "tx", wil->csr + HOST_MBOX +
		       offsetof(struct wil6210_mbox_ctl, tx));
	wil_print_ring(s, "rx", wil->csr + HOST_MBOX +
		       offsetof(struct wil6210_mbox_ctl, rx));

	wil_pm_runtime_put(wil);

	return 0;
}

@@ -265,15 +272,38 @@ static const struct file_operations fops_mbox = {

static int wil_debugfs_iomem_x32_set(void *data, u64 val)
{
	writel(val, (void __iomem *)data);
	struct wil_debugfs_iomem_data *d = (struct
					    wil_debugfs_iomem_data *)data;
	struct wil6210_priv *wil = d->wil;
	int ret;

	ret = wil_pm_runtime_get(wil);
	if (ret < 0)
		return ret;

	writel_relaxed(val, (void __iomem *)d->offset);

	wmb(); /* make sure write propagated to HW */

	wil_pm_runtime_put(wil);

	return 0;
}

static int wil_debugfs_iomem_x32_get(void *data, u64 *val)
{
	*val = readl((void __iomem *)data);
	struct wil_debugfs_iomem_data *d = (struct
					    wil_debugfs_iomem_data *)data;
	struct wil6210_priv *wil = d->wil;
	int ret;

	ret = wil_pm_runtime_get(wil);
	if (ret < 0)
		return ret;

	*val = readl_relaxed((void __iomem *)d->offset);

	wil_pm_runtime_put(wil);

	return 0;
}
@@ -284,10 +314,21 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, wil_debugfs_iomem_x32_get,
static struct dentry *wil_debugfs_create_iomem_x32(const char *name,
						   umode_t mode,
						   struct dentry *parent,
						   void *value)
						   void *value,
						   struct wil6210_priv *wil)
{
	return debugfs_create_file(name, mode, parent, value,
				   &fops_iomem_x32);
	struct dentry *file;
	struct wil_debugfs_iomem_data *data = &wil->dbg_data.data_arr[
					      wil->dbg_data.iomem_data_count];

	data->wil = wil;
	data->offset = value;

	file = debugfs_create_file(name, mode, parent, data, &fops_iomem_x32);
	if (!IS_ERR_OR_NULL(file))
		wil->dbg_data.iomem_data_count++;

	return file;
}

static int wil_debugfs_ulong_set(void *data, u64 val)
@@ -346,7 +387,8 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil,
		case doff_io32:
			f = wil_debugfs_create_iomem_x32(tbl[i].name,
							 tbl[i].mode, dbg,
							 base + tbl[i].off);
							 base + tbl[i].off,
							 wil);
			break;
		case doff_u8:
			f = debugfs_create_u8(tbl[i].name, tbl[i].mode, dbg,
@@ -475,13 +517,22 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil,
static int wil_memread_debugfs_show(struct seq_file *s, void *data)
{
	struct wil6210_priv *wil = s->private;
	void __iomem *a = wmi_buffer(wil, cpu_to_le32(mem_addr));
	void __iomem *a;
	int ret;

	ret = wil_pm_runtime_get(wil);
	if (ret < 0)
		return ret;

	a = wmi_buffer(wil, cpu_to_le32(mem_addr));

	if (a)
		seq_printf(s, "[0x%08x] = 0x%08x\n", mem_addr, readl(a));
	else
		seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);

	wil_pm_runtime_put(wil);

	return 0;
}

@@ -502,10 +553,12 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
{
	enum { max_count = 4096 };
	struct wil_blob_wrapper *wil_blob = file->private_data;
	struct wil6210_priv *wil = wil_blob->wil;
	loff_t pos = *ppos;
	size_t available = wil_blob->blob.size;
	void *buf;
	size_t ret;
	int rc;

	if (test_bit(wil_status_suspending, wil_blob->wil->status) ||
	    test_bit(wil_status_suspended, wil_blob->wil->status))
@@ -526,10 +579,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
	if (!buf)
		return -ENOMEM;

	rc = wil_pm_runtime_get(wil);
	if (rc < 0) {
		kfree(buf);
		return rc;
	}

	wil_memcpy_fromio_32(buf, (const void __iomem *)
			     wil_blob->blob.data + pos, count);

	ret = copy_to_user(user_buf, buf, count);

	wil_pm_runtime_put(wil);

	kfree(buf);
	if (ret == count)
		return -EFAULT;
@@ -1786,6 +1848,13 @@ static const struct dbg_off dbg_statics[] = {
	{},
};

static const int dbg_off_count = 4 * (ARRAY_SIZE(isr_off) - 1) +
				ARRAY_SIZE(dbg_wil_regs) - 1 +
				ARRAY_SIZE(pseudo_isr_off) - 1 +
				ARRAY_SIZE(lgc_itr_cnt_off) - 1 +
				ARRAY_SIZE(tx_itr_cnt_off) - 1 +
				ARRAY_SIZE(rx_itr_cnt_off) - 1;

int wil6210_debugfs_init(struct wil6210_priv *wil)
{
	struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME,
@@ -1794,6 +1863,17 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
	if (IS_ERR_OR_NULL(dbg))
		return -ENODEV;

	wil->dbg_data.data_arr = kcalloc(dbg_off_count,
					 sizeof(struct wil_debugfs_iomem_data),
					 GFP_KERNEL);
	if (!wil->dbg_data.data_arr) {
		debugfs_remove_recursive(dbg);
		wil->debug = NULL;
		return -ENOMEM;
	}

	wil->dbg_data.iomem_data_count = 0;

	wil_pmc_init(wil);

	wil6210_debugfs_init_files(wil, dbg);
@@ -1818,6 +1898,8 @@ void wil6210_debugfs_remove(struct wil6210_priv *wil)
	debugfs_remove_recursive(wil->debug);
	wil->debug = NULL;

	kfree(wil->dbg_data.data_arr);

	/* free pmc memory without sending command to fw, as it will
	 * be reset on the way down anyway
	 */
+15 −0
Original line number Diff line number Diff line
@@ -47,9 +47,14 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
	struct wil6210_priv *wil = ndev_to_wil(ndev);
	u32 tx_itr_en, tx_itr_val = 0;
	u32 rx_itr_en, rx_itr_val = 0;
	int ret;

	wil_dbg_misc(wil, "ethtoolops_get_coalesce\n");

	ret = wil_pm_runtime_get(wil);
	if (ret < 0)
		return ret;

	tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL);
	if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
		tx_itr_val = wil_r(wil, RGF_DMA_ITR_TX_CNT_TRSH);
@@ -58,6 +63,8 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
	if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN)
		rx_itr_val = wil_r(wil, RGF_DMA_ITR_RX_CNT_TRSH);

	wil_pm_runtime_put(wil);

	cp->tx_coalesce_usecs = tx_itr_val;
	cp->rx_coalesce_usecs = rx_itr_val;
	return 0;
@@ -67,6 +74,7 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
				       struct ethtool_coalesce *cp)
{
	struct wil6210_priv *wil = ndev_to_wil(ndev);
	int ret;

	wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n",
		     cp->rx_coalesce_usecs, cp->tx_coalesce_usecs);
@@ -86,8 +94,15 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev,

	wil->tx_max_burst_duration = cp->tx_coalesce_usecs;
	wil->rx_max_burst_duration = cp->rx_coalesce_usecs;

	ret = wil_pm_runtime_get(wil);
	if (ret < 0)
		return ret;

	wil_configure_interrupt_moderation(wil);

	wil_pm_runtime_put(wil);

	return 0;

out_bad:
+7 −0
Original line number Diff line number Diff line
@@ -221,6 +221,10 @@ int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd)
{
	int ret;

	ret = wil_pm_runtime_get(wil);
	if (ret < 0)
		return ret;

	switch (cmd) {
	case WIL_IOCTL_MEMIO:
		ret = wil_ioc_memio_dword(wil, data);
@@ -233,9 +237,12 @@ int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd)
		break;
	default:
		wil_dbg_ioctl(wil, "Unsupported IOCTL 0x%04x\n", cmd);
		wil_pm_runtime_put(wil);
		return -ENOIOCTLCMD;
	}

	wil_pm_runtime_put(wil);

	wil_dbg_ioctl(wil, "ioctl(0x%04x) -> %d\n", cmd, ret);
	return ret;
}
+16 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ MODULE_PARM_DESC(alt_ifname, " use an alternate interface name wigigN instead of
static int wil_open(struct net_device *ndev)
{
	struct wil6210_priv *wil = ndev_to_wil(ndev);
	int rc;

	wil_dbg_misc(wil, "open\n");

@@ -35,16 +36,29 @@ static int wil_open(struct net_device *ndev)
		return -EINVAL;
	}

	return wil_up(wil);
	rc = wil_pm_runtime_get(wil);
	if (rc < 0)
		return rc;

	rc = wil_up(wil);
	if (rc)
		wil_pm_runtime_put(wil);

	return rc;
}

static int wil_stop(struct net_device *ndev)
{
	struct wil6210_priv *wil = ndev_to_wil(ndev);
	int rc;

	wil_dbg_misc(wil, "stop\n");

	return wil_down(wil);
	rc = wil_down(wil);
	if (!rc)
		wil_pm_runtime_put(wil);

	return rc;
}

static int wil_change_mtu(struct net_device *ndev, int new_mtu)
+35 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/suspend.h>
#include "wil6210.h"
#include <linux/rtnetlink.h>
#include <linux/pm_runtime.h>

static bool use_msi = true;
module_param(use_msi, bool, 0444);
@@ -316,6 +317,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	wil6210_debugfs_init(wil);
	wil6210_sysfs_init(wil);

	wil_pm_runtime_allow(wil);

	return 0;

bus_disable:
@@ -348,6 +351,8 @@ static void wil_pcie_remove(struct pci_dev *pdev)
#endif /* CONFIG_PM_SLEEP */
#endif /* CONFIG_PM */

	wil_pm_runtime_forbid(wil);

	wil6210_sysfs_remove(wil);
	wil6210_debugfs_remove(wil);
	rtnl_lock();
@@ -477,10 +482,40 @@ static int wil6210_pm_resume(struct device *dev)
}
#endif /* CONFIG_PM_SLEEP */

static int wil6210_pm_runtime_idle(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct wil6210_priv *wil = pci_get_drvdata(pdev);

	wil_dbg_pm(wil, "Runtime idle\n");

	return wil_can_suspend(wil, true);
}

static int wil6210_pm_runtime_resume(struct device *dev)
{
	return wil6210_resume(dev, true);
}

static int wil6210_pm_runtime_suspend(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct wil6210_priv *wil = pci_get_drvdata(pdev);

	if (test_bit(wil_status_suspended, wil->status)) {
		wil_dbg_pm(wil, "trying to suspend while suspended\n");
		return 1;
	}

	return wil6210_suspend(dev, true);
}
#endif /* CONFIG_PM */

static const struct dev_pm_ops wil6210_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(wil6210_pm_suspend, wil6210_pm_resume)
	SET_RUNTIME_PM_OPS(wil6210_pm_runtime_suspend,
			   wil6210_pm_runtime_resume,
			   wil6210_pm_runtime_idle)
};

static struct pci_driver wil6210_driver = {
Loading