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

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

Merge "wil6210: add support for device led configuration"

parents 32f53e92 abe2134d
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -374,8 +374,9 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
		return -EBUSY;
	}

	/* scan on P2P_DEVICE is handled as p2p search */
	if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
	/* social scan on P2P_DEVICE is handled as p2p search */
	if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
	    wil_p2p_is_social_scan(request)) {
		wil->scan_request = request;
		wil->radio_wdev = wdev;
		rc = wil_p2p_search(wil, request);
+19 −3
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
#include "wil6210.h"
#include "trace.h"

void wil_err(struct wil6210_priv *wil, const char *fmt, ...)
void __wil_err(struct wil6210_priv *wil, const char *fmt, ...)
{
	struct net_device *ndev = wil_to_ndev(wil);
	struct va_format vaf = {
@@ -32,7 +32,7 @@ void wil_err(struct wil6210_priv *wil, const char *fmt, ...)
	va_end(args);
}

void wil_info(struct wil6210_priv *wil, const char *fmt, ...)
void __wil_info(struct wil6210_priv *wil, const char *fmt, ...)
{
	struct net_device *ndev = wil_to_ndev(wil);
	struct va_format vaf = {
@@ -47,7 +47,7 @@ void wil_info(struct wil6210_priv *wil, const char *fmt, ...)
	va_end(args);
}

void wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...)
void __wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...)
{
	if (net_ratelimit()) {
		struct net_device *ndev = wil_to_ndev(wil);
@@ -64,6 +64,22 @@ void wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...)
	}
}

void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...)
{
	struct va_format vaf;
	va_list args;

	if (!net_ratelimit())
		return;

	va_start(args, fmt);
	vaf.fmt = fmt;
	vaf.va = &args;
	netdev_dbg(wil_to_ndev(wil), "%pV", &vaf);
	trace_wil6210_log_dbg(&vaf);
	va_end(args);
}

void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...)
{
	struct va_format vaf = {
+131 −10
Original line number Diff line number Diff line
@@ -165,6 +165,8 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
	int rsize;
	uint i;

	wil_halp_vote(wil);

	wil_memcpy_fromio_32(&r, off, sizeof(r));
	wil_mbox_ring_le2cpus(&r);
	/*
@@ -241,6 +243,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
	}
 out:
	seq_puts(s, "}\n");
	wil_halp_unvote(wil);
}

static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
@@ -505,9 +508,9 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
				    size_t count, loff_t *ppos)
{
	enum { max_count = 4096 };
	struct debugfs_blob_wrapper *blob = file->private_data;
	struct wil_blob_wrapper *wil_blob = file->private_data;
	loff_t pos = *ppos;
	size_t available = blob->size;
	size_t available = wil_blob->blob.size;
	void *buf;
	size_t ret;

@@ -526,8 +529,9 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
	if (!buf)
		return -ENOMEM;

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

	ret = copy_to_user(user_buf, buf, count);
	kfree(buf);
@@ -550,9 +554,9 @@ static
struct dentry *wil_debugfs_create_ioblob(const char *name,
					 umode_t mode,
					 struct dentry *parent,
					 struct debugfs_blob_wrapper *blob)
					 struct wil_blob_wrapper *wil_blob)
{
	return debugfs_create_file(name, mode, parent, blob, &fops_ioblob);
	return debugfs_create_file(name, mode, parent, wil_blob, &fops_ioblob);
}

/*---reset---*/
@@ -843,7 +847,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
	u16 cmdid;
	int rc, rc1;

	if (cmdlen <= 0)
	if (cmdlen < 0)
		return -EINVAL;

	wmi = kmalloc(len, GFP_KERNEL);
@@ -856,7 +860,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
		return rc;
	}

	cmd = &wmi[1];
	cmd = (cmdlen > 0) ? &wmi[1] : NULL;
	cmdid = le16_to_cpu(wmi->command_id);

	rc1 = wmi_send(wil, cmdid, cmd, cmdlen);
@@ -1464,6 +1468,118 @@ static const struct file_operations fops_sta = {
	.llseek		= seq_lseek,
};

static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf,
				     size_t count, loff_t *ppos)
{
	char buf[80];
	int n;

	n = snprintf(buf, sizeof(buf),
		     "led_id is set to %d, echo 1 to enable, 0 to disable\n",
		     led_id);

	n = min_t(int, n, sizeof(buf));

	return simple_read_from_buffer(user_buf, count, ppos,
				       buf, n);
}

static ssize_t wil_write_file_led_cfg(struct file *file,
				      const char __user *buf_,
				      size_t count, loff_t *ppos)
{
	struct wil6210_priv *wil = file->private_data;
	int val;
	int rc;

	rc = kstrtoint_from_user(buf_, count, 0, &val);
	if (rc) {
		wil_err(wil, "Invalid argument\n");
		return rc;
	}

	wil_info(wil, "%s led %d\n", val ? "Enabling" : "Disabling", led_id);
	rc = wmi_led_cfg(wil, val);
	if (rc) {
		wil_info(wil, "%s led %d failed\n",
			 val ? "Enabling" : "Disabling", led_id);
		return rc;
	}

	return count;
}

static const struct file_operations fops_led_cfg = {
	.read = wil_read_file_led_cfg,
	.write = wil_write_file_led_cfg,
	.open  = simple_open,
};

/* led_blink_time, write:
 * "<blink_on_slow> <blink_off_slow> <blink_on_med> <blink_off_med> <blink_on_fast> <blink_off_fast>
 */
static ssize_t wil_write_led_blink_time(struct file *file,
					const char __user *buf,
					size_t len, loff_t *ppos)
{
	int rc;
	char *kbuf = kmalloc(len + 1, GFP_KERNEL);

	if (!kbuf)
		return -ENOMEM;

	rc = simple_write_to_buffer(kbuf, len, ppos, buf, len);
	if (rc != len) {
		kfree(kbuf);
		return rc >= 0 ? -EIO : rc;
	}

	kbuf[len] = '\0';
	rc = sscanf(kbuf, "%d %d %d %d %d %d",
		    &led_blink_time[WIL_LED_TIME_SLOW].on_ms,
		    &led_blink_time[WIL_LED_TIME_SLOW].off_ms,
		    &led_blink_time[WIL_LED_TIME_MED].on_ms,
		    &led_blink_time[WIL_LED_TIME_MED].off_ms,
		    &led_blink_time[WIL_LED_TIME_FAST].on_ms,
		    &led_blink_time[WIL_LED_TIME_FAST].off_ms);
	kfree(kbuf);

	if (rc < 0)
		return rc;
	if (rc < 6)
		return -EINVAL;

	return len;
}

static ssize_t wil_read_led_blink_time(struct file *file, char __user *user_buf,
				       size_t count, loff_t *ppos)
{
	static char text[400];

	snprintf(text, sizeof(text),
		 "To set led blink on/off time variables write:\n"
		 "<blink_on_slow> <blink_off_slow> <blink_on_med> "
		 "<blink_off_med> <blink_on_fast> <blink_off_fast>\n"
		 "The current values are:\n"
		 "%d %d %d %d %d %d\n",
		 led_blink_time[WIL_LED_TIME_SLOW].on_ms,
		 led_blink_time[WIL_LED_TIME_SLOW].off_ms,
		 led_blink_time[WIL_LED_TIME_MED].on_ms,
		 led_blink_time[WIL_LED_TIME_MED].off_ms,
		 led_blink_time[WIL_LED_TIME_FAST].on_ms,
		 led_blink_time[WIL_LED_TIME_FAST].off_ms);

	return simple_read_from_buffer(user_buf, count, ppos, text,
				       sizeof(text));
}

static const struct file_operations fops_led_blink_time = {
	.read = wil_read_led_blink_time,
	.write = wil_write_led_blink_time,
	.open  = simple_open,
};

/*----------------*/
static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
				       struct dentry *dbg)
@@ -1472,16 +1588,18 @@ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
	char name[32];

	for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
		struct debugfs_blob_wrapper *blob = &wil->blobs[i];
		struct wil_blob_wrapper *wil_blob = &wil->blobs[i];
		struct debugfs_blob_wrapper *blob = &wil_blob->blob;
		const struct fw_map *map = &fw_mapping[i];

		if (!map->name)
			continue;

		wil_blob->wil = wil;
		blob->data = (void * __force)wil->csr + HOSTADDR(map->host);
		blob->size = map->to - map->from;
		snprintf(name, sizeof(name), "blob_%s", map->name);
		wil_debugfs_create_ioblob(name, S_IRUGO, dbg, blob);
		wil_debugfs_create_ioblob(name, S_IRUGO, dbg, wil_blob);
	}
}

@@ -1510,6 +1628,8 @@ static const struct {
	{"link",	S_IRUGO,		&fops_link},
	{"info",	S_IRUGO,		&fops_info},
	{"recovery",	S_IRUGO | S_IWUSR,	&fops_recovery},
	{"led_cfg",	S_IRUGO | S_IWUSR,	&fops_led_cfg},
	{"led_blink_time",	S_IRUGO | S_IWUSR,	&fops_led_blink_time},
};

static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
@@ -1572,6 +1692,7 @@ static const struct dbg_off dbg_statics[] = {
	{"mem_addr",	S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32},
	{"vring_idle_trsh", S_IRUGO | S_IWUSR, (ulong)&vring_idle_trsh,
	 doff_u32},
	{"led_polarity", S_IRUGO | S_IWUSR, (ulong)&led_polarity, doff_u8},
	{},
};

+72 −21
Original line number Diff line number Diff line
@@ -36,14 +36,18 @@
 */

#define WIL6210_IRQ_DISABLE		(0xFFFFFFFFUL)
#define WIL6210_IRQ_DISABLE_NO_HALP	(0xF7FFFFFFUL)
#define WIL6210_IMC_RX		(BIT_DMA_EP_RX_ICR_RX_DONE | \
				 BIT_DMA_EP_RX_ICR_RX_HTRSH)
#define WIL6210_IMC_RX_NO_RX_HTRSH (WIL6210_IMC_RX & \
				    (~(BIT_DMA_EP_RX_ICR_RX_HTRSH)))
#define WIL6210_IMC_TX		(BIT_DMA_EP_TX_ICR_TX_DONE | \
				BIT_DMA_EP_TX_ICR_TX_DONE_N(0))
#define WIL6210_IMC_MISC	(ISR_MISC_FW_READY | \
#define WIL6210_IMC_MISC_NO_HALP	(ISR_MISC_FW_READY | \
					 ISR_MISC_MBOX_EVT | \
					 ISR_MISC_FW_ERROR)

#define WIL6210_IMC_MISC		(WIL6210_IMC_MISC_NO_HALP | \
					 BIT_DMA_EP_MISC_ICR_HALP)
#define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \
					BIT_DMA_PSEUDO_CAUSE_TX | \
					BIT_DMA_PSEUDO_CAUSE_MISC))
@@ -51,6 +55,7 @@
#if defined(CONFIG_WIL6210_ISR_COR)
/* configure to Clear-On-Read mode */
#define WIL_ICR_ICC_VALUE	(0xFFFFFFFFUL)
#define WIL_ICR_ICC_MISC_VALUE	(0xF7FFFFFFUL)

static inline void wil_icr_clear(u32 x, void __iomem *addr)
{
@@ -58,6 +63,7 @@ static inline void wil_icr_clear(u32 x, void __iomem *addr)
#else /* defined(CONFIG_WIL6210_ISR_COR) */
/* configure to Write-1-to-Clear mode */
#define WIL_ICR_ICC_VALUE	(0UL)
#define WIL_ICR_ICC_MISC_VALUE	(0UL)

static inline void wil_icr_clear(u32 x, void __iomem *addr)
{
@@ -86,10 +92,21 @@ static void wil6210_mask_irq_rx(struct wil6210_priv *wil)
	      WIL6210_IRQ_DISABLE);
}

static void wil6210_mask_irq_misc(struct wil6210_priv *wil)
static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp)
{
	wil_dbg_irq(wil, "%s: mask_halp(%s)\n", __func__,
		    mask_halp ? "true" : "false");

	wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS),
	      WIL6210_IRQ_DISABLE);
	      mask_halp ? WIL6210_IRQ_DISABLE : WIL6210_IRQ_DISABLE_NO_HALP);
}

static void wil6210_mask_halp(struct wil6210_priv *wil)
{
	wil_dbg_irq(wil, "%s()\n", __func__);

	wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS),
	      BIT_DMA_EP_MISC_ICR_HALP);
}

static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
@@ -109,14 +126,27 @@ void wil6210_unmask_irq_tx(struct wil6210_priv *wil)

void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
{
	bool unmask_rx_htrsh = test_bit(wil_status_fwconnected, wil->status);

	wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMC),
	      WIL6210_IMC_RX);
	      unmask_rx_htrsh ? WIL6210_IMC_RX : WIL6210_IMC_RX_NO_RX_HTRSH);
}

static void wil6210_unmask_irq_misc(struct wil6210_priv *wil)
static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp)
{
	wil_dbg_irq(wil, "%s: unmask_halp(%s)\n", __func__,
		    unmask_halp ? "true" : "false");

	wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC),
	      WIL6210_IMC_MISC);
	      unmask_halp ? WIL6210_IMC_MISC : WIL6210_IMC_MISC_NO_HALP);
}

static void wil6210_unmask_halp(struct wil6210_priv *wil)
{
	wil_dbg_irq(wil, "%s()\n", __func__);

	wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC),
	      BIT_DMA_EP_MISC_ICR_HALP);
}

static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
@@ -134,7 +164,7 @@ void wil_mask_irq(struct wil6210_priv *wil)

	wil6210_mask_irq_tx(wil);
	wil6210_mask_irq_rx(wil);
	wil6210_mask_irq_misc(wil);
	wil6210_mask_irq_misc(wil, true);
	wil6210_mask_irq_pseudo(wil);
}

@@ -147,12 +177,12 @@ void wil_unmask_irq(struct wil6210_priv *wil)
	wil_w(wil, RGF_DMA_EP_TX_ICR + offsetof(struct RGF_ICR, ICC),
	      WIL_ICR_ICC_VALUE);
	wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICC),
	      WIL_ICR_ICC_VALUE);
	      WIL_ICR_ICC_MISC_VALUE);

	wil6210_unmask_irq_pseudo(wil);
	wil6210_unmask_irq_tx(wil);
	wil6210_unmask_irq_rx(wil);
	wil6210_unmask_irq_misc(wil);
	wil6210_unmask_irq_misc(wil, true);
}

void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
@@ -228,11 +258,8 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
	 */
	if (likely(isr & (BIT_DMA_EP_RX_ICR_RX_DONE |
			  BIT_DMA_EP_RX_ICR_RX_HTRSH))) {
		wil_dbg_irq(wil, "RX done\n");

		if (unlikely(isr & BIT_DMA_EP_RX_ICR_RX_HTRSH))
			wil_err_ratelimited(wil,
					    "Received \"Rx buffer is in risk of overflow\" interrupt\n");
		wil_dbg_irq(wil, "RX done / RX_HTRSH received, ISR (0x%x)\n",
			    isr);

		isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE |
			 BIT_DMA_EP_RX_ICR_RX_HTRSH);
@@ -344,7 +371,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
		return IRQ_NONE;
	}

	wil6210_mask_irq_misc(wil);
	wil6210_mask_irq_misc(wil, false);

	if (isr & ISR_MISC_FW_ERROR) {
		u32 fw_assert_code = wil_r(wil, RGF_FW_ASSERT_CODE);
@@ -372,12 +399,19 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
		isr &= ~ISR_MISC_FW_READY;
	}

	if (isr & BIT_DMA_EP_MISC_ICR_HALP) {
		wil_dbg_irq(wil, "%s: HALP IRQ invoked\n", __func__);
		wil6210_mask_halp(wil);
		isr &= ~BIT_DMA_EP_MISC_ICR_HALP;
		complete(&wil->halp.comp);
	}

	wil->isr_misc = isr;

	if (isr) {
		return IRQ_WAKE_THREAD;
	} else {
		wil6210_unmask_irq_misc(wil);
		wil6210_unmask_irq_misc(wil, false);
		return IRQ_HANDLED;
	}
}
@@ -414,7 +448,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)

	wil->isr_misc = 0;

	wil6210_unmask_irq_misc(wil);
	wil6210_unmask_irq_misc(wil, false);

	return IRQ_HANDLED;
}
@@ -556,6 +590,23 @@ void wil6210_clear_irq(struct wil6210_priv *wil)
	wmb(); /* make sure write completed */
}

void wil6210_set_halp(struct wil6210_priv *wil)
{
	wil_dbg_misc(wil, "%s()\n", __func__);

	wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS),
	      BIT_DMA_EP_MISC_ICR_HALP);
}

void wil6210_clear_halp(struct wil6210_priv *wil)
{
	wil_dbg_misc(wil, "%s()\n", __func__);

	wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR),
	      BIT_DMA_EP_MISC_ICR_HALP);
	wil6210_unmask_halp(wil);
}

int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi)
{
	int rc;
+92 −3
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include "wmi.h"
#include "boot_loader.h"

#define WAIT_FOR_HALP_VOTE_MS 100

bool debug_fw; /* = false; */
module_param(debug_fw, bool, S_IRUGO);
MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug");
@@ -132,6 +134,14 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
		*d++ = __raw_readl(s++);
}

void wil_memcpy_fromio_halp_vote(struct wil6210_priv *wil, void *dst,
				 const volatile void __iomem *src, size_t count)
{
	wil_halp_vote(wil);
	wil_memcpy_fromio_32(dst, src, count);
	wil_halp_unvote(wil);
}

void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
			size_t count)
{
@@ -142,6 +152,15 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
		__raw_writel(*s++, d++);
}

void wil_memcpy_toio_halp_vote(struct wil6210_priv *wil,
			       volatile void __iomem *dst,
			       const void *src, size_t count)
{
	wil_halp_vote(wil);
	wil_memcpy_toio_32(dst, src, count);
	wil_halp_unvote(wil);
}

static void wil_disconnect_cid(struct wil6210_priv *wil, int cid,
			       u16 reason_code, bool from_event)
__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
@@ -194,6 +213,18 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
	memset(&sta->stats, 0, sizeof(sta->stats));
}

static bool wil_ap_is_connected(struct wil6210_priv *wil)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
		if (wil->sta[i].status == wil_sta_connected)
			return true;
	}

	return false;
}

static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
				u16 reason_code, bool from_event)
{
@@ -247,6 +278,11 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
		}
		clear_bit(wil_status_fwconnecting, wil->status);
		break;
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_P2P_GO:
		if (!wil_ap_is_connected(wil))
			clear_bit(wil_status_fwconnected, wil->status);
		break;
	default:
		break;
	}
@@ -457,9 +493,11 @@ int wil_priv_init(struct wil6210_priv *wil)
	mutex_init(&wil->wmi_mutex);
	mutex_init(&wil->probe_client_mutex);
	mutex_init(&wil->p2p_wdev_mutex);
	mutex_init(&wil->halp.lock);

	init_completion(&wil->wmi_ready);
	init_completion(&wil->wmi_call);
	init_completion(&wil->halp.comp);

	wil->bcast_vring = -1;
	setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
@@ -555,12 +593,11 @@ static inline void wil_release_cpu(struct wil6210_priv *wil)
static void wil_set_oob_mode(struct wil6210_priv *wil, bool enable)
{
	wil_info(wil, "%s: enable=%d\n", __func__, enable);
	if (enable) {
	if (enable)
		wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
	} else {
	else
		wil_c(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
}
}

static int wil_target_reset(struct wil6210_priv *wil)
{
@@ -804,6 +841,9 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
	wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
	wil_bcast_fini(wil);

	/* Disable device led before reset*/
	wmi_led_cfg(wil, false);

	/* prevent NAPI from being scheduled and prevent wmi commands */
	mutex_lock(&wil->wmi_mutex);
	bitmap_zero(wil->status, wil_status_last);
@@ -871,6 +911,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
	wil->ap_isolate = 0;
	reinit_completion(&wil->wmi_ready);
	reinit_completion(&wil->wmi_call);
	reinit_completion(&wil->halp.comp);

	if (load_fw) {
		wil_configure_interrupt_moderation(wil);
@@ -1061,3 +1102,51 @@ int wil_find_cid(struct wil6210_priv *wil, const u8 *mac)

	return rc;
}

void wil_halp_vote(struct wil6210_priv *wil)
{
	unsigned long rc;
	unsigned long to_jiffies = msecs_to_jiffies(WAIT_FOR_HALP_VOTE_MS);

	mutex_lock(&wil->halp.lock);

	wil_dbg_misc(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
		     wil->halp.ref_cnt);

	if (++wil->halp.ref_cnt == 1) {
		wil6210_set_halp(wil);
		rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
		if (!rc)
			wil_err(wil, "%s: HALP vote timed out\n", __func__);
		else
			wil_dbg_misc(wil,
				     "%s: HALP vote completed after %d ms\n",
				     __func__,
				     jiffies_to_msecs(to_jiffies - rc));
	}

	wil_dbg_misc(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
		     wil->halp.ref_cnt);

	mutex_unlock(&wil->halp.lock);
}

void wil_halp_unvote(struct wil6210_priv *wil)
{
	WARN_ON(wil->halp.ref_cnt == 0);

	mutex_lock(&wil->halp.lock);

	wil_dbg_misc(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
		     wil->halp.ref_cnt);

	if (--wil->halp.ref_cnt == 0) {
		wil6210_clear_halp(wil);
		wil_dbg_misc(wil, "%s: HALP unvote\n", __func__);
	}

	wil_dbg_misc(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
		     wil->halp.ref_cnt);

	mutex_unlock(&wil->halp.lock);
}
Loading