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

Commit a6bf0f28 authored by Maya Erez's avatar Maya Erez
Browse files

usb: gadget: rndis: Extend rndis to support IPA on BAM mode



Add support for RNDIS in BAM to BAM mode to allow HW
acceleration of the data path.

Change-Id: If141840f992c40160f101fa7dc2f358c67cd6c55
Signed-off-by: default avatarShimrit Malichi <smalichi@codeaurora.org>
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent f71b1f08
Loading
Loading
Loading
Loading
+35 −7
Original line number Diff line number Diff line
@@ -64,9 +64,9 @@
#include "rndis.c"
#include "f_qc_ecm.c"
#include "f_mbim.c"
#include "f_qc_rndis.c"
#include "u_bam_data.c"
#include "f_ecm.c"
#include "f_qc_rndis.c"
#include "u_ether.c"
#include "u_qc_ether.c"
#ifdef CONFIG_TARGET_CORE
@@ -1649,6 +1649,8 @@ static struct android_usb_function ptp_function = {
	.bind_config	= ptp_function_bind_config,
};

/* rndis transport string */
static char rndis_transports[MAX_XPORT_STR_LEN];

struct rndis_function_config {
	u8      ethaddr[ETH_ALEN];
@@ -1741,6 +1743,7 @@ static int rndis_qc_function_bind_config(struct android_usb_function *f,
					struct usb_configuration *c)
{
	int ret;
	char *trans;
	struct rndis_function_config *rndis = f->config;

	if (!rndis) {
@@ -1752,11 +1755,17 @@ static int rndis_qc_function_bind_config(struct android_usb_function *f,
		rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
		rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);

	ret = gether_qc_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
	pr_debug("%s: rndis_transport is %s", __func__, rndis_transports);

	trans = strim(rndis_transports);
	if (strcmp("BAM2BAM_IPA", trans)) {
		ret = gether_qc_setup_name(c->cdev->gadget,
					rndis->ethaddr, "rndis");
		if (ret) {
			pr_err("%s: gether_setup failed\n", __func__);
			return ret;
		}
	}

	if (rndis->wceis) {
		/* "Wireless" RNDIS; auto-detected by Windows */
@@ -1772,7 +1781,7 @@ static int rndis_qc_function_bind_config(struct android_usb_function *f,

	return rndis_qc_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
				    rndis->manufacturer,
					rndis->max_pkt_per_xfer);
					rndis->max_pkt_per_xfer, trans);
}

static void rndis_function_unbind_config(struct android_usb_function *f,
@@ -1785,6 +1794,9 @@ static void rndis_function_unbind_config(struct android_usb_function *f,
static void rndis_qc_function_unbind_config(struct android_usb_function *f,
						struct usb_configuration *c)
{
	char *trans = strim(rndis_transports);

	if (strcmp("BAM2BAM_IPA", trans))
		gether_qc_cleanup_name("rndis0");
}

@@ -1919,6 +1931,21 @@ static ssize_t rndis_max_pkt_per_xfer_store(struct device *dev,
static DEVICE_ATTR(max_pkt_per_xfer, S_IRUGO | S_IWUSR,
				   rndis_max_pkt_per_xfer_show,
				   rndis_max_pkt_per_xfer_store);
static ssize_t rndis_transports_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%s\n", rndis_transports);
}

static ssize_t rndis_transports_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	strlcpy(rndis_transports, buf, sizeof(rndis_transports));
	return size;
}

static DEVICE_ATTR(rndis_transports, S_IRUGO | S_IWUSR, rndis_transports_show,
					       rndis_transports_store);

static ssize_t rndis_rx_trigger_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
@@ -1941,6 +1968,7 @@ static struct device_attribute *rndis_function_attributes[] = {
	&dev_attr_ethaddr,
	&dev_attr_vendorID,
	&dev_attr_max_pkt_per_xfer,
	&dev_attr_rndis_transports,
	&dev_attr_rx_trigger,
	NULL
};
+104 −16
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@
#include "u_ether.h"
#include "u_qc_ether.h"
#include "rndis.h"

#include "u_bam_data.h"
#include <mach/rndis_ipa.h>

/*
 * This function is an RNDIS Ethernet port -- a Microsoft protocol that's
@@ -95,8 +96,13 @@ struct f_rndis_qc {
	struct usb_request		*notify_req;
	atomic_t			notify_count;
	struct data_port		bam_port;
	enum transport_type		xport;
};

static struct ipa_usb_init_params rndis_ipa_params;
static bool rndis_ipa_supported;
static void rndis_qc_open(struct qc_gether *geth);

static inline struct f_rndis_qc *func_to_rndis_qc(struct usb_function *f)
{
	return container_of(f, struct f_rndis_qc, port.func);
@@ -424,6 +430,8 @@ static int rndis_qc_bam_connect(struct f_rndis_qc *dev)
	u8 src_connection_idx, dst_connection_idx;
	struct usb_composite_dev *cdev = dev->port.func.config->cdev;
	struct usb_gadget *gadget = cdev->gadget;
	enum peer_bam peer_bam = (dev->xport == USB_GADGET_XPORT_BAM2BAM_IPA) ?
		IPA_P_BAM : A2_P_BAM;

	dev->bam_port.cdev = cdev;
	dev->bam_port.func = &dev->port.func;
@@ -431,16 +439,24 @@ static int rndis_qc_bam_connect(struct f_rndis_qc *dev)
	dev->bam_port.out = dev->port.out_ep;

	/* currently we use the first connection */
	src_connection_idx = usb_bam_get_connection_idx(gadget->name, A2_P_BAM,
	src_connection_idx = usb_bam_get_connection_idx(gadget->name, peer_bam,
		USB_TO_PEER_PERIPHERAL, 0);
	dst_connection_idx = usb_bam_get_connection_idx(gadget->name, A2_P_BAM,
	dst_connection_idx = usb_bam_get_connection_idx(gadget->name, peer_bam,
		PEER_PERIPHERAL_TO_USB, 0);
	if (src_connection_idx < 0 || dst_connection_idx < 0) {
		pr_err("%s: usb_bam_get_connection_idx failed\n", __func__);
		return ret;
	}
	ret = bam_data_connect(&dev->bam_port, 0, USB_GADGET_XPORT_BAM2BAM,
		src_connection_idx, dst_connection_idx, USB_FUNC_RNDIS);
	if (peer_bam == A2_P_BAM)
		ret = bam_data_connect(&dev->bam_port, 0,
			USB_GADGET_XPORT_BAM2BAM, src_connection_idx,
			dst_connection_idx, USB_FUNC_RNDIS);
	else {
		ret = bam_data_connect(&dev->bam_port, 0,
			USB_GADGET_XPORT_BAM2BAM_IPA, src_connection_idx,
			dst_connection_idx, USB_FUNC_RNDIS);
		rndis_qc_open(&dev->port);
	}
	if (ret) {
		pr_err("bam_data_connect failed: err:%d\n",
				ret);
@@ -586,6 +602,7 @@ static void rndis_qc_command_complete(struct usb_ep *ep,
	if (buf->MessageType == RNDIS_MSG_INIT) {
		rndis->max_pkt_size = buf->MaxTransferSize;
		pr_debug("MaxTransferSize: %d\n", buf->MaxTransferSize);
		u_bam_data_set_max_xfer_size(rndis->max_pkt_size);
	}
}

@@ -694,7 +711,10 @@ static int rndis_qc_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
			 * we can disconnect the port from the network layer.
			 */
			rndis_qc_bam_disconnect(rndis);
			gether_qc_disconnect_name(&rndis->port, "rndis0");

			if (rndis->xport != USB_GADGET_XPORT_BAM2BAM_IPA)
				gether_qc_disconnect_name(&rndis->port,
					"rndis0");
		}

		if (!rndis->port.in_ep->desc || !rndis->port.out_ep->desc) {
@@ -708,6 +728,16 @@ static int rndis_qc_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
				goto fail;
			}
		}
		if (rndis->xport == USB_GADGET_XPORT_BAM2BAM_IPA &&
			gadget_is_dwc3(cdev->gadget)) {
				if (msm_ep_config(rndis->port.in_ep) ||
					msm_ep_config(rndis->port.out_ep)) {
					pr_err("%s: ep_config failed\n",
						__func__);
					goto fail;
				}
		} else
			pr_debug("RNDIS is being used with non DWC3 core\n");

		/* Avoid ZLPs; they can be troublesome. */
		rndis->port.is_zlp_ok = false;
@@ -730,7 +760,11 @@ static int rndis_qc_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
			goto fail;

		DBG(cdev, "RNDIS RX/TX early activation ...\n");
		net = gether_qc_connect_name(&rndis->port, "rndis0", false);
		if (rndis->xport != USB_GADGET_XPORT_BAM2BAM_IPA)
			net = gether_qc_connect_name(&rndis->port, "rndis0",
				false);
		else
			net = gether_qc_get_net("rndis0");
		if (IS_ERR(net))
			return PTR_ERR(net);

@@ -755,7 +789,10 @@ static void rndis_qc_disable(struct usb_function *f)

	rndis_uninit(rndis->config);
	rndis_qc_bam_disconnect(rndis);
	if (rndis->xport != USB_GADGET_XPORT_BAM2BAM_IPA)
		gether_qc_disconnect_name(&rndis->port, "rndis0");
	else
		rndis_ipa_supported = false;

	usb_ep_disable(rndis->notify);
	rndis->notify->driver_data = NULL;
@@ -923,7 +960,8 @@ rndis_qc_bind(struct usb_configuration *c, struct usb_function *f)
	rndis_set_param_medium(rndis->config, RNDIS_MEDIUM_802_3, 0);
	rndis_set_host_mac(rndis->config, rndis->ethaddr);

	if (rndis_set_param_vendor(rndis->config, rndis->vendorID,
	if (rndis->manufacturer && rndis->vendorID &&
		rndis_set_param_vendor(rndis->config, rndis->vendorID,
			rndis->manufacturer))
		goto fail;

@@ -989,9 +1027,19 @@ rndis_qc_unbind(struct usb_configuration *c, struct usb_function *f)
	kfree(rndis->notify_req->buf);
	usb_ep_free_request(rndis->notify, rndis->notify_req);

	if (rndis->xport == USB_GADGET_XPORT_BAM2BAM_IPA) {
		rndis_ipa_cleanup(rndis_ipa_params.private);
		rndis_ipa_supported = false;
	}

	kfree(rndis);
}

bool is_rndis_ipa_supported(void)
{
	return rndis_ipa_supported;
}

/* Some controllers can't support RNDIS ... */
static inline bool can_support_rndis_qc(struct usb_configuration *c)
{
@@ -1014,13 +1062,13 @@ static inline bool can_support_rndis_qc(struct usb_configuration *c)
int
rndis_qc_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
{
	return rndis_qc_bind_config_vendor(c, ethaddr, 0, NULL, 1);
	return rndis_qc_bind_config_vendor(c, ethaddr, 0, NULL, 1, NULL);
}

int
rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
					 u32 vendorID, const char *manufacturer,
					 u8 max_pkt_per_xfer)
					 u8 max_pkt_per_xfer, char *xport_name)
{
	struct f_rndis_qc	*rndis;
	int		status;
@@ -1075,13 +1123,26 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
		goto fail;
	}

	rndis->xport = str_to_xport(xport_name);

	/* export host's Ethernet address in CDC format */
	if (rndis->xport == USB_GADGET_XPORT_BAM2BAM_IPA) {
		gether_qc_get_macs(rndis_ipa_params.device_ethaddr,
				rndis_ipa_params.host_ethaddr);
		pr_debug("setting host_ethaddr=%pM, device_ethaddr=%pM",
			rndis_ipa_params.host_ethaddr,
			rndis_ipa_params.device_ethaddr);
		rndis_ipa_supported = true;
	} else
		memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);

	rndis->vendorID = vendorID;
	rndis->manufacturer = manufacturer;

	/* if max_pkt_per_xfer was not configured set to default value */
	rndis->max_pkt_per_xfer =
		max_pkt_per_xfer ? max_pkt_per_xfer : DEFAULT_MAX_PKT_PER_XFER;
	u_bam_data_set_max_pkt_num(rndis->max_pkt_per_xfer);

	/* RNDIS activates when the host changes this filter */
	rndis->port.cdc_filter = 0;
@@ -1107,9 +1168,23 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
	status = usb_add_function(c, &rndis->port.func);
	if (status) {
		kfree(rndis);
		goto fail;
	}

	if (rndis->xport != USB_GADGET_XPORT_BAM2BAM_IPA)
		return status;

	status = rndis_ipa_init(&rndis_ipa_params);
	if (status) {
		pr_err("%s: failed to initialize rndis_ipa\n", __func__);
		kfree(rndis);
		goto fail;
	} else {
		pr_debug("%s: rndis_ipa successful created\n", __func__);
		return status;
	}
fail:
	rndis_exit();
	}
	return status;
}

@@ -1220,4 +1295,17 @@ static void rndis_qc_cleanup(void)
	_rndis_qc = NULL;
}

void *rndis_qc_get_ipa_rx_cb(void)
{
	return rndis_ipa_params.ipa_rx_notify;
}

void *rndis_qc_get_ipa_tx_cb(void)
{
	return rndis_ipa_params.ipa_tx_notify;
}

void *rndis_qc_get_ipa_priv(void)
{
	return rndis_ipa_params.private;
}
+16 −6
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>

#include "u_bam_data.h"

#undef	VERBOSE_DEBUG

@@ -544,14 +544,24 @@ static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len,
		 */
		retval = 0;
		if (*params->filter) {
			params->state = RNDIS_DATA_INITIALIZED;
			if (!is_rndis_ipa_supported()) {
				netif_carrier_on(params->dev);
				if (netif_running(params->dev))
					netif_wake_queue(params->dev);
			} else {
			params->state = RNDIS_INITIALIZED;
				if (params->state != RNDIS_DATA_INITIALIZED)
					u_bam_data_start_rndis_ipa();
			}
			params->state = RNDIS_DATA_INITIALIZED;
		} else {
			if (!is_rndis_ipa_supported()) {
				netif_carrier_off(params->dev);
				netif_stop_queue(params->dev);
			} else {
				if (params->state == RNDIS_DATA_INITIALIZED)
					u_bam_data_stop_rndis_ipa();
			}
			params->state = RNDIS_INITIALIZED;
		}
		break;

+1 −1
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ int rndis_signal_connect (int configNr);
int  rndis_signal_disconnect (int configNr);
int  rndis_state (int configNr);
extern void rndis_set_host_mac (int configNr, const u8 *addr);

extern bool is_rndis_ipa_supported(void);
int rndis_init(void);
void rndis_exit (void);

+161 −4
Original line number Diff line number Diff line
@@ -35,6 +35,14 @@ static int n_bam2bam_data_ports;
#define SPS_PARAMS_TBE		        BIT(6)
#define MSM_VENDOR_ID			BIT(16)

struct rndis_data_ch_info {
	u32 max_transfer_size;
	u32 max_packets_number;
	u32 prod_clnt_hdl;
	u32 cons_clnt_hdl;
	void *priv;
};

struct bam_data_ch_info {
	unsigned long		flags;
	unsigned		id;
@@ -55,6 +63,10 @@ struct bam_data_ch_info {
	struct usb_bam_connect_ipa_params	ipa_params;
};

static struct work_struct *rndis_conn_w;
static struct work_struct *rndis_disconn_w;
static bool is_ipa_rndis_net_on;

struct bam_data_port {
	unsigned			port_num;
	unsigned int                    ref_count;
@@ -66,8 +78,15 @@ struct bam_data_port {
	struct work_struct		suspend_w;
	struct work_struct		resume_w;
};
struct  usb_bam_data_connect_info {
	u32 usb_bam_pipe_idx;
	u32 peer_pipe_idx;
	u32 usb_bam_handle;
	struct sps_mem_buffer data_fifo;
};

struct bam_data_port *bam2bam_data_ports[BAM2BAM_DATA_N_PORTS];
static struct rndis_data_ch_info rndis_data;

static void bam2bam_data_suspend_work(struct work_struct *w);
static void bam2bam_data_resume_work(struct work_struct *w);
@@ -185,6 +204,12 @@ static void bam2bam_data_disconnect_work(struct work_struct *w)
	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		if (d->func_type == USB_FUNC_ECM)
			ecm_ipa_disconnect(d->ipa_params.priv);

		if (d->func_type == USB_FUNC_RNDIS) {
			rndis_ipa_pipe_disconnect_notify(d->ipa_params.priv);
			is_ipa_rndis_net_on = false;
		}

		ret = usb_bam_disconnect_ipa(&d->ipa_params);
		if (ret)
			pr_err("usb_bam_disconnect_ipa failed: err:%d\n", ret);
@@ -200,6 +225,8 @@ static void bam2bam_data_connect_work(struct work_struct *w)
						  connect_w);
	struct teth_bridge_connect_params connect_params;
	struct bam_data_ch_info *d = &port->data_ch;
	struct data_port *d_port = port->port_usb;
	struct usb_gadget *gadget = d_port->cdev->gadget;
	ipa_notify_cb usb_notify_cb;
	void *priv;
	u32 sps_params;
@@ -225,23 +252,76 @@ static void bam2bam_data_connect_work(struct work_struct *w)
			d->ipa_params.notify = ecm_qc_get_ipa_rx_cb();
			d->ipa_params.priv = ecm_qc_get_ipa_priv();
		}

		if (d->func_type == USB_FUNC_RNDIS) {
			d->ipa_params.notify = rndis_qc_get_ipa_rx_cb();
			d->ipa_params.priv = rndis_qc_get_ipa_priv();
		}

		ret = usb_bam_connect_ipa(&d->ipa_params);
		if (ret) {
			pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
				__func__, ret);
			return;
		}
		if (d->func_type == USB_FUNC_RNDIS && gadget_is_dwc3(gadget)) {
			u8 idx;
			struct usb_bam_data_connect_info bam_info;

			idx = usb_bam_get_connection_idx(gadget->name,
				IPA_P_BAM, USB_TO_PEER_PERIPHERAL, 0);
			if (idx < 0) {
				pr_err("%s: get_connection_idx failed\n",
					__func__);
				return;
			}
			get_bam2bam_connection_info(idx,
				&bam_info.usb_bam_handle,
				&bam_info.usb_bam_pipe_idx,
				&bam_info.peer_pipe_idx,
				NULL, &bam_info.data_fifo);
			msm_data_fifo_config(port->port_usb->out,
				bam_info.data_fifo.phys_base,
				bam_info.data_fifo.size,
				bam_info.usb_bam_pipe_idx);
		}

		d->ipa_params.dir = PEER_PERIPHERAL_TO_USB;
		if (d->func_type == USB_FUNC_ECM) {
			d->ipa_params.notify = ecm_qc_get_ipa_tx_cb();
			d->ipa_params.priv = ecm_qc_get_ipa_priv();
		}
		if (d->func_type == USB_FUNC_RNDIS) {
			d->ipa_params.notify = rndis_qc_get_ipa_tx_cb();
			d->ipa_params.priv = rndis_qc_get_ipa_priv();
		}
		ret = usb_bam_connect_ipa(&d->ipa_params);
		if (ret) {
			pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
				__func__, ret);
			return;
		}
		if (d->func_type == USB_FUNC_RNDIS && gadget_is_dwc3(gadget)) {
			u8 idx;
			struct usb_bam_data_connect_info bam_info;

			idx = usb_bam_get_connection_idx(gadget->name,
				IPA_P_BAM, PEER_PERIPHERAL_TO_USB, 0);
			if (idx < 0) {
				pr_err("%s: get_connection_idx failed\n",
					__func__);
				return;
			}
			get_bam2bam_connection_info(idx,
				&bam_info.usb_bam_handle,
				&bam_info.usb_bam_pipe_idx,
				&bam_info.peer_pipe_idx,
				NULL, &bam_info.data_fifo);
			msm_data_fifo_config(port->port_usb->in,
				bam_info.data_fifo.phys_base,
				bam_info.data_fifo.size,
				bam_info.usb_bam_pipe_idx);
		}

		if (d->func_type == USB_FUNC_MBIM) {
			mbim_configure_params();
@@ -270,6 +350,26 @@ static void bam2bam_data_connect_work(struct work_struct *w)
				return;
			}
		}
		if (d->func_type == USB_FUNC_RNDIS) {
			rndis_data.prod_clnt_hdl =
				d->ipa_params.prod_clnt_hdl;
			rndis_data.cons_clnt_hdl =
				d->ipa_params.cons_clnt_hdl;
			rndis_data.priv = d->ipa_params.priv;

			ret = rndis_ipa_pipe_connect_notify(
				rndis_data.cons_clnt_hdl,
				rndis_data.prod_clnt_hdl,
				rndis_data.max_transfer_size,
				rndis_data.max_packets_number,
				rndis_data.priv);
			if (ret) {
				pr_err("%s: failed to connect IPA: err:%d\n",
					__func__, ret);
				return;
			}
			is_ipa_rndis_net_on = true;
		}
	} else { /* transport type is USB_GADGET_XPORT_BAM2BAM */
		usb_bam_reset_complete();
		ret = usb_bam_connect(d->src_connection_idx, &d->src_pipe_idx);
@@ -302,8 +402,15 @@ static void bam2bam_data_connect_work(struct work_struct *w)
	d->rx_req->complete = bam_data_endless_rx_complete;
	d->rx_req->length = 0;
	d->rx_req->no_interrupt = 1;

	if (d->func_type == USB_FUNC_RNDIS && gadget_is_dwc3(gadget)) {
		sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | MSM_PRODUCER |
			d->src_pipe_idx;
		d->rx_req->length = 32*1024;
	} else
		sps_params = (SPS_PARAMS_SPS_MODE | d->src_pipe_idx |
			MSM_VENDOR_ID) & ~SPS_PARAMS_TBE;

	d->rx_req->udc_priv = sps_params;
	d->tx_req = usb_ep_alloc_request(port->port_usb->in, GFP_KERNEL);
	if (!d->tx_req)
@@ -313,8 +420,14 @@ static void bam2bam_data_connect_work(struct work_struct *w)
	d->tx_req->complete = bam_data_endless_tx_complete;
	d->tx_req->length = 0;
	d->tx_req->no_interrupt = 1;

	if (d->func_type == USB_FUNC_RNDIS && gadget_is_dwc3(gadget)) {
		sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | d->dst_pipe_idx;
		d->tx_req->length = 32*1024;
	} else
		sps_params = (SPS_PARAMS_SPS_MODE | d->dst_pipe_idx |
			MSM_VENDOR_ID) & ~SPS_PARAMS_TBE;

	d->tx_req->udc_priv = sps_params;

	/* queue in & out requests */
@@ -376,12 +489,30 @@ static int bam2bam_data_port_alloc(int portno)
	d->ipa_params.src_client = IPA_CLIENT_USB_PROD;
	d->ipa_params.dst_client = IPA_CLIENT_USB_CONS;

	rndis_disconn_w = &port->disconnect_w;

done:
	pr_debug("port:%p portno:%d\n", port, portno);

	return 0;
}

void u_bam_data_start_rndis_ipa(void)
{
	pr_debug("%s\n", __func__);

	if (!is_ipa_rndis_net_on)
		queue_work(bam_data_wq, rndis_conn_w);
}

void u_bam_data_stop_rndis_ipa(void)
{
	pr_debug("%s\n", __func__);

	if (is_ipa_rndis_net_on)
		queue_work(bam_data_wq, rndis_disconn_w);
}

void bam_data_disconnect(struct data_port *gr, u8 port_num)
{
	struct bam_data_port	*port;
@@ -483,6 +614,11 @@ int bam_data_connect(struct data_port *gr, u8 port_num,
		d->ipa_params.dst_idx = dst_connection_idx;
	}

	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA && d->func_type ==
		USB_FUNC_RNDIS) {
			rndis_conn_w = &port->connect_w;
			return 0;
	}
	queue_work(bam_data_wq, &port->connect_w);

	return 0;
@@ -650,3 +786,24 @@ static void bam2bam_data_resume_work(struct work_struct *w)
	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA)
		usb_bam_resume(&d->ipa_params);
}

void u_bam_data_set_max_xfer_size(u32 max_transfer_size)
{
	if (!max_transfer_size) {
		pr_err("%s: invalid parameters\n", __func__);
		return;
	}

	rndis_data.max_transfer_size = max_transfer_size;
}

void u_bam_data_set_max_pkt_num(u32 max_packets_number)

{
	if (!max_packets_number) {
		pr_err("%s: invalid parameters\n", __func__);
		return;
	}

	rndis_data.max_packets_number = max_packets_number;
}
Loading