Loading drivers/usb/gadget/function/f_rndis.c +28 −0 Original line number Original line Diff line number Diff line Loading @@ -818,6 +818,27 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis_data_intf.bInterfaceNumber = status; rndis_data_intf.bInterfaceNumber = status; rndis_union_desc.bSlaveInterface0 = 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; status = -ENODEV; /* allocate instance-specific endpoints */ /* allocate instance-specific endpoints */ Loading Loading @@ -950,11 +971,15 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis); /* f_rndis_opts_ifname */ /* f_rndis_opts_ifname */ USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); /* f_rndis_opts_wceis */ USB_ETHERNET_CONFIGFS_ITEM_ATTR_WCEIS(rndis); static struct configfs_attribute *rndis_attrs[] = { static struct configfs_attribute *rndis_attrs[] = { &rndis_opts_attr_dev_addr, &rndis_opts_attr_dev_addr, &rndis_opts_attr_host_addr, &rndis_opts_attr_host_addr, &rndis_opts_attr_qmult, &rndis_opts_attr_qmult, &rndis_opts_attr_ifname, &rndis_opts_attr_ifname, &rndis_opts_attr_wceis, NULL, NULL, }; }; Loading Loading @@ -1008,6 +1033,9 @@ static struct usb_function_instance *rndis_alloc_inst(void) } } opts->rndis_interf_group = rndis_interf_group; opts->rndis_interf_group = rndis_interf_group; /* Enable "Wireless" RNDIS by default */ opts->wceis = true; return &opts->func_inst; return &opts->func_inst; } } Loading drivers/usb/gadget/function/u_ether_configfs.h +46 −0 Original line number Original line Diff line number Diff line Loading @@ -188,4 +188,50 @@ out: \ \ \ CONFIGFS_ATTR_RO(_f_##_opts_, ifname) CONFIGFS_ATTR_RO(_f_##_opts_, ifname) #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 */ #endif /* __U_ETHER_CONFIGFS_H */ drivers/usb/gadget/function/u_rndis.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,9 @@ struct f_rndis_opts { */ */ struct mutex lock; struct mutex lock; int refcnt; int refcnt; /* "Wireless" RNDIS; auto-detected by Windows */ bool wceis; }; }; void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net); void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net); Loading Loading
drivers/usb/gadget/function/f_rndis.c +28 −0 Original line number Original line Diff line number Diff line Loading @@ -818,6 +818,27 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis_data_intf.bInterfaceNumber = status; rndis_data_intf.bInterfaceNumber = status; rndis_union_desc.bSlaveInterface0 = 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; status = -ENODEV; /* allocate instance-specific endpoints */ /* allocate instance-specific endpoints */ Loading Loading @@ -950,11 +971,15 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis); /* f_rndis_opts_ifname */ /* f_rndis_opts_ifname */ USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); /* f_rndis_opts_wceis */ USB_ETHERNET_CONFIGFS_ITEM_ATTR_WCEIS(rndis); static struct configfs_attribute *rndis_attrs[] = { static struct configfs_attribute *rndis_attrs[] = { &rndis_opts_attr_dev_addr, &rndis_opts_attr_dev_addr, &rndis_opts_attr_host_addr, &rndis_opts_attr_host_addr, &rndis_opts_attr_qmult, &rndis_opts_attr_qmult, &rndis_opts_attr_ifname, &rndis_opts_attr_ifname, &rndis_opts_attr_wceis, NULL, NULL, }; }; Loading Loading @@ -1008,6 +1033,9 @@ static struct usb_function_instance *rndis_alloc_inst(void) } } opts->rndis_interf_group = rndis_interf_group; opts->rndis_interf_group = rndis_interf_group; /* Enable "Wireless" RNDIS by default */ opts->wceis = true; return &opts->func_inst; return &opts->func_inst; } } Loading
drivers/usb/gadget/function/u_ether_configfs.h +46 −0 Original line number Original line Diff line number Diff line Loading @@ -188,4 +188,50 @@ out: \ \ \ CONFIGFS_ATTR_RO(_f_##_opts_, ifname) CONFIGFS_ATTR_RO(_f_##_opts_, ifname) #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 */ #endif /* __U_ETHER_CONFIGFS_H */
drivers/usb/gadget/function/u_rndis.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,9 @@ struct f_rndis_opts { */ */ struct mutex lock; struct mutex lock; int refcnt; int refcnt; /* "Wireless" RNDIS; auto-detected by Windows */ bool wceis; }; }; void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net); void rndis_borrow_net(struct usb_function_instance *f, struct net_device *net); Loading