usb: gadget: Implement ECM over IPA

Add bam transport parameter for u_bam_data interface to
support two types of data transfer - over bam2bam and over ipa.
Add required calls for ecm_ipa driver which will handle the
transfer of data over IPA.

Change-Id: I3fd73b159676f5475c527bf52208533e65dddb1d
Signed-off-by: Anna Perel <aperel@codeaurora.org>
Signed-off-by: Amit Blay <ablay@codeaurora.org>
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 8e25780..9dd9c40 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -76,10 +76,10 @@
 #define USB_ETH_RNDIS y
 #include "f_rndis.c"
 #include "rndis.c"
+#include "f_qc_ecm.c"
 #include "u_bam_data.c"
 #include "f_mbim.c"
 #include "f_ecm.c"
-#include "f_qc_ecm.c"
 #include "f_qc_rndis.c"
 #include "u_ether.c"
 #include "u_qc_ether.c"
@@ -655,6 +655,9 @@
 	.attributes	= rmnet_function_attributes,
 };
 
+/* ecm transport string */
+static char ecm_transports[MAX_XPORT_STR_LEN];
+
 struct ecm_function_config {
 	u8      ethaddr[ETH_ALEN];
 };
@@ -678,6 +681,7 @@
 					struct usb_configuration *c)
 {
 	int ret;
+	char *trans;
 	struct ecm_function_config *ecm = f->config;
 
 	if (!ecm) {
@@ -689,19 +693,28 @@
 		ecm->ethaddr[0], ecm->ethaddr[1], ecm->ethaddr[2],
 		ecm->ethaddr[3], ecm->ethaddr[4], ecm->ethaddr[5]);
 
-	ret = gether_qc_setup_name(c->cdev->gadget, ecm->ethaddr, "ecm");
-	if (ret) {
-		pr_err("%s: gether_setup failed\n", __func__);
-		return ret;
+	pr_debug("%s: ecm_transport is %s", __func__, ecm_transports);
+
+	trans = strim(ecm_transports);
+	if (strcmp("BAM2BAM_IPA", trans)) {
+		ret = gether_qc_setup_name(c->cdev->gadget,
+						ecm->ethaddr, "ecm");
+		if (ret) {
+			pr_err("%s: gether_setup failed\n", __func__);
+			return ret;
+		}
 	}
 
-	return ecm_qc_bind_config(c, ecm->ethaddr);
+	return ecm_qc_bind_config(c, ecm->ethaddr, trans);
 }
 
 static void ecm_qc_function_unbind_config(struct android_usb_function *f,
 						struct usb_configuration *c)
 {
-	gether_qc_cleanup_name("ecm0");
+	char *trans = strim(ecm_transports);
+
+	if (strcmp("BAM2BAM_IPA", trans))
+		gether_qc_cleanup_name("ecm0");
 }
 
 static ssize_t ecm_ethaddr_show(struct device *dev,
@@ -731,7 +744,24 @@
 static DEVICE_ATTR(ecm_ethaddr, S_IRUGO | S_IWUSR, ecm_ethaddr_show,
 					       ecm_ethaddr_store);
 
+static ssize_t ecm_transports_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", ecm_transports);
+}
+
+static ssize_t ecm_transports_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	strlcpy(ecm_transports, buf, sizeof(ecm_transports));
+	return size;
+}
+
+static DEVICE_ATTR(ecm_transports, S_IRUGO | S_IWUSR, ecm_transports_show,
+					       ecm_transports_store);
+
 static struct device_attribute *ecm_function_attributes[] = {
+	&dev_attr_ecm_transports,
 	&dev_attr_ecm_ethaddr,
 	NULL
 };