diff options
| -rw-r--r-- | drivers/usb/gadget/function/f_gsi.c | 49 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_gsi.h | 13 |
2 files changed, 56 insertions, 6 deletions
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 19fe6c8cb25a..1900870eee39 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -2507,6 +2507,16 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f) DEFAULT_PKT_ALIGNMENT_FACTOR); rndis_set_pkt_alignment_factor(gsi->params, DEFAULT_PKT_ALIGNMENT_FACTOR); + if (gsi->rndis_use_wceis) { + info.iad_desc->bFunctionClass = + USB_CLASS_WIRELESS_CONTROLLER; + info.iad_desc->bFunctionSubClass = 0x01; + info.iad_desc->bFunctionProtocol = 0x03; + info.ctrl_desc->bInterfaceClass = + USB_CLASS_WIRELESS_CONTROLLER; + info.ctrl_desc->bInterfaceSubClass = 0x1; + info.ctrl_desc->bInterfaceProtocol = 0x03; + } break; case IPA_USB_MBIM: info.string_defs = mbim_gsi_string_defs; @@ -2986,6 +2996,42 @@ static ssize_t gsi_info_show(struct config_item *item, char *page) CONFIGFS_ATTR_RO(gsi_, info); +static ssize_t gsi_rndis_wceis_show(struct config_item *item, char *page) +{ + struct f_gsi *gsi = to_gsi_opts(item)->gsi; + + return snprintf(page, PAGE_SIZE, "%d\n", gsi->rndis_use_wceis); +} + +static ssize_t gsi_rndis_wceis_store(struct config_item *item, + const char *page, size_t len) +{ + struct f_gsi *gsi = to_gsi_opts(item)->gsi; + bool val; + + if (kstrtobool(page, &val)) + return -EINVAL; + + gsi->rndis_use_wceis = val; + + return len; +} + +CONFIGFS_ATTR(gsi_, rndis_wceis); + +static struct configfs_attribute *gsi_rndis_attrs[] = { + &gsi_attr_info, + &gsi_attr_rndis_wceis, + NULL, +}; + +static struct config_item_type gsi_func_rndis_type = { + .ct_item_ops = &gsi_item_ops, + .ct_attrs = gsi_rndis_attrs, + .ct_owner = THIS_MODULE, +}; + + static struct configfs_attribute *gsi_attrs[] = { &gsi_attr_info, NULL, @@ -3015,6 +3061,9 @@ static int gsi_set_inst_name(struct usb_function_instance *fi, return -EINVAL; } + if (ret == IPA_USB_RNDIS) + config_group_init_type_name(&opts->func_inst.group, "", + &gsi_func_rndis_type); gsi = gsi_function_init(ret); if (IS_ERR(gsi)) return PTR_ERR(gsi); diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h index 262a60e8a450..14490ab296c2 100644 --- a/drivers/usb/gadget/function/f_gsi.h +++ b/drivers/usb/gadget/function/f_gsi.h @@ -237,6 +237,7 @@ struct f_gsi { struct rndis_params *params; atomic_t connected; bool data_interface_up; + bool rndis_use_wceis; const struct usb_endpoint_descriptor *in_ep_desc_backup; const struct usb_endpoint_descriptor *out_ep_desc_backup; @@ -470,9 +471,9 @@ static struct usb_interface_descriptor rndis_gsi_control_intf = { /* .bInterfaceNumber = DYNAMIC */ /* status endpoint is optional; this could be patched later */ .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_WIRELESS_CONTROLLER, - .bInterfaceSubClass = 0x01, - .bInterfaceProtocol = 0x03, + .bInterfaceClass = USB_CLASS_MISC, + .bInterfaceSubClass = 0x04, + .bInterfaceProtocol = 0x01, /* RNDIS over Ethernet */ /* .iInterface = DYNAMIC */ }; @@ -530,9 +531,9 @@ rndis_gsi_iad_descriptor = { .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, .bFirstInterface = 0, /* XXX, hardcoded */ .bInterfaceCount = 2, /* control + data */ - .bFunctionClass = USB_CLASS_WIRELESS_CONTROLLER, - .bFunctionSubClass = 0x01, - .bFunctionProtocol = 0x03, + .bFunctionClass = USB_CLASS_MISC, + .bFunctionSubClass = 0x04, + .bFunctionProtocol = 0x01, /* RNDIS over Ethernet */ /* .iFunction = DYNAMIC */ }; |
