summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAjay Agarwal <ajaya@codeaurora.org>2016-10-21 10:40:45 +0530
committerAjay Agarwal <ajaya@codeaurora.org>2016-11-30 21:15:21 +0530
commit52b9f4271fd006f5df246461d001ab3fece06dc1 (patch)
treea4db1f2d6dffb4bb7d76df45a32b5629551178c4
parent24d0c1f91eb2850889cb27ef6fdcadc0c8ff2834 (diff)
usb: gadget: Add RMNET support using IPA over BAM2BAM
This change adds RMNET support using IPA over BAM2BAM. Removes all different supported control and data transports and assumes BAM2BAM_IPA as default mode. Cleans up QTI Control driver to support only RMNET and DPL. Change-Id: I5b763acfb28c2f1832874af786704835314fa9c7 Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
-rw-r--r--drivers/usb/gadget/function/f_qdss.h8
-rw-r--r--drivers/usb/gadget/function/f_rmnet.c645
-rw-r--r--drivers/usb/gadget/function/u_ctrl_qti.c172
-rw-r--r--drivers/usb/gadget/function/u_data_ipa.c8
-rw-r--r--drivers/usb/gadget/function/u_data_ipa.h4
-rw-r--r--drivers/usb/gadget/function/u_rmnet.h48
6 files changed, 214 insertions, 671 deletions
diff --git a/drivers/usb/gadget/function/f_qdss.h b/drivers/usb/gadget/function/f_qdss.h
index c4af5ac839cd..e3fe8ae03775 100644
--- a/drivers/usb/gadget/function/f_qdss.h
+++ b/drivers/usb/gadget/function/f_qdss.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016, 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
@@ -21,6 +21,8 @@
#include <linux/usb/composite.h>
#include <linux/usb/usb_qdss.h>
+#include "u_rmnet.h"
+
struct usb_qdss_bam_connect_info {
u32 usb_bam_pipe_idx;
u32 peer_pipe_idx;
@@ -33,8 +35,8 @@ struct gqdss {
struct usb_ep *ctrl_out;
struct usb_ep *ctrl_in;
struct usb_ep *data;
- int (*send_encap_cmd)(u8 port_num, void *buf, size_t len);
- void (*notify_modem)(void *g, u8 port_num, int cbits);
+ int (*send_encap_cmd)(enum qti_port_type qport, void *buf, size_t len);
+ void (*notify_modem)(void *g, enum qti_port_type qport, int cbits);
};
/* struct f_qdss - USB qdss function driver private structure */
diff --git a/drivers/usb/gadget/function/f_rmnet.c b/drivers/usb/gadget/function/f_rmnet.c
index d84b55cef666..758414d6bcb5 100644
--- a/drivers/usb/gadget/function/f_rmnet.c
+++ b/drivers/usb/gadget/function/f_rmnet.c
@@ -18,15 +18,8 @@
#include <linux/spinlock.h>
#include <linux/usb_bam.h>
-#include "usb_gadget_xport.h"
-#include "u_ether.h"
#include "u_rmnet.h"
-#include "gadget_chips.h"
-
-static unsigned int rmnet_dl_max_pkt_per_xfer = 7;
-module_param(rmnet_dl_max_pkt_per_xfer, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(rmnet_dl_max_pkt_per_xfer,
- "Maximum packets per transfer for DL aggregation");
+#include "u_data_ipa.h"
#define RMNET_NOTIFY_INTERVAL 5
#define RMNET_MAX_NOTIFY_SIZE sizeof(struct usb_cdc_notification)
@@ -38,10 +31,9 @@ MODULE_PARM_DESC(rmnet_dl_max_pkt_per_xfer,
* control paths
*/
struct f_rmnet {
- struct gether gether_port;
+ struct usb_function func;
struct grmnet port;
int ifc_id;
- u8 port_num;
atomic_t online;
atomic_t ctrl_online;
struct usb_composite_dev *cdev;
@@ -53,30 +45,11 @@ struct f_rmnet {
struct usb_request *notify_req;
/* control info */
+ struct gadget_ipa_port ipa_port;
struct list_head cpkt_resp_q;
unsigned long notify_count;
unsigned long cpkts_len;
- const struct usb_endpoint_descriptor *in_ep_desc_backup;
- const struct usb_endpoint_descriptor *out_ep_desc_backup;
-};
-
-static unsigned int nr_rmnet_ports;
-static unsigned int no_ctrl_smd_ports;
-static unsigned int no_ctrl_qti_ports;
-static unsigned int no_ctrl_hsic_ports;
-static unsigned int no_ctrl_hsuart_ports;
-static unsigned int no_data_bam_ports;
-static unsigned int no_data_bam2bam_ports;
-static unsigned int no_data_hsic_ports;
-static unsigned int no_data_hsuart_ports;
-static struct rmnet_ports {
- enum transport_type data_xport;
- enum transport_type ctrl_xport;
- unsigned data_xport_num;
- unsigned ctrl_xport_num;
- unsigned port_num;
- struct f_rmnet *port;
-} rmnet_ports[NR_RMNET_PORTS];
+} rmnet_port;
static struct usb_interface_descriptor rmnet_interface_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
@@ -244,7 +217,7 @@ static void frmnet_ctrl_response_available(struct f_rmnet *dev);
static inline struct f_rmnet *func_to_rmnet(struct usb_function *f)
{
- return container_of(f, struct f_rmnet, gether_port.func);
+ return container_of(f, struct f_rmnet, func);
}
static inline struct f_rmnet *port_to_rmnet(struct grmnet *r)
@@ -253,8 +226,7 @@ static inline struct f_rmnet *port_to_rmnet(struct grmnet *r)
}
static struct usb_request *
-frmnet_alloc_req(struct usb_ep *ep, unsigned len, size_t extra_buf_alloc,
- gfp_t flags)
+frmnet_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags)
{
struct usb_request *req;
@@ -262,7 +234,7 @@ frmnet_alloc_req(struct usb_ep *ep, unsigned len, size_t extra_buf_alloc,
if (!req)
return ERR_PTR(-ENOMEM);
- req->buf = kmalloc(len + extra_buf_alloc, flags);
+ req->buf = kmalloc(len, flags);
if (!req->buf) {
usb_ep_free_request(ep, req);
return ERR_PTR(-ENOMEM);
@@ -308,195 +280,48 @@ static void rmnet_free_ctrl_pkt(struct rmnet_ctrl_pkt *pkt)
static int rmnet_gport_setup(void)
{
int ret;
- int port_idx;
- int i;
- u8 base;
-
- pr_debug("%s: bam ports:%u bam2bam ports:%u data hsic ports:%u\n",
- __func__, no_data_bam_ports, no_data_bam2bam_ports,
- no_data_hsic_ports);
-
- pr_debug("%s: data hsuart ports:%u smd ports:%u ctrl hsic ports:%u\n",
- __func__, no_data_hsuart_ports, no_ctrl_smd_ports,
- no_ctrl_hsic_ports);
-
- pr_debug("%s: ctrl hsuart ports:%u nr_rmnet_ports:%u\n",
- __func__, no_ctrl_hsuart_ports, nr_rmnet_ports);
-
- if (no_data_bam_ports) {
- ret = gbam_setup(no_data_bam_ports);
- if (ret < 0)
- return ret;
- }
-
- if (no_data_bam2bam_ports) {
- ret = gbam2bam_setup(no_data_bam2bam_ports);
- if (ret < 0)
- return ret;
- }
-
- if (no_ctrl_smd_ports) {
- ret = gsmd_ctrl_setup(FRMNET_CTRL_CLIENT,
- no_ctrl_smd_ports, &base);
- if (ret)
- return ret;
- for (i = 0; i < nr_rmnet_ports; i++)
- if (rmnet_ports[i].port)
- rmnet_ports[i].port->port_num += base;
- }
-
- 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++;
- }
- }
- }
-
+ ret = ipa_data_setup(USB_IPA_FUNC_RMNET);
+ if (ret < 0)
+ return ret;
return 0;
}
static int gport_rmnet_connect(struct f_rmnet *dev, unsigned intf)
{
int ret;
- unsigned port_num;
- enum transport_type cxport = rmnet_ports[dev->port_num].ctrl_xport;
- enum transport_type dxport = rmnet_ports[dev->port_num].data_xport;
int src_connection_idx = 0, dst_connection_idx = 0;
struct usb_gadget *gadget = dev->cdev->gadget;
enum usb_ctrl usb_bam_type;
- void *net;
-
- pr_debug("%s: ctrl xport: %s data xport: %s dev: %p portno: %d\n",
- __func__, xport_to_str(cxport), xport_to_str(dxport),
- dev, dev->port_num);
-
- port_num = rmnet_ports[dev->port_num].ctrl_xport_num;
- switch (cxport) {
- case USB_GADGET_XPORT_SMD:
- ret = gsmd_ctrl_connect(&dev->port, port_num);
- if (ret) {
- pr_err("%s: gsmd_ctrl_connect failed: err:%d\n",
- __func__, ret);
- return ret;
- }
- break;
- case USB_GADGET_XPORT_QTI:
- ret = gqti_ctrl_connect(&dev->port, port_num, dev->ifc_id,
- dxport, USB_GADGET_RMNET);
- if (ret) {
- pr_err("%s: gqti_ctrl_connect failed: err:%d\n",
- __func__, ret);
- 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:
- pr_err("%s: Un-supported transport: %s\n", __func__,
- xport_to_str(cxport));
- return -ENODEV;
+
+ ret = gqti_ctrl_connect(&dev->port, QTI_PORT_RMNET, dev->ifc_id);
+ if (ret) {
+ pr_err("%s: gqti_ctrl_connect failed: err:%d\n",
+ __func__, ret);
+ return ret;
}
- port_num = rmnet_ports[dev->port_num].data_xport_num;
-
- switch (dxport) {
- case USB_GADGET_XPORT_BAM_DMUX:
- ret = gbam_connect(&dev->port, port_num,
- dxport, src_connection_idx, dst_connection_idx);
- if (ret) {
- pr_err("%s: gbam_connect failed: err:%d\n",
- __func__, ret);
- gsmd_ctrl_disconnect(&dev->port, port_num);
- return ret;
- }
- break;
- case USB_GADGET_XPORT_BAM2BAM_IPA:
- usb_bam_type = usb_bam_get_bam_type(gadget->name);
- src_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
- IPA_P_BAM, USB_TO_PEER_PERIPHERAL, USB_BAM_DEVICE,
- port_num);
- dst_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
- IPA_P_BAM, PEER_PERIPHERAL_TO_USB, USB_BAM_DEVICE,
- port_num);
- if (dst_connection_idx < 0 || src_connection_idx < 0) {
- pr_err("%s: usb_bam_get_connection_idx failed\n",
- __func__);
- gsmd_ctrl_disconnect(&dev->port, port_num);
- return -EINVAL;
- }
- ret = gbam_connect(&dev->port, port_num,
- dxport, src_connection_idx, dst_connection_idx);
- if (ret) {
- pr_err("%s: gbam_connect failed: err:%d\n",
- __func__, ret);
- if (cxport == USB_GADGET_XPORT_QTI)
- gqti_ctrl_disconnect(&dev->port, port_num);
- else
- gsmd_ctrl_disconnect(&dev->port, port_num);
- 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_ETHER:
- gether_enable_sg(&dev->gether_port, true);
- net = gether_connect(&dev->gether_port);
- if (IS_ERR(net)) {
- pr_err("%s: gether_connect failed: err:%ld\n",
- __func__, PTR_ERR(net));
- if (cxport == USB_GADGET_XPORT_QTI)
- gqti_ctrl_disconnect(&dev->port, port_num);
- else
- gsmd_ctrl_disconnect(&dev->port, port_num);
-
- return PTR_ERR(net);
- }
- gether_update_dl_max_pkts_per_xfer(&dev->gether_port,
- rmnet_dl_max_pkt_per_xfer);
- gether_update_dl_max_xfer_size(&dev->gether_port, 16384);
- break;
- case USB_GADGET_XPORT_NONE:
- break;
- default:
- pr_err("%s: Un-supported transport: %s\n", __func__,
- xport_to_str(dxport));
- return -ENODEV;
+ dev->ipa_port.cdev = dev->cdev;
+ ipa_data_port_select(USB_IPA_FUNC_RMNET);
+ usb_bam_type = usb_bam_get_bam_type(gadget->name);
+ src_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
+ IPA_P_BAM, USB_TO_PEER_PERIPHERAL, USB_BAM_DEVICE,
+ QTI_PORT_RMNET);
+ dst_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
+ IPA_P_BAM, PEER_PERIPHERAL_TO_USB, USB_BAM_DEVICE,
+ QTI_PORT_RMNET);
+ if (dst_connection_idx < 0 || src_connection_idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n",
+ __func__);
+ gqti_ctrl_disconnect(&dev->port, QTI_PORT_RMNET);
+ return -EINVAL;
+ }
+ ret = ipa_data_connect(&dev->ipa_port, USB_IPA_FUNC_RMNET,
+ src_connection_idx, dst_connection_idx);
+ if (ret) {
+ pr_err("%s: ipa_data_connect failed: err:%d\n",
+ __func__, ret);
+ gqti_ctrl_disconnect(&dev->port, QTI_PORT_RMNET);
+ return ret;
}
return 0;
@@ -504,53 +329,8 @@ static int gport_rmnet_connect(struct f_rmnet *dev, unsigned intf)
static int gport_rmnet_disconnect(struct f_rmnet *dev)
{
- unsigned port_num;
- enum transport_type cxport = rmnet_ports[dev->port_num].ctrl_xport;
- enum transport_type dxport = rmnet_ports[dev->port_num].data_xport;
-
- pr_debug("%s: ctrl xport: %s data xport: %s dev: %p portno: %d\n",
- __func__, xport_to_str(cxport), xport_to_str(dxport),
- dev, dev->port_num);
-
- port_num = rmnet_ports[dev->port_num].ctrl_xport_num;
- switch (cxport) {
- case USB_GADGET_XPORT_SMD:
- gsmd_ctrl_disconnect(&dev->port, port_num);
- break;
- case USB_GADGET_XPORT_QTI:
- gqti_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:
- pr_err("%s: Un-supported transport: %s\n", __func__,
- xport_to_str(cxport));
- return -ENODEV;
- }
-
- port_num = rmnet_ports[dev->port_num].data_xport_num;
- switch (dxport) {
- case USB_GADGET_XPORT_BAM_DMUX:
- case USB_GADGET_XPORT_BAM2BAM_IPA:
- gbam_disconnect(&dev->port, port_num, dxport);
- break;
- case USB_GADGET_XPORT_HSIC:
- ghsic_data_disconnect(&dev->port, port_num);
- break;
- case USB_GADGET_XPORT_ETHER:
- gether_disconnect(&dev->gether_port);
- break;
- case USB_GADGET_XPORT_NONE:
- break;
- default:
- pr_err("%s: Un-supported transport: %s\n", __func__,
- xport_to_str(dxport));
- return -ENODEV;
- }
-
+ gqti_ctrl_disconnect(&dev->port, QTI_PORT_RMNET);
+ ipa_data_disconnect(&dev->ipa_port, USB_IPA_FUNC_RMNET);
return 0;
}
@@ -558,7 +338,7 @@ static void frmnet_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_rmnet *dev = func_to_rmnet(f);
- pr_debug("%s: portno:%d\n", __func__, dev->port_num);
+ pr_debug("%s: start unbinding\n", __func__);
if (gadget_is_superspeed(c->cdev->gadget))
usb_free_descriptors(f->ss_descriptors);
if (gadget_is_dualspeed(c->cdev->gadget))
@@ -575,8 +355,7 @@ static void frmnet_purge_responses(struct f_rmnet *dev)
unsigned long flags;
struct rmnet_ctrl_pkt *cpkt;
- pr_debug("%s: port#%d\n", __func__, dev->port_num);
-
+ pr_debug("%s: Purging responses\n", __func__);
spin_lock_irqsave(&dev->lock, flags);
while (!list_empty(&dev->cpkt_resp_q)) {
cpkt = list_first_entry(&dev->cpkt_resp_q,
@@ -591,117 +370,46 @@ static void frmnet_purge_responses(struct f_rmnet *dev)
static void frmnet_suspend(struct usb_function *f)
{
- struct f_rmnet *dev = func_to_rmnet(f);
- unsigned port_num;
- enum transport_type dxport = rmnet_ports[dev->port_num].data_xport;
- bool remote_wakeup_allowed;
+ struct f_rmnet *dev = func_to_rmnet(f);
+ bool remote_wakeup_allowed;
if (f->config->cdev->gadget->speed == USB_SPEED_SUPER)
remote_wakeup_allowed = f->func_wakeup_allowed;
else
remote_wakeup_allowed = f->config->cdev->gadget->remote_wakeup;
- pr_debug("%s: data xport: %s dev: %p portno: %d remote_wakeup: %d\n",
- __func__, xport_to_str(dxport),
- dev, dev->port_num, remote_wakeup_allowed);
+ pr_debug("%s: dev: %p remote_wakeup: %d\n",
+ __func__, dev, remote_wakeup_allowed);
usb_ep_fifo_flush(dev->notify);
frmnet_purge_responses(dev);
- port_num = rmnet_ports[dev->port_num].data_xport_num;
- switch (dxport) {
- case USB_GADGET_XPORT_BAM_DMUX:
- break;
- case USB_GADGET_XPORT_BAM2BAM_IPA:
- if (remote_wakeup_allowed) {
- gbam_suspend(&dev->port, port_num, dxport);
- } else {
- /*
- * When remote wakeup is disabled, IPA is disconnected
- * because it cannot send new data until the USB bus is
- * resumed. Endpoint descriptors info is saved before it
- * gets reset by the BAM disconnect API. This lets us
- * restore this info when the USB bus is resumed.
- */
- dev->in_ep_desc_backup = dev->port.in->desc;
- dev->out_ep_desc_backup = dev->port.out->desc;
- pr_debug("in_ep_desc_bkup = %p, out_ep_desc_bkup = %p",
- dev->in_ep_desc_backup, dev->out_ep_desc_backup);
- pr_debug("%s(): Disconnecting\n", __func__);
- gport_rmnet_disconnect(dev);
- }
- break;
- case USB_GADGET_XPORT_HSIC:
- break;
- case USB_GADGET_XPORT_HSUART:
- break;
- case USB_GADGET_XPORT_ETHER:
- break;
- case USB_GADGET_XPORT_NONE:
- break;
- default:
- pr_err("%s: Un-supported transport: %s\n", __func__,
- xport_to_str(dxport));
- }
+ ipa_data_suspend(&dev->ipa_port, USB_IPA_FUNC_RMNET,
+ remote_wakeup_allowed);
}
static void frmnet_resume(struct usb_function *f)
{
- struct f_rmnet *dev = func_to_rmnet(f);
- unsigned port_num;
- enum transport_type dxport = rmnet_ports[dev->port_num].data_xport;
- int ret;
- bool remote_wakeup_allowed;
+ struct f_rmnet *dev = func_to_rmnet(f);
+ bool remote_wakeup_allowed;
if (f->config->cdev->gadget->speed == USB_SPEED_SUPER)
remote_wakeup_allowed = f->func_wakeup_allowed;
else
remote_wakeup_allowed = f->config->cdev->gadget->remote_wakeup;
- pr_debug("%s: data xport: %s dev: %p portno: %d remote_wakeup: %d\n",
- __func__, xport_to_str(dxport),
- dev, dev->port_num, remote_wakeup_allowed);
+ pr_debug("%s: dev: %p remote_wakeup: %d\n",
+ __func__, dev, remote_wakeup_allowed);
- port_num = rmnet_ports[dev->port_num].data_xport_num;
- switch (dxport) {
- case USB_GADGET_XPORT_BAM_DMUX:
- break;
- case USB_GADGET_XPORT_BAM2BAM_IPA:
- if (remote_wakeup_allowed) {
- gbam_resume(&dev->port, port_num, dxport);
- } else {
- dev->port.in->desc = dev->in_ep_desc_backup;
- dev->port.out->desc = dev->out_ep_desc_backup;
- pr_debug("%s(): Connecting\n", __func__);
- ret = gport_rmnet_connect(dev, dev->ifc_id);
- if (ret) {
- pr_err("%s: gport_rmnet_connect failed: err:%d\n",
- __func__, ret);
- }
- }
- break;
- case USB_GADGET_XPORT_HSIC:
- break;
- case USB_GADGET_XPORT_HSUART:
- break;
- case USB_GADGET_XPORT_ETHER:
- break;
- case USB_GADGET_XPORT_NONE:
- break;
- default:
- pr_err("%s: Un-supported transport: %s\n", __func__,
- xport_to_str(dxport));
- }
+ ipa_data_resume(&dev->ipa_port, USB_IPA_FUNC_RMNET,
+ remote_wakeup_allowed);
}
static void frmnet_disable(struct usb_function *f)
{
- struct f_rmnet *dev = func_to_rmnet(f);
- enum transport_type dxport = rmnet_ports[dev->port_num].data_xport;
- struct usb_composite_dev *cdev = dev->cdev;
-
- pr_debug("%s: port#%d\n", __func__, dev->port_num);
+ struct f_rmnet *dev = func_to_rmnet(f);
+ pr_debug("%s: Disabling\n", __func__);
usb_ep_disable(dev->notify);
dev->notify->driver_data = NULL;
@@ -709,11 +417,8 @@ static void frmnet_disable(struct usb_function *f)
frmnet_purge_responses(dev);
- if (dxport == USB_GADGET_XPORT_BAM2BAM_IPA &&
- gadget_is_dwc3(cdev->gadget)) {
- msm_ep_unconfig(dev->port.out);
- msm_ep_unconfig(dev->port.in);
- }
+ msm_ep_unconfig(dev->ipa_port.out);
+ msm_ep_unconfig(dev->ipa_port.in);
gport_rmnet_disconnect(dev);
}
@@ -723,12 +428,11 @@ frmnet_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
struct f_rmnet *dev = func_to_rmnet(f);
struct usb_composite_dev *cdev = dev->cdev;
int ret;
- struct list_head *cpkt;
-
- pr_debug("%s:dev:%p port#%d\n", __func__, dev, dev->port_num);
+ struct list_head *cpkt;
+ pr_debug("%s: dev: %p\n", __func__, dev);
if (dev->notify->driver_data) {
- pr_debug("%s: reset port:%d\n", __func__, dev->port_num);
+ pr_debug("%s: reset port\n", __func__);
usb_ep_disable(dev->notify);
}
@@ -749,14 +453,14 @@ frmnet_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
}
dev->notify->driver_data = dev;
- if (!dev->port.in->desc || !dev->port.out->desc) {
- if (config_ep_by_speed(cdev->gadget, f, dev->port.in) ||
- config_ep_by_speed(cdev->gadget, f, dev->port.out)) {
+ if (!dev->ipa_port.in->desc || !dev->ipa_port.out->desc) {
+ if (config_ep_by_speed(cdev->gadget, f, dev->ipa_port.in) ||
+ config_ep_by_speed(cdev->gadget, f, dev->ipa_port.out)) {
pr_err("%s(): config_ep_by_speed failed.\n", __func__);
ret = -EINVAL;
goto err_disable_ep;
}
- dev->port.gadget = dev->cdev->gadget;
+ dev->ipa_port.cdev = dev->cdev;
}
ret = gport_rmnet_connect(dev, intf);
@@ -777,8 +481,8 @@ frmnet_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
return ret;
err_disable_ep:
- dev->port.in->desc = NULL;
- dev->port.out->desc = NULL;
+ dev->ipa_port.in->desc = NULL;
+ dev->ipa_port.out->desc = NULL;
usb_ep_disable(dev->notify);
return ret;
@@ -790,10 +494,9 @@ static void frmnet_ctrl_response_available(struct f_rmnet *dev)
struct usb_cdc_notification *event;
unsigned long flags;
int ret;
- struct rmnet_ctrl_pkt *cpkt;
-
- pr_debug("%s:dev:%p portno#%d\n", __func__, dev, dev->port_num);
+ struct rmnet_ctrl_pkt *cpkt;
+ pr_debug("%s: dev: %p\n", __func__, dev);
spin_lock_irqsave(&dev->lock, flags);
if (!atomic_read(&dev->online) || !req || !req->buf) {
spin_unlock_irqrestore(&dev->lock, flags);
@@ -913,8 +616,7 @@ frmnet_send_cpkt_response(void *gr, void *buf, size_t len)
dev = port_to_rmnet(gr);
- pr_debug("%s: dev:%p port#%d\n", __func__, dev, dev->port_num);
-
+ pr_debug("%s: dev: %p\n", __func__, dev);
if (!atomic_read(&dev->online) || !atomic_read(&dev->ctrl_online)) {
rmnet_free_ctrl_pkt(cpkt);
return 0;
@@ -934,32 +636,27 @@ frmnet_cmd_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_rmnet *dev = req->context;
struct usb_composite_dev *cdev;
- unsigned port_num;
if (!dev) {
pr_err("%s: rmnet dev is null\n", __func__);
return;
}
-
- pr_debug("%s: dev:%p port#%d\n", __func__, dev, dev->port_num);
-
+ pr_debug("%s: dev: %p\n", __func__, dev);
cdev = dev->cdev;
if (dev->port.send_encap_cmd) {
- port_num = rmnet_ports[dev->port_num].ctrl_xport_num;
- dev->port.send_encap_cmd(port_num, req->buf, req->actual);
+ dev->port.send_encap_cmd(QTI_PORT_RMNET, req->buf, req->actual);
}
}
static void frmnet_notify_complete(struct usb_ep *ep, struct usb_request *req)
{
- struct f_rmnet *dev = req->context;
- int status = req->status;
+ struct f_rmnet *dev = req->context;
+ int status = req->status;
unsigned long flags;
struct rmnet_ctrl_pkt *cpkt;
- pr_debug("%s: dev:%p port#%d\n", __func__, dev, dev->port_num);
-
+ pr_debug("%s: dev: %p\n", __func__, dev);
switch (status) {
case -ECONNRESET:
case -ESHUTDOWN:
@@ -1021,14 +718,12 @@ frmnet_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
struct f_rmnet *dev = func_to_rmnet(f);
struct usb_composite_dev *cdev = dev->cdev;
struct usb_request *req = cdev->req;
- unsigned port_num;
u16 w_index = le16_to_cpu(ctrl->wIndex);
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
int ret = -EOPNOTSUPP;
- pr_debug("%s:dev:%p port#%d\n", __func__, dev, dev->port_num);
-
+ pr_debug("%s: dev: %p\n", __func__, dev);
if (!atomic_read(&dev->online)) {
pr_warn("%s: usb cable is not connected\n", __func__);
return -ENOTCONN;
@@ -1085,8 +780,8 @@ frmnet_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
pr_debug("%s: USB_CDC_REQ_SET_CONTROL_LINE_STATE: DTR:%d\n",
__func__, w_value & ACM_CTRL_DTR ? 1 : 0);
if (dev->port.notify_modem) {
- port_num = rmnet_ports[dev->port_num].ctrl_xport_num;
- dev->port.notify_modem(&dev->port, port_num, w_value);
+ dev->port.notify_modem(&dev->port,
+ QTI_PORT_RMNET, w_value);
}
ret = 0;
@@ -1135,9 +830,7 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
pr_err("%s: usb epin autoconfig failed\n", __func__);
return -ENODEV;
}
- dev->port.in = ep;
- /* Update same for u_ether which uses gether port struct */
- dev->gether_port.in_ep = ep;
+ dev->ipa_port.in = ep;
ep->driver_data = cdev;
ep = usb_ep_autoconfig(cdev->gadget, &rmnet_fs_out_desc);
@@ -1146,9 +839,7 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
ret = -ENODEV;
goto ep_auto_out_fail;
}
- dev->port.out = ep;
- /* Update same for u_ether which uses gether port struct */
- dev->gether_port.out_ep = ep;
+ dev->ipa_port.out = ep;
ep->driver_data = cdev;
ep = usb_ep_autoconfig(cdev->gadget, &rmnet_fs_notify_desc);
@@ -1162,7 +853,6 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
dev->notify_req = frmnet_alloc_req(ep,
sizeof(struct usb_cdc_notification),
- cdev->gadget->extra_buf_alloc,
GFP_KERNEL);
if (IS_ERR(dev->notify_req)) {
pr_err("%s: unable to allocate memory for notify req\n",
@@ -1218,10 +908,9 @@ static int frmnet_bind(struct usb_configuration *c, struct usb_function *f)
}
}
- pr_debug("%s: RmNet(%d) %s Speed, IN:%s OUT:%s\n",
- __func__, dev->port_num,
- gadget_is_dualspeed(cdev->gadget) ? "dual" : "full",
- dev->port.in->name, dev->port.out->name);
+ pr_debug("%s: RmNet %s Speed, IN:%s OUT:%s\n",
+ __func__, gadget_is_dualspeed(cdev->gadget) ? "dual" : "full",
+ dev->ipa_port.in->name, dev->ipa_port.out->name);
return 0;
@@ -1238,16 +927,16 @@ ep_notify_alloc_fail:
dev->notify->driver_data = NULL;
dev->notify = NULL;
ep_auto_notify_fail:
- dev->port.out->driver_data = NULL;
- dev->port.out = NULL;
+ dev->ipa_port.out->driver_data = NULL;
+ dev->ipa_port.out = NULL;
ep_auto_out_fail:
- dev->port.in->driver_data = NULL;
- dev->port.in = NULL;
+ dev->ipa_port.in->driver_data = NULL;
+ dev->ipa_port.in = NULL;
return ret;
}
-static int frmnet_bind_config(struct usb_configuration *c, unsigned portno)
+static int frmnet_bind_config(struct usb_configuration *c)
{
int status;
struct f_rmnet *dev;
@@ -1255,32 +944,7 @@ static int frmnet_bind_config(struct usb_configuration *c, unsigned portno)
unsigned long flags;
pr_debug("%s: usb config:%p\n", __func__, c);
-
- if (portno >= nr_rmnet_ports) {
- pr_err("%s: supporting ports#%u port_id:%u\n", __func__,
- nr_rmnet_ports, portno);
- return -ENODEV;
- }
-
- dev = rmnet_ports[portno].port;
-
- if (rmnet_ports[portno].data_xport == USB_GADGET_XPORT_ETHER) {
- struct net_device *net = gether_setup_name_default("usb_rmnet");
-
- if (IS_ERR(net)) {
- pr_err("%s: gether_setup failed\n", __func__);
- return PTR_ERR(net);
- }
- dev->gether_port.ioport = netdev_priv(net);
- gether_set_gadget(net, c->cdev->gadget);
- status = gether_register_netdev(net);
- if (status < 0) {
- pr_err("%s: gether_register_netdev failed\n", __func__);
- free_netdev(net);
- return status;
- }
- }
-
+ dev = &rmnet_port;
if (rmnet_string_defs[0].id == 0) {
status = usb_string_id(c->cdev);
if (status < 0) {
@@ -1293,8 +957,8 @@ static int frmnet_bind_config(struct usb_configuration *c, unsigned portno)
spin_lock_irqsave(&dev->lock, flags);
dev->cdev = c->cdev;
- f = &dev->gether_port.func;
- f->name = kasprintf(GFP_ATOMIC, "rmnet%d", portno);
+ f = &dev->func;
+ f->name = kasprintf(GFP_ATOMIC, "rmnet%d", 0);
spin_unlock_irqrestore(&dev->lock, flags);
if (!f->name) {
pr_err("%s: cannot allocate memory for name\n", __func__);
@@ -1312,7 +976,6 @@ static int frmnet_bind_config(struct usb_configuration *c, unsigned portno)
dev->port.send_cpkt_response = frmnet_send_cpkt_response;
dev->port.disconnect = frmnet_disconnect;
dev->port.connect = frmnet_connect;
- dev->gether_port.cdc_filter = 0;
status = usb_add_function(c, f);
if (status) {
@@ -1327,17 +990,6 @@ static int frmnet_bind_config(struct usb_configuration *c, unsigned portno)
return status;
}
-static void frmnet_unbind_config(void)
-{
- int i;
-
- for (i = 0; i < nr_rmnet_ports; i++)
- if (rmnet_ports[i].data_xport == USB_GADGET_XPORT_ETHER) {
- gether_cleanup(rmnet_ports[i].port->gether_port.ioport);
- rmnet_ports[i].port->gether_port.ioport = NULL;
- }
-}
-
static int rmnet_init(void)
{
return gqti_ctrl_init();
@@ -1345,130 +997,25 @@ static int rmnet_init(void)
static void frmnet_cleanup(void)
{
- int i;
-
gqti_ctrl_cleanup();
-
- for (i = 0; i < nr_rmnet_ports; i++)
- kfree(rmnet_ports[i].port);
-
- gbam_cleanup();
- nr_rmnet_ports = 0;
- no_ctrl_smd_ports = 0;
- no_ctrl_qti_ports = 0;
- no_data_bam_ports = 0;
- no_data_bam2bam_ports = 0;
- no_ctrl_hsic_ports = 0;
- no_data_hsic_ports = 0;
- no_ctrl_hsuart_ports = 0;
- no_data_hsuart_ports = 0;
+ kfree(&rmnet_port);
}
static int frmnet_init_port(const char *ctrl_name, const char *data_name,
const char *port_name)
{
- struct f_rmnet *dev;
- struct rmnet_ports *rmnet_port;
- int ret;
- int i;
-
- if (nr_rmnet_ports >= NR_RMNET_PORTS) {
- pr_err("%s: Max-%d instances supported\n",
- __func__, NR_RMNET_PORTS);
- return -EINVAL;
- }
+ struct f_rmnet *dev;
- pr_debug("%s: port#:%d, ctrl port: %s data port: %s\n",
- __func__, nr_rmnet_ports, ctrl_name, data_name);
+ pr_debug("%s: ctrl port: %s data port: %s\n",
+ __func__, ctrl_name, data_name);
dev = kzalloc(sizeof(struct f_rmnet), GFP_KERNEL);
if (!dev)
return -ENOMEM;
- dev->port_num = nr_rmnet_ports;
spin_lock_init(&dev->lock);
INIT_LIST_HEAD(&dev->cpkt_resp_q);
-
- rmnet_port = &rmnet_ports[nr_rmnet_ports];
- rmnet_port->port = dev;
- rmnet_port->port_num = nr_rmnet_ports;
- rmnet_port->ctrl_xport = str_to_xport(ctrl_name);
- rmnet_port->data_xport = str_to_xport(data_name);
-
- switch (rmnet_port->ctrl_xport) {
- case USB_GADGET_XPORT_SMD:
- rmnet_port->ctrl_xport_num = no_ctrl_smd_ports;
- no_ctrl_smd_ports++;
- break;
- case USB_GADGET_XPORT_QTI:
- rmnet_port->ctrl_xport_num = no_ctrl_qti_ports;
- no_ctrl_qti_ports++;
- break;
- case USB_GADGET_XPORT_HSIC:
- ghsic_ctrl_set_port_name(port_name, ctrl_name);
- rmnet_port->ctrl_xport_num = no_ctrl_hsic_ports;
- no_ctrl_hsic_ports++;
- break;
- case USB_GADGET_XPORT_HSUART:
- rmnet_port->ctrl_xport_num = no_ctrl_hsuart_ports;
- no_ctrl_hsuart_ports++;
- break;
- case USB_GADGET_XPORT_NONE:
- break;
- default:
- pr_err("%s: Un-supported transport: %u\n", __func__,
- rmnet_port->ctrl_xport);
- ret = -ENODEV;
- goto fail_probe;
- }
-
- switch (rmnet_port->data_xport) {
- case USB_GADGET_XPORT_BAM2BAM:
- /* Override BAM2BAM to BAM_DMUX for old ABI compatibility */
- rmnet_port->data_xport = USB_GADGET_XPORT_BAM_DMUX;
- /* fall-through */
- case USB_GADGET_XPORT_BAM_DMUX:
- rmnet_port->data_xport_num = no_data_bam_ports;
- no_data_bam_ports++;
- break;
- case USB_GADGET_XPORT_BAM2BAM_IPA:
- rmnet_port->data_xport_num = no_data_bam2bam_ports;
- no_data_bam2bam_ports++;
- break;
- case USB_GADGET_XPORT_HSIC:
- ghsic_data_set_port_name(port_name, data_name);
- rmnet_port->data_xport_num = no_data_hsic_ports;
- no_data_hsic_ports++;
- break;
- case USB_GADGET_XPORT_HSUART:
- rmnet_port->data_xport_num = no_data_hsuart_ports;
- no_data_hsuart_ports++;
- break;
- case USB_GADGET_XPORT_ETHER:
- case USB_GADGET_XPORT_NONE:
- break;
- default:
- pr_err("%s: Un-supported transport: %u\n", __func__,
- rmnet_port->data_xport);
- ret = -ENODEV;
- goto fail_probe;
- }
- nr_rmnet_ports++;
+ rmnet_port = *dev;
return 0;
-
-fail_probe:
- for (i = 0; i < nr_rmnet_ports; i++)
- kfree(rmnet_ports[i].port);
-
- nr_rmnet_ports = 0;
- no_ctrl_smd_ports = 0;
- no_ctrl_qti_ports = 0;
- no_data_bam_ports = 0;
- no_ctrl_hsic_ports = 0;
- no_data_hsic_ports = 0;
- no_ctrl_hsuart_ports = 0;
- no_data_hsuart_ports = 0;
-
- return ret;
}
diff --git a/drivers/usb/gadget/function/u_ctrl_qti.c b/drivers/usb/gadget/function/u_ctrl_qti.c
index 7ef56eca20b8..c0650b0abf8c 100644
--- a/drivers/usb/gadget/function/u_ctrl_qti.c
+++ b/drivers/usb/gadget/function/u_ctrl_qti.c
@@ -14,11 +14,11 @@
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/usb/usb_ctrl_qti.h>
-
-#include <soc/qcom/bam_dmux.h>
+#include <linux/miscdevice.h>
+#include <linux/debugfs.h>
#include "u_rmnet.h"
-#include "usb_gadget_xport.h"
+#include "f_qdss.h"
#define RMNET_CTRL_QTI_NAME "rmnet_ctrl"
#define DPL_CTRL_QTI_NAME "dpl_ctrl"
@@ -54,18 +54,18 @@ struct qti_ctrl_port {
struct list_head cpkt_req_q;
spinlock_t lock;
- enum gadget_type gtype;
+ enum qti_port_type port_type;
unsigned host_to_modem;
unsigned copied_to_modem;
unsigned copied_from_modem;
unsigned modem_to_host;
unsigned drp_cpkt_cnt;
};
-static struct qti_ctrl_port *ctrl_port[NR_QTI_PORTS];
+static struct qti_ctrl_port *ctrl_port[QTI_NUM_PORTS];
static inline int qti_ctrl_lock(atomic_t *excl)
{
- if (atomic_inc_return(excl) == 1) {
+ if (atomic_inc_return(excl) == 1)
return 0;
atomic_dec(excl);
return -EBUSY;
@@ -76,6 +76,32 @@ static inline void qti_ctrl_unlock(atomic_t *excl)
atomic_dec(excl);
}
+static struct rmnet_ctrl_pkt *alloc_rmnet_ctrl_pkt(unsigned len, gfp_t flags)
+{
+ struct rmnet_ctrl_pkt *pkt;
+
+ pkt = kzalloc(sizeof(struct rmnet_ctrl_pkt), flags);
+ if (!pkt)
+ return ERR_PTR(-ENOMEM);
+
+ pkt->buf = kmalloc(len, flags);
+ if (!pkt->buf) {
+ kfree(pkt);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ pkt->len = len;
+
+ return pkt;
+}
+
+static void free_rmnet_ctrl_pkt(struct rmnet_ctrl_pkt *pkt)
+{
+ kfree(pkt->buf);
+ kfree(pkt);
+}
+
+
static void qti_ctrl_queue_notify(struct qti_ctrl_port *port)
{
unsigned long flags;
@@ -106,7 +132,8 @@ static void qti_ctrl_queue_notify(struct qti_ctrl_port *port)
wake_up(&port->read_wq);
}
-static int gqti_ctrl_send_cpkt_tomodem(u8 portno, void *buf, size_t len)
+static int gqti_ctrl_send_cpkt_tomodem(enum qti_port_type qport,
+ void *buf, size_t len)
{
unsigned long flags;
struct qti_ctrl_port *port;
@@ -118,12 +145,11 @@ static int gqti_ctrl_send_cpkt_tomodem(u8 portno, void *buf, size_t len)
return -EINVAL;
}
- if (portno >= NR_QTI_PORTS) {
- pr_err("%s: Invalid QTI port %d\n", __func__, portno);
+ if (qport >= QTI_NUM_PORTS) {
+ pr_err("%s: Invalid QTI port %d\n", __func__, qport);
return -ENODEV;
}
- port = ctrl_port[portno];
-
+ port = ctrl_port[qport];
cpkt = alloc_rmnet_ctrl_pkt(len, GFP_ATOMIC);
if (IS_ERR(cpkt)) {
pr_err("%s: Unable to allocate ctrl pkt\n", __func__);
@@ -133,8 +159,8 @@ static int gqti_ctrl_send_cpkt_tomodem(u8 portno, void *buf, size_t len)
memcpy(cpkt->buf, buf, len);
cpkt->len = len;
- pr_debug("%s: gtype:%d: Add to cpkt_req_q packet with len = %zu\n",
- __func__, port->gtype, len);
+ pr_debug("%s: port type:%d: Add to cpkt_req_q packet with len = %zu\n",
+ __func__, port->port_type, len);
spin_lock_irqsave(&port->lock, flags);
/* drop cpkt if port is not open */
@@ -159,71 +185,51 @@ static int gqti_ctrl_send_cpkt_tomodem(u8 portno, void *buf, size_t len)
}
static void
-gqti_ctrl_notify_modem(void *gptr, u8 portno, int val)
+gqti_ctrl_notify_modem(void *gptr, enum qti_port_type qport, int val)
{
struct qti_ctrl_port *port;
- if (portno >= NR_QTI_PORTS) {
- pr_err("%s: Invalid QTI port %d\n", __func__, portno);
+ if (qport >= QTI_NUM_PORTS) {
+ pr_err("%s: Invalid QTI port %d\n", __func__, qport);
return;
}
- port = ctrl_port[portno];
-
+ port = ctrl_port[qport];
atomic_set(&port->line_state, val);
/* send 0 len pkt to qti to notify state change */
qti_ctrl_queue_notify(port);
}
-int gqti_ctrl_connect(void *gr, u8 port_num, unsigned intf,
- enum transport_type dxport, enum gadget_type gtype)
+int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned intf)
{
struct qti_ctrl_port *port;
struct grmnet *g_rmnet = NULL;
struct gqdss *g_dpl = NULL;
unsigned long flags;
- pr_debug("%s: gtype:%d gadget:%p\n", __func__, gtype, gr);
- if (port_num >= NR_QTI_PORTS) {
- pr_err("%s: Invalid QTI port %d\n", __func__, port_num);
+ pr_debug("%s: port type:%d gadget:%p\n", __func__, qport, gr);
+ if (qport >= QTI_NUM_PORTS) {
+ pr_err("%s: Invalid QTI port %d\n", __func__, qport);
return -ENODEV;
}
- port = ctrl_port[port_num];
+ port = ctrl_port[qport];
if (!port) {
pr_err("%s: gadget port is null\n", __func__);
return -ENODEV;
}
spin_lock_irqsave(&port->lock, flags);
- port->gtype = gtype;
- if (dxport == USB_GADGET_XPORT_BAM_DMUX) {
- /*
- * BAM-DMUX data transport is used for RMNET and DPL
- * on some targets where IPA is not available.
- * Set endpoint type as BAM-DMUX and interface
- * id as channel number. This information is
- * sent to user space via EP_LOOKUP ioctl.
- *
- */
-
- port->ep_type = DATA_EP_TYPE_BAM_DMUX;
- port->intf = (gtype == USB_GADGET_RMNET) ?
- BAM_DMUX_USB_RMNET_0 :
- BAM_DMUX_USB_DPL;
- port->ipa_prod_idx = 0;
- port->ipa_cons_idx = 0;
- } else {
- port->ep_type = DATA_EP_TYPE_HSUSB;
- port->intf = intf;
- }
+ port->port_type = qport;
+ port->ep_type = DATA_EP_TYPE_HSUSB;
+ port->intf = intf;
- if (gr && port->gtype == USB_GADGET_RMNET) {
+ if (gr && port->port_type == QTI_PORT_RMNET) {
port->port_usb = gr;
g_rmnet = (struct grmnet *)gr;
g_rmnet->send_encap_cmd = gqti_ctrl_send_cpkt_tomodem;
g_rmnet->notify_modem = gqti_ctrl_notify_modem;
- } else if (gr && port->gtype == USB_GADGET_DPL) {
+ } else if (gr && port->port_type == QTI_PORT_DPL) {
port->port_usb = gr;
g_dpl = (struct gqdss *)gr;
g_dpl->send_encap_cmd = gqti_ctrl_send_cpkt_tomodem;
@@ -231,7 +237,7 @@ int gqti_ctrl_connect(void *gr, u8 port_num, unsigned intf,
atomic_set(&port->line_state, 1);
} else {
spin_unlock_irqrestore(&port->lock, flags);
- pr_err("%s(): Port is used without gtype.\n", __func__);
+ pr_err("%s(): Port is used without port type.\n", __func__);
return -ENODEV;
}
@@ -251,7 +257,7 @@ int gqti_ctrl_connect(void *gr, u8 port_num, unsigned intf,
return 0;
}
-void gqti_ctrl_disconnect(void *gr, u8 port_num)
+void gqti_ctrl_disconnect(void *gr, enum qti_port_type qport)
{
struct qti_ctrl_port *port;
unsigned long flags;
@@ -261,13 +267,12 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num)
pr_debug("%s: gadget:%p\n", __func__, gr);
- if (port_num >= NR_QTI_PORTS) {
- pr_err("%s: Invalid QTI port %d\n", __func__, port_num);
+ if (qport >= QTI_NUM_PORTS) {
+ pr_err("%s: Invalid QTI port %d\n", __func__, qport);
return;
}
- port = ctrl_port[port_num];
-
+ port = ctrl_port[qport];
if (!port) {
pr_err("%s: gadget port is null\n", __func__);
return;
@@ -282,17 +287,17 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num)
port->ipa_cons_idx = -1;
port->port_usb = NULL;
- if (gr && port->gtype == USB_GADGET_RMNET) {
+ if (gr && port->port_type == QTI_PORT_RMNET) {
g_rmnet = (struct grmnet *)gr;
g_rmnet->send_encap_cmd = NULL;
g_rmnet->notify_modem = NULL;
- } else if (gr && port->gtype == USB_GADGET_DPL) {
+ } else if (gr && port->port_type == QTI_PORT_DPL) {
g_dpl = (struct gqdss *)gr;
g_dpl->send_encap_cmd = NULL;
g_dpl->notify_modem = NULL;
} else {
pr_err("%s(): unrecognized gadget type(%d).\n",
- __func__, port->gtype);
+ __func__, port->port_type);
}
while (!list_empty(&port->cpkt_req_q)) {
@@ -309,18 +314,17 @@ void gqti_ctrl_disconnect(void *gr, u8 port_num)
qti_ctrl_queue_notify(port);
}
-void gqti_ctrl_update_ipa_pipes(void *gr, u8 port_num, u32 ipa_prod,
- u32 ipa_cons)
+void gqti_ctrl_update_ipa_pipes(void *gr, enum qti_port_type qport,
+ u32 ipa_prod, u32 ipa_cons)
{
struct qti_ctrl_port *port;
- if (port_num >= NR_QTI_PORTS) {
- pr_err("%s: Invalid QTI port %d\n", __func__, port_num);
+ if (qport >= QTI_NUM_PORTS) {
+ pr_err("%s: Invalid QTI port %d\n", __func__, qport);
return;
}
- port = ctrl_port[port_num];
-
+ port = ctrl_port[qport];
port->ipa_prod_idx = ipa_prod;
port->ipa_cons_idx = ipa_cons;
@@ -492,12 +496,12 @@ qti_ctrl_write(struct file *fp, const char __user *buf, size_t count,
spin_lock_irqsave(&port->lock, flags);
if (port && port->port_usb) {
- if (port->gtype == USB_GADGET_RMNET) {
+ if (port->port_type == QTI_PORT_RMNET) {
g_rmnet = (struct grmnet *)port->port_usb;
} else {
spin_unlock_irqrestore(&port->lock, flags);
pr_err("%s(): unrecognized gadget type(%d).\n",
- __func__, port->gtype);
+ __func__, port->port_type);
return -EINVAL;
}
@@ -530,15 +534,15 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
struct ep_info info;
int val, ret = 0;
- pr_debug("%s: Received command %d for gtype:%d\n",
- __func__, cmd, port->gtype);
+ pr_debug("%s: Received command %d for port type:%d\n",
+ __func__, cmd, port->port_type);
if (qti_ctrl_lock(&port->ioctl_excl))
return -EBUSY;
switch (cmd) {
case QTI_CTRL_MODEM_OFFLINE:
- if (port && (port->gtype == USB_GADGET_DPL)) {
+ if (port && (port->port_type == QTI_PORT_DPL)) {
pr_err("%s(): Modem Offline not handled\n", __func__);
goto exit_ioctl;
}
@@ -550,7 +554,7 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
gr->disconnect(gr);
break;
case QTI_CTRL_MODEM_ONLINE:
- if (port && (port->gtype == USB_GADGET_DPL)) {
+ if (port && (port->port_type == QTI_PORT_DPL)) {
pr_err("%s(): Modem Online not handled\n", __func__);
goto exit_ioctl;
}
@@ -568,13 +572,13 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
pr_err("copying to user space failed");
ret = -EFAULT;
}
- pr_debug("%s: Sent line_state: %d for gtype:%d\n", __func__,
- atomic_read(&port->line_state), port->gtype);
+ pr_debug("%s: Sent line_state: %d for port type:%d\n", __func__,
+ atomic_read(&port->line_state), port->port_type);
break;
case QTI_CTRL_EP_LOOKUP:
- pr_debug("%s(): EP_LOOKUP for gtype:%d\n", __func__,
- port->gtype);
+ pr_debug("%s(): EP_LOOKUP for port type:%d\n", __func__,
+ port->port_type);
val = atomic_read(&port->connected);
if (!val) {
pr_err_ratelimited("EP_LOOKUP failed: not connected\n");
@@ -593,9 +597,9 @@ static long qti_ctrl_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
info.ipa_ep_pair.cons_pipe_num = port->ipa_cons_idx;
info.ipa_ep_pair.prod_pipe_num = port->ipa_prod_idx;
- pr_debug("%s(): gtype:%d ep_type:%d intf:%d\n",
- __func__, port->gtype, info.ph_ep_info.ep_type,
- info.ph_ep_info.peripheral_iface_id);
+ pr_debug("%s(): port type:%d ep_type:%d intf:%d\n",
+ __func__, port->port_type, info.ph_ep_info.ep_type,
+ info.ph_ep_info.peripheral_iface_id);
pr_debug("%s(): ipa_cons_idx:%d ipa_prod_idx:%d\n",
__func__, info.ipa_ep_pair.cons_pipe_num,
@@ -650,7 +654,7 @@ static int qti_ctrl_read_stats(struct seq_file *s, void *unused)
unsigned long flags;
int i;
- for (i = 0; i < NR_QTI_PORTS; i++) {
+ for (i = 0; i < QTI_NUM_PORTS; i++) {
port = ctrl_port[i];
if (!port)
continue;
@@ -687,7 +691,7 @@ static ssize_t qti_ctrl_reset_stats(struct file *file,
int i;
unsigned long flags;
- for (i = 0; i < NR_QTI_PORTS; i++) {
+ for (i = 0; i < QTI_NUM_PORTS; i++) {
port = ctrl_port[i];
if (!port)
continue;
@@ -762,10 +766,9 @@ int gqti_ctrl_init(void)
int ret, i, sz = QTI_CTRL_NAME_LEN;
struct qti_ctrl_port *port = NULL;
- for (i = 0; i < NR_QTI_PORTS; i++) {
+ for (i = 0; i < QTI_NUM_PORTS; i++) {
port = kzalloc(sizeof(struct qti_ctrl_port), GFP_KERNEL);
if (!port) {
- pr_err("Failed to allocate rmnet control device\n");
ret = -ENOMEM;
goto fail_init;
}
@@ -787,16 +790,16 @@ int gqti_ctrl_init(void)
port->ipa_prod_idx = -1;
port->ipa_cons_idx = -1;
- if (i == 0)
+ if (i == QTI_PORT_RMNET)
strlcat(port->name, RMNET_CTRL_QTI_NAME, sz);
- else if (i == DPL_QTI_CTRL_PORT_NO)
+ else if (i == QTI_PORT_DPL)
strlcat(port->name, DPL_CTRL_QTI_NAME, sz);
else
snprintf(port->name, sz, "%s%d",
- RMNET_CTRL_QTI_NAME, i);
+ RMNET_CTRL_QTI_NAME, i);
port->ctrl_device.name = port->name;
- if (i == DPL_QTI_CTRL_PORT_NO)
+ if (i == QTI_PORT_DPL)
port->ctrl_device.fops = &dpl_qti_ctrl_fops;
else
port->ctrl_device.fops = &qti_ctrl_fops;
@@ -809,7 +812,6 @@ int gqti_ctrl_init(void)
}
}
qti_ctrl_debugfs_init();
-
return ret;
fail_init:
@@ -825,7 +827,7 @@ void gqti_ctrl_cleanup(void)
{
int i;
- for (i = 0; i < NR_QTI_PORTS; i++) {
+ for (i = 0; i < QTI_NUM_PORTS; i++) {
misc_deregister(&ctrl_port[i]->ctrl_device);
kfree(ctrl_port[i]);
ctrl_port[i] = NULL;
diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c
index 56e7dea427ec..2da0c59fdfc2 100644
--- a/drivers/usb/gadget/function/u_data_ipa.c
+++ b/drivers/usb/gadget/function/u_data_ipa.c
@@ -23,6 +23,7 @@
#include <linux/usb_bam.h>
#include "u_data_ipa.h"
+#include "u_rmnet.h"
struct ipa_data_ch_info {
struct usb_request *rx_req;
@@ -564,6 +565,11 @@ static void ipa_data_connect_work(struct work_struct *w)
atomic_set(&port->pipe_connect_notified, 1);
}
+ if (port->func_type == USB_IPA_FUNC_RMNET) {
+ gqti_ctrl_update_ipa_pipes(port->port_usb, QTI_PORT_RMNET,
+ gport->ipa_producer_ep, gport->ipa_consumer_ep);
+ }
+
pr_debug("ipa_producer_ep:%d ipa_consumer_ep:%d\n",
gport->ipa_producer_ep,
gport->ipa_consumer_ep);
@@ -1135,7 +1141,7 @@ int ipa_data_setup(enum ipa_func_type func)
}
if (ipa_data_wq) {
pr_debug("ipa_data_wq is already setup.");
- goto free_rndis_data;
+ return 0;
}
ipa_data_wq = alloc_workqueue("k_usb_ipa_data",
diff --git a/drivers/usb/gadget/function/u_data_ipa.h b/drivers/usb/gadget/function/u_data_ipa.h
index a1c1055bd8ef..a6b0a51442a2 100644
--- a/drivers/usb/gadget/function/u_data_ipa.h
+++ b/drivers/usb/gadget/function/u_data_ipa.h
@@ -20,6 +20,8 @@
#include <linux/ipa_usb.h>
#include <linux/usb_bam.h>
+#include "u_rmnet.h"
+
enum ipa_func_type {
USB_IPA_FUNC_ECM,
USB_IPA_FUNC_MBIM,
@@ -87,4 +89,6 @@ void *rndis_qc_get_ipa_rx_cb(void);
bool rndis_qc_get_skip_ep_config(void);
void *rndis_qc_get_ipa_tx_cb(void);
void rndis_ipa_reset_trigger(void);
+void gqti_ctrl_update_ipa_pipes(void *gr, enum qti_port_type qport,
+ u32 ipa_prod, u32 ipa_cons);
#endif
diff --git a/drivers/usb/gadget/function/u_rmnet.h b/drivers/usb/gadget/function/u_rmnet.h
index 4336dbf26274..e0843794b594 100644
--- a/drivers/usb/gadget/function/u_rmnet.h
+++ b/drivers/usb/gadget/function/u_rmnet.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, 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
@@ -19,18 +19,19 @@
#include <linux/workqueue.h>
struct rmnet_ctrl_pkt {
- void *buf;
- int len;
+ void *buf;
+ int len;
struct list_head list;
};
-struct grmnet {
- struct usb_function func;
+enum qti_port_type {
+ QTI_PORT_RMNET,
+ QTI_PORT_DPL,
+ QTI_NUM_PORTS
+};
- struct usb_gadget *gadget;
- struct usb_ep *in;
- struct usb_ep *out;
+struct grmnet {
/* to usb host, aka laptop, windows pc etc. Will
* be filled by usb driver of rmnet functionality
*/
@@ -39,18 +40,13 @@ struct grmnet {
/* to modem, and to be filled by driver implementing
* control function
*/
- int (*send_encap_cmd)(u8 port_num, void *buf, size_t len);
-
- void (*notify_modem)(void *g, u8 port_num, int cbits);
+ int (*send_encap_cmd)(enum qti_port_type qport, void *buf, size_t len);
+ void (*notify_modem)(void *g, enum qti_port_type qport, int cbits);
void (*disconnect)(struct grmnet *g);
void (*connect)(struct grmnet *g);
};
-#define NR_QTI_PORTS (NR_RMNET_PORTS + NR_DPL_PORTS)
-#define NR_RMNET_PORTS 4
-#define NR_DPL_PORTS 1
-
enum ctrl_client {
FRMNET_CTRL_CLIENT,
GPS_CTRL_CLIENT,
@@ -58,22 +54,8 @@ enum ctrl_client {
NR_CTRL_CLIENTS
};
-int gbam_setup(unsigned int no_bam_port);
-int gbam2bam_setup(unsigned int no_bam2bam_port);
-void gbam_cleanup(void);
-int gbam_connect(struct grmnet *gr, u8 port_num,
- enum transport_type trans, u8 src_connection_idx,
- u8 dst_connection_idx);
-void gbam_disconnect(struct grmnet *gr, u8 port_num,
- enum transport_type trans);
-void gbam_suspend(struct grmnet *gr, u8 port_num, enum transport_type trans);
-void gbam_resume(struct grmnet *gr, u8 port_num, enum transport_type trans);
-int gbam_mbim_setup(void);
-int gbam_mbim_connect(struct usb_gadget *g, struct usb_ep *in,
- struct usb_ep *out);
-void gbam_mbim_disconnect(void);
-int gsmd_ctrl_connect(struct grmnet *gr, int port_num);
-void gsmd_ctrl_disconnect(struct grmnet *gr, u8 port_num);
-int gsmd_ctrl_setup(enum ctrl_client client_num, unsigned int count,
- u8 *first_port_idx);
+int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned intf);
+void gqti_ctrl_disconnect(void *gr, enum qti_port_type qport);
+int gqti_ctrl_init(void);
+void gqti_ctrl_cleanup(void);
#endif /* __U_RMNET_H*/