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

Commit 89ec4a55 authored by Lena Salman's avatar Lena Salman Committed by Stephen Boyd
Browse files

usb: Add support for multiple RMNETs via IPA



This change adds full support for up to 4 RMNET instances
on via IPA BAM2BAM pipes. Per each RMNET instance
there is a pipe connection accordingly.

Change-Id: I6c94674555d102395b31ab20bb69ae10caf8d41a
Signed-off-by: default avatarLena Salman <esalman@codeaurora.org>
Signed-off-by: default avatarIdo Shayevitz <idos@codeaurora.org>
parent a557d4ef
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -58,7 +58,8 @@ struct usb_bam_connect_ipa_params {
	u32 prod_clnt_hdl;
	u32 cons_clnt_hdl;
	/* params assigned by the CD */
	enum ipa_client_type client;
	enum ipa_client_type src_client;
	enum ipa_client_type dst_client;
	struct ipa_ep_cfg ipa_ep_cfg;
	void *priv;
	void (*notify)(void *priv, enum ipa_dp_evt_type evt,
@@ -101,11 +102,17 @@ struct usb_bam_event_info {
* @desc_mem_buf: descriptor fifo buffer.
* @event: event for wakeup.
* @enabled: true if pipe is enabled.
* @suspended: true if pipe is suspended.
* @cons_stopped: true is pipe has consumer requests stopped.
* @prod_stopped: true if pipe has producer requests stopped.
* @ipa_clnt_hdl : pipe handle to ipa api.
* @priv: private data to return upon activity_notify
*	or inactivity_notify callbacks.
* @activity_notify: callback to invoke on activity on one of the in pipes.
* @inactivity_notify: callback to invoke on inactivity on all pipes.
* @start: callback to invoke to enqueue transfers on a pipe.
* @stop: callback to invoke on dequeue transfers on a pipe.
* @start_stop_param: param for the start/stop callbacks.
*/
struct usb_bam_pipe_connect {
	const char *name;
@@ -127,10 +134,15 @@ struct usb_bam_pipe_connect {
	struct usb_bam_event_info event;
	bool enabled;
	bool suspended;
	bool cons_stopped;
	bool prod_stopped;
	int ipa_clnt_hdl;
	void *priv;
	int (*activity_notify)(void *priv);
	int (*inactivity_notify)(void *priv);
	void (*start)(void *, enum usb_bam_pipe_dir);
	void (*stop)(void *, enum usb_bam_pipe_dir);
	void *start_stop_param;
};

/**
@@ -226,6 +238,8 @@ int usb_bam_register_peer_reset_cb(int (*callback)(void *), void *param);
/**
 * Register callbacks for start/stop of transfers.
 *
 * @idx - Connection index
 *
 * @start - the callback function that will be called in USB
 *				driver to start transfers
 * @stop - the callback function that will be called in USB
@@ -237,6 +251,7 @@ int usb_bam_register_peer_reset_cb(int (*callback)(void *), void *param);
 *
 */
int usb_bam_register_start_stop_cbs(
	u8 idx,
	void (*start)(void *, enum usb_bam_pipe_dir),
	void (*stop)(void *, enum usb_bam_pipe_dir),
	void *param);
@@ -378,6 +393,7 @@ static inline int usb_bam_register_peer_reset_cb(
}

static inline int usb_bam_register_start_stop_cbs(
	u8 idx,
	void (*start)(void *, enum usb_bam_pipe_dir),
	void (*stop)(void *, enum usb_bam_pipe_dir),
	void *param)
+438 −276

File changed.

Preview size limit exceeded, changes collapsed.

+5 −6
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ struct f_rmnet {
	unsigned long			cpkts_len;
};

#define NR_RMNET_PORTS	3
static unsigned int nr_rmnet_ports;
static unsigned int no_ctrl_smd_ports;
static unsigned int no_ctrl_qti_ports;
@@ -414,7 +413,7 @@ static int gport_rmnet_connect(struct f_rmnet *dev)
		}
		break;
	case USB_GADGET_XPORT_QTI:
		ret = gqti_ctrl_connect(&dev->port);
		ret = gqti_ctrl_connect(&dev->port, port_num);
		if (ret) {
			pr_err("%s: gqti_ctrl_connect failed: err:%d\n",
					__func__, ret);
@@ -486,7 +485,7 @@ static int gport_rmnet_connect(struct f_rmnet *dev)
			pr_err("%s: gbam_connect failed: err:%d\n",
					__func__, ret);
			if (cxport == USB_GADGET_XPORT_QTI)
				gqti_ctrl_disconnect(&dev->port);
				gqti_ctrl_disconnect(&dev->port, port_num);
			else
				gsmd_ctrl_disconnect(&dev->port, port_num);
			return ret;
@@ -516,7 +515,7 @@ static int gport_rmnet_connect(struct f_rmnet *dev)
			pr_err("%s: gether_connect failed: err:%ld\n",
					__func__, PTR_ERR(net));
			if (cxport == USB_GADGET_XPORT_QTI)
				gqti_ctrl_disconnect(&dev->port);
				gqti_ctrl_disconnect(&dev->port, port_num);
			else
				gsmd_ctrl_disconnect(&dev->port, port_num);

@@ -550,7 +549,7 @@ static int gport_rmnet_disconnect(struct f_rmnet *dev)
		gsmd_ctrl_disconnect(&dev->port, port_num);
		break;
	case USB_GADGET_XPORT_QTI:
		gqti_ctrl_disconnect(&dev->port);
		gqti_ctrl_disconnect(&dev->port, port_num);
		break;
	case USB_GADGET_XPORT_HSIC:
		ghsic_ctrl_disconnect(&dev->port, port_num);
+19 −9
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@
#include "u_rmnet.h"

#define BAM_N_PORTS	1
#define BAM2BAM_N_PORTS	3
#define BAM2BAM_N_PORTS	4

static struct workqueue_struct *gbam_wq;
static int n_bam_ports;
@@ -40,6 +40,15 @@ static unsigned bam_ch_ids[] = { 8 };

static const char *bam_ch_names[] = { "bam_dmux_ch_8" };

static const enum ipa_client_type usb_prod[BAM2BAM_N_PORTS] = {
	IPA_CLIENT_USB_PROD, IPA_CLIENT_USB2_PROD,
	IPA_CLIENT_USB3_PROD, IPA_CLIENT_USB4_PROD
};
static const enum ipa_client_type usb_cons[BAM2BAM_N_PORTS] = {
	IPA_CLIENT_USB_CONS, IPA_CLIENT_USB2_CONS,
	IPA_CLIENT_USB3_CONS, IPA_CLIENT_USB4_CONS
};

#define BAM_PENDING_LIMIT			220
#define BAM_MUX_TX_PKT_DROP_THRESHOLD		1000
#define BAM_MUX_RX_PKT_FCTRL_EN_TSHOLD		500
@@ -751,7 +760,7 @@ static void gbam2bam_disconnect_work(struct work_struct *w)
		if (ret)
			pr_err("%s: usb_bam_disconnect_ipa failed: err:%d\n",
				__func__, ret);
		teth_bridge_disconnect(IPA_CLIENT_USB_PROD);
		teth_bridge_disconnect(d->ipa_params.src_client);
	}
}

@@ -817,7 +826,7 @@ static void gbam2bam_connect_work(struct work_struct *w)
		}
	} else if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		ret = teth_bridge_init(&usb_notify_cb, &priv,
				IPA_CLIENT_USB_PROD);
				d->ipa_params.src_client);
		if (ret) {
			pr_err("%s:teth_bridge_init() failed\n", __func__);
			return;
@@ -825,8 +834,6 @@ static void gbam2bam_connect_work(struct work_struct *w)
		d->ipa_params.notify = usb_notify_cb;
		d->ipa_params.priv = priv;
		d->ipa_params.ipa_ep_cfg.mode.mode = IPA_BASIC;

		d->ipa_params.client = IPA_CLIENT_USB_PROD;
		d->ipa_params.dir = USB_TO_PEER_PERIPHERAL;
		ret = usb_bam_connect_ipa(&d->ipa_params);
		if (ret) {
@@ -834,8 +841,6 @@ static void gbam2bam_connect_work(struct work_struct *w)
				__func__, ret);
			return;
		}

		d->ipa_params.client = IPA_CLIENT_USB_CONS;
		d->ipa_params.dir = PEER_PERIPHERAL_TO_USB;
		ret = usb_bam_connect_ipa(&d->ipa_params);
		if (ret) {
@@ -847,7 +852,7 @@ static void gbam2bam_connect_work(struct work_struct *w)
		connect_params.ipa_usb_pipe_hdl = d->ipa_params.prod_clnt_hdl;
		connect_params.usb_ipa_pipe_hdl = d->ipa_params.cons_clnt_hdl;
		connect_params.tethering_mode = TETH_TETHERING_MODE_RMNET;
		connect_params.client_type = IPA_CLIENT_USB_PROD;
		connect_params.client_type = d->ipa_params.src_client;
		ret = teth_bridge_connect(&connect_params);
		if (ret) {
			pr_err("%s:teth_bridge_connect() failed\n", __func__);
@@ -937,7 +942,8 @@ static void gbam2bam_suspend_work(struct work_struct *w)

	usb_bam_register_wake_cb(d->dst_connection_idx, gbam_wake_cb, port);
	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		usb_bam_register_start_stop_cbs(gbam_start, gbam_stop, port);
		usb_bam_register_start_stop_cbs(d->dst_connection_idx,
						gbam_start, gbam_stop, port);
		usb_bam_suspend(&d->ipa_params);
	}
}
@@ -1189,6 +1195,8 @@ static int gbam2bam_port_alloc(int portno)
	/* data ch */
	d = &port->data_ch;
	d->port = port;
	d->ipa_params.src_client = usb_prod[portno];
	d->ipa_params.dst_client = usb_cons[portno];
	bam2bam_ports[portno] = port;

	pr_debug("%s: port:%p portno:%d\n", __func__, port, portno);
@@ -1443,6 +1451,8 @@ int gbam_connect(struct grmnet *gr, u8 port_num,
		d->dst_connection_idx = dst_connection_idx;
	} else if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		port->gr = gr;
		d->src_connection_idx = src_connection_idx;
		d->dst_connection_idx = dst_connection_idx;
		d->ipa_params.src_pipe = &(d->src_pipe_idx);
		d->ipa_params.dst_pipe = &(d->dst_pipe_idx);
		d->ipa_params.src_idx = src_connection_idx;
+8 −9
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ static void bam2bam_data_disconnect_work(struct work_struct *w)
		if (ret)
			pr_err("usb_bam_disconnect_ipa failed: err:%d\n", ret);
		if (d->func_type == USB_FUNC_MBIM)
			teth_bridge_disconnect(IPA_CLIENT_USB_PROD);
			teth_bridge_disconnect(d->ipa_params.src_client);

	}
}
@@ -209,7 +209,7 @@ static void bam2bam_data_connect_work(struct work_struct *w)
	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		if (d->func_type == USB_FUNC_MBIM) {
			ret = teth_bridge_init(&usb_notify_cb, &priv,
					IPA_CLIENT_USB_PROD);
					d->ipa_params.src_client);
			if (ret) {
				pr_err("%s:teth_bridge_init() failed\n",
				      __func__);
@@ -219,8 +219,6 @@ static void bam2bam_data_connect_work(struct work_struct *w)
			d->ipa_params.priv = priv;
			d->ipa_params.ipa_ep_cfg.mode.mode = IPA_BASIC;
		}

		d->ipa_params.client = IPA_CLIENT_USB_PROD;
		d->ipa_params.dir = USB_TO_PEER_PERIPHERAL;
		if (d->func_type == USB_FUNC_ECM) {
			d->ipa_params.notify = ecm_qc_get_ipa_rx_cb();
@@ -232,8 +230,6 @@ static void bam2bam_data_connect_work(struct work_struct *w)
				__func__, ret);
			return;
		}

		d->ipa_params.client = IPA_CLIENT_USB_CONS;
		d->ipa_params.dir = PEER_PERIPHERAL_TO_USB;
		if (d->func_type == USB_FUNC_ECM) {
			d->ipa_params.notify = ecm_qc_get_ipa_tx_cb();
@@ -254,7 +250,7 @@ static void bam2bam_data_connect_work(struct work_struct *w)
				d->ipa_params.cons_clnt_hdl;
			connect_params.tethering_mode =
				TETH_TETHERING_MODE_MBIM;
			connect_params.client_type = IPA_CLIENT_USB_PROD;
			connect_params.client_type = d->ipa_params.src_client;
			ret = teth_bridge_connect(&connect_params);
			if (ret) {
				pr_err("%s:teth_bridge_connect() failed\n",
@@ -365,6 +361,8 @@ static int bam2bam_data_port_alloc(int portno)
	d = &port->data_ch;
	d->port = port;
	bam2bam_data_ports[portno] = port;
	d->ipa_params.src_client = IPA_CLIENT_USB_PROD;
	d->ipa_params.dst_client = IPA_CLIENT_USB_CONS;

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

@@ -615,7 +613,8 @@ static void bam2bam_data_suspend_work(struct work_struct *w)

	usb_bam_register_wake_cb(d->dst_connection_idx, bam_data_wake_cb, port);
	if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		usb_bam_register_start_stop_cbs(bam_data_start, bam_data_stop,
		usb_bam_register_start_stop_cbs(d->dst_connection_idx,
						bam_data_start, bam_data_stop,
						port);
		usb_bam_suspend(&d->ipa_params);
	}
Loading