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

Commit 33409396 authored by Bar Weiner's avatar Bar Weiner
Browse files

usb: mbim: Add port mapper support for MBIM



Adding IOCTL call to be used by QBI. This new call
queries the required information for configuring port
mapper.

Change-Id: Iedfc9d7b5db287ddf8d5864f11aca16180b0aa8a
Signed-off-by: default avatarDanny Segal <dsegal@codeaurora.org>
Signed-off-by: default avatarDov Levenglick <dovl@codeaurora.org>
Signed-off-by: default avatarBar Weiner <bweiner@codeaurora.org>
parent a525e5d0
Loading
Loading
Loading
Loading
+68 −3
Original line number Diff line number Diff line
@@ -34,10 +34,37 @@

#define MBIM_BULK_BUFFER_SIZE		4096


enum mbim_peripheral_ep_type {
	MBIM_DATA_EP_TYPE_RESERVED   = 0x0,
	MBIM_DATA_EP_TYPE_HSIC       = 0x1,
	MBIM_DATA_EP_TYPE_HSUSB      = 0x2,
	MBIM_DATA_EP_TYPE_PCIE       = 0x3,
	MBIM_DATA_EP_TYPE_EMBEDDED   = 0x4,
};

struct mbim_peripheral_ep_info {
	enum peripheral_ep_type	ep_type;
	u32  peripheral_iface_id;
};

struct mbim_ipa_ep_pair {
	u32 cons_pipe_num;
	u32 prod_pipe_num;
};

struct mbim_ipa_ep_info {
	struct mbim_peripheral_ep_info ph_ep_info;
	struct mbim_ipa_ep_pair        ipa_ep_pair;
};

#define MBIM_IOCTL_MAGIC	 'o'
#define MBIM_GET_NTB_SIZE	 _IOR(MBIM_IOCTL_MAGIC, 2, u32)
#define MBIM_GET_DATAGRAM_COUNT	 _IOR(MBIM_IOCTL_MAGIC, 3, u16)

#define MBIM_EP_LOOKUP	_IOR(MBIM_IOCTL_MAGIC, 4, struct mbim_ipa_ep_info)


#define NR_MBIM_PORTS			1

/* ID for Microsoft OS String */
@@ -1885,10 +1912,17 @@ static int mbim_release(struct inode *ip, struct file *fp)
static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
{
	struct f_mbim *mbim = fp->private_data;
	struct data_port *port;
	struct mbim_ipa_ep_info info;
	int ret = 0;

	pr_debug("Received command %d", cmd);

	if (!mbim) {
		pr_err("Bad parameter");
		return -EINVAL;
	}

	if (mbim_lock(&mbim->ioctl_excl))
		return -EBUSY;

@@ -1913,6 +1947,34 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
		pr_info("Sent NTB datagrams count %d",
			mbim->ntb_max_datagrams);
		break;

	case MBIM_EP_LOOKUP:
		if (!atomic_read(&mbim->online)) {
			pr_warn("usb cable is not connected\n");
			return -ENOTCONN;
		}

		port = &mbim->bam_port;
		if ((port->ipa_producer_ep == -1) ||
			(port->ipa_consumer_ep == -1)) {
			pr_err("EP_LOOKUP failed - IPA pipes were not updated");
			ret = -EAGAIN;
			break;
		}

		info.ph_ep_info.ep_type = MBIM_DATA_EP_TYPE_HSUSB;
		info.ph_ep_info.peripheral_iface_id = mbim->data_id;
		info.ipa_ep_pair.cons_pipe_num = port->ipa_consumer_ep;
		info.ipa_ep_pair.prod_pipe_num = port->ipa_producer_ep;

		ret = copy_to_user((void __user *)arg, &info,
			sizeof(info));
		if (ret) {
			pr_err("copying to user space failed");
			ret = -EFAULT;
		}
		break;

	default:
		pr_err("wrong parameter");
		ret = -EINVAL;
@@ -1961,6 +2023,9 @@ static int mbim_init(int instances)
		}

		dev->port_num = i;
		dev->bam_port.ipa_consumer_ep = -1;
		dev->bam_port.ipa_producer_ep = -1;

		spin_lock_init(&dev->lock);
		INIT_LIST_HEAD(&dev->cpkt_req_q);
		INIT_LIST_HEAD(&dev->cpkt_resp_q);
+18 −9
Original line number Diff line number Diff line
@@ -295,6 +295,10 @@ static void bam2bam_data_connect_work(struct work_struct *w)
				__func__, ret);
			return;
		}

		d_port->ipa_consumer_ep = d->ipa_params.ipa_cons_ep_idx;
		d_port->ipa_producer_ep = d->ipa_params.ipa_prod_ep_idx;

		if (gadget_is_dwc3(gadget)) {
			u8 idx;

@@ -555,8 +559,13 @@ void bam_data_disconnect(struct data_port *gr, u8 port_num)
		return;
	}

	if (port->port_usb && port->port_usb->in &&
	  port->port_usb->in->driver_data) {
	d = &port->data_ch;
	if (port->port_usb) {
		if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
			port->port_usb->ipa_consumer_ep = -1;
			port->port_usb->ipa_producer_ep = -1;
		}
		if (port->port_usb->in && port->port_usb->in->driver_data) {
			/* disable endpoints */
			usb_ep_disable(port->port_usb->out);
			usb_ep_disable(port->port_usb->in);
@@ -564,10 +573,10 @@ void bam_data_disconnect(struct data_port *gr, u8 port_num)
			port->port_usb->in->driver_data = NULL;
			port->port_usb->out->driver_data = NULL;

		port->port_usb = 0;
			port->port_usb = NULL;
		}
	}

	d = &port->data_ch;
	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		queue_work(bam_data_wq, &port->disconnect_w);
	} else {
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -26,6 +26,8 @@ struct data_port {
	struct usb_function		*func;
	struct usb_ep			*in;
	struct usb_ep			*out;
	int                             ipa_consumer_ep;
	int                             ipa_producer_ep;
};

void bam_data_disconnect(struct data_port *gr, u8 port_num);