MOTODESK-2239 Make NCM driver compatible with windows

1. Fix NTP-32 support
When connecting a CDC-NCM gadget to an host that uses the NTP-32 mode,
or that relies on the default CRC setting, the current implementation gets
confused, and does not expect the correct signature for its packets.
Fix this, by ensuring that the ndp_sign member in the f_ncm structure
always contain a valid value.
https://lore.kernel.org/patchwork/patch/1062690/

2. Add OS descriptor support
To be able to use the default USB class drivers available in Microsoft
Windows, we need to add OS descriptors to the exported USB gadget to
tell the OS that we are compatible with the built-in drivers.
Copy the OS descriptor support from f_rndis into f_ncm. As a result,
using the WINNCM compatible ID, the UsbNcm driver is loaded on
enumeration without the need for a custom driver or inf file.
https://lore.kernel.org/patchwork/patch/1062691/

3. Use "ncm0" interface name
The default interfacename "usb0" is confused. Use "ncm0" better.

Change-Id: I36d085c519f8205d7f9e0a1d9c669d3fb6623483
Reviewed-on: https://gerrit.mot.com/1872002
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Yonghua Yan <yanyh2@motorola.com>
Reviewed-by: Yuecai Liu <liuyc20@motorola.com>
Reviewed-by: Zonghua Liu <a17671@motorola.com>
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
(cherry picked from commit edda0121735f5436ef2287379fb6b57325ef04f4)
Reviewed-on: https://gerrit.mot.com/1916170
Reviewed-by: Xuejin Wang <wangxjn@motorola.com>
Tested-by: M(CR) SU <suzh1@lenovo.com>
This commit is contained in:
Mike SU authored and Gilberto Gambugge committed 2023-06-01 00:47:14 -03:00
1 parent 8d56fc509d
commit fc82a43871
2 files changed
+60 -9

No files matched your search

+54 -9
View File
@@ -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);
+6
View File
@@ -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.
*