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

Commit cbba912b authored by Hamad Kadmany's avatar Hamad Kadmany
Browse files

wil6210: Handle set WPS-P2P IE ioctl



hostap in Android issues private ioctls in some scenarios,
specifically P2P and WPS.

Currently 11ad driver supports WPS but not P2P, when WPS
is enabled IE related to WPS in P2P is sent through
private ioctl and fails which blocks WPS.

Add handling of this command so that WPS could be
enabled outside of P2P flow.

Change-Id: Id67174ad128b47a6b6244b1fe48b0e535b397247
Signed-off-by: default avatarHamad Kadmany <hkadmany@codeaurora.org>
parent 32829884
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -24,6 +24,14 @@
			     DUMP_PREFIX_OFFSET, 16, 1, buf, len, true)
#define wil_dbg_ioctl(wil, fmt, arg...) wil_dbg(wil, "DBG[IOC ]" fmt, ##arg)

#define WIL_PRIV_DATA_MAX_LEN	8192
#define CMD_SET_AP_WPS_P2P_IE	"SET_AP_WPS_P2P_IE"

struct wil_android_priv_data {
	char *buf;
	int used_len;
	int total_len;
};
static void __iomem *wil_ioc_addr(struct wil6210_priv *wil, uint32_t addr,
				  uint32_t size, enum wil_memio_op op)
{
@@ -159,6 +167,52 @@ out_free:
	return rc;
}

static int wil_ioc_android(struct wil6210_priv *wil, void __user *data)
{
	int rc = 0;
	char *command;
	struct wil_android_priv_data priv_data;

	wil_dbg_ioctl(wil, "%s()\n", __func__);

	if (copy_from_user(&priv_data, data, sizeof(priv_data)))
		return -EFAULT;

	if (priv_data.total_len <= 0 ||
	    priv_data.total_len >= WIL_PRIV_DATA_MAX_LEN) {
		wil_err(wil, "%s: invalid data len %d\n",
			__func__, priv_data.total_len);
		return -EINVAL;
	}

	command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
	if (!command)
		return -ENOMEM;

	if (copy_from_user(command, priv_data.buf, priv_data.total_len)) {
		rc = -EFAULT;
		goto out_free;
	}

	/* Make sure the command is NUL-terminated */
	command[priv_data.total_len] = '\0';

	wil_dbg_ioctl(wil, "%s(command = %s)\n", __func__, command);

	/* P2P not supported, but WPS is (in AP mode).
	 * Ignore those in order not to block WPS functionality
	 * in non-P2P mode.
	 */
	if (strncasecmp(command, CMD_SET_AP_WPS_P2P_IE,
			strlen(CMD_SET_AP_WPS_P2P_IE)) == 0)
		rc = 0;
	else
		rc = -ENOIOCTLCMD;

out_free:
	kfree(command);
	return rc;
}
int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd)
{
	switch (cmd) {
@@ -166,6 +220,8 @@ int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd)
		return wil_ioc_memio_dword(wil, data);
	case WIL_IOCTL_MEMIO_BLOCK:
		return wil_ioc_memio_block(wil, data);
	case (SIOCDEVPRIVATE + 1):
		return wil_ioc_android(wil, data);
	default:
		wil_dbg_ioctl(wil, "Unsupported IOCTL 0x%04x\n", cmd);
		return -ENOIOCTLCMD;