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

Commit 06183625 authored by Liangliang Lu's avatar Liangliang Lu Committed by Gerrit - the friendly Code Review server
Browse files

usb: gadget: f_rndis: Add 'wceis' flag to indicate 'Wireless' RNDIS



The 'wceis' flag used to indicate the device as wireless controller.
Set the default value is true as this is what we want in most of the
cases.

Change-Id: Idc03717526350421d94b9445333b36823a372aad
Signed-off-by: default avatarLiangliang Lu <luliang@codeaurora.org>
parent 8b7fffb4
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -752,6 +752,27 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
	rndis_data_intf.bInterfaceNumber = status;
	rndis_union_desc.bSlaveInterface0 = status;

	if (rndis_opts->wceis) {
		/* "Wireless" RNDIS; auto-detected by Windows */
		rndis_iad_descriptor.bFunctionClass =
						USB_CLASS_WIRELESS_CONTROLLER;
		rndis_iad_descriptor.bFunctionSubClass = 0x01;
		rndis_iad_descriptor.bFunctionProtocol = 0x03;
		rndis_control_intf.bInterfaceClass =
						USB_CLASS_WIRELESS_CONTROLLER;
		rndis_control_intf.bInterfaceSubClass =	 0x01;
		rndis_control_intf.bInterfaceProtocol =	 0x03;
	} else {
		rndis_iad_descriptor.bFunctionClass = USB_CLASS_COMM;
		rndis_iad_descriptor.bFunctionSubClass =
						USB_CDC_SUBCLASS_ETHERNET;
		rndis_iad_descriptor.bFunctionProtocol = USB_CDC_PROTO_NONE;
		rndis_control_intf.bInterfaceClass = USB_CLASS_COMM;
		rndis_control_intf.bInterfaceSubClass =	USB_CDC_SUBCLASS_ACM;
		rndis_control_intf.bInterfaceProtocol =
						USB_CDC_ACM_PROTO_VENDOR;
	}

	status = -ENODEV;

	/* allocate instance-specific endpoints */
@@ -890,6 +911,9 @@ USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass);
/* f_rndis_opts_protocol */
USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol);

/* f_rndis_opts_wceis */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_WCEIS(rndis);

static struct configfs_attribute *rndis_attrs[] = {
	&rndis_opts_attr_dev_addr,
	&rndis_opts_attr_host_addr,
@@ -898,6 +922,7 @@ static struct configfs_attribute *rndis_attrs[] = {
	&rndis_opts_attr_class,
	&rndis_opts_attr_subclass,
	&rndis_opts_attr_protocol,
	&rndis_opts_attr_wceis,
	NULL,
};

@@ -962,6 +987,9 @@ static struct usb_function_instance *rndis_alloc_inst(void)
	}
	opts->rndis_interf_group = rndis_interf_group;

	/* Enable "Wireless" RNDIS by default */
	opts->wceis = true;

	return &opts->func_inst;
}

+46 −0
Original line number Diff line number Diff line
@@ -188,4 +188,50 @@ out: \
									\
	CONFIGFS_ATTR(_f_##_opts_, _n_)

#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_WCEIS(_f_)			\
	static ssize_t _f_##_opts_wceis_show(struct config_item *item,	\
					     char *page)		\
	{								\
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		bool wceis;						\
									\
		if (opts->bound == false) {				\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;					\
		}							\
									\
		mutex_lock(&opts->lock);				\
		wceis = opts->wceis;					\
		mutex_unlock(&opts->lock);				\
		return snprintf(page, PAGE_SIZE, "%d", wceis);		\
	}								\
									\
	static ssize_t _f_##_opts_wceis_store(struct config_item *item, \
					      const char *page, size_t len)\
	{								\
		struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);	\
		bool wceis;						\
		int ret;						\
									\
		if (opts->bound == false) {				\
			pr_err("Gadget function do not bind yet.\n");	\
			return -ENODEV;					\
		}							\
									\
		mutex_lock(&opts->lock);				\
									\
		ret = kstrtobool(page, &wceis);				\
		if (ret)						\
			goto out;					\
									\
		opts->wceis = wceis;					\
		ret = len;						\
out:									\
		mutex_unlock(&opts->lock);				\
									\
		return ret;						\
	}								\
									\
	CONFIGFS_ATTR(_f_##_opts_, wceis)

#endif /* __U_ETHER_CONFIGFS_H */
+3 −0
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ struct f_rndis_opts {
	 */
	struct mutex			lock;
	int				refcnt;

	/* "Wireless" RNDIS; auto-detected by Windows */
	bool	wceis;
};

void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net);