forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/usb/gadget/function/f_ncm.c
....@@ -23,6 +23,7 @@
2323 #include "u_ether.h"
2424 #include "u_ether_configfs.h"
2525 #include "u_ncm.h"
26
+#include "configfs.h"
2627
2728 /*
2829 * This function is a "CDC Network Control Model" (CDC NCM) Ethernet link.
....@@ -35,9 +36,7 @@
3536
3637 /* to trigger crc/non-crc ndp signature */
3738
38
-#define NCM_NDP_HDR_CRC_MASK 0x01000000
3939 #define NCM_NDP_HDR_CRC 0x01000000
40
-#define NCM_NDP_HDR_NOCRC 0x00000000
4140
4241 enum ncm_notify_state {
4342 NCM_NOTIFY_NONE, /* don't notify */
....@@ -379,7 +378,7 @@
379378 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
380379
381380 /* the following 2 values can be tweaked if necessary */
382
- /* .bMaxBurst = 0, */
381
+ .bMaxBurst = 15,
383382 /* .bmAttributes = 0, */
384383 };
385384
....@@ -529,6 +528,7 @@
529528 {
530529 ncm->parser_opts = &ndp16_opts;
531530 ncm->is_crc = false;
531
+ ncm->ndp_sign = ncm->parser_opts->ndp_sign;
532532 ncm->port.cdc_filter = DEFAULT_FILTER;
533533
534534 /* doesn't make sense for ncm, fixed size used */
....@@ -811,25 +811,20 @@
811811 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
812812 | USB_CDC_SET_CRC_MODE:
813813 {
814
- int ndp_hdr_crc = 0;
815
-
816814 if (w_length != 0 || w_index != ncm->ctrl_id)
817815 goto invalid;
818816 switch (w_value) {
819817 case 0x0000:
820818 ncm->is_crc = false;
821
- ndp_hdr_crc = NCM_NDP_HDR_NOCRC;
822819 DBG(cdev, "non-CRC mode selected\n");
823820 break;
824821 case 0x0001:
825822 ncm->is_crc = true;
826
- ndp_hdr_crc = NCM_NDP_HDR_CRC;
827823 DBG(cdev, "CRC mode selected\n");
828824 break;
829825 default:
830826 goto invalid;
831827 }
832
- ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc;
833828 value = 0;
834829 break;
835830 }
....@@ -846,6 +841,8 @@
846841 ctrl->bRequestType, ctrl->bRequest,
847842 w_value, w_index, w_length);
848843 }
844
+ ncm->ndp_sign = ncm->parser_opts->ndp_sign |
845
+ (ncm->is_crc ? NCM_NDP_HDR_CRC : 0);
849846
850847 /* respond with data transfer or status phase? */
851848 if (value >= 0) {
....@@ -1432,6 +1429,16 @@
14321429 return -EINVAL;
14331430
14341431 ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst);
1432
+
1433
+ if (cdev->use_os_string) {
1434
+ f->os_desc_table = kzalloc(sizeof(*f->os_desc_table),
1435
+ GFP_KERNEL);
1436
+ if (!f->os_desc_table)
1437
+ return -ENOMEM;
1438
+ f->os_desc_n = 1;
1439
+ f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc;
1440
+ }
1441
+
14351442 /*
14361443 * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
14371444 * configurations are bound in sequence with list_for_each_entry,
....@@ -1445,13 +1452,15 @@
14451452 status = gether_register_netdev(ncm_opts->net);
14461453 mutex_unlock(&ncm_opts->lock);
14471454 if (status)
1448
- return status;
1455
+ goto fail;
14491456 ncm_opts->bound = true;
14501457 }
14511458 us = usb_gstrings_attach(cdev, ncm_strings,
14521459 ARRAY_SIZE(ncm_string_defs));
1453
- if (IS_ERR(us))
1454
- return PTR_ERR(us);
1460
+ if (IS_ERR(us)) {
1461
+ status = PTR_ERR(us);
1462
+ goto fail;
1463
+ }
14551464 ncm_control_intf.iInterface = us[STRING_CTRL_IDX].id;
14561465 ncm_data_nop_intf.iInterface = us[STRING_DATA_IDX].id;
14571466 ncm_data_intf.iInterface = us[STRING_DATA_IDX].id;
....@@ -1467,6 +1476,10 @@
14671476
14681477 ncm_control_intf.bInterfaceNumber = status;
14691478 ncm_union_desc.bMasterInterface0 = status;
1479
+
1480
+ if (cdev->use_os_string)
1481
+ f->os_desc_table[0].if_id =
1482
+ ncm_iad_desc.bFirstInterface;
14701483
14711484 status = usb_interface_id(c, f);
14721485 if (status < 0)
....@@ -1547,6 +1560,9 @@
15471560 return 0;
15481561
15491562 fail:
1563
+ kfree(f->os_desc_table);
1564
+ f->os_desc_n = 0;
1565
+
15501566 if (ncm->notify_req) {
15511567 kfree(ncm->notify_req->buf);
15521568 usb_ep_free_request(ncm->notify, ncm->notify_req);
....@@ -1601,16 +1617,22 @@
16011617 gether_cleanup(netdev_priv(opts->net));
16021618 else
16031619 free_netdev(opts->net);
1620
+ kfree(opts->ncm_interf_group);
16041621 kfree(opts);
16051622 }
16061623
16071624 static struct usb_function_instance *ncm_alloc_inst(void)
16081625 {
16091626 struct f_ncm_opts *opts;
1627
+ struct usb_os_desc *descs[1];
1628
+ char *names[1];
1629
+ struct config_group *ncm_interf_group;
16101630
16111631 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
16121632 if (!opts)
16131633 return ERR_PTR(-ENOMEM);
1634
+ opts->ncm_os_desc.ext_compat_id = opts->ncm_ext_compat_id;
1635
+
16141636 mutex_init(&opts->lock);
16151637 opts->func_inst.free_func_inst = ncm_free_inst;
16161638 opts->net = gether_setup_default();
....@@ -1619,8 +1641,20 @@
16191641 kfree(opts);
16201642 return ERR_CAST(net);
16211643 }
1644
+ INIT_LIST_HEAD(&opts->ncm_os_desc.ext_prop);
1645
+
1646
+ descs[0] = &opts->ncm_os_desc;
1647
+ names[0] = "ncm";
16221648
16231649 config_group_init_type_name(&opts->func_inst.group, "", &ncm_func_type);
1650
+ ncm_interf_group =
1651
+ usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
1652
+ names, THIS_MODULE);
1653
+ if (IS_ERR(ncm_interf_group)) {
1654
+ ncm_free_inst(&opts->func_inst);
1655
+ return ERR_CAST(ncm_interf_group);
1656
+ }
1657
+ opts->ncm_interf_group = ncm_interf_group;
16241658
16251659 return &opts->func_inst;
16261660 }
....@@ -1646,6 +1680,9 @@
16461680
16471681 hrtimer_cancel(&ncm->task_timer);
16481682
1683
+ kfree(f->os_desc_table);
1684
+ f->os_desc_n = 0;
1685
+
16491686 ncm_string_defs[0].id = 0;
16501687 usb_free_all_descriptors(f);
16511688