diff options
-rw-r--r-- | drivers/usb/gadget/function/f_qdss.h | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_rmnet.c | 645 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_ctrl_qti.c | 172 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_data_ipa.c | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_data_ipa.h | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_rmnet.h | 48 |
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*/ |