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

Commit 655c3734 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: IPA: RNDIS: Add both device and host side parameters"

parents 5fd5d8b9 cc2f14c1
Loading
Loading
Loading
Loading
+27 −19
Original line number Diff line number Diff line
@@ -302,8 +302,8 @@ static void rndis_ipa_dump_skb(struct sk_buff *skb);
static int rndis_ipa_debugfs_init(struct rndis_ipa_dev *rndis_ipa_ctx);
static void rndis_ipa_debugfs_destroy(struct rndis_ipa_dev *rndis_ipa_ctx);
static int rndis_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl,
		u32 ipa_to_usb_hdl, u32 max_transfer_size,
		u32 max_packet_number, u32 mtu,
		u32 ipa_to_usb_hdl, u32 max_xfer_size_bytes_to_dev,
		u32 max_xfer_size_bytes_to_host, u32 mtu,
		bool deaggr_enable);
static int rndis_ipa_set_device_ethernet_addr(u8 *dev_ethaddr,
		u8 device_ethaddr[]);
@@ -698,8 +698,9 @@ EXPORT_SYMBOL(rndis_ipa_init);
 */
int rndis_ipa_pipe_connect_notify(u32 usb_to_ipa_hdl,
			u32 ipa_to_usb_hdl,
			u32 max_transfer_byte_size,
			u32 max_packet_number,
			u32 max_xfer_size_bytes_to_dev,
			u32 max_packet_number_to_dev,
			u32 max_xfer_size_bytes_to_host,
			void *private)
{
	struct rndis_ipa_dev *rndis_ipa_ctx = private;
@@ -712,8 +713,11 @@ int rndis_ipa_pipe_connect_notify(u32 usb_to_ipa_hdl,

	RNDIS_IPA_DEBUG("usb_to_ipa_hdl=%d, ipa_to_usb_hdl=%d, private=0x%p\n",
				usb_to_ipa_hdl, ipa_to_usb_hdl, private);
	RNDIS_IPA_DEBUG("max_xfer_sz=%d, max_pkt_num=%d\n",
			max_transfer_byte_size, max_packet_number);
	RNDIS_IPA_DEBUG("max_xfer_sz_to_dev=%d, max_pkt_num_to_dev=%d\n",
			max_xfer_size_bytes_to_dev,
			max_packet_number_to_dev);
	RNDIS_IPA_DEBUG("max_xfer_sz_to_host=%d\n",
			max_xfer_size_bytes_to_host);

	next_state = rndis_ipa_next_state(rndis_ipa_ctx->state,
		RNDIS_IPA_CONNECT);
@@ -734,10 +738,14 @@ int rndis_ipa_pipe_connect_notify(u32 usb_to_ipa_hdl,
	}
	rndis_ipa_ctx->ipa_to_usb_hdl = ipa_to_usb_hdl;
	rndis_ipa_ctx->usb_to_ipa_hdl = usb_to_ipa_hdl;
	if (max_packet_number_to_dev > 1)
		rndis_ipa_ctx->deaggregation_enable = true;
	else
		rndis_ipa_ctx->deaggregation_enable = false;
	result = rndis_ipa_ep_registers_cfg(usb_to_ipa_hdl,
			ipa_to_usb_hdl,
			max_transfer_byte_size,
			max_packet_number,
			max_xfer_size_bytes_to_dev,
			max_xfer_size_bytes_to_host,
			rndis_ipa_ctx->net->mtu,
			rndis_ipa_ctx->deaggregation_enable);
	if (result) {
@@ -1876,12 +1884,10 @@ static bool rm_enabled(struct rndis_ipa_dev *rndis_ipa_ctx)
 *  the USB to IPA end-point
 * @ipa_to_usb_hdl: handle received from ipa_connect which represents
 *  the IPA to USB end-point
 * @max_transfer_byte_size: the maximum size, in bytes, that the device
 * @max_xfer_size_bytes_to_dev: the maximum size, in bytes, that the device
 *  expects to receive from the host. supplied on REMOTE_NDIS_INITIALIZE_CMPLT.
 * @max_packet_number: The maximum number of
 * concatenated REMOTE_NDIS_PACKET_MSG messages that the device can handle
 * in a single bus transfer to it.
 * This value MUST be at least 1.
 * @max_xfer_size_bytes_to_host: the maximum size, in bytes, that the host
 *  expects to receive from the device. supplied on REMOTE_NDIS_INITIALIZE_MSG.
 * @mtu: the netdev MTU size, in bytes
 *
 * USB to IPA pipe:
@@ -1897,8 +1903,8 @@ static bool rm_enabled(struct rndis_ipa_dev *rndis_ipa_ctx)
 */
static int rndis_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl,
		u32 ipa_to_usb_hdl,
		u32 max_transfer_byte_size,
		u32 max_packet_number,
		u32 max_xfer_size_bytes_to_dev,
		u32 max_xfer_size_bytes_to_host,
		u32 mtu,
		bool deaggr_enable)
{
@@ -1913,7 +1919,7 @@ static int rndis_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl,
		RNDIS_IPA_DEBUG("deaggregation disabled\n");
	}

	usb_to_ipa_ep_cfg->deaggr.max_packet_len = max_transfer_byte_size;
	usb_to_ipa_ep_cfg->deaggr.max_packet_len = max_xfer_size_bytes_to_dev;
	result = ipa_cfg_ep(usb_to_ipa_hdl, usb_to_ipa_ep_cfg);
	if (result) {
		pr_err("failed to configure USB to IPA point\n");
@@ -1921,9 +1927,9 @@ static int rndis_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl,
	}
	RNDIS_IPA_DEBUG("IPA<-USB end-point configured\n");

	ipa_to_usb_ep_cfg.aggr.aggr_pkt_limit = max_packet_number;
	ipa_to_usb_ep_cfg.aggr.aggr_pkt_limit = 0;
	ipa_to_usb_ep_cfg.aggr.aggr_byte_limit =
		(max_transfer_byte_size - mtu)/1024;
		(max_xfer_size_bytes_to_host - mtu)/1024;
	result = ipa_cfg_ep(ipa_to_usb_hdl, &ipa_to_usb_ep_cfg);
	if (result) {
		pr_err("failed to configure IPA to USB end-point\n");
@@ -2676,8 +2682,10 @@ static int rndis_ipa_setup_loopback(bool enable,
	retval = rndis_ipa_pipe_connect_notify(
			rndis_ipa_ctx->usb_to_ipa_loopback_pipe.ipa_drv_ep_hdl,
			rndis_ipa_ctx->ipa_to_usb_loopback_pipe.ipa_drv_ep_hdl,
			BAM_DMA_DATA_FIFO_SIZE,
			15,
			BAM_DMA_DATA_FIFO_SIZE - rndis_ipa_ctx->net->mtu,
			15, rndis_ipa_ctx);
			rndis_ipa_ctx);
	if (retval) {
		RNDIS_IPA_ERROR("connect notify fail");
		return -ENODEV;
+15 −13
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ struct f_rndis_qc {
	u8				ctrl_id, data_id;
	u8				ethaddr[ETH_ALEN];
	u32				vendorID;
	u8				max_pkt_per_xfer;
	u8				ul_max_pkt_per_xfer;
	u8				pkt_alignment_factor;
	u32				max_pkt_size;
	const char			*manufacturer;
@@ -587,6 +587,7 @@ static void rndis_qc_command_complete(struct usb_ep *ep,
	struct f_rndis_qc		*rndis = req->context;
	int				status;
	rndis_init_msg_type		*buf;
	u32		ul_max_xfer_size, dl_max_xfer_size;

	/* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
	status = rndis_msg_parser(rndis->config, (u8 *) req->buf);
@@ -597,9 +598,10 @@ static void rndis_qc_command_complete(struct usb_ep *ep,
	buf = (rndis_init_msg_type *)req->buf;

	if (buf->MessageType == RNDIS_MSG_INIT) {
		rndis->max_pkt_size = buf->MaxTransferSize;
		pr_debug("MaxTransferSize: %d\n", buf->MaxTransferSize);
		u_bam_data_set_max_xfer_size(rndis->max_pkt_size);
		ul_max_xfer_size = rndis_get_ul_max_xfer_size(rndis->config);
		u_bam_data_set_ul_max_xfer_size(ul_max_xfer_size);
		dl_max_xfer_size = rndis_get_dl_max_xfer_size(rndis->config);
		u_bam_data_set_dl_max_xfer_size(dl_max_xfer_size);
	}
}

@@ -968,8 +970,8 @@ rndis_qc_bind(struct usb_configuration *c, struct usb_function *f)
		goto fail;

	pr_debug("%s(): max_pkt_per_xfer:%d\n", __func__,
				rndis->max_pkt_per_xfer);
	rndis_set_max_pkt_xfer(rndis->config, rndis->max_pkt_per_xfer);
				rndis->ul_max_pkt_per_xfer);
	rndis_set_max_pkt_xfer(rndis->config, rndis->ul_max_pkt_per_xfer);

	/* In case of aggregated packets QC device will request
	 * aliment to 4 (2^2).
@@ -1195,10 +1197,10 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
	rndis->manufacturer = manufacturer;

	/* if max_pkt_per_xfer was not configured set to default value */
	rndis->max_pkt_per_xfer =
	rndis->ul_max_pkt_per_xfer =
			max_pkt_per_xfer ? max_pkt_per_xfer :
			DEFAULT_MAX_PKT_PER_XFER;
	u_bam_data_set_max_pkt_num(rndis->max_pkt_per_xfer);
	u_bam_data_set_ul_max_pkt_num(rndis->ul_max_pkt_per_xfer);

	/*
	 * Check no RNDIS aggregation, and alignment if not mentioned,
@@ -1210,7 +1212,7 @@ rndis_qc_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
	 * those values will always override default values.
	 */
	if ((rndis->pkt_alignment_factor == 0) &&
			(rndis->max_pkt_per_xfer == 1))
			(rndis->ul_max_pkt_per_xfer == 1))
		rndis->pkt_alignment_factor = 0;
	else
		rndis->pkt_alignment_factor = pkt_alignment_factor ?
@@ -1305,14 +1307,14 @@ static long rndis_qc_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
	switch (cmd) {
	case RNDIS_QC_GET_MAX_PKT_PER_XFER:
		ret = copy_to_user((void __user *)arg,
					&rndis->max_pkt_per_xfer,
					sizeof(rndis->max_pkt_per_xfer));
					&rndis->ul_max_pkt_per_xfer,
					sizeof(rndis->ul_max_pkt_per_xfer));
		if (ret) {
			pr_err("copying to user space failed\n");
			ret = -EFAULT;
		}
		pr_info("Sent max packets per xfer %d\n",
				rndis->max_pkt_per_xfer);
		pr_info("Sent UL max packets per xfer %d\n",
				rndis->ul_max_pkt_per_xfer);
		break;
	case RNDIS_QC_GET_MAX_PKT_SIZE:
		ret = copy_to_user((void __user *)arg,
+26 −1
Original line number Diff line number Diff line
@@ -615,6 +615,7 @@ static int rndis_init_response(int configNr, rndis_init_msg_type *buf)
	resp->AFListOffset = cpu_to_le32(0);
	resp->AFListSize = cpu_to_le32(0);

	params->ul_max_xfer_size = le32_to_cpu(resp->MaxTransferSize);
	params->resp_avail(params->v);
	return 0;
}
@@ -820,7 +821,7 @@ void rndis_set_host_mac(int configNr, const u8 *addr)
 */
int rndis_msg_parser(u8 configNr, u8 *buf)
{
	u32 MsgType, MsgLength;
	u32 MsgType, MsgLength, major, minor, max_transfer_size;
	__le32 *tmp;
	struct rndis_params *params;

@@ -845,6 +846,19 @@ int rndis_msg_parser(u8 configNr, u8 *buf)
	case RNDIS_MSG_INIT:
		pr_debug("%s: RNDIS_MSG_INIT\n",
			__func__);
		tmp++; /* to get RequestID */
		major = get_unaligned_le32(tmp++);
		minor = get_unaligned_le32(tmp++);
		max_transfer_size = get_unaligned_le32(tmp++);

		params->host_rndis_major_ver = major;
		params->host_rndis_minor_ver = minor;
		params->dl_max_xfer_size = max_transfer_size;

		pr_debug("%s(): RNDIS Host Major:%d Minor:%d version\n",
					__func__, major, minor);
		pr_debug("%s(): UL Max Transfer size:%x\n", __func__,
					max_transfer_size);
		params->state = RNDIS_INITIALIZED;
		return rndis_init_response(configNr,
					(rndis_init_msg_type *)buf);
@@ -967,6 +981,17 @@ int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed)

	return 0;
}
u32 rndis_get_dl_max_xfer_size(u8 configNr)
{
	pr_debug("%s:\n", __func__);
	return rndis_per_dev_params[configNr].dl_max_xfer_size;
}

u32 rndis_get_ul_max_xfer_size(u8 configNr)
{
	pr_debug("%s:\n", __func__);
	return rndis_per_dev_params[configNr].ul_max_xfer_size;
}

void rndis_set_max_pkt_xfer(u8 configNr, u8 max_pkt_per_xfer)
{
+6 −0
Original line number Diff line number Diff line
@@ -196,6 +196,10 @@ typedef struct rndis_params
	void			*v;
	struct list_head	resp_queue;
	spinlock_t		lock;
	u32			host_rndis_major_ver;
	u32			host_rndis_minor_ver;
	u32			ul_max_xfer_size;
	u32			dl_max_xfer_size;
} rndis_params;

/* RNDIS Message parser and other useless functions */
@@ -208,6 +212,8 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID,
			    const char *vendorDescr);
int  rndis_set_param_medium (u8 configNr, u32 medium, u32 speed);
void rndis_set_max_pkt_xfer(u8 configNr, u8 max_pkt_per_xfer);
u32  rndis_get_ul_max_xfer_size(u8 configNr);
u32  rndis_get_dl_max_xfer_size(u8 configNr);
void rndis_add_hdr (struct sk_buff *skb);
int rndis_rm_hdr(struct gether *port, struct sk_buff *skb,
			struct sk_buff_head *list);
+42 −9
Original line number Diff line number Diff line
@@ -58,8 +58,12 @@ module_param(bam_data_mux_rx_req_size, uint, S_IRUGO | S_IWUSR);
#define MSM_VENDOR_ID			BIT(16)

struct rndis_data_ch_info {
	u32 max_transfer_size;
	u32 max_packets_number;
	/* this provides downlink (device->host i.e host) side configuration*/
	u32 dl_max_transfer_size;
	/* this provides uplink (host->device i.e device) side configuration */
	u32 ul_max_transfer_size;
	u32 ul_max_packets_number;
	bool ul_aggregation_enable;
	u32 prod_clnt_hdl;
	u32 cons_clnt_hdl;
	void *priv;
@@ -1025,11 +1029,19 @@ static void bam2bam_data_connect_work(struct work_struct *w)
				d->ipa_params.cons_clnt_hdl;
			rndis_data.priv = d->ipa_params.priv;

			pr_debug("ul_max_transfer_size:%d\n",
					rndis_data.ul_max_transfer_size);
			pr_debug("ul_max_packets_number:%d\n",
					rndis_data.ul_max_packets_number);
			pr_debug("dl_max_transfer_size:%d\n",
					rndis_data.dl_max_transfer_size);

			ret = rndis_ipa_pipe_connect_notify(
				rndis_data.cons_clnt_hdl,
				rndis_data.prod_clnt_hdl,
				rndis_data.max_transfer_size,
				rndis_data.max_packets_number,
				rndis_data.ul_max_transfer_size,
				rndis_data.ul_max_packets_number,
				rndis_data.dl_max_transfer_size,
				rndis_data.priv);
			if (ret) {
				pr_err("%s: failed to connect IPA: err:%d\n",
@@ -1726,17 +1738,18 @@ exit:
	spin_unlock_irqrestore(&port->port_lock, flags);
}

void u_bam_data_set_max_xfer_size(u32 max_transfer_size)
void u_bam_data_set_dl_max_xfer_size(u32 max_transfer_size)
{

	if (!max_transfer_size) {
		pr_err("%s: invalid parameters\n", __func__);
		return;
	}

	rndis_data.max_transfer_size = max_transfer_size;
	rndis_data.dl_max_transfer_size = max_transfer_size;
	pr_debug("%s(): dl_max_xfer_size:%d\n", __func__, max_transfer_size);
}

void u_bam_data_set_max_pkt_num(u32 max_packets_number)
void u_bam_data_set_ul_max_pkt_num(u8 max_packets_number)

{
	if (!max_packets_number) {
@@ -1744,5 +1757,25 @@ void u_bam_data_set_max_pkt_num(u32 max_packets_number)
		return;
	}

	rndis_data.max_packets_number = max_packets_number;
	rndis_data.ul_max_packets_number = max_packets_number;

	if (max_packets_number > 1)
		rndis_data.ul_aggregation_enable = true;
	else
		rndis_data.ul_aggregation_enable = false;

	pr_debug("%s(): ul_aggregation enable:%d\n", __func__,
				rndis_data.ul_aggregation_enable);
	pr_debug("%s(): ul_max_packets_number:%d\n", __func__,
				max_packets_number);
}

void u_bam_data_set_ul_max_xfer_size(u32 max_transfer_size)
{
	if (!max_transfer_size) {
		pr_err("%s: invalid parameters\n", __func__);
		return;
	}
	rndis_data.ul_max_transfer_size = max_transfer_size;
	pr_debug("%s(): ul_max_xfer_size:%d\n", __func__, max_transfer_size);
}
Loading