summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/function/f_gsi.c49
-rw-r--r--drivers/usb/gadget/function/f_gsi.h13
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 */
};