usb: gadget: Add network gadget driver for dun and rmnet
This gadget driver works as independent data and control pass
through between modem device connected over USB or HSIC
and host/laptop.This driver communicates with modem device
using network bridge host driver.
Change-Id: Iaffdeaa6b5dbd601b73cba721a8f062d69912908
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Jack Pham <jackp@codeaurora.org>
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index 2c6a31c..32791d9 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -64,7 +64,9 @@
#define NR_RMNET_PORTS 1
static unsigned int nr_rmnet_ports;
static unsigned int no_ctrl_smd_ports;
+static unsigned int no_ctrl_hsic_ports;
static unsigned int no_data_bam_ports;
+static unsigned int no_data_hsic_ports;
static struct rmnet_ports {
enum transport_type data_xport;
enum transport_type ctrl_xport;
@@ -235,11 +237,14 @@
static int rmnet_gport_setup(void)
{
- int ret;
+ int ret;
+ int port_idx;
+ int i;
- pr_debug("%s: bam ports: %u smd ports: %u nr_rmnet_ports: %u\n",
- __func__, no_data_bam_ports, no_ctrl_smd_ports,
- nr_rmnet_ports);
+ pr_debug("%s: bam ports: %u data hsic ports: %u smd ports: %u"
+ " ctrl hsic ports: %u nr_rmnet_ports: %u\n",
+ __func__, no_data_bam_ports, no_data_hsic_ports,
+ no_ctrl_smd_ports, no_ctrl_hsic_ports, nr_rmnet_ports);
if (no_data_bam_ports) {
ret = gbam_setup(no_data_bam_ports);
@@ -253,6 +258,34 @@
return ret;
}
+ if (no_data_hsic_ports) {
+ port_idx = ghsic_data_setup(no_data_hsic_ports,
+ USB_GADGET_RMNET);
+ if (port_idx < 0)
+ return port_idx;
+ for (i = 0; i < nr_rmnet_ports; i++) {
+ if (rmnet_ports[i].data_xport ==
+ USB_GADGET_XPORT_HSIC) {
+ rmnet_ports[i].data_xport_num = port_idx;
+ port_idx++;
+ }
+ }
+ }
+
+ if (no_ctrl_hsic_ports) {
+ port_idx = ghsic_ctrl_setup(no_ctrl_hsic_ports,
+ USB_GADGET_RMNET);
+ if (port_idx < 0)
+ return port_idx;
+ for (i = 0; i < nr_rmnet_ports; i++) {
+ if (rmnet_ports[i].ctrl_xport ==
+ USB_GADGET_XPORT_HSIC) {
+ rmnet_ports[i].ctrl_xport_num = port_idx;
+ port_idx++;
+ }
+ }
+ }
+
return 0;
}
@@ -277,6 +310,14 @@
return ret;
}
break;
+ case USB_GADGET_XPORT_HSIC:
+ ret = ghsic_ctrl_connect(&dev->port, port_num);
+ if (ret) {
+ pr_err("%s: ghsic_ctrl_connect failed: err:%d\n",
+ __func__, ret);
+ return ret;
+ }
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
@@ -296,6 +337,15 @@
return ret;
}
break;
+ case USB_GADGET_XPORT_HSIC:
+ ret = ghsic_data_connect(&dev->port, port_num);
+ if (ret) {
+ pr_err("%s: ghsic_data_connect failed: err:%d\n",
+ __func__, ret);
+ ghsic_ctrl_disconnect(&dev->port, port_num);
+ return ret;
+ }
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
@@ -322,6 +372,9 @@
case USB_GADGET_XPORT_SMD:
gsmd_ctrl_disconnect(&dev->port, port_num);
break;
+ case USB_GADGET_XPORT_HSIC:
+ ghsic_ctrl_disconnect(&dev->port, port_num);
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
@@ -335,6 +388,9 @@
case USB_GADGET_XPORT_BAM:
gbam_disconnect(&dev->port, port_num);
break;
+ case USB_GADGET_XPORT_HSIC:
+ ghsic_data_disconnect(&dev->port, port_num);
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
@@ -898,6 +954,8 @@
nr_rmnet_ports = 0;
no_ctrl_smd_ports = 0;
no_data_bam_ports = 0;
+ no_ctrl_hsic_ports = 0;
+ no_data_hsic_ports = 0;
}
static int frmnet_init_port(const char *ctrl_name, const char *data_name)
@@ -937,6 +995,10 @@
rmnet_port->ctrl_xport_num = no_ctrl_smd_ports;
no_ctrl_smd_ports++;
break;
+ case USB_GADGET_XPORT_HSIC:
+ rmnet_port->ctrl_xport_num = no_ctrl_hsic_ports;
+ no_ctrl_hsic_ports++;
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
@@ -951,6 +1013,10 @@
rmnet_port->data_xport_num = no_data_bam_ports;
no_data_bam_ports++;
break;
+ case USB_GADGET_XPORT_HSIC:
+ rmnet_port->data_xport_num = no_data_hsic_ports;
+ no_data_hsic_ports++;
+ break;
case USB_GADGET_XPORT_NONE:
break;
default:
@@ -970,6 +1036,8 @@
nr_rmnet_ports = 0;
no_ctrl_smd_ports = 0;
no_data_bam_ports = 0;
+ no_ctrl_hsic_ports = 0;
+ no_data_hsic_ports = 0;
return ret;
}