diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 4ba859295524..2660a84eb133 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -23,6 +23,8 @@ #include "u_ether.h" #include "u_ether_configfs.h" #include "u_ncm.h" +/* MOTODESK-2239 Add OS descriptor. suzh1 2021-02-05 */ +#include "configfs.h" /* * This function is a "CDC Network Control Model" (CDC NCM) Ethernet link. @@ -35,9 +37,7 @@ /* to trigger crc/non-crc ndp signature */ -#define NCM_NDP_HDR_CRC_MASK 0x01000000 #define NCM_NDP_HDR_CRC 0x01000000 -#define NCM_NDP_HDR_NOCRC 0x00000000 enum ncm_notify_state { NCM_NOTIFY_NONE, /* don't notify */ @@ -529,6 +529,8 @@ static inline void ncm_reset_values(struct f_ncm *ncm) { ncm->parser_opts = &ndp16_opts; ncm->is_crc = false; + /* MOTODESK-2239 Fix NTP-32 support. suzh1 2021-02-05 */ + ncm->ndp_sign = ncm->parser_opts->ndp_sign; ncm->port.cdc_filter = DEFAULT_FILTER; /* doesn't make sense for ncm, fixed size used */ @@ -811,25 +813,20 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | USB_CDC_SET_CRC_MODE: { - int ndp_hdr_crc = 0; - if (w_length != 0 || w_index != ncm->ctrl_id) goto invalid; switch (w_value) { case 0x0000: ncm->is_crc = false; - ndp_hdr_crc = NCM_NDP_HDR_NOCRC; DBG(cdev, "non-CRC mode selected\n"); break; case 0x0001: ncm->is_crc = true; - ndp_hdr_crc = NCM_NDP_HDR_CRC; DBG(cdev, "CRC mode selected\n"); break; default: goto invalid; } - ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc; value = 0; break; } @@ -846,6 +843,9 @@ invalid: ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); } + /* MOTODESK-2239 Fix NTP-32 support. suzh1 2021-02-05 */ + ncm->ndp_sign = ncm->parser_opts->ndp_sign | + (ncm->is_crc ? NCM_NDP_HDR_CRC : 0); /* respond with data transfer or status phase? */ if (value >= 0) { @@ -1432,6 +1432,16 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) return -EINVAL; ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst); + /* Begin MOTODESK-2239 Add OS descriptor support. suzh1 2021-02-05 */ + if (cdev->use_os_string) { + f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), + GFP_KERNEL); + if (!f->os_desc_table) + return -ENOMEM; + f->os_desc_n = 1; + f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; + } + /* End MOTODESK-2239 */ /* * in drivers/usb/gadget/configfs.c:configfs_composite_bind() * configurations are bound in sequence with list_for_each_entry, @@ -1441,7 +1451,8 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) */ if (!ncm_opts->bound) { mutex_lock(&ncm_opts->lock); - ncm_opts->net = gether_setup_default(); + /* MOTODESK-2239 Use ncm interface name. suzh1 2021-02-05 */ + ncm_opts->net = gether_setup_name_default("ncm"); if (IS_ERR(ncm_opts->net)) { status = PTR_ERR(ncm_opts->net); mutex_unlock(&ncm_opts->lock); @@ -1490,6 +1501,11 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) ncm_control_intf.bInterfaceNumber = status; ncm_union_desc.bMasterInterface0 = status; + /* MOTODESK-2239 Add OS descriptor. suzh1 2021-02-05 */ + if (cdev->use_os_string) + f->os_desc_table[0].if_id = + ncm_iad_desc.bFirstInterface; + status = usb_interface_id(c, f); if (status < 0) goto fail; @@ -1577,6 +1593,10 @@ netdev_cleanup: gether_cleanup(netdev_priv(ncm_opts->net)); error: + /* Begin MOTODESK-2239 Add OS descriptor support. suzh1 2021-02-05 */ + kfree(f->os_desc_table); + f->os_desc_n = 0; + /* End MOTODESK-2239 */ ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -1672,21 +1692,42 @@ static void ncm_free_inst(struct usb_function_instance *f) opts = container_of(f, struct f_ncm_opts, func_inst); if (opts->bound) gether_cleanup(netdev_priv(opts->net)); + /* MOTODESK-2239 Add OS descriptor support. suzh1 2021-02-05 */ + kfree(opts->ncm_interf_group); kfree(opts); } static struct usb_function_instance *ncm_alloc_inst(void) { struct f_ncm_opts *opts; + /* Begin MOTODESK-2239 Add OS descriptor support. suzh1 2021-02-05 */ + struct usb_os_desc *descs[1]; + char *names[1]; + struct config_group *ncm_interf_group; opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) return ERR_PTR(-ENOMEM); + opts->ncm_os_desc.ext_compat_id = opts->ncm_ext_compat_id; + mutex_init(&opts->lock); opts->func_inst.free_func_inst = ncm_free_inst; - config_group_init_type_name(&opts->func_inst.group, "", &ncm_func_type); + INIT_LIST_HEAD(&opts->ncm_os_desc.ext_prop); + descs[0] = &opts->ncm_os_desc; + names[0] = "ncm"; + + config_group_init_type_name(&opts->func_inst.group, "", &ncm_func_type); + ncm_interf_group = + usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, + names, THIS_MODULE); + if (IS_ERR(ncm_interf_group)) { + ncm_free_inst(&opts->func_inst); + return ERR_CAST(ncm_interf_group); + } + opts->ncm_interf_group = ncm_interf_group; + /* End MOTODESK-2239 */ #ifdef CONFIG_USB_CONFIGFS_UEVENT _ncm_setup_desc = kzalloc(sizeof(*_ncm_setup_desc), GFP_KERNEL); if (!_ncm_setup_desc) @@ -1723,6 +1764,10 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) hrtimer_cancel(&ncm->task_timer); + /* Begin MOTODESK-2239 Add OS descriptor support. suzh1 2021-02-05 */ + kfree(f->os_desc_table); + f->os_desc_n = 0; + /* End MOTODESK-2239 */ ncm_string_defs[0].id = 0; usb_free_all_descriptors(f); diff --git a/drivers/usb/gadget/function/u_ncm.h b/drivers/usb/gadget/function/u_ncm.h index 785bda0a4c7f..061a34cdabb4 100644 --- a/drivers/usb/gadget/function/u_ncm.h +++ b/drivers/usb/gadget/function/u_ncm.h @@ -20,6 +20,12 @@ struct f_ncm_opts { struct net_device *net; bool bound; + /* Begin MOTODESK-2239 Add OS descriptor support. suzh1 2021-02-05 */ + struct config_group *ncm_interf_group; + struct usb_os_desc ncm_os_desc; + char ncm_ext_compat_id[16]; + /* End MOTODESK-2239 */ + /* * Read/write access to configfs attributes is handled by configfs. *